Feeds

245612 items (586 unread) in 24 feeds

CNN CNN
MSNBC MSNBC
PHP PHP
Deals Deals
Tech Tech
Web Development Web Development
CNN Money CNN Money
Frugal Blogs Frugal Blogs

Nettuts+ (18 unread)

 
== Installation == 1. Download, unzip and upload to your WordPress plugins directory 2. activate the plugin within you WordPress Administration That’s it!

You just successfully wrote your first WordPress plugin, which is working and ready for the WP Plugins Directory. Along the way, you learned about filters and actions, using WP global objects, a lot about the WordPress nomencalture, how to interact with the database, cron events, and activation/deactivation hooks. If you have any questions, please leave a comment and I’ll respond as soon as I can.

The final code:
<?php
/*
Plugin Name: Simple Optimization
Plugin URI: [net.tutsplus.com] Description: A super-simple plugin to improve your blog
Version: 1.0
Author: Jonathan Wolfe
Author URI: [fire-studios.com] License: GPL2
.
This plugin written for NETTUTS at [net.tutsplus.com] .
*/

// Clean up wp_head
// Remove Really simple discovery link
remove_action('wp_head', 'rsd_link');
// Remove Windows Live Writer link
remove_action('wp_head', 'wlwmanifest_link');
// Remove the version number
remove_action('wp_head', 'wp_generator');

// Remove curly quotes
remove_filter('the_content', 'wptexturize');
remove_filter('comment_text', 'wptexturize');

// Allow HTML in user profiles
remove_filter('pre_user_description', 'wp_filter_kses');

// SEO
// add tags as keywords
function tags_to_keywords(){
    global $post; // Get access to the $post object
    if(is_single() || is_page()){ // only run on posts or pages
        $tags = wp_get_post_tags($post->ID); // get post tags
        foreach($tags as $tag){ // loop through each tag
            $tag_array[] = $tag->name; // create new array with only tag names
        }
        $tag_string = implode(', ',$tag_array); // convert array into comma seperated string
        if($tag_string !== ''){ // it we have tags
            echo "<meta name='keywords' content='".$tag_string."' />\r\n"; // add meta tag to <head>
        }
    }
}
add_action('wp_head','tags_to_keywords'); // Add tags_to_keywords to wp_head function
// add except as description
function excerpt_to_description(){
    global $post; // get access to the $post object
    if(is_single() || is_page()){ // only run on posts or pages
        $all_post_content = wp_get_single_post($post->ID); // get all content from the post/page
        $excerpt = substr($all_post_content->post_content, 0, 100).' [...]'; // get first 100 characters and append "[...]" to the end
        echo "<meta name='description' content='".$excerpt."' />\r\n"; // add meta tag to <head>
    }
    else{ // only run if not a post or page
        echo "<meta name='description' content='".get_bloginfo('description')."' />\r\n"; // add meta tag to <head>
    }
}
add_action('wp_head','excerpt_to_description'); // add excerpt_to_description to wp_head function

//Optimize Database
function optimize_database(){
    global $wpdb; // get access to $wpdb object
    $all_tables = $wpdb->get_results('SHOW TABLES',ARRAY_A); // get all table names
    foreach ($all_tables as $tables){ // loop through every table name
        $table = array_values($tables); // get table name out of array
        $wpdb->query("OPTIMIZE TABLE ".$table[0]); // run the optimize SQL command on the table
    }
}
function simple_optimization_cron_on(){
    wp_schedule_event(time(), 'daily', 'optimize_database'); // rdd optimize_database to wp cron events
}
function simple_optimization_cron_off(){
    wp_clear_scheduled_hook('optimize_database'); // remove optimize_database from wp cron events
}
register_activation_hook(__FILE__,'simple_optimization_cron_on'); // run simple_optimization_cron_on at plugin activation
register_deactivation_hook(__FILE__,'simple_optimization_cron_off'); // run simple_optimization_cron_off at plugin deactivation
?>
  • Permalink for 'HTML5 Globals and You'

    HTML5 Globals and You

    Posted: May 31st, 2010, 9:49am MDT by John Cox


    Much has been written on the big ticket changes in HTML5, like forms, semantics, and media, but information on the less splashy changes is sparse. While global attributes aren’t the most sexy change of HTML5, they are the change that you will be using over and over and over as you migrate to the new specification.

    Introduction: What is a Global Attribute?

    While the term attribute relating to HTML might be a bit fuzzy to you, you certainly use them with almost every element that you write. HTML attributes give elements meaning. They also give context. They are both the adjective and verb for an element, if you think of the element as the noun. For instance:

        <div></div>
    

    Doesn’t really have much meaning. It’s a division of the page, and that’s it. When we add an attribute though, it does have meaning:

        <div id="foo" class="bar" style="color: red" title="FooBar To The Rescue"  dir="rtl" lang="en-US" tabindex="1" accesskey="F"></div>
    

    We now have a division that is “Foo” with a class of “Bar”, which has a color of red, a title of “FooBar to the Rescue”, is displayed right to left, is to be read in US English, and when you press the tab button or “F”, it’s the first element to have focus. It’s basic, I know. The attributes are all those things that give elements meaning. The difference in HTML 5 from previous versions of the specification is there are attributes that can be used on any HTML element. These are now global attributes. Beyond the ones illustrated in the example above, there are some new ones that are global as well which will expand the possibilities beyond just boring peanut butter.

    “HTML attributes give elements meaning. They also give context. They are both the adjective and verb for an element, if you think of the element as the noun.”

    Common Attributes: Which Ones Are Now Global?

    This is a relatively minor change in HTML 5. The attributes id, class, style, title, dir, lang, accesskey and tabindex are now valid attributes to have on any HTML element. You want to give a meta tag an id, that’s valid now. It’s even valid to give that same meta element a direction, language, class or any global attribute for that matter. While they might not have meaning at first blush, it’s perfectly valid to define them in any tag that you feel necessary.

        <meta name="description" content="FooBar, making me feel like it is actually FUBAR." id="foo" class="bar" style="color: red" title="FooBar To The Rescue"  dir="rtl" lang="en-US" tabindex="1" accesskey="F">
    

    The above example is perfectly valid in HTML5. That said, where there is no reason to use an attribute, and it looks silly, perhaps the best course of action is to not use that global attribute. A tabindex on a head element might not be the best use of time and energy. The important part to understand is not the odd case of putting a global attribute in something that doesn’t quite make sense, but rather the fact that they are available in any element.

    Each of these was common attributes in the past, and while their use were restricted somewhat in the past, you probably already thought of them as global. I actually had to look up id, because I couldn’t think of an element that you couldn’t use it (base, head, html, meta, script, style, title). The old common attributes are just half of the new global attributes though.

    Edit Inline: The Contenteditable and Spellcheck Attributes

    The first of the new attributes to look at are contenteditable and spellcheck. They are not mutually exclusive and you can use one without the other, but for the purposes of illustration, it makes sense to look at them at the same time. Both of these attributes do what their names imply; they allow an element to be editable (contenteditable) or allows / disallows spellcheck on content. Let’s start with contenteditable:

    Let’s look at number handling first:

        <article id="id">
            <p>You can not edit this paragraph.  I am happy, and and just sit here with no regrets.</p>
            <p contenteditable="true">This paragraph you can edit.</p>
        </article>
    

    In this snippet, we have one paragraph which is not editable, and one that is. When you click on the non-editable paragraph, it works as you would expect by highlighting a word, etc:

    However, when you click in the editable portion a whole new world opens:

    The paragraph now becomes editable simply by adding the contenteditable attribute. It gets even cooler when we start using the contenteditable with multiple elements. Let’s look at a larger snippet and see what happens.

        <article id="edit_test"  contenteditable="true">
            <header>
                <hgroup>
                    <h1>Let's See What Happens</h1>
                    <h3>Does every element become editable?</h3>
                </hgroup>
            </header>
            <p>You can edit this paragraph now.</p>
            <p>You can edit this paragraph as well.</p>
        </article>
    

    We start with something that looks like this:

    When we focus the article element though, we have the entire span editable:

    Furthermore, we can style the box (for lack of better term) using the CSS3 pseudo class of :focus

        #edit_test:focus { background: #eee; padding: 1%; }
    

    and it will look something like this:

    >

    Final notes about contenteditable: there are three basic conditions that it takes: true, false, inherit. You can nest contenteditable conditions with nested tags. For instance, if we do something like:

        <article id="edit_test"  contenteditable="true">
            <header>
                <hgroup contenteditable="false">
                    <h1>Let's See What Happens</h1>
                    <h3>Does every element become editable?</h3>
                </hgroup>
            </header>
            <p>You can edit this paragraph now.</p>
            <p>You can edit this paragraph as well.</p>
        </article>
    

    We would be able to edit the paragraphs in the article, but not the header group. Since this is a global attribute, you could theoretically add contenteditable to your body element, and then pick and chose the elements which are not editable in the document.

    The spellcheck attribute goes along with the contenteditable, but it also can be used where your user might interact with your document, for instance, with forms. The spellcheck attribute is assumed on, unless you say otherwise:

        <article id="edit_test">
            <header>
                <hgroup>
                    <h1>Let's See What Happens</h1>
                    <h3>Does spellcheck work?</h3>
                </hgroup>
            </header>
            <p spellcheck="false" contenteditable="true">Spell check off.</p>
            <p spellcheck="true" contenteditable="true">Spell check is on.</p>
        </article>
    

    As you can see, when we have the spellcheck set to false, we do not get an indication of a misspelled word, but with it set to true, we do. It’s a very simple, but helpful functionality. From my tests, browser implementation is a bit raw, but it does work now.

    Adding Behavior: The Hidden Attribute

    Another new global attribute is hidden. It basically does the same job as “display: hidden” does with CSS, but within an element. The advantage to this, it gives a semantical meaning to the element that it is not relevant at this moment in time. Therefore, screen readers, etc., would not mention the element in the hidden state when it would with a style of “display: hidden,” since that is dealing with its presentation. It is a boolean attribute, therefore, false is the assumed state and you only need to add the attribute name to the element that you wish to hide.

        <article id="hide_test">
            <header>
                <hgroup>
                    <h1>Let's See What Happens</h1>
                    <h3>Can we hide elements?</h3>
                </hgroup>
            </header>
            <p>We can see this paragraph</p>
            <p hidden>We can't see this paragraph</p>
        </article>
    
    Dragging Elements: The Draggable Attribute

    HTML5 implements a new “Drag and Drop” API. While the specifics of the API are a bit out of the scope of this tutorial, the attribute to allow something to be dragged is not. Any element that has draggable set to true, can be dragged:

        <article id="drag_test">
            <header>
                <hgroup>
                    <h1>Let's See What Happens</h1>
                    <h3>Can we drag elements?</h3>
                </hgroup>
            </header>
            <p draggable="true">We can drag this paragraph.</p>
            <p draggable="false">We can't drag this paragraph</p>
        </article>
    

    Without any JavaScript, you can see the difference in browsers that support draggable. When set to false, if you mousedown over the element it will begin to highlight the text; however, when set to true it does not. In Chrome you get the drag icon, whereas in Firefox you just don’t get the highlight of the element. Either way, the browsers are trying to do something with these elements.

    Saving Space With Menus: The contextmenu Attribute

    The contextmenu attribute allows you to display a menu without taking up valuable UI space for the menu. It is a menu which fires on events, such as mouseup or keyup providing a bubble menu which provides options and actions based on those selections.

        <article id="contextmenu_test">
            <header>
                <hgroup>
                    <h1>Let's See What Happens</h1>
                    <h3>Can we give a context menu?</h3>
                </hgroup>
            </header>
            <p contextmenu="foo">This paragraph has a context menu called "foo" attached.</p>
        </article>
        <menu id="foo">
            <command label="Step 1: Write Tutorial" onclick="doSomething();">
            <command label="Step 2: Edit Tutorial" onclick="doSomethingElse();">
            <command label="Step 3: ..." onclick="youGetTheDrift();">
        </menu>
    

    In this example, there are a few more things going on with contextmenu that are new. For instance, a menu must be defined, so that the contextmenu knows where to point. In the example above, we are saying, when there is a mouse event (depending on browser implementation), go out and find the menu “foo” in the DOM, and display its commands. The syntax is relatively simple after that. We have a menu label which will display the attribute text, and we have an onclick event which will do whatever we have defined.

    The Catch-All: The data-* Attribute

    When you add ambiguity to a specification, it tends to be misused, when there are better options available.

    I have saved the most controversial global attribute for last. I have mixed feelings with this new one. On one hand, I am looking forward to the ability to connect my logic layer with my behavior layer without going through too many hoops, or using attributes and elements outside of their design specs. On the other hand, I know that when you add ambiguity to a specification, it tends to be overused and misused when there are better options available.

    What this attribute is, is a catch-all. Basically, the specification is stating that we can not ever think of all of the use-cases for attributes, therefore we will leave you to your own to make them up. The logic in me feels a specification should give us a set of rules to play with, and leave it at that, but the innovator in me loves having the power to define new attributes. I just know from experience when there is a chance to do something not quite right, but easier, that path generally bites you in the behind. All that said, let’s keep it positive and look at a couple of possible cases.

    I think this attribute will be a wonderful addition for microformats, and might be the thing that puts them in the forefront of development. I can also see some uses where on the backend, I want to provide some bread crumbs to my behaivor layer in JavaScript to close some gaps. Another idea where you might use this attribute is to provide a location for where you are when you post an article. That might look something like this:

        <article id="data_test" data-latitude="38.254" data-longitude="85.72">
            <header>
                <hgroup>
                    <h1>Post From Louisville, KY</h1>
                    <h3>Waterfront Park Concert</h3>
                </hgroup>
            </header>
            <p>I've just attached a post from Waterfront Park in Louisville, KY.</p>
        </article>
    

    I can now take those data-* attributes and do something via JavaScript or another API, such as post a map, from attributes from my application layer. It ends up opening a ton of possibilities, but don’t forget the immortal words of Ben Parker: “With great power, comes great responsibility.”

    Conclusion

    Like most things in HTML5 at the moment, the browser support for these changes are spotty at best. Some new attributes are supported. some are incorrectly implemented, some have no support at all at the moment! That said, they all appear to degrade nicely without much hoopla involved, so there isn’t a compelling case to not begin experimenting and implementing. The specification changes are slowing, so more than likely, what you see is what you will get…at some point. Thanks for reading!

  • Permalink for 'Quick Tip: The Multi-Column CSS3 Module'

    Quick Tip: The Multi-Column CSS3 Module

    Posted: May 28th, 2010, 11:45am MDT by Jeffrey Way


    For over six years, CSS3 columns have been available to us; yet, strangely, they’re rarely utilized. Because they currently are only supported in Mozilla and Webkit-based browsers, this means that – again – no support in Internet Explorer. But that’s okay! The world will not end if IE users see one longer paragraph. I’ll show you how to use this helpful module in today’s video quick tip.


    Subscribe to our YouTube page to watch all of the video tutorials!

    Prefer to watch this video on Screenr?

    Final Product
    #container p {
    	-webkit-column-count: 3;
    	-webkit-column-gap: 10px;
    
    	-moz-column-count: 3;
    	-moz-column-gap: 10px;
    
    	column-count: 3;
    	column-gap: 10px;
    }
    
    • column-count: The desired number of columns for the element.
    • column-gap: The padding between each column.
    • column-rule: The divider for each column; can be used to specify a border.
    • column-width: Used to specifically state the width of each column.

    Please note that we must prefix each property with the -webkit or -moz, accordingly; so: -webkit-column-count.

    Do you use CSS columns in your projects? If no, why not?

  • Permalink for 'Magento for Designers: Part 4'

    Magento for Designers: Part 4

    Posted: May 28th, 2010, 10:13am MDT by Siddharth


    Magento is a stunningly powerful e-commerce platform. In this miniseries, we’ll learn how to get started with the platform, getting to know the terminologies, setting up a store and all related aspects of it and finally learn how to customize it to make it our very own.

    In this fourth part, we’ll lay the groundwork for our theme which we’ll be building completely from scratch. Excited? Let’s get started!

    The Full Series A Quick Recap

    In the last parts, we learned how to get your Magento store from installed to ready for deployment including how to set up your products, product categories, taxes, shipping, payment gateways and many more.

    We also took a look at the basics of Magento theming. We learnt the general idea behind Magento themes, the various terminologies behind it and the basic structure of a theme.

    Goals for our Theme

    Our goal for building this theme is fairly straightforward: to practically understand how to build a Magento theme. With that in mind, I’m going to keep the theme as simple as possible.

    • Everything but the bare essential features stripped out
    • No images other than the product images and the logo
    • Single column to keep it visually simple
    What are We Building Today?

    Since the Magento coding process is reasonably complicated for someone used to WordPress, we’re going to take it extremely slow. Today, we’ll build just the core part our theme, the skeleton that gets used in each view of the site. I’ll also explain the general principle behind the process so we can move on to each individual view in future parts.

    The source files, both the front end and back end, are included but try to not use it just yet. We’ll be defining just the core parts without defining what content is to be displayed, how it should be displayed and where the content is to be pulled from. So, if you try to use this right now, you’re going to see a bunch of gibberish since Magento pulls in all absent files from its default theme thus completely ruining our look. So my advice is, wait for a bit.

    The Basic Template

    The basic template looks like so. We have a generic logo up top along with a simple menu which lets the user access his account, wish list and cart along with letting him checkout or logout.

    Below that, we have a utility bar that contains a breadcrumb style navigation to let the user know the contextual hierarchy of the site. We also let the user search through our store through the search input on the right.

    The content area is currently empty since its contents will vary depending on which view Magento is loading. So we’ll keep is empty for now and handle it later when we’re building each individual page.

    The footer is fairly generic with a link to report bugs and copyright information.

    Step 1 – The HTML

    We’ll first look at the HTML for the theme’s skeleton. I’m assuming you’re fairly fluent in HTML and CSS so I’ll skip to the more important parts.

    <!-- Lumos! )  -->
    <!DOCTYPE html>
    <html lang="en-GB">
    <head>
    <title>Cirrus - Magento Theme</title>
    <link rel="stylesheet" href="css/cirrus.css" />
    </head>
    
    <body>
    <div id="wrapper" class="border">
    
    <div id="header">
    <div id="logo"><img src="images/logo.gif" /></div>
    <div id="hud">
    <h3>Welcome, Sid</h3>
    <ul class="links">
                <li><a href="#" title="My Account">My Account</a></li>
                <li ><a href="#" title="My Wish list">My Wish list</a></li>
                <li ><a href="#" title="My Cart">My Cart</a></li>
                <li ><a href="#" title="Checkout">Checkout</a></li>
                <li><a href="#" title="Log Out" >Log Out</a></li>
        </ul>
    </div>
    </div>
    
    <div id="utilities">
    <div id="breadcrumbs">Home » State of Fear</div>
    <div id="header-search"><input type="text" class="border" value="Search our store" /></div>
    </div>
    
    <div id="content" class="product">
    <h1>Content here</h1>
    </div>
    
    <div id="footer" class="border">
    Help Us to Keep Magento Healthy - Report All Bugs (ver. 1.4.0.1)
    © 2008 Magento Demo Store. All Rights Reserved.
    </div>
    
    </div>
    </body>
    </html>
    

    First up, note that I’ve wrapped everything under a wrapper div to make it easier to manage things. Also note that the header, content and footer section get their individual blocks.

    The search input is fairly useless at this point. We’ll hook it up properly during when we’re integrating with Magento. Same with the various links. Currently, I’ve put them there as placeholders. Once we dig into Magento, we’ll get them working.

    Step 2 – The CSS
    * {
    	margin: 0;
    	padding: 0;
    	border: none;
    	outline: none;
    	color: #333;
    	font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
    	font-size: 14px;
    	list-style: none;
    	line-height: 1.3em;
    }
    
    a {
    	color : #7db000;
    }
    
    h1, h2, h3, h4 {
    	font-weight: normal;
    }
    
    h1 {
    	font-size: 32px;
    	margin-bottom: 10px;
    }
    
    h2 {
    	font-size: 24px;
    	margin: 10px 0 12px 0;
    }
    
    h3 {
    	font-size: 20px;
    	margin-bottom: 5px;
    }
    
    h4 {
    	font-size: 20px;
    }
    
    .border {
    	border: 1px solid #666;
    }
    
    /* Base Elements */
    
    #wrapper {
    	width: 920px;
    	margin: 10px auto;
    	padding: 20px;
    }
    
    #header {
    	margin: 0 0 20px 0;
    	overflow: auto;
    }
    
    #content {
    	margin: 20px 0;
    	overflow: auto;
    }
    
    #footer {
    	padding: 10px;
    	border: 1px solid #E1E1E1;
    	background: #F3F3F3;
    	text-align: center;
    }
    
    /* Header content */
    
    #logo {
    	float: left;
    }
    
    #hud {
    	float: right;
    	width: 320px;
    	height: 50px;
    	padding: 10px;
    	border: 1px solid #E1E1E1;
    	background: #F3F3F3;
    }
    
    #hud li a {
    	float: left;
    	font-size: 12px;
    	margin: 0 10px 0 0;
    }
    
    #utilities {
    	clear: both;
    	margin: 20px 0;
    	overflow: auto;
    	padding: 7px 10px;
    	border: 1px solid #E1E1E1;
    	background: #F3F3F3;
    }
    
    #breadcrumbs {
    	float: left;
    }
    
    #header-search {
    	float: right;
    }
    

    Nothing fancy here. Very basic CSS to place the elements in position and style it just a tiny bit. Let’s move on.

    Step 3 – Creating our page.xml File

    This part is a little tricky so stay with me here. Magento uses XML files to handle a page’s layout and also to define which elements are available to be rendered. The aim is that instead of mucking around with arcane code, you can just edit the XML file and be done with it without worrying about dependencies.

    Each view/screen/module gets its own XML file along with a master file to define the general layout of the site. That master file is the page.xml file we’re going to create now.

    The complete file for today looks like so. I’ll explain each bit part by part below.

    <?xml version="1.0"?>
    <layout version="0.1.0">
        <default translate="label" module="page">
            <label>All Pages</label>
            <block type="page/html" name="root" output="toHtml" template="page/1column.phtml">
    		<block type="page/html_head" name="head" as="head">
                    <action method="addCss"><stylesheet>css/cirrus.css</stylesheet></action>
                </block>
    
                <block type="page/html_header" name="header" as="header">
    				<block type="page/template_links" name="top.links" as="topLinks"/>
    				<block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
                    <block type="core/template" name="top.search" as="topSearch"/>
                </block>
    
                <block type="core/text_list" name="content" as="content"/>
    
                <block type="page/html_footer" name="footer" as="footer" template="page/html/footer.phtml"/>
            </block>
        </default>
    </layout>
    

    Disregard the initial XML and layout version declarations. They’re of no significance to us now.

    <block type="page/html" name="root" output="toHtml" template="page/1column.phtml">
    

    First, we create a master block for all the data. Consider this the equivalent of the wrapper DIV element we used in our HTML. Next, we instruct it to use page/1column.phtml as the template for our page. Don’t worry, we haven’t created the file yet. We’ll do so later in this tutorial.

    <block type="page/html_head" name="head" as="head">
           <action method="addCss"><stylesheet>css/cirrus.css</stylesheet></action>
    </block>
    

    Next, we define the elements to be included in the head section of the page. Magento, by default, includes a load of CSS and JS files but we won’t be requiring any of their functionality today. So, we’ll just include our CSS file.

    <block type="page/html_header" name="header" as="header">
    				<block type="page/template_links" name="top.links" as="topLinks"/>
    				<block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
                    <block type="core/template" name="top.search" as="topSearch"/>
                </block>
    

    We’re defining what goes into the header of our site. We want the menu/links at the top as well as the breadcrumbs and the search.

    <block type="core/text_list" name="content" as="content"/>
    

    We’ll need the content part, of course, so we’re including the content part. We won’t define anything about this section here since Magento just loads up all the necessary content into this block.

    <block type="page/html_footer" name="footer" as="footer" template="page/html/footer.phtml"/>
    

    And finally, we’ve included our footer. We also tell Magento where to load its template from.

    You’re probably wondering why we specify a template path for some blocks whilst omitting it for others. It’s a rather higher level topic but did you note that each block has a type attribute? When it’s type matches one of those predefined by Magento, you need not specify a template. It’s auto loaded. Nifty, no?

    And with this, our base page.xml file is complete.

    Step 4 – Creating our Skeleton Template

    Ok, now that we’ve specified our layout we can move on to creating the 1column.phtml file that we specified in the XML earlier.

    This file is nothing but a skeleton template which calls in the header, content area and footer as needed. Our file looks like so:

    <!-- Lumos! )  -->
    <!DOCTYPE html>
    <html lang="en-GB">
    <head>
    <?php echo $this->getChildHtml('head') ?>
    </head>
    
    <body>
    <div id="wrapper" class="border">
    
    <?php echo $this->getChildHtml('header') ?>
    
    <div id="content" class="product">
    <?php echo $this->getChildHtml('content') ?>
    </div>
    
    <?php echo $this->getChildHtml('footer') ?>
    
    </div>
    </body>
    </html>
    

    This is pretty much our original HTML file except that we use the getChildHtml method to acquire each block’s content. The template needs to be pretty page agnostic as it’s the master page from which each page is rendered.

    Step 5 – Creating the Templates for our Blocks

    Now comes the slightly hard part: cutting up our core HTML blocks by functionality, creating the required templates files for each functionality and then populating those files.

    We’ll tackle each in order of appearance

    head Section

    getChildHtml(‘head’) maps directly to page/html/head.phtml. Our file looks like so:

    <title><?php echo $this->getTitle() ?></title>
    <link rel="icon" href="<?php echo $this->getSkinUrl('favicon.ico') ?>" type="image/x-icon" />
    <link rel="shortcut icon" href="<?php echo $this->getSkinUrl('favicon.ico') ?>" type="image/x-icon" />
    <?php echo $this->getCssJsHtml() ?>
    <?php echo $this->getChildHtml() ?>
    <?php echo $this->getIncludes() ?>
    

    You’ll see that we let Magento dynamically create the titles. Other than that, do notice the getCssJsHtml method being called. This method imports all the CSS and JS files that we specified in the page.xml file.

    Page Header

    getChildHtml(‘header’) maps directly to page/html/header.phtml. Our file looks like so:

    <div id="header">
    <div id="logo"><a href="<?php echo $this->getUrl('') ?>" title="<?php echo $this->getLogoAlt() ?>" class="logo"><img src="<?php echo $this->getLogoSrc() ?>" alt="<?php echo $this->getLogoAlt() ?>" /></a></div>
    <div id="hud">
    <h3>Welcome</h3>
    <?php echo $this->getChildHtml('topLinks') ?>
    </div>
    </div>
    
    <div id="utilities">
    <?php echo $this->getChildHtml('breadcrumbs') ?>
    <?php echo $this->getChildHtml('topSearch') ?>
    </div>
    

    We use Magento’s API to acquire the logo first. Then to further modularize things, we get the HTML for the breadcrumbs, links and the search function.

    Note that the name is purely semantic. As you can see, you’re not limited to the header in it’s purest, strict technical sense. You can also tack on other elements as needed.

    Page Footer

    getChildHtml(‘footer’) maps directly to page/html/footer.phtml as specified in the XML file. Our file looks like so:

    <div id="footer" class="border">
    <?php echo $this->__('Help Us to Keep Magento Healthy') ?> - <a href="http://www.magentocommerce.com/bug-tracking"
    onclick="this.target='_blank'"><strong><?php echo $this->__('Report All Bugs') ?></strong></a>
    <?php echo $this->__('(ver. %s)', Mage::getVersion()) ?> <?php echo $this->getCopyright() ?></address>
    </div>
    

    With the footer, you’re free to include any info you deem fit. I just included the default content since I couldn’t think of anything clever to say there.

    With the core elements finished, we can move on to the smaller functional blocks specified in the header section now i.e. the breadcrumbs, links and the search feature.

    Top Links

    getChildHtml(‘topLinks’) maps directly to page/html/template/links.phtml. Our file looks like so:

    <?php $_links = $this->getLinks(); ?>
    <?php if(count($_links)>0): ?>
    <ul class="links"<?php if($this->getName()): ?> id="<?php echo $this->getName() ?>"<?php endif;?>>
        <?php foreach($_links as $_link): ?>
            <li<?php if($_link->getIsFirst()||$_link->getIsLast()): ?> class="<?php if($_link->getIsFirst()): ?>first<?php endif; ?><?php if($_link->getIsLast()): ?> last<?php endif; ?>"<?php endif; ?> <?php echo $_link->getLiParams() ?>><?php echo $_link->getBeforeText() ?><a href="<?php echo $_link->getUrl() ?>" title="<?php echo $_link->getTitle() ?>" <?php echo $_link->getAParams() ?>><?php echo $_link->getLabel() ?></a> <?php echo $_link->getAfterText() ?></li>
        <?php endforeach; ?>
    </ul>
    <?php endif; ?>
    

    I know it looks a little complicated, but all it does is loop through an array of links and then spit it out, whilst adding a special class if it’s the first or last item in the list. If you’d prefer, you can scrap all this, and just hard code your top menu.

    Breadcrumbs

    getChildHtml(‘breadcrumbs’) maps directly to page/html/breadcrumbs.phtml. Our file looks like so:

    <?php if($crumbs && is_array($crumbs)): ?>
    <div id="breadcrumbs">
            <?php foreach($crumbs as $_crumbName=>$_crumbInfo): ?>
                <?php if($_crumbInfo['link']): ?>
                    <a href="<?php echo $_crumbInfo['link'] ?>" title="<?php echo $this->htmlEscape($_crumbInfo['title']) ?>"><?php echo $this->htmlEscape($_crumbInfo['label']) ?></a>
                <?php elseif($_crumbInfo['last']): ?>
                    <strong><?php echo $this->htmlEscape($_crumbInfo['label']) ?></strong>
                <?php else: ?>
                    <?php echo $this->htmlEscape($_crumbInfo['label']) ?>
                <?php endif; ?>
                <?php if(!$_crumbInfo['last']): ?>
                    <span>» </span>
                <?php endif; ?>
            <?php endforeach; ?>
    </div>
    <?php endif; ?>
    

    As with before, it merely loops through the crumbs to render the text. The naughty bits in there checks whether the crumb is a link, to format it as such, and check whether it’s the final element so it doesn’t have to render a separator. There’s nothing else to this block.

    Search

    getChildHtml(‘topSearch’) maps directly to catalogsearch/form.mini.phtml. Our file looks like so:

    <div id="header-search">
    		<form id="search_mini_form" action="<?php echo $this->helper('catalogsearch')->getResultUrl() ?>" method="get">
            <input id="search" type="text" name="<?php echo $this->helper('catalogsearch')->getQueryParamName() ?>" value="<?php echo $this->helper('catalogsearch')->getEscapedQueryText() ?>" class="input-text border" />
    
    </form>
    </div>
    

    Magento does all the weight lifting here. All you need to do is call the proper API method for the URLs and such.

    If you’ve noticed that the string passed on to the getChildHtml method maps directly to the as attribute used in the page.xml file, then congrats, you’re an astute reader and you get a delicious cookie!

    What We’ll be Building in the Next Part

    Now that we’ve built a very strong core, we can now move on to building the individual views of the store. In the next part, we’re going to build one of the core views of any store, the product view. Stay tuned!

    The Last Word

    And we are done! Today, we took the first step in creating our custom Magento theme, Cirrus. Hopefully this has been useful to you and you found it interesting. Since this is a rather new topic for a lot of readers, I’ll be closely watching the comments section so chime in there if you’re having any doubts.

    Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!

  • Permalink for 'Rock-Solid WordPress 3.0 Themes using Custom Post Types'

    Rock-Solid WordPress 3.0 Themes using Custom Post Types

    Posted: May 27th, 2010, 10:18am MDT by Joe Casabona


    The WordPress community is buzzing with excitement over the soon-to-be-released WordPress 3.0. Currently in Beta 2 now, WordPress 3.0 will have a lot of exciting new features , such as a new default theme and better menu management. Quite possibly the most exciting of these features is custom post types. In this tutorial, we’ll talk about creating and using custom post types to make a rock-solid theme.

    What is a Custom Post Type?

    Well, according to the WordPress Codex:

    “Post type refers to the various structured data that is maintained in the WordPress posts table. Custom post types allow users to easily create and manage such things as portfolios, projects, video libraries, podcasts, quotes, chats, and whatever a user or developer can imagine.”

    Essentially, it allows us developers to make new kinds of posts similar to the post and page types, which all appear in the main navigation in the WordPress admin. There are several advantages to this; most notably, we no longer need plugins to create special types, we can build a theme that relies less on custom fields (as we know them), and they make managing the site easier for clients and non-technical users. Instead of telling them to create a “post” and make sure to fill in all kinds of custom fields for say, music, we can simply tell them to click “Music” to add a new music post.

    Let’s Get Started!

    In this tutorial we will:

    • Create a Custom Post Type for Products with our own inputs
    • Create a custom “taxonomy” for the type.
    • Create a theme template to go along with the new type.
    Register the Custom Post Type

    All of this will be done from within our theme’s functions.php file. I’m modifying the default 3.0 theme, TwentyTen.

    The first thing we will do is tell WordPress that we want to register a new custom type. Here’s the code:

    	add_action('init', 'product_register');
    
    	function product_register() {
        	$args = array(
            	'label' => __('Products'),
            	'singular_label' => __('Product'),
            	'public' => true,
            	'show_ui' => true,
            	'capability_type' => 'post',
            	'hierarchical' => false,
            	'rewrite' => true,
            	'supports' => array('title', 'editor', 'thumbnail')
            );
    
        	register_post_type( 'product' , $args );
    	}
    

    The first line is a hook to tell WordPress that we want to call the function product_register() during initialization. It’s in that function that we register the new post type.

    The function register_post_type() accepts two arguments: the name we want to give our post type, and a list of arguments used to create that post type, which we put in an array called $args. You can read exactly what all of the arguments are here, but I want to point out the important ones.

    • label & singular_label: These are the labels as we want them to appear in the WordPress admin. ‘label’ will show up in the admin nav and anywhere that references multiple entries of that type (Edit Products, for example). ’singular_label’ will show up when one of that type is referenced (Add Product, for example).
    • capability_type: This tells WordPress which native type (post, page, attachment, revision, or nav-menu-item) the custom type will behave as. By making it a ‘post’ type, we can do things like add it to a category.
    • rewrite: Tell WordPress if (or how) to apply permalinks formatting. You can send a boolean as we did, or any array of arguments to apply a custom permalink format to the type.
    • supports: This is everything on the add/edit page that will show up. We want to have a title, editor(the content), and thumbnail images. Next, we will add our own custom inputs by cleverly masking custom fields as input fields for our custom type.
    Adding Our Own Inputs

    Let’s add our own custom inputs for our new type. Since we can now create new post types, we can make the custom fields more streamlined for users that might not be as familiar with WordPress as we are. It’s worth noting here that this functionality has been available since 2.5 and up until this point, has been used primarily by plugin developers. Here we are going to add a price field.

    <?php
    	add_action("admin_init", "admin_init");
    	add_action('save_post', 'save_price');
    
    	function admin_init(){
    		add_meta_box("prodInfo-meta", "Product Options", "meta_options", "product", "side", "low");
    	}
    
    	function meta_options(){
    		global $post;
    		$custom = get_post_custom($post->ID);
    		$price = $custom["price"][0];
    ?>
    	<label>Price:</label><input name="price" value="<?php echo $price; ?>" />
    <?php
    	}
    
    function save_price(){
    	global $post;
    	update_post_meta($post->ID, "price", $_POST["price"]);
    }
    ?>
    

    Once again, the first couple of lines are hooks to tell WordPress when we want to use certain functions. The first line says that when the admin panel is initialized, call the function that we wrote, admin_init(). This function tells WordPress to add an area called “Product Options” to any posts of type ‘product’, and to use the function meta_options() to print the form fields. You can read more about add_meta_box here. meta_options() will then get any preexisting custom values and print the form field. The second action line states that when a post is saved, call our function save_price(), which uses update_post_meta() to add or update a custom field called ‘price’.

    Custom Categories and Edit Columns

    Our last step in creating a completely custom type is giving unique names to its category and edit column labels. First, the custom category name, or ‘taxonomy’.

    register_taxonomy("catalog", array("product"), array("hierarchical" => true, "label" => "Catalogs", "singular_label" => "Catalog", "rewrite" => true));
    

    The function we use is register_taxonomy(), which you can find in the codex here; it has been available since 2.8. It’s essentially saying that we want to create a new category type called ‘catalog’ which we will associate with the ‘product’ type. The last argument is an array of information similar to what we saw the register_post_type() function. When all is said and done, we will have the term ‘Catalog’ appear beneath our Products menu in the WordPress admin and it will behave like Post Categories do.

    Next, we want to create a custom set of columns for our Product type.

    add_filter("manage_edit-product_columns", "prod_edit_columns");
    add_action("manage_posts_custom_column",  "prod_custom_columns");
    
    function prod_edit_columns($columns){
    		$columns = array(
    			"cb" => "<input type=\"checkbox\" />",
    			"title" => "Product Title",
    			"description" => "Description",
    			"price" => "Price",
    			"catalog" => "Catalog",
    		);
    
    		return $columns;
    }
    
    function prod_custom_columns($column){
    		global $post;
    		switch ($column)
    		{
    			case "description":
    				the_excerpt();
    				break;
    			case "price":
    				$custom = get_post_custom();
    				echo $custom["price"][0];
    				break;
    			case "catalog":
    				echo get_the_term_list($post->ID, 'catalog', '', ', ','');
    				break;
    		}
    }
    

    The first two lines are hooks to tell WordPress that we want custom columns for the ‘product’ type. The first line says that when printing columns for the product type, use the ones defined in the function prod_edit_columns().

    In prod_edit_columns(), we have a key-value array where the keys are used to reference certain post information, which we define in the second function, prod_custom_columns(). The values in that array are the column headings. You might notice that prod_edit_columns() lists five columns, but we only describe display information for three in prod_custom_columns(). ‘cb’ and ‘title’ are part of a set of default keys that WordPress already has associations for. WordPress doesn’t know what the other three are, so it’s up to us to define them.

    Making the Theme Template

    Not too shabby, right? And now we are finally up to the fun part- the theme template. To make a theme template for a custom post type, we simply name the template single-<post-type-slug>.php and add it to our theme. In our case, this would be single-product.php. Here I will show you a snippet of that page that displays all of the information we’ve added to our custom post type:

    <?php the_post(); ?>
    
    <?php
    	$custom = get_post_custom($post->ID);
    	$price = "$". $custom["price"][0];
    
    ?>
    
    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <h1 class="entry-title"><?php the_title(); ?> - <?=$price?></h1>
    
    <div class="entry-meta">
    
    	<div class="entry-content">
    		<?php the_post_thumbnail(); ?>
    		<?php the_content(); ?>
    	</div>
    </div>
    

    I’ve added this code to the Twentyten theme in WordPress 3.0 Beta, as it’s the only theme that supports the new functionality- namely the menu system. I copied the single.php template, renamed it single-product.php and replaced everything in the ‘content’ div with the code above. To test my code, I went to Themes->Menus and added our new type to my site’s navigation. Then, I clicked through to our custom post type.

    Wrapping Up

    As I said previously, WordPress 3.0 is still in beta (you can get it here); so there are still some bugs to work out and some things may change in the final version. The best thing you can do is get in there and play with some of the new features to familiarize yourself with the updates/changes. From what I’ve seen so far, things are looking pretty good!

  • Permalink for '2 New Premium Tutorials: Refinery and Modernizr'

    2 New Premium Tutorials: Refinery and Modernizr

    Posted: May 26th, 2010, 2:43pm MDT by Jeffrey Way


    This week, we have two excellent new Net Premium tutorials for our members. First, Glenn Goodrich will teach you how to work with Refinery – a Rails CMS. Next, I’ll teach you how to detect CSS3 and HTML5 support in browsers, by using the wonderful Modernizr library. Help give back to Nettuts+ by signing up for a Premium membership.

    Getting Started with Refinery: A Rails CMS

    Refinery is an open-source, Rails-based CMS that really attempts to use “the Rails Way” for content management. Anyone familiar with Rails will be able to pick up Refinery and be productive almost instantly. The folks over at Resolve Digital created Refinery to scratch their own itch, and then were kind enough to release it on GitHub (MIT License). Refinery has a growing set of users and developers, making it ideal if you’re just starting out with Rails-base content management systems. I’ll teach you how to get started with it!

    A Video Crash-Course in Modernizr

    It’s a common misconception that the JavaScript library, Modernizr, miraculously upgrades all browsers to allow for HTML5 and CSS3 support. Unfortunately, this isn’t the case. However, instead, it detects support, which provides us with a lot of power! I’ll show you how to get started today!

    Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Join today!

  • Permalink for 'Why you Should be using PHP’s PDO for Database Access'

    Why you Should be using PHP’s PDO for Database Access

    Posted: May 26th, 2010, 10:04am MDT by Erik Wurzer


    Many PHP programmers learned how to access databases by using either the mysql or mysqli extensions. Since PHP 5.1, there’s been a better way. PHP Data Objects (PDO) provide methods for prepared statements and working with objects that will make you far more productive!

    PDO Introduction

    “PDO – PHP Data Objects – is a database access layer providing a uniform method of access to multiple databases.”

    It doesn’t account for database-specific syntax, but can allow for the process of switching databases and platforms to be fairly painless, simply by switching the connection string in many instances.

    PDO - db abstraction layer

    This tutorial isn’t meant to be a complete how-to on SQL. It’s written primarily for people currently using the mysql or mysqli extension to help them make the jump to the more portable and powerful PDO.

    Database Support

    The extension can support any database that a PDO driver has been written for. At the time of this writing, the following database drivers are available:

    • PDO_DBLIB ( FreeTDS / Microsoft SQL Server / Sybase )
    • PDO_FIREBIRD ( Firebird/Interbase 6 )
    • PDO_IBM ( IBM DB2 )
    • PDO_INFORMIX ( IBM Informix Dynamic Server )
    • PDO_MYSQL ( MySQL 3.x/4.x/5.x )
    • PDO_OCI ( Oracle Call Interface )
    • PDO_ODBC ( ODBC v3 (IBM DB2, unixODBC and win32 ODBC) )
    • PDO_PGSQL ( PostgreSQL )
    • PDO_SQLITE ( SQLite 3 and SQLite 2 )
    • PDO_4D ( 4D )

    All of these drivers are not necessarily available on your system; here’s a quick way to find out which drivers you have:

    print_r(PDO::getAvailableDrivers());
    
    Connecting

    Different databases may have slightly different connection methods. Below, the method to connect to some of the most popular databases are shown. You’ll notice that the first three are identical, other then the database type – and then SQLite has its own syntax.

    Connection String
    try {
      # MS SQL Server and Sybase with PDO_DBLIB
      $DBH = new PDO("mssql:host=$host;dbname=$dbname, $user, $pass");
      $DBH = new PDO("sybase:host=$host;dbname=$dbname, $user, $pass");
    
      # MySQL with PDO_MYSQL
      $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
    
      # SQLite Database
      $DBH = new PDO("sqlite:my/database/path/database.db");
    }
    catch(PDOException $e) {
        echo $e->getMessage();
    }
    

    Please take note of the try/catch block – you should always wrap your PDO operations in a try/catch, and use the exception mechanism – more on this shortly. Typically you’re only going to make a single connection – there are several listed to show you the syntax. $DBH stands for ‘database handle’ and will be used throughout this tutorial.

    You can close any connection by setting the handle to null.

    # close the connection
    $DBH = null;
    

    You can get more information on database specific options and/or connection strings for other databases from PHP.net.

    Exceptions and PDO

    PDO can use exceptions to handle errors, which means anything you do with PDO should be wrapped in a try/catch block. You can force PDO into one of three error modes by setting the error mode attribute on your newly created database handle. Here’s the syntax:

    $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
    $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
    $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    

    No matter what error mode you set, an error connecting will always produce an exception, and creating a connection should always be contained in a try/catch block.

    PDO::ERRMODE_SILENT

    This is the default error mode. If you leave it in this mode, you’ll have to check for errors in the way you’re probably used to if you used the mysql or mysqli extensions. The other two methods are more ideal for DRY programming.

    PDO::ERRMODE_WARNING

    This mode will issue a standard PHP warning, and allow the program to continue execution. It’s useful for debugging.

    PDO::ERRMODE_EXCEPTION

    This is the mode you should want in most situations. It fires an exception, allowing you to handle errors gracefully and hide data that might help someone exploit your system. Here’s an example of taking advantage of exceptions:

    # connect to the database
    try {
      $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
      $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    
      # UH-OH! Typed DELECT instead of SELECT!
      $DBH->prepare('DELECT name FROM people');
    }
    catch(PDOException $e) {
        echo "I'm sorry, Dave. I'm afraid I can't do that.";
        file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
    }
    

    There’s an intentional error in the select statement; this will cause an exception. The exception sends the details of the error to a log file, and displays a friendly (or not so friendly) message to the user.

    Insert and Update

    Inserting new data, or updating existing data is one of the more common database operations. Using PDO, this is normally a two-step process. Everything covered in this section applies equally to both UPDATE and INSERT operations.

    2 to 3 step insert and update

    Here’s an example of the most basic type of insert:

    # STH means "Statement Handle"
    $STH = $DBH->prepare("INSERT INTO folks ( first_name ) values ( 'Cathy' )");
    $STH->execute();
    

    You could also accomplish the same operation by using the exec() method, with one less call. In most situations, you’re going to use the longer method so you can take advantage of prepared statements. Even if you’re only going to use it once, using prepared statements will help protect you from SQL injection attacks.

    Prepared Statements

    Using prepared statements will help protect you from SQL injection.

    A prepared statement is a precompiled SQL statement that can be executed multiple times by sending just the data to the server. It has the added advantage of automatically making the data used in the placeholders safe from SQL injection attacks.

    You use a prepared statement by including placeholders in your SQL. Here’s three examples: one without placeholders, one with unnamed placeholders, and one with named placeholders.

    # no placeholders - ripe for SQL Injection!
    $STH = $DBH->("INSERT INTO folks (name, addr, city) values ($name, $addr, $city)");
    
    # unnamed placeholders
    $STH = $DBH->("INSERT INTO folks (name, addr, city) values (?, ?, ?);
    
    # named placeholders
    $STH = $DBH->("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
    

    You want to avoid the first method; it’s here for comparison. The choice of using named or unnamed placeholders will affect how you set data for those statements.

    Unnamed Placeholders
    # assign variables to each place holder, indexed 1-3
    $STH->bindParam(1, $name);
    $STH->bindParam(2, $addr);
    $STH->bindParam(3, $city);
    
    # insert one row
    $name = "Daniel"
    $addr = "1 Wicked Way";
    $city = "Arlington Heights";
    $STH->execute();
    
    # insert another row with different values
    $name = "Steve"
    $addr = "5 Circle Drive";
    $city = "Schaumburg";
    $STH->execute();
    

    There are two steps here. First, we assign variables to the various placeholders (lines 2-4). Then, we assign values to those placeholders and execute the statement. To send another set of data, just change the values of those variables and execute the statement again.

    Does this seem a bit unwieldy for statements with a lot of parameters? It is. However, if your data is stored in an array, there’s an easy shortcut:

    # the data we want to insert
    $data = array('Cathy', '9 Dark and Twisty Road', 'Cardiff');
    
    $STH = $DBH->("INSERT INTO folks (name, addr, city) values (?, ?, ?);
    $STH->execute($data);
    

    That’s easy!

    The data in the array applies to the placeholders in order. $data[0] goes into the first placeholder, $data[1] the second, etc. However, if your array indexes are not in order, this won’t work properly, and you’ll need to re-index the array.

    Named Placeholders

    You could probably guess the syntax, but here’s an example:

    # the first argument is the named placeholder name - notice named
    # placeholders always start with a colon.
    $STH->bindParam(':name', $name);
    

    You can use a shortcut here as well, but it works with associative arrays. Here’s an example:

    # the data we want to insert
    $data = array( 'name' => 'Cathy', 'addr' => '9 Dark and Twisty', 'city' => 'Cardiff' );
    
    # the shortcut!
    $STH = $DBH->("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
    $STH->execute($data);
    

    The keys of your array do not need to start with a colon, but otherwise need to match the named placeholders. If you have an array of arrays you can iterate over them, and simply call the execute with each array of data.

    Another nice feature of named placeholders is the ability to insert objects directly into your database, assuming the properties match the named fields. Here’s an example object, and how you’d perform your insert:

    # a simple object
    class person {
        public $name;
        public $addr;
        public $city;
    
        function __construct($n,$a,$c) {
            $this->name = $n;
            $this->addr = $a;
            $this->city = $c;
        }
        # etc ...
    }
    
    $cathy = new person('Cathy','9 Dark and Twisty','Cardiff');
    
    # here's the fun part:
    $STH = $DBH->("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
    $STH->execute((array)$cathy);
    

    By casting the object to an array in the execute, the properties are treated as array keys.

    Selecting Data Fetch data into arrays or objects

    Data is obtained via the ->fetch(), a method of your statement handle. Before calling fetch, it’s best to tell PDO how you’d like the data to be fetched. You have the following options:

    • PDO::FETCH_ASSOC: returns an array indexed by column name
    • PDO::FETCH_BOTH (default): returns an array indexed by both column name and number
    • PDO::FETCH_BOUND: Assigns the values of your columns to the variables set with the ->bindColumn() method
    • PDO::FETCH_CLASS: Assigns the values of your columns to properties of the named class. It will create the properties if matching properties do not exist
    • PDO::FETCH_INTO: Updates an existing instance of the named class
    • PDO::FETCH_LAZY: Combines PDO::FETCH_BOTH/PDO::FETCH_OBJ, creating the object variable names as they are used
    • PDO::FETCH_NUM: returns an array indexed by column number
    • PDO::FETCH_OBJ: returns an anonymous object with property names that correspond to the column names

    In reality, there are three which will cover most situations: FETCH_ASSOC, FETCH_CLASS, and FETCH_OBJ. In order to set the fetch method, the following syntax is used:

    $STH->setFetchMode(PDO::FETCH_ASSOC);
    

    You can also set the fetch type directly within the ->fetch() method call.

    FETCH_ASSOC

    This fetch type creates an associative array, indexed by column name. This should be quite familiar to anyone who has used the mysql/mysqli extensions. Here’s an example of selecting data with this method:

    # using the shortcut ->query() method here since there are no variable
    # values in the select statement.
    $STH = $DBH->query('SELECT name, addr, city from folks');
    
    # setting the fetch mode
    $STH->setFetchMode(PDO::FETCH_ASSOC);
    
    while($row = $STH->fetch()) {
        echo $row['name'] . "\n";
        echo $row['addr'] . "\n";
        echo $row['city'] . "\n";
    }
    

    The while loop will continue to go through the result set one row at a time until complete.

    FETCH_OBJ

    This fetch type creates an object of std class for each row of fetched data. Here’s an example:

    # creating the statement
    $STH = $DBH->query('SELECT name, addr, city from folks');
    
    # setting the fetch mode
    $STH->setFetchMode(PDO::FETCH_OBJ);
    
    # showing the results
    while($row = $STH->fetch()) {
        echo $row->name . "\n";
        echo $row->addr . "\n";
        echo $row->city . "\n";
    }
    
    FETCH_CLASS

    The properties of your object are set BEFORE the constructor is called. This is important.

    This fetch method allows you to fetch data directly into a class of your choosing. When you use FETCH_CLASS, the properties of your object are set BEFORE the constructor is called. Read that again, it’s important. If properties matching the column names don’t exist, those properties will be created (as public) for you.

    This means if your data needs any transformation after it comes out of the database, it can be done automatically by your object as each object is created.

    As an example, imagine a situation where the address needs to be partially obscured for each record. We could do this by operating on that property in the constructor. Here’s an example:

    class secret_person {
        public $name;
        public $addr;
        public $city;
        public $other_data;
    
        function __construct($other = '') {
            $this->address = preg_replace('/[a-z]/', 'x', $this->address);
            $this->other_data = $other;
        }
    }
    

    As data is fetched into this class, the address has all its lowercase a-z letters replaced by the letter x. Now, using the class and having that data transform occur is completely transparent:

    $STH = $DBH->query('SELECT name, addr, city from folks');
    $STH->setFetchMode(PDO::FETCH_CLASS, 'secret_person');
    
    while($obj = $STH->fetch()) {
        echo $obj->addr;
    }
    

    If the address was ‘5 Rosebud,’ you’d see ‘5 Rxxxxxx’ as your output. Of course, there may be situations where you want the constructor called before the data is assigned. PDO has you covered for this, too.

    $STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'secret_person');
    

    Now, when you repeat the previous example with this fetch mode (PDO::FETCH_PROPS_LATE) the address will NOT be obscured, since the constructor was called and the properties were assigned.

    Finally, if you really need to, you can pass arguments to the constructor when fetching data into objects with PDO:

    $STH->setFetchMode(PDO::FETCH_CLASS, 'secret_person', array('stuff'));
    

    If you need to pass different data to the constructor for each object, you can set the fetch mode inside the fetch method:

    $i = 0;
    while($rowObj =  $STH->fetch(PDO::FETCH_CLASS, 'secret_person', array($i))) {
        // do stuff
        $i++
    }
    
    Some Other Helpful Methods

    While this isn’t meant to cover everything in PDO (it’s a huge extension!) there are a few more methods you’ll want to know in order to do basic things with PDO.

    $DBH->lastInsertId();
    

    The ->lastInsertId() method is always called on the database handle, not statement handle, and will return the auto incremented id of the last inserted row by that connection.

    $DBH->exec('DELETE FROM folks WHERE 1');
    $DBH->exec("SET time_zone = '-8:00'");
    

    The ->exec() method is used for operations that can not return data other then the affected rows. The above are two examples of using the exec method.

    $safe = $DBH->quote($unsafe);
    

    The ->quote() method quotes strings so they are safe to use in queries. This is your fallback if you’re not using prepared statements.

    $rows_affected = $STH->rowCount();
    

    The ->rowCount() method returns an integer indicating the number of rows affected by an operation. In at least one known version of PDO, according to [this bug report] [bugs.php.net] the method does not work with select statements. If you’re having this problem, and can’t upgrade PHP, you could get the number of rows with the following:

    $sql = "SELECT COUNT(*) FROM folks";
    if ($STH = $DBH->query($sql)) {
        # check the row count
        if ($STH->fetchColumn() > 0) {
    
        # issue a real select here, because there's data!
        }
        else {
            echo "No rows matched the query.";
        }
    }
    
    Conclusion

    I hope this helps some of you migrate away from the mysql and mysqli extensions. What do you think? Are there any of you out there who might make the switch?

  • Permalink for 'Premium Members: Contribute Your Testimonials'

    Premium Members: Contribute Your Testimonials

    Posted: May 25th, 2010, 6:55pm MDT by Skellie


    We have started to collect testimonials from happy Premium members to display on our Tuts+ Testimonials page. If you’d like your testimonial featured on the page, please leave your testimonial in a comment on this post. We’ll publish your name and a link to your website with your testimonial.

    If you’re a Premium member, please take a minute to let us know what you think about Premium. What would you say to someone considering signing up for a membership?

  • Permalink for 'CSS DIY Organization'

    CSS DIY Organization

    Posted: May 25th, 2010, 10:07am MDT by John Cox


    I detest looking at code or mark-up that I’ve written in the past, which I don’t understand right off the bat. I’m surely no different from you in that I want to be able to come back years later, pick the code up, and understand exactly what is going on. I don’t want to dissect the simplest concepts, where the brackets are located, or even how the mark-up is indented. I have created habits to help me with rapid development, which have kept my sanity somewhat intact. I will be honest though, I have never given much thought to how I write and organize my CSS until recently, and that is what I am sharing today.

    Introduction: Why Bother?

    There are plenty of ways to do what I am suggesting with CSS. Let me be the first to say, don’t use anything that I am writing about today if your comfort level is not high with my concepts. Instead, think about the concepts, and improve on the solutions I am writing about. Share your own insights. I won’t argue with you if you think there is a better way to organize style sheets, as in the end there is no right or wrong way. However, I believe the more structure you add, the better off you are in the end when working with CSS.

    “How easy is it for us, as developers, to rapidly find, understand, repair or add-on to a given code base? The easier that task is, the better the internal usability.”

    There are a couple of concepts that I want to cover now in general to get the brain juices working. First, there is a concentration on usability with web development. We want the users of our websites to find things quicker, navigate more naturally, and overall intrinsically understand the concepts of our applications. That’s a very worthy use of time and energy. What is sometimes forgotten is the internal usability in all of the planning and discussions for our projects. How easy is it for us as developers, to rapidly find, understand, repair or add-on to a given code base? The easier that task is, the better the internal usability. In my opinion, that concept is as worthy of our time and thought as the front end usability.

    Second, remember there is a C in CSS. It’s the cascading part. The method I use might fly in the face of some conventional thoughts, but when you back yourself into a corner for only using a certain aspects of CSS, you lose out on the power. When I am planning a large project, I think of the id selectors as “explain the entity”, class selectors as “describe the entity” and style attributes as “override what I just said”. I cascade the properties down to lessen the code, and give a little method to the madness. Again, there are no right or wrong ways, but when you have no plan, you are setting yourself up for a lot of extra work, not to mention extra overhead.

    Finally, remember there are always tradeoffs in development. The most elegant ways of doing things aren’t always the most efficient.

    Sometimes, the most efficient ways of doing things cost you down the road when you have to pick the code back up for support.

    No one can make these choices for you, but you need to consider the tradeoffs while you write. Sometimes you have to bite the bullet just a little bit, perhaps to add an additional HTTP request to make the end result internally usable. Other times, you need to add a good comment to remind yourself of the choice that you made, and move on.

    A Couple of Choices: Frameworks or The Wild West

    Chances are, you are using either a framework to handle your CSS or you are adding your styles in a manner that you have grown accustomed to, but without much of a structure. Both have there upsides and downsides. Let’s look at a few CSS frameworks first, from the horse’s mouths:

    Blue Print YUI 2 Baseline YAML

    There are a numerous more, and just like a frameworks for your server side language of choice, each have their advantages over one another, and each have their drawbacks. I am not here to steer you away from a framework, as I have used them in the past and I believe in the concepts. I think when you are working on a large team, there is no better choice as it standardizes your styles and it lessons the voice of the individual developer and designer. That said, I do believe there are some drawbacks from using a CSS framework, as it adds to the overhead particularly with styles you aren’t using, and the learning curve is rather high. This can be a bit frustrating particularly with projects that have strict schedules. That said, the learning curve is just that, a curve, and over time you will master whichever project you deem best. The advantage of using a framework is that you now have improved your internal usability, as you are using a set method paradigm, although that method is something that is most likely outside of your control.

    Wild West

    The other solution is what I call the “Wild West” where anything goes. I’ll be honest and say there are many times I have just pushed something out the door without much thought to the future, or in the case of a very small project where the CSS is not very substantial. The learning curve here isn’t so bad, because you are writing your CSS as you go. You have complete control over your style’s destiny. Pretty cool so far! The problem is the internal usability. Come back to that project after it is no longer fresh in your mind, and there will be some problems. “Why the heck did I write this like this” or “I have no idea what I meant by this comment” or “Why is that input not changing styles” or “what is this big chunk of chum controlling” are common responses after the style sheet is no longer fresh in your mind.

    My Choice: The Hybrid Solution

    If I could put the framework solution on a sliding scale with the wild west solution on the other end, I think I would prefer something just in the middle. While one bed is too hard, and the other bed is too soft, I want to find the bed that is just right. That’s what I call the hybrid solution. It shares traits with both the wild west and frameworks. On the one hand, I have control over my styles, and with that the learning curve is rather low. On the other, I want to give a little structure to what I write, so that when I come back to it later, I have at least a familiarity of the structure because I build onto my methods which each project.

    It’s a bit of a DIY project like in home improvement. You are trading the structure and cost of a professional for the convenience and familiarity of using your own hands to do the work. What you hope for in the end is the same finished project, but one without the learning curve or foreign ideas and concepts from the industrial strength version.

    File Naming Convention

    Thinking back on the choices that we have to make as developers, I make the choice of increasing the HTTP requests for a little better organization. I know I am costing myself a little bit of performance but what I get in the end is CSS that is easier to understand when I have to look at them next. You may make a different choice here, and you won’t get much argument from me. I just prefer smaller file sizes organized in a consistent manner over the one large CSS file or header in my HTML.

    Here’s what works for me:
    • reset.css : A reset css is one that sets all or at least of the majority of browser styles to nullify. I use a reset css so that I can battle some differences with browsers, and I see the value when dealing with cross browser issues. It’s not Nirvana, and there are some that prefer no reset, or what I recently read, a soft reset. I prefer to reset everything, and I use the Eric Meyer flavor of resets.

    • forms.css: I segregate my form styles from the rest of my CSS. I want to know when I am working on forms, and they aren’t quite appearing as I wish exactly where to go.

    • global.css: My global css file is something that I use for each larger project that I write. What is contained in this small file are small classes which I might use over and over again in projects. My rule of thumb is, if there is a shortcut for the property, then it probably doesn’t belong in the global file. I wouldn’t use the font property. For instance:

    /* Colors */
    .red {
        color: red;
        background: inherit;
    }
    
    .blue {
        color: blue;
        background: inherit;
    }
    
    .highlight {
        color: black;
        background: yellow;
    }
    
    /* Lists */
    .horizontal {
        list-style-type: none;
        display: inline;
    }
    
    .vertical {
        list-style-type: none;
        display: block;
    }
    
    /* Text */
    .small {
        font-size: small;
    }
    
    .large {
        font-size: large;
    }
    
    .bold {
        font-weight: bold;
    }
    

    Notice that these are very specific classes, that add to the cascading rules of styles. While none generally will be used as the only style for an element, they add to the description of the element that they class is applied.

    • style.css: My style.css is my main controller of my style. If you think in terms of OO for CSS, my style.css is my class, while the other files extend my class (somewhat anyway) and add to the inheritance of my main objects. I use my style.css to import my other files, and to define my local, project only, id selectors and classes.

    ID and Class Selectors: Think a Little Differently

    My hybrid method diverges here from most people, as my general rule with ids is merely to explain the element in question. ID Selectors are only used once per page (including GET processes), so I want these to be very specific in nature. In order to really maximize the reuse of code, any property outside of that explanation of an element, I really would prefer to use a class selector. Since this ID is unique to the page, I only want to use unique explanations for this selector.

    For instance, my width would be somewhat unique. My padding and margin would be somewhat unique. My position would be somewhat unique. You could argue that the display for this selector would be somewhat unique. My color for the element; not really unique. My background, again not really unique. For the not really unique items, I think of these as “describe the element” for which I use class selectors.

    Let’s illustrate this with a little code. For ease, I am using a recent tutorial by Jeffrey Way titled Quick Tip: Practical CSS Shapes. What if we took the original CSS:

    #container {
    	background: #666;
    	margin: auto;
    	width: 500px;
    	height: 700px;
    	padding-top: 30px;
    	font-family: helvetica, arial, sans-serif;
    	}
    
    h1 {
    	 background: #e3e3e3;
    	 background: -moz-linear-gradient(top, #e3e3e3, #c8c8c8);
    	 background: -webkit-gradient(linear, left top, left bottom, from(#e3e3e3), to(#c8c8c8));
    	 padding: 10px 20px;
    	 margin-left: -20px;
    	 margin-top: 0;
    	 position: relative;
    	 width: 70%;
    	 -moz-box-shadow: 1px 1px 3px #292929;
    	 -webkit-box-shadow: 1px 1px 3px #292929;
         box-shadow: 1px 1px 3px #292929;
    	 color: #454545;
    	 text-shadow: 0 1px 0 white;
    }
    

    and transformed to this:

    #container {
    	margin: auto;
    	width: 500px;
    	height: 700px;
    	padding-top: 30px;
    	font-family: helvetica, arial, sans-serif;
    	}
    
    #heading-one {
    	 padding: 10px 20px;
    	 margin-left: -20px;
    	 margin-top: 0;
    	 position: relative;
    	 width: 70%;
    }
    
    .norm-background {
            color: #fff;
            background: #666;
    }
    
    .heading-fancy {
    	 background: #e3e3e3;
    	 background: -moz-linear-gradient(top, #e3e3e3, #c8c8c8);
    	 background: -webkit-gradient(linear, left top, left bottom, from(#e3e3e3), to(#c8c8c8));
    	 -moz-box-shadow: 1px 1px 3px #292929;
    	 -webkit-box-shadow: 1px 1px 3px #292929;
    	 color: #454545;
    	 text-shadow: 0 1px 0 white;
    }
    

    So far, all I have really done is added two new classes from the unique h1 selector and abstracted that h1 out to a unique ID. I haven’t gained anything for the moment, and in actuality I have added just a whee bit more overhead to my file. Where’s the advantage then?

    If you think for a moment that you might reuse these descriptions somewhere else, perhaps for a sub-heading, then we have some code reuse. Let’s look to see what we can do now. Here’s how it originally looks:

    Heading

    and here is how it looks with a sub-heading:

    Subheading

    I only added a new definition now:

    #heading-two {
    	 padding: 10px 20px;
    	 margin-left: -20px;
    	 margin-top: 0;
    	 position: relative;
    	 width: 30%;
    }
    

    Along with a little HTML:

        <h1 id="heading-one" class="heading-fancy"> My Heading <span class="arrow"></span> </h1>
        <h2 id="heading-two" class="heading-fancy small"> My Sub-Heading <span class="arrow"></span> </h2>
    

    We have code reuse, and we have a method which is consistent. If you take this method and apply it, you will reduce the number of styles (or objects if you prefer) that you write. Less code with a method means easier support at a later date. Really, nothing earth shattering here, but when you begin to explain your ID selectors but describe your classes it’s an easy method to add a little sanity to your code.

    Style Attributes

    I’m sure someone, somewhere, has told you to never use the style attribute. I am also sure that some of you will disagree with me, and that’s OK, I can take it. I am going to break that rule just a bit with a caveat. Never use it without a little thought to what you are doing. There are legitimate uses for the style attribute, particularly when working with complex applications using AJAX calls, but those uses come from your behavior layer.

    When you should use the style attribute, is when you need to make a quick final call to override something in the cascade display for the element which wouldn’t make sense to add to your global.css file. For instance, you might need to override a style from your behavior layer based on an user action. It does add to the complexity just a bit, but it adds to the cascade. I wouldn’t use multiple properties, as this is a quick override, or rather, “forget what I just told you, do this instead”. It’s a cascade, and you should treat your CSS as such, in my opinion.

    Indentation, Layout and Comments

    We spend a lot of time putting emphasis on our indentation in our code and HTML, but I don’t often see the same emphasis in our CSS. It makes the world of difference. Let’s take our working example again:

    <div id="container" class="norm-background">
        <h1 id="heading-one" class="heading-fancy"> My Heading <span class="arrow"></span> </h1>
        <h2 id="heading-two" class="heading-fancy small"> My Sub-Heading <span class="arrow"></span> </h2>
    </div>
    

    If we indent that in our markup, why not indent it the same way in our CSS:

    #container {
    	margin: auto;
    	width: 500px;
    	height: 700px;
    	padding-top: 30px;
    	font-family: helvetica, arial, sans-serif;
    	}
    
        #heading-one {
             padding: 10px 20px;
             margin-left: -20px;
             margin-top: 0;
             position: relative;
             width: 70%;
        }
    
        #heading-two {
             padding: 10px 20px;
             margin-left: -20px;
             margin-top: 0;
             position: relative;
             width: 30%;
        }
    

    It adds just a little more emphasis as to what is going on with these ID selectors. I understand now that they are children to the container div without comparing my mark-up.

    When deciding on the layout of your style file, this is the rule of thumb that I use. You have to @import your additional CSS files first starting with the reset.css file, and then the rest. Define your elements next such as h1, anchors, etc. Next, define your ID selectors in your style.css. If you are working with multiple pages, comment the start of each new page within your indentation. For instance, #container is probably an element of the layout which is the container for each page, so start there with your indentation and work out commenting where you are using each element. Finally, define your classes. I don’t normally indent my classes, due to the fact that they are often reused, and the indentation doesn’t show where they are used.

    Finally, and probably most importantly, comment your CSS just as you would your server side code. If there is any context that you can give to a class, such as elements that it is used, or ID that it matches, comment it. Any context that you give your future self is like having a time machine. Marty McFly might not have knocked that creepy guy out of the way of oncoming traffic if he had just read the Flux Capacitor comments first.

    Conclusion

    I am relatively sure my methods will not have a new dance move named after it, nor will it cure cancer. I am not even sure if they would be adapted by a single person outside of my immediate family. That said, I really hope you take the concepts away from this and build methods that work for you. Development usability is a goal that we should all be striving to achieve. When you create a methodology, you increase your internal usability exponentially as you are developing habits which you reuse and share with your team and others. It fixes development problems, increases productivity, and decreases the overall cost of development. It is one of those rare win / win propositions that you encounter in your daily development life.

    Thanks for reading, and please share your ideas.

  • Permalink for 'Massive iPad Vector GUI Elements'

    Massive iPad Vector GUI Elements

    Posted: May 24th, 2010, 6:28am MDT by Jeffrey Way


    The folks at IconShock have a massive vector pack of, quite literally, all the iPad GUI elements. This includes the iPad itself, buttons, alert boxes, tabs, the keyboard, and plenty more.

    Screenshot
  • Permalink for '10 Django Trouble Spots for Beginners'

    10 Django Trouble Spots for Beginners

    Posted: May 24th, 2010, 4:42am MDT by Glen Stansberry


    Django is an incredibly-powerful web framework, but using it can be a bit daunting for new users. I found this out the hard way over a year ago, spending hours struggling with even the most basic of concepts. If you're new to Django, (or MVC frameworks in general), you're probably going to have to shift your thinking a bit to use this robust framework. Here are some of the issues that I had to struggle with before I fully understood them. Hopefully, this will save you hours of struggling.

    1. It's Not a CMS

    Django isn't a CMS. It can't do everything that Wordpress or Drupal can do right out of the box. That said, you can do infinitely more with Django, because it isn't a CMS.

    If you have a background with, for example, a platform like WordPress, it's going to take a while to wrap your head around the fact that you're going to have to do a lot more things manually, such as creating urls or modifying settings. Most of the configurations won't be done in a UI, but instead with Python files.

    While Django does come with a pretty nifty admin area straight out of the box, configuring Django sometimes isn't as easy as a standard CMS.

    2. Local Environment Setup

    One of the biggest initial hurdles that new users face is configuring their local environment for Django. For many beginners, it takes longer to install the framework locally than to build their first app. PHP frameworks like CakePHP are pretty much ready to start using once you've downloaded them on your local machine.

    Installing Django and configuring it to run on the local machine can be kind of tricky, especially if you're not familiar with concepts like symlinks. The Django install docs are pretty comprehensive, but if those don't work for you search for some video instruction or platform-specific documentation.

    3. Projects vs. Apps

    If you're new to Django (or MVC frameworks in general), odds are the terms "projects" and "apps" might be a little confusing.

    With Django, a Project is just a collection of apps. Say you were building a YouTube clone; you would create a project, "MyTube", that would contain apps like "videos", "comments", "ratings", "blog", etc.

    Apps are similar to modules in a CMS, except you build them from scratch. They're a lot smaller in scope, typically performing only one main function. For the MyTube example, you wouldn't just create one app that allowed users to upload videos, comment on them, rate them, and anything else. You want your apps to be small in scope, performing only one or two functions by themselves.

    4. Template Inheritance

    Template inheritance is one of the best features of Django, but it usually takes a while to truly understand.

    With a traditional CMS, you might split reusable parts of a template out into their own files (like a header file), and include them in each of the templates. With Django, you create a base.html template, and you specify blocks that can be overwritten in child templates. This keeps your code more reusable.

    So, for an example, you might have a base.html template that has this:

    <div>
      {% block content %}
        <p>Here is our content that will be overwritten</p>
      {% endblock %}
      <p>Other stuff that won't be overwritten.</p>
    </div>
    

    Then in another template you may choose to overwrite the {% content %} block. Instead of having to include a sidebar file into the design, we just simply do something like this:

    {% extends base.html %}
    
    {% block content %}
    I'd like a different content block!
    {% endblock %}
    

    This extends the base.html. This method allows you finer control over your templates, and ensures that you're not creating duplicate code.

    To learn more about the power of template inheritance, check out this article on the power of Django template inheritance.

    5. Separation of Code and Media Files

    Because Django doesn't serve media files itself, it likes to separate the media files (images, JavaScripts, stylesheets, etc. ) into a directory away from the apps. This allows you to decide how you're going to serve those static files. You could use a separate webserver or cloud services like Amazon S3 to serve the files.

    Your project files might look something like this:

    MyProject
      - app
      - app2
      - media
        - javascript
        - stylesheets
        - images
      ....
    
    6. Migrations

    Database migrations are a trouble-spot for many beginners. This happens when you already have fields in your database (production or development), and you add something that modifies the database.

    Other frameworks like Rails have database migrations built in. With Django, however, unless you use a third-party solution, you have to do the migrations by hand. Fortunately, there is an excellent third-party tool that handles Django migrations: South.

    South allows you to perform database migrations, much like Rails allows, and is easy to roll into your existing project. It's powerful and simple, and takes care of the issue of database migrations that Django has. Here's a tutorial that has examples of how South works.

    7. Local vs. Production Environments

    Django comes with sqlite, a simple flat-file database that doesn't need any configuration. This makes prototyping fast and easy right out of the box.

    However, once you've moved your project into a production environment, odds are you'll have to use a more robust database like Postgresql or MySQL. This means that you're going to have two separate environments: production and development.

    Django doesn't really have logic baked in that allows you to easily switch between two different settings without manually editing the settings.py file. For example, having the setting

    DEBUG = True

    is helpful for local environments, because it provides helpful error messages when code goes bad. But if you're on a production environment, you'll never want users to see your error messages, so you'd need to specify –

    DEBUG = False

    .

    There is a way to automatically toggle between the two environments, using this quick modification:

      import socket
    
      if socket.gethostname() == '<a href="http://productionserver.com" target="_blank">productionserver.com</a>':
          DEBUG = False
      else:
          DEBUG = True
    

    You can reuse the socket bit in different areas of your settings.py as well.

    8. Writing Custom Template Tags

    Template tags are an insanely useful aspect of Django. In fact, it ships with many built-in template tags right out of the box.

    However, if you're wanting to write your own custom template tags, it can get a bit tricky. Here's a simple example of writing a custom template tag that should give you a better understanding of how template tags work and how to create your own.

    9. Django User Authentication

    Django comes with a great user authentication system in the project admin that you can use to manage users. However, the user authentication system doesn't provide a simple way to allow non-admins to create user accounts. CMSs, like Drupal, handle this beautifully right out of the box.

    There are a few great options for public user authentication systems that provide this missing functionality. The most popular third-party solution is probably django-registration. It's simple yet flexible, and provides everything you need to get user signups in your application.

    10. Generic Views

    Generic views are incredibly powerful, and can save you a lot of time writing views for your Django app. However, most beginners don't know how useful and powerful they are.

    For example, if you want to create a flat page for your homepage, but want to style it differently, you can create a template in your flatpages template directory that utilizes the direct_to_template view.

    Aside from creating the proper template, you'll need to modify your urls.py file to point to it:

    urlpatterns = patterns('',
      (r'^$', 'django.views.generic.simple.<WBR>direct_to_template', {'template': 'homepage.html'}),
    .....
    

    Now, we have a homepage with a custom design that doesn’t require writing any custom views. I’ve utilized this technique many times instead of writing extra views.

    Conclusion

    Once you've worked through all the tricky areas that catch most beginners, Django will prove to be a really fast and powerful tool for building web applications. Don't get discouraged if you find yourself confused early on. You can always find help within the Django IRC channel; Stackoverflow is another excellent place to ask questions.

  • Permalink for 'Quick Tip: Pure CSS Text Gradients'

    Quick Tip: Pure CSS Text Gradients

    Posted: May 21st, 2010, 2:42pm MDT by Jeffrey Way


    With the latest advancements in CSS, we now have access to powerful styling techniques, including box shadows, rounded corners, background gradients, etc. However, we don’t currently have the ability to apply gradients to the text itself. Luckily, with a bit of trickery, we can force this effect — at least in webkit browsers! I’ll show you how in today’s video quick tip.

    4 Minutes: Video Tutorial

    Subscribe to our YouTube page to watch all of the video tutorials!
    Prefer to watch this video on Screenr?

    Screenshot Final Code
    <!DOCTYPE html>
    
    <html lang="en">
    <head>
    	<meta charset="utf-8">
    	<title>Text Gradients</title>
    	<link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>
    
    	<style>
    	body {
    		background: #292929;
    		padding: 1em;
    	}
    
    	h1 {
    		position: relative;
    		font-size: 70px;
    		margin-top: 0;
    		font-family: 'Lobster', helvetica, arial;
    	}
    
    	h1 a {
    		text-decoration: none;
    		color: #666;
    		position: absolute;
    
    		-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1)), color-stop(50%, rgba(0,0,0,.5)), to(rgba(0,0,0,1)));
    	}
    
    	h1:after {
    		content : 'Hello World';
    		color: #d6d6d6;
    		text-shadow: 0 1px 0 white;
    	}
    
    	</style>
    </head>
    <body>
         <h1> <a href="#"> Hello World </a> </h1>
    </body>
    </html>
    

    I originally learned this technique from the guys over at NiceWebType.com. Be sure to visit their website to learn more! So what do you think?

  • Permalink for 'HTML Parsing and Screen Scraping with the Simple HTML DOM Library'

    HTML Parsing and Screen Scraping with the Simple HTML DOM Library

    Posted: May 21st, 2010, 10:00am MDT by Erik Wurzer


    If you need to parse HTML, regular expressions aren’t the way to go. In this tutorial, you’ll learn how to use an open source, easily learned parser, to read, modify, and spit back out HTML from external sources. Using nettuts as an example, you’ll learn how to get a list of all the articles published on the site and display them.

    Step 1. Preparation

    The first thing you’ll need to do is download a copy of the simpleHTMLdom library, freely available from sourceforge.

    There are several files in the download, but the only one you need is the simple_html_dom.php file; the rest are examples and documentation.

    Download from Sourceforge Step 2. Parsing Basics

    This library is very easy to use, but there are some basics you should review before putting it into action.

    Loading HTML
    $html = new simple_html_dom();
    
    // Load from a string
    $html->load('<html><body><p>Hello World!</p><p>We're here</p></body></html>');
    
    // Load a file
    $html->load_file('http://net.tutsplus.com/');
    

    You can create your initial object either by loading HTML from a string, or from a file. Loading a file can be done either via URL, or via your local file system.

    A note of caution: The load_file() method delegates its job to PHP’s file_get_contents. If allow_url_fopen is not set to true in your php.ini file, you may not be able to open a remote file this way. You could always fall back on the CURL library to load remote pages in this case, then read them in with the load() method.

    Accessing Information Transforming your HTML

    Once you have your DOM object, you can start to work with it by using find() and creating collections. A collection is a group of objects found via a selector – the syntax is quite similar to jQuery.

    <html>
    <body>
        <p>Hello World!</p>
        <p>We're Here.</p>
    </body>
    </html>
    

    In this example HTML, we’re going to take a look at how to access the information in the second paragraph, change it, and then output the results.

    # create and load the HTML
    include('simple_html_dom.php');
    $html = new simple_html_dom();
    $html->load("<html><body><p>Hello World!</p><p>We're here</p></body></html>");
    
    # get an element representing the second paragraph
    $element = $html->find("p");
    
    # modify it
    $element[1]->innertext .= " and we're here to stay.";
    
    # output it!
    echo $html->save();
    

    Using the find() method always returns a collection (array) of tags unless you specify that you only want the nth child, as a second parameter.

    Lines 2-4: Load the HTML from a string, as explained previously.

    Line 7: This line finds all <p> tags in the HTML, and returns them as an array. The first paragraph will have an index of 0, and subsequent paragraphs will be indexed accordingly.

    line 10: This accesses the 2nd item in our collection of paragraphs (index 1), and makes an addition to its innertext attribute. Innertext represents the contents between the tags, while outertext represents the contents including the tag. We could replace the tag entirely by using outertext.

    We’re going to add one more line, and modify the class of our second paragraph tag.

    $element[1]->class = "class_name";
    echo $html->save();
    

    The resulting HTML of the save command would be:

    <html>
    <body>
        <p>Hello World!</p>
        <p class="class_name">We're here and we're here to stay.</p>
    </body>
    </html>
    
    Other Selectors

    Here are some other examples of selectors. If you’ve used jQuery, these will seem very familiar.

    # get the first occurrence of id="foo"
    $single = $html->find('#foo', 0);
    
    # get all elements with class="foo"
    $collection = $html->find('.foo');
    
    # get all the anchor tags on a page
    $collection = $html->find('a');
    
    # get all anchor tags that are inside H1 tags
    $collection = $html->find('h1 a');
    
    # get all img tags with a title of 'himom'
    $collection = $html->find('img[title=himom]');
    

    The first example isn’t entirely intuitive – all queries by default return collections, even an ID query, which should only return a single result. However, by specifying the second parameter, we are saying “only return the first item of this collection”.

    This means $single is a single element, rather then an array of elements with one item.

    The rest of the examples are self-explanatory.

    Documentation

    Complete documentation on the library can be found at the project documentation page.

    special properties Step 3. Real World Example

    To put this library in action, we’re going to write a quick script to scrape the contents of the Nettuts website, and produce a list of articles present on the site by title and description….only as an example. Scraping is a tricky area of the web, and shouldn’t be performed without permission.

    Screen Scraping Nettuts
    include('simple_html_dom.php');
    
    $articles = array();
    getArticles('http://net.tutsplus.com/page/76/');
    

    We start by including the library, and calling the getArticles function with the page we’d like to start parsing. In this case we’re starting near the end and being kind to Nettuts’ server.

    We’re also declaring a global array to make it simple to gather all the article information in one place. Before we begin parsing, let’s take a look at how an article summary is described on Nettuts+.

    <div class="preview">
        <!-- Post Taxonomies -->
        <div class="post_taxonomy"> ... </div>
        <!-- Post Title -->
        <h1 class="post_title"><a>Title</a></h1>
        <!-- Post Meta -->
        <div class="post_meta"> ... </div>
        <div class="text"><p>Description</p></div>
    </div>
    

    This represents a basic post format on the site, including source code comments. Why are the comments important? They count as nodes to the parser.

    Step 4. Starting the Parsing Function
    function getArticles($page) {
        global $articles;
    
        $html = new simple_html_dom();
        $html->load_file($page);
    
        // ... more ...
    }
    

    We begin very simply by claiming our global, creating a new simple_html_dom object, then loading the page we want to parse. This function is going to be calling itself later, so we’re setting it up to accept the URL as a parameter.

    Step 5. Finding the Information We Want Count The Children
    $items = $html->find('div[class=preview]');  
    
    foreach($items as $post) {
        # remember comments count as nodes
        $articles[] = array($post->children(3)->outertext,
                            $post->children(6)->first_child()->outertext);
    }
    

    This is the meat of the getArticles function. It’s going to take a closer look to really understand what’s happening.

    Line 1: Creates an array of elements – div’s with the class of preview. We now have a collection of articles stored in $items.

    Line 5: $post now refers to a single div of class preview. If we look at the original HTML, we can see that the third child is the H1 containing the article title. We take that and assign it to $articles[index][0].

    Remember to start at 0 and to count comments when trying to determine the proper index of a child node.

    Line 6: The sixth child of $post is <div class=”text”>. We want the description text from within, so we grab the first child’s outertext – this will include the paragraph tag. A single record in articles now looks like this:

    $articles[0][0] = "My Article Name Here";
    $articles[0][1] = "This is my article description"
    
    Step 6, Pagination

    The first thing we do is determine how to find our next page. On Nettuts+, the URLs are easy to figure out, but we’re going to pretend they aren’t, and get the next link via parsing.

    Find the next page to parse

    If we look at the HTML, we see the following:

    <a href="http://net.tutsplus.com/page/2/" class="nextpostslink">»</a>
    

    If there is a next page (and there won’t always be), we’ll find an anchor with the class of ‘nextpostslink’. Now that information can be put to use.

    if($next = $html->find('a[class=nextpostslink]', 0)) {
        $URL = $next->href;
    
        $html->clear();
        unset($html);
    
        getArticles($URL);
    }
    

    On the first line, we see if we can find an anchor with the class nextpostslink. Take special notice of the second parameter for find(). This specifies we only want the first element (index 0) of the found collection returned. $next will only be holding a single element, rather than a group of elements.

    Next, we assign the link’s HREF to the variable $URL. This is important because we’re about to destroy the HTML object. Due to a php5 circular references memory leak, the current simple_html_dom object must be cleared and unset before another one is created. Failure to do so could cause you to eat up all your available memory.

    Finally, we call getArticles with the URL of the next page. This recursion ends when there are no more pages to parse.

    Step 7 Outputting the Results

    First we’re going to set up a few basic stylings. This is completely arbitrary – you can make your output look however you wish.

    Final Output
    #main {
        margin:80px auto;
        width:500px;
    }
    h1 {
        font:bold 40px/38px helvetica, verdana, sans-serif;
        margin:0;
    }
    h1 a {
        color:#600;
        text-decoration:none;
    }
    p {
        background: #ECECEC;
        font:10px/14px verdana, sans-serif;
        margin:8px 0 15px;
        border: 1px #CCC solid;
        padding: 15px;
    }
    .item {
        padding:10px;
    }
    

    Next we’re going to put a small bit of PHP in the page to output the previously stored information.

    <?php
        foreach($articles as $item) {
            echo "<div class='item'>";
            echo $item[0];
            echo $item[1];
            echo "</div>";
        }
    ?>
    

    The final result is a single HTML page listing all the articles, starting on the page indicated by the first getArticles() call.

    Step 8 Conclusion

    If you’re parsing a great deal of pages (say, the entire site) it may take longer then the max execution time allowed by your server. For example, running from my local machine it takes about one second per page (including time to fetch).

    On a site like Nettuts, with a current 78 pages of tutorials, this would run over one minute.

    This tutorial should get you started with HTML parsing. There are other methods to work with the DOM, including PHP’s built in one, which lets you work with powerful xpath selectors to find elements. For easy of use, and quick starts, I find this library to be one of the best. As a closing note, always remember to obtain permission before scraping a site; this is important. Thanks for reading!

  • Permalink for 'Simple PHP Class-Based Querying'

    Simple PHP Class-Based Querying

    Posted: May 20th, 2010, 10:04am MDT by Brant Steen


    Though it is usually advisable to use some sort of framework or CMS, sometimes a project is small enough such that those options would weigh down the development. However, even in smaller projects, separating presentational elements from backend querying should not be ignored. This tutorial will walk you through creating a basic class-based querying engine for PHP and MySQL.

    Step 1. Setup the Project

    The first thing we are going to want to do is make some specific files and directories. Here’s how I like to setup my projects. You can, of course, feel free to change the names and structure to your liking. Just make sure you change the require’s later on as well.

    Make directories

    We’ll need a new directory to hold everything. In this case, I called it tut. Inside of that, I put my configuration files in a directory called conf. Then, I will make an inc directory (short for include) and put a “class” directory inside of that.

    Add Files

    Then, inside /conf, we will make config.php. Inside /inc/class we will make DAL.php. Finally, in the root directory, we will make index.php.

    DAL stands for “Data Access Layer” or “Data Access Link”.

    In multi-tiered architecture, it is essentially used to translate database query results into objects and vice-versa.

    Step 2. Setup the Database

    We need to make a database and populate it with some data. For the purposes of this tutorial, it will just be a two-table database with a single one-to-many relationship. This is just so we can show our querying engine spanning at least one relationship.

    Create tables

    So, in a database named “tut”, let’s make a table called makes and a table called models. The makes table will have fields “id” and “name” and the models table will have fields “id”,”make”, and “name”.

    Add some data

    Now we can just add some makes (like Ford, Chevy, etc.) as data in the makes table and some models that those manufacturers are responsible for.

    This tutorial assumes you have some working knowledge of databases and SQL, so I won’t go into details about the relation/foreign key setup.

    Step 3. The Database Connection

    Usually, I don’t like working with raw constants in PHP. I will typically define a bunch of things then make some functions to hook into those constants. For this example, let’s just keep things simple and use the constants.

    Define connection variables

    In our /conf/config.php file, let’s setup our database connection variables. While we are at it, let’s throw an include to our DAL.php script.

    <?php
    
    // Include DAL
    require_once(dirname(dirname(__FILE__)) . '/inc/class/DAL.php');
    
    // Database
    define ( 'DB_HOST', 'localhost' );
    define ( 'DB_USER', 'root' );
    define ( 'DB_PASSWORD', 'password1' );
    define ( 'DB_DB', 'tut' );
    
    ?>
    

    This setup assumes you are running MySQL on it’s default port.

    Create connection function

    Now, inside /inc/class/DAL.php, we will make a function that we will use to connect to our database.

    The connection, as well as all forthcoming queries, will live inside a class named DAL. Wrapping all database involvement inside a single class allows us to manipulate our queries later without needing to touch business or presentation layer scripts. Also, it provides some degree of mock namespacing.

    In the case of this class, we will add a constructor even though it doesn’t need to do anything.

    <?php 
    
    class DAL {
    
      public function __construct(){}
    
      private function dbconnect() {
        $conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)
          or die ("
    Could not connect to MySQL server"); mysql_select_db(DB_DB,$conn) or die ("
    Could not select the indicated database"); return $conn; } } ?>

    Notice that the scope of the dbconnect method is private. This is because we should not need to connect to the database from outside our DAL. Instead, we will have public query methods which will call the dbconnect from inside the DAL. A little confusing? No worries, read on.

    Step 4. Create Generic Query Tools

    To abstract our queries so that we can reuse short pieces of code, we will need two things. First, we will need some sort of “generic query result” class. Second, we will need a generic querying method inside our DAL.

    Create generic query result class

    The purpose of all of this is to be able to convert SQL queries into objects and minimize use of the ugly while($row = mysql_fetch_array($result)) loop. Objects are far easier to work with and allow us to use properties instead of array keys.

    In short, we want to make a class that will create property names on the fly and store data associated with those properties.

    We will put this class inside our /inc/class/DAL.php script. Since it is a new class, it will be outside the DAL class.

    class DALQueryResult {
    
      private $_results = array();
    
      public function __construct(){}
    
      public function __set($var,$val){
        $this->_results[$var] = $val;
      }
    
      public function __get($var){
        if (isset($this->_results[$var])){
          return $this->_results[$var];
        }
        else{
          return null;
        }
      }
    }
    
    Create generic query method

    Now, inside our DAL class, we need to make a generic querying method that will turn SELECT queries into DALQueryResult objects.

    Basically, we want to turn each returned field name into a property of the DALQueryResult object.

    private function query($sql){
    
      $this->dbconnect();
    
      $res = mysql_query($sql);
    
      if ($res){
        if (strpos($sql,'SELECT') === false){
          return true;
        }
      }
      else{
        if (strpos($sql,'SELECT') === false){
          return false;
        }
    	else{
    	  return null;
    	}
      }
    
      $results = array();
    
      while ($row = mysql_fetch_array($res)){
    
        $result = new DALQueryResult();
    
        foreach ($row as $k=>$v){
          $result->$k = $v;
        }
    
        $results[] = $result;
      }
      return $results;
    }
    

    Here is a private function that accepts a SQL query. It connects to the database and runs the query. Then, it checks to see if there are any results. If there are not any results, it returns null on a SELECT query, false on other queries. If the query was successful and the query was not a SELECT query, it will return true. If it was a SELECT, then it converts the results into an array of DALQueryResult objects. This mimics the results that one would normally get from a mysql_query.

    Step 5. Write a Specific Query

    Now we are ready to actually write a SQL query. DAL queries should be very specific both in name and purpose. Let’s make one that finds all models of a given make.

    This will be our first public method.

    public function get_models_by_make_name($name){
      $sql = "SELECT models.id as id, models.name as name, makes.name as make FROM models INNER JOIN makes ON models.make=makes.id WHERE makes.name='$name'";
      return $this->query($sql);
    }
    

    Here we are just writing the query and returning the result in the form of DALQueryResult objects. Our generic query method takes care of the itterations and decision making.

    Finished DAL

    At this point, our DAL.php script is finished. It should look like the following.

    <?php 
    
    class DALQueryResult {
    
      private $_results = array();
    
      public function __construct(){}
    
      public function __set($var,$val){
        $this->_results[$var] = $val;
      }
    
      public function __get($var){
        if (isset($this->_results[$var])){
    	  return $this->_results[$var];
    	}
        else{
    	  return null;
    	}
      }
    }
    
    class DAL {
    
      public function __construct(){}
    
      public function get_models_by_make_name($name){
        $sql = "SELECT models.id as id, models.name as name, makes.name as make FROM models INNER JOIN makes ON models.make=makes.id WHERE makes.name='$name'";
        return $this->query($sql);
      }
    
      private function dbconnect() {
        $conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)
        	or die ("<br/>Could not connect to MySQL server");
    
        mysql_select_db(DB_DB,$conn)
        	or die ("<br/>Could not select the indicated database");
    
    	return $conn;
      }
    
      private function query($sql){
    
        $this->dbconnect();
    
        $res = mysql_query($sql);
    
        if ($res){
          if (strpos($sql,'SELECT') === false){
            return true;
          }
        }
        else{
          if (strpos($sql,'SELECT') === false){
            return false;
          }
          else{
            return null;
          }
        }
    
        $results = array();
    
        while ($row = mysql_fetch_array($res)){
    
          $result = new DALQueryResult();
    
          foreach ($row as $k=>$v){
            $result->$k = $v;
          }
    
          $results[] = $result;
        }
        return $results;
      }
    }
    
    ?>
    
    Step 6. Use the DAL

    Now, let’s finally head over to our /index.php script and display our results using the DAL. All we need to do is include our /conf/config.php file, instantiate the DAL, and do something with the data. Here’s an example.

    <?php
    // include configuration
    require_once(dirname(__FILE__) . '/conf/config.php');
    
    // instanciate a new DAL
    $dal = new DAL();
    
    // array of makes to check
    $makes = array('Ford','Chevy','Honda');
    
    // cycle through the makes
    foreach ($makes as $make){
      $results = $dal->get_models_by_make_name($make);
      echo "<h1>Models by $make</h1>";
    
      // check if there were any results
      if ($results){
      	echo "<ul>";
    
    	// cycle through results
    	foreach ($results as $model){
      		echo "<li>$model->make $model->name (Database ID: $model->id)</li>";
      	}
      	echo "</ul>";
      }
      else{
        // Display a message concerning lack of data
      	echo "<p>Sorry, we have no information regarding that manufacturer.</p>";
      }
    }
    ?>
    

    As you can see, we now have results that we can call the field names as properties of a PHP object.

    Step 7. Taking Things one Step Further

    Often, it will be useful to convert the generic DALQueryResult into a more specific object. In this case, you can write business objects that accept a DALQueryResult as a constructor parameter. Then, you just use that to build the new object.

    Here’s an example

    <?php
    
    class CarModel{
      private $_id;
      private $_make;
      private $_name;
    
      public function __construct(DALQueryResult $result){
        $this->_id = $result->id;
        $this->_make = $result->make;
        $this->_name = $result->name;
      }
      public function __get($var){
        switch ($var){
    	  case 'id':
    	    return $this->_id;
    		break;
    	  case 'make':
    	    return $this->_make;
    		break;
    	  case 'name':
    	    return $this->_name;
    		break;
    	  default:
    	    return null;
    	    break;
    	}
      }
      public function __toString(){
        return $this->_name;
      }
    }
    
    ?>
    

    Then, just write a query to return an array of these objects instead of an array of generic DALQueryResult objects.

    Remember, always name your queries very specifically.

    public function get_models_by_make_name_as_CarModel($name){
      // Reuse existing query
      $results = $this->get_models_by_make_name($sql);
    
      // check for results
      if (!$results){
        return $results;
      }
      else{
        // array to hold CarModel objects
        $object_results = array();
        // cycle through and convert to CarModel objects
        foreach ($results as $result){
          object_results[] = new CarModel($result);
        }
        // return array of CarModel objects
        return object_results;
      }
    }
    

    Building specific objects can become very useful when calculations are needed to extract meaningful data from fields.

    Hope you all enjoyed the tutorial! Good luck.

  • Permalink for 'Quick Tip: Google Fonts API: You’re Going to Love This'

    Quick Tip: Google Fonts API: You’re Going to Love This

    Posted: May 19th, 2010, 1:57pm MDT by Jeffrey Way


    Google have made two huge announcements today. One of these concerns the Google Fonts API. Simply by linking to a particular font, stored on Google’s servers (save on bandwidth + caching benefits), we now have access to a wide array of custom fonts. Quite literally, you can integrate these fonts into your project in about 20 seconds. It’s as simple as that. Further, due to the operations being performed behind the scenes, these custom fonts will even be recognized back to Internet Explorer 6. I, for one, and am extremely excited about the possibilities, and the font catalog is surely to continue expanding over the coming years.


    Subscribe to our YouTube page to watch all of the video tutorials!
    Prefer to watch this video on Screenr.com? One Step Only

    To take advantage of the Google Fonts API, you only need to link to your desired font, and reference it within font-family. That’s it! When you find yourself integrating a custom font in less than 15 seconds, you’ll laugh with joy! For example:

    <!DOCTYPE html>
    
    <html lang="en">
    <head>
    	<meta charset="utf-8">
    	<title>untitled</title>
    <link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz' rel='stylesheet' type='text/css'>
    	<style>
    	body { font-family: 'Yanone Kaffeesatz', serif; font-size: 100px; }
    	</style>
    </head>
    <body>
         Hello World
    </body>
    </html>
    
    Custom Fonts

    Crazy, isn’t it!? You can refer here for the current list of available fonts. So what do you think?

  • Permalink for 'ASP.NET from Scratch: Master Pages'

    ASP.NET from Scratch: Master Pages

    Posted: May 19th, 2010, 1:36pm MDT by Jeremy McPeak


    This latest lesson in our ASP.NET from Scratch series delves into Master Pages – ASP.NET’s built-in templating engine. You’ll learn what Master Pages are, and how to use Master and Content pages to provide a consistent look and feel to your web application.

    The Complete Series Lesson 5: Master Pages Sell ASP.NET Components on CodeCanyon
    CodeCanyon

    Did you know that you can sell your ASP.NET scripts and components on CodeCanyon? Simply sign-up for a free author account, and start selling!

  • Permalink for 'Top 50 Web Graphics, Admin Skins and Scripts to Accelerate Development'

    Top 50 Web Graphics, Admin Skins and Scripts to Accelerate Development

    Posted: May 18th, 2010, 11:32pm MDT by Travis King


    As the Beatles so elegantly wrote, we could all use a little help from our friends to get by. And when it comes to design and development who couldn’t use a friend to speed things up? Thanks to our sister sites ThemeForest, GraphicRiver and CodeCanyon, there are plenty of web graphics, admin skins and scripts to drop in to your work. Best of all they are all made by our massive community of authors. Today across Tuts+ we’re celebrating and showcasing the quality of marketplace goods to bring over the Tuts+ masses to browse the plethora of super work on sale. So without further ado, here they are!

    1. Admin Skins Complete Liquid Admin Control Panel

    Complex Liquid Admin template contains a login page as well as a modular content page that includes all the elements you could possibly need in your admin. From these elements you should be able to generate pretty much any required page!

    Flexy

    Advanced and easy to use administration theme which comes in 7 different colour variations. The theme is liquid, which means the width of the content area adapts to your browsers window size.

    Admintasia

    Admintasia is a complete backend administration user interface that has the flexibility to house any kind of application. It loads last, it’s intuitive and easy to use, it uses only three small images and it also looks good.

    Simpla Admin

    Simpla Admin is a professional template with a beautiful and user friendly interface. With various smart and intuitive jQuery functions, navigating the interface is a breeze.

    Profi Admin

    Profi Admin is a clean and simple style template but it’s complexity and expandability goes beyond expectations. The big visual menu creates the intuitive navigation while the tabbed and the hidden submenu expands the structure to 3 menu levels. Inspired by the WordPress Administration layout.

    Cleanity Complete Admin

    This professional looking and highly flourished skin is suitable for almost any kind purpose. Cleanity is a compilation of all features you might need on an administration theme.

    Boxie Admin

    Simple, stylish and modern template for your website’s administration

    Wide Admin

    Wide admin is a powerful lightweight backend interface application, ready to use for any software / CMS you want.

    Quik v1 Admin Skin

    Quik is a simple skin for use on little back end applications. It’s just a clean way of presenting say a CMS or some other little app to a client. The general admin template, includes a table style, error and alert styles, a sidebar, tabs, form fields and some general text styles.

    Meta Admin

    Advanced yet easy to use administration panel template. It includes 4 color schemes (blue, green, grey, red) and is divided in a login page and a content page that includes all the the elements you could possibly need in your admin. From these elements you can generate any required page.

    2. Web Graphics Web Ribbons & Corner Graphics

    These ribbons are specially designed for the websites which are indeed of High Quality corner graphics and Featuring ribbons on the websites or products highlighting and need of some cool graphics like seal icons ribbons on featured products or some highlight banners and money back guarantee ribbons etc

    Clean Web Navigation Menu

    Cool, clean and contemporary Web navigation menu using Arial font. I have used Arial because it is freely available across all operating systems, but you can change the to whatever you want! Menu comes in three flavors! File includes a fully layered Photoshop PSD version and a fully editable Fireworks vector PNG file.

    Shoppify Buttons

    Set includes 5 buttons with icons: – Buy now (with price tag) – Download – FREE Trial – Take a Tour – Live Demo

    Badges and Sale Tags for Online Shop

    Attractive Online Shop Badges and Tags for your Online Shop, Make your Products/Promos Speak More

    Light Arrow Buttons

    This is a pack of arrow buttons for web sliders, scroll boxes, or anything that needs arrows!

    Stylish Menu For CSS Sprites

    This is a very Stylish menu including a fully layerd PSD file, it could be used for a CSS Sprite menu or whatever type of menu.

    Great Web boxes

    2 Different designs 3 different color scheme (you can create many more)

    Web Pricing Tables & Premium Buttons

    These boxes are specially designed for the websites which are indeed of web 2.0 styled pricing tables boxes or featuring any tables or comparision tables on the websites and need of some cool graphics like download now or register now buttons, banners and signup buttons etc.

    Clean Navigation Menu

    Fully-editable, fully-layered Photoshop file. You can very easily change the gradient of the menu.

    Web Elements – Volume 1

    A detailed, large collection of layered, grouped and named web elements that can be easily edited.

    Shadows Pack for Web Boxes

    Spice up your plain html container with a simple but stylish web2.0 style shadow!

    Tags Stickers and Labels

    This set of tags, stickers and labels features 100% photoshop paths, NO raster layer at all. ensures easy scalability and editing.

    10 Styles of Login/Signup

    These Login/Signup screen elements are designed in Adobe Photoshop CS4 , and to be used for your projects of web application and or website. You can modify or can change their colors according to your project theme. Each Login/Sign-up design is layered and categorized in layer groups.

    We’re on a Break

    Unique style of under maintenance screen, a full layered Photoshop file, very easy to edit text.

    Clean Web Menus

    This is a fully-editable, fully-layered Photoshop file for clean, stylish web menus.

    Premium Gold and Platinum Seals

    Gold and Platinum Seals for everyone, maybe used for web and for graphics too, as it’s dimension is 2267 by 1442, now that’s large baby! -Includes the item preview and 2 ready-made PNG file, that was created using the save for web feature of photoshop at 15% of actual size.

    User Interface Elements – Simple White

    Easily customizable web design / application / user interface elements in one consistent, clear style.

    Web Photo Frames

    Give the smaller photos on your site a Polaroid look with a sexy spin. This set of web photo frames gives the photos on your website a clean border with the option of a title.

    Delicious Buttons

    Fully editable .psd vector buttons with 2 stylish colours (green and gray).

    Web 2.0 Buttons, Social icons & Product Showcase

    Website and internet Web 2.0 Buttons, both normal and rollover are included(except small button – no rollover state). buttons contains texts and icons.

    3. 404 Pages AK – 404 Error Pages

    These template pages can use for 404 errors on your web site. It comes by 8 different themes.

    404 Idea Style

    Beautiful 404 Error Page inspired by Idea Template. Site links included for better user experience.

    Sleek Server Error Pages

    This is a clean, web 2.0 design for website / server error pages. It is flexible and very easy to customize. It comes with 5 of the most common error pages (404, 403, 401, 500 and 503) but it’s very easy to add more if needed. All

    404 Pingu

    Funky Pingu 404 page. Suitable for every website. Give it a try!

    Oops…404 Page Template

    This is a nice, clean modern and solid template for your 404 page. It is designed to go straight to the point.

    Modern Error Page Template

    These template pages can be user for any HTTP errors on your website. It comes in 5 color variations (purple, blue, red, green and orange) and 5 error codes (401, 403, 404, 500 and 503).

    Smart 404 Page

    A Simple 404 Error Page in 6 Different Color Variations with there respective psd’s.

    Fancy Jquery 404 Error Popup

    This is a JQUERY script that is simple, unobtrusive, no need extra markup and is used to display 404 error in fancy popup box on the current page instead of redirecting to 404 page.

    Powerful Errors – PHP/Ajax error template

    This is a very useful and adaptable error template which features jQuery animation and effects as well as an Ajax Error Report form in PHP.

    Creative 404 Error Page

    Error pages are often overlooked by many designers. No more ugly 404/503/500 pages! Produce the wow effect.

    3. Scripts Twitter Reactions

    Twitter Reactions is a quick and easy method of displaying Tweets on a website that mention that particular page. It is a simple script that can be easily integrated on any website as long as your have access to the source code.

    Sexy Slider

    SexySlider is a JQuery plugin that lets you easily create powerful javascript Sliders with very nice transition effects. Enhance your website by adding a unique and attractive slider.

    jSocial

    With jSocial you can easily place social share buttons under your articles and pages on your website. This script uses the jQuery framework and works completely client side. So you can use it on static and dynamic webpages.

    Sticky Nav Menu

    If you’ve ever seen those neat little bars that stick to the bottom of a website – like the one at Envato.com – this mimics that functionality.

    FeaturedBox

    With this script you can make a nice interactive slide gallery like you find on every big site these days. Because the script is highly customizable you can use this script for lots of purposes.

    Put Me On The Map

    Put Me On The Map is simple JavaScript component that marks a location on The Google Maps based on its street address. This is a useful component for any “Contact Us” page on your website to mark exactly where you are located.

    Smart Menu

    Smart Menu is simple JavaScript driven menu, which is written on top of jQuery framework.

    My Video Channel

    My Video Channel is a jQuery based script which makes it possible to display a list of YouTube videos from a specific user and play them in your own website.

    Flickr Import

    Flickr Import is an extremely lightweight, quick and robust tool to display photos from Flickr onto your website.

    tweetGrab

    tweetGrab is an unobtrusive jQuery plugin and a jQuery-ed Wordpress plugin that simplifies and enhances the process of embedding and referencing individual Tweets, @user feeds, #hashtag feeds, $ticker feeds, and general search results.

    Got something to sell? Become an Author!

    Authors on the Envato Marketplaces earn literally thousands of dollars a month. The absolute highest selling author makes over $25,000 every month. Of course he’s got more talent in his left thumb than most of us can dream of, but even so regular authors can still earn a good income on the side. Best of all it just keeps trickling in, no matter what you are doing, no matter where you are. So if you think you have the skills and know-how to make files like the ones showcased here, head over and become an author!

  • Permalink for 'Quick Tip: Making a Fancy WordPress Register Form from Scratch'

    Quick Tip: Making a Fancy WordPress Register Form from Scratch

    Posted: May 18th, 2010, 6:35pm MDT by Ivor Padilla


    In this tutorial, I will guide you through the process of making a beautiful “Register” form, using Fancybox, jQuery, and, of course, WordPress. As you’ll find, the process is really quite simple.

    Step 1. The Markup

    First, let’s place our button at the top of the page, replacing the default description in the theme.

    <div id="registration"><a class="show register-button" href="#register-form">Register</a></div>
    

    Notice that in the register button, the href (#register-form) is the same ID as the form below. We’re also using the class “.show” to call FancyBox with jQuery.

    We need our base; let’s create our markup. Open header.php, and place this following snippet anywhere you’d like.

    <div style="display:none"> <!-- Registration -->
    		<div id="register-form">
    		<div class="title">
    			<h1>Register your Account</h1>
    			<span>Sign Up with us and Enjoy!</span>
    		</div>
    			<form action="" method="post">
    			<input type="text" name="" value="Username" id="" class="input"/>
    			<input type="text" name="" value="E-Mail" id="" class="input" />
    				<input type="submit" value="Register" id="register" />
    			<hr />
    			<p class="statement">A password will be e-mailed to you.</p>
    			</form>
    		</div>
    </div><!-- /Registration -->
    

    Note that I’m using display:none to hide the form initially.

    Step 2. CSS

    The CSS is rather simple; I’m merely styling a quick form design in PhotoShop.

    The form, minus the styling, looks like so: (note that I’ve removed the display:none in the markup to check my styles)

    Let’s next begin styling our box.

    div#register-form {
    	width: 400px;
    	overflow: hidden;
    	height: 230px;
    	position: relative;
    	background: #f9f9f9 url(images/secure.png) no-repeat 260px 40px;
    	font-family: Helvetica Neue, Helvetica, Arial !important;
    }
    

    Continuing on, I’ll now style the text inputs, adding some fanciness.

    div#register-form input[type="text"] {
    	display: block;
    	border: 1px solid #ccc;
    	margin: 5px 20px;
    	padding: 9px 4px;
    	-moz-border-radius: 4px;
    	-webkit-border-radius:4px;
    	width: 200px;
    	font-family: Helvetica Neue, Helvetica, Arial !important;
    }
    
    div#register-form input[type="text"]:hover {
    	border-color: #b1b1b1;
    }
    
    div#register-form input[type="text"]:focus {
    	-moz-box-shadow: 0 0 3px #ccc;
    	-webkit-box-shadow: 0 0 3px #ccc;
    }
    

    Now, I’ll style the button, adding a hover state, and replacing the default button with an image.

    div#register-form input[type="submit"]#register {
    	background: url(images/register.jpg) no-repeat;
    	border: 0;
    	clear: both;
    	cursor: pointer;
    	height: 31px;
    	overflow: hidden;
    	position: relative;
    	left:295px;
    	text-indent: -9999px;
    	top:42px;
    	width:92px;
    }
    div#register-form input[type="submit"]#register:hover {
    	background-position: 0 -32px;
    }
    

    Finally, we add some general styling.

    div#register-form span {
    	display: block;
    	margin-bottom: 22px;
    }
    
    div#register-form div.title {margin-left:15px}
    div#register-form div.title h1,
    div#register-form div.title span {text-shadow:1px 1px 0px #fff}
    div#register-form div.title h1 {
    	margin:7px 0;
    }
    
    p.statement {
    	position:absolute;
    	bottom:-2px;
    	left:10px;
    	font-size:.9em;
    	color:#6d6d6d;
    	text-shadow:1px 1px 0px #fff;
    }
    

    Voila! we have our form. Now, let’s move forward with the jQuery functionality.

    Step 3. jQuery

    First, we need to include jQuery within WordPress. To achieve this, we need to place the following chunk of code before the <head> tag within the header.php file. Remember, as WordPress itself utilizes jQuery, we don’t want to potentially load it twice!

    <?php wp_enqueue_script("jquery"); ?>
    <?php wp_head(); ?>
    

    Download Fancybox and place it in your WordPress folder. To organize things a bit more, I’ve created an “Includes” folder.

    Next, open your footer.php file, and place the following before the end of the </body> tag

    <link rel="stylesheet" type="text/css" href="<?php bloginfo('template_url'); ?>/includes/fancybox/jquery.fancybox-1.3.1.css" media="screen" />
    	<!-- Javascript -->
    <script type="text/javascript" src="<?php bloginfo('template_url'); ?>/includes/fancybox/jquery.mousewheel-3.0.2.pack.js"></script>
    <script type="text/javascript" src="<?php bloginfo('template_url'); ?>/includes/fancybox/jquery.fancybox-1.3.1.pack.js"></script>
    

    And now, let’s call the fancybox method; paste this after the code above and before the closing body tag.

    		jQuery(document).ready(function() {
    			jQuery(".show").fancybox({
    				'titleShow'		: 'false',
    				'transitionIn'		: 'fade',
    				'transitionOut'		: 'fade'
    			});
    		});
    

    We’re done! Our form has been created; we lastly just need to pass the necessary WordPress information to make it function properly.

    Step 4. WordPress

    There is nothing fancy here; we only require two WordPress snippets, hidden within the wp-login.php file.

    The first snippet:

    <?php echo site_url('wp-login.php?action=register', 'login_post') ?>
    

    And:

    <?php do_action('register_form'); ?>
    

    The final code should look like so:

    <div style="display:none"> <!-- Registration -->
    		<div id="register-form">
    		<div class="title">
    			<h1>Register your Account</h1>
    			<span>Sign Up with us and Enjoy!</span>
    		</div>
    			<form action="<?php echo site_url('wp-login.php?action=register', 'login_post') ?>" method="post">
    			<input type="text" name="user_login" value="Username" id="user_login" class="input" />
    			<input type="text" name="user_email" value="E-Mail" id="user_email" class="input"  />
    				<?php do_action('register_form'); ?>
    				<input type="submit" value="Register" id="register" />
    			<hr />
    			<p class="statement">A password will be e-mailed to you.</p>
    
    			</form>
    		</div>
    </div><!-- /Registration -->
    

    Please note that it’s really important, and necessary, to have user_login as a name and as an ID in your text input; the same is true for the email input. Otherwise, it won’t work.

    And with that, we’re done!

    Conclusion

    With a touch of code, and some tweaks, we’ve managed to build a great looking “Register Form” for our users. What do you think?

  • Permalink for 'HVMC: an Introduction and Application'

    HVMC: an Introduction and Application

    Posted: May 18th, 2010, 9:56am MDT by Barry Cogan


    This tutorial is an introduction to the Hierarchical Model View Controller(HMVC) pattern, and how it applies to web application development. For this tutorial, I will use examples provided from the CodeIgniter from Scratch series and demonstrate how HMVC can be a valuable modification to your development process. This introduction assumes you have an understanding of the Model View Controller (MVC) pattern. We suggest you read our introduction to MVC to get acquainted with the topic before tackling this tutorial.

    What is HMVC?

    HMVC is an evolution of the MVC pattern used for most web applications today. It came about as an answer to the salability problems apparent within applications which used MVC. The solution presented in the JavaWorld web site, July 2000, proposed that the standard Model, View, and Controller triad become layered into a “hierarchy of parent-child MCV layers“. The image below illustrates how this works:

    Each triad functions independently from one another. A triad can request access to another triad via their controllers. Both of these points allow the application to be distributed over multiple locations, if needed. In addition, the layering of MVC triads allows for a more in depth and robust application development. This leads to several advantages which brings us to our next point.

    Why should I use HMVC?

    Key advantages to implementing the HMVC pattern in your development cycle:

    • Modularization: Reduction of dependencies between the disparate parts of the application.
    • Organization: Having a folder for each of the relevant triads makes for a lighter work load.
    • Reusability: By nature of the design it is easy to reuse nearly every piece of code.
    • Extendibility: Makes the application more extensible without sacrificing ease of maintenance.

    These advantages will allow you to get M.O.R.E out of your application with less headaches.

    Setting up HMVC in CodeIgniter

    To add extra depth to the CodeIgniter from Scratch series, we will be viewing today’s examples in CodeIgniter. I will lead us though the steps needed to get CodeIgniter working with HMVC. Once we’re done with that, I’ll provide a couple of examples. Let’s begin!

    Preface

    To run web applications, you need a web server on your computer if you are not working remotely. Here are recommendations with links to installation instructions:

    Step 1. Download and Install CodeIgniter

    Go to codeigniter.com and click the “Download CodeIgniter” link. If you know how to install it and want to skip past this step click here

    Extract the contents of the zip file to your web server’s document root.

    Rename the “CodeIgniter_1.7.2” folder to “hmvcExample“.

    Move the “hmvcExample/system/application” folder to “hmvcExample/application“. This is common practice with CodeIgniter. The purpose of doing this is to separate the application from the core of the framework. We should now have a directory that looks like the image below:

    Open “hmvcExample/application/config/config.php” in your editor of choice.

    Edit the site base url to match the location of your install. In my case I would change

    $config['base_url'] = "http://example.com/";

    into

    $config['base_url'] = "http://localhost/hmvcExample/";

    Save your changes and close “hmvcExample/application/config/config.php“

    Test that we have a working version of CodeIgniter. Open your browser and check your “ [yourhost]
    You should be greeted with the “Welcome to CodeIgniter” screen below:

    That’s it! You have successfully downloaded and installed CodeIgniter. Now we will move on to making it work with the HMVC extension.

    Step 2. Download and Install HMVC Extension

    Download version 5.2 of the modular extension from the CodeIgniter Wiki.

    In the contents of the zip file are three php files:

    Move these three files into the “hmvcExample/application/libraries/” folder.

    Recheck your browser. You should still see the Welcome to CodeIgniter screen.

    It’s time to add the modules. Create the following directory structure “application/modules/welcome/controllers/“.

    Move the “application/controllers/welcome.php” to “application/modules/welcome/controllers/welcome.php“.

    Recheck your browser. You should still see the Welcome to CodeIgniter screen.

    Create the folder “application/modules/welcome/views/“

    Move the “application/views/welcome_message.php” to “application/modules/welcome/views/welcome_message.php“.

    Do a final check on your browser. You should still see the Welcome to CodeIgniter screen.

    That’s it! Modular Extensions is installed correctly.

    Login Module Example

    Now that we have our HMVC enabled instance of CodeIgniter, I will demonstrate some short examples. For our first example I will show how you can apply user access restrictions to pages or entire modules.

    Download and unzip CodeIgniter from Scratch Day 6 source files into your web server. You should end up with a folder called “ci_day6/” alongside our “hmvcExample/“

    Create the “login” module in our “hmvcExample/application” directory. It should end up looking like this

    	hmvcExample/application/modules/login/controllers/
    	hmvcExample/application/modules/login/models/
    	hmvcExample/application/modules/login/views/
    

    Create the “site” module in our “hmvcExample/application” directory. It should end up looking like this

    	hmvcExample/application/modules/site/controllers/
    	hmvcExample/application/modules/site/models/
    	hmvcExample/application/modules/site/views/
    

    TIP: When working with modules I keep a folder named RENAME with the three empty folders controllers, models and views. This saves me a little bit of time anytime I wish to create a new model.

    Now we copy over the login module files from “ci_day6/” to our “hmvcExample/“.

    	ci_day6/application/controllers/login.php
    	ci_day6/application/models/membership_model.php
    	ci_day6/application/views/login_form.php
    	ci_day6/application/views/signup_form.php
    	ci_day6/application/views/signup_successful.php
    

    Copy/Move each of the above files over as listed below

    	hmvcExample/application/modules/login/controllers/login.php
    	hmvcExample/application/modules/login/models/membership_model.php
    	hmvcExample/application/modules/login/views/login_form.php
    	hmvcExample/application/modules/login/views/signup_form.php
    	hmvcExample/application/modules/login/views/signup_successful.php
    

    Next we copy over the site module files from “ci_day6/” to our “hmvcExample/“.

    	ci_day6/application/controllers/site.php
    	ci_day6/application/views/logged_in_area.php
    

    Copy/Move each of the above files over as listed below

    	hmvcExample/application/modules/site/controllers/site.php
    	hmvcExample/application/modules/site/views/logged_in_area.php
    

    The last files to copy over are the global views and CSS and image files. The asterisk (*) denotes folder and all its contents including sub folders

    ci_day6/css/*
    ci_day6/img/*
    ci_day6/application/views/includes/*
    

    Copy each of the above folders and all their content over as listed below

    hmvcExample/css/*
    hmvcExample/img/*
    hmvcExample/application/views/includes/*
    

    Open “hmvcExample/application/config/autoload.php” and edit it to look like the this:

    $autoload['libraries'] = array('database', 'session');	// Need to Autoload DB and Session
    
    /*
    | -------------------------------------------------------------------
    |  Auto-load Helper Files
    | -------------------------------------------------------------------
    | Prototype:
    |
    |	$autoload['helper'] = array('url', 'file');
    */
    
    $autoload['helper'] = array('url', 'form');		// Need to autoload url and form.
    

    If you have not already done so from step one, open “hmvcExample/application/config/config.php” and edit it so that the base url is set to your appropriate location.

    $config['base_url'] = "http://localhost/hmvcExample/";	// web address. WARNING keep trailing /
    

    Open “hmvcExample/application/config/database.php” and add the appropriate links to your database.

    $db['default']['hostname'] = "localhost";		// location of DB server
    $db['default']['username'] = "YOUR USERNAME HERE";	// username you use to connect
    $db['default']['password'] = "YOUR PASSWORD HERE";	// associated password
    $db['default']['database'] = "ci_series";		// The database you want to use
    

    Open your browser to test that the login page displays “ [localhost]

    Now to make this login function, we need to create the membership database table. For this, we need to create a table in your PHPMyAdmin.

    Select or create your “ci_series” database.

    In the sQL tab, paste the code below into the textarea and click go

    CREATE TABLE  `ci_series`.`membership` (
    `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `first_name` VARCHAR( 32 ) NOT NULL ,
    `last_name` VARCHAR( 32 ) NOT NULL ,
    `email_address` VARCHAR( 64 ) NOT NULL ,
    `username` VARCHAR( 32 ) NOT NULL ,
    `password` VARCHAR( 32 ) NOT NULL
    ) ENGINE = MYISAM ;
    

    With the membership table created, we click on the create account link on the login page and add a user to the database.

    Login in as the user and confirm that you are now in the “site/members_area” of the site. It should look similar to the image below:

    Click “logoff” link and try to manually go back to the members area. you will see that you no longer have permission to do so.

    So we have our triads grouped, but we are still not quite in HMVC mode yet. In the site controller we find a function called is_logged_in().

    	function is_logged_in()
    	{
    		$is_logged_in = $this->session->userdata('is_logged_in');
    		if(!isset($is_logged_in) || $is_logged_in != true)
    		{
    			echo 'You don\'t have permission to access this page. Login';
    			die();
    		}
    	}
    

    This is a login related function. In MVC mode, this is required because site cannot access login. With HMVC we can fix this.

    Cut the is_logged_in() function out of “applications/modules/site/controllers/site.php“

    Save site.php without the is_logged_in() function.

    Open “applications/modules/login/controllers/login.php“.

    Paste the is_logged_in() function into the class.

    Save login.php

    Open “applications/modules/site/controllers/site.php“.

    	function __construct()
    	{
    		parent::Controller();
            $this->is_logged_in();
    	}
    

    In the __Construct() function, we make the HMVC call to login’s is_logged_in() function, as seen below:

    	function __construct()
    	{
    		parent::Controller();
            // Format: modules::run('module/controller/action', $param1, $param2, .., $paramN);
            modules::run('login/is_logged_in');
    	}
    
    MVC 101 Complete

    There you have it! We have successfully altered day six code into HMVC format. The site module now requests the login check instead of having to use its own. While outwardly we observe no difference, the site design has fundamentally been changed. All login functions are now where they belong: inside the login triad. This may seem like a lot of work with small reward but it is not so. Any login changes can be made once. The internal structure of the triad can be edited without having to change the entire application in response. Code replication for other controllers is no longer required. Last but not least, all the related code is in one handy location. This tiny step may not WOW you but when we delve deeper into bigger, complex applications, the M.O.R.E. apparent it will become how effective the HMVC pattern is.

    Members Section Example

    We are now going to uncover more of HMVC’s power. We just demonstrated how to call a module from a controller. There are other places you can do that as well. HMVC was build with the User Interface (UI) in mind. We get to call modules from our views as a result. This is where the power of HMVC can really shine.

    When calling HMVC from a view you will use the same modules::run(). There is only one requirement when doing this. The resulting output from the call must be a html snippet and not a complete view. This is because we are already inside a view at the time we call the run function. We will see this in action down the page as we edit the site module views.

    Step 1. Edit Login Controller

    We are going to create a block which appears on the top of every page with our user’s name, important links, and logout option. Widgets like this are commonplace on sites today. The image below illustrates the end result.

    Open “applications/modules/login/controllers/login.php“.

        function cp()
        {
            if( $this->session->userdata('username') )
            {
                // load the model for this controller
                $this->load->model('membership_model');
                // Get User Details from Database
                $user = $this->membership_model->get_member_details();
                if( !$user )
                {
                    // No user found
                    return false;
                }
                else
                {
                    // display our widget
                    $this->load->view('user_widget', $user);
                }
            }
            else
            {
                // There is no session so we return nothing
                return false;
            }
        }
    

    Paste/Write the code above into the login controller.

    cp() receives information from the membership_model function, get_member_details(), which we create in the next step. If a user is found we will display the view snippet detailed in step three. From there we should get the desired block illustrated above.

    Save the changes you made to login.php

    Step 2. Edit Membership Model

    You will notice that we called a get_member_details() from the membership_model. This function gets our user information from the database and will be accessed from a few different sources. We are going to work on that now.

    Open “applications/modules/login/models/membership_model.php“.

    	function get_member_details($id=false)
    	{
    		if( !$id )
    		{
    			// Set Active Record where to the current session's username
    			if( $this->session->userdata('username') )
    			{
    				$this->db->where('username', $this->session->userdata('username'));
    			}
    			else
    			{
    				// Return a non logged in person from accessing member profile dashboard
    				return false;
    			}
    		}
    		else
    		{
    			// get the user by id
    			$this->db->where('id', $id);
    		}
    		// Find all records that match this query
    		$query = $this->db->get('membership');
    		// In this case because we don't have a check set for unique username
    		// we will return the last user created with selected username.
    		if($query->num_rows() > 0)
    		{
    			// Get the last row if there are more than one
    			$row = $query->last_row();
    			// Assign the row to our return array
    			$data['id'] = $row->id;
    			$data['first_name'] = $row->first_name;
    			$data['last_name'] = $row->last_name;
    			// Return the user found
    			return $data;
    		}
    		else
    		{
    			// No results found
    			return false;
    		}
    

    Comment your code! It’s a best practice and will help others understand what you wrote.

    Line 01: The function call has a default variable $id. This allows us an option of finding a user by ID rather than by username. This made optional by setting it to false in the declaration.

    The rest of the function is straight forward and well commented. We query the membership table for a user via username or ID. The result is saved to the $data array and returned. All other outcomes return false.

    Save the changes you made to membership_model.php

    Step 3. Create User Widget View

    The third and final piece to the widget we are creating is the xhtml snippet, which we can put into any other view. This is called by the login controller’s cp() function which we just wrote.

    Open “applications/modules/login/views/user_widget.php“.

    <code style="font-family: Monaco, Verdana, Sans-serif;
                     font-size: 12px;
                     background-color: #f9f9f9;
                     border: 1px solid #D0D0D0;
                     color: #002166;
                     display: block;
                     margin: 14px 0 14px 0;
                     padding: 12px 10px 12px 10px;">
    	<?php echo $first_name.' '.$last_name; ?> &middot;
    	<?php echo anchor('site/members_area', 'Dashboard'); ?> |
    	<?php echo anchor('site/profile/'.$id, 'Profile'); ?> |
        <?php echo anchor('site/messages/'.$id, 'Messages'); ?> |
    	<?php echo anchor('login/logout', 'Logout'); ?>
    </code>
    

    Note: It is not a good practice to use inline styling. I opted to put this one instance of inline style for the sake of remaining on topic.

    This styled code block takes the information passed from the cp() function. We generate the links using CodeIgniter’s URL helper’s anchor() function. More information about the user guide can be found on codeigniter.com.

    After working on those three files we will test the “login/cp” page. We should see something like the image below. Note: You need to be logged int to see it. Be sure to do so before checking the page or you will see nothing.

    Step 4. Edit Site Controller

    The links in the snippet to profile and messages will return an error for the moment. This is ok because we have not created those functions yet. Lets do that now.

    Open “applications/modules/site/controllers/site.php“.

    <?php
    class Site extends Controller
    {
    	function __construct()
    	{
    		parent::Controller();
    	}
    
    	function members_area()
    	{
    		modules::run('login/is_logged_in');
    		$this->load->view('logged_in_area');
    	}
    

    __construct()
    For the purpose of this example we shall remove the…

    modules::run('login/is_logged_in');

    …from the function so that we can make specific parts private and have other parts public.

    members_area()
    We want only logged in users to access the members dashboard area. So we will use the modules:run HMVC function and call the is_logged_in check from the login controller. We then load the logged_in_area view file which will be edited further down the page.

    	function messages()
    	{
    		modules::run('login/is_logged_in');
    		$this->load->model('login/membership_model');
    		$user = $this->membership_model->get_member_details($this->uri->segment(3));
    		if( !$user )
    		{
    			// No user found
    			return false;
    		}
    		else
    		{
    			// display our widget
    			$this->load->view('member_messages', $user);
    		}
    	}
    

    messages()
    Like members_area(), we only want logged in users so we have included the is_logged_in check. We have already written the code on how to get user details from the database so we will load the login model, membership_model. This will allow us to get the user information via the get_member_details() function. The third URI segment being passed into that function is an id for the user we wish to get messages for. For example, if the url was:

     [localhost] 

    Then our function get_member_details() would be receiving “43″ as an input variable. Depending on the result of get_member_details(), we are either shown the view: member_messages or we get nothing (as a result of a failed query).

    	function profile()
    	{
    		$this->load->model('login/membership_model');
    		$user = $this->membership_model->get_member_details($this->uri->segment(3));
    		if( !$user )
    		{
    			// No user found
    			$data['main_content'] = 'member_profile';
    			$data['notice'] = 'you need to view a profile id';
    			$this->load->view('includes/template', $data);
    		}
    		else
    		{
    			// display our widget
    			$user['main_content'] = 'member_profile';
    			$this->load->view('includes/template', $user);
    		}
    	}
    }
    

    profile()
    Just like any social network; we want the profile pages to be public. So we have not included the is_logged_in check. Just like messages, we call the login triad’s membership_model and query the database for our desired user. In this case, if no user is found, we quit a bit more gracefully. We also notify the visitor that an id needs to be specified. With a successful result, we see the member’s profile.

    Step 5 Edit Logged In Area View

    Open “applications/modules/site/views/logged_in_area.php“.

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta [http-equiv="Content-Type"] content="text/html; charset=utf-8">
    	<title>untitled</title>
    </head>
    <body>
    	<?php echo modules::run('login/cp');?>
    	<h2>Welcome Back, <?php echo $this->session->userdata('username'); ?>!</h2>
         <p>This section represents the area that only logged in members can access.</p>
    </body>
    </html>
    

    Overwrite the contents of the file with the code above.

    Line 08: HMVC is put into action here. Our view calls the “login/cp” function, and echoes out the html snippet exactly where we tell it. Notice how we didn’t have to prepare anything ourselves? It’s all handled internally by login for us. Handy isn’t it?

    Save the changes you made to logged_in_area.php. Your finished page should display like:

    Step 6. Create Member Messages View

    Create a new view: “applications/modules/site/views/member_messages.php“.

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta [http-equiv="Content-Type"] content="text/html; charset=utf-8">
    	<title>untitled</title>
    </head>
    <body>
    	<?php echo modules::run('login/cp');?>
    	<h2><?php echo $first_name; ?>'s Messages</h2>
         <p>This could be where the messaging system gets displayed</p>
    </body>
    </html>
    

    Write or paste the code above into the newly created file.

    This view is pretty much just a clone of the members area to test that login holds on multiple pages. There is one difference: we fished some information from the login module’s membership_model. This is shown as the $first_name variable.

    The point of getting user information here would be to pass it on to a module which would return a snippet with the user’s messages.

    Save the changes you made to member_messages.php. Your finished page should display like:

    Step 7. Create Member Profile View

    Create a new view: “applications/modules/site/views/member_profile.php“.

    	<?php echo modules::run('login/cp');?>
        <?php if( isset($notice) ): ?>
        <h2>Member Profile Pages</h2>
        <p><?php echo $notice; ?></p>
        <?php else: ?>
    	<h2><?php echo $first_name; ?>'s Profile</h2>
         <p>Put all the good wholesome profile info here!</p>
    	<?php endif; ?>
    

    Write or paste the code above into the newly created file.

    We have an if statement which detects whether a user was found or not. If not, we get brought to an error page stating we need an ID to view a profile.

    Again, we retrieve the user information. Just like messages we would use this to retrieve the user’s friend list, latest blog entry, and activity feed, etc.

    Save the changes you made to member_profile.php. Your finished page should display like:

    What Happens When We Logoff?

    Because we want the profile pages to be public, it should still display. Minus the user widget of course.

    When logged in, and we go to profile without a third uri segment we see our own profile. Logded off, we will be shown the error below.

    We should not be able to view the message or dashboard. When we check the messages page we are greeted with this:

    We’re Done

    That’s it! We have added more depth to our initial example and demonstrated the different ways to use HMVC.

    • Call modules::run() from a controller.
    • Echo modules::run() from a view to display a HTML snippet.
    • Load a model from another module.

    I hope this has been an enlightening experience. HMVC is an extraordinary pattern which makes applications more robust. It is well worth the investment. Give it a try. I promise you won’t ever want to go back to vanilla MVC!

  • Permalink for 'One Developer’s Switch from PC to Mac'

    One Developer’s Switch from PC to Mac

    Posted: May 17th, 2010, 10:16am MDT by Andrew Burgess


    If you’ve watched/read my latest tutorial and screencast, you may have noticed a change: I’ve switched from Windows to Mac. If you’re curious about this change, wonder no more. I’ll tell you why I made the change and give you some reasons you might consider switching, as well as what trip-ups you might run into in the process.

    The Story

    Before I get into why I switched, there’s some background you need to know. A year or three ago, you’d be hard pressed to find a more dedicated self-ordained Windows evangelist. I even wrote a lengthly piece about Mac vs. Windows and how I thought Windows had a stronger position (thankfully, that was only published on Google Docs, so no one can ever find it, as it was obviously biased). Over time, a few things happened. First, a couple of my cousins—shoutout to Britt and Matt—came in possession of a couple of MacBooks. Since I see them rather regularly, there was no shortage of opportunities for them to tout their new tools.

    Have you ever tried to resist brainwashing?

    The next big shift was dabbling in several dynamic programming languages, like Python and Ruby. It seems that it’s always easier to start up with these languages if you’re using a Unix-based OS. While it’s definitely not impossible on Windows, they don’t seem to integrate with the OS in the same way they do with Unix flavours.

    Of course, there were better reasons than peer pressure (more on that in a minute). However, when my Windows 7 Release Candidate ran out, I gave myself an ultimatum: either buy Window 7 and secondary monitor, or get a used Mac. After a week or so of deliberation, I found myself in a miniature Starbucks in downtown Toronto, buying a 20-inch iMac off a third-year psychology student.

    The Reasons Why I Switched

    So what came out of those few weeks of deliberation? Here’s why I switched:

    1 Unix

    Probably the biggest motivation to switch was the fact that Mac OS X is built on Unix. Being a real geek, I’m reasonably comfortable with the terminal; if you’re the same, you probably know that a Unix shell offers a lot more power than the Windows command line. Yes, I’ve tried Cygwin, but it’s not quite the same (and I never actually got it to work on Window 7 RC). Then there are Ruby and Python, so much more at home on Unix. And of course, there are so many other low-level benefits to running Unix.

    So why didn’t I just switch to Ubuntu? Well, Ubuntu is really nice, especially the latest release, but it really just didn’t work for me, not for a full time gig.

    2 Hardware Hardware

    This one’s a no-brainer: Apple just makes their hardware better than most of the competition. I know that beauty is in the eye of the beholder, and that all that’s beautiful is not aluminium. However, I like Apple’s minimalistic stance. And of course, it’s what insides that matters most, and Apple does an excellent job there, too. There’s a catch to Apple hardware, though, and we’ll talk about that later.

    3 Software Software

    The final reason was simply this: there’s a lot of great software for Macs that doesn’t have a good Windows counterpart. There are two cases I ran into. First, there’s nothing on Windows that does as well, or at all, what I’ve found in a Mac app. Example: I use Simplenote a lot on my iPod Touch; there are four or five Mac apps that sync with Simplenote; before I switched, I had to use a perl script to do this on Windows. (Now, Uri Fridman has made Notes, which is based on Notational Velocity, and will soon support Simplenote sycing! Check out his site for other great nuggets; Codex is another of my favourites). Then, there are programs that do the right things, but aren’t as aesthetically pleasing and user-friendly as the Mac apps. For example, I use Evernote a lot; their Windows client does as much (and a bit more, I think) as their Mac client, but it’s just not as pretty.

    However, there’s a catch on the software, too.

    The Good What I’m Liking

    So now that I’ve switched, here are my favourite things about the Mac; some may seem rather insignificant, but when your working full-speed and don’t want to break that flow, little things matter a lot.

    1 The Terminal The Terminal

    I’ve already pointed out that the Terminal was part of my first reason for switching; it’s every bit as glorious as I expected it to be, and has motivated me to use it more that I have on Windows. Anyone who has used the Command Line on Windows and Terminal on Mac will know exactly how much better a Unix shell is.

    2 Languages Preinstalled

    I was surprised and delighted to find that my Mac came with Ruby, Python, Perl, and even Java (which I need for university) already installed.

    3 Mounted Drives on the Desktop Drives

    This is a feature of Unix that I’ve always loved and could never find a way to duplicate on Windows. Not huge, I know; but, huge.

    4 Quicklook Quicklook

    Another tiny feature that saves me a second-and-a-half, dozens and dozens of times a day. I’m working mainly with text files, but for everything from code to Word docs, I’m just a tap on the spacebar away from inspecting the contents of that file. Only gripe: I can’t copy from the quicklook panel.

    5 Time Machine Time Machine

    It’s kind of a hassle to do backup and restore on Windows. With Time Machine, it’s easy and fun. I do wish I had a bit more control over what it backs up and how often (without the numerous hacks), but for daily backup and revisions, it works flawlessly and easily.

    6 Installing Apps Installing Apps

    Installing apps on Mac is much different from installing them on Windows. They both use extremely different methods; and overall, I think the Mac does it much more smoothly.

    The Bad What I’m not Liking

    But all’s not perfect in any OS; here’s what’s bothering me about the Mac:

    1 The Trash The Trash

    I really don’t get the philosophy of the trash on the Mac; I know you’re not supposed to use the Trash as a holding place for the files you’re not sure about, but why can’t I delete individual files? Why? Here’s a scenario I’ve had: I wanted to get rid of several gigabytes of files, in multiple folders that I’d just zipped into an archive; so, I moved them all to the trash, and then opened the trash to get rid of them permanently. First, I wanted to sort the files by the date/time they were moved to the trash, but that’s not a feature Jobs would ever need, and so I can’t do it. That’s when I found I couldn’t delete individual items; just all or nothing. Mighty inconvenient, if you ask me. I should have used the Terminal to terminate them.

    2 Too Few USB ports

    My 20-inch iMac has fewer USB ports than my Dell Laptop did; it only has 3; my Inspiron 1520 had 4; how do you explain that? Then, the old USB extender I was using on Windows doesn’t appear to work on the Mac; not Mac’s fault necessarily, but certainly less than ideal.

    3 “Enter” doesn’t open the file/folder

    This one is just a matter of muscle memory, but it’s rather annoying. On Windows, hitting enter opens a file or folder; on Mac, the enter key renames the item in question. To open it, I’ve got to use two keys: cmd + o. On the same note, it now takes two keystokes to send files to that crooked Trash: cmd + delete instead of just delete.

    4 Home and End Keys

    This has to be the most frustrating part about the Mac. On Windows, the home key places your cursor at the front of the current line; the end key places it at the end. However, on a Mac the respective commands are cmd + left-arrow and cmd + right-arrow. This has been pretty hard to get used to; and, since I’m in text editors a lot of the time, hitting home and end (which, by the way, bring you to the top or bottom of the line but does not move your cursor) has been a dizzying experience.

    5 Keyboard shortcuts Keyboard

    I know I’ve already talked about two specific keyboard shortcuts that bother me, but keyboard shortcuts in general have been hard. It’s mainly because the cmd key takes the place of the ctrl key in the shortcuts, but it takes the place of the alt key on the keyboard. So if you’ve used Windows for a long time, caveat emptor.

    The Other What I’d also like to mention

    I’ve shown you what’s good and what’s bad, but there are a few things I have to mention that don’t really fit into either of those categories. Welcome to miscellaneous.

    1 Closing Windows / Programs

    One of the biggest differences between Windows is Mac what happens when you close a window; on Windows (and with a name like that, they should know how to deal with it) the program closes; on Mac, the window closes but the program continues to run. I think the idea here is that it will be quicker to open just a window instead of the whole app next time you need to open it. This is nice for the most part, but I think some apps of a certain nature should really and truly exit when you close their windows. And some do, like System Preferences. I really wish Preview did this. This is one of those fundamental feature of Mac OS X that really takes a paradigm shift to properly grok.

    2 Knowing what’s going on

    I’m familiar with Windows, to say the least. I had my A+ certification, which deals mainly with Windows, so I have a pretty good idea of what’s going on under the covers when working on Windows PC. I really miss this intimate knowledge of the system when working with a Mac. I know it’s not an unsolvable problem, but it’s been pretty different to not have that background knowledge. For example, I was recently surprised to find that Time Machine has maxed out my external hard drive; it turned out that iTunes copies all the imported media into the iTunes folder, so I had a two copies of the entire library being backed up. Like Sir Francis Bacon said, “Knowledge [about how the system works] is power.”

    3 The software catch

    There’s a ton of great software for Mac; however, it seems that the moving from Windows to Mac also requires a move from free software to quality software. Now, I know there’s quality, paid-for software for Windows, and free software for Macs. However, for every quality, paid-for app on Windows, there are five or six free ones that will do the same job decently. On Mac, the same isn’t quite so true. It seems that Mac developers just put a lot of thought and sweat into their products.

    4 The hardware catch

    Like I’ve said, Apple makes great hardware. However, one thing I know I’m going to miss is the ability to upgrade it. Apple does make it easy enough to add RAM. But when I’m ready to upgrade my hard drive, well, it will be scary at best. But I’d gladly sacrifice the single-piece back-side of my iMac for an easy-to-access hard drive slot.

    5 Switching?

    Throughout this article, I’ve talked about switching to a Mac. And yes, I’ve switched to a Mac as my main workhorse. But my trusty old Dell hasn’t gone anywhere. It’s still in good use, and syncing services like Evenote and Dropbox (referral link) more than ever.

    The Resources What I’ve found Helpful

    Switching operating systems is a pretty big change; here are the resources that have been the biggest help to me while doing so; don’t forget to let me know about other great sources in the comments!

    A Very Important Conclusion

    Switching to Mac has in no way made me an Apple fanboy or a Microsoft hater. I couldn’t say it better than this:

    “Mac vs PC debates make me want to throw up. Does your OS of choice work for you? Great, problem solved!”
    - Drew Douglass

  • Permalink for 'Easy Graphs with Google Chart Tools'

    Easy Graphs with Google Chart Tools

    Posted: May 14th, 2010, 9:53am MDT by Pablo Pastor


    Google Chart Tools provide several ways to easily add charts to any web page. Charts may be static or interactive, and in this tutorial, we’ll learn how to use both of them.

    Static vs Interactive Charts

    There are two different types of graphs that Chart Tools can generate: image charts (static graphs) and interactive charts.

    • Image Charts.- Use the Google Chart API.
    • Interactive Charts.- Use the Google Visualization API.

    Image Charts are quite easy to use, however, interactive charts are far more flexible, because they can trigger events which we can use to interact with other elements in the page.

    First, The Super-Easy Way

    Yes, there is a super-easy way to include a chart in your page – as easy as writing a URL like this:

     [chart.apis.google.com] 

    if you copy and paste this url in your browser, you’ll see the following:

    You can place the image anywhere in your page using the URL as the src attribute of an image tag:

    <img src='http://chart.apis.google.com/chart?cht=p3&chs=450x200&chd=t:2,4,3,1&chl=Phones|Computers|Services|Other&chtt=Company%20Sales&chco=ff0000'>
    

    That’s the Google Charts API. Request are sent as GET or POST URLs, and the Google charts server returns a PNG image in response. The type of chart, data and options are all specified within the querystring of the URL. The API defines how to do that. Let’s review the different options.

    http://chart.apis.google.com/chart?

    This is the base URL; we’ll use it for all image chart requests. The rest are parameters in the form name=value separated by &.

    Mandatory Parameters

    There are only three mandatory parameters: cht, chs, and chd. The rest are optional.

    cht=p3

    This is the chart type. We are using a 3D pie chart which is p3. You can visit the chart gallery for all available chart types.

    chs=450×200

    This is the chart size in pixels (width x height).

    chd=t:2,4,3,1

    This is the data to display in the chart. The first letter (t) indicates the data format. In this case, we are using basic text format which is a list of comma separated values.

    Optional Parameters

    Each chart type has a few optional parameters to configure some aspects of your graph: title, labels, font types, colors, gradients, etc. This is what we have included:

    chl=Phones|Computers|Services|Other

    Chart labels for each pie slice.

    chtt=Company%20Sales

    Chart title.

    chco=ff0000

    Chart color in rrggbb hexadecimal format.

    If you specify one single color, the slices will have different gradations. You can also specify a gradient with two colors (chco=ff0000,00ff00) or a color for each slice (chco=ff0000|3355aa|8322c2|112233).

    This is it for image charts. There isn’t much to it! There are a lot of different chart types available, and, if you play with the parameters, you can get some really nice results. The Google Live Chart Playground is an excellent tool to do this. You play with parameters and see the changes in the generated image – an easy way to fine-tune the url for your graph!

    Interactive Charts

    To include interactive charts in your web pages, you have to use a different API: the Google Visualization API. In this case, the interface is not a URL. You’ll have to use a JavaScript library, and write a few lines of code – but nothing difficult.

    There is a gallery of ready-made visualizations (graphs) that you can use. You can also create and share your own graph, but the visualizations in the gallery will probably cover most of your needs for displaying data.

    The level of interactivity depends on the particular visualizations you use. Usually, the graph will react in a certain way when clicked (showing a tool tip or animating), but the really powerful feature is that they can trigger events and you can register callbacks to perform any action related to that event. Examples of events can be selecting a bar or a pie slice, mouseOver, mouseOut, etc.

    We’ll use local data to feed the visualizations in our examples, but you can obtain your data in any other way. A common option would be to retrieve the data from a database using AJAX. You can even use the Visualization API; it also defines a way to request and offer (for servers) data in a format which can be immediatly used in any visualization, but we won’t cover that here.

    Formatting the Data

    It doesn’t matter how we get our data, but all visualizations need to receive it in a DataTable object. It’s basically a table with rows and columns. Each column is defined with a particular data type (and an ID and a Label which are optional).

    To reference a particular cell in the table, you use the pair (row, column). Row is always a number, starting a zero. Column can also be a zero-based number or an optional ID.

    If we want to display the earnings of our company in 2009 in a column chart, we have to prepare the data in the following way:

    Quarters 2009 Earnings
    Q1 308
    Q2 257
    Q3 375
    Q4 123

    Two columns: the first one (with type ’string’) is the label for each bar in the chart, and the second one (with type ‘number’) is the value for that bar. We have four rows which means well have four bars to display.

    How do we put that in a DataTable object? This is the code to do so – each line is explained later:

    
    //create data table object
    var dataTable = new google.visualization.DataTable();
    
    //define columns
    dataTable.addColumn('string','Quarters 2009');
    dataTable.addColumn('number', 'Earnings');
    
    //define rows of data
    dataTable.addRows([['Q1',308], ['Q2',257],['Q3',375],['Q4', 123]]);
    

    First we create our DataTable object with:

    var dataTable = new google.visualization.DataTable();
    

    Then we define the two columns in our table using the method addColumn(). The first value is the type and the second value is the optional label.

    dataTable.addColumn('string','Quarters 2009');
    dataTable.addColumn('number', 'Earnings');
    

    And finally, we define the data rows using the addRows() method.

    dataTable.addRows([['Q1',308], ['Q2',257],['Q3',375],['Q4', 123]]);
    

    Each row is an array, and all data is also enclosed in another array.

    Rows can also be defined one row at a time:

    dataTable.addRow(['Q1',308]);
    

    or even one cell at a time:

    data.setValue(0, 0, 'Q1');
    

    Here, the first two numbers are the row and column, respectively.

    This is the way to create DataTable objects. Every visualization needs to be loaded with data in this format. That doesn’t mean that the table is the same for every visualization. The particular number and type of columns and rows has to be checked in the documentation for each chart.

    Visualizing our Data as a Column Chart

    For this first example, we’ll use a Column Chart to present our data. In the Google Visualization Gallery, we can click any chart type to see documentation and examples.

    To use any visualization, we have to load the Google AJAX API before; it provides the core functionality needed in many other google APIs.

    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    

    Now we can load the Visualization API using the google.load() function (from the AJAX API):

    google.load('visualization', '1', {'packages': ['columnchart']});
    

    The second parameter, ‘1,’ refers to the version of the API to load (‘1′ means the current version). ‘packages’ is an array with all the visualizations we are going to use. In this case, we’ll use only one: the column chart.

    At this point, we have the necessary libraries to create our DataTable object and display our graph, however, we need to be sure that the visualization is completely loaded, otherwise we’ll get JavaScript errors and our graph won’t display.

    The way to do this is by registering a callback. The function will be called when the visualization (API and package) is loaded.

                //set callback
                google.setOnLoadCallback (createChart);
    

    Function createChart is where we create our data table and our chart. The final, complete code, is:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
        <head>
            <title>Google Charts Tutorial</title>
    
            <!-- load Google AJAX API -->
            <script type="text/javascript" src="http://www.google.com/jsapi"></script>
            <script type="text/javascript">
                //load the Google Visualization API and the chart
                google.load('visualization', '1', {'packages': ['columnchart']});
    
                //set callback
                google.setOnLoadCallback (createChart);
    
                //callback function
                function createChart() {
    
                    //create data table object
                    var dataTable = new google.visualization.DataTable();
    
                    //define columns
                    dataTable.addColumn('string','Quarters 2009');
                    dataTable.addColumn('number', 'Earnings');
    
                    //define rows of data
                    dataTable.addRows([['Q1',308], ['Q2',257],['Q3',375],['Q4', 123]]);
    
                    //instantiate our chart object
                    var chart = new google.visualization.ColumnChart (document.getElementById('chart'));
    
                    //define options for visualization
                    var options = {width: 400, height: 240, is3D: true, title: 'Company Earnings'};
    
                    //draw our chart
                    chart.draw(dataTable, options);
    
                }
            </script>
    
        </head>
    
        <body>
    
            <!--Div for our chart -->
            <div id="chart"></div>
    
        </body>
    </html>
    

    The chart object is created with this line:

    var chart = new google.visualization.ColumnChart (document.getElementById('chart'));
    

    The argument is the DOM reference to the element containing the visualization. In this case, we have a <div id=”chart”></div>.

    Then, we define the options we want and draw the chart:

     var options = {width: 400, height: 240, is3D: true, title: 'Company Earnings'};
     chart.draw(dataTable, options);
    

    Our graph looks like this:

    Note: All images here are static to make the tutorial available regardless of your browser or your JavaScript settings. Review the live demo for the interactive version.

    And a Pie Chart Too

    The advantage of having a clearly defined data format is that once you know how to create and populate a DataTable object, you know how to feed any visualization. You just have to check the documentation to see the particular table (number and type of columns) you have to build.

    For a pie chart, we can use the exact same table we have now. Let’s add a pie chart in the same page.

    We have to add our new package in the google.load() line:

    google.load('visualization', '1', {'packages':['columnchart','piechart']});
    

    and extend our createChart function with these two lines:

    var secondChart = new google.visualization.PieChart (document.getElementById('secondChart'));
    secondChart.draw(dataTable, options);
    

    The complete code is:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
        <head>
            <title>Google Charts Tutorial</title>
    
            <!-- load Google AJAX API -->
            <script type="text/javascript" src="http://www.google.com/jsapi"></script>
            <script type="text/javascript">
                //load the Google Visualization API and the chart
                google.load('visualization', '1', {'packages':['columnchart','piechart']});
    
                //set callback
                google.setOnLoadCallback (createChart);
    
                //callback function
                function createChart() {
    
                    //create data table object
                    var dataTable = new google.visualization.DataTable();
    
                    //define columns
                    dataTable.addColumn('string','Quarters 2009');
                    dataTable.addColumn('number', 'Earnings');
    
                    //define rows of data
                    dataTable.addRows([['Q1',308], ['Q2',257],['Q3',375],['Q4', 123]]);
    
                    //instantiate our chart objects
                    var chart = new google.visualization.ColumnChart (document.getElementById('chart'));
                    var secondChart = new google.visualization.PieChart (document.getElementById('Chart2'));
    
                    //define options for visualization
                    var options = {width: 400, height: 240, is3D: true, title: 'Company Earnings'};
    
                    //draw our chart
                    chart.draw(dataTable, options);
                    secondChart.draw(dataTable, options);
    
                }
            </script>
    
        </head>
    
        <body>
    
            <!--Divs for our charts -->
            <div id="chart"></div>
            <div id="Chart2"></div>
    
        </body>
    </html>
    

    And the generated charts:

    Note: check the live demo for the interactive version.

    This was easy in this case, because both visualizations used the same table columns and rows. But there are visualizations that need more columns or columns of different types, and you cannot use the data table directly. However, you can solve this by generating a different view of the original table to feed a visualization. We’ll review that shortly.

    More Columns for Our Column Chart!

    The data table for a column chart doesn’t have to be as simple as in the previous example. We can have bars representing the earnings for each quarter in the last three years, for example. In that case the data
    table would look like so:

    Quarters Earnings 2009 Earnings 2008 Earnings 2007
    Q1 308 417 500
    Q2 257 300 420
    Q3 375 350 235
    Q4 123 100 387

    The only code we have to change from our first example is the DataTable object, to add two more columns and more data in each row:

    //create data table object
    var dataTable = new google.visualization.DataTable();
    
    //define columns
    dataTable.addColumn('string','Quarters');
    dataTable.addColumn('number', 'Earnings 2009');
    dataTable.addColumn('number', 'Earnings 2008');
    dataTable.addColumn('number', 'Earnings 2007');
    
    //define rows of data
    dataTable.addRows([['Q1',308,417,500], ['Q2',257,300,420],['Q3',375,350,235],['Q4', 123,100,387]]);
    

    The rest of the code does not change. The generated chart is:

    But, what if now we want to use a pie chart to represent part of this data? We cannot use the same data table as we did before, because pie charts need a two-column table (slice label and value). There is an easy way to obtain a different table from an existing DataTable object and use it to feed a chart: data Views.

    Using Data Views

    Views are a way to adapt our table for a different visualization. If we now want to display, in the same page, a pie chart showing the quarterly earnings distribution for last year, the table we need is only this:

    Quarters Earnings 2009
    Q1 308
    Q2 257
    Q3 375
    Q4 123

    A data view (DataView object) allows you to use only a subset of the original data. You can reorder or duplicate columns and rows or introduce columns with calculated values.

    First, create the View object:

    var view = new google.visualization.DataView(dataTable);
    

    A data view is initialized with the original table and then we use the DataView methods to hide, show or filter columns or rows ( setColumns(), hideColumns(), setRows(), hideRows(), getFilteredRows, getColumnRange, etc ).

    We can filter the original table to get only the first two columns (columns 0 and 1) using setColumns():

    view.setColumns([0, 1]);
    

    Now we can draw the pie chart using this view as a data table:

    secondChart.draw(view, options);
    

    Remember that we have to include the piechart package with google.load(), and we have to create the pieChart object with:

    var secondChart = new google.visualization.PieChart
    

    Now we can see both charts generated using the same data table:

    Introducing Events

    Events provide an easy way to connect your visualizations with other elements on your page. Visualizations can trigger some events, and you can register a listener to react to that event and perform some action. The event model is similar to the browser event model. Once again, we have to look at the documentation to check the events triggered for each visualization.

    To show how events work, let’s return to our first example, the simplest column chart:

    This graph triggers events on mouseover, on mouseout and on select. That means we can make it much more interactive than it is by default.

    Since this graphic shows earnings for a company, it could be interesting to show a message with a brief explanation of the most important achievements or sales for each quarter when the user places the pointer over a column (onmouseover event).

    Our callback will be showDetails(), and we register it for the onmouseover event:

    google.visualization.events.addListener(chart, 'onmouseover', showDetails);
    

    The first parameter is the variable that contains our chart object.

    We will also need to hide the message when the pointer goes out of the column so we need another function to be called when onmouseout event triggers:

    google.visualization.events.addListener(chart, 'onmouseout', hideDetails);
    

    Within the <body> or our HTML page we have to define four divs with the messages:

        <body>
    
            <!--Div for our chart -->
            <div id="chart"></div>
    
            <!--Divs for our messages -->
            <div id="details0">These are the details for Q1...</div>
            <div id="details1">Here you have the numbers for Q2...</div>
            <div id="details2">Explanations for the third quarter...</div>
            <div id="details3">Q4 was as expected...</div>
    
        </body>
    

    And then the callback functions just show or hide the corresponding message:

        function showDetails(e) {
            switch (e['row']) {
                case 0: document.getElementById('details0').style.visibility='visible';
                    break;
                case 1: document.getElementById('details1').style.visibility='visible';
                    break;
                case 2: document.getElementById('details2').style.visibility='visible';
                    break;
                case 3: document.getElementById('details3').style.visibility='visible';
                    break;
            }
        }
    
        function hideDetails(e) {
            switch (e['row']) {
                case 0: document.getElementById('details0').style.visibility='hidden';
                    break;
                case 1: document.getElementById('details1').style.visibility='hidden';
                    break;
                case 2: document.getElementById('details2').style.visibility='hidden';
                    break;
                case 3: document.getElementById('details3').style.visibility='hidden';
                    break;
            }
        }
    

    Our functions accept a single parameter: the event fired. This object has all available information about the event details.

    To know what bar we are over, we check the ‘row’ property of the event object. This information refers to the rows and columns of the DataTable object, but we know that row 0 corresponds to Q1, first column, and so on.

    Note: Not all events pass the event object. Sometimes you have to use methods to get the information you need, read the visualization documentation to know how to get the information relative to the event fired.

    The following listing include the complete code for this example. I have included a short internal CSS snippet to hide the message divs, and provide minimal formatting.

    <html>
        <head>
            <title>Google Chart Tools Tutorial</title>
    
            <style type="text/css">
    
                #details0, #details1, #details2, #details3 {
                    visibility:hidden;
                    background: #FFFF7F;
                    border: solid 1px;
                    width: 350px;
                    padding: 5px;
                    font-size:smaller;
                    position:absolute;
                    top: 250px;
    
                }
    
            </style>
    
            <!-- load Google AJAX API -->
            <script type="text/javascript" src="http://www.google.com/jsapi"></script>
            <script type="text/javascript">
                //load thee Google Visualization API and the chart
                google.load('visualization', '1', {'packages': ['columnchart']});
    
                //set callback
                google.setOnLoadCallback (createChart);
    
                //callback function
                function createChart() {
    
                    //create data table object
                    var dataTable = new google.visualization.DataTable();
    
                    //define columns
                    dataTable.addColumn('string','Quarters 2009');
                    dataTable.addColumn('number', 'Earnings');
    
                    //define rows of data
                    dataTable.addRows([['Q1',308], ['Q2',257],['Q3',375],['Q4', 123]]);
    
                    //instantiate our chart objects
                    var chart = new google.visualization.ColumnChart (document.getElementById('chart'));
    
                    //define options for visualization
                    var options = {width: 400, height: 240, is3D: true, title: 'Company Earnings'};
    
                    //draw our chart
                    chart.draw(dataTable, options);
    
                    //register callbacks
                    google.visualization.events.addListener(chart, 'onmouseover', showDetails);
                    google.visualization.events.addListener(chart, 'onmouseout', hideDetails);
                }
    
                function showDetails(e) {
                    switch (e['row']) {
                        case 0: document.getElementById('details0').style.visibility='visible';
                            break;
                        case 1: document.getElementById('details1').style.visibility='visible';
                            break;
                        case 2: document.getElementById('details2').style.visibility='visible';
                            break;
                        case 3: document.getElementById('details3').style.visibility='visible';
                            break;
                    }
                }
    
                function hideDetails(e) {
                    switch (e['row']) {
                        case 0: document.getElementById('details0').style.visibility='hidden';
                            break;
                        case 1: document.getElementById('details1').style.visibility='hidden';
                            break;
                        case 2: document.getElementById('details2').style.visibility='hidden';
                            break;
                        case 3: document.getElementById('details3').style.visibility='hidden';
                            break;
                    }
                }
    
            </script>
        </head>
    
        <body>
    
            <!--Div for our chart -->
            <div id="chart"></div>
    
            <!--Divs for our messages -->
            <div id="details0">These are the details for Q1...</div>
            <div id="details1">Here you have the numbers for Q2...</div>
            <div id="details2">Explanations for the third quarter...</div>
            <div id="details3">Q4 was as expected...</div>
    
        </body>
    
    </html>
    

    And this is the result:

    Once again, check the live demo to see the interactivity.

    The Playground

    As with the static images, there is a Google Code Playground where you can play with your visualizations and parameters, and view the results:

    Conclusion

    Hopefully, this should be enough to get you started with Google Chart Tools. Once you get the hang of it, you’ll find that a huge level of flexibility is available to you in your web applications. Thanks for reading!

  • Permalink for 'Quick Tip: Practical CSS Shapes'

    Quick Tip: Practical CSS Shapes

    Posted: May 13th, 2010, 10:39am MDT by Jeffrey Way


    A common design technique lately is to create a fold effect, where it appears as if a heading is wrapping behind its container. This is generally achieved through the use of tiny images; however, with CSS, we can mimic this effect quite easily. I’ll show you how in four minutes.


    Subscribe to our YouTube page to watch all of the video tutorials!

    Rather watch on Screenr.com?

    Example Final HTML
    <!DOCTYPE html>
    
    <html lang="en">
    <head>
    	<meta charset="utf-8">
    	<title>CSS Shapes</title>
    
    	<!--[if IE]>
    		<style>
    			.arrow { top: 100%; }
    		</style>
    	<![endif]-->
    
    </head>
    <body>
    	 <div id="container">
    
    		<h1> My Heading <span class="arrow"></span> </h1>
    
    	</div>
    </body>
    </html>
    
    Final CSS
    #container {
    	background: #666;
    	margin: auto;
    	width: 500px;
    	height: 700px;
    	padding-top: 30px;
    	font-family: helvetica, arial, sans-serif;
    	}
    
    h1 {
    	 background: #e3e3e3;
    	 background: -moz-linear-gradient(top, #e3e3e3, #c8c8c8);
    	 background: -webkit-gradient(linear, left top, left bottom, from(#e3e3e3), to(#c8c8c8));
    	 padding: 10px 20px;
    	 margin-left: -20px;
    	 margin-top: 0;
    	 position: relative;
    	 width: 70%;
    
    	-moz-box-shadow: 1px 1px 3px #292929;
    	-webkit-box-shadow: 1px 1px 3px #292929;
           box-shadow: 1px 1px 3px #292929;
    
    	color: #454545;
    	text-shadow: 0 1px 0 white;
    }
    
    .arrow {
    	 width: 0; height: 0;
    	 line-height: 0;
    	 border-left: 20px solid transparent;
    	 border-top: 10px solid #c8c8c8;
    	 top: 104%;
    	 left: 0;
    	 position: absolute;
    }
    
  • Permalink for 'Switching to Chrome? Download these Extensions'

    Switching to Chrome? Download these Extensions

    Posted: May 13th, 2010, 9:01am MDT by Toni Kukurin


    When Chrome first entered the browser wars in September 2008, although it quickly acquired a big 1% of the audience, many resented the fact it wasn’t as extensible as the long-time favorite Firefox browser. Developers want add-ons – things that’ll make their coding faster and easier, with less room for mistakes. Things which, let’s face it, Chrome couldn’t yet offer. But things have since changed.

    Chrome features a vast collection of extensions at the moment. It also regularly beats its opponents in various speed and compatibility tests, while the great set of developer tools promoted the browser to a very interesting solution for web enthusiasts. But does it have enough ‘extension power’ to overcome Firefox? Check out the following twenty extensions, and make up your own mind!

    1. Web Developer

    Some of you might be familiar with this plug-in from Firefox. Although the Chrome version can’t disable JavaScript, due to some restrictions from the browser’s side, WDT remains one of the most powerful additions to a web developer’s arsenal.

    You can easily outline different elements of a site, and test it in various environments (for instance, without CSS and images) through the extension. It also offers quick access to important code validation services and some other interesting options.

    2. Pendule

    Though it isn’t filled with features like Chris Pederick’s Web developer toolbar, Pendule proves itself to be worthy of comparison against the famous Firefox add-on.

    Other than the basics (source, images, validators), it contains a couple of very cool tools, like the ruler and the color picker, which will be highly valued by web developers and aren’t a part of WDT.

    3. Chrome Sniffer

    No, Chrome sniffer can’t produce smells equivalent to your screen picture. Sorry. However, if you’d like to find out which frameworks and libraries a particular site uses, that’s an area sniffer can help you with.

    As appealing as looking through someone else’s uncommented code might sound to you, there are times when a web developer doesn’t have time to play games. Sometimes you may just want to figure the library out and get it over with. Is the site using jQuery? Yes? OK, let’s move on. That’s what Code sniffer is all about.

    4. Chrome SEO

    Although still in Beta, Chrome SEO is one of the best search engine optimization analyzers you can find as a browser extension these days.

    It provides easy access to various tools that can help you out with Competitive Analysis, Keyword Research, Backlink Checks, PageRank Checks and other daily SEO tasks.

    5. Speed Tracer

    Speed tracer is an official Chrome extension, developed by Google. It tracks your site performance in real-time, generating reports on various problems that might have occurred while communicating with the server. You can then use these metrics to optimize your code for better site performance.

    Note: You should read the getting started guide before using Speed tracer.

    6. Frame Two Pages

    “Frame Two Pages” does exactly what it sounds like; it splits your two tabs into resizable frames. In other words, your physical screen will be split into independent areas.

    Once you click the extension’s icon, the current tab will be merged with the previous (left) one into a frameset with two rows or columns (frames). Unlike the other similar extensions, “Frame Two Pages” can open links in the same frame they were clicked in.

    7. Snippy

    Snippy allows you to grab snippets from web pages and save them for future use or upload to Google Docs. The extension is very useful when copying a lot of information from various sites, since it shortens the cpoy/paste process to only one simple click.

    8. IE Tab

    No matter how much we hate it, the fact remains that some sites need Internet Explorer to work properly. IE tab acts as if you had the Internet Explorer engine running inside your Chrome browser.

    Although most developers will use IE tab to test their work in Internet Explorer, the extension can also be used to access local (file://) URLs (not possible through Chrome itself).

    9. Color Picker

    Color picker can provide you with both hexadecimal and RGB values of a currently selected color. It does a pretty good job most of the time, but the desired site must be fully loaded at 100% zoom level for best results.

    10. BuiltWith

    Similar to Chrome sniffer, BuiltWith does a great job of understanding which technologies and frameworks a particular site is using. In addition to their names and short descriptions, you’ll be provided with usage statistics and a list of other websites using the same technologies.

    11. Lightshot

    LightShot is a tool which allows you to easily make screenshots of any area of a website. You just hit the Lightshot icon on the toolbar; select an area you want to make a screenshot of, and click “Save” or “Upload to server”. In case of uploading you instantly get a link to the screenshot you’ve just uploaded.

    You can also copy or edit your screenshots (add text, draw lines and more other functions) using an on line tool much reminding of Photoshop.

    12. Xmarks bookmark sync

    If you’re working on multiple computers, you likely know it’s not easy to maintain synchronization between your bookmarks in order. Maybe one of the PCs is using Firefox, the other one Safari, the third Chrome, etc. You can’t just keep copying all your bookmarks between them forever.

    And you don’t have to, because Xmarks will do that for you. It can synchronize across multiple computers and web browsers, and is available as a free extension for Chrome, Firefox, Safari and Internet Explorer.

    13. Web of Trust

    Chrome is an extremely safe browser. The safety measures actually go as far as to start entirely new processes for each tab; so there is very little room for any wandering viruses to crawl thorough and attack your computer. It also warns you if you’re visiting a site that is on the Chrome “blacklist.”

    If you need more security, “Web of Trust” is for you. WOT ratings are powered by the users and their experiences with websites, so it’ll warn you when trying to access a site others have had problems with. It’ll also rate your Google/Yahoo/Bing search results so you are warned about a particular site reputation in advance.

    14. Last Pass

    LastPass is a free online password manager and form filler that easily remembers your on line passwords and auto-fills them for you. The only password you’ll need to remember from now on is the one of your Last pass account!

    15. Chromeshark

    ChromeShark is a Chrome extension containing basic playback controls for your Grooveshark account. You can pause a song, skip it, or stop the playback entirely.

    Note: The extension has problems when multiple Grooveshark tabs are opened.

    16. Recent History

    Chrome has a fairly complicated way of accessing your browsing history. It can be done through two long mouse clicks! That’s why Recent history is such a big time saver. It’s positioned in the right-hand side of your address bar, and allows you to access the recently closed tabs and most recently visited pages from only one pop-up.

    17. L(ink)y URL Shortener

    Twitter users will absolutely adore this extension. It automatically shortens your URLs using the popular Bit.ly URL shortening service. It also remembers the most recent shortened URLs so you don’t have to retype them.

    18. Tab Menu

    For those who like to get carried away opening new tabs in Google Chrome, this tool will be of great assistance. Instead of looking at tiny horizontal tab icons, it gives you a vertical overview of all your current tabs opened and enables searching as well!

    19. Note Anywhere

    With “Note Anywhere,” you can post a sticky note on any page you are viewing, customize it, and then review the note on a later date.

    It can be quite useful when doing on line research, since the sites you posted the stickers on will be remembered in the extension’s options page. They remain posted until you delete them.

    20. Auto Translate

    This translator can be customized according to your preferences, so you can choose when will the translate pop-up appear.

    For instance, you could set it to translate from English when Control double clicked, but to try to detect the language automatically when you Shift select a word.

    Thanks so much for reading. Which ones are your favorites? Any I missed?

  • Permalink for 'New Tuts+ Site ‘Mobiletuts+’ Launched'

    New Tuts+ Site ‘Mobiletuts+’ Launched

    Posted: May 13th, 2010, 1:40am MDT by Skellie


    We’ve been burning the midnight oil at Tuts+ HQ to bring you Mobiletuts+, the youngest member of the Tuts+ family. It’s all about quality tutorials for mobile developers – all mobile developers, regardless of preferred platform. Topics will include native development with the iPhone, Android, Windows and Blackberry platforms, cross-platform development with tools like Titanium and Phone Gap, and techniques for building mobile web apps and mobile accessible web sites with HTML 5. Visit Mobiletuts+ or read more after the jump.

    Whether you want to create the next killer app or become a pioneer of the mobile frontier, we’ve got you covered! In addition to publishing top quality tutorials, articles, and Quick Tips, Mobiletuts+ will be the first Tuts+ site to offer regular multi-media updates on the hottest mobile industry news. We will also be publishing interviews with successful mobile developers to provide you with the most effective real-world development techniques and strategies.

    “But I’ve never done mobile development before!”

    No problem! Mobiletuts+ will grow with its users. Initially we’ll be publishing lots of content on the fundamentals, like our first tutorial: An Introduction to iPhone SDK Development. We’ll be hitting all the major mobile development platforms with our introductory content, then moving on to the more advanced stuff. If you’re a veteran mobile developer, stick with us! The advanced goodness is almost ready to rumble.

    Meet the Editor, Mark Hammonds
      Mark Hammonds, Mobiletuts+ Editor
    • Like all our Tuts+ sites, Mobiletuts+ is helmed by an expert. Mark Hammonds is a software engineer, author, and entrepreneur living in the D.C. / Baltimore area.

      In addition to his work with OmniTI, where he develops high-performance web sites and mobile applications, he is also the co-founder and CTO of Somba Mobile and was among the first developers to publish applications in the iTunes App Store.

    Contribute!

    If you think you have the skills to create screencasts, written tutorials, articles or Quick Tips for Mobiletuts+ it’s easy to familiarize yourself with the guidelines and become a tutorial author. We’re hungry for user contributions and pay a negotiated USD rate for each tutorial, article or Quick Tip we publish. Submit your concept today!

  • Permalink for '3 Awesome New Tutorials and Screencasts for Premium Members'

    3 Awesome New Tutorials and Screencasts for Premium Members

    Posted: May 12th, 2010, 1:43pm MDT by Jeffrey Way


    We have a bunch of new stuff this week for Premium subscribers. If you’re interested in HTML5, Andrew Burgess will teach you how to work with web SQL databases. If you’re a PHP fan, Burak Guzel will teach you the ins and outs of PHP exceptions. Finally, as a simple convenience, members will now be able to download each new video tutorial on the regular site, beginning with today’s “Kick-Ass Practical CSS Buttons.” Sound interesting? Give back to Nettuts+ by becoming a Premium member!

    PHP Exceptions PHP Exceptions

    In this article we are going to learn about PHP Exceptions from ground up. These concepts are utilized in many large, scalable and object oriented applications and frameworks. Take advantage of this language feature to improve your skills as a web application developer.

    Working With HTML5 Web SQL Databases HTML5 Databases

    It’s an exciting time to be a web developer; so many exciting functionalities and new standards are slowly emerging. In this new Premium tutorial and screencast, we’re going to look at one of these new standards, in particular: Web SQL Databases.

    Video Download: Build Kick-Ass CSS3 Buttons HTML5 Databses

    What once required background images and icons can now be created with plain-old CSS. Because modern browsers have access to things like box shadow, gradients, rounded corners, text-shadows, and font-face, we can finally take advantage of this and remove any need for images, when creating visual elements, such as buttons! Download this video tutorial to find out how!

    Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Join today!

  • Permalink for 'Build Kick-Ass Practical CSS3 Buttons'

    Build Kick-Ass Practical CSS3 Buttons

    Posted: May 12th, 2010, 10:59am MDT by Jeffrey Way


    What once required background images and icons can now be created with plain-old CSS. Because modern browsers have access to things like box shadow, gradients, rounded corners, text-shadows, and font-face, we can finally take advantage of this and remove any need for images, when creating visual elements, such as buttons! I’ll show you how in today’s video tutorial.

    Video Tutorial Final Code
    <!DOCTYPE html>
    
    <html lang="en">
    <head>
    	<meta charset="utf-8">
    	<title>CSS3 Buttons</title>
    	<style>
    
    	/* CUSTOM FONT */
    	@font-face {
    		font-family: 'EfonRegular';
    		src: url('font/EFON-webfont.eot');
    		src: local('EfonRegular'), url('font/EFON-webfont.woff') format('woff'), url('font/EFON-webfont.ttf') format('truetype'), url('font/EFON-webfont.svg#webfont') format('svg');
    		font-weight: normal;
    		font-style: normal;
    	}	
    
    	body {
    	 width: 400px;
    	 margin: 200px auto;
    	 background: #666;
    	}
    
    	.button {
    	 width: 400px;
    	 height: 100px;
    	 line-height: 100px;
    	 color: white;
    	 text-decoration: none;
    	 font-size: 50px;
    	 font-family: helvetica, arial;
    	 font-weight: bold;
    	 display: block;
    	 text-align: center;
    	 position: relative;
    
    	 /* BACKGROUND GRADIENTS */
    	 background: #014464;
    	 background: -moz-linear-gradient(top, #0D658E, #0C577A 50%, #014D71 51%, #003E5C);
    	 background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #0E658E), color-stop(.5, #0C577A), color-stop(.5, #014D71), to(#003E5C)); 
    
    	 /* BORDER RADIUS */
    	 -moz-border-radius: 10px;
    	 -webkit-border-radius: 10px;
    	 border-radius: 10px;
    
    	 border: 1px solid #368DBE;
    	 border-top: 1px solid #c3d6df;
    
    	 /* TEXT SHADOW */
    
    	 text-shadow: 1px 1px 1px black;
    
    	 /* BOX SHADOW */
    	 -moz-box-shadow: 0 1px 3px black;
    	 -webkit-box-shadow: 0 1px 3px black;
    	 box-shadow: 0 1px 3px black;
    	}
    
    	/* WHILE HOVERED */
    	.button:hover {
    		background: #014464;
    	 	background: -moz-linear-gradient(top, #0c5f85, #0b5273 50%, #024869 51%, #003853);
    	 	background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #0c5f85), color-stop(.5, #0b5273), color-stop(.51, #024869), to(#003853));
    	}
    
    	/* WHILE BEING CLICKED */
    	.button:active {
    		-moz-box-shadow: 0 2px 6px black;
    		-webkit-box-shadow: 0 2px 6px black;
    	}
    	/* FONT GLYPH (MOSTLY FOR FUN) */
    	.button:before {
    		font-family: EfonRegular;
    		content: 'v';
    		color: #09232F;
    		font-size: 90px;
    		float: left;
    		margin-left: 35px;
    		margin-right: -10px;
    		text-shadow: 0 1px 0 #4190AF;
    	}
    
    	</style>
    </head>
    <body>
         <a href="#" class="button"> Follow Me </a>
    </body>
    </html>
    
    Conclusion Button

    The truth is that it would probably be smarter to use a tiny image for the Twitter-bird icon. But, the goal was to achieve this effect with all CSS! What do you think?

  • Permalink for 'Best of Tuts – April'

    Best of Tuts – April

    Posted: May 11th, 2010, 6:04pm MDT by Aaron Osteraas


    April was an enormous month for Tuts+. In one month Tuts introduced Creative Sessions, teaching the theory behind the techniques and practices that get used in tutorials and by professionals in the field. We also saw Cgtuts+ and Activetuts+ commence their Premium Programs and introduced Moneybookers as an alternate payment method, for those who don’t have PayPal. On top of that we also introduced Pre-paid memberships so if you don’t have a credit card, you can still become a Premium Member. Here’s a selection of the best from each site, just in case you missed it amongst all the action.

    Psdtuts+ – Photoshop Tutorials
    • How to Create an Incredible Typographic Illustration – Part 1

      All work and no play makes Jack a dull boy. In this two-part tutorial, we’re going to learn how to bring a simple proverb into a complex typographic illustration that achieves a level of realism without actually using any photos. Yes, we’re going to build this idea from the bottom up. In the first part, learn how to model your own objects in Cinema 4D and prepare them for isolation in Photoshop.

      Continue Reading

    • Give a Photo a Complete Glamour Makeover With Stunning Light and 3D Effects

      Have you ever wanted to see what you would look like after a complete makeover? Today, I’m going to show you how to transform a regular, every day photo into a real glamour shot. In this tutorial, you will learn how to retouch a model’s face and subtly manipulate her hair. In addition, we will enhance the canvas by adding attractive lighting and 3D effects. This tutorial requires considerable Pen Tool skills, but with perseverance and a passion for design, you will certainly be able to achieve great results.

      Continue Reading

    • Create an Angelic Sculpture Made of Ice in Photoshop

      Sometimes all you need to create an incredible photo manipulation in Photoshop is a rough sketch, some nice imagery, and some knowledge of how to use Photoshop’s transformation tools. In today’s tutorial we will demonstrate how assemble an angelic ice sculpture from a rough sketch and some beautiful scenic photos.

      Continue Reading

    • Turn a Flawless Blonde Beauty Into a Sword-Wielding Fantasy Action Hero

      In today’s tutorial we are going to turn a flawless blonde beauty into a sword-wielding survival huntress. To do this we are going to make her skin sweaty and dirty, her dress stained and torn, we’ll add blood stains to the sword, manipulate her hair, and create a post-apocalyptic background full of smoke and fire effects. It’s gonna be a gas!

      Continue Reading

    • Quick Tip: Create a Realistic Paper Texture in 5 Minutes

      In this quick tip tutorial, we will learn how to create a realistic paper texture from scratch in just 5 minutes. To do this we will use some simple filters and effects. Let’s get started!

      Continue Reading

    Activetuts+ – Flash, Flex and ActionScript Tutorials
    • Exclusive Freebie: The Piecemaker XML Gallery

      To kick us off in style, here’s the awesome Piecemaker gallery created by Björn from Modularweb. Besides the freebie, you’ll find extensive documentation and a tut explaining the native 3D features of Flash CS4. Over to you, Björn..

      Continue Reading

    • A better way to build flash banners A Better Way to Build Flash Banners

      Banner development is often plagued by multiple files, fragmented code and messy timelines. This tutorial will show you how you can create a project template to serve as a solid base which will help you develop robust banners quickly, freeing you up to focus on bringing the creative idea to life.

      Continue Reading

    • How to Create a Flash Menu in 20 Minutes How to Create a Flash Menu in 20 Minutes

      Imagine you’ve promised your client he will have that menu idea you told him about later on today, when you meet. You open up Flash and begin a rough but great example, which you can code or extend later. During this tut we’ll focus on making just such a menu; as customizable as possible, without using any classes, just component parameters.

      Read More

    • How to Automatically Resize an Image to Fit the Screen Quick Tip: How to Automatically Resize an Image to Fit the Screen

      This Quick Tip explains how to use an image as a website background and scale it proportionally to the stage size. It’s great for when you’re using a SWF that’s full-height and full-width inside a webpage.

      Read More

    • Throw Objects by Creating a PanAndThrow Class Throw Objects by Creating a PanAndThrow Class

      In this tutorial we will be mocking up and finishing a pan and throw class that will allow us to add this effect to any element we want. To accomplish this, we will create a image viewer – but not your average viewer. Here we’ll have zooming, throwing, panning.. Almost sounds like a ninja app, huh?

      Visit Article

    Aetuts+ – Adobe After Effects Tutorials
    • Discover How To Recreate the Sherlock Holmes End Credits Effect Discover How To Recreate the Sherlock Holmes End Credits Effect

      After Effects, my dear Watson! This tutorial uses hand drawn elements, textures, and pre-matted motion elements to recreate a look that is similar to the Sherlock Holmes credits. It gives you basics to build on. The great thing about this effect is that it is made to look organic and not 3D and effects heavy, but it still turns out looking really professional. It does not require very much expertise in free hand drawing seeing that all you have to do is trace a still image. Take this tutorial and build upon it to create something awesome.

      Visit Article

    • Create A Realistic Glass Reflection Create A Realistic Glass Reflection

      Transparency is an important element to reflect in one’s relationships and if we can help you in that area it’d be our pleasure! In this tutorial you’ll find out how to create a realistic glass reflection on a 3D object, created within After Effects. We’ll then simulate a normal pass and have it reflect the environment with the “normality” free plug-in.

      Visit Article

    • Get Caught Up In A Spider Web Tutorial – AE Premium Get Caught Up In A Spider Web Tutorial – AE Premium

      Learn how to use Trapcode Form to create a stylistic and dynamic Spider Web. This tutorial will show you how to “think outside the box” when it comes to using plug-ins to get away from that “preset” look.

      Visit Article

    • Welcome CS5! An Intro To The New “Roto Brush” Welcome CS5! An Intro To The New “Roto Brush”

      A HUGE welcome to After Effects CS5! In this tutorial, I’ll be going through and explaining the new “Roto Brush” tool included within CS5. It isn’t a “keyer”, it’s not quite a “magic wand”, I wouldn’t even call it a “pen”. You’re just gonna have to watch the tutorial to find out what this amazing new feature is made of!

      Visit Article

    • 61 Mesmerizing VFX Breakdowns 61 Mesmerizing VFX Breakdowns

      A subject we haven’t touched on for a couple months is the wonder of visual effects and compositing breakdowns. Take a look at the largest roundup of this genre to date!

      Visit Article

    Audiotuts+ – Audio and Production Tutorials
    • " /> Quick Tip: How to Create Interesting Drum Patterns Quickly

      Here is a quick and effective way of creating original and complex drum patterns spontaneously. I am using Logic, but the concept is not DAW specific.

      Visit Article

    • How To Recognize Frequencies How To Recognize Frequencies

      In the last installment we studied the first four octaves of the frequency spectrum with pink noise. Now we’ll continue with the rest of the octaves and revisit the others using music samples.

      Visit Article

    • 6 Apps & Websites to Get Your Ear in Shape 6 Apps & Websites to Get Your Ear in Shape

      If you followed along with us a few weeks ago, you know how much interval ear training can help you as a musician and how to get started with training itself. If you haven’t read it, head on over to Boot Camp for Your Ear.
      This time, we’re going to look at a bunch of applications and websites that will help you with regular ear training sessions. Most of these go beyond intervals, of course.

      Visit Article

    • 8 Free, Cross-Platform Apps for Musicians 8 Free, Cross-Platform Apps for Musicians

      Like most of us when we’re in the studio, it’s hard to get me to work with anything other than the industry standards; Pro Tools, Reason, Logic (which sort of falls into that category), and so on. But given the rising prices of just about everything under the sun, not to mention the chronic emptiness of the musician’s wallet, it’s worth taking a look at the alternatives out there that can be had for free.

      Visit Article

    • How to Record the Acoustic Guitar Basix: How to Record the Acoustic Guitar

      Recording acoustic instruments can be scary for beginners. In this day and age many people just plug in and play their instruments, electric guitars, basses and synths, never needing to record an instrument except the odd vocal track. True as it may be that we get better sounds out our guitar plug-ins and software synths with every update, we must not forget how to record a “proper” instrument, in the real world.

      Visit Article

    Cgtuts+ – CG and 3D Tutorials
    • An Archiviz Workflow Overview in 3ds Max, Sketchup, and Digital Fusion An Archiviz Workflow Overview in 3ds Max, Sketchup, and Digital Fusion

      In this Architectural Visualization workflow overview you will learn how to use Google Sketchup for photo matching, create a Vray-proxy in 3ds Max, use Max script to speed up your workflow, reduce render times when creating a large scene, set render layers in 3ds Max, and do some post production in Digital Fusion.

      Visit Article

    • Model, Texture, and Render the Legendary Katana in Maya – Day 1 Model, Texture, and Render the Legendary Katana in Maya

      In this 3 part Maya workflow tutorial you will learn how to model, texture, and render a Katana, the legendary Samurai sword. For the modeling portion, we will use Maya’s basic polygon editing tools, while UVlayout will be used to create the UVs, and of course Photoshop to create the textures. We will also briefly cover Mental Ray for rendering the final image.

      Visit Article

    • Create Convincing Looking Clouds using Pyrocluster in Cinema 4D Create Convincing Looking Clouds using Pyrocluster in Cinema 4D

      This tutorial will demonstrate the ease and versatility with which you can create convincing looking gas effects using Cinema 4D’s Pyrocluster. You will learn how to optimize your scene and tune it to your own visual tastes, while focusing on creating realistic clouds as the subject matter. The basic techniques, however, can be applied to a variety of different scenarios and effects.

      Visit Article

    • Create a Logo Dispersion Effect using Particle Flow and After Effects Create a Logo Dispersion Effect using Particle Flow and After Effects

      As you may know, when you get a grasp on particles in CG, the possibilities of what you can accomplish are nearly limitless. In this 3ds Max based Particle Flow tutorial, you will learn an easy method of dispersing a logo into particles using materials.

      Visit Article

    • Simulating Chains using Reactor in 3ds Max Quick Tip: Simulating Chains using Reactor in 3ds Max

      In this short tutorial, you will learn how to simulate chains, necklaces, or pearls using an easy and very efficient method with reactor in 3ds Max. After watching this, you will be able to simulate chains in just a few short seconds, a skill which can prove to be very useful in countless different situations.

      Visit Article

    Nettuts+ – Web Development Tutorials
    • HTML5 Features you Should be Using Right Now Quick Tip: HTML5 Features you Should be Using Right Now

      With all this talk about HTML5 not being complete until 2022, many people disregard it entirely – which is a big mistake. In fact, there are a handful of HTML5 features that we can use in all our projects right now! Simpler, cleaner code is always a good thing. In today’s video quick tip, I’ll show you a handful of options.

      Visit Article

    • Combining Modern CSS3 and HTML5 Techniques Combining Modern CSS3 and HTML5 Techniques

      Just because some techniques don’t work in decade old browsers doesn’t mean that you shouldn’t be learning everything you can! Stay on the cutting edge, as we use everything from CSS shadows and animations, to HTML 5 mark-up and local storage, to utilizing jQuery to work with the Picasa API. We’ll also take advantage of the excellent jQuery library, and review some best practices when coding.

      Visit Article

    • An Introduction to jQuery Templating Quick Tip: An Introduction to jQuery Templating

      JavaScript Templating is a neat idea: it allows you to easily convert JSON to HTML without having to parse it. At Microsoft’s MIX10 conference, they announced that they are starting to contribute to the jQuery team. One of their efforts is to provide a templating plugin. In this quick tip, I’ll show you how to use it!

      Visit Article

    • 10 Kick-Ass Magento Templates 10 Kick-Ass Magento Templates

      I’m proud to announce that ThemeForest is now selling Magento eCommerce templates at cheap prices that any business or individual can afford. We’ve launched with thirty-five awesome Magento templates, but we’re just scratching the surface. By the end of the year, ThemeForest will be the premier location for buying and selling Magento templates! Here are some of the best that we’ve launched with.

      Visit Article

    • Notable New Features in Dreamweaver CS5 Quick Tip: Notable New Features in Dreamweaver CS5

      If you’re a Twitter user, it was difficult not to be aware of Adobe’s CS5 global launch presentation. While they did an excellent job of promoting Photoshop and Flash, other applications, such as Dreamweaver, only received limited coverage. Nonetheless, take a look at some of the awesome new features in Dreamweaver CS5, slated to be released in mid-May.

      Visit Article

    Phototuts+ – Photography and Post-processing tutorials
    • Advanced Macro and Still Life Photography Advanced Macro and Still Life Photography

      You face special challenges when shooting objects that are close-up, or capturing still life. As with most subjects, many of these challenges have to do with light quality and quantity. With macro photographs, the challenge grows as the subjects get smaller. This article delves into designing for still-life and macro photography, outlines high and low-key techniques, and discusses the importance of depth of field.

      Visit Article

    • 5 Useful New Features in Adobe CS5 Quick Tip: 5 Useful New Features in Adobe CS5

      Today marks the launch of the latest edition of Adobe’s Creative Suite – CS5. In today’s Quick Tip, we’ll be taking a look at a few of the new features in Photoshop CS5 that are particularly useful for photographers. We’d also love to hear what you’re looking forward to, and whether you’ll be upgrading!

      Visit Article

    • Simple Steps for Shooting Amazing Silhouettes Simple Steps for Shooting Amazing Silhouettes

      Silhouettes can be an excellent way to add drama to a scene. The stark contrast and lack of detail in the subject infuse a psychological effect into the image that can be beautiful, mysterious, or even frightening.
      Today we’ll look at a few suggestions to keep in mind the next time you set out to shoot some silhouettes. We’ll also examine the settings used in some real-life amazing silhouette shots to see what we can learn from them.

      Visit Article

    • The Almighty Histogram – Your Guide to Better Exposure The Almighty Histogram – Your Guide to Better Exposure

      In this tutorial you’ll learn about the histogram, and what it’s able to tell you about your photography. If you’re going to use the back of your camera as guide to judging exposure, then you need the histogram. Understanding it fully will help you capture better, more flexible images!

      Visit Article

    • The Ultimate Guide for Buying Your First Digital SLR The Ultimate Guide for Buying Your First Digital SLR

      Let’s assume that you’ve been shooting with your “point and shoot” for a while now, and you’ve taken some pretty nice snapshots. But maybe you are starting to feel a little limited by what the camera is capable of doing. You’ve read up on photography, and there are things you want to work on. You feel it is time to step up!
      This guide will help you to understand some of the basic features of Digital SLR cameras (DSLRs), and hopefully help you find one that fits both your needs and budget.

      Visit Article

    Vectortuts+ – Adobe Illustrator and Vector Tutorials
    • Time-Savers: 400+ Stock Images, Retro Vectors Time-Savers: 400+ Stock Images, Retro Vectors

      Stock images can save you many hours of work on illustration and allow you to focus your attention on the important task of designing. Finding the right vector for you, however, is a completely different matter, and can sometimes take just as long as creating a vector image yourself! That’s why in this post we have rounded up a total of over 400 retro-themed vector images which you can use in your own projects.

      Visit Article

    • How To Create Outstanding Modern Infographics How To Create Outstanding Modern Infographics

      Merge form and function to create outstanding modern infographics. In this tutorial you will learn that data doesn’t have to be boring, it can be beautiful! Learn how to use various graph tools, illustration techniques and typography to make an accurate and inspiring infographic

      Visit Article

    • Amazing 3D Typography Inspiration: Amazing 3D Typography

      Three-dimensional typography is something we’ve seen a lot of recently, and it doesn’t seem to be dying down, either. This post showcases a huge collection of 3D typography, and we have no doubt whatsoever that it is going inspire!

      Visit Article

    • The Tilde Key Trick Quick Tip: The Tilde Key Trick

      This screencast covers fun with the Tilde key and Adobe Illustrator. Works with any Shape Tool, the Line Segment Tool, the Arc Tool, the Spiral Tool, and more. Use this technique to quickly make complex shape patterns.

      Visit Article

    • Create a Realistic, Vector Building Illustration Create a Realistic, Vector Building Illustration

      We have another great Vector Premium tutorial available exclusively for Premium members today. If you want to learn how to create realistic vector buildings, then we have a massive and extremely detailed tutorial for you.

      Visit Article

    Creative Sessions
    • The Elements of Cute Character Design The Elements of Cute Character Design

      You’ve always wanted to develop a character which has the potential to enchant the world and to compete with Hello Kitty? In this article I’d like to present some elements making a character cute and lovable and to support you in achieving your goals. First, I talk about why something is regarded as cute. Afterwards I’d like to offer an overall view on cute proportions and as a conclusion consider general rules and tips. The goal is to create a manual of cute character design which can be universally used in the process of design.

      Visit Article

    • Character Design Sketching Approaches Roughly Speaking: Character Design Sketching Approaches

      Character design comes in many styles, but they all start with the rough sketch. Often overlooked in online tutorials, technique and process videos, they are the foundation to creating quality characters. The following is an overview of rough sketches from some fantastic character design artists, with many different styles and approaches.

      Visit Article

    • Character Design – Nailing the Basics Character Design – Nailing the Basics

      If you’re thinking of becoming a professional illustrator, character design will come up as a client request again and again, so keeping up on current trends is a must. To get started creating your own characters, you’ll need to nail the basics, which includes: getting comfortable sketching, refining your process, and streamlining your overall approach.

      Visit Article

    • Creating Personal Character Designs with Precision Creating Personal Character Designs with Precision

      Designing a character can apply to both personal and professional projects. The character can be a mascot that works in the context of a multi-national brand, or it can simply be inspired by a well-known character within pop culture. The later is usually referred to as “Fan Art.” The character “Mickey Rat” first appeared in the early 1970’s as a subversive underground comic that I enjoyed as a kid. Many artists over the years have taken their own approach with the character, and this article goes over my creation of this vectorized vermin.

      Visit Article

    • How to Make an Animated Paper Robot How to Make an Animated Paper Robot

      In this tutorial we’ll go through the steps of designing and making an animated paper robot character. Not just a picture, this is a moving character that will sit nicely on top of your computer monitor. Push the robot body up and down and he stretches out his robot claws! We’ll start with the lines ready and learn the craft of coloring and then physically putting this paper character together..

      Visit Article

    FreelanceSwitch
    • Keeping In Touch with Prospective Clients Keeping In Touch with Prospective Clients

      A lot of your success as a freelancer will depend on your persistence.
      It takes many forms – your persistence in learning and improving your skills, the persistence that’s involved in bringing a long, difficult project to completion, and the topic of this article, persistence in keeping in touch with the people who may do business with you.

      Visit Article

    • Turning Your Knowledge into Products Turning Your Knowledge into Products

      One of the big downsides of the freelance world is that when you’re not doing billable work, your income goes to zero. So, there’s a lot of talk about creating income streams that aren’t dependent on your selling your time.

      Visit Article

    • Why I Believe in Pricing Work Based on Value Why I Believe in Pricing Work Based on Value

      For freelancers, the question of how to price your services is always up for debate. Should you charge by the hour or per project? What should your hourly rate be? What type of payment terms should you require? The answers to these questions will vary based on your industry, your reputation, and your personal preferences for your business. But there is one thing that I believe should factor into every pricing decision you make:
      Price your services based on value.

      Visit Article

    • A Few Suggestions Setting Your Standards as a Freelancer: A Few Suggestions

      Having standards is important when you’re trying to find and work with clients on your own. It’s surprisingly tempting not to stick to your standards: a quick project that you wouldn’t normally take can look pretty appealing if you’re having a slow month. But sticking to your guns can be important in more ways than one. If you take that problematic job, not only are you doing something that you don’t want to do, but you’re also likely to hand in work that you know isn’t as good as you could do. Even worse, that sub-standard job can take up the time you need to find higher paying clients, sticking you in a position where you can’t afford to move forward.

      Visit Article

    • Get Business Buzzing with a Buzz Piece Get Business Buzzing with a Buzz Piece

      Most business models can attest to the power of a buzz piece. This marketing tool provides valuable information for prospective clients, the ability to transform readers into customers and a ton of exposure. So if you don’t have one, you should absolutely consider it.
      Here’s what you need to know about buzz pieces.

      Visit Article

    We’ll be publishing the best of Tuts+ each month, so you get to see the best of everything.

  • Permalink for 'Introducing WordPress 3 Custom Taxonomies'

    Introducing WordPress 3 Custom Taxonomies

    Posted: May 11th, 2010, 8:47am MDT by Paul Kaiser


    WordPress 3 fills in a number of important gaps towards being a serious content management system. The easy-to-use custom taxonomies function gives site designers some powerful tools for building a good information architecture. Learn what taxonomies are, why they’re useful, and how to use them in today’s tutorial!

    What is a Taxonomy?

    Taxonomies are different methods for classifying things.

    Taxonomies are different methods for classifying things. This tutorial uses an example of posts about different desktop computers, which can be classified by a number of distinct criteria, including:

    • Amount of RAM
    • Size of hard drive
    • Speed of CPU
    • Type of CPU
    • Operating system installed
    • and so forth…
    A Brief History of WordPress Taxonomies Categories Category Example

    Prior to version 2.3, WordPress had only one generic taxonomy, called Category, for Posts. This worked well for blogs, as you could create a top-level category called “Desktop Computers,” with a subcategory called “RAM,” which may have subcategories such as “Less than 1 GB,” “1 GB,” “2 GB to 4GB,” and so on. A second child category of “Desktop Computers” might be called “Operating System,” with subcategories such as “Windows XP,” “Mac OS,” “Red Hat,” “Ubuntu,” and so forth.

    When a system allows you to have categories that can be divided into subcategories, we call it a hierarchical structure. The best you could do for a serious site architecture prior to WordPress version 2.3 was to create a large hierarchy of categories, where the top level categories represented large taxonomy groups.

    Tags Tags Example

    Version 2.3 of WordPress added another type of taxonomy called Tags. While categories are usually thought out in advance, specific to the types of content on a site, tags provide a more freeform, impromptu method of classifying content.

    For instance, when writing a Post about a particular desktop computer, tags allow the author to type one or more keywords such as “gaming,” “tivo,” “noisy fan,” and so forth. These keywords might not make sense as site-wide categories, but help provide some additional classification to a post. Site visitors could then easily find all the posts tagged with “noisy fan” later. The freeform nature of tags, however, doesn’t help us build a solid classification system around known values such as operating system types or CPU types. Tags are also one-dimensional, not allowing any hierarchical structure.

    Single-Level Custom Taxonomies Single-Level Custom Taxonomies

    Wordpress version 2.8 made it possible to add custom classification schemes with just a few changes to the code on your site. This allowed you to build a list of possible operating systems, separate from a list of possible RAM types, and so on. It did not, however, allow these custom taxonomies to be built in a hierarchy similar to the generic categories taxonomy.

    Fully Hierarchical Custom Taxonomies Fully Hierarchical Custom Taxonomies

    Finally, WordPress version 3 gives us fully hierarchical custom taxonomies. Notice how the hierarchical nature allows us to simplify the Operating System taxonomy, for instance, by pushing all the different Windows variants under a “Windows” parent classification. This will allow visitors to see all posts classified with any Windows operating system, or allow them to be more specific and see only posts classified with Windows XP, for instance.

    Creating a Custom Taxonomy Editing your theme’s functions.php file

    WordPress version 3 does not allow you to create custom taxonomies from the administration screen. To initially define your custom taxonomies without a plugin, you’ll need to add a little bit of code to your theme’s functions.php file. This isn’t too difficult — just follow my lead.

    To add custom taxonomies, we need to edit the “functions.php” file found inside your theme directory. For instance, I’m using the default “twentyten” theme that comes with WordPress 3.0, and my WordPress installation is in a directory named “wp.” My functions.php file is then at:
    [website_root]/wp/wp-content/themes/twentyten/functions.php.

    Adding the Taxonomies in Code

    We’ll stick with the Desktop Computer example, adding separate taxonomies for RAM, Hard Drive, and Operating System. At this point, we’re simply adding the taxonomies themselves, like empty containers. Fortunately, we can add and manage the different classifications, such as “Windows XP,” from the comfort of the admin dashboard. Step 1 One Function to Create Them All

    First, we need to build one function that creates all the taxonomies we need. We’ll call the function “build_taxonomies.” Let’s add this function to the bottom of the functions.php file.

    function build_taxonomies() {
        // code will go here
    }
    
    Step 2 Defining the Taxonomies

    Next, for each taxonomy we want to create, we need to call a particular WordPress function with the right parameters. Here’s the function, and its important parameters explained.

    register_taxonomy(
    	'internal_name',
    	'object_type',
    	array(
    		'hierarchical' => {true|false},
    		'label' => 'Human Readable Name',
    		'query_var' => {true|false},
    		'rewrite' => {true|false}
    	)
    );
    
    • internal_name: What will this taxonomy be called from inside WordPress, in the database and template files?
    • object_type: Which types of content can be classified with this taxonomy? Possible values are “post, page, link,” and then names of custom post types we’ll learn to create in a future tutorial.
    • Next comes an array of optional parameters. We’ll use the most important ones here in this tutorial, but a full list can be found on the Function Reference / register_taxonomy Codex page. The parameters we’ll use are:
    • hierarchical: If ‘true,’ this taxonomy has hierarchical abilities like WordPress Categories. If ‘false,’ this taxonomy behaves much like freeform Tags.
    • label: This is the human-readable name used in your site’s interface to label the taxonomy.
    • query_var: If ‘true,’ we’ll be able to ask WordPress for posts dependent upon the selections for this taxonomy. For example, we could search for all the posts where the operating system taxonomy has ‘Windows’ selected.
    • rewrite: If ‘true,’ WordPress will use friendly URL’s when viewing a page for this taxonomy. For example, a page listing all the posts with the “Windows” operating system selected would be represented by the following url: [domain.com]

    Our entry specific to adding the Operating System taxonomy looks like so:

    register_taxonomy( 'operating_system', 'post', array( 'hierarchical' => true, 'label' => 'Operating System', 'query_var' => true, 'rewrite' => true ) );
    

    Go ahead and add that to your “build_taxonomies” function.

    More information:

    “register_taxonomy” is further defined within the WordPress codex.

    Step 3 Calling the Taxonomy-Creating Function

    We need to add one more line to the “functions.php” file so our “build_taxonomies” function will actually be executed. We’ll “hook” the “build_taxonomies” function to the “init” event by adding the following code:

    add_action( 'init', 'build_taxonomies', 0 );
    

    You can add this line anywhere, but I generally add it above the function we’re calling, so it would look like this:

    // Custom Taxonomy Code
    add_action( 'init', 'build_taxonomies', 0 );
    
    function build_taxonomies() {
        register_taxonomy( 'operating_system', 'post', array( 'hierarchical' => true, 'label' => 'Operating System', 'query_var' => true, 'rewrite' => true ) );
    }
    
    More information:

    Learn more about add_action.

    Adding Classifications to the New Taxonomy Viewing taxonomy classifications

    Once you’ve added the “Operating System” taxonomy to the “functions.php” file correctly, it should show up as a new item in the “Posts” panel of your dashboard. Click the taxonomy’s name to add and edit the classifications you want to include.

    Adding taxonomy classifications

    Now, you can add and edit Operating Systems just as you would add generic Categories. Adding More Taxonomies

    If you want to add the “RAM” and “Hard Drive” taxonomies to follow along with the example, just add the following to your functions.php file:

    register_taxonomy( 'ram', 'post', array( 'hierarchical' => true, 'label' => 'RAM', 'query_var' => true, 'rewrite' => true ) );
    register_taxonomy( 'hard_drive', 'post', array( 'hierarchical' => true, 'label' => 'Hard Drive', 'query_var' => true, 'rewrite' => true ) );
    

    Once finished, the changed section of your functions.php file will look something like this:

    // Custom Taxonomy Code
    add_action( 'init', 'build_taxonomies', 0 );
    
    function build_taxonomies() {
    register_taxonomy( 'operating_system', 'post', array( 'hierarchical' => true, 'label' => 'Operating System', 'query_var' => true, 'rewrite' => true ) );
    register_taxonomy( 'ram', 'post', array( 'hierarchical' => true, 'label' => 'RAM', 'query_var' => true, 'rewrite' => true ) );
    register_taxonomy( 'hard_drive', 'post', array( 'hierarchical' => true, 'label' => 'Hard Drive', 'query_var' => true, 'rewrite' => true ) );
    }
    
    Creating a Post Using your New Taxonomy Creating post with classifications

    Create a few new posts, and you’ll see your new taxonomy options appear in the Edit Post screen. Select whatever classifications you feel apply to your posts.

    Showing a Post’s Various Taxonomies

    Nothing we’ve done so far can be seen by your site visitors. We’d like for posts to show what custom taxonomies they’re classified in, just like posts commonly reveal their categories and tags.

    To do so, we only need to make a simple addition to the loop in certain template files.

    Displaying Taxonomy Classifications on Individual Pages

    In the twentyten theme, and many others, a post’s categories and tags are listed below the body text. We’re going to add custom taxonomy information, if it exists, just before the category and tag information.

    Taxonomy info on single posts

    To make this happen, we’ll need to edit the “single.php” template file, which is normally called to display an individual post. My single.php file is at: [website_root]/wp/wp-content/themes/twentyten/single.php.

    Step 1 Find the Right Place to Add Code

    In single.php, find the line with:

    <div class="entry-utility">

    This appears just before the:

    <div id="nav-below">

    In twentyten, this div contains the categories, tags, permalink, and other data for the current post. We’ll put our taxonomy information just above this div.

    Step 2 Retrieve Taxonomy Information About the Current Post

    Populate some variables for holding the taxonomy information output and the different taxonomy information we may expect to find.

    <?php
    // Let's find out if we have taxonomy information to display
    // Something to build our output in
    $taxo_text = "";
    
    // Variables to store each of our possible taxonomy lists
    // This one checks for an Operating System classification
    $os_list = get_the_term_list( $post->ID, 'operating_system', '<strong>Operating System(s):</strong> ', ', ', '' );
    

    Here, we’re calling the WordPress function “get_the_term” list with the following parameters:

    • $post->ID : the id of the current post.
    • ‘operating_system’ : the name of the custom taxonomy we’re checking for data. We’re asking if the current post has been given any classifications in the ‘operating_system’ taxonomy.
    • ‘Operating System(s)’ : If anything is returned, this is the string we’d like to have in front of it.
    • ‘, ‘ : If multiple items are returned, this is the string we’d like to have them separated by.
    • ” : If anything is returned, this is the string we’d like to have behind it. In this case, we want nothing added behind the result.

    We’ll do the same for the other two taxonomies we might expect to contain data:

    $ram_list = get_the_term_list( $post->ID, 'ram', '<strong>RAM Option(s):</strong> ', ', ', '' );
    $hd_list = get_the_term_list( $post->ID, 'hard_drive', '<strong>Hard Drive Option(s):</strong> ', ', ', '' );
    
    More information:

    Learn more about “get_the_term_list.”

    Step 3 Format Results from Classifications, if Any

    Check for results in each of the three possible taxonomies. If they exist, add them to our output, as well as a linebreak.

    // Add OS list if this post was so tagged
    if ( '' != $os_list ) {
        $taxo_text .= "$os_list<br />\n";
    }
    // Add RAM list if this post was so tagged
    if ( '' != $ram_list ) {
        $taxo_text .= "$ram_list<br />\n";
    }
    // Add HD list if this post was so tagged
    if ( '' != $hd_list ) {
        $taxo_text .= "$hd_list<br />\n";
    }
    
    Step 4 Display Classification Results, if Any

    Check to see if the above steps resulted in any taxonomy information at all to output. If taxonomy info exists, we’ll output it wrapped in a div of class “entry-utility.”

    // Output taxonomy information if there was any
    // NOTE: We won't even open a div if there's nothing to put inside it.
    if ( '' != $taxo_text ) {
    ?>
    <div class="entry-utility">
    <?php
    echo $taxo_text;
    ?>
    </div>
    <?
    } // endif
    ?>
    
    Step 5 Check Your Results

    Visit a post page, and you should see any custom taxonomy classifications listed below.

    Taxonomy info on single posts 2 Viewing a List of Posts by Taxonomy Classification

    Now our individual posts tell us what custom taxonomies they have been classified with. When they list a custom taxonomy classification, they also provide a link to list all posts under that classification. For instance, clicking the “Mac OS” link next to “Operating Systems” under our post will theoretically list all the posts with the “Mac OS” operating system classification.

    However, this doesn’t happen out of the box with WordPress version 3. We’ll have to make a custom template file for displaying taxonomy archives in order for it to work. WordPress already lets visitors view all posts assigned to a particular category, or all posts given a certain tag. When we’re done here, we’ll be able to view all posts assigned to particular classifications in our custom taxonomies, too.

    To make this happen, we’ll need to create the “taxonomy.php” template file. WordPress will try to use this file any time it wants to list posts in a custom taxonomy.

    Step 1

    Open the “category.php” file, copy its contents, and paste it into a new file called “taxonomy.php.” Save taxonomy.php in the theme directory. For instance, my taxonomy.php file is at:
    [website_root]/wp/wp-content/themes/twentyten/taxonomy.php.

    Step 2 Get Information About Current Taxonomy Classification

    In the taxonomy.php file, we need to get information about the taxonomy being listed. We’ll probably want the name and description (if any) for the selected classification.

    Just under <?php get_header(); ?>, add the following line:

    $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );
    

    This gets all of the information about the taxonomy that called this page and returns it as an object into the variable $term. For example, the “Mac OS” classification returns an object as such:

    stdClass Object
    (
        [term_id] => 13
        [name] => Mac OS
        [slug] => mac-os
        [term_group] => 0
        [term_taxonomy_id] => 22
        [taxonomy] => operating_system
        [description] =>
        [parent] => 0
        [count] => 2
    )
    
    Step 3 Display Classification Name and Description

    We want to change the page name to tell visitors what they’re looking at. Since we started with the category.php template, we can take the line that used to print the category name and change it a bit to give us our desired page name and, if applicable, description.

    Change the following line from category.php:

    printf( __( 'Category Archives: %s', 'twentyten' ), '<span>' . single_cat_title( '', false ) . '</span>' );
    

    To read as follows:

    printf( __( 'Posts classified under: %s', 'twentyten' ), '<span>' . $term_name . '</span>' );
    

    This changes the static text beginning the line, and then inserts the name of the classification. (Note: for proper localization, we would need to add ‘Posts classified under:’ correctly to the languages/twentyten.pot file. That’s outside the scope of this tutorial, but be aware of the transgression here.)

    Then add the following:

    if ('' != $term_descr ) {
    echo "<p>$term_descr</p>\n";
    }
    

    If a description exists for this classification, it will be displayed just beneath the title.

    Taxonomy Archive Page

    After making changes to taxonomy.php, visit one of your posts that has been given a custom taxonomy classification. Because of our earlier work in the file “single.php,” the post should show custom classifications below it. Simply click one of those classifications to see the taxonomy listing at work.

    Conclusion

    I hope this tutorial explained clearly what taxonomies are and showed you how to make use of them in WordPress 3 as a powerful organizational tool. I hope to provide a follow up tutorial soon explaining WordPress custom post types, their tight relationship with custom taxonomies, and how to use them. Thanks so much for taking the time to visit Nettuts!

  • Permalink for 'Rethinking Forms in HTML5'

    Rethinking Forms in HTML5

    Posted: May 10th, 2010, 4:00am MDT by John Cox

    While there are many changes for the better in the HTML5 specification, there is no better bang for the buck for the data driven website than the transformation of forms. These simple changes will transform how you enter, validate, process, and even display inputs. You will be able to create more usable web applications with less code and less confusion.

    Introduction What’s in Store?

    “In the recent past, the majority of innovation in forms have come from the use of JavaScript, rather than old fashioned HTML. While there is nothing wrong with using JavaScript to enhance forms, it does bring its own usability along with many development headaches.”

    HTML 5 is still undergoing changes before it is finalized. If you look at the spec, you will see that there is still a last call for comments along with statements, such as, Implementers should be aware that this specification is not stable. Furthermore, particularly for the purposes of this tutorial, focusing on the changes to forms, browser implementation is spotty to say the least. That said, the changes on the horizon are worth examining today. While the changes are major in scope, the implementation for developers look to be rather easy. In this tutorial, we will take a high level overview of these ground breaking changes, and think about how they will impact the nature of user input.

    In the past, changes to forms have been relatively minor. If you go back to the HTML 3.2 spec, which was finalized in 1997, you will see the same basic form inputs that you use today. Select, textarea, radio, checkboxes and text were available then. A generation of web developers have grown up writing to these same standards. While later versions of the specification brought changes to forms, such as the fieldset, label, legend, and form actions such as onsubmit or onchange, the way we deal with user input has remained somewhat static. In the recent past, the majority of innovation in forms have come from the use of JavaScript, rather than old fashioned HTML. While there is nothing wrong with using JavaScript to enhance forms, it does bring its own usability along with many development headaches. For instance, there are many different ways that we can validate forms using JavaScript, but what happens when a user does not have JavaScript enabled? We further have to apply logic to our server side scripts. In the end, we have a not so consistent way of handling user input. HTML 5 doesn’t address every innovation headache for forms in the past 13 years, but it does give us plenty of tools to
    make our jobs much easier, and allows us to produce much more consistent forms.

    There are three basic changes that we should examine. First, we will look at the changes to the input elements, such as autocomplete or autofocus. The second is changes to the input states, and there are quite a few! Finally, we will examine the new form elements. It is important to restate that the specification is in flux; so I wouldn’t be surprised if, in the future, there are subtle changes to what we are discussing. That’s what makes this fun!

    Changes to Input Elements: A Whole New Playground.

    Input attributes are those items that you place in inputs to explain what the input is doing. For instance:

        <input name="form_text" id="form_text" type="text" value="foo" size="10" maxlength="100">
    

    In the example above, the input attributes are value, size, and maxlength. These have been around for quite some time. HTML 5 doesn’t change the concept of having input elements, but rather adds quite a few more. There does appear to be at least one subtraction, or rather substitution, and that is the change of disabled now appears to become readonly. The spec does not go into detail to the change, but if I was a betting man, the change would allow event handlers, such as onblur, to fire – which a disabled element prevents.

    The new attributes include autofocus, autocomplete, list, required, multiple, pattern, min and max, step and placeholder. I think of these as two different flavors of elements. The first flavor enhances the experience for the user, while the second enhances the development experience. What I mean by this, is autofocus, autocomplete, list, multiple, and placeholder helps the user experience in selecting items, or perhaps by giving a description of what the form input is looking for, or by aiding in completing the form. required, min and max, pattern and step add to the development experience by saying what should be in the form itself.

    Autofocus

    What each of these new attributes do is relatively easy to understand. For instance:

        <input name="form_text" id="form_text" type="text" value="foo" autofocus>
    

    Above, the autofocus element focuses the text input on page load. This means that as soon as the page loads, this text input is ready to take an entry. You can start typing right away, as this element has the focus of the document. Something that we used to do in JavaScript in a line or so, can now be done with a single word.

        <input name="form_text" id="form_text" type="text" value="foo" autocomplete="off">
    

    In the above example, by turning off autocomplete, you keep the browser from filling in the form field from a previous value. Nothing bugs me more than seeing my credit card number come up in a form as soon as I type a digit. The default for autocomplete is to be on, so the only time you need to use this element is when you want to prevent the form field from completing from previous entries. It adds to the user experience by keeping sensitive information from just “popping up.”

    List
        <input name="form_url" id="form_url" type="url" list="url_list">
        <datalist id="url_list">
            <option value="http://www.google.com" label="Google">
            <option value="http://www.nettuts.com" label="NetTuts">
        </datalist>
    

    The list attribute is very cool. Essentially, you provide a datalist, and it will create a drop down from your text input. Think of it as a natural auto complete. Take it a bit further, and instead of having to add a JavaScript library for a quick look up, based on key entries, you could easily just add an “onchange” event handler, with an AJAX post, and you end up with a drop down that gets more specific as the user types into the box. With HTML 5, this functionality an be created with just a few lines.

    Multiple
    <input name="form_url" id="form_url" type="url" list="url_list" multiple>
    

    The multiple attribute allows you to select multiple items from your datalist. For instance, you might have a form which sends messages from your website. By using the multiple element, you can allow the user to select multiple recipients to send that message. Again, this is something we can accomplish with a bit of JavaScript now, but with HTML 5, we only have to add a single command to the form.

    Placeholder
        <input name="form_text" id="form_text" type="text" placeholder="Type Here">
    

    The placeholder attribute is something we have been doing for years with a touch of JavaScript. What this does is, as soon as the input is focused, Type Here will vanish. If there was no change to the text on blur, then Type Here will reappear. Once again, we are taking some JavaScript out of the picture to enhance the user experience.

    Required

    These next new attributes all enhance our development. With the exception of “step,” each aids in the validation of the user input.

        <input name="form_text" id="form_text" type="text" value="foo" required>
    

    The required attribute is exactly as it sounds. I, the developer of this webpage, require you to fill out this form prior to hitting submit. This is the basic form validation that we use today with JavaScript. What took a library before to add a required entry, now takes a single word in the form.

    RegEx
        <input name="form_text" id="form_text" type="text" value="foo" pattern="[0-9][A-Z]{3}">
    

    Of all the new form attributes, this is the one that I am most excited about. Mr. Form, let me introduce you to my good friend, Regex. Thats right, we can validate form entries based on regular expressions. While this one is going to be mystifying at first, as you learn regular expression, the possibilities of validation now become limitless.

    Validation
        <input name="form_range" id="form_range" type="range" min="1" max="10" step=".5" value="5" >
    

    I have lumped the final three into one example, as they all deal with number validation – or the range of numbers that we can include.

    • Min: is the minimal value that an input will take.
    • max: is the maximum input value the input will take.

    Each of these are dealing with numerical values. Dont confuse them with maxlength, which deals with the number of characters an input will take. The step element is just as it sounds. As you select a numerical value, step it up by .5 or down by .5 — meaning this input type will have the possible values of 1, 1.5, 2, 2.5, and so on.

    As of right now, to the best of my knowledge, browser support is somewhat spotty on these attributes. Heres a quick chart showing what I was able to find on the implementations.

    Changes to Input Types: A Whole Lot of Love.

    There are eight new input types, not counting all the new date and time types, which for our purposes, I am lumping into one. Its important to note that the browsers which have not implemented the new input types will degrade to a type of text on each that I have tested. What the new input types bring is an ability to validate user input based upon the type that you are using. There is also more validation to come which I will be discussing in the next two sections. Each of the new input types allows us to separate from a text field to something more specific. For instance, to take integer or float values prior to HTML 5, we mostly used an input type of text. Just from the annotation, it is counter intuitive for beginners. By being more specific, we then have better visual control over our interface, as the more specific the element in HTML, the greater control you have from within the CSS, and the easier it is to define those visual elements. In addition, with the new specific input types, browsers are now able to fine tune what the input range should be. Finally, with the advent of mobile computing, we are able to make web application form elements which can be styled to look like natural applications, or can shape the keyboard that we are using.

    Let’s look at number handling first:

    Numbers, Integers and Floats
        <input name="form_range" id="form_range" type="range" min="1" max="10" step=".5" value="5" >
    
        <input name="form_number" id="form_number" type="number" min="1" max="10" >
    

    Each of these input types allows us to play with numbers, and when we post the forms, we should be sure that we have those float values for our server side processing without the added JavaScript validation. Simply put, for each of these types, we are expecting to get numbers back within the range that we define and with the step that we want. The difference between the two types is how they are displayed. While I am waiting to see implementation on the number type, I would expect either a roll, or a text box, or possibly a type of a select with numbers. The range type is a bit different, in that it looks like a sliding value, similar to what you would expect to see for a volume control.

    Dates and Times
        <input name="form_date" id="form_date" type="date">
    
        <input name="form_month" id="form_month" type="month">
    
        <input name="form_week" id="form_week" type="week">
    
        <input name="form_time" id="form_time" type="time">
    
        <input name="form_datetime_local" id="form_datetime_local" type="datetime-local">
    

    Another big relief to standardize your backend development is the new date and time input types. From the Opera implementation that I have seen, each shows a calendar drop down, which allows your user to select a date. Again, we can validate on our webpage that the input is in the format that we are expecting. Each does exactly what you would think; you are selecting a month, week, day, or time. The one that is a little different is the datetime-local, which is showing the date and time without your timezone offset. For instance, if you are selecting a flight, the datetime-local would show the time and date in the city that you are going, which is not necessarily the timezone that you are currently in.

    Urls, Emails, Telephone, and Color
        <input name="form_url" id="form_url" type="url" list="url_list">
        <datalist id="url_list">
            <option value="http://www.google.com" label="Google">
            <option value="http://net.tutsplus.com" label="NetTuts+">
        </datalist>
    
        <input name="form_email" id="form_email" type="email" list="email_list" multiple>
        <datalist id="url_list">
            <option value="jane.doe@test.com" label="Jane Doe">
            <option value="john.doe@test.com" label="John Doe">
        </datalist>
    
        <input name="form_telephone" id="form_telephone" type="telephone">
    
        <input name="form_color" id="form_color" type="color">
    

    Each of these input types are descriptive. The URL and Email types both have the validations of valid url patterns and valid email patterns. The telephone does not, however, conform to any specific pattern. It just strips line breaks. If you want to enforce a validation pattern on the telephone field, you can always use the pattern element. Each of these elements minus color will also take the list attribute, minus color. Color is the oddball of the bunch; I can see its practical use, where you can select a color from a fancy pull down that shows colors, and enforce the text entry of something like #000000, but it doesn’t really fit the rest of the changes, in my opinion. Its like playing which one is not like the others.

    Like the attributes, the input type browser implementation is quite spotty. My iPhone seems to support more of these than Safari, which is a bit funny to me. This is the best that I could find, as to support.

    Changes to Form Elements: Not Quite as Drastic

    The number of changes to the form elements is not as drastic as input attributes and types. That said, there are a few new elements to be aware of. We have already covered datalist – it is how we define what will be selected from a list element call – but we haven’t seen keygen, output, progress, or meter. Outside of keygen. these aren’t quite as self explanatory as the new attributes. Lets dig into these just a bit.

    Keygen
        <keygen name="key">
    

    This one is a bit confusing. It does not generate a public key for you. Instead, it is a key pair generator control. Once the form is submitted, it packages the key pair to store the private key in the local key store, and sends the public key back to the server. It will generate the client certificate and offer it back to the user to download. Once downloaded and stored with the private key, you can then authenticate services, such as SSL or certificate authentication.

    Output
        <input name="number_1" type="number"> + <input name="number_2" type="number"> =
        <output onforminput="value = number_1.valueAsNumber + number_2.valueAsNumber"></output>
    

    Think of the output element as a text area on steroids. What you can do is calculate from two number type text inputs and output that calculation without ever submitting the form back to the server. If you just return false onsubmit, in the above example, it will calculate number_1 plus number_2, and provide you the answer. Like many things discussed in this tutorial, this is something that we can accomplish today with JavaScript, but this really lessens the amount of code that we need to write in the future.

    Progress and Meter
        <progress id="p" max=100>0% </progress>
    
        <meter min=0 max=20 value=12 optimum=10>12cm </meter>
    

    The final two new elements are progress and meter. They are similar, but with one difference. Progress is meant to be used to measure the progress of a specific task. For instance, if you might have five more pages to complete before a survey is done, you would show the progress element in that area. The meter, on the other hand, is a measurement of something. You might want to show the remaining disk space a user has left. You would use the meter to display that measurement. There are new boundary elements, such as low, high and optimum. These supersede the min or max elements; so if they exceed them, they become the new lower and upper limits of the form.

    Like the rest of the HTML 5 form changes, browser implementation is poor at the moment. Heres what seems to work, and what doesn’t (at the time of this writing).

    Conclusion

    From what I can see, there is no reason to not start using HTML 5 forms. The input elements and types all degrade nicely, even in IE6, where they are either ignored as elements, or degraded to text inputs. We are going to have to wait a while for the validation attributes to become a reality, but with that said, there are still some uses today without those advantages. For instance, the iPhone modifies the keyboard if you are using the url, email, or number types. The range input type is already supported in WebKit browsers, so you could be the first kid on the block with a number slider that works without JavaScript. The spec is rapidly finalizing, and browsers are catching up rather quickly to the paradigm shifts. There is no time like the present to at least begin playing with these new toys! What do you think?


  • Permalink for '7 Simple and Useful Command-Line Tips'

    7 Simple and Useful Command-Line Tips

    Posted: May 7th, 2010, 10:26am MDT by Japh

    One of the most useful, but under-used, tools a web developer has is the command-line. The terminal often scares people away; so here’s where we demonstrate some of the most useful day-to-day commands.

    1. The Basics

    If you’re new to the command-line, you’re going to want to know a few things to help find your way around.

    Changing directories

    You can change to a different directory with the following:

    cd ../relative/path/to/other/directory/or/file
    cd /absolute/path/to/other/directory/or/file

    If you get lost, you can go back to your “home” directory with the command “cd ~”.

    Listing files and directories

    If you need to know what files a particular directory contains:

    ls ../relative/path/to/other/directory/or/file
    ls /absolute/path/to/other/directory/or/file

    You can use the “-l” switch to show the contents as a list, and the “-A” switch to also show hidden files (on Linux based machines, files and directories whose name begins with a “.” are considered ‘hidden’).

    Showing your current directory

    Sometimes you just want to know what directory you’re currently in!

    pwd

    This will display a path to your current folder.

    Copying files

    Copying files from one place to another is quick and easy:

    cp /files/or/directories/to/copy /directory/to/copy/to/

    You can also use the “-R” switch when copying to make it recursive, so all sub-directories and files are also copied.

    But typing is slow, and what if I can’t remember the exact path or command?

    Most of the time, the command-line has tab-completion enabled, so you can start typing the name of a command or a file path, press tab, and it will complete it for you. If there is more than one option, it won’t complete for you but if you double-press tab, it will list the options.

    Tab-completion makes typing out long file paths much faster!

    How do you know what options a command has?

    There are a few ways to determine what options a command has. Most commands have a –help (or -help, or -h) operator available, which lists the possible arguments and options you can use:

    cd --help

    If you find that the brief help given by the –help operator isn’t enough, you can read more detail with the man program:

    man mysqldump

    Which will tell you all about the “nano” program. Simple commands like “cd” may not have an entry in man.

    2. Making a Database Backup (with GZip Compression)

    Backing up your database is something you should do often. Like most things, there are a lot of ways to do this, but using the command-line is one of the best. Why? Because it helps you get around potential problems like execution timeouts for tools like phpMyAdmin, and potential network dropouts from using a local administration tool like MySQL Workbench.

    The command to run the backup is fairly small, but may require some explaining:

    mysqldump -u mysqluser -p mysqldatabase

    Now, to explain what’s going on here! The “mysqldump” program is a tool for creating database backups. The parameters being used are:

    • “-u” switch means you’re going to specify a username to connect with, which must follow, like “-u mysqluser” above
    • “-p” switch means you’re either going to immediately specify the password to use (with no space), or it’ll prompt you for one
    • The final parameter used in the example above is the name of the database to backup (of course!)

    If you ran the command above, you would’ve seen the contents of your database go whizzing by on the screen. That’s good, because we know that part works (actually connecting to the database), but it’s also bad, because… where did it go? Answer: nowhere! It scrolled past, and that was it. Now we need to capture it and put it in a file.

    To place the contents of the output into a file, for back-up purposes, we need to use what’s called a redirection.

    mysqldump -u mysqluser -p mysqldatabase > db_backup.sql

    So we added a redirecter, and the filename we wanted the output to go into. Now you should be able to see a file named “db_backup.sql”, and if you open it you can see a SQL script with the structure and content of your database ready for restoration or migration.

    One last thing that could be useful for a backup, is compressing the SQL script. For this example, I’m going to use GZip compression, because it’s quite common, but you could also use Bzip2 or something else.

    To add compression into this command, we just do what’s called piping. We pipe the output from the mysqldump through gzip, and then redirect it into the file we want, like so:

    mysqldump -u mysqluser -p mysqldatabase | gzip > db_backup.sql.gz

    I also added the “.gz” to the filename, so I know it’s compressed and not just plain text anymore (it’ll also be smaller!)

    3. Restoring from a Database Backup (with GZip Compression)

    So you’ve got a backup of your database (either using the method above, or some other way), and something has gone wrong and you need to restore, or you’re migrating it to a new server. You could use one of the other tools mentioned before, but in the example of phpMyAdmin, what if your database backup file is bigger than the allowed upload size? Well luckily, the command-line doesn’t mind.

    The command to restore is very similar to the one for backing up. Firstly, without GZip compression:

    cat db_backup.sql | mysql -u mysqluser -p mysqldatabase

    We use the “cat” command to output the contents of the backup script, and pipe its contents into the mysql program. As you can see, the mysql program takes the same options as the mysqldump one does in section two.

    Now if the script was GZip compressed, we can’t just output its contents into mysql, as it will be compressed data instead of a nice SQL script. So we do the following:

    gunzip 
    

    See, it's very familiar, just switched around a bit.

    What's happening here is we run "gunzip" too and redirect the backup script into it to be decompressed. We then pipe the decompressed output into the "mysql" program.

    4. Find / Replace in a Text File

    Sometimes you have a big file, like maybe a database export, and you need to do some find / replace on it... but it won't open in any of your text editors, because your machine runs out of memory trying to open it! Well, here's a way around that, by using the command-line and a little regular expressions.

    The way this works is to output the contents of the SQL script (or whatever file you're using), pipe it through a program called "sed," which is specifically form manipulating streaming content, and then redirect that output into the new file. Sound complicated? Well... I guess it is a little, but the command itself looks simple!

    cat original_dump.sql | sed s/Japheth/Japh/ > new_dump.sql

    The new part here is really the "sed" program. Basically what it's doing is taking input and matching the first pattern (in this case, my name, "Japheth"), and replacing it with the second pattern (in this case, a shortening of my name, "Japh"), then outputting that.

    5. Securely Copying Files to / from a Server (over SSH with SCP)

    If you're working on the command-line and need to copy a file, especially if you need to do it securely, why go and fire up your FTP client? Just use a program called Secure Copy, or SCP, which is especially for doing remote file copying securely. Secure Copy uses SSH to copy the files, so you need to make sure you can connect to the remote computer via SSH first (I'll talk about this a little more at the end of the article, so hold that thought).

    The syntax of the scp command is similar to that of the cp command covered in section one, with the addition of the hostname of the remove computer and the username to connect with:

    scp /path/to/local/file username@hostname:/path/to/copy/to/

    The bits to note are "username@hostname:", which, as I explained above, are the username to use and hostname to use when connecting. You will be prompted to enter the password for that user, and you also will get a progress indicator for the copying so you can see how it goes.

    You can use the "-r" switch (note: it's lowercase for scp, uppercase for cp) with secure copying to make it recursive. Also, if this is the first time using SCP or SSH to connect to the remote machine, you may be asked to accept an RSA fingerprint for security, which you should accept (assuming you're certain you're connecting to the correct server).

    It's worth mentioning that this works both ways. You can also copy files from the remote computer to your local machine by switching the arguments around:

    scp username@hostname:/path/to/remote/file /local/path/to/copy/to/

    If you're SSHed into one web server, and you want to copy files to another one, you can use this command to copy the files directly without having to download them to your local computer first!

    6. Finding Specific Files in a Large Project Finding a file with a particular name

    Want to find a specific file but not sure where in the many directories of your project it's hiding? (or even if there's more than one!)

    find ./ -iname "index.php"

    The "find" command is for locating files within a directory heirarchy. It has many options, so its uses are quite varied. Here I've specified to search in the current directory with "./", and used the "-iname" switch, which means to search for a file with a name like the one I supply. There is also a "-name" switch, but the "-iname" switch is case-insensitive, so it'll find INDEX.php as well.

    Finding a file with particular content

    Ever known that you had written a function for something, but can't remember which file it was in?

    grep -iR myFunction ./

    "grep" is a program for printing out lines that match a particular pattern. You can provide it with some switches, like the "-i" for making it case-insensitive, and "-R" for making it recursive in my example. Then provide a pattern, and the path to search in (here I'm searching the current directory with "./"). This example will show the filename and the line in that file for any matches it finds to "myfunction" (case-insensitve because of the "-i").

    If your projects are Subversion working copies, you may find that it's annoying to see results from the ".svn" directories. To exclude particular directories from the search, use the "--exclude-dir=" switch, for example "--exclude-dir=.svn".

    7. Performing Bulk Actions on Specific Files

    Now we know how to find particular files; what if we want to do particular things with those files? For example, I often work on a Mac, and find that when I save files to Windows shares or Linux Samba shares on the network, Mac OS X kindly litters "._filename" files everywhere. So I like to be able to clean these up regularly.

    To find such files, I use both methods from the previous section for finding files with a particular name:

    find ./ | grep "\.\_.*"

    We're finding a way to output all files in the current directory (recursively), and are then piping the output to grep, which ensures that it matches my regular expression. The regular expressions just says, "match anything that starts with a literal . followed by a literal _ followed by 0 or more of anything else." Run it like so to make sure you see the desired files.

    Now to do something with all the files you captured from that command, you wrap it with back-quotes (``). If I wanted to delete all of them:

    rm -f `find ./ | grep "\.\_.*"`

    I have the "rm" command (to remove, or delete, files) with a "-f" switch (which means to force a delete without asking for confirmation), and it will run for each file returned by the command within the back-quotes!

    I feel it would be irresponsible not to mention here that you should be very careful using the "rm" command. If you use the "rm" command with the "-f" switch, make sure you know exactly what you're going to be deleting, and that you really want it gone! If you use "-f", you won't get a second-chance.

    How do I get Command-line Access to my Web Host?

    I mentioned earlier in the article about connecting to a remote computer via SSH. A lot of these commands are most useful when used on your web server, which likely runs linux, so you'll need to be able to connect to the command line. The way to do so is by using a program called SSH, which does it securely.

    On Mac OS X, or on linux, you can run SSH from the Terminal application:

    ssh username@hostname

    If you're on Windows, you'll need to use a freely available program called PuTTY.

    You will be prompted for your password when you are connecting.

    If you do not have SSH access to your web host already, you will most likely be able to request it, and they will set it up for you.

    In Summary...

    Like most things, "you don't know, what you don't know." It might seem difficult to discover how to use the command-line; but there's a huge amount of power available to you once you wrap your head around it! Hopefully, this article will get you started exploring! Any questions?


  • Permalink for 'Quick Tip: Top 5 Awesome Features in Transmit 4'

    Quick Tip: Top 5 Awesome Features in Transmit 4

    Posted: May 6th, 2010, 12:03pm MDT by Andrew Burgess

    The ever-amazing Mac software company, Panic, has released the fourth version of their incredible FTP client Transmit last week. What’s packed into this version? Well, according to the release notes, “Everything is new!”


    Subscribe to our YouTube page to watch all of the video tutorials! 5. Brand New Interface

    The biggest changes in Transmit 4 are in the interface; you almost don’t recognize it as the same software!

    Transmit 3 Transmit 4 4. Super User-Friendly

    A lot of Transmit 4’s awesomeness is in its incredibly ease-of-use. For example, when viewing a folder (both local and remote) you’ve got a “bread-crumb” trail to make navigating between folders a breeze. Then, the sync panel now gives you a nice tooltip, making it easier to see exactly what will happen.

    3. Rules

    The preferences panel in Transmit 4 now includes a rules panel; this makes it really easy to skip certain files, like source control files.

    2. Local to Local / Server to Server

    With Transmit 4, either panel can be either a server or a local folder, making it super-simple to transfer files between folders.

    1. Mounting Disks

    The “one more thing” about Transmit 4 is that you mount servers as disks, just like you’d mount a local hard drive.

    Do you use Transmit?

    Or do you have another favourite FTP client? If you’d like to learn more, head on over to MacAppStorm for the full review.


  • Permalink for 'The State of CSS3 in Email Templates'

    The State of CSS3 in Email Templates

    Posted: May 6th, 2010, 9:06am MDT by Ros Hodgekiss

    On the heels of some of our recent findings regarding the state of CSS in email, I reckoned it was high time to shake things up a bit. So here goes – CSS3 in email lives. Ok, so I’m sorry if I made you drop your toast, there. I know you’re thinking, “But… It’s still largely experimental… In the browser, to boot!” Yes, CSS3 support is even more fickle amongst a swag of email clients that can’t even get CSS2 right. But that doesn’t mean that it’s too soon to touch any of it.

    In this article, I’ll go through two properties you can use in your email templates, alongside some practical examples. So, brush off your toast and let’s get down to business.

    Let’s talk CSS2 in Email.

    If you’ve been designing HTML email templates for a while now, you will know that it’s often near-impossible to predict what sort of CSS-related quirks will display when testing your design across the major email clients. For example, Gmail has been notorious for stripping any CSS that isn’t inline (and for a while, not recognizing table cellpadding & cellspacing), while some clients simply choose to do away with styles altogether.

    Gmail Style Tags

    If you’re new to designing HTML email templates, this is probably the most foreboding thing you can possibly read. But fear not, there’s lots of info out there to bring you up to speed. Give 24ways’ ‘Rock Solid HTML Emails‘ a skim and you will see that there’s no reason to crank up the zefrank. It’s manageable.

    Anyway, given that designers already have enough troubles with CSS2 support in email clients, shouldn’t CSS3 be a bit of a pipe dream? Well, read on.

    Is it too Early to be Using CSS3 in Email?

    Yes and no. For the yes case, there’s a couple of popular email clients that have pretty robust CSS3 support (more on that later). The great news is that a fair few of the CSS3 properties that display in these clients degrade gracefully elsewhere, meaning that there’s always a fallback option. But that said, if you want to ensure that your email templates display near-consistently across the major email clients, then CSS3 is not for you.

    If you swing over to our guide to CSS in email, you will see that there’s a few email clients that have partial, or full support for a number of CSS3 properties. And for the most part, they have one thing in common – Webkit.

    It’s a Webkit World

    How your email template looks in Outlook isn’t anything like how it will look on your Blackberry, or when you’re viewing your webmail in Firefox.

    If you have the blessing of always working on a Mac, checking your email on your iPhone and passing the time by browsing on your iPad, then you have one, fairly consistent view of the web. Unfortunately, the rest of us have to do with varying degrees of CSS support across a number of vendor platforms. How your email template looks in Outlook isn’t anything like how it will look on your Blackberry, or when you’re viewing your webmail in Firefox.

    So it’s probably no surprise to you that Apple devices use the same rendering engine (the software that decides how to display HTML & CSS code) across their email apps and the Safari browser. For designers, it’s probably less of a surprise that this engine is Webkit and its CSS3 support is comparatively, very good.

    That said, Webkit email clients (Apple Mail, iPhone & iPad Mail) account for roughly 20% of email clients used overall. However, what really counts are the email clients your subscribers are using. For example, a Mac software developer may have close to 100% of their customers viewing their newsletter on Apple devices.

    With this in mind, let’s have a look at some of the CSS3 properties that are now creeping into your inbox.

    Using Text-Shadow Usage:
    <!-- x offset, y offset, blur, and color, respectively -->
    <p style="text-shadow: 2px 2px 2px #000;">
       Welcome to the latest issue of Widgets Inc monthly widget gossip.
    </p>
    
    Works in:
    • Apple, iPhone & iPad Mail
    • Yahoo! Mail, Hotmail Live! & Gmail (when viewed in browsers other than IE)
    • Android default client & Gmail

    Adding drop and inner shadows with text-shadow is a non-destructive way to decorate your text. Not only can it save you from otherwise creating the same effect using an image, but it looks fine in clients where text-shadow isn’t supported.

    Using Border-Radius Usage:
    <p style="border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; border: 3px solid #000; background-color: #ccc; padding: 5px;">
       View it in a web browser.
    </p>
    Works in:
    • Apple, iPhone & iPad Mail
    • Thunderbird
    • Yahoo! Mail, Hotmail Live! & Gmail (when viewed in browsers other than IE)
    • Android default client

    Using rounded corners on your otherwise boxy layout or square buttons is already a commonly used technique on the web. It also can give your email templates a softer, more modern look in the above email clients, plus safely reverts to square corners when not supported.

    With the announcement that border-radius will be formally implemented in IE9, we can expect to see more of its use.

    One Step Further: Animation and More

    Some of the more extreme uses of CSS3 in email templates can be found in situations where the recipients are using a very limited set of email clients. A great example of this is the aforementioned Mac developer. Panic, the purveyors of ’shockingly good Mac software’, send amazing invoices after you purchase one of their titles, which include – gasp! – animated, glowing buttons:

    Here’s the code they used to achieve this effect:

    -webkit-animation-name: 'glow';
    -webkit-animation-duration: .7s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-direction: alternate;
    -webkit-animation-timing-function: ease-in-out;

    Of course, this wouldn’t look nearly as good in an email client other than Apple Mail, but it’s certainly a neat concept!

    And Another Example…

    How much CSS3 can you spot in this other email design from Panic? Click through for a larger version:

    Take note of how the design resizes elegantly in the browser. And those airmail stripes? They’re forward slashes (/). Genius! To find out what went into this template, check out this article.

    /
    <b style="color: #f5290a;">/</b>
    <i style="color: #006699;">/</i>
    <b style="color: #f5290a;">/</b>
    <i style="color: #006699;">/</i>
    <b style="color: #f5290a;">/</b>
    <i style="color: #006699;">/</i>
    <b style="color: #f5290a;">/</b>
    <i style="color: #006699;">/</i>
    
    So, on that Note…

    Take a look at CampaignMonitor’s email client usage reports, and swing over to the definitive guide to CSS in email to get an idea of which CSS3 properties are available across the major email clients. And of course, test, test, test. With a sprinkle of CSS3, a little experimentation and a dollop of caution, you can make your email template stand out from the crowd.

    If you’re of the ability, and would like to sell your email designs, now is the time to check out the Email Templates category on ThemeForest!


  • Permalink for 'Build a WordPress Plugin to Add Author Biographies to your Posts'

    Build a WordPress Plugin to Add Author Biographies to your Posts

    Posted: May 5th, 2010, 10:28am MDT by Dan Walker

    Many popular blogs these days are authored by multiple contributors. Today, we’ll create a simple WordPress plugin that will allow us to add the post author’s biography to the conclusion of each post, much like you see on Nettuts.

    Nettuts Author Bio 1. Have a Bio Ready

    If you don’t already display authors’ biographical info, then the you can add and edit biographical info by heading to the users pane from within the WordPress dashboard, selecting a user, and filling in a quick bio. We’re also going to be adding a gravatar for the author, so ensure that you also set an email address.

    2. Create the Necessary Files

    We’ll need to create a single file that contains the functionality of our plugin. Fire up your FTP of choice, and, within the wp-content/plugins/ folder, create a file called ntauthorbio.php. In order for WordPress to recognize our plugin, we need to create a quick header comment in our file, much like you do at the top of style.css. Paste the following code into your file, and, of course, make adjustments accordingly.

    /*
    Plugin Name: Nettuts Author Bio
    Plugin URI: [www.nettuts.com] Description: This plugin adds an authors bio to his/her post
    Author: nettuts
    Version: 0.1
    Author URI: [www.nettuts.com] */
    
    3. Functions & Actions

    Next, we’ll create the base for our plugin. Paste the following after the opening comment header.

    function author_bio_display($content)
    {
    	// this is where we'll display the bio
    }
    
    function author_bio_style()
    {
    	// this is where we'll style our box
    }
    
    function author_bio_settings()
    {
    	// this is where we'll display our admin options
    }
    
    function author_bio_admin_menu()
    {
    	// this is where we add our plugin to the admin menu
    }
    
    add_action('the_content', 'author_bio_display');
    add_action('admin_menu', 'author_bio_admin_menu');
    add_action('wp_head', 'author_bio_style');
    

    “Hooks are provided by WordPress to allow your plugin to ‘hook into’ the rest of WordPress; that is, to call functions in your plugin at specific times, and thereby set your plugin in motion.”

    Above we’ve created four functions that our plugin will require to work properly. Each function has a specific purpose (as commented above), and also, each is tied to a specific action (apart from author_bio_settings, which will be called from another function.

    When developing plugins, it’s important to understand what a ‘hook’ is. A hook is a place in the running cycle where we can hook into WordPress, and call our functions. For example the hook used above, for author_bio_display, is the_content; this means that when WordPress uses the_content (used for displaying a post/page’s main content), it will first call the function we’ve given it.

    • the_content – the content of the page/post is displayed
    • admin_menu – called when the sidebar in the admin dashboard is created
    • wp_head – lets us add code to the head tags of the page. This is why you include wp_head() when designing your themes.
    4. The Display Function

    The most important function in our plugin is the display function, which will handle the process of actually displaying the information after the content. Before we start, it’s important to note that this function accepts a parameter, called $content. This means that the content of the page/post is passed to our function, so we can then append our author bio.

    Let’s start with a simple if/else statement.

    function author_bio_display($content)
    {
    	// this is where we will display the bio
    
    	if ( is_single() || is_page() )
    	{
    		$bio_box = // placeholder;
    		return $content . $bio_box;
    	} else {
    		return $content;
    	}
    }
    

    Above, we check to see if the content is being displayed on a single post using is_single(), or a page using is_page(). If either returns true, we can post our box which will be placed in the $bio_box variable. Otherwise, if we’re on some different page, such as the archives or front page, we should simply return the content untouched.

    Now we need to add our code for the box to appear, change your $bio_box to match the following code.

    $bio_box =
    '<div id="author-bio-box">
    	'.get_avatar( get_the_author_meta('user_email'), '80' ).'
    	<span class="author-name">'.get_the_author_meta('display_name').'</span>
    	<p>'.get_the_author_meta('description').'</p>
    	<div class="spacer"></div>
    </div>';
    

    The styling, of course, can be changed later to fit your own tastes, but for now, we’ll use a simple box, and will add some CSS to style it shortly.

    We’re using a few functions above to retrieve our required data. get_avatar() is a built-in function in WordPress that will return a user’s gravatar, if they have one, according to their email. We pass the get_avatar() function two parameters; the author’s email, and a size for the image (80px*80px in our case).

    The function get_the_author_metacan retrieve any piece of information about a registered WordPress user. A full list of the items you can return can be found on WordPress Codex.

    If we now run our plugin, we should see something that resembles this:

    It’s not the prettiest looking biography, but we now have the basic functionality we’re after. If you’re still having problems, ensure that the author of the post/page has a biography and/or gravatar, and also ensure that the plugin has been activated in the plugins section of the dashboard. Let’s next style things a bit.

    5. Making it Pretty

    If you’re a designer, here’s your chance to do as you please! My code below is just enough to make our box look clean and simple. To provide an example of how wp_head() can be used, we’ll insert the CSS for this box into the head tag of our document. However, you can also simply place this within your stylesheet.

    This author_bio_style() function needs to return a simple block of CSS.

    function author_bio_style()
    {
    	// this is where we'll style our box
    	echo
    	'<style type=\'text/css\'>
    	#author-bio-box {
    		border: 1px solid #bbb;
    		background: #eee;
    		padding: 5px;
    	}
    
    	#author-bio-box img {
    		float: left;
    		margin-right: 10px;
    	}
    
    	#author-bio-box .author-name {
    		font-weight: bold;
    		margin: 0px;
    		font-size: 14px;
    	}
    
    	#author-bio-box p {
    		font-size: 10px;
    		line-height: 14px;
    		font-style: italic;
    	}
    
    	.spacer { display: block; clear: both; }
    	</style>';
    }
    

    The above code doesn’t require much explanation; CSS is beyond the scope of this tutorial. Generally, we’re just creating a box with a border, and floating the image left. Finally, we add a spacer to make sure the box is big enough to fit the image and text in. You could also use the clearfix hack, or even overflow:hidden to achieve this effect. Ultimately, that will depend on your specific layout.

    Your new fangled box should look similar to mine now; see below.

    6. Making a Settings Page

    Before we wrap up, let’s take a look at adding a settings page in the dashboard for our plugin. Most plugins rely on some sort of settings section to provide a bit more flexibility without the user having to edit any code.

    There are numerous options we could add; such as, where the box appears (top or bottom), the colors used, exclude certain users, and so on. For this tutorial, I’ve chosen to specify if the plugin can appear on only pages, only posts, or both. Hopefully this will be enough to show you the ropes. At that point, you can extend the functionality how you see fit.

    Making the Page

    We need to setup a page in the admin dashboard. To do so, we need to tell WordPress what to do when the admin_menu action triggers. To compensate, we’ll edit our author_bio_admin_menu() function to look like the code below:

    function author_bio_admin_menu()
    {
    	// this is where we add our plugin to the admin menu
    	add_options_page('Author Bio', 'Author Bio', 9, basename(__FILE__), 'author_bio_settings');
    }
    

    The above code creates an options page in the dashboard, and passes the following parameters:

    • Menu Name – Author Bio
    • Page Title – Author Bio
    • Access Privilege – 9 – or, only Administrator access
    • Handle
    • The required function – author_bio_settings()

    We next need to provide the page some content. Since we called author_bio_settings() when creating the page, that’s the function we’ll be using to display our options form and update the database.

    The Settings Function

    Simply put, this function needs to display a form with the options. It also needs to check whether the form has been submitted, and, if so, store the new values in the database. First, let’s concentrate on creating the form.

    function author_bio_settings()
    {
    	// this is where we'll display our admin options
    
    	$options['page'] = get_option('bio_on_page');
    	$options['post'] = get_option('bio_on_post');
    
    	echo '
    	<div class="wrap">
    		'.$message.'
    		<div id="icon-options-general" class="icon32"><br /></div>
    		<h2>Author Bio Settings</h2>
    
    		<form method="post" action="">
    		<input type="hidden" name="action" value="update" />
    
    		<h3>When to Display Author Bio</h3>
    		<input name="show_pages" type="checkbox" id="show_pages" '.$options['page'].' /> Pages<br />
    		<input name="show_posts" type="checkbox" id="show_posts" '.$options['post'].' /> Posts<br />
    		<br />
    		<input type="submit" class="button-primary" value="Save Changes" />
    		</form>
    
    	</div>';
    }
    

    We start by grabbing some options from the database. Of course, we don’t currently have a method for setting them yet, so they’ll be blank for now. Next, we display the form, which is already styled by WordPress’ dashboard CSS. You’ll notice we’re displaying a (currently unset) variable called $message; this is so we can notify the user when we update the settings if it was successful.

    We print our options at the end of the checkbox code. If the user turns an option on, we need to store it in the database as ‘checked’ in order to check the checkbox. The functions we use to get and set options are get_option() and update_option() respectively. The get function requires the name of the option (so it’s important to be unique), and the update option needs the name of the option and the new value. If the update function doesn’t find the option, it simply creates a new one.

    So far your page should look like do:

    Now, let’s add our code to take the values sent by the form, and update the options in the database. The form contains a hidden value, called action, which is set to ‘update.’ We’ll check if that value is set, and if so, we update our options. This code should be placed at the top of our autor_bio_settings() function.

    if ($_POST['action'] == 'update')
    {
    	$_POST['show_pages'] == 'on' ? update_option('bio_on_page', 'checked') : update_option('bio_on_page', '');
    	$_POST['show_posts'] == 'on' ? update_option('bio_on_post', 'checked') : update_option('bio_on_post', '');
    	$message = '<div id="message" class="updated fade"><p><strong>Options Saved</strong></p></div>';
    }
    

    If the form has been submitted, we use the ternary operator (if you’re unsure of how these work, look them up – they’re a simple form of if/else) to check whether the checkboxes are checked or not. If they are, then we set the option as ‘checked;’ otherwise we set it as blank. Finally, we set the message displayed to a successful dialog, already styled by WordPress.

    Changing the Output

    Now, we should be able to set options and see them change in our options page; however, the functionality of our plugin will not alter yet as we’ve not told it to do so. So the final step in our project is to make the display function react to these options. In our author_bio_display() function, prepend the following code to the top, in order to get the options previously set.

    $options['page'] = get_option('bio_on_page');
    $options['post'] = get_option('bio_on_post');
    

    Now that we have these values, we only need to execute the display code if the option is set. To do so, we change our if statement accordingly.

    if ( (is_single() && $options['post']) || (is_page() && $options['page']) )
    

    Here we have implemented two conditions that, if met, will cause our box to display. Not too hard, right? Here’s our full plugin:

    <?php
    /*
    Plugin Name: Nettuts Author Bio
    Plugin URI: [www.nettuts.com] Description: This plugin adds an authors bio to his/her post
    Author: nettuts
    Version: 0.1
    Author URI: [www.nettuts.com] */
    
    function author_bio_display($content)
    {
    	// this is where we will display the bio
    
    	$options["page"] = get_option("bio_on_page");
    	$options["post"] = get_option("bio_on_post");
    
    	if ( (is_single() && $options["post"]) || (is_page() && $options["page"]) )
    	{
    		$bio_box =
    		"<div id="author-bio-box">
    			".get_avatar( get_the_author_meta("user_email"), "80" )."
    			<span class="author-name">".get_the_author_meta("display_name")."</span>
    			<p>".get_the_author_meta("description")."</p>
    			<div class="spacer"></div>
    		</div>";
    
    		return $content . $bio_box;
    	} else {
    		return $content;
    	}
    }
    
    function author_bio_style()
    {
    	// this is where we will style our box
    	echo
    	"<style type=\"text/css\">
    	#author-bio-box {
    		border: 1px solid #bbb;
    		background: #eee;
    		padding: 5px;
    	}
    
    	#author-bio-box img {
    		float: left;
    		margin-right: 10px;
    	}
    
    	#author-bio-box .author-name {
    		font-weight: bold;
    		margin: 0px;
    		font-size: 14px;
    	}
    
    	#author-bio-box p {
    		font-size: 10px;
    		line-height: 14px;
    		font-style: italic;
    	}
    
    	.spacer { display: block; clear: both; }
    	</style>";
    }
    
    function author_bio_settings()
    {
    	// this is where we will display our admin options
    	if ($_POST["action"] == "update")
    	{
    		$_POST["show_pages"] == "on" ? update_option("bio_on_page", "checked") : update_option("bio_on_page", "");
    		$_POST["show_posts"] == "on" ? update_option("bio_on_post", "checked") : update_option("bio_on_post", "");
    		$message = "<div id="message" class="updated fade"><p><strong>Options Saved</strong></p></div>";
    	}
    
    	$options["page"] = get_option("bio_on_page");
    	$options["post"] = get_option("bio_on_post");
    
    	echo "
    	<div class="wrap">
    		".$message."
    		<div id="icon-options-general" class="icon32"><br /></div>
    		<h2>Author Bio Settings</h2>
    
    		<form method="post" action="">
    		<input type="hidden" name="action" value="update" />
    
    		<h3>When to Display Author Bio</h3>
    		<input name="show_pages" type="checkbox" id="show_pages" ".$options["page"]." /> Pages<br />
    		<input name="show_posts" type="checkbox" id="show_posts" ".$options["post"]." /> Posts<br />
    		<br />
    		<input type="submit" class="button-primary" value="Save Changes" />
    		</form>
    
    	</div>";
    }
    
    function author_bio_admin_menu()
    {
    	// this is where we add our plugin to the admin menu
    	add_options_page("Author Bio", "Author Bio", 9, basename(__FILE__), "author_bio_settings");
    }
    
    add_action("the_content", "author_bio_display");
    add_action("admin_menu", "author_bio_admin_menu");
    add_action("wp_head", "author_bio_style");
    
    ?>
    
    Voila

    Hopefully if everything went according to plan, you should now have a working authors’ biography box after your posts/pages. Further, you now have a custom settings page in your WordPress dashboard, that you’re free to extend how you see fit.

    Thanks for reading my first post here on Nettuts. If you have any questions feel free to leave a comment below!


  • Permalink for 'I Can’t Believe it’s Gone Premium!'

    I Can’t Believe it’s Gone Premium!

    Posted: May 4th, 2010, 6:55pm MDT by Aaron Osteraas

    Tuts+ Premium just got more awesome. Cgtuts+ and Activetuts+ have now joined our Premium program. Your Premium Membership already grants you access to the best and most in depth Photoshop, web development, vector, audio and After Effects tutorials and files. With CG Premium and Active Premium, you now have access to high-end computer graphics, Flash and ActionScript tutorials and source files.

    We now offer 7 Premium programs for $9 a month. That’s $1.29 per Premium program, per month. You’ll get up to 28 new Premium tutorials and downloads in total each month as part of your membership. You’ll also get instant access to 283 exclusive tutorials and 716 source files – and counting – already available to Premium members.

    Make sure you’re getting the best and most valuable education you can and say thank you to Tuts+ – become a member.

    Want to know more?

    To kick-off CG Premium, members will instantly get access to a brand new tutorial exclusive for Premium members. In it, you’ll learn how to Model, UV, and Texture a Mac-10 Submachine Gun

    Our first Cgtuts+ Premium tutorial is loaded with tips.

    Over the course of this 10 hour monster of a tutorial, you will gain access to time saving professional gun modeling tricks and techniques that are universal to any 3d modeling application. We’ll give you an in-depth look at using the revolutionary and intuitive Headus UVLayout to quickly and effectively lay out all of the gun’s UVs, and finally, some tried tested and true texture painting techniques that use a careful balance between diffuse, specular, and bump maps to create realistic and convincing final metal textures.

    Learn the Secret to High-End CG Weapon Creation

    Follow professional CG artist, Ben Tate, as he demonstrates his entire process of modeling, UV mapping and texturing an extremely high quality Mac-10 submachine gun.

    In the first part of this mammoth series, we will discuss a variety of efficient and innovative modeling techniques to create a medium density model. You will learn how to break the model down into into its respective parts in the blockout stage, and the approaches and tools to use when crafting the more complex shapes and parts.

    We’ll also discuss where and where not to use subdivision modeling to speed things up further. This tutorial is intended for intermediate to advanced CG artists who are looking to take their skills up a notch, or maybe learn a new trick or two.

    CG Tuts textured machine gun

    Activetuts+ has an amazing first Premium tutorial.

    Build an OOP Based Turntable in AS3

    You’ll build a turntable with controls which will allow users to view and rotate an object in 360°. You’ll use Object-Oriented Programming techniques so that you end up with a class (in a package) that can be re-used from project to project.

    Professional and Detailed Instructions Inside

    Premium members can Log in and Download! Otherwise, Join Now! Here’s a taster of what you can expect from this tutorial.

    Our Premium tutorials will be added weekly in addition to our existing publishing schedule. Once you’re a member you can log in at the Tuts+ Dashboard and go to Premium Content to get started.


  • Permalink for 'Building a 5 Star Rating System with jQuery, AJAX and PHP'

    Building a 5 Star Rating System with jQuery, AJAX and PHP

    Posted: May 4th, 2010, 4:46pm MDT by Erik Wurzer

    In this tutorial, you’ll learn how to build a rating system with AJAX, PHP, and jQuery. Votes will be recorded and updated in real-time with the magic of AJAX, and we’ll also leverage the power of PHP so that you don’t even need a database!

    Step 1. Building the HTML

    We’re going to create a simple page that lists two movies, and allows you to rate them. This means we need the stars to show the current rating, and to allow voting. We also want an area to show the total votes cast, and the current rating down to one decimal place.

    Let’s take a look at the HTML/CSS

            <div class='movie_choice'>
                Rate: Raiders of the Lost Ark
                <div id="r1" class="rate_widget">
                    <div class="star_1 ratings_stars"></div>
                    <div class="star_2 ratings_stars"></div>
                    <div class="star_3 ratings_stars"></div>
                    <div class="star_4 ratings_stars"></div>
                    <div class="star_5 ratings_stars"></div>
                    <div class="total_votes">vote data</div>
                </div>
            </div>
    
            <div class='movie_choice'>
                Rate: The Hunt for Red October
                <div id="r2" class="rate_widget">
                    <div class="star_1 ratings_stars"></div>
                    <div class="star_2 ratings_stars"></div>
                    <div class="star_3 ratings_stars"></div>
                    <div class="star_4 ratings_stars"></div>
                    <div class="star_5 ratings_stars"></div>
                    <div class="total_votes">vote data</div>
                </div>
            </div>
        

    Notice how there are no graphics in this HTML? They’ll be added with CSS. We’re just using the HTML to create the framework that the widget works from. Now it’s time to start adding CSS.

            .rate_widget {
                border:     1px solid #CCC;
                overflow:   visible;
                padding:    10px;
                position:   relative;
                width:      180px;
                height:     32px;
            }
            .ratings_stars {
                background: url('star_empty.png') no-repeat;
                float:      left;
                height:     28px;
                padding:    2px;
                width:      32px;
            }
            .ratings_vote {
                background: url('star_full.png') no-repeat;
            }
            .ratings_over {
                background: url('star_highlight.png') no-repeat;
            }
        

    This first part of the CSS accomplishes a few things:

    • Gives the default ‘empty’ start to each star location
    • Sets up classes for filled in stars, and highlighted stars
    • Defines and styles the stars’ container.

    You can either use the graphics provided in the download, or make your own. There needs to be a graphic for each of the three states: empty, full, and highlighted.

    Next we add a little more CSS to position the total votes box, and center the widgets so the page matches the graphic at the start of this section.

            .total_votes {
                background: #eaeaea;
                top: 58px;
                left: 0;
                padding: 5px;
                position:   absolute;
            }
            .movie_choice {
                font: 10px verdana, sans-serif;
                margin: 0 auto 40px auto;
                width: 180px;
            }
        
    Step 2. Adding the UI Interactivity

    At this point, we have a very plain looking bunch of empty stars, but they don’t do a whole lot at this point. This is where jQuery comes to the rescue.

    Our first step is to add mouseover and mouseout handlers for the stars. We need to highlight the star the mouse is over, and all the preceding stars.

            $('.ratings_stars').hover(
                // Handles the mouseover
                function() {
                    $(this).prevAll().andSelf().addClass('ratings_over');
                    $(this).nextAll().removeClass('ratings_vote');
                },
                // Handles the mouseout
                function() {
                    $(this).prevAll().andSelf().removeClass('ratings_over');
                    set_votes($(this).parent());
                }
            );
        

    We’re taking advantage of jQuery’s powerful .prevAll() and .nextAll() methods to get the stars preceding and following the currently moused over star.

    The code above then adds and removes the classes to make the stars under the mouse and before ‘highlighted’, and the stars after ‘not highlighted’.

    What about set_votes() ?

    This is a function that checks which stars should be in the ‘full’ state, and ties in closely with the next step, where we grab remote data from the server.

    Step 3. Retrieving Data from the Server

    Our stars highlight when you move the mouse over them, and that’s a great start. But what about the red stars showing the current vote? To reach this step, we need to both get the information from the server, and write some JavaScript to handle that data.

            $('.rate_widget').each(function(i) {
                var widget = this;
                var out_data = {
                    widget_id : $(widget).attr('id'),
                    fetch: 1
                };
                $.post(
                    'ratings.php',
                    out_data,
                    function(INFO) {
                        $(widget).data( 'fsr', INFO );
                        set_votes(widget);
                    },
                    'json'
                );
            });
        

    This code block – actually all the JavaScript – goes in a document.ready block. This particular code executes right away. It queries the server and gets some information on every vote widget on the page.

    First we set up an object, out_data, to contain the information we’re sending to the server. Our PHP script expects to see ‘fetch’ when just grabbing data, so we include it here. We also include the ID of the widget, which lets the server-side script know what data we’re after. When the call back function fires, it contains a JavaScript object that looks like this:

            {
                "widget_id"     : "r1",
                "number_votes"  : 129,
                "total_points"  : 344,
                "dec_avg"       : 2.7,
                "whole_avg"     : 3
            }
        

    The .data() method is a bit of jQuery magic that allows you to associate arbitrary data with a DOM
    object.

    If you look closely at the code, you’ll see we’re taking that object (stored in the variable INFO) and
    doing something with it via the .data() method.

    The .data() method is a bit of jQuery magic that allows you to associate arbitrary data with a DOM
    object. In this case, we’re storing the data in the widget div. It can be accessed later like this:

            $('#one_of_your_widgets).data('fsr').widget_id;
        
    set_votes(), Finally.

    After the data has been returned from the server, its handed off indirectly to set_votes().

            function set_votes(widget) {
    
                var avg = $(widget).data('fsr').whole_avg;
                var votes = $(widget).data('fsr').number_votes;
                var exact = $(widget).data('fsr').dec_avg;
    
                $(widget).find('.star_' + avg).prevAll().andSelf().addClass('ratings_vote');
                $(widget).find('.star_' + avg).nextAll().removeClass('ratings_vote');
                $(widget).find('.total_votes').text( votes + ' votes recorded (' + exact + ' rating)' );
            }
        

    The first three lines are for readability, as those variable names are pretty long. So let’s take a look at what’s happening here.

    Line 7: ‘avg’ is a whole number, representing the rounded vote average of this widget. Because it’s
    a number 1-5, we can use it to find the proper star in the widget, and turn it, and the
    preceding ones to our ‘filled’ graphic. Notice the use of .andSelf() to include the star that
    we’ve selected.

    Line 8: This is quite similar to line seven, but we’re removing the filled graphic from later stars. This
    is necessary in case the average for this widget has gone down since the last vote.

    Line 9: Here we’re updating the grey box underneath the widget, which shows a more precise rating,
    and lets a visitor know how many votes have been cast.

    Step 4. Let the Voting Begin

    The final step for the UI is to enable voting. We’re going to add a click handler to each of the stars. This click handler will be responsible for sending the vote data to the server.

    Here’s the click handler:

            $('.ratings_stars').bind('click', function() {
                var star = this;
                var widget = $(this).parent();
    
                var clicked_data = {
                    clicked_on : $(star).attr('class'),
                    widget_id : widget.attr('id')
                };
                $.post(
                    'ratings.php',
                    clicked_data,
                    function(INFO) {
                        widget.data( 'fsr', INFO );
                        set_votes(widget);
                    },
                    'json'
                );
            });
        

    In this code block, we start out by creating some variables not only for clarity, but, in this case, so they can be used within the .post callback. Remember the click handler is assigned to the stars, so we also need that second variable, widget, to have the object containing the data.

    First, we set up our outgoing data, which we place in the object clicked_data. We grab the class which includes a class name in the format of star_# telling us what vote is being given, and prepare to send that to the server, along with the widget’s ID.

    The widget ID is the corner stone that this voting system relies on. It allows us to look up our stored data, and to easily show that data to the visitor.

    Finally, on line line, we send this information to the server. The server will add the vote to the current totals, and send information back to the browser containing the updated data. The values displayed by the widget are then updated with set_votes().

    Step 5. PHP: Creating the Class

    Now that the UI is finished, we need to create a server side script to store and retrieve voting data.

    We’re going to create a very simple class in PHP, called ‘Ratings,’ and use it to handle server requests for our rating system. There are only going to be two methods, plus the invocation. The use of our class will look like so:

            # New Object
            $rating = new ratings($_POST['widget_id']);
    
            # either return ratings, or process a vote
            isset($_POST['fetch']) ? $rating->get_ratings() : $rating->vote();
        

    If you go back to section four, you’ll see we load the data with the variable ‘fetch’ set – that’s what we’re looking for here on line five. If its not set, then we’re processing a vote.

    The first thing we’re going to look at is the begining of the class, and, more specifically, the constructor.

            class ratings {
    
                private $data_file = './ratings.data.txt';
                private $widget_id;
                private $data = array();
    
            function __construct($wid) {
    
                $this->widget_id = $wid;
    
                $all = file_get_contents($this->data_file);
    
                if($all) {
                    $this->data = unserialize($all);
                }
            }
        

    serialize() and unserialize are a great way to easily store
    PHP data structures on disk.

    There’s a lot going on here in very few lines, so I’m going to cover the important bits.

    Line 3: This needs to be set to a text file you’d like to use to store your data. We’re not using a database for this project, although you easily could. A simple file will suffice for our needs.

    Line 7: The constructor. This is called when we create our object, and immediately stores the ID of the widget.

    Line 11: We try to load the text file. If the file doesn’t exist, fine, but on some systems you’ll need to create it ahead of time and give it the proper permissions for PHP to be able to read and write to it.

    Line 14: This line is important. It takes the data from the text file – if there is one – and unserializes() it. The file contains a complex PHP array that’s been converted to a plain text representation, via serialize(), allowing us to store it and read it back in as an array later.

    Step 6. The get_ratings() Method.

    This method is called either on its own, or from the vote() method. It finds the data for a particular widget ID and returns it to the requesting page, in JSON format.

        public function get_ratings() {
            if($this->data[$this->widget_id]) {
                echo json_encode($this->data[$this->widget_id]);
            }
            else {
                $data['widget_id'] = $this->widget_id;
                $data['number_votes'] = 0;
                $data['total_points'] = 0;
                $data['dec_avg'] = 0;
                $data['whole_avg'] = 0;
                echo json_encode($data);
            }
        }
        

    This only looks complicated – it’s actually pretty simple. The first thing we do is check if the array stored in $this->data has a key matching our widget ID. If it does, we just return that information, because that’s the widget data the page was requesting.

    We don’t have to do anything to that data because its already in array form. $this->data is just an array of arrays. We encode the array we want with json_encode() and send it back to the browser.

    If there’s no data for the widget ID we’ve requested, we create a record with all zero values, and send it back to the browser.

    Step 7. The vote() Method

    Next, we need to create a method to handle incoming votes. When the method finishes, it has to call get_ratings() to send the updated information back to the web browser.

    The Method Start
            public function vote() {
                # Get the value of the vote
                preg_match('/star_([1-5]{1})/', $_POST['clicked_on'], $match);
                $vote = $match[1];   
    

    The first thing we do is get the value of the vote. Remember that somewhere in ‘clicked_on’ is a class name in the format of star_#. "star_4", for example. To get that value, we’re using a regular expression and capturing the value of the number to $match[1].

    The method Middle
                $ID = $this->widget_id;
                # Update the record if it exists
                if($this->data[$ID]) {
                    $this->data[$ID]['number_votes'] += 1;
                    $this->data[$ID]['total_points'] += $vote;
                }
                # Create a new one if it does not
                else {
                    $this->data[$ID]['number_votes'] = 1;
                    $this->data[$ID]['total_points'] = $vote;
                }
        

    Here we store $this->widget_id into $ID for clarity – the following code gets a bit rough on the eyes without it.

    We check if information for this ID exists, and, if so, we add a vote to the total vote count, and add the points from the vote received. This is a running total of all votes; so if one person gives five stars, and another, three, that’s eight points total.

    If the record doesn’t exist, we create one, with one vote, and just the points from the incoming vote.

    Finishing Up
                $this->data[$ID]['dec_avg'] = round( $this->data[$ID]['total_points'] / $this->data[$ID]['number_votes'], 1 );
                $this->data[$ID]['whole_avg'] = round( $this->data[$ID]['dec_avg'] );
    
                file_put_contents($this->data_file, serialize($this->data));
                $this->get_ratings();
            }
        

    Once we’ve updated the vote and point totals, we have to calculate both the average expressed as a whole number, and to one decimal point. To avoid having to do the math twice, we first calculate the average to one decimal on line one, and then round that off to a whole number, on line two.

    On line four, we’re storing the changed information back on disk after processing it with serialize(). Once the data is safely stored away, we call $this->get_ratings() to send the new, updated information to the browser.

    Conclusion

    For the sake of simplicity, this isn’t a 100% complete solution. To extend this project, we should store a cookie to make sure people only vote once, or even record the IP address. It’s also possible that two first-votes couple happen simultaneously, and only one may be recorded. It is, however, a great start, and is more then suitable for keeping track of votes on a few handfuls of items on your website. Thoughts? Thanks for reading!


  • Permalink for 'Quick Tip: A 4 Minute Crash-Course in WordPress Custom Fields'

    Quick Tip: A 4 Minute Crash-Course in WordPress Custom Fields

    Posted: May 4th, 2010, 2:27pm MDT by Jeffrey Way

    Today’s Basix video quick tip topic comes from a question on Twitter, concerning the use of custom fields in WordPress. Luckily, as you’ll find, attaching unique data to postings is as simple as assigning a value in the “Edit Post” page, and then referencing that information with the get_post_meta() method.


    Subscribe to our YouTube page to watch all of the video tutorials!

    Prefer to watch this video on Screenr.com?

    Step 1: Create a New Post

    In your local testing environment, create a new posting in the WordPress admin panel, and scroll to the bottom, until you see the “Custom Fields” widget.

    Custom Fields

    This section allows for a key, and a value. For example, if you aren’t taking advantage of the new “Post Thumbnail” feature, available in WordPress 2.9, and need a way to attach a thumbnail to each posting, this is where you’d accomplish that task. You could assign a key of “thumb,” and a value, which is equal to a path to the desired thumbnail. Go ahead and fill this section with some test data – anything you wish. I’ll use “difficulty” as my key,” and “hard” as the value.

    Step 2: Edit Index.php

    Now visit your theme, and within the WordPress loop in your index.php page, reference the get_post_meta() method.

    <?php echo get_post_meta($post->ID, 'difficulty', true); ?><
    

    This method accepts three parameters.

    • The id for the desired post. You can use $post->ID or “the_id()” to insert this value.
    • The key that you require. Remember, you can insert multiple custom fields. This is why we need to reference the key, in my case, “difficulty.”
    • A boolean, which determines whether you want the information returned as a string, or an array. As I’m echoing out my value, I’ve chosen true (or string).
    Step 3: What If…

    If you view run the website, you’ll see the correct value. If you went with a thumbnail path in your custom field, make sure that you echo out that string from within an IMG tag, accordingly. However, there’s one problem here; it’s possible that not EVERY single post will have this “difficulty” custom field attached, yet we’re blatantly assuming that there will be. This is inefficient. Instead, why don’t we first create an “if” statement, and determine whether our desired key exists first. Smarter right?

    <?php if ( get_post_meta($post->ID, 'difficulty') ) :  ?>
       <small> <?php echo get_post_meta($post->ID, 'difficulty', true); ?></small>
    <?php endif; ?>
    
    Conclusion

    Custom fields are a staple in every experienced WordPress designer’s toolbox. Learn them, and use them! Thanks for reading or watching!


  • Permalink for 'Creating a CMS Website with SiteGrinder and Pagelime'

    Creating a CMS Website with SiteGrinder and Pagelime

    Posted: May 3rd, 2010, 5:56pm MDT by Adam Dexter

    In this tutorial, you will learn how to take a Photoshop file, and convert it to a valid, jQuery enabled, Pagelime CMS integrated website, ready to hand off to your clients with no coding, using Photoshop, SiteGrinder 3 and Pagelime.

    Prefer a Video Tutorial? Before We Get Started

    SiteGrinder 3 is a fantastic, feature packed piece of software, by the guys over at Media Lab, which allows you to take a website mocked up in Adobe Photoshop, and export it into a fully valid, chopped and functioning website in minutes with no coding knowledge necessary. Pagelime is a simple CMS, designed with your clients in mind, that allows immediate integration into a website without any coding skill required. Pagelime allows your client to simply and easily make edits to content, change images, add and delete pages and basically manage their own website in a way they can understand, all within a clean, brand-able, web based application.

    A Quick Note

    The tutorial is approximately 10-15 minutes long, and assumes a general working knowledge of SiteGrinder 3. If you’re not quite up to snuff on your SiteGrinder skills, visit Media Lab’s SiteGrinder 3 TV site for a great set of video tutorials that will more than get you up to speed on how to implement your site. Overall, the system is really cool and has a TON of features. We highly recommend starting with the Essentials 1 – Workflow, I personally enjoyed the Buttons and Animation which details how to painlessly add jQuery effects and really nice drop-down menus, and Essentials 2 – Content. If you only have time for one, just watch Essentials 1 – Workflow to get up to speed.

    I’ll be walking you through in general step by step instructions with more in-depth information within each step.

    Step 1 Open your PSD Site Design in Photoshop

    Today we will be using a “Compani” template that the SiteGrinder crew has generously lent us, however, almost any website mocked up in Photoshop can become “SiteGrinder ready,” through the process of adding SiteGrinder hints and formatting your layers appropriately. Again, this tutorial assumes you have knowledge of the SiteGrider markup and using hints. If you don’t, we recommend that you visit SiteGrinder 3 TV and catch up with the first two parts of the SiteGrinder essentials. To download this template or a slew of any other templates, you can visit their wiki page with the template downloads.

    Step 2 Make sure any images you want to edit through Pagelime have the “-content” hint attached to them.

    Because SiteGrinder does not make image CSS classes accessible to the user by default, through adding the “-content” hint, we can force SiteGrinder to render the image (IMG) tag within a DIV. This DIV will then be available later in the SiteGrinder 3 Design Manager to have a CSS class added to it. This is important because for Pagelime to work correctly, all editable regions, or, “things you want the client to be able to change,” must be tagged with the same special CSS class, we’ll get to this in more detail in step 4.

    Step 3 Save the PSD file and then navigate to File >>> Automate >>> SiteGrinder 3

    If the SiteGrinder 3 Engine is not already open, this will launch the SiteGrinder 3 engine. After the Engine launches, SiteGrinder will generate a report on any errors or warnings it may find in the template. Review the errors and fix any serious errors that apply* (you can also choose to ignore them, the site should still build). After you have resolved the errors, continue to the Build and Deploy page. Here, you should check off the pages you want to have built by SiteGrinder. In this tutorial, we will only be building out the home page. After the desired pages are selected, click “Build”.

    *Note: If you are using the SiteGrinder 3 test template with a demo or basic version of SiteGrinder 3, it’s possible that you might encounter a report with 2 “serious” errors. Look through the errors carefully. It’s most likely that the errors are being thrown because you are referencing tags such as -$ or -blog within the template that require additional plugins. The Commerce Add On for -$ and The Control Add On for -blog. If that is the case, you can continue anyway. In this tutorial, we are not building out the “store” or “blog” page, so these errors are irrelevant.

    Step 4 After the buildout is complete, click on the page file name to enter the Design Manager.

    The Design Manager is where you can make additional edits and style declarations to the design and CSS class implementation. Most of your text and border effects should be done here and not in the PSD. Additionally, you will be able to customize your animation/jQuery functions from this screen as well. Again, for more details on, check out Site Grinder TV.

    For this tutorial, we will not be creating any real CSS styles with attributes. Instead, we are simply adding a class name to a few tags on the site for Pagelime to use. In the Design Manager, navigate to the “border and background styles” dropdown menu. Using the dropdowns next to the elements, add a new style called “editable” with no additional attributes. Click Apply. After applying the style once, it will be accessible in all the other drop-down menus. Select each other region you would like to be editable by Pagelime and then apply to those elements.

    When the site gets implemented into Pagelime in step 13, we’ll define this css class “editable” as the signal class for Pagelime to make regions user editable. Essentially this tag can be called anything you want it to be, as long as it’s unique, however, we suggest you make it something understandable for easy reference.

    Step 5 Once you’ve set all the classes, click back to Photoshop to see the main SiteGrinder 3 engine module.

    In the deploy area, select the newly built pages. Once you’ve checked the pages to deploy, select the site you want to deploy out to in the lower drop-down called “Deploy To.” You may have to create a new site if you do not have any previous sites. Just give it a name, select local only and click OK.

    This “site” simply refers to how the directory on your local computer will be referenced. Don’t worry too much about what it’s called; you just need to be able to identify it later. The name also cannot have any spaces or special characters.

    Step 6 Select “Deploy Design” to save the markup to a local folder on your computer.

    At this point, the site HTML and markup is already compete, this was accomplished in the “Build” stage, Sitegrinder is now just recompiling and saving those .html and related files to your compute in the directory you selected.

    Step 7 Once you’ve set all the classes, click back to Photoshop to see the main SiteGrinder 3 engine module.

    It looks similar to the Design Manager and will have a local address. You need to define which page will be the default loading page on your site, or the “Index”. Check the “index” box next to the desired page, this will cause SiteGrinder to rename that file to “index.html” upon FTP upload to your server.

    Step 8 Under the “Upload” tab, choose “Connection Settings,” and input your ftp/server credentials

    Once this is all inputted, click OK.

    The server address will most likely start with ftp. When setting the Remote Path, it is highly recommended you use the “Browse” feature for the most accurate directory. The “HTTP Address” will be where SiteGrinder will direct you after upload, so it’s probably best to choose the domain or sub directory where you are uploading.

    Step 9 To push the site to the server, go back to the Upload Menu and choose Upload Everything

    On the first upload, either upload option will do the exact same thing, since there are essentially no files on your server. However, just to be safe, when uploading a new deploy for the first time, I always choose Upload Everything to make sure I’ll get a fresh clean copy on my server.

    >

    Step 10 After the upload is complete, click “open site”.

    This will display your page (or whatever you entered as your HTTP Address). You can see that your page is now live. That’s about it for the SiteGrinder portion, next we’ll move on to implementing the site into Pagelime for easy editing.

    Step 11 Login to Pagelime.

    If you are new to Pagelime, you can visit the Sign Up Page, to get a free account to use with SiteGrinder. Pagelime is a great simple CMS that will cut implementation time dramatically and give your client something they can understand.

    Pro Tip:

    When you sign-up for a PRO or Business Account, in addition to all the standard Pagelime features and plugins, you’ll have the ability to completely customize and brand the backend. Pagelime gives you the ability to entirely white-label the CMS from URL to logo and color scheme. This will allow you to offer your client a consistent and branded experience while working with you and on their site. It will also allow you to markup the service and add cash-flow to your revenue stream. You can setup clients on automatic recurring billing cycles for using your CMS aka Pagelime right from within the Pagelime Account/Billing Manager.

    Step 12 Click, “Add New Site”, enter the full directory address, including the the index.html, setup the FTP settings, and choose a site title.

    If you need any further assistance on this page, Pagelime has some extremely helpful tool-tips that show up on the right hand side when each field is selected. Use these as reference for what to enter and how to format it. You can also test your connection at the bottom of the page. It’s recommended that you use the “Browse” feature when selecting the file path as that will ensure the most accuracy. Also, make sure to change your Advanced settings (next step) before clicking “Save Site Settings”

    Step 13 Under the “Advanced” tab, make sure to change the editable CSS class name to “editable”

    This can be changed to whatever special class you named in the SiteGrinder Design Manager in step 4.

    This is how Pagelime will identify which regions should be editable. If this class name does not match the class you added in step 4, or if the classes you added in step 4 are inconsistent with this “Editable CSS Class Name” across your pages, you will not be able to edit those regions within the Pagelime Site Editor. However, if you forgot to add the class to a region, don’t freak out, and if you’re not afraid of a little HTML code, than you don’t even have to go back to step 4. You don’t even have to use an external editor like Dreamweaver either. Instead, when you’ve selected a page to edit in the Pagelime Site Editor, use the right drop-down and select edit code. This will open up a rich, highlighted syntax view of your sites raw code that will allow you to manually add CSS classes. For more details on this process, check out a tutorial about it, called Manually adding CSS Classes through the Pagelime Site Editor

    If the SiteGrinder 3 Engine is not already open, this will launch the SiteGrinder 3 engine. After the Engine launches, SiteGrinder will generate a report on any errors or warnings it may find in the template. Review the errors and fix any serious errors that apply* (you can also choose to ignore them, the site should still build). After you have resolved the errors, continue to the Build and Deploy page. Here, you should check off the pages you want to have built by SiteGrinder. In this tutorial, we will only be building out the home page. After the desired pages are selected, click “Build”.

    *Note: If you are using the SiteGrinder 3 test template with a demo or basic version of SiteGrinder 3, it’s possible that you might encounter a report with 2 “serious” errors. Look through the errors carefully. It’s most likely that the errors are being thrown because you are referencing tags such as -$ or -blog within the template that require additional plugins. The Commerce Add On for -$ and The Control Add On for -blog. If that is the case, you can continue anyway. In this tutorial, we are not building out the “store” or “blog” page, so these errors are irrelevant.

    Step 14 Click Save Site Settings

    Saving Site Settings will confirm and save the FTP and Pagelime settings you just entered. This will also cause Pagelime to Reload. After it’s done, you can navigate back to the Site Dashboard.

    Step 15 If you are editing images, make sure to activate the Image Gallery Plugin under Site Features on your site dashboard.

    This plugin will allow you to upload and manage images through Pagelime. It is required that you have this plugin updated to manage ANY images on a Pagelime enabled site. If you want to get fancy with your images, we also recommend turning on Image Optimization which will allow you to control image quality and add photo effects from within Pagelime.

    From the Site Features menu, you can also activate a number of additional features such as Page Templates and Content History. Content History can be extremely helpful when making continuous edits to a site as it will log all of your previous edits from a session and will allow you to roll-back content if an error or incorrect change is made.

    Step 16 You’re almost done! You are ready to rock and roll with edits.

    Just click on an image or text, either the main area or the little black edit bubble. This will open up either a WYSIWYG editor (which also has an HTML view) or the ZoomCrop browser for images. From here, you simply edit the content, save, and then when your done with all changes on a page, click the publish button on under “Page Actions.” This will push all of your edits live to your public site.

    To pass this off to your client, you would create a new user under your Account Manager and give them permissions to the site. That user would then log in via either your custom URL or cms.pagelime.com – it’s that simple. The actual editing is covered in the video below, or we also have a shorter 5 minute video that gets straight to editing if you need a refresher.

    Note, that when editing the images inside these DIVs, you need to hover over the center of the image and look for the little image icon. Click this area to access the ZoomCrop browser. Remember, the Image Gallery Plugin must be enabled. If you click the DIV tag, you activate the image in a WYSIWYG editor which, although can work, is not what we want and will not give us the best editing control for our images. This situation is created because SiteGrinder created a DIV around the image. If you would like to fix this manually, you can edit the code and remove the editable tag from the surrounding div and instead move the class to the IMG tag, again, this can be done all within Pagelime easily, see our blog post/tutorial about it called Manually adding CSS Classes through the Pagelime Site Editor

    Step 17 Edit your content, Publish as normal and never deal with minor Client Content edits ever again!

    To publish, click the “Page Actions” drop-down and click publish, then, BAM!, you’re done!

    Conclusion

    Thanks for following along in this tutorial. If you have any questions, comments, troubleshooting, wishes, hopes or dreams about Pagelime, you can visit the PageLime forums, or thedocumentation wiki.


  • Permalink for 'Quick Tip: “Popular Posts By Comment Count” SQL Query in WordPress'

    Quick Tip: “Popular Posts By Comment Count” SQL Query in WordPress

    Posted: May 2nd, 2010, 3:56pm MDT by Jeffrey Way

    You might have noticed that the Tuts+ sites have a section on the home page where we list the most popular posts of the month, according to comment count. While there are numerous plugins available, it’s always best to write the code yourself if you can. Too much abstraction is never a good thing! Luckily, once we learn how to query WordPress’ database, tasks like this become a cinch!


    Subscribe to our YouTube page to watch all of the video tutorials!

    Prefer to watch this video on Screenr?

    The SQL Query

    To query WordPress’ database, we can use the $wpdb->get_results() method. As the parameter, we simply pass a SQL query. In this particular example, let’s say that we only want to display a list of popular posts within our sidebar. We can use the following query:

    $pop = $wpdb->get_results("SELECT id, post_title, comment_count FROM {$wpdb->prefix}posts WHERE post_type='post' ORDER BY comment_count DESC LIMIT 10");
    

    id, post_title, and comment_count our columns within the database.

    MySQL DB

    Because WordPress allows you to set a custom prefix for your database tables, we need to fetch that prefix dynamically, by using {wpdb->prefix}posts. In this case, that results in “wp_posts”. Next, we must ensure that we only display posts, and not anything else, such as attachments or pages. Finally, we ORDER BY comment_count. That’s the point of all this right? Display the most commented postings?

    Now that our SQL query has been executed, we can simply use a foreach statement to filter through the results, and display them on the page.

    $pop = $wpdb->get_results("SELECT id, post_title, comment_count FROM {$wpdb->prefix}posts WHERE post_type='post' ORDER BY comment_count DESC LIMIT 10");
    
    foreach($pop as $post) : ?>
    <li> <?php echo $post->post_title; ?> </li>
    <?php endforeach; ?>
    

    Note that the $post variable will have access to any of the columns that we fetched. In our case, we’d have access to:

    • $post->id : The id of the post
    • $post->post_title : The title of the post
    • $post->comment_count : The number of comments for that particular post.

    If you need the permalink, you can either also SELECT from the “guid” column, or you can just use the get_permalink($post->id) method, and pass in the id of the post accordingly.

    Once you’ve learned how to directly interact with the WordPress database, you then have a lot of power at your disposal; this is only the tip of the iceberg!

    One Last Thing

    This tutorial was created to demonstrate how to specifically query WordPress’ tables in the database. Truthfully, as of WordPress 2.9, you can achieve this exact effect by using query_posts(), and passing orderby=’comment_count‘. But remember, it all boils down to the same thing: passing a SQL query to the database.

    Any questions? Thanks for viewing or reading!


  • Permalink for 'Free Copies of “jQuery: Novice to Ninja”'

    Free Copies of “jQuery: Novice to Ninja”

    Posted: May 1st, 2010, 3:20pm MDT by Jeffrey Way

    A few weeks ago, the amazing guys at SitePoint sent me a handful of copies of their latest book, “jQuery: Novice to Ninja,” to give away to our community. As their first book to focus specifically on jQuery, the final product is a resounding success, covering the absolute basics up to building your own plugins. The writers, Earle Castledine and Craig Sharkie have really done a great job simplifying as much as possible so that even the absolute beginners can immediately dive into working in jQuery.

    Update: Winners Announced

    A big congratulations goes out to @iBlend @cgfaulkner @angbown @theswineharts. If you haven’t already, please email me at nettuts@tutsplus.com to claim your prize. Thanks for entering everyone!

    jQuery Novice to Ninja How to Win

    We’re going to make this one as simple as possible. Rather than leaving a comment to enter, all you have to do is follow us on Twitter, and tweet stating that you want the book. I’ll then sort through the first thirty tweets, and choose a handful of winners! That’s it. Please note that these are hard-copies. The winners will be announced on Sunday, May 2nd, US time.

    Novice to Ninja


  • Permalink for 'We Need an Awesome Weekly Writer'

    We Need an Awesome Weekly Writer

    Posted: May 1st, 2010, 2:05pm MDT by Jeffrey Way

    It’s that time again; I’m in need of a kick-ass – and consistent – author to help out on Nettuts once per week. Your duties will be to write an in-depth tutorial or article each week on anything ranging from PHP to JavaScript to CSS. Your pay will begin at $200 per article, resulting in roughly $800 per month. However, if you do a great job, you’ll also be invited to write a Premium tutorial every month, which would increase your pay to around $1100 – $1200 each month. Not bad for a once a week gig!

    When I make these kinds of posts, I receive far too many one-sentence emails that don’t help. This time, to apply (and note that not many people do), I need you to email me with a few sentences about yourself, and a link to something that you’ve written on the web. It can be a link to your blog, or even a tutorial you’ve written for another web development tutorial site. If this is not included, your email will be deleted. Please email nettuts@tutsplus.com with this information. Thanks, everyone!


  • Permalink for 'Free “Aurelius” Website Template'

    Free “Aurelius” Website Template

    Posted: April 30th, 2010, 10:33am MDT by Jeffrey Way

    We have a free static website template to give away today, built by Matt Corner. This theme is called “Aurelius,” and hosts a variety of nice features. If you happen to be in need of a starting point for your next website, feel free to use this one how you wish!

    Home Page Portfolio Page Contact Page


  • Permalink for 'How jQuery Beginners can Test and Improve their Code'

    How jQuery Beginners can Test and Improve their Code

    Posted: April 29th, 2010, 10:38am MDT by Siddharth

    jQuery’s arrival has made the process writing JavaScript laughably easy. But, you’ll notice that making small changes to your code improves the readability and/or performance significantly. Here are some tips to get you on your way to optimizing your code.

    Setting up the Platform

    We’ll need a solid platform to conduct our tests. Here is the HTML markup for the test page in which we’ll be running all our tests:

     
    <!DOCTYPE html>
    <html lang="en-GB">
    
    <head>
    <title>Testing out performance enhancements - Siddharth/NetTuts+</title>
    </head>
    
    <body>
    
    <div id="container">
    <div class="block">
    <p id="first">
      Some text here
    </p>
    <ul id="someList">
      <li class="item"></li>
      <li class="item selected" id="mainItem">Oh, hello there!</li>
      <li class="item"></li>
      <li class="item"></li>
    </ul>
    </div>
    </div>
    
    <script  src=" [ajax.googleapis.com] <script>
      console.profile() ;
    
      // Our code here
    
      console.profileEnd();
    </script>
    
    </body>
    </html>
    

    There’s nothing special here; just a bunch of elements that we can target and test. We’re using Firebug to log the times here. profile begins the process, and profileEnd stops it, and makes a note of how much time the task took. I typically use Firebug’s main profile method, but for our devious purposes, this will be sufficient.

    1. Detect if an Element Exists

    As is often the case, you’ll be serving a single script file containing your code to all the pages in your site. This is usually code which often performs actions on nonexistent elements in the current page. Though jQuery handles problems such as these quite gracefully, this doesn’t mean that you can just ignore any problems. In fact, if you call jQuery’s methods on an empty collection, they won’t be run.

    As a best practice, only run code which is applicable to the currently loaded page, instead of bunching all of your code into a single document ready check, and serving it to the client.

    Let’s look at the first scenario:

    console.profile();
    var ele = $("#somethingThatisNotHere");
    ele.text("Some text").slideUp(300).addClass("editing");
    $("#mainItem");
    console.profileEnd();
    
    //Some more awesome, ground shattering code here ._.
    

    Firebug’s spits out the following result:

    Tutorial Image

    This time, let’s check whether the element we’re looking to perform actions on exists before doing so.

    console.profile() ;
    var ele = $("#somethingThatisNotHere");
    if ( ele[0] ) {
       ele.text("Some text").slideUp(300).addClass("editing");
    }
    $("#mainItem");
    console.profileEnd();
    
    //Some more awesome, ground shattering code here ._.
    

    And the results:

    Tutorial Image

    See? It’s pretty simple, to the point and gets the job done. Note that you don’t need to check whether an element exists for every single bit of your code. You’ll notice in your page that certain bigger parts will generally benefit from this method. Use your judgment here.

    2. Use Selectors Effectively

    Try to use an ID instead of passing a class.

    This is a big topic so I’ll keep it as concise as possible. First up, when passing in selectors, try to use an ID instead of passing a class. jQuery directly uses the native getElementById method to find an element by ID while in the case of a class it has to do some internal voodoo to acquire it, at least in older browsers.

    We’ll look at the different selectors you can use to target the 2nd li element. We’ll test each one of them and how they modify the performance.

    The first method, the easiest, will be to plainly target it using the selected class. Let’s see what Firebug’s profiler returns.

    console.profile() ;
    
    $(".selected");
    
    console.profileEnd();
    
    Tutorial Image

    And the result: 0.308ms. Next, we prefix a tag name to narrow it down. This way, we can narrow down our search by first targeting only the selected DOM elements, with document.getElementsByTagName.

    console.profile() ;
    
    $("li.selected");
    
     console.profileEnd();
    
    Tutorial Image

    And the result: 0.291ms. Roughly 0.02 ms shaved off. This is negligible due to the fact that we’re testing in Firefox; however, it should be noted that this performance boost will be notably higher in older browsers, like Internet Explorer 6.

    Next, we descend from the ID of the parent element.

    console.profile() ;
    
    $("#someList .selected");
    
    console.profileEnd();
    
    Tutorial Image

    And the result: 0.283ms. Let’s try to be a bit more specific. We also specify the type of element in addition to the ancestor’s ID.

    console.profile() ;
    
    $("#someList li.selected");
    
    console.profileEnd();
    
    Tutorial Image

    And the result: 0.275 ms. Another small part shaved off. Finally, let’s just target it directly using an ID to.

    console.profile() ;
    
    $("#mainItem");
    
    console.profileEnd();
    
    Tutorial Image

    And the result: 0.165ms. Impressive! This really shows you how much faster it is to run native methods Note that while modern browsers can take advantage of things like getElementsByClassName, older browsers cannot – resulting in much slower performance. Always consider this when coding.

    3. Account for Sizzle’s Parsing Model and Adding Scopes

    Sizzle, the selector engine that jQuery uses – built by John Resig – parses selectors from right to left, which raises a few unexpected chains of parsing.

    Consider this selector:

    $("#someList .selected");
    

    When Sizzle encounters such a selector, it first builds the DOM structure, using the selector as the root, discards items that don’t have the required class, and, for every element with the class, it checks whether its parent has an ID of someList.

    To account for this, make sure that the right-most part of your selector is as specific as possible. For example, by specifying li.selected instead of .selected, you cut down the number of nodes it has to check. This is the reason why performance jumped in the previous section. By adding additional constraints, you effectively reduce the number of nodes it has to check.

    To better fine-tune the way elements are obtained, you should look into adding a context for each request.

    var someList = $('#someList')[0];
    $(".selected", someList);
    

    By adding a context, the way the element is searched changes completely. Now, the element providing the context – someList in our case – is first searched for, and once it has been obtained, child elements that don’t have the requisite class are removed.

    Note that it’s generally a best practice to pass a DOM element as the context of your jQuery selector. Using a context is most helpful when it is stored in some variable. Otherwise, you can streamline the process and use find() — which jQuery, itself, does under the hood.

    $('#someList').find('.selected');
    

    I’d like to say the performance increase will be clearly defined, but I can’t. I’ve run tests on a number of browsers and whether the scoped approach performance beats that of the vanilla version depends on a number of factors including whether the browser supports specific methods.

    4. Avoid Query Waste

    When you’re browsing through someone else’s code, you’ll often find.

    // Other code
    
    $(element).doSomething();
    
    // More code
    
    $(element).doSomethingElse();
    
    // Even more code
    
    $(element).doMoreofSomethingElse();
    

    Please don’t do this. Ever. The developer is instantiating this “element” over and over. This is wasteful.

    Let’s see how much time such horrendous code takes to run.

     console.profile() ;
    
     $("#mainItem").hide();
     $("#mainItem").val("Hello");
     $("#mainItem").html("Oh, hey there!");
     $("#mainItem").show();
    
     console.profileEnd();
    
    Tutorial Image

    If the code is structured like above, one after the other, you can use chaining like so:

    console.profile();
    
    $("#mainItem").hide().val("Hello").html("Oh, hey there!").show();
    
    console.profileEnd();
    

    By chaining, the element initially passed in is acquired and a reference is passed along to each subsequent calls cutting down on execution time. Otherwise a new jQuery object is created each time.

    But if unlike above, the sections referencing the element aren’t concurrent, you’ll have to cache the element and then do all the same operations as before.

    console.profile() ;
    
    var elem = $("#mainItem");
    
    elem.hide();
    
    //Some code
    elem.val("Hello");
    
    //More code
    elem.html("Oh, hey there!");
    
    //Even more code
    elem.show();
    
    console.profileEnd();
    
    Tutorial Image

    As is evident from the results, caching or chaining considerably decreases the execution time.

    5. Perform DOM Manipulation more Intelligently

    Suggesting non-traditional DOM manipulation in my earlier article drew a little flak from a few people before being shown that the performance boost really is worth it. We’ll now test it ourselves.

    For the test, we’ll create 50 li elements, and append them to the current list, and determine how much time it takes.

    We’ll review the normal, inefficient method first. We’re essentially appending the element to the list every time the loop runs.

    console.profile() ;
    
    var list = $("#someList");
    
    for (var i=0; i<50; i++)
    {
       list.append('<li>Item #' + i + '</li>');
    }
    
    console.profileEnd();
    

    Let’s see how it did, shall we?

    Tutorial Image

    Now, we’ll follow a slightly different path. We’ll essentially append the required HTML string to a variable firs, and then only reflow the DOM one time.

    console.profile() ;
    
    var list = $("#someList");
    var items = "";
    
    for (var i=0; i<50; i++){
         items += '<li>Item #' + i + '</li>';
     }
    
    list.append(items);
    
    console.profileEnd();
    
    Tutorial Image

    As expected, the time taken has decreased significantly.

    Tutorial Image

    If you’re using jQuery as a replacement for getElementById, but never utilize any of its provided methods, then you’re doing it wrong.

    If you’d like to take things further, ask yourself if you really need to create a new jQuery object all for the purpose of targeting some element? If you’re using jQuery as a replacement for document.getElementById, but never utilize any of its provided methods, then you’re doing it wrong. In this case, we can get away with raw JS.

    console.profile() ;
    
    var list = document.getElementById('someList');
    var items = '';
    
    for (var i=0; i<50; i++){
         items += '<li>Item #' + i + '</li>';
     }
    
    list.innerHTML = items;
    
    console.profileEnd();
    
    A Few Caveats

    You’ll notice that the difference in execution time between the optimized and un optimized code is in the fraction of a millisecond range. This is because our test document is very small with an impossibly small number of nodes. Once you start working with production level sites with a few thousand nodes in it, it’ll really add up.

    Also note that in most of these tests, I’m simply accessing the elements. When you start applying proper functions to them, the delta in the execution time will increase.

    I also do understand that this isn’t the most scientific of methods to test performance, however, to gain a general feel for how much each of these changes affect the performance, I think this is suitably sufficient.

    Ffinally, in most of your web apps, the connection speed and response time of the web server in question is going to play a bigger role in the performance of your app more than the tweaks in the code you’ll make. Nevertheless, this is still important information and will help you down the line when you’re trying to eke out as much performance as possible from your code.

    That’s all Folks

    And we’re done. A few points to keep in mind when you’re trying to optimize your code; this is not the all encompassing list of tweaks, of course, and the points may not necessarily apply to all situations. Either way, I’ll be watching the comments closely to read what you have to say on the topic. Any mistake you see here? Drop me a line below.

    Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!


  • Permalink for 'Working with Advanced 3D CSS: New Premium Screencast'

    Working with Advanced 3D CSS: New Premium Screencast

    Posted: April 28th, 2010, 2:36pm MDT by Jeffrey Way

    CSS is capable of so much more than browsers can currently handle, namely when it comes to working in 3D spaces. In this week’s premium video tutorial, I’m going to teach you how to work with CSS transitions, animations, and specifically how to work with Webkit’s CSS 3D capabilities. Help give back to Nettuts+ by becoming a premium member!

    Preview Screenshot You’ll Learn About:
    • CSS3 radial gradients
    • HTML5 mark-up
    • Using the Webkit nightlies
    • CSS perspective
    • Defining keyframes for animations
    • preserve-3d
    Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Join today!


  • Permalink for 'Introducing Moneybookers Payment & Pre-paid Premium Memberships'

    Introducing Moneybookers Payment & Pre-paid Premium Memberships

    Posted: April 28th, 2010, 2:35pm MDT by Aaron Osteraas

    Always wanted to go Premium but don’t have a PayPal account, or a credit card linked to your PayPal account? Well, we have good news! Thanks to the stellar work of our developers, we can now accept payments from a Moneybookers account. We hope this will open Tuts+ Premium Memberships to a lot more people.

    Even more good news: if you don’t have a credit card you can now purchase a pre-paid Premium membership. Pre-paid memberships don’t require you to have a credit card linked to your PayPal account to become a Premium member. Your pre-paid options are:

    • $22 – Three Month Membership
    • $40 – Six Month Membership
    • $78 – One Year Membership
    • This news comes at a good time, because we’re one day away from launching CG Premium (the Premium program for Cgtuts+) and after that, Active Premium (the Premium program for Activetuts+).

      Become a Premium member and gain instant access to 279 exclusive tutorials and over 700 source files. You’ll get all the content for Psd Premium, Net Premium, Audio Premium, Ae Premium and, very soon, Active Premium and CG Premium.


  • Permalink for 'How to Build a Simple Twitter Widget with ASP.NET'

    How to Build a Simple Twitter Widget with ASP.NET

    Posted: April 28th, 2010, 11:00am MDT by Charlie Somerville

    In this tutorial, I’ll be walking you through how to a write a Twitter widget for ASP.NET in the form of a reusable server control complete with nice things such as automatically turning URLs into links, and caching to speed up page load times.

    Step 1 Getting Started

    To follow this tutorial, all you need is Visual Studio (You can use MonoDevelop if you’re not on Windows, although there’s no guarantees there.) If you don’t want to fork over cash for the full version of Visual Studio, you can grab the free Express Edition.

    You’ll also need knowledge of C# 3.0, as this tutorial makes use of some of the newer features of the language, such as lambda expressions and the var keyword.

    Step 2 Creating the Control

    ASP.NET includes a handy feature known as Server Controls. These are custom tags that aim to help developers structure their code. When a page using a server control is requested, the ASP.NET runtime executes the Render() method and includes the output in the final page.

    Once you’ve created a new Web Application in Visual Studio, right click in the Solution Explorer and add a new item to the solution. Select ASP.NET Server Control, and give it a name. Here, I’ve called it Twidget.cs, but you’re welcome to call it whatever you like. Paste the following code in, and don’t worry if it all looks a bit foreign – I’ll explain it all shortly.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.Script.Serialization;
    using System.Net;
    
    namespace WebApplication1
    {
        public class Twidget : Control
        {
            public string Account { get; set; }
            public int Tweets { get; set; }
    
            protected override void Render(HtmlTextWriter writer)
            {
                writer.Write("<ul>");
    
                foreach (var t in GetTweets().Take(Tweets))
                    writer.Write("<li>{0}</li>", [HttpUtility.HtmlEncode(t));] 
                writer.Write("</ul>");
            }
    
            public List<string> GetTweets()
            {
                var ls = new List<string>();
    
                var jss = new JavaScriptSerializer();
                var d = jss.Deserialize<List<Dictionary<string, object>>>(
                    new WebClient()
                    .DownloadString("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + Account)
                    );
    
                foreach (var x in d)
                    ls.Add((string)x["text"]);
    
                return ls;
            }
        }
    }
    

    This is about as basic as you can get for a Twitter widget. Here’s how it works:

    When a user requests a page with this control on it, the Render() method gets executed with a HtmlTextWriter passed as a parameter. It writes out the <ul> tag, and then enters a loop which prints out each tweet as a list item. The magic here happens in the GetTweets() method. Notice how we are using the Take() extension method to make sure we only print the amount of tweets that we’re asked to.

    Once execution passes to the GetTweets() method, we setup a List>string< to hold our tweets and a JavaScriptSerializer to parse the JSON from the Twitter API servers. The statement on lines 31 – 34 (split up for readability) retrives the user timeline in JSON format, then deserializes into .NET types we can work with. On line 36, we loop through all the tweets and add them one by one to the tweet list. We have to manually cast x["text"] to a string because we deserialized it as an object. We had to do this, because the JSON returned by the Twitter API uses a smorgasboard of different types – which is fine for JavaScript, but a little tricky with C#.

    Step 3 Using the Control

    Now we have the code for our Twitter widget; let’s put it to use! Open your Default.aspx page (or whichever page you want to use this in) and put the following code immediately after the <%@ Page %> directive:

    <%@ Register TagPrefix="widgets" Namespace="WebApplication1" Assembly="WebApplication1" %>
    

    Feel free to change the TagPrefix to whatever you like, but make sure that the Namespace attribute is correctly set to whatever namespace you placed the widget code in, and ensure that the Assembly attribute is set to the name of your web application (in our case, WebApplication1).

    Once you’ve registered the proper tag prefix (and you’ll need to do this for every page you want to use the control on), you can start using it. Paste the following code somewhere into your page, and once again, feel free to change the attributes to whatever you want:

    <widgets:Twidget runat="server" Account="twitter" Tweets="10" />
    

    If you’ve done everything properly, you should see a page similar to this when you run your web application:

    Step 4 Some Fancy Stuff…

    You’ve got to admit, the control we’ve got at the moment is pretty rudimentary. It doesn’t have to be though, so let’s spiffy it up a little by turning URLs into nice, clickable links for your visitors.

    Find the foreach loop in the Render() method and scrap it completely. Replace it with this:

    // you'll need to add this using directive to the top of the file:
    using System.Text.RegularExpressions;
    
    foreach (var t in GetTweets().Take(Tweets))
    {
        string s = Regex.Replace(
            [HttpUtility.HtmlEncode(t),]         @"[a-z]+://[^\s]+",
            x => "<a href='" + x.Value.Replace("'", "&quot;") + "'>" + x.Value + "</a>",
            RegexOptions.Compiled | RegexOptions.IgnoreCase
            );
    
        writer.Write("<li>{0}</li>", s);
    }
    

    It’s all pretty much the same code, except for the humongous call to Regex.Replace() on line 6. I’ll explain what this does.

    The first parameter is the input, or the string that the Regex works on. In this case, it’s just the tweet text after being passed through [HttpUtility.HtmlEncode()] so we don’t fall victim to a vicious XSS attack. The input is then matched against the second parameter which is a regular expression designed to match a URL.

    The third parameter is where it gets a little involved. This is a lambda expression, a feature new to C# 3. It’s basically a very short way of writing a method like this:

    public static string SomeFunction(Match x)
    {
        return "<a href='" + x.Value.Replace("'", "&quot;") + "'>" + x.Value + "</a>";
    }
    

    All it does is wrap the URL with an <a> tag, of which all quotation marks in the URL are replace with the HTML entity &quot;, which helps prevent XSS attacks. The fourth and final parameter is just an ORed together pair of flags adjusting the way our regex behaves.

    The output of the control after making this adjustment is somewhat similar to the screenshot below.

    Step 5 Caching

    There’s a big problem with the code I’ve given to you above, and that is that it doesn’t cache the response from the Twitter API. This means that every time someone loads your page, the server has to make a request to the Twitter API and wait for a response. This can slow down your page load time dramatically and can also leave you even more vulnerable to a Denial of Service attack. Thankfully, we can work around all this by implementing a cache.

    Although the basic structure of the control’s code remains after implementing caching, there’s too many small changes to list, so I’ll give you the full source and then – as usual – explain how it works.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.Script.Serialization;
    using System.Net;
    using System.Threading;
    using System.Text.RegularExpressions;
    
    namespace WebApplication1
    {
        public class Twidget : Control
        {
            public string Account { get; set; }
            public int Tweets { get; set; }
            public int CacheTTL { get; set; }
    
            static Dictionary<string, CachedData<List<string>>> Cache = new Dictionary<string, CachedData<List<string>>>();
    
            protected override void Render(HtmlTextWriter writer)
            {
                writer.Write("<ul>");
    
                foreach (var t in GetTweets().Take(Tweets))
                {
                    string s = Regex.Replace(
                        [HttpUtility.HtmlEncode(t),]                     @"[a-z]+://[^\s]+",
                        x => "<a href='" + x.Value.Replace("'", """) + "'>" + x.Value + "</a>",
                        RegexOptions.Compiled | RegexOptions.IgnoreCase
                        );
    
                    writer.Write("<li>{0}</li>", s);
                }
    
                writer.Write("</ul>");
            }
    
            public List<string> GetTweets()
            {
                if (!Cache.Keys.Contains(Account)
                    || (DateTime.Now - Cache[Account].Time).TotalSeconds > CacheTTL
                    )
                    new Thread(Update).Start(Account);
    
                if (!Cache.Keys.Contains(Account))
                    return new List<string>();
    
                return Cache[Account].Data;
            }
    
            public static void Update(object acc)
            {
                try
                {
                    string Account = (string)acc;
    
                    var ls = new List<string>();
    
                    var jss = new JavaScriptSerializer();
                    var d = jss.Deserialize<List<Dictionary<string, object>>>(
                        new WebClient()
                        .DownloadString("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + Account)
                        );
    
                    foreach (var x in d)
                        ls.Add((string)x["text"]);
    
                    if (!Cache.Keys.Contains(Account))
                        Cache.Add(Account, new CachedData<List<string>>());
    
                    Cache[Account].Data = ls;
                }
                catch (Exception) { }
            }
        }
    
        class CachedData<T>
        {
            public DateTime Time { get; private set; }
    
            T data;
            public T Data {
                get {
                    return data;
                }
                set
                {
                    Time = DateTime.Now;
                    data = value;
                }
            }
        }
    }
    

    As you can see, the Render() method remains unchanged, but there’s some pretty drastic changes everywhere else. We’ve changed the GetTweets() method, added a new property (CacheTTL), added a private static field (Cache), and there’s even a whole new class – CachedData.

    The GetTweets() method is no longer responsible for talking to the API. Instead, it just returns the data already sitting in the cache. If it detects that the requested Twitter account hasn’t been cached yet, or is out of date (you can specify how long it takes for the cache to expire in the CacheTTL attribute of the control), it will spawn a seperate thread to asynchronously update the tweet cache. Note that the entire body of the Update() method is enclosed in a try/catch block, as although an exception in the Page thread just displays an error message to the user, if an exception occurs in another thread, it will unwind all the way back up the stack and eventually crash the entire worker process responsible for serving your web application.

    The tweet cache is implemented as a Dictionary<string, CachedData<string>>, where the username of the twitter account being cached is the key, and an instance of the CachedData<T> class is the value. The CachedData<T> class is a generic class and can therefore be used with any type (although in our case, we’re only using it to cache a string.) It has two public properties, Data, which uses the data field behind the scenes, and Time, which is updated to the current time whenever the Data property is set.

    You can use the following code in your page to use this caching version of the widget. Note that the new CacheTTL attribute sets the expiry (in seconds) of the tweet cache.

    <widgets:Twidget runat="server" Account="twitter" Tweets="10" CacheTTL="600" />
    
    Conclusion

    I hope this tutorial has not only taught you how to make a Twitter widget, but has given you an insight into how server controls work as well as some best practices when ‘mashing up’ data from external sources. I realise that the browser output of this control isn’t exactly the prettiest, but I felt that styling it and making it look pretty was outside the scope of the article and has therefore been left as an exercise for the reader. Thanks for reading! Feel free to ask any questions that you might have in the comments section below.


  • Permalink for 'Win FusionCharts Licenses worth $5,000'

    Win FusionCharts Licenses worth $5,000

    Posted: April 28th, 2010, 11:00am MDT by Jeffrey Way


    How would you like your web reports to look wow with animated Flash charts? You would love it, wouldn’t you? We have just the right thing for you.

    FusionCharts is generously giving away seven Professional Licenses for its flagship product, FusionCharts v3 (worth $499 each), to our readers. Using it, you can create great-looking animated and interactive Flash charts for your web applications and websites. You might have come across it in one of the numerous web applications it is being used in: LinkedIn Polls, AWeber, Vertical Response, Wufoo, PollDaddy and AddThis.

    Winners Announced!

    Congratulations to the following winners:

    • Prince
    • Matthew
    • Chad
    • Mike Nguyen
    • Jason Schmidt
    • Mark Dijkstra
    • Nelsaidi

    Please email nettutsblog@gmail.com to claim your licenses. Congrats again!

    How to Participate?

    Just leave a comment below telling us:

    • Where do you need charting?
    • What is the single biggest challenge you face with charting?
    • What do you love most about FusionCharts? In case you haven’t heard of them before, check out the online demos
    Flash Chart Choosing the Winners

    We and the FusionCharts team will select the seven users with the most insightful comments as the winners. The results will be announced on this page on May 7th, 2010 (Eastern Standard Time).

    Wait a Second…

    If you did a little math, you might have realized that seven licenses worth $499 each doesn’t equal $5,000, as we mentioned in the title. So where’s the rest?

    Well, there comes in the big one: If the number of comments exceeds 500, then we will select one winner for the FusionCharts Professional Bundle. The bundle is worth $1,499, and contains a license of each of their other data visualization components as well:

    • FusionWidgets – for gauges and data streaming charts
    • FusionMaps – for interactive data-driven maps
    • PowerCharts – for super-powerful specialized charts for specific domains

    So what are you waiting for? Get typing now. And tell your friends too.

  • Permalink for '9 Useful PHP Functions and Features You Need to Know'

    9 Useful PHP Functions and Features You Need to Know

    Posted: April 27th, 2010, 9:28am MDT by Burak Guzel

    Even after using PHP for years, we stumble upon functions and features that we did not know about. Some of these can be very useful, yet underused. Not all of us have read the manual and the function reference from cover to cover!

    1. Functions with Arbitrary Number of Arguments

    You may already know that PHP allows you to define functions with optional arguments. But there is also a method for allowing completely arbitrary number of function arguments.

    First, here is an example with just optional arguments:

    // function with 2 optional arguments
    function foo($arg1 = '', $arg2 = '') {
    
    	echo "arg1: $arg1\n";
    	echo "arg2: $arg2\n";
    
    }
    
    foo('hello','world');
    /* prints:
    arg1: hello
    arg2: world
    */
    
    foo();
    /* prints:
    arg1:
    arg2:
    */
    

    Now, let’s see how we can build a function that accepts any number of arguments. This time we are going to utilize func_get_args():

    // yes, the argument list can be empty
    function foo() {
    
    	// returns an array of all passed arguments
    	$args = func_get_args();
    
    	foreach ($args as $k => $v) {
    		echo "arg".($k+1).": $v\n";
    	}
    
    }
    
    foo();
    /* prints nothing */
    
    foo('hello');
    /* prints
    arg1: hello
    */
    
    foo('hello', 'world', 'again');
    /* prints
    arg1: hello
    arg2: world
    arg3: again
    */
    
    2. Using Glob() to Find Files

    Many PHP functions have long and descriptive names. However it may be hard to tell what a function named glob() does unless you are already familiar with that term from elsewhere.

    Think of it like a more capable version of the scandir() function. It can let you search for files by using patterns.

    // get all php files
    $files = glob('*.php');
    
    print_r($files);
    /* output looks like:
    Array
    (
        [0] => phptest.php
        [1] => pi.php
        [2] => post_output.php
        [3] => test.php
    )
    */
    

    You can fetch multiple file types like this:

    // get all php files AND txt files
    $files = glob('*.{php,txt}', GLOB_BRACE);
    
    print_r($files);
    /* output looks like:
    Array
    (
        [0] => phptest.php
        [1] => pi.php
        [2] => post_output.php
        [3] => test.php
        [4] => log.txt
        [5] => test.txt
    )
    */
    

    Note that the files can actually be returned with a path, depending on your query:

    $files = glob('../images/a*.jpg');
    
    print_r($files);
    /* output looks like:
    Array
    (
        [0] => ../images/apple.jpg
        [1] => ../images/art.jpg
    )
    */
    

    If you want to get the full path to each file, you can just call the realpath() function on the returned values:

    $files = glob('../images/a*.jpg');
    
    // applies the function to each array element
    $files = array_map('realpath',$files);
    
    print_r($files);
    /* output looks like:
    Array
    (
        [0] => C:\wamp\www\images\apple.jpg
        [1] => C:\wamp\www\images\art.jpg
    )
    */
    
    3. Memory Usage Information

    By observing the memory usage of your scripts, you may be able optimize your code better.

    PHP has a garbage collector and a pretty complex memory manager. The amount of memory being used by your script. can go up and down during the execution of a script. To get the current memory usage, we can use the memory_get_usage() function, and to get the highest amount of memory used at any point, we can use the memory_get_peak_usage() function.

    echo "Initial: ".memory_get_usage()." bytes \n";
    /* prints
    Initial: 361400 bytes
    */
    
    // let's use up some memory
    for ($i = 0; $i 
    
    4. CPU Usage Information
    

    For this, we are going to utilize the getrusage() function. Keep in mind that this is not available on Windows platforms.

    print_r(getrusage());
    /* prints
    Array
    (
        [ru_oublock] => 0
        [ru_inblock] => 0
        [ru_msgsnd] => 2
        [ru_msgrcv] => 3
        [ru_maxrss] => 12692
        [ru_ixrss] => 764
        [ru_idrss] => 3864
        [ru_minflt] => 94
        [ru_majflt] => 0
        [ru_nsignals] => 1
        [ru_nvcsw] => 67
        [ru_nivcsw] => 4
        [ru_nswap] => 0
        [ru_utime.tv_usec] => 0
        [ru_utime.tv_sec] => 0
        [ru_stime.tv_usec] => 6269
        [ru_stime.tv_sec] => 0
    )
    
    */
    

    That may look a bit cryptic unless you already have a system administration background. Here is the explanation of each value (you don't need to memorize these):

    • ru_oublock: block output operations
    • ru_inblock: block input operations
    • ru_msgsnd: messages sent
    • ru_msgrcv: messages received
    • ru_maxrss: maximum resident set size
    • ru_ixrss: integral shared memory size
    • ru_idrss: integral unshared data size
    • ru_minflt: page reclaims
    • ru_majflt: page faults
    • ru_nsignals: signals received
    • ru_nvcsw: voluntary context switches
    • ru_nivcsw: involuntary context switches
    • ru_nswap: swaps
    • ru_utime.tv_usec: user time used (microseconds)
    • ru_utime.tv_sec: user time used (seconds)
    • ru_stime.tv_usec: system time used (microseconds)
    • ru_stime.tv_sec: system time used (seconds)

    To see how much CPU power the script has consumed, we need to look at the 'user time' and 'system time' values. The seconds and microseconds portions are provided separately by default. You can divide the microseconds value by 1 million, and add it to the seconds value, to get the total seconds as a decimal number.

    Let's see an example:

    // sleep for 3 seconds (non-busy)
    sleep(3);
    
    $data = getrusage();
    echo "User time: ".
    	($data['ru_utime.tv_sec'] +
    	$data['ru_utime.tv_usec'] / 1000000);
    echo "System time: ".
    	($data['ru_stime.tv_sec'] +
    	$data['ru_stime.tv_usec'] / 1000000);
    
    /* prints
    User time: 0.011552
    System time: 0
    */
    

    Even though the script took about 3 seconds to run, the CPU usage was very very low. Because during the sleep operation, the script actually does not consume CPU resources. There are many other tasks that may take real time, but may not use CPU time, like waiting for disk operations. So as you see, the CPU usage and the actual length of the runtime are not always the same.

    Here is another example:

    // loop 10 million times (busy)
    for($i=0;$i
    

    That took about 1.4 seconds of CPU time, almost all of which was user time, since there were no system calls.

    System Time is the amount of time the CPU spends performing system calls for the kernel on the program's behalf. Here is an example of that:

    $start = microtime(true);
    // keep calling microtime for about 3 seconds
    while(microtime(true) - $start 
    

    Now we have quite a bit of system time usage. This is because the script calls the microtime() function many times, which performs a request through the operating system to fetch the time.

    Also you may notice the numbers do not quite add up to 3 seconds. This is because there were probably other processes on the server as well, and the script was not using 100% CPU for the whole duration of the 3 seconds.

    5. Magic Constants

    PHP provides useful magic constants for fetching the current line number (__LINE__), file path (__FILE__), directory path (__DIR__), function name (__FUNCTION__), class name (__CLASS__), method name (__METHOD__) and namespace (__NAMESPACE__).

    We are not going to cover each one of these in this article, but I will show you a few use cases.

    When including other scripts, it is a good idea to utilize the __FILE__ constant (or also __DIR__ since PHP 5.3):

    // this is relative to the loaded script's path
    // it may cause problems when running scripts from different directories
    require_once('config/database.php');
    
    // this is always relative to this file's path
    // no matter where it was included from
    require_once(dirname(__FILE__) . '/config/database.php');
    

    Using __LINE__ makes debugging easier. You can track down the line numbers:

    // some code
    // ...
    my_debug("some debug message", __LINE__);
    /* prints
    Line 4: some debug message
    */
    
    // some more code
    // ...
    my_debug("another debug message", __LINE__);
    /* prints
    Line 11: another debug message
    */
    
    function my_debug($msg, $line) {
    	echo "Line $line: $msg\n";
    }
    
    6. Generating Unique ID's

    There may be situations where you need to generate a unique string. I have seen many people use the md5() function for this, even though it's not exactly meant for this purpose:

    // generate unique string
    echo md5(time() . mt_rand(1,1000000));
    

    There is actually a PHP function named uniqid() that is meant to be used for this.

    // generate unique string
    echo uniqid();
    /* prints
    4bd67c947233e
    */
    
    // generate another unique string
    echo uniqid();
    /* prints
    4bd67c9472340
    */
    

    You may notice that even though the strings are unique, they seem similar for the first several characters. This is because the generated string is related to the server time. This actually has a nice side effect, as every new generated id comes later in alphabetical order, so they can be sorted.

    To reduce the chances of getting a duplicate, you can pass a prefix, or the second parameter to increase entropy:

    // with prefix
    echo uniqid('foo_');
    /* prints
    foo_4bd67d6cd8b8f
    */
    
    // with more entropy
    echo uniqid('',true);
    /* prints
    4bd67d6cd8b926.12135106
    */
    
    // both
    echo uniqid('bar_',true);
    /* prints
    bar_4bd67da367b650.43684647
    */
    

    This function will generate shorter strings than md5(), which will also save you some space.

    7. Serialization

    Did you ever need to store a complex variable in a database or a text file? You do not have to come up with a fancy solution to convert your arrays or objects into formatted strings, as PHP already has functions for this purpose.

    There are two popular methods of serializing variables. Here is an example that uses the serialize() and unserialize():

    // a complex array
    $myvar = array(
    	'hello',
    	42,
    	array(1,'two'),
    	'apple'
    );
    
    // convert to a string
    $string = serialize($myvar);
    
    echo $string;
    /* prints
    a:4:{i:0;s:5:"hello";i:1;i:42;i:2;a:2:{i:0;i:1;i:1;s:3:"two";}i:3;s:5:"apple";}
    */
    
    // you can reproduce the original variable
    $newvar = unserialize($string);
    
    print_r($newvar);
    /* prints
    Array
    (
        [0] => hello
        [1] => 42
        [2] => Array
            (
                [0] => 1
                [1] => two
            )
    
        [3] => apple
    )
    */
    

    This was the native PHP serialization method. However, since JSON has become so popular in recent years, they decided to add support for it in PHP 5.2. Now you can use the json_encode() and json_decode() functions as well:

    // a complex array
    $myvar = array(
    	'hello',
    	42,
    	array(1,'two'),
    	'apple'
    );
    
    // convert to a string
    $string = json_encode($myvar);
    
    echo $string;
    /* prints
    ["hello",42,[1,"two"],"apple"]
    */
    
    // you can reproduce the original variable
    $newvar = json_decode($string);
    
    print_r($newvar);
    /* prints
    Array
    (
        [0] => hello
        [1] => 42
        [2] => Array
            (
                [0] => 1
                [1] => two
            )
    
        [3] => apple
    )
    */
    

    It is more compact, and best of all, compatible with javascript and many other languages. However, for complex objects, some information may be lost.

    8. Compressing Strings

    When talking about compression, we usually think about files, such as ZIP archives. It is possible to compress long strings in PHP, without involving any archive files.

    In the following example we are going to utilize the gzcompress() and gzuncompress() functions:

    $string =
    "Lorem ipsum dolor sit amet, consectetur
    adipiscing elit. Nunc ut elit id mi ultricies
    adipiscing. Nulla facilisi. Praesent pulvinar,
    sapien vel feugiat vestibulum, nulla dui pretium orci,
    non ultricies elit lacus quis ante. Lorem ipsum dolor
    sit amet, consectetur adipiscing elit. Aliquam
    pretium ullamcorper urna quis iaculis. Etiam ac massa
    sed turpis tempor luctus. Curabitur sed nibh eu elit
    mollis congue. Praesent ipsum diam, consectetur vitae
    ornare a, aliquam a nunc. In id magna pellentesque
    tellus posuere adipiscing. Sed non mi metus, at lacinia
    augue. Sed magna nisi, ornare in mollis in, mollis
    sed nunc. Etiam at justo in leo congue mollis.
    Nullam in neque eget metus hendrerit scelerisque
    eu non enim. Ut malesuada lacus eu nulla bibendum
    id euismod urna sodales. ";
    
    $compressed = gzcompress($string);
    
    echo "Original size: ". strlen($string)."\n";
    /* prints
    Original size: 800
    */
    
    echo "Compressed size: ". strlen($compressed)."\n";
    /* prints
    Compressed size: 418
    */
    
    // getting it back
    $original = gzuncompress($compressed);
    

    We were able to achive almost 50% size reduction. Also the functions gzencode() and gzdecode() achive similar results, by using a different compression algorithm.

    9. Register Shutdown Function

    There is a function called register_shutdown_function(), which will let you execute some code right before the script finishes running.

    Imagine that you want to capture some benchmark statistics at the end of your script execution, such as how long it took to run:

    // capture the start time
    $start_time = microtime(true);
    
    // do some stuff
    // ...
    
    // display how long the script took
    echo "execution took: ".
    		(microtime(true) - $start_time).
    		" seconds.";
    

    At first this may seem trivial. You just add the code to the very bottom of the script and it runs before it finishes. However, if you ever call the exit() function, that code will never run. Also, if there is a fatal error, or if the script is terminated by the user (by pressing the Stop button in the browser), again it may not run.

    When you use register_shutdown_function(), your code will execute no matter why the script has stopped running:

    $start_time = microtime(true);
    
    register_shutdown_function('my_shutdown');
    
    // do some stuff
    // ...
    
    function my_shutdown() {
    	global $start_time;
    
    	echo "execution took: ".
    			(microtime(true) - $start_time).
    			" seconds.";
    }
    
    Conclusion

    Do you know any other PHP features that are not widely known but can be very useful? Please share with us in the comments. And thank you for reading!


  • Permalink for 'Color Inspiration: Awesome Red Websites'

    Color Inspiration: Awesome Red Websites

    Posted: April 26th, 2010, 11:03pm MDT by Cameron Chapman

    Red is a very powerful and strong color. It’s associated with a variety of things, from courage and bravery to warnings and danger. It’s also, of course, strongly tied to love and passion.

    It’s a popular color in website design, though, due to its boldness, is most commonly used as an accent color. With that said, there’s no reason why it can’t take on a more prominent role in a website’s overall design, as demonstrated in these twenty-five awesome red websites.

    Intensity in Ten Cities Big Spaceship Grafik jonwallacedesign Codebutton.com Chrome Khai Liew Thierry Castel Hemlock Sonze Design Studio Host Riser Youth Against Sudoku Take the Walk Remood Waider Mediendesign Liga Retro Saforian Red Relevant Coalmarch Productions Avalon Business Advice Mirror Communications Blogsessive New to York Associate Truf Creative You Also Might Like


  • Permalink for 'Quick Tip: Loop Through Folders with PHP’s Glob()'

    Quick Tip: Loop Through Folders with PHP’s Glob()

    Posted: April 26th, 2010, 6:05pm MDT by Marcus Schumann

    Are you still using opendir() to loop through folders in PHP? Doesn’t that require a lot of repetitive code everytime you want to search a folder? Luckily, PHP’s glob() is a much smarter solution.

    Introduction

    Here’s an example of echoing out some information from a folder, using the traditional opendir() function.

    
    	$dir = "/etc/php5/";
    
    	// Open a known directory, and proceed to read its contents
    	if (is_dir($dir))
    	{
    
    		if ($dh = opendir($dir))
    		{
    
    			while (($file = readdir($dh)) !== false)
    			{
    				echo "filename: $file : filetype: " . filetype($dir . $file) . "\n";
    			}
    
    			closedir($dh);
    
    		}
    
    	}
    

    That should look somewhat familiar. We can massively shorten the code above with:

    	$dir = "/etc/php5/*";
    
    	// Open a known directory, and proceed to read its contents
    	foreach(glob($dir) as $file)
    	{
    		echo "filename: $file : filetype: " . filetype($file) . "<br />";
    	}
    

    Isn’t that much easier? Eager to learn how the method works? If yes, then let’s get on with it.

    glob() supports a total of two arguments, with the second argument being optional. The first argument is the path to the folder, however, it’s a bit more powerful than that.

    Step 1. The First Argument

    This first argument supports a pattern. This means that you can limit the search to specific filetypes or even multiple directories at the same time by using multiple asterixes “*”. Let’s assume that you have a website that allows users to upload images (just because I read this). Each user has his/her own folder within the folder “userImages.” Inside these folder are two additional folders, called “HD” and “TN,” for high definition (full-sized) images, and for thumbnails. Let’s imagine that you want to loop through all your users’ “TN” folders and print the filenames. This would require a relatively large snippet of code if you were to use open_dir(); however, with glob(), it’s easy.

    	foreach(glob('userImages/*/TN/*') as $image)
    	{
    		echo "Filename: " . $image . "<br />";
    	}
    

    This will search userImages/any/TN/any and will return a list of the files that match the pattern.

    	Filename: userImages/username1/TN/test.jpg
    	Filename: userImages/username1/TN/test3.jpg
    	Filename: userImages/username1/TN/test5.png
    	Filename: userImages/username2/TN/subfolder
    	Filename: userImages/username2/TN/test2.jpg
    	Filename: userImages/username2/TN/test4.gif
    	Filename: userImages/username3/TN/styles.css
    

    We can even take things a step further, and be more specific by including a file format in our foreach statement:

    	foreach(glob('userImages/*/TN/*.jpg') as $image)
    	{
    		echo "Filename: " . $image . "<br />";
    	}
    

    Now, this will only return Jpegs.

    	Filename: userImages/username1/TN/test.jpg
    	Filename: userImages/username1/TN/test3.jpg
    	Filename: userImages/username2/TN/test2.jpg
    

    It gets even better. What if, for instance, you require Jpegs, but also Gifs; nothing else? Or what if you want to print only folder names? This is where the second argument comes into play.

    Step 2. The Second Argument

    The second argument is, as mentioned previously, optional. It does, however, provide a very nice set of optional flags. These will allow you to change the way your glob() behaves.

    • GLOB_MARK: Adds a slash to each directory returned
    • GLOB_NOSORT: Return files as they appear in the directory (no sorting)
    • GLOB_NOCHECK: Return the search pattern if no files matching it were found
    • GLOB_NOESCAPE: Backslashes do not quote metacharacters
    • GLOB_BRACE: Expands {a,b,c} to match ‘a’, ‘b’, or ‘c’
    • GLOB_ONLYDIR: Return only directory entries which match the pattern
    • GLOB_ERR: Stop on read errors (like unreadable directories), by default errors are ignored

    As you see, the potential requirements that we noted at the end of Step 1 can easily be fixed with GLOB_BRACE:

    	foreach(glob('userImages/*/TN/{*.jpg,*.gif}', GLOB_BRACE) as $image)
    	{
    		echo "Filename: " . $image . "<br />";
    	}
    

    which will return this:

    	Filename: userImages/username1/TN/test.jpg
    	Filename: userImages/username1/TN/test3.jpg
    	Filename: userImages/username2/TN/test2.jpg
    	Filename: userImages/username2/TN/test4.gif
    

    If we wish to only print subfolder names, we could use GLOB_ONLYDIR:

    	foreach(glob('userImages/*/TN/*', GLOB_ONLYDIR) as $image)
    	{
    		echo "Filename: " . $image . "<br />";
    	}
    

    which will print:

    	Filename: userImages/username2/TN/subfolder
    
    Conclusion and One More Example

    This method has been available since PHP 4.3, however, it’s not used very often, strangely. I didn’t learn it until quite late myself. Now, I often use glob() when loading plugins into my framework:

    	foreach(glob('includes/plugins/*.php') as $plugin)
    	{
    		include_once($plugin);
    	}
    

    That’s all; I hope you enjoyed this quick tip, and let me know if you have any questions!


  • Permalink for 'Quick Tip: Ever Thought About Using @Font-face for Icons?'

    Quick Tip: Ever Thought About Using @Font-face for Icons?

    Posted: April 23rd, 2010, 9:28am MDT by Wayne Helman

    The evolution of Internet technologies never ceases to amaze. Seemingly daily, new concepts and techniques are being thought up by creative and talented people. With modern browsers being adopted at a greater rate, systems like CSS3 are becoming more and more viable for use on projects of all sizes. Clearly, this can be seen by looking at new services sprouting on-line like TypeKit. Conceptually, if we deconstruct a font down to it’s basic elements, we can make use of this technology for things other than type, icons.

    The Need for Speed

    For a short period of time, developers began producing websites with little regard for bandwidth consumption. HTML and CSS where restrictive and Adobe Flash was an open canvas for designers and developers to stuff animations and complex layouts into. This resulted in some extremely bandwidth heavy sites—we all remember a few. Those were the days before the proliferation of mobile smart phones.

    With smart phones accessing the Internet more frequently, bandwidth and page load speeds have suddenly returned to the forefront. Thankfully, advances in HTML, CSS, and JavaScript have made that all possible. Central to webpage speed and responsiveness is the number of HTTP requests a page load must make. Modern browsers limit the number of requests to a single server. The W3C HTTP 1.1 specification reads

    “A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.”

    One technique that has become increasingly popular is the use of CSS sprites. CSS sprites are designed to reduce the number of HTTP requests to the web server by combining many smaller images into a single larger image and defining a block level CSS element to only show a defined portion of the larger image. The technique is simple, but ingenious.

    Deconstructing the Font

    Fonts at their most basic molecular level are a series of vector glyphs packaged up into a single “glyph archive”.

    CSS3 has introduced to the web development world the ability to embed fonts with the @face-face declaration. Without question, this advancement in Internet technologies is one of the most exciting and important stages in our brief history. With developers able to embed fonts of their choice, designers can produce layouts that will render far more consistently from platform to platform bringing the art of interactive layout closer to it’s print cousin.

    If we take a closer look at the technology behind a font, we can gain a far better understanding of how they can be used and deployed. Fonts at their most basic molecular level are a series of vector glyphs packaged up into a single “glyph archive”. We can then reference each glyph by its corresponding character code. Theoretically, it’s very similar to the way in which we reference an array in almost any programming language—through a key/value pair.

    With this in mind, the glyphs we reference can really be any vector-based single color image. This is nothing new—we’ve all seen Dingbats and Webdings. They are two examples of non-type fonts, that is, a series of vector based images compiled into a single font archive.

    Abstracting and Expanding @font-face

    With the advent of font embedding and the realization that fonts are essentially a series of simple vector glyphs, I began to experiment on how to use this format to my advantage. Conceptually, if I placed all required icons for a particular site into a custom font, I would then be able to use those icons anywhere on the site with the ability to change size and color, add backgrounds, shadows and rotation, and just about anything else CSS will allow for text. The added advantage being a single CSS sprite-like HTTP request.

    To illustrate, I’ve compiled a new font with a few of the great icons from Brightmix.

    Sample glyph chart

    I’ve used the lower case slots for plain icons, and the uppercase slots for the same icon in a circular treatment.

    To use my new Icon Pack, I’ll first have to export my font set as a number of different font files (.eot, .woff, .ttf, .svg) to be compatible with all browsers. The topic of font embedding and file format converting is covered elsewhere, so I will avoid a detailed explanation here. However, the CSS would look something like this.

    
    @font-face {
      font-family: 'IconPack';
      src: url('iconpack.eot');
      src: local('IconPack'),
        url('iconpack.woff') format('woff'),
        url('iconpack.ttf') format('truetype'),
        url('iconpack.svg#IconPack') format('svg');
    }
    

    Once embedded, I now have a complete icon set in vector format to reference. To reference an icon I simply need a style that includes the font-family of “IconPack”.

    
    <style>
    .staricon {
      font-family: 'IconPack';
    }
    </style>
    
    <div class="staricon">a</div>
    

    The above example would render a star and is the most basic use of the Icon Pack concept, however it’s not very intuative from a development perspective, not SEO friendly, nor does it gracefully degrade in the case of non-CSS support.

    To remedy the situation, I’m going to include a :before pseudo-element and wrap the content in a span tag.

    
    <style>
    .staricon {
      font-family: 'IconPack';
    }
    .staricon:before {
      content: 'a';
    }
    .show {
      display:block;
    }
    .hide {
      display:none;
    }
    </style>
    
    <div class="staricon">
      <span class="show">star</span>
    </div>
    

    Now, the star is added to the display and I can toggle the visiblility of the text by using the show and hide classes. The result is an easy to reference CSS class that degrades gracefully and is optimized for search engines. For my entire set of icons, I can write something like below.

    
    <style>
    .show {
      display:block;
    }
    .hide {
      display:none;
    }
    .icon {
      font-family: 'IconPack';
    }
    .star:before {
      content: 'a';
    }
    .rss:before {
      content: 'b';
    }
    .screen:before {
      content: 'c';
    }
    .talkbubble:before {
      content: 'd';
    }
    <!--
    ... and so on ...
    -->
    </style>
    
    <div class="icon screen">
      <span class="hide">screen icon</span>
    </div>
    
    Icon Pack Usage

    The benefit here is that the icon will scale with the font size. In fact, all icons will scale and maintain perfect clarity.

    So far, we’ve only touched the tip of the iceberg, nothing groundbreaking here, although you may start to see the possibilities. A real world scenerio would be the replacement of the list-item-style. As apposed to using an image, we can now use a vector icon from our Icon Pack. The benefit here is that the icon will scale with the font size. In fact, all icons will scale and maintain perfect clarity.

    Since the icons are now placed on our page as if they were text, we can apply any valid CSS style to them without downloading any other assets. We could apply color, font-size, text-shadow, etc and make use of the :hover pseudo-element for mouse over effects—all with a single glyph.

    As with anything, there are some unfortunate limitations. As of this writing, there is no way to display a single glyph with multiple colors. There has been some CSS trickery to get gradients over live text, however complex shapes with varying colors in a single glyph is a limitation. Having said that, there are ways to approximate multi-colored glyphs by segragating the parts of a vector graphic into individual glyphs then assembling and coloring them on the page through CSS.

    Another interesting usage is a simple CAPTCHA validation. By replacing the glyphs for the alphabet with numbers, users will see numbers, but the page code will be letters. Some simple computation to translate between the two, and you have an easy to read CAPTCHA.

    To better illustrate these concepts, I’ve assembled a sample page made up of two HTTP requests—the page code and a single Icon Pack. Included as well is the ability to scale the font size of the page to clearly demonstrate the flexibility of embedding vector glyphs. The company logo, navigation, imagery, and CAPTCHA are all using glyphs. Please note, the CAPTCHA included here is for illustration only. To use this on a production site, I would recommend validating on the server side with a dynamic algorithm as apposed to JavaScript.

    This sample page also demostrates the use of a glyph as a scalable “repeating” background. I’ll be the first to admit this implementation is hack-ish at best, however I think it demonstrates the flexibility and versatility of the Icon Pack.

    Clearly, this opens up some possiblities. Designers can develop Icon Packs for sale, corporate entities can host a single Icon Pack to be used on all corporate media. Template designers can easily distribute multiple color options of the same template all without having to save and export a single extra file. Web designers can easily scale existing sites to be compatible with hand held devices. Furthermore, this technique exposes our icons to the DOM enabling animated Flash-like effects with your favourite JavaScript API.

    As usage and browser support for CSS3 penetrates further, Icon Packs will soon have a large impact on content delivery furthering the light weight, scalable, multi-device trends that are starting to become a necessity.


  • Permalink for 'A jQuery UI and .Net Image Organizer'

    A jQuery UI and .Net Image Organizer

    Posted: April 23rd, 2010, 8:57am MDT by Dan Wellman

    Over the course of this tutorial we’ll look at how to create a simple image organizer that lets users reorder a series of images; this functionality could be useful on any kind of image-based site where users have a collection of images that they have uploaded or otherwise added to their profile or account. We’ll use .net to retrieve and store the order of images in a SQL database on the server, and jQuery UI to handle the reordering of the images on the client.

    Image Organizer Getting Started

    The page we create will be of the type aspx; we can create and edit these files with a simple text editor if necessary, but it’s far more efficient to use a proper .Net IDE. Visual Web Developer Express from Microsoft is a great .Net IDE and it’s completely free; grab a copy now from [www.microsoft.com] . It can be downloaded as part of the Web Platform; you can choose a range of different products when you download it, for the purposes of this tutorial we’ll be using the following components:

    • Visual Web Developer Express 2008
    • SQL Server Express 2008 (with SQL Server 2008 Management Studio Express)

    The Web Platform is actually pretty good and gives you access to a wide range of popular web applications and frameworks, such as dotNetNuke, Joomla, Umbraco and many others, and the platform installer downloads and configures everything you need. It’ll take a little while to download and install, so while it’s doing its thing we can set up a development area; create a new folder and call it image_organiser, then inside this folder create two new folders and call them js and css.

    You should also grab a copy of the latest release of jQuery UI; head over to the download builder at [jqueryui.com] and make sure the following components at the left of the page are checked:

    • Core
    • Widget
    • Mouse
    • Sortable

    A theme isn’t required but make sure version 1.8 is selected at the right of the page and then hit the download button. Once the archive has downloaded open it up and copy the following files from the js folder in the archive to the js folder we just created:

    • jquery-1.4.2.min.js
    • jquery-ui-1.8.custom.min.js

    We also make use of Doug Crockford’s excellent JSON utility, which can be downloaded from [www.JSON.org] . Save a copy of this file to our js folder and be sure to remove the alert from the top of the file.

    Once the platform installer has finished, fire up Visual Web Developer Express and go to File » Open Web Site and then choose the image_organiser project folder that we just created. You’ll get a prompt asking whether to upgrade the site to use .net 3.5; choose Yes.

    Creating a Database

    We’ll create a new database and table for this example; open the SQL Server Management Studio and connect to the local instance of SQL Server (it will be called something like COMPUTERNAME\SQLEXPRESS). To create a new database right-click on the Databases folder and choose New Database. In the dialog that appears set the Database name to image_organiser and then click Ok. You should then see the new database listed in the left pane of the manager.

    We now need to create a new table within our new database; expand the new database, then right-click on the Tables folder and choose New table. The management console will give you a couple of extra panels; one showing the table columns and one showing the table properties. Add three columns to the table, the first should have the name src and be of type varchar(50), the second should have the name alt and also be of type varchar(50). The final column is called [order] and is of the type int. Only the alt column should allow null values.

    Click the disk icon on the toolbar and choose the name images. When you expand the Tables folder in the Object Explorer on the left, the new table should be listed. In a full implementation, each user of the application would have their own set of images, and there would no doubt be other tables in the database for usernames and passwords and other information associated with the user. For the purpose of this tutorial, imagine that we’re a single authenticated user manipulating our own set of images.

    Now we need to populate the table with some data; right-click on the new table and choose Edit Top 200 Rows; the console will change again so that you have an editable view of the table. An id column is inserted into the table automatically; in this example I’ve simply used a zero-based index number for the values in this column, but this should match the file names of the images in use. Use the data shown here:

    The aspx File

    To create a new aspx page, right click the root of the site in the Solution Explorer at the right of the application and choose Add New Item. In the dialog that appears choose Web Form in the top section and Visual C# in the Language select box. Click Add.

    This will give a new page called Default.aspx, which will open up in the IDE automatically. The new page is listed in the Solution Explorer at the right and it has a plus icon beside it indicating that it contains something. For those of you that have never worked with .Net before, it contains the code-behind aspx.cs file which we can use to add the server-side logic for the page a little later on.

    The aspx file will have a few elements inside it already, including a <form>; add the following code within the <form> element:

    <div id="outerWrap">
    	<div id="left">
    		<h1>Image Organiser</h1>
    		<p>Re-order the images by dragging an image to a new location. Your changes will be saved automatically.</p>
    	</div>
    	<div id="images"></div>
    </div>

    We’ve got a simple outer container with two <div> elements inside it; one holds some brief instructions while the other will be used to hold the sortable image elements. In order to populate the images container with the images from the database we can use the handy .Net Repeater control; add the following code inside the images container:

    <asp:Repeater id="imageRepeat" runat="server">
    	<ItemTemplate>
          		<li id="<%# DataBinder.Eval(Container.DataItem, "id") %>">
    			<img src="<%# DataBinder.Eval(Container.DataItem, "src") %>" alt="<%# DataBinder.Eval(Container.DataItem, "alt") %>" />
    		</li>
    	</ItemTemplate>
    </asp:Repeater>

    We use the <asp:Repeater> element whichrepeater control we just added to the page. When you open up the Default.aspx.cs file you’ll see that there are several items in the file already; there are a series of using directives at the top of the file which indicate to the server the namespaces of the .Net components that are required by the aspx file. As well as those included in the file, we’ll also need to add the following:

    using System.Data;
    using System.Data.SqlClient;

    Following this we have a class definition and a Page_Load event handler which we can use to execute server-side code when the aspx page loads. Within this event handler add the following code:

    //define connection
    SqlConnection dbCon = new SqlConnection("Server=DESKTOP\\SQLEXPRESS;UID=sa;PWD=your_password;Database=image_organiser");
    
    //define query
    string sSQL = "Select * from images";
    
    //define command
    SqlCommand cmd = new SqlCommand(sSQL, dbCon);
    
    //open connection
    dbCon.Open();  
    
    //read data
    SqlDataReader ds = cmd.ExecuteReader(); 
    
    //bind to repeater
    imageRepeat.DataSource = ds;
    imageRepeat.DataBind();
    
    //close connection
    dbCon.Close();

    The code is very straight-forward, let’s walk through it; we define a new SqlConnection using the variable dbCon. The value of this variable is the connection string we use to connect to the database and consists of the server name, user name (sa is the default), password and database name. Don’t forget to replace your_password in the above code with the password you set when installing SQL.

    Next we define our query, which in this case is just to select everything in the database using the * wildcard. We also store the SqlCommand in a variable which consists of the query and the connection. Following this we can then open the connection with the Open() method and read the data into a SqlDataReader variable with the ExecuteReader() method called on the SqlCommand.

    Lastly we bind the data to our repeater control by setting the ds variable as the repeater’s DataSource and calling the DataBind() method on it, before finally closing the database connection. We don’t need to select the repeater control, we can just refer to it directly using the ID we specified in the aspx page. The first stage of our code is now complete, the repeater will display an <li> and <img> for each row of our database. It’ll look a little bland at this point however so let’s add some basic styling.

    Styling the Page

    To add a new style sheet to the site right-click on the css folder in the Solution Explorer at the right and choose Add New Item; select Style Sheet in the top pane of the dialog and set the Name field to image_organiser.css, then hit Add. The new file will automatically open in the IDE; add the following code to it:

    #outerWrap { width:1004px; margin:auto; position:relative; background-color:#eee; border:1px solid #999; }
    #outerWrap:after { content:"."; display:block; visibility:hidden; clear:both; }
    h1 { font:italic normal 24px Georgia, Serif; text-align:center; margin:10px 0; }
    p { margin:0; font:12px Arial, Sans-serif; padding:0 10px; }
    #left { width:218px; float:left; }
    #images { margin:0; padding:0; float:left; width:786px; }
    #images li { list-style-type:none; float:left; cursor:move; margin:10px 10px 0 0; width:250px; height:250px; border:1px solid #999; }
    #images .vacant { border:3px dotted #66d164; width:246px; height:246px; background-color:#fff; }
    .success, .failure { margin:0 0 0 10px; padding:4px 0 4px 26px; position:absolute; bottom:18px; font-weight:bold; }
    .success { background:url('../img/tick.png') no-repeat 0 1px; color:#12751c; }
    .failure { background:url('../img/cross.png') no-repeat 0 0; color:#861b16; }

    These basic styles simply lay the page out in the format we want for this example. There’s nothing really important here, any of it could easily be changed to suit other requirements. Don’t forget to link to the new stylesheet in the <head> of the page with the following:

    <link rel="stylesheet" type="text/css" href="css/image_organiser.css" />

    At this point, the page should now appear like this when it first loads in the browser:

    You can view the page by right-clicking the aspx file in the Solution Explorer and choosing View in browser. This will use the IDE’s built-in web server to display the page.

    Making the Images Sortable

    The point to the page is to make the images sortable so that the user can reorder them, to do this we need to link to the jQuery UI files in our js folder; add the following <script> tags directly before the closing </body> tag:

    <script type="text/javascript" src="js/jquery-1.4.2.js"></script>
    <script type="text/javascript" src="js/jquery-ui-1.8.custom.min.js"></script>

    Making the images sortable is extremely easy; after the above <script> elements add the following code:

    <script type="text/javascript">
    	$(function() {
    
    		//make li sortable
    		$("#images").sortable({
    			placeholder: "vacant",
    			update: function(e, ui) {
    
    				//code to save new order      			
    
    	      		}
          		});
    	});
    </script>

    All we do is call the sortable() method on the container of the items we would like to be able to sort. We supply a configuration object to the method specifying the class name that should be applied to the empty slot that the item being sorted can be dropped into using the placeholder option, and a callback function that should be executed whenever a sort occurs and the order of the items changes. When we run the page at this point, we should find that the images are sortable and that our vacant styles are applied:

    Saving the New Order

    All we need to do now in the main .aspx file is send the new order of the images to the server whenever the images are sorted; replace the comment in the update callback with the following code:

    //create vars
    var orderArray = [], wrap = {};
    
    //reset 'saved' message
    $(".success", $("#left")).remove();
    
    //process each image
    $("#images img").each(function(i) {
    
    	//build img object
    	var imgObj = {
    		"id": $(this).parent().attr("id").split("_")[1],
    		"order": i + 1
    	};
    
    	//add object to array
    	orderArray.push(imgObj);
    });
    
    //wrap in object
    wrap.d = orderArray;
    
    //pass to server
    $.ajax({
    	type: "POST",
    	url: "WebService.asmx/updateOrder",
    	data: JSON.stringify(wrap),
    	contentType: "application/json; charset=utf-8",
    	success: function(data) {
    		if (data.d === "saved") {
    			$("<p>").text("New order saved!")
    				.addClass("success").appendTo("#left");
    		} else {
    			$("<p>").text("Save failed")
    				.addClass("failure").appendTo("#left");
    		}
    	}
    });

    Let’s look at what this code does; first we create a couple of variables which we’ll need later on in the script, the first is an array literal, the second an object literal. We then remove any success messages that may be present from previous sort interactions. We then process each of the images in the image grid using jQuery’s each() method, which will execute the anonymous function we specify once for each image in the list. This function is automatically passed an index number for the current item, which we need to make use of.

    Within this function we create a new object literal and give it two properties; the id of the current image, and the index number of the current each() iteration. We then insert this object into the array we created a moment ago. Once we have done this for each image on the page we insert the array into a wrapping object. This object will be passed to the server, which is done using jQuery’s low-level ajax() method.

    We need to use the ajax() method instead of, say, the post() or getJSON() methods, because we need to specify the contentType in order for the server to process the data correctly. We set the request type to POST, specify the server-side file with the name of the method that will handle the request as a query string parameter. We also pass in our prepared wrap object. In order to convert the object fully into JSON syntax we use the stringify() method of the json2.js file.

    We also specify a success handler which will be executed once the request is completed; we can see the string returned by the server by accessing the data passed back to this success handler. The actual string will be contained in a propery of the data object labelled d. Data returned to a page via AJAX in .Net is usually accessed via a d object in this way.

    We can add a different message and class name to the page depending on whether the server indicates the request was a success or failure. You can test this and see the different messages by using Firebug to change the id attribute of one of the image containers to a value that doesn’t exist in the database, and then sorting an image. This is how our messages should appear:

    The Active Server Method File

    To receive the JSON object passed to the server via AJAX following a sort interaction we can use an asmx file; right-click the root of the site in the Solution Explorer and choose Add New Item. In the dialog that appears choose Web Service in the top section and Visual C# in the Language select box, then click Add.

    This will give you a new WebService.asmx file in your site, but the code-behind for this file will go into an automatically created folder called App_code. We don’t need to update the asmx file at all, everything will be done in the code-behind WebService.asmx.cs file. Open it up and you’ll see that there is already of lot of code in the file; change it so that the file in its entirety appears as follows:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Web.Script.Services;
    
    /// <summary>
    /// Receives and saves new order of images
    /// </summary>
    
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    
    public class WebService : System.Web.Services.WebService {
    
        public class ImageDTO
        {
            public string id { get; set; }
            public int order { get; set; }
        }
    
        [WebMethod]
        public string updateOrder(List<ImageDTO> d)
        {
            //define connection
            SqlConnection dbCon = new SqlConnection("Server=DESKTOP\\SQLEXPRESS;UID=sa;PWD=your_password;Database=image_organiser");
    
            //process JSON object
            foreach (ImageDTO img in d)
            {
                //define procedure
                string sSQL = "Update images set [order] = " + img.order + "where id = " + img.id;
    
                try
                {
                    //open connection
                    dbCon.Open();
    
                    //update data
                    cmd.ExecuteNonQuery();
    
                    //close connection
                    dbCon.Close();
                }
                catch (SqlException ex)
                {
                    return "failed";
                }
            }        
    
            //success!
            return "saved";
    
        }
    
    }

    We need to add several namespaces to the using section at the top of the file in order to work with our SQL database. We’ll also need to ensure we uncomment the line that allows our web service to be called from the script in the main aspx page (it’s clearly marked with a comment in the default version of the file).

    Within the WebService class we need to add a new class that represents each of the inner objects within the array passed to the web service. We do this with the ImageDTO class and give each object id and order properties and assign getter and setter methods for working with the values of these properties.

    Next comes the method that is called from our script; the updateOrder web method. This method receives the d object which we cast as a list of ImageDTO objects; we’ll then be able to use the methods defined in our class to access each property.

    We define the connection information needed to connect to our database and then process each object in our ImageDTO list. We extract the new order and the id of the image and use this to update the order column for the corresponding row in the MSSQL table.

    This code is relatively similar to the code we used to get the information out of the database on page load, we just use a different connection string and use the ExecuteNonQuery() method instead of ExecuteReader() because we’re updating the database instead of just reading from it. We also wrap our connection execution in a try…catch statement and either output the string failed or saved depending on whether the update succeeds.

    Summary

    We used the c# flavour of .Net combined with jQuery UI in this tutorial to create a page that remembers the order of images on it and allows the images to be reordered according the whims and desires of the visitor to the page. In this example it is a simple page but don’t forget that in a proper implementation this would probably be accessible only by the authenticated user; each user would have access to his or her own images and be able to sort them, while the images would be fixed on the publicly accessible version of the page.

    We didn’t do any sanitization of the data being passed into the server-side file that updates the database; although the user doesn’t enter the data in a text field, the outgoing request from the page could easily be manipulated in order to send malicious code to the server. The danger of this kind of attack would be limited as we would probably only be allowing sorting in the first place to registered, authenticated users. Although security is beyond the scope of this tutorial, it should always be a primary concern when dealing with live code.


  • Permalink for 'Photoshop to HTML: Slice your Designs Like a Pro'

    Photoshop to HTML: Slice your Designs Like a Pro

    Posted: April 22nd, 2010, 1:18pm MDT by Jeffrey Way

    Hey, everyone! I have some exciting news (at least for me)! Late last year, I was asked to prepare a book and video series that covers exactly how to convert PSDs into standards-compliant HTML/CSS websites. This is what web designers do day-in and day-out. I’m proud to announce that it’s now been released by Rockable Press! So, if you’re at the point in your learning where this might be helpful, please do read on and consider checking it out.

    Slice Your Designs Like a Pro!

    Within its pages, Nettuts+ editor Jeffrey Way takes you through the entire process of converting a design from Photoshop into a complete HTML/CSS website. If you can create gorgeous designs in Photoshop but don’t know how to convert them into solid, functioning website, this book will teach you how. With these skills in your arsenal you can begin working as a professional web designer, or increase the money you earn for every web design gig you do.

    But this is NOT just an eBook. It also comes packed with extras, like a directory of Photoshop, HTML and CSS files for you to use as you work through the book AND a series of 14 screencasts (over 4 hours of training) taking you through the whole project from beginning to end. The eBook and training were created by Jeffrey Way, a superstar in front-end development and veteran editor of Nettuts+, one of the biggest web development learning sites on the internet.

    You get a 145 page eBook + Example Photoshop, HTML and CSS files + 4 hours of screencasts

    What’s Covered?

    This eBook is for anyone who has an elementary understanding of HTML and CSS. You should be familiar with HTML tags and the most common CSS properties. Some of the topics covered in the book are as follows:

    • Different methods for slicing a PSD.
    • Create semantic mark-up, and learn how this HTML relates to the original PSD.
    • How to utilize techniques, such as background replacement and sprite generation.
    • Use custom fonts with Cufon font replacement.
    • The differences between absolute and relative positioning.
    • How to compensate for the dreaded Internet Explorer 6.
    • Take advantage of advanced CSS3 features.
    • How to take advantage of a variety of helpful browser extensions to expedite your coding.
    • Utilize the jQuery library to add a touch of interactivity.

    And there’s plenty more!

    Sample Pages

    If you’re undecided, you can Download the Sample Pages (17 pages). But, don’t forget, it also comes with four hours of video training that covers the entire book. So you have your choice: read or watch!

    About the Author

    Jeffrey Way is part of the Envato team. He is the Editor of Nettuts+, a web development tutorials blog with over 50,000 daily readers, and he’s also the manager of two marketplaces for web developers: ThemeForest and CodeCanyon. He has been in the web industry for over 5 years, with expertise in HTML, CSS, PHP, JavaScript, jQuery, CodeIgniter, Database Development and WordPress.

    PDF eBook, $29 – Purchase


  • Permalink for 'Using Twitter’s @Anywhere Service in 6 Steps'

    Using Twitter’s @Anywhere Service in 6 Steps

    Posted: April 22nd, 2010, 9:55am MDT by Rafael Soto

    Last week, Twitter released @Anywhere, which, with only a few added lines in your code, can bring all of Twitter’s platform functionalities into your website. @Anywhere can allow for anything, ranging from converting a simple @username into a clickable link, to even creating new tweets directly from your personal site. I’ll show you exactly how to do so in this tutorial!

    Twitter Anywhere Before you Begin, Create an Application

    In order to begin using @Anywhere, you must have an API key. What? You don't have it? No problem. Just go here and register a new application  (don't register it from here).

    • If you have a local server installed, set it to a domain (developertutorial.com, for example), as it won't work with your localhost (if you don't know how, check out this tutorial, the hosts file part is particularly important).
    • If you don't have a local server, then leave this section blank. Just remember that for production, you will have to set it to the domain you are working on.

    And finally, set the default access type to Read & Write. This is very important!

    Now, you will be redirected to the application settings page. Copy the consumer key (API Key), and let's get started using @Anywhere.

    Including @Anywhere's Javascript

    Open your new HTML file, and, inside the <head> tag, include:

    <script src=" [platform.twitter.com] type="text/javascript"></script>

    Your code should look like:

    <!DOCTYPE HTML>
    <html>
    <head>
    <title>@Anywhere</title>
    <meta [http-equiv="Content-Type"] content="text/html; charset=UTF-8" />
    <link href="styles.css" rel="stylesheet" type="text/css" />
    <script src="http://platform.twitter.com/anywhere.js?id=APIKey&v=1" type="text/javascript"></script>
    </head>
    <body>
    ...
    </body>
    </html>
    

    Replace APIKey with the Application's API Key you got in the previous step. The parameter v=1 is the version. Perhaps in the future, Twitter will add new features and maybe new syntaxes. To prevent breaking the existing @Anywhere code, they will be preserving old code if specified. Version 1 supports every major browser, including IE6.

    After including this JavaScript file, we can access the twttr object, which will invoke the anywhere() function with a parameter when @Anywhere is ready:

    twttr.anywhere(function(twitter) {
    	// Actions when @Anywhere is ready
    });
    

    The parameter (in this case twitter) is the object we will be using, similar to jQuery's $.

    Next, we need to create an HTML base. Copy and paste the following code, and place it within the “body” tag.

    <div id="main">
    	<div class="post">
    		<h2>My blog post</h2>
    		<div class="content">
    			<p>This is a test blog post testing @Anywhere by @twitter.</p>
    			<p>If you enjoyed this tutorial, please <a href="http://twitter.com/faelazo" class="hovercard">follow me</a> and keep in touch with @NETTUTS for more awesomeness.</p>
    		</div>
    	</div>
    	<div class="comments">
    	<h3>Comments</h3>
    	<ol>
    		<li><span class="author">@corcholat</span> says:
    			<p>Such a great tutorial! </p>
    		</li>
    		<li><span class="author">@faelazo</span> says:
    			<p>You should also follow @smashingmag</p>
    		</li>
    	</ol>
    	</div>
    </div>
    

    Now let's dig in.

    1. linkifyUsers: Convert @something into Links

    @Anywhere lets us to convert @mentions into links. This functionality is called linkifyUsers, and is pretty straight-forward: it sets the HTML element you wish to convert to a link.

    Since we want all the document's @mentions to be converted into links, we just call the linkifyUsers() function in the body element:

    twttr.anywhere(function(twitter) {
    	twitter("body").linkifyUsers();
    });
    
    linkifyUsers result

    As mentioned previously, the “twitter” parameter, inside the callback function, is much like jQuery's “$” alias; f we want to convert @mentions into links, but only those within a certain section, we can use a CSS selector, as shown below.

    twttr.anywhere(function(twitter) {
    	twitter(".post").linkifyUsers();
    });
    

    linkifyUsers() accepts an object as a parameter, with two properties: className and success. With className, you can specify a class to be applied when the @mentions are found; so, for example, you could add an unsemantic 'red' class and specify in your CSS:

    	.red { color:#f00; }
    

    Here’s the code.

    twttr.anywhere(function(twitter) {
    	twitter("body").linkifyUsers({
    		className:'red'
    	});
    });
    
    2. hovercards: Display Additional Information on Hover

    hovercards() converts @mentions to links, but also loads a small pop-up tooltip on mouseover. Here’s a basic example of its usage.

    twttr.anywhere(function(twitter) {
    	twitter.hovercards();
    });
    
    hovercards result

    However, hovercards() is flexible enough to include certain elements even if they don't have a @mention in them. In the HTML, I'm linking "follow me" to http://twitter.com/faelazo; but @anywhere is smart enough to convert this link to a hovercard. By adding a class of “hovercard” to the anchor tag, Twitter will handle the rest!

    twttr.anywhere(function(twitter) {
        // Find the @mentions and linkify as usual
        twitter("body").hovercards();
    
        // Let's find the elements which has a hovercard class
        twitter(".hovercard").hovercards({
            username: function(node){
                var twitter_regexp = /twitter\.com\/([a-z0-9_]*)\/?(.*)?/gi;
                if(node.href.match(twitter_regexp) && (twitter_match = twitter_regexp.exec(node.href))){
                    return twitter_match[1];
                }
                return '';
            }
        });
    });
    

    The username parameter takes a function with a parameter that will be the object found (in this case node). Here's what happens inside the function, line by line.

    var twitter_regexp = /twitter\.com\/([a-z0-9_]*)/gi;

    This is a regular expression. It will match a twitter.com/ string with alphanumeric values and an underscore.

    if(node.href.match(twitter_regexp) && (twitter_match = twitter_regexp.exec(node.href))){

    If the regexp matches the href property from the node element, then set the variable twitter_match to capture the values in an array.

    return twitter_match[1];

    It will return the match found.

    We add a “return” just in case the element does have a class, but does not refer to twitter.com; so there will be no match. If it returns false or NULL, the script throws an error. With an empty string, it shows a hovercard but with no user found.

    Now, if this is a bit too complicated, you can always simplify the process, and add the username as the title attribute of the anchor tag.

    <a href=" [twitter.com] class="hovercard" title="faelazo">follow me</a>
    

    And just return the node’s title attribute. Much easier, right?

    twitter(".hovercard").hovercards({
        username: function(node){
            return node.title;
        }
    });
    

    “hovercards” can be applied to any element (even a div), just as long as it specifies a username.

    twitter("#main").hovercards({ username: function(){ return 'therrorcom'; }});
    

    3. followButton: Invite to Follow with Just One Click

    followButton() will append a button to follow the username parameter in the element previously specified.

    The following code will append a button to follow Nettuts+ in the #main div.

    twttr.anywhere(function(twitter) {
        twitter("#main").followButton("nettuts");
    });
    
    followButton result

    followButton() expects one parameter: the username to follow. Simple enough, eh?

    4. tweetBox: Tweets From your Site

    tweetBox() will append a box in which the users can enter their comments and tweet them via your site.
    tweetBox can receive an object as parameter, with the following properites:

    • counter (boolean, default true)
      Whether or not to show the counter for remaining characters.
    • height (integer, default 65)
      The height of the box, in pixels.
    • width (integer, default 515)
      The widht of the box, in pixels.
    • label (string, default "What's happening?")
      The text above the box.
    • defaultContent (string, default none)
      You can enter by default the URL, a @mention, a #hashtag, etc.
    • onTweet (function)
      It's called after the tweet button is pressed. It receives two arguments: plain text tweet and HTML tweet.

    A default tweetBox can be called after the element with the comments class with the following snippet.

    twttr.anywhere(function(twitter) {
        twitter(".comments").tweetBox();
    });
    

    So if you want a custom label, content, and a callback when the tweet has been sent, use this code.

    twitter(".comments").tweetBox({
        label: 'What do you think about this article?',
        defaultContent: '#nettuts ',
        onTweet: function(plain, html){
            // Actions when tweet is sent
        }
    });
    
    custom tweetBox result

    onTweet might be useful if you are planning to replace the default comment area with the CMS you are using. You would still need a database and a table to show the comments, right? So you can hack the CMS a little and make a AJAX request with the onTweet event to insert the tweet into your database.

    5. connect: Sign in a User to your Application

    As you probably saw, the two last methods require confirmation to grant permission to the application. @Anywhere has a method to check if the user is logged in with the application (not on twitter). You can use conditionals to whether or not to show certain elements.

    This snippet will append the connect button in the element with a comments class.

    twttr.anywhere(function(twitter) {
    	twitter(".comments").connectButton();
    });
    
    custom tweetBox result

    If you need a button with a different size, you can pass an object literal with the property size and value small, medium, large or xlarge. Note that “medium” is the default value.

    twttr.anywhere(function(twitter) {
    	twitter(".comments").connectButton({ size: 'large' });
    });
    

    The Twitter object includes some extra goodies; one is currentUser, which is an object; the other is isConnected(), which is a function that returns a boolean. From here, we can create some conditional statements.

    twttr.anywhere(function(twitter) {
    	if(twitter.isConnected()){
    		alert('Welcome, you are connected');
    	} else {
    		twitter(".comments").connectButton();
    	}
    });
    

    If isConnected() returns true, we can show some user information, such as the username (screen_name), profile picture (profile_image_url), followers or following. Here's a list for the information that the application can access. Let's see the currentUser object in the final roundup.

    6. Final Roundup: Mixing it All Together

    I will be modifying the div with the comments class.

    <div class="comments">
    	<h3>Comments</h3>
    	<ol>
    		<li><span class="author">@corcholat</span> says:
    			<p>Such a great tutorial! </p>
    		</li>
    		<li><span class="author">@faelazo</span> says:
    			<p>You should also follow @smashingmag</p>
    		</li>
    	</ol>
    	<div class="add">
    		<h3>Add comment</h3>
    		<div class="author"></div>
    		<div class="box"></div>
    	</div>
    </div>
    

    Now let's include jQuery to make things a bit easier. Insert, between <head> and </head>, the following code:

    <script src=" [ajax.googleapis.com] type="text/javascript"></script>
    

    Now we have a space to add comments. First, let's use the isConnected() conditional to show a button if the user is not signed into our application; this button will be appended to the element with an "add" class.

    if(twitter.isConnected()){
        twitter(".comments").connectButton();
    }
    

    Now let's use Twitter’s currentUser object. This object can retrieve information with the data() method. So the following snippet will retrieve the user's screen_name.

    twitter.currentUser.data('screen_name');
    

    @Anywhere lets us specify callback functions for the connectButton feature. As an argument, it accepts an object with two properties: authComplete and signOut; both are functions, so when signOut is invoked, we could refresh the page. The same holds true for authComplete. Let's replace the connectButton() line with this snippet:

    twitter(".comments > .add").connectButton({
        authComplete: function(user) {
            location.reload();
        },
        signOut: function() {
            location.reload();
        }
    });
    

    This is pretty straightfoward: we pass an object as the argument, then set both the signOut and authComplete functions to reload the page. Note that I've dropped the else clause for the isConnected() conditional in order to set the signOut event.

    Next, let's add a tweetBox inside the conditional.

    if(twitter.isConnected()){
        $(".comments > .add > .author").html('<img src="'+ twitter.currentUser.data('profile_image_url') +'" /> <a href="http://twitter.com/'+ twitter.currentUser.data('screen_name') +'">'+ twitter.currentUser.data('screen_name') +'</a> | <a href="javascript:twttr.anywhere.signOut();">Sign out</a>');
        twitter(".comments > .add").tweetBox({
            label: 'What do you think about this article?',
            defaultContent: '#nettuts '
        });
    }
    

    If the user is logged in, a follow button should be there. Again, inside the conditional:

    twitter(".comments > .add").followButton("nettuts");
    

    Here is the whole conditional, rounding up all of the @Anywhere features.

    if(twitter.isConnected()){
        $(".comments > .add > .author").html('<img src="'+ twitter.currentUser.data('profile_image_url') +'" /> <a href="http://twitter.com/'+ twitter.currentUser.data('screen_name') +'">'+ twitter.currentUser.data('screen_name') +'</a> | <a href="javascript:twttr.anywhere.signOut();">Sign out</a>');
        twitter(".comments > .add").tweetBox({
            label: 'What do you think about this article?',
            defaultContent: '#nettuts '
        });
        twitter(".comments > .add").followButton("nettuts");
    }
    
    Final roundup

    Conclusion

    @Anywhere is obviously Twitter's response to Facebook Connect. They’re hoping to bring this platform to as many sites on the web as possible; and while the service is still young, and the documentation could definitely be improved, it’s definitely promising! Please show us what you’ve done with @Anywhere in your own websites!


  • Permalink for 'Exclusive Free PSD Templates for Premium Members'

    Exclusive Free PSD Templates for Premium Members

    Posted: April 21st, 2010, 1:48pm MDT by Jeffrey Way

    We’re going to try something a bit different this week for our Premium members. I have three exclusive, and fantastically designed PSD web templates available, built by the very talented Dany Duchaine. Help give back to Tuts+ by signing up for a Premium account.

    Each of these three PSD themes are fully-featured, containing at least five subpages. If you’re ready to build your next website, but aren’t much of a designer, one of these templates, exclusive to our Premium members, will surely do the trick!

    A&D A&D A&D Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Sign up for a Premium account!


  • Permalink for 'The Intricacy of Simplicity: CSS3'

    The Intricacy of Simplicity: CSS3

    Posted: April 21st, 2010, 10:37am MDT by Jeffrey Way

    Ever wondered how a particular effect was achieved in a web design, and, after zooming in several clicks, you found that the author added several subtle shadows, borders, gradients, etc? In the past, this was achieved simply by slicing out an image, and setting it as a background of some element. Luckily, with CSS3, we can be afforded much more flexibility. Now, while the code for such a simple effect might be a bit tedious, it’s well worth it, and that’s what we’ll review in today’s written and video quick tip!

    Video Version
    Subscribe to our YouTube page to watch all of the video tutorials!

    Rather watch this screencast on Screenr.com?

    Text Version

    It’s amazing that something this simple requires that much code, but, it’s not too rough, and can easily be abstracted away to a snippet for future use.

    Step 1. Create the Mark-up

    To make our project as cut-and-paste as possible, we’re only working with an empty div. Create a new index.html file, and paste in the following:

    <body>
         <div id="box">
    
    	</div>
    </body>
    
    Step 2. Create the Canvas

    Next, we’ll add some basic styling for the body element. This is just for the presentation, and can easily be removed. Within style tags in your header, add:

    /* Nothing special here. Just the canvas. */
    body {
    	width: 500px;
    	margin: 60px auto 0;
    	background: #666;
    }
    
    Body Styling Step 3. Styling the Box

    Now, we’ll create our box, supplying a width and height.

    #box {
    	/* Just a box */
    	width: 500px;
    	height: 500px;
    }
    
    Box Step 4. Rounded Corners

    We should all know about CSS rounded corners by now. Let’s go ahead and implement that.

    /* Rounded corners */
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    
    Rounded corners

    Note that we’re also supplying the final spec, of “border-radius,” in addition to Mozilla and Webkit’s versions.

    Step 5. Border Colors

    Mozilla offers a handy property, called “-moz-border-*-colors.” This allows us to set an infinite number of colors for a border. To achieve a subtle “double-border” effect, let’s implement this property.

    /* Set a base border and color */
    border: 2px solid white;
    
    /* Multiple border colors in Gecko */
    -moz-border-top-colors: #292929 white;
    -moz-border-right-colors: #292929 white;
    -moz-border-bottom-colors: #292929 white;
    -moz-border-left-colors: #292929 white;
    

    Note how the number of colors we supply are the same as the border width that we set at the beginning (2px). Also, don’t place commas after each hex value; I made that mistake at first!

    Border Colors Step 6. Compensating for Webkit

    To the best of my knowledge, webkit doesn’t currently support border-colors, though it’s possible that I’m wrong. If I am, please leave a comment and let me know! Anyhow, to mimic this effect as best as we can in Safari and Chrome, we’ll use box-shadow.

    /* Compensate for Webkit. Not as nice, but works. */
    -webkit-box-shadow: 0 -1px 2px #292929;
    

    Note that the provided values refer to the X offset, Y offset, blur, and shadow color, respectively. By passing -1px as the Y offset, we can push the shadow upwards.

    In Safari Step 7. CSS Background Gradients

    The final step is to supply a subtle background gradient for our box. However, we must be sure to provide a fallback solid color for the browsers that don’t support CSS gradients.

    /* Background subtle gradient, with fallback to solid color */
    background: #e3e3e3;
    background: -moz-linear-gradient(top, #a4a4a4, #e3e3e3);
    background: -webkit-gradient(linear, left top, left bottom, from(#a4a4a4), to(#e3e3e3));
    

    Unfortunately, Mozilla and Webkit don’t quite agree on the syntax for gradients, which makes the process extra irritating. If it’s too confusing, you can use a new service called CSS3 Please to auto generate each browser’s syntax; it’s very cool!

    Final Product You’re Done!

    It’s amazing; looking over our final image, it’s hard to tell what we actually did! But this is a good thing; subtlety is key in all aspects of design. Thanks for reading/viewing!

    Final Code
    /* Nothing special here. Just the canvas. */
    body {
    	width: 500px;
    	margin: 60px auto 0;
    	background: #666;
    }
    
    #box {
    	/* Just a box */
    	width: 500px;
    	height: 500px;
    
    	/* Rounded corners */
    	-moz-border-radius: 3px;
    	-webkit-border-radius: 3px;
    	border-radius: 3px;
    
    	border: 2px solid white;
    
    	/* Multiple border colors in Gecko */
    	-moz-border-top-colors: #292929 white;
    	-moz-border-right-colors: #292929 white;
    	-moz-border-bottom-colors: #292929 white;
    	-moz-border-left-colors: #292929 white;
    
    	/* Compensate for Webkit. Not as nice, but works. */
    	-webkit-box-shadow: 0 -1px 2px #292929;
    
    	/* Background subtle gradient, with fallback to solid color */
    	background: #e3e3e3;
    	background: -moz-linear-gradient(top, #a4a4a4, #e3e3e3);
    	background: -webkit-gradient(linear, left top, left bottom, from(#a4a4a4), to(#e3e3e3));
    }
    


  • Permalink for 'Integrating the Piecemaker 3D Gallery into your WordPress Theme'

    Integrating the Piecemaker 3D Gallery into your WordPress Theme

    Posted: April 21st, 2010, 9:07am MDT by Sean Corey

    This tutorial will show you how to successfully integrate the Piecemaker 3D Flash image rotator into your WordPress theme. We’ll also discuss setting up a custom admin panel which will make it super easy for your users to make customizations to the rotator.

    Piecemaker is a gorgeous, open-source, 3D Flash image rotator created by Björn Crüger from Modularweb. You can preview the piecemaker in action on Sansation, the first premium WordPress theme on ThemeForest to incorporate Piecemaker.

    Piecemaker Preview Brief Overview

    All of the files included in the ZIP file are already modified for you. We’ve also included a folder which has all of the default unmodified Piecemaker files. I recommend that you go check out the Piecemaker site and familiarize yourself with it before proceeding with the tutorial.

    Step 1. Modify the ActionScript

    The first step is to modify the ActionScript so that it’ll play nicely with WordPress. The ActionScript that comes with Piecemaker defines three values that the Piecemaker needs in order to function properly:

    • the XML Source
    • the CSS Source
    • the path to the images folder.

    The XML Source defines the Picemaker’s various settings and allows you to define images and their descriptions. The CSS file styles the Piecemaker’s description panels, and the images directory tells the Piecemaker where to pull the images from.

    Open up the FLA file named “piecemakerNoShadow.fla” and open the Actions window. In frame 1 you will see the actions below. Please note that you need Flash CS4 to open the source file.

    In order for the Piecemaker to work properly within our WordPress theme, we need to dynamically set these variables. To achieve this, we will be using FlashVars. FlashVars are variables the we’ll set within our WordPress page template that will get passed to the flash movie when the page loads. Go ahead and delete the default actions in frame 1 of the flash file, and replace them with the following code:

    stage.scaleMode = StageScaleMode.NO_SCALE;
    
    // Pull in the Flashvars
    var allFlashVars:Object = LoaderInfo(this.root.loaderInfo).parameters;
    
    // Set the required variables for piecemaker
    piecemaker.xmlSource = String(allFlashVars.xmlSource);
    piecemaker.cssSource = String(allFlashVars.cssSource);
    piecemaker.imageSource = String(allFlashVars.imageSource);
    piecemaker.dispatchEvent(new Event("properties"));
    

    The above ActionScript first loads in the FlashVars, and then replaces the default Piecemaker values with these new variables. Our Flash file is now all set to go. Publish the SWF and load your FTP client of choice.

    Step 2. Upload Files and Folders

    The next step is to upload the required files and folders into your WordPress theme’s directory. This tutorial assumes that you will be uploading everything directly into your theme’s main directory. Here is a list of the required items:

    • piecemakerCSS.css
    • piecemakerNoShadow.swf
    • piecemakerXML.xml
    • ‘images’ folder (with your images in it)
    • ’swfobject’ folder (plus contents)
    • piecemakerXML.php (needde for use with the custom admin panel)
    Step 3. Embed the SWF and set the FlashVars

    The next step is to embed the SWF movie into your WordPress page template. We’ll be using SWFObject 2 to embed the movie, and we’ll also define the three FlashVars that we referenced in step one.

    You first need to reference swfobject within the head of your page. To do so, open up your theme’s “header.php” file in your code editor of choice (mine’s BBEdit), and add the following code in the head of your page:

    <script type="text/javascript" src="<?php bloginfo('template_url'); ?>/swfobject/swfobject.js"></script>
    

    Next, open up the WordPress page template where you’d like the Piecemaker 3D Rotator to display, and paste the following code:

    <div id="flashcontent">
    <p>You need to <a href=" [www.adobe.com] target="_blank">upgrade your Flash Player</a> to version 10 or newer.</p>
    </div><!-- end flashcontent -->
    
    <script type="text/javascript">
    		var flashvars = {};
    		flashvars.xmlSource = "<?php bloginfo('template_url'); ?>/piecemakerXML.xml";
    		flashvars.cssSource = "<?php bloginfo('template_url'); ?>/piecemakerCSS.css";
    		flashvars.imageSource = "<?php bloginfo('template_url'); ?>/images";
    		var attributes = {};
    		attributes.wmode = "transparent";
    		swfobject.embedSWF("<?php bloginfo('template_url'); ?>/piecemakerNoShadow.swf", "flashcontent", "960", "610", "10", "<?php bloginfo('template_url'); ?>/swfobject/expressInstall.swf", flashvars, attributes);
    </script>
    
    Code Explaination

    The bulk of the code is just your standard swfobject code used to embed a flash movie onto any webpage. The important stuff we need to be concerned with are the FlashVars:

    flashvars.xmlSource = "<?php bloginfo('template_url'); ?>/piecemakerXML.xml";
    flashvars.cssSource = "<?php bloginfo('template_url'); ?>/piecemakerCSS.css";
    flashvars.imageSource = "<?php bloginfo('template_url'); ?>/images";
    

    Notice that we have named our FlashVars just as we defined them in the ActionScript in step on4. We are also using WordPress’ built-in bloginfo() function to reference the exact locations of the three required files.

    That’s it! Well, Sort of…

    The above steps will enable you to successfully deploy the Piecemaker 3D Image Rotator into your WordPress theme, but we’re going to take it a step further. In the following steps, we will discuss how to create a custom admin panel that will allow you to customize Piecemaker’s settings right from the WordPress back-end.

    If you’re not interested in setting up the admin panel, you can go over to the Piecemaker website to read the documentation and start making some really kick-awesome animations.

    Step 4. Create The Admin Panel

    We will not be covering how to create the entire admin panel from scratch. Instead, we’ll expand upon an already in-depth tutorial here on Nettuts: How to Create a Better WordPress Panel.

    Once you have followed that tutorial and you have your admin panel setup, please proceed to the next step.

    Step 5. Define Our New Options Panel

    We now need to add additional options to the admin panel you just created in the tutorial. Open your theme’s “functions.php” file, and replace the first chunk of code with the following:

    <?php
    $themename = "Nettuts";
    $shortname = "nt";
    
    $categories = get_categories('hide_empty=0&orderby=name');
    $wp_cats = array();
    foreach ($categories as $category_list ) {
           $wp_cats[$category_list->cat_ID] = $category_list->cat_name;
    }
    array_unshift($wp_cats, "Choose a category");
    $tween_types = array("linear","easeInSine","easeOutSine", "easeInOutSine", "easeInCubic", "easeOutCubic", "easeInOutCubic", "easeOutInCubic", "easeInQuint", "easeOutQuint", "easeInOutQuint", "easeOutInQuint", "easeInCirc", "easeOutCirc", "easeInOutCirc", "easeOutInCirc", "easeInBack", "easeOutBack", "easeInOutBack", "easeOutInBack", "easeInQuad", "easeOutQuad", "easeInOutQuad", "easeOutInQuad", "easeInQuart", "easeOutQuart", "easeInOutQuart", "easeOutInQuart", "easeInExpo", "easeOutExpo", "easeInOutExpo", "easeOutInExpo", "easeInElastic", "easeOutElastic", "easeInOutElastic", "easeOutInElastic", "easeInBounce", "easeOutBounce", "easeInOutBounce", "easeOutInBounce");
    

    The bulk of the above code is identical to the tutorial, but we’ve added a new array named $tween_types. This array holds all of the various animation effects that are available with PieceMaker. We will use this array to generate a dropdown list of the various animation effects in our custom options panel. You can check out the Tweener Documentation to review a visual representation of the various Piecemaker animation effects.

    Still within the functions.php file, add the following array below the ones you’ve already created in the tutorial.

    This will create a new sliding options panel similar to the ones you created in the tutorial. It’s a long bit of code, but it follows the same exact logic as the tutorial. We are simply creating variables for all of the different settings that we’ll need to define in the Piecemaker’s XML file. An important thing to note is that we made sure to define default values for each option (the values in ’std’ are the default values). There are a decent amount of settings for the Piecemaker and we don’t want to force our users to set up all those options if they don’t want to.

    array( "name" => "3D Rotator Options",
    "type" => "section"),
    array( "type" => "open"),
    
    array( "name" => "Segments",
    "desc" => "Number of segments in which the image will be sliced.",
    "id" => $shortname."_segments",
    "type" => "text",
    "std" => "9"),
    
    array( "name" => "Tween Time",
    "desc" => "Number of seconds for each element to be turned.",
    "id" => $shortname."_tween_time",
    "type" => "text",
    "std" => "3"),
    
    array( "name" => "Tween Delay",
    "desc" => "Number of seconds from one element starting to turn to the next element starting.",
    "id" => $shortname."_tween_delay",
    "type" => "text",
    "std" => "0.1"),
    
    array( "name" => "Tween Type",
    "desc" => "Type of animation transition.",
    "id" => $shortname."_tween_type",
    "type" => "select",
    "options" => $tween_types,
    "std" => "Choose a category"),
    
    array( "name" => "Z Distance",
    "desc" => "to which extend are the cubes moved on z axis when being tweened. Negative values bring the cube closer to the camera, positive values take it further away. A good range is roughly between -200 and 700.",
    "id" => $shortname."_z_distance",
    "type" => "text",
    "std" => "25"),
    
    array( "name" => "Expand",
    "desc" => "To which etxend are the cubes moved away from each other when tweening.",
    "id" => $shortname."_expand",
    "type" => "text",
    "std" => "9"),
    
    array( "name" => "Inner Color",
    "desc" => "Color of the sides of the elements in hex values (e.g. 0x000000 for black)",
    "id" => $shortname."_inner_color",
    "type" => "text",
    "std" => "0x000000"),
    
    array( "name" => "Text Background Color",
    "desc" => "Color of the description text background in hex values (e.g. 0xFF0000 for red)",
    "id" => $shortname."_text_background",
    "type" => "text",
    "std" => "0x666666"),
    
    array( "name" => "Text Distance",
    "desc" => "Distance of the info text to the borders of its background.",
    "id" => $shortname."_text_distance",
    "type" => "text",
    "std" => "25"),
    
    array( "name" => "Shadow Darkness",
    "desc" => "To which extend are the sides shadowed, when the elements are tweening and the sided move towards the background. 100 is black, 0 is no darkening.",
    "id" => $shortname."_shadow_darkness",
    "type" => "text",
    "std" => "25"),
    
    array( "name" => "Auto Play",
    "desc" => "Number of seconds to the next image when autoplay is on. Set 0, if you don't want autoplay.",
    "id" => $shortname."_autoplay",
    "type" => "text",
    "std" => "2"),
    
    array( "type" => "close"),
    
    Step 6. Update Our Page Template

    In this step, we need to slightly modify our WordPress page template from Step three. Instead of pointing our xmlSource to an XML file, we need to point it to a PHP file. By using a PHP file instead of an XML file, we can pull in all of the values that were set by the user in our custom options panel. It’s just the one line of code that needs to be replaced:

    flashvars.xmlSource = "<?php bloginfo('template_url'); ?>/piecemakerXML.php";
    
    Step 7. Generate our XML File with PHP

    We’re almost there! In this step, we’ll create the PHP file that we just referenced in the code above. This PHP file will be used to pull in all of the values from our custom options panel and generate the XML file that the Piecemaker needs in order to function properly. The code is somewhat lengthy, so I’ll try to break it up into more digestable chunks.

    Create a blank PHP file, name it “piecemakerXML.php”, and paste the following code at the start of the file:

    <?php require_once( '../../../wp-load.php' );
    $segments = get_option('nt_segments');
    $tweentime = get_option('nt_tween_time');
    $tweendelay = get_option('nt_tween_delay');
    $tweentype = get_option('nt_tween_type');
    $zdistance = get_option('nt_z_distance');
    $expand = get_option('nt_expand');
    $innercolor = get_option('nt_inner_color');
    $textbackground = get_option('nt_text_background');
    $textdistance = get_option('nt_text_distance');
    $shadow = get_option('nt_shadow_darknent');
    $autoplay = get_option('nt_autoplay');
    ?>
    
    • The first line loads WordPress into our PHP file. This allows us to have access to all of the default WordPress functions, as well as any values stored within our database.
    • The rest of the code pulls in the data from our custom options panel and stores those values into variables. We will use these variables to generate the rest of the Piecemaker’s settings.
    • Next, we need to set the content-type header so that the browser knows we are going to output XML content rather than the default text/html. We will also include some initial Piecemaker settings tags.

      <?php
      header("Content-type: text/xml");
      echo '<?xml version="1.0" encoding="utf-8" ?>
      <Piecemaker>
        <Settings>
      	<imageWidth>830</imageWidth>
      	<imageHeight>360</imageHeight>';
      

      We are now going to output the variables we stored into their correct XML tags, and close out the Piecemaker settings tag.

      echo '<segments>'. $segments . '</segments>';
      echo '<tweenTime>'. $tweentime . '</tweenTime>';
      echo '<tweenDelay>'. $tweendelay . '</tweenDelay>';
      echo '<tweenType>'. $tweentype . '</tweenType>';
      echo '<zDistance>'. $zdistance . '</zDistance>';
      echo '<expand>'. $expand . '</expand>';
      echo '<innerColor>'. $innercolor . '</innerColor>';
      echo '<textBackground>'. $textbackground . '</textBackground>';
      echo '<textDistance>'. $textdistance . '</textDistance>';
      echo '<shadowDarknent>' . $shadow . '</shadowDarknent>';
      echo '<autoplay>' . $autoplay .  '</autoplay>';
      echo '
      </Settings>
      

      The final step is to output the images that we want to include in the rotator along with their descriptions, and we’ll also close out the Piecemaker XML tag.

      <Image Filename="image1.jpg">
          <Text>
            <headline>Description Text</headline>
            <break>Ӂ</break>
            <paragraph>Here you can add a description text for every single slide.</paragraph>
            <break>Ӂ</break>
            <inline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam eu quam dolor, a venenatis nisl. Praesent scelerisque iaculis fringilla. Sed congue placerat eleifend.</inline>
            Ӂ<a href=" [themes.5-squared.com] target="_blank">hyperlinks</a>
          </Text>
        </Image>
      
        <Image Filename="image2.jpg">
          <Text>
            <headline>Description Text</headline>
            <break>Ӂ</break>
            <paragraph>Here you can add a description text for every single slide.</paragraph>
            <break>Ӂ</break>
            <inline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam eu quam dolor, a venenatis nisl. Praesent scelerisque iaculis fringilla. Sed congue placerat eleifend.</inline>
            Ӂ<a href=" [themes.5-squared.com] target="_blank">hyperlinks</a>
          </Text>
        </Image>
      
        <Image Filename="image3.jpg">
          <Text>
            <headline>Description Text</headline>
            <break>Ӂ</break>
            <paragraph>Here you can add a description text for every single slide.</paragraph>
            <break>Ӂ</break>
            <inline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam eu quam dolor, a venenatis nisl. Praesent scelerisque iaculis fringilla. Sed congue placerat eleifend.</inline>
            Ӂ<a href=" [themes.5-squared.com] target="_blank">hyperlinks</a>
          </Text>
        </Image>
      
        <Image Filename="image4.jpg">
          <Text>
            <headline>Description Text</headline>
            <break>Ӂ</break>
            <paragraph>Here you can add a description text for every single slide.</paragraph>
            <break>Ӂ</break>
            <inline>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam eu quam dolor, a venenatis nisl. Praesent scelerisque iaculis fringilla. Sed congue placerat eleifend.</inline>
            Ӂ<a href=" [themes.5-squared.com] target="_blank">hyperlinks</a>
          </Text>
        </Image>
      </Piecemaker>';
      ?>
      
      Conclusion

      I hope you learned something useful in this tutorial. By combining various different technologies, we’re able to add powerful functionality to our WordPress themes. More importantly, we made it easy for the average user to make customizations to our theme.


  • Permalink for '10 Kick-Ass Magento Templates'

    10 Kick-Ass Magento Templates

    Posted: April 20th, 2010, 9:17am MDT by Jeffrey Way

    I’m proud to announce that ThemeForest is now selling Magento eCommerce templates at cheap prices that any business or individual can afford. We’ve launched with thirty-five awesome Magento templates, but we’re just scratching the surface. By the end of the year, ThemeForest will be the premier location for buying and selling Magento templates! Here are some of the best that we’ve launched with.

    1. Woodrow Woodrow 2. Organic Organic 3. Acumen Acumen 4. Boho Boho 5. Media Store Media Store 6. Contemporary Design Contemporary Design 7. Tribeca Tribeca 8. Tecknica Tecknica 9. Gnarly Gnarly 10. Guise Guise

    So if you have a spare moment, and are in the market for an incredible Magento template, I hope you’ll stop by your neighborhood ThemeForest and take a look around! And don’t forget, if you’re a developer of eCommerce themes, now might be the perfect time to look into signing up for a free author account, and earning 40-70% of every sale you make!


  • Permalink for 'Magento for Designers: Part 3'

    Magento for Designers: Part 3

    Posted: April 20th, 2010, 8:17am MDT by Siddharth

    Magento is a stunningly powerful e-commerce platform. In this miniseries, we’ll learn how to get started with the platform, getting to know the terminologies, setting up a store and all related aspects of it and finally learn how to customize it to make it our very own.

    In this third part, we’ll focus on the process behind theming Magento: how to install themes, the various concepts you’ll need to understand to create a theme and the general file structure. Excited? Let’s get started!

    The Full Series A Quick Recap

    In the last part, we saw how to get your Magento store from installed to ready for deployment including how to set up your products, product categories, taxes, shipping, payment gateways and many more.

    Today, we’ll look at the basics of Magento theming. We’ll learn the general idea behind Magento themes, the various terminologies behind it and the basic structure of a theme.

    Magento Theme Basics

    First up, theming Magento isn’t really as hard as it is purported. It’s a little different from how WordPress or Joomla handles themes, yes, but definitely not difficult. All you need to know is a little know how to start theming like a pro!

    To make it brutally simple, a Magento theme is a collection of PHTML, CSS and JS files thrown in together along with XML files to define the structure. A PHTML file consists of regular HTML markup interspersed by PHP code for the functionality. In case, you’re confused, a random block of code looks like so:

    <div class="quick-access">
            <?php echo $this->getChildHtml('store_language') ?>
            <p class="welcome-msg"><?php echo $this->getWelcome()?></p>
            <?php echo $this->getChildHtml('topLinks') ?>
    </div>
    

    See? It’s really simple once you wrap your head around it. If you’ve worked with creating themes for other systems, great, you’ll pick this up rather quickly. If not, no worries, I’ll walk you through the entire process.

    Note that in Magento, the front end and the back end are skinned completely separately. I’m assuming most of you won’t need to skin the backend so I’ll stick to theming the front end alone.

    Installing a Theme

    Before we start, a number of people DMed me through Twitter/emailed me asking the same question: how to install a theme. I’ll talk about it first.

    There are two ways to install a Magento theme:

    • The traditional method where you can just copy the packaged theme to appropriate folder
    • Magento Connect

    I’ll talk briefly about both.

    Direct Upload/Copy

    The first method is the one you’re used to. Download a theme, upload it and done. But you’ll need to know where to upload since this works a little differently than you’d assume.

    Themes are packaged differently according to the source but at it’s core, you have 2 folders:

    • app
    • skin

    You can just drag these to the root of the installation and let it merge with the existing data.

    If by chance, you get the theme packaged as a collection of 3 folders, don’t worry.

    The folder containing the PHTML files and the one containing the XML files go into root/app/design/frontend/default/themename while the one containing the CSS files, images and other assets goes into root/skin/frontend/default/themename.

    Right now, this is all you need to do. I’ll explain why each part goes to a specific location later below. You can activate your theme now.

    Tutorial Image

    Navigate to System -> Design and click on Add Design Change.

    Tutorial Image

    Choose the theme you want, click on save and you’re done.

    Magento Connect

    Using Magento Connect is easier provided it is available there. Navigate to System ->Magento Connect -> Magento Connect Manager.

    After logging in, you’ll be asked to enter the extension key of the theme you want to install. Enter the key and wait for the system to do it’s thing.

    Tutorial Image Tutorial Image

    After it has downloaded the necessary files and placed them where they need to be, you can now activate the theme like before.

    Magento Design Concepts You Need to Master

    When working with Magento, there are a few design related concepts you need to wrap your mind around before you can even start modifying the default theme.

    Layouts

    Layouts is a clever, new idea in Magento. This system lets you define a page’s, any page’s, structure through properly formed XML tags.

    Essentially, you can dictate which section of the page goes where by changing just a few attributes in an XML file. Each view or module gets it’s layout specified by its own XML file.

    Layouts in Magento is a big topic and just a few paragraphs here won’t do it justice. Along the way, I’ll cover all the necessary information you need to build your own theme along with a detailed article on layouts to cover all the advanced things you can do with this functionality.

    For now, if you’re interested, here is a small snippet to get an idea of what layouts are:

    <block type="page/html_notices" name="global_notices" as="global_notices" template="page/html/notices.phtml" />
    
                <block type="page/html_header" name="header" as="header">
                    <block type="page/template_links" name="top.links" as="topLinks"/>
                    <block type="page/switch" name="store_language" as="store_language" template="page/switch/languages.phtml"/>
                    <block type="core/text_list" name="top.menu" as="topMenu"/>
                    <block type="page/html_wrapper" name="top.container" as="topContainer" translate="label">
                        <label>Page Header</label>
                        <action method="setElementClass"><value>top-container</value></action>
                    </block>
                </block>
    
                <block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
    
                <block type="core/text_list" name="left" as="left" translate="label">
                    <label>Left Column</label>
                </block>
    
                <block type="core/messages" name="global_messages" as="global_messages"/>
                <block type="core/messages" name="messages" as="messages"/>
    
    Templates

    Templates consist of PHTML files filled with regular HTML markup and PHP code. Similar to WordPress, you use a number of predefined methods to specify the output. Just like with other popular systems, important sections like the header, footer and the sidebar are placed in separate files and pulled in when necessary.

    You can have different templates for each view of Magento. For example, you can have different code for a wish list or a checkout page instead of using the same look for the entire site.

    Here is a piece of a template for the curious:

    <ul class="products-grid">
    
             <li class="item">
                  <p class="product-image">
                        <a href="<?php echo $_product->getProductUrl() ?>"
    		        title="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>">
                            <img src="<?php echo $this->helper('catalog/image')
    				         ->init($_product, 'small_image')
    				         ->resize(100, 100); ?>"
    		                          width="100" height="100"
    		                          alt="<?php echo $this->htmlEscape($this
    				         ->getImageLabel($_product, 'small_image')) ?>"
    		                          title="<?php echo $this->htmlEscape($this
    			          	 ->getImageLabel($_product, 'small_image')) ?>" />
                        </a>
                  </p>
                  <h5 class="product-name">
    				<a href="<?php echo $_product->getProductUrl() ?>"
    				title="<?php echo $this->htmlEscape($_product->getName()) ?>">
    				<?php echo $this->htmlEscape($_product->getName()) ?></a>
    	     </h5>
                    <?php echo $this->getReviewsSummaryHtml($_product, 'short') ?>
                    <?php echo $this->getPriceHtml($_product, true, '-new') ?>
    
                </li>
            <?php if ($i%$_columnCount==0 || $i==count($_products)): ?>
    </ul>
    

    Looks a little messy, I know but strip out the PHP parts and you’ll see how similar it is to other systems.

    Skins

    Skins are nothing but the CSS files, JavaScript files, images and other assets you’re using in the markup to create your design. Essentially all non PHP assets go here. Fonts for embedding? Some swanky flash demo? A spiffy piece of SVG? All of those fall under this category.

    Blocks

    Blocks are the integral building blocks of a theme and let you build your theme in a modular fashion.

    As part of layouts, this forms the backbone of Magento’s strong templating system. Blocks are essentially sections which you can move around using the XML mentioned above to modify how a page is presented.

    Blocks need to reference a relevant template file so that Magento can pull in the required file. A little confused? Here is an example.

    <block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
    

    We essentially define a new block, which template to load by specifying the type of block and a name. It’s a little different from what we’ve been used to but trust me you’ll get it once you get started developing. Either way, I’ll cover blocks a bit more in detail when we’re building our theme and still more I’ll do a full write up on layouts and blocks down the line so don’t worry if it doesn’t make complete sense now. Just get a general feel for the topics at hand.

    Structural Blocks

    A structural block defines the basic structure of a page. Think HTML 5 header, footer and aside sections. They were created for the sole purpose of visual demarcation of a design.

    Tutorial Image From the Magento docs Content Blocks

    Content blocks are similar to your regular container/wrapper DIV elements you use in a design. Just like with design, each content block contains a specific functionality or purpose. A menu in your header, a callout in the sidebar, legal clarifications in the footer all go into separate content blocks.

    Remember, content blocks are still blocks and map to a specific PHTML file to generate and render its HTML contents.

    Tutorial Image From the Magento docs Interface

    Mentioned finally because from a strict theming perspective of a beginner, this shouldn’t come into play for quite a while.

    To be simple, an interface is a named collection of themes you can leverage to define the look of your store.

    Important Locations to Keep in Mind Whilst Theming

    Just like other powerful software, Magento has a complex file structure. However, for theming along, you can narrow your focus down considerably.

    Tutorial ImageTutorial Image

    Here are the locations you’ll be working on when creating a theme:

    • root/app/design/frontend/default – The folder of the default interface. Aptly named default, by default. (Heh!)
    • root/app/design/frontend/default/Cirrus – The folder for the theme we will be building. I’ve named our theme, Cirrus
    • root/skin/frontend/default – The folder of the default interface.
    • root/skin/frontend/default/Cirrus – The folder where all the assets for our theme will be placed.
    A Theme’s Directory Structure

    Magento requires that your executable PHP content be placed seperately from your static assets which is why you have a separate skin directory on your root. While this may seem counter-productive at first, once you’ve slightly adapted your workflow, you’ll realize that this move increases the general security of your installation..

    Nevertheless, a theme is typically split into the following parts.

    • Layouts – root/app/design/frontend/default/Cirrus/layouts
    • Templates – root/app/design/frontend/default/Cirrus/templates
    • Skins – root/skin/frontend/default/Cirrus
    The [Second to] Last Word

    And we are done! We looked at the basic concepts behind theming Magento and managing themes. Hopefully this has been useful to you and you found it interesting. Since this is a rather new topic for a lot of readers I’ll be closely watching the comments section so chime in there if you’re having any doubts.

    Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!

    What We’ll Build in the Upcoming Parts

    So far, we’ve been dealing strictly theoretically with the platform. A necessity considering Magento’s size and scope. But now that we have all the basics nailed down we can move on to the fun part.

    Remember how when creating a skin for a CMS/generic system you always start from a skeleton and build outwards? Like Kubrick for WordPress? If you thought we were going to take one and start building a theme out of it, you thought wrong. No, sir. We’re going to build a custom, bare bones skin similar to the Blank skin completely from scratch. A skin you can use yourselves as a base for your own skin.

    All this and more in the upcoming parts. Stay tuned!

    The Full Series Purchase Magento Themes from ThemeForest ThemeForest

    Did you know that your friendly neighborhood ThemeForest sells premium quality Magento themes? Whether you’re a skilled Magento developer looking to start profiting from your efforts, or a buyer, hoping to build your first eCommerce store, we’ve got you covered!


  • Permalink for 'Quick Tip: HTML5 Features you Should be Using Right Now'

    Quick Tip: HTML5 Features you Should be Using Right Now

    Posted: April 19th, 2010, 10:13am MDT by Jeffrey Way

    With all this talk about HTML5 not being complete until 2022, many people disregard it entirely – which is a big mistake. In fact, there are a handful of HTML5 features that we can use in all our projects right now! Simpler, cleaner code is always a good thing. In today’s video quick tip, I’ll show you a handful of options.


    Subscribe to our YouTube page to watch all of the video tutorials!

    Or, watch this video on Screenr.com.


  • Permalink for 'Best of the Web: First Quarter'

    Best of the Web: First Quarter

    Posted: April 19th, 2010, 7:41am MDT by Andrew Burgess

    It’s hard to believe that 2010 is already one quarter over. With a seemingly never-ending supply of developer goodness, it’s hard not to miss some incredible articles. To catch up, check out our list of top articles from January, February, and March. Don’t forget to share your own favorites within comments!

    January 2010 Scheduling Tasks with Cron Jobs

    Cron Jobs are used for scheduling tasks to run on the server. They’re most commonly used for automating system maintenance or administration. However, they are also relevant to web application development. There are many situations when a web application may need certain tasks to run periodically. Today we are going to explore the fundamentals of Cron Jobs.

    How to Make All Browsers Render HTML5 Mark-up Correctly — Even IE6

    HTML 5 provides some great new features for web designers who want to code readable, semantically-meaningful layouts. However, support for HTML 5 is still evolving, and Internet Explorer is the last to add support. In this tutorial, we’ll create a common layout using some of HTML 5’s new semantic elements, then use JavaScript and CSS to make our design backwards-compatible with Internet Explorer. Yes, even IE 6.

    Getting Started with XSL(T)

    In this tutorial, we will adventure into the world of XSL(T) and explain what it is, how to pull data from an XML document, basic iteration and basic login and conditional statements.

    jQuery 1.4 Released: The 15 New Features you Must Know

    jQuery 1.4 was recently released. This wasn’t simply a maintenance release as some had speculated; there are many new features, enhancements and performance improvements included in 1.4! This post covers the new features and enhancements that you may find beneficial.
    You can download jQuery 1.4 right now, here: [code.jquery.com]

    Zero-to-Sixty: Creating and Deploying a Rails App in Under an Hour

    Give me an hour of your time, and I’ll take you on a fly by of the Ruby on Rails framework. We’ll create controllers, models, views, add admin logins, and deploy using Heroku’s service in under an hour! In this article we’ll create a simple bookshelf application where you can add books and write thoughts about them. Then we’ll deploy the application in just a few minutes. So buckle up because this article moves fast!

    This article assumes that you may know what Ruby on Rails is, but not exactly how it works. This article doesn’t describe in-depth how each step works, but it does describe what we need to do, then the code to do that.

    10 Tips for Better Print Style Sheets

    Print style sheets have been somewhat forgotten, and yet they remain important all the same. Many people print out articles to read while traveling or when they have no access to the Internet.
    Print style sheets have definite benefits. For example, reading on paper is less tiring on the eyes than reading on screen.

    Also, following tutorials is easier if you have one next to you, with your code editor open on the screen; that way, you don’t have to switch windows every time to look something up.

    In this article we’ll point out 10 easy tips that will help you create better print style sheets.

    Unleashing the Power of Website Analytics

    Most people use web analytics—you’d have to be crazy not to—especially with such powerful free solutions out there. However, for many people, analyzing their stats goes no further than rejoicing at having a few more visitors and repeating the figures to potential advertisers.

    But analytics, used properly, is so much more – it’s a marketing tool, an error checker, a usability tool, an ROI calculator, an eCommerce tracker, an ad tool and the list goes on.

    So we’re going to take a look at the basic ways of getting more from your analytics.

    How To Create an IE-Only Stylesheet

    If you read this blog, there is a 99% chance you’ve had a hair-pulling experience with IE. But if you are worth your salt as a CSS coder, you should be able to deal with it. I am of the opinion that you can handle anything IE can throw at you without the use of hacks. Hacks are dangerous, since they are based on non-standard exploits, you can’t predict how they are going to behave in future browsers. The tool of choice for fighting IE problems is the conditional stylesheet. IE provides comment tags, supported all the way up to the current IE 8 to target specific versions, as well as greater-than/less-than stuff for targeting multiple versions at once.

    Hot Effect: MooTools Drag Opacity

    As you should already know, the best visual features of a website are usually held within the most subtle of details. one simple trick that usually makes a big different is the use of opacity and fading. another awesome mootools functionality is dragging. why not double the awesomeness of element dragging by adding fading?

    Tips for Coding and Designing Usable Web Forms

    The web form has been one of the most discussed elements in web design for more than ten years now. We can’t help it. Call-to-action functionality often leads users to a form; purchases are made using forms; users register or subscribe using forms — the uses for forms are endless.

    While it is fairly easy to slap together a form in HTML, it’s not as easy to code, style, and design your form in a manner that makes it usable and accessible to the majority of users. Since forms play such a large role in website conversions and success rates, the tips below, as well as the resources provided at the end of this article, should prove valuable for developers creating and coding web forms.

    February 2010 24 Best Practices for AJAX Implementations

    Implementing AJAX technology can be a hit or miss thing. Do it well and you’ll have users raving over the slickness it provides to the general user experience while if you mess it up, you’ll be at the receiving end of their wrath. Here are 24 tips to guide you with implementing AJAX technology within your web application.

    How to Test your JavaScript Code with QUnit

    QUnit, developed by the jQuery team, is a great framework for unit testing your JavaScript. In this tutorial, I’ll introduce what QUnit specifically is, and why you should care about rigorously testing your code.

    How to Create a Better WordPress Options Panel

    Today, we’ll go through the entire process of creating an admin options panel for a WordPress theme, using the excellent WooFramework as an example. Then, we’ll take things a step further, as we implement jQuery to improve some of the functionality.

    CodeIgniter from Scratch, day 8, day 9, and day 10

    Three new episodes to the “CodeIgniter from Scratch” Series came out in February. If you use this framework, you’ll be sure to learn a lot from these screencasts!

    Design a Prettier Web Form with CSS 3

    Thanks to advanced CSS properties, such as gradients and shadows, it’s now quite easy to turn a dull web form into something beautiful – with minimal effort. I’ll show you how in today’s tutorial!

    Create an Animated Sliding Button Using MooTools

    Buttons (or links) are usually the elements on our sites that we want to draw a lot of attention to. Unfortunately many times they end up looking the most boring. You don’t have to let that happen though! I recently found a Tympanus post which provided a great method for making button have an unexpected pop. Here’s a quick tutorial on how to duplicate that look using MooTools.

    How nth-child Works

    There is a CSS selector, really a pseudo-selector, called nth-child. Here is an example of using it:

    ul li:nth-child(3n+3) {
      color: #ccc;
    }
    

    What the above CSS does, is select every third list item inside unordered lists. That is, the 3rd, 6th, 9th, 12th, etc. But how does that work? And what other kinds of things can you do with nth-child? Let’s take a look.

    Share Feedback with Twitter and the Bit.ly API

    Regular blog readers probably notice the wide range of social media “hare this” links found on most sites. With everyone from CNN to ESPN integrating ways of sharing content, one of the most popular techniques is using a URL shortener to neaten up and condense the link.

    Today we’re going to explore this idea of sharing content a little bit more. Sharing links to content is just one piece of the social media equation. Capturing the response to it is quite another.

    The Life, Times (and Death?) of Internet Explorer 6

    In recent years Internet Explorer 6 has become the browser web designers love to hate. Security issues, JavaScript errors and inexplicable CSS rendering quirks have made it the brunt of many jokes. With IE6 in its twilight and big companies like Google dropping support, it seems like a good time …

    How iPad Affects the Way we Design Websites?

    The iPad has received mixed reviews. While the geeks (people like you and me) have looked at it with disdain for being “just” what we expected, the media publishing industry (read print media) has seen it as the salvation they had been waiting for. Whether the iPad is able to change the world or not, is not the issue of this article. But the fact of the matter is that it is here and sooner or later we need to learn to design the web keeping it in our minds. So what are the things we need to consider?

    March 2010 How to Create an Infinite Scrolling Web Gallery

    When working my way through a web gallery, I find it annoying when I must change pages; so in today’s tutorial, we will learn how to create an auto-generating, one-page, infinite scrolling gallery with PHP and AJAX. Let’s get started!

    MVC for Noobs

    Model-View-Controller (MVC) is probably one of the most quoted patterns in the web programming world in recent years. Anyone currently working in anything related to web application development will have heard or read the acronym hundreds of times. Today, we’ll clarify what MVC means, and why it has become so popular.

    Image Resizing Made Easy with PHP

    Ever wanted an all purpose, easy to use method of resizing your images in PHP? Well that’s what PHP classes are for—reusable pieces of functionality that we call to do the dirty work behind the scenes. We’re going to learn how to create our own class that will be well constructed, as well as expandable. Resizing should be easy. How easy? How about three steps!

    How to Build a Lava-Lamp Style Navigation Menu

    A couple weeks ago, I created a screencast that demonstrated how to build a three-level navigation menu. In a response email, one of our readers requested a tutorial on how to build a lava-lamp style menu. Luckily, it’s quite a simple task, especially when using a JavaScript library. We’ll build one from scratch today.

    Uncovering jQuery’s Hidden Features

    jQuery is not always as it appears. There’s a lot of cool stuff going on under the surface, and there are many methods just waiting to be discovered, and many potential usages of jQuery’s API that you may not have considered before. In this article I’ll be taking you through a few of the not-so-obvious things I’ve discovered about jQuery.

    3D Text Tower

    Have you seen David Desandro’s site? It’s pretty slick. His footer is especially fun. The technique is clever in it’s simplicity. Let’s take a look.

    jQuery Dropdown Navigation in WordPress

    Today, we will learn how to enhance you WordPress in a whole new way. Multi-Level or Multi-Dimensional navigation menus can offer your theme and users 2 new things. One, add a nice new type of effect to enhance your theme. Two, allow the users to find things more easily. We will start off by making a HTML version, then making it compatible with WordPress.

    Labelled Blocks, Useful?

    I was recently playing around with labels and blocks (as one does) and found that they could be used as a way to annotate/contain chunks of JavaScript without using ugly comments (or abstraction?). I can see its appeal—it offers a sense of containment that is hard to get with just comments.

    Creating Unique Styles for WordPress Pages

    In WordPress 2.8, there is one small but very useful feature, both for WP web developers, and for bloggers. This is an opportunity to change the appearance of any individual page or group of pages without the need to write either the functions/conditions on php or install plugins. All you need to do is simply add your desired style to your css file.

    How to Find and Remove Broken Links in Your Website

    Broken links are links that lead to pages that do not exist. When clicking on a broken link, the page you land on is called a 404 error page, a standard HTTP response that indicates that the requested URL doesn’t exist.

    What do you do when you happily surf the web and suddenly come across a 404 error? For most of us, the immediate response would be to simply leave the current site in favor of another one because both people and search engines consider broken links as unprofessional.

    That’s it!

    Of course, be sure to share the best articles you’ve seen in 2010 so far in the comments!


  • Permalink for 'Magento 1.3: PHP Developer’s Guide – Free Copies'

    Magento 1.3: PHP Developer’s Guide – Free Copies

    Posted: April 18th, 2010, 9:00am MDT by Jeffrey Way

    Magento is one of the most popular PHP eCommerce solutions available for web developers. In their own words, it’s the fastest growing eCommerce platform in the world. Packt Publishing has generously donated a handful of copies of their latest Magento book, called “Magento 1.3: PHP Developer’s Guide”. Given that ThemeForest and CodeCanyon have both begun selling Magento themes and extensions, respectively, now would be a fantastic time to get on board with your training! To win a free copy, simply leave a comment, and I’ll randomly choose and contact some of you.


    Magento 1.3 Developer's Guide

    “Magento is the most powerful e-commerce solution around and has gained popularity in a short period of time. You can create and manage online stores using the extensive suite of powerful tools it offers. However, because of its powerful features, developing with Magento can be easier said than done.

    This book will show you how to develop better and do more with the Magento. You will be able to extend and customize modules for the Magento system without editing the core system code. It will show you how to create both basic and advanced functionality modules for your store and help you turn your ideas for extending Magento into reality by building modules from scratch.”

    Thanks so much to Packt Publishing for always helping out on Nettuts+!


  • Permalink for 'Advanced Regular Expression Tips and Techniques'

    Advanced Regular Expression Tips and Techniques

    Posted: April 16th, 2010, 7:45am MDT by Burak Guzel

    Regular Expressions are the Swiss Army knife for searching through information for certain patterns. They have a wide arsenal of tools, some of which often go undiscovered or underutilized. Today I will show you some advanced tips for working with regular expressions.

    Adding Comments

    Sometimes regular expressions can become complex and unreadable. A regular expression you write today may seem too obscure to you tomorrow even though it was your own work. Much like programming in general, it is a good idea to add comments to improve the readability of regular expressions.

    For example, here is something we might use to check for US phone numbers.

    preg_match("/^(1[-\s.])?(\()?\d{3}(?(2)\))[-\s.]?\d{3}[-\s.]?\d{4}$/",$number)
    

    It can become much more readable with comments and some extra spacing.

    preg_match("/^
    
    			(1[-\s.])?	# optional '1-', '1.' or '1'
    			( \( )?		# optional opening parenthesis
    			\d{3}		# the area code
    			(?(2) \) )	# if there was opening parenthesis, close it
    			[-\s.]?		# followed by '-' or '.' or space
    			\d{3}		# first 3 digits
    			[-\s.]?		# followed by '-' or '.' or space
    			\d{4}		# last 4 digits
    
    			$/x",$number);
    

    Let’s put it within a code segment.

    $numbers = array(
    "123 555 6789",
    "1-(123)-555-6789",
    "(123-555-6789",
    "(123).555.6789",
    "123 55 6789");
    
    foreach ($numbers as $number) {
    	echo "$number is ";
    
    	if (preg_match("/^
    
    			(1[-\s.])?	# optional '1-', '1.' or '1'
    			( \( )?		# optional opening parenthesis
    			\d{3}		# the area code
    			(?(2) \) )	# if there was opening parenthesis, close it
    			[-\s.]?		# followed by '-' or '.' or space
    			\d{3}		# first 3 digits
    			[-\s.]?		# followed by '-' or '.' or space
    			\d{4}		# last 4 digits
    
    			$/x",$number)) {
    
    		echo "valid\n";
    	} else {
    		echo "invalid\n";
    	}
    }
    
    /* prints
    
    123 555 6789 is valid
    1-(123)-555-6789 is valid
    (123-555-6789 is invalid
    (123).555.6789 is valid
    123 55 6789 is invalid
    
    */
    

    The trick is to use the ‘x’ modifier at the end of the regular expression. It causes the whitespaces in the pattern to be ignored, unless they are escaped (\s). This makes it easy to add comments. Comments start with ‘#’ and end at a newline.

    Using Callbacks

    In PHP preg_replace_callback() can be used to add callback functionality to regular expression replacements.

    Sometimes you need to do multiple replacements. If you call preg_replace() or str_replace() for each pattern, the string will be parsed over and over again.

    Let’s look at this example, where we have an e-mail template.

    $template = "Hello [first_name] [last_name],
    
    Thank you for purchasing [product_name] from [store_name].
    
    The total cost of your purchase was [product_price] plus [ship_price] for shipping.
    
    You can expect your product to arrive in [ship_days_min] to [ship_days_max] business days.
    
    Sincerely,
    [store_manager_name]";
    
    // assume $data array has all the replacement data
    // such as $data['first_name'] $data['product_price'] etc...
    
    $template = str_replace("[first_name]",$data['first_name'],$template);
    $template = str_replace("[last_name]",$data['last_name'],$template);
    $template = str_replace("[store_name]",$data['store_name'],$template);
    $template = str_replace("[product_name]",$data['product_name'],$template);
    $template = str_replace("[product_price]",$data['product_price'],$template);
    $template = str_replace("[ship_price]",$data['ship_price'],$template);
    $template = str_replace("[ship_days_min]",$data['ship_days_min'],$template);
    $template = str_replace("[ship_days_max]",$data['ship_days_max'],$template);
    $template = str_replace("[store_manager_name]",$data['store_manager_name'],$template);
    
    // this could be done in a loop too,
    // but I wanted to emphasize how many replacements were made
    

    Notice that each replacement has something in common. They are always strings enclosed within square brackets. We can catch them all with a single regular expression, and handle the replacements in a callback function.

    So here is the better way of doing this with callbacks:

    // ...
    
    // this will call my_callback() every time it sees brackets
    $template = preg_replace_callback('/\[(.*)\]/','my_callback',$template);
    
    function my_callback($matches) {
    	// $matches[1] now contains the string between the brackets
    
    	if (isset($data[$matches[1]])) {
    		// return the replacement string
    		return $data[$matches[1]];
    	} else {
    		return $matches[0];
    	}
    }
    

    Now the string in $template is only parsed by the regular expression once.

    Greedy vs. Ungreedy

    Before I start explaining this concept, I would like to show an example first. Let’s say we are looking to find anchor tags in an html text:

    $html = 'Hello World!';
    
    if (preg_match_all('/.*/',$html,$matches)) {
    
    	print_r($matches);
    
    }
    

    The result will be as expected:

    /* output:
    Array
    (
        [0] => Array
            (
                [0] => World!
            )
    
    )
    */
    

    Let’s change the input and add a second anchor tag:

    $html = 'Hello
    World!';
    
    if (preg_match_all('/.*/',$html,$matches)) {
    
    	print_r($matches);
    
    }
    
    /* output:
    Array
    (
        [0] => Array
            (
                [0] => Hello
                [1] => World!
    
            )
    
    )
    */
    

    Again, it seems to be fine so far. But don’t let this trick you. The only reason it works is because the anchor tags are on separate lines, and by default PCRE matches patterns only one line at a time (more info on: ‘m’ modifier). If we encounter two anchor tags on the same line, it will no longer work as expected:

    $html = 'Hello World!';
    
    if (preg_match_all('/.*/',$html,$matches)) {
    
    	print_r($matches);
    
    }
    
    /* output:
    Array
    (
        [0] => Array
            (
                [0] => Hello World!
    
            )
    
    )
    */
    

    This time the pattern matches the first opening tag, and last opening tag, and everything in between as a single match, instead of making two separate matches. This is due to the default behavior being “greedy”.

    “When greedy, the quantifiers (such as * or +) match as many character as possible.”

    If you add a question mark after the quantifier (.*?) it becomes “ungreedy”:

    $html = 'Hello World!';
    
    // note the ?'s after the *'s
    if (preg_match_all('/.*?/',$html,$matches)) {
    
    	print_r($matches);
    
    }
    
    /* output:
    Array
    (
        [0] => Array
            (
                [0] => Hello
                [1] => World!
    
            )
    
    )
    */
    

    Now the result is correct. Another way to trigger the ungreedy behavior is to use the U pattern modifier.

    Lookahead and Lookbehind Assertions

    A lookahead assertion searches for a pattern match that follows the current match. This might be explained easier through an example.

    The following pattern first matches for ‘foo’, and then it checks to see if it is followed by ‘bar’:

    $pattern = '/foo(?=bar)/';
    
    preg_match($pattern,'Hello foo'); // false
    preg_match($pattern,'Hello foobar'); // true
    

    It may not seem very useful, as we could have simply checked for ‘foobar’ instead. However, it is also possible to use lookaheads for making negative assertions. The following example matches ‘foo’, only if it is NOT followed by ‘bar’.

    $pattern = '/foo(?!bar)/';
    
    preg_match($pattern,'Hello foo'); // true
    preg_match($pattern,'Hello foobar'); // false
    preg_match($pattern,'Hello foobaz'); // true
    

    Lookbehind assertions work similarly, but they look for patterns before the current match. You may use (?< for positive assertions, and (?<! for negative assertions.

    The following pattern matches if there is a ‘bar’ and it is not following ‘foo’.

    $pattern = '/(?<!foo)bar/';
    
    preg_match($pattern,'Hello bar'); // true
    preg_match($pattern,'Hello foobar'); // false
    preg_match($pattern,'Hello bazbar'); // true
    
    Conditional (If-Then-Else) Patterns

    Regular expressions provide the functionality for checking certain conditions. The format is as follows:

    (?(condition)true-pattern|false-pattern)
    
    or
    
    (?(condition)true-pattern)
    

    The condition can be a number. In which case it refers to a previously captured subpattern.

    For example we can use this to check for opening and closing angle brackets:

    $pattern = '/^()$/';
    
    preg_match($pattern, ''); // true
    preg_match($pattern, ''); // false
    preg_match($pattern, 'hello'); // true
    

    In the example above, ‘1′ refers to the subpattern (

    The condition can also be an assertion:

    // if it begins with 'q', it must begin with 'qu'
    // else it must begin with 'f'
    $pattern = '/^(?(?=q)qu|f)/';
    
    preg_match($pattern, 'quake'); // true
    preg_match($pattern, 'qwerty'); // false
    preg_match($pattern, 'foo'); // true
    preg_match($pattern, 'bar'); // false
    
    Filtering Patterns

    There are various reasons for input filtering when developing web applications. We filter data before inserting it into a database, or outputting it to the browser. Similarly, it is necessary to filter any arbitrary string before including it in a regular expression. PHP provides a function named preg_quote to do the job.

    In the following example we use a string that contains a special character (*).

    $word = '*world*';
    
    $text = 'Hello *world*!';
    
    preg_match('/'.$word.'/', $text); // causes a warning
    preg_match('/'.preg_quote($word).'/', $text); // true
    

    Same thing can be accomplished also by enclosing the string between \Q and \E. Any special character after \Q is ignored until \E.

    $word = '*world*';
    
    $text = 'Hello *world*!';
    
    preg_match('/\Q'.$word.'\E/', $text); // true
    

    However, this second method is not 100% safe, as the string itself can contain \E.

    Non-capturing Subpatterns

    Subpatterns, enclosed by parentheses, get captured into an array so that we can use them later if needed. But there is a way to NOT capture them also.

    Let’s start with a very simple example:

    preg_match('/(f.*)(b.*)/', 'Hello foobar', $matches);
    
    echo "f* => " . $matches[1]; // prints 'f* => foo'
    echo "b* => " . $matches[2]; // prints 'b* => bar'
    

    Now let’s make a small change by adding another subpattern (H.*) to the front:

    preg_match('/(H.*) (f.*)(b.*)/', 'Hello foobar', $matches);
    
    echo "f* => " . $matches[1]; // prints 'f* => Hello'
    echo "b* => " . $matches[2]; // prints 'b* => foo'
    

    The $matches array was changed, which could cause the script to stop working properly, depending on what we do with those variables in the code. Now we have to find every occurence of the $matches array in the code, and adjust the index number accordingly.

    If we are not really interested in the contents of the new subpattern we just added, we can make it ‘non-capturing’ like this:

    preg_match('/(?:H.*) (f.*)(b.*)/', 'Hello foobar', $matches);
    
    echo "f* => " . $matches[1]; // prints 'f* => foo'
    echo "b* => " . $matches[2]; // prints 'b* => bar'
    

    By adding ‘?:’ at the beginning of the subpattern, we no longer capture it in the $matches array, so the other array values do not get shifted.

    Named Subpatterns

    There is another method for preventing pitfalls like in the previous example. We can actually give names to each subpattern, so that we can reference them later on using those names instead of array index numbers. This is the format: (?Ppattern)

    We could rewrite the first example in the previous section, like this:

    preg_match('/(?Pf.*)(?Pb.*)/', 'Hello foobar', $matches);
    
    echo "f* => " . $matches['fstar']; // prints 'f* => foo'
    echo "b* => " . $matches['bstar']; // prints 'b* => bar'
    

    Now we can add another subpattern, without disturbing the existing matches in the $matches array:

    preg_match('/(?PH.*) (?Pf.*)(?Pb.*)/', 'Hello foobar', $matches);
    
    echo "f* => " . $matches['fstar']; // prints 'f* => foo'
    echo "b* => " . $matches['bstar']; // prints 'b* => bar'
    
    echo "h* => " . $matches['hi']; // prints 'h* => Hello'
    
    Don’t Reinvent the Wheel

    Perhaps it’s most important to know when NOT to use regular expressions. There are many situations where you can find existing utilities than you can use instead.

    Parsing [X]HTML

    A poster at Stackoverflow has a brilliant explanation on why we should not use regular expressions to parse [X]HTML.

    …dear lord help us how can anyone survive this scourge using regex to parse HTML has doomed humanity to an eternity of dread torture and security holes using regex as a tool to process HTML establishes a breach between this world and the dread realm of corrupt entities…

    Joking aside, it is a good idea to take some time and figure out what kind of XML or HTML parsers are available, and how they work. For example, PHP offers multiple extensions related to XML (and HTML).

    Example: Getting the second link url in an HTML page

    $doc = DOMDocument::loadHTML('
    	<html>
    	<body>Test
    		<a href="http://www.nettuts.com">First link</a>
    		<a href="http://net.tutsplus.com">Second link</a>
    	</body>
    	</html>
    ');
    
    echo $doc->getElementsByTagName('a')
    		->item(1)
    		->getAttribute('href');
    
    // prints: [net.tutsplus.com] 
    Validating Form Input

    Again, you can use existing functions to validate user inputs, such as form submissions.

    if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    
    	$errors []= "Please enter a valid e-mail.";
    }
    
    // get supported filters
    print_r(filter_list());
    
    /* output
    Array
    (
        [0] => int
        [1] => boolean
        [2] => float
        [3] => validate_regexp
        [4] => validate_url
        [5] => validate_email
        [6] => validate_ip
        [7] => string
        [8] => stripped
        [9] => encoded
        [10] => special_chars
        [11] => unsafe_raw
        [12] => email
        [13] => url
        [14] => number_int
        [15] => number_float
        [16] => magic_quotes
        [17] => callback
    )
    */
    

    More info: PHP Data Filtering

    Other

    Here are some other utilities to keep in mind, before using regular expressions:

    Thanks so much for reading!


  • Permalink for 'Color Inspiration: Wonderful Uses of Beige'

    Color Inspiration: Wonderful Uses of Beige

    Posted: April 15th, 2010, 9:53am MDT by Callum Chapman

    Beige and tan are most often used in websites simply as background colors. They’re commonly seen used in paper textures, grunge sites, or, occasionally, as a solid-colored background. The advantage is that, because they’re neutral, they can easily be combined with any number of other colors without clashing.

    The websites shown below offer a pretty complete picture of how beige and tan are used in today’s website designs. There are twenty five sites included, but please feel free to share more within the comments.

    The Theme Foundry All For Design James Charlick True Design Advuli Eighty Two Design Sinopse InkByte Infinitum I am Docto Tenth Time Make Film Work Pixelcraft Mr. Simon Collison Giantpea Noora Katto Grafikas ONETWENTYSIX Carol Rivello Cooper Graphic Design People 82 Christopher Barrett – Photographer Mutt Ink Sprocket House E3Solutions


  • Permalink for 'Combining Modern CSS3 and HTML5 Techniques'

    Combining Modern CSS3 and HTML5 Techniques

    Posted: April 14th, 2010, 8:15pm MDT by Jeffrey Way

    Just because some techniques don’t work in decade old browsers doesn’t mean that you shouldn’t be learning everything you can! Stay on the cutting edge, as we use everything from CSS shadows and animations, to HTML 5 mark-up and local storage, to utilizing jQuery to work with the Picasa API. We’ll also take advantage of the excellent jQuery library, and review some best practices when coding.

    Give back to Nettuts and sign up for a Premium membership!

    Preview You’ll Learn About:
    • HTML5 Mark-up that you can use in all your projects today
    • CSS transitions and shadows
    • Making IE understand HTML5 mark-up
    • Working with the Picasa API, combined with jQuery’s $.getJSON
    • Best practices when coding
    • How to take advantage of features in the yet to be released Firefox 3.7
    • Drag and Drop with jQuery UI
    • And plenty more in this in depth video tutorial
    Screenshot
    Screenshot Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Give back to Nettuts and sign up for a Premium membership!


  • Permalink for 'Quick Tip: Understanding CSS Specificity'

    Quick Tip: Understanding CSS Specificity

    Posted: April 14th, 2010, 3:05pm MDT by Andrew Burgess

    The “C” in CSS stands for cascading. This means that that style rules that show up later in the stylesheet will override rules which appear earlier. But this isn’t always the case. There’s something else you have to take into consideration, as well: specificity. In this quick tip, I’ll show you how to do just that.

    Specificity Rules

    CSS Specificity is basically this: the more specific your selector is, the more precedence it will have. To figure out which selectors are worth more, use this system:

    • Give each HTML element selector 1 point. Example: p
    • Give each class selector 10 points. Example: .column
    • Give each id selector 100 point. Example: #wrap
    • Add up the points for each piece of the selector to get the full value of the selector.
    For Example
    #test { background: red; } /* specificity : 100 */
    
    .item p { background: green; } /* specificity : 10 + 1 = 11 */
    
    p { background: orange; } /* specificity : 1  */
    
    body #wrap p { background: yellow; } /* specificity : 1 + 100 + 1 = 102 */
    


  • Permalink for 'Visual Database Creation with MySQL Workbench'

    Visual Database Creation with MySQL Workbench

    Posted: April 14th, 2010, 1:19pm MDT by Pablo Pastor

    In today’s tutorial, you’ll learn how to use a visual database modeling utility to draw a database diagram and automatically generate SQL. Specifically, we’ll review how to use MySQL Workbench, a cross-platform, visual database design tool.

    What is MySQL Workbench?

    MySQL Workbench is a powerful tool developed by MySQL with three primary areas of functionality:

    • SQL Development: Replaces MySQL query browser. Allows the user to connect to an existing database and edit and execute SQL queries.
    • Data Modeling: Complete visual database design and modeling.
    • Database Administration: Replaces MySQL administrator. Graphic interface to start/stop servers, create user accounts, edit configuration files, etc.

    In this tutorial, we’ll focus on the Data Modeling aspect to create a database from scratch, and then have just a quick look at the SQL editor to execute our generated SQL script and create the database within MySQL.

    MySQL Workbench is available for Windows, Linux and Mac OSX. There are two different editions: the Community OSS Edition and the commercial Standard Edition. The community edition is Open Source and GPL licensed, as you’d expect. It’s fully functional, and is the one we’ll be using in this article. The commercial edition adds some extra functionalities, such as schema and model validation or documentation generation.

    Note: this tutorial is based on the Community OSS Edition version 5.2 (5.2.16), currently in beta release at the time of the writing (April 2010).

    Planning our Database

    To learn how to use MySQL Workbench, we’ll use a very simple database for online classes as an example. Suppose a group of teachers want to offer online classes for several subjects, using Skype or any other video conferencing software. For our little project, we have decided that we need to store the following information:

    When drawing our diagram, we will need to know the relationships between these groups of data as well; so we better think about that now!

    • One teacher can teach many subjects
    • One subject can be taught by many teachers
    • Each class has only one teacher
    • One teacher can teach many classes
    • One student can attend many classes
    • One class has many students
    • One class may have several hours (in a week)
    • At one particular day and hour, there may be several classes
    • A class is about one subject
    • One subject may be taught in many classes

    At this point, we have all the information we need to meet the star of this show…

    Send in MySQL Workbench

    It’s time to launch Workbench. In the data modeling part of the home screen, we click ‘Create new EER Model’, and the following screen appears:

    When we create a new database model, it contains the default mydb schema. We can rename it and use it as our DB schema. A database model can have several different schemas.

    The catalog on the right will show every element in our schema, and allow us to drag and drop elements to diagrams if needed.

    Having the separate sections for Physical Schemata and EER Diagrams, and the possibility to include several Schemas in one database model may be confusing. The next section explains these concepts and how they are related.

    Clarifying Concepts

    The physical schema contains all the necessary pieces to define the database: tables, columns, types, indexes, constraints, etc. This is what we are really defining. Every object added in the graphical model also shows up in the physical schema. It is, in fact, a visual way to define our schema.

    We can have several schemas for the same database model in the same way we can have several databases in a MySQL server. Each schema will be a MySQL database. For example, in the next screen, we have two schema tabs:

    If we generate the SQL script, we will have two separate CREATE DATABASE statements – actually we will have CREATE SCHEMA which is just a synonym.

    CREATE SCHEMA IF NOT EXISTS `schema1`;
    CREATE SCHEMA IF NOT EXISTS `schema2`;

    “EER stands for Extended (or Enhanced) Entity-Relationship. EER diagrams are just a way to model the data and the relationships between data using standard symbols”

    They will be listed as databases within the MySQL server host when using SHOW DATABASES.

    Now, what is an EER Diagram?. EER stands for Extended (or Enhanced) Entity-Relationship>. EER diagrams are just a way to model the data and the relationships between data using standard symbols. EER models can be complex, but MySQL Workbench uses only a subset of all possible graphical elements, because the purpose of this diagram (in this tool) is to have every element mapped to the physical schema.

    We can use an EER diagram to define the whole database, or just small parts. For example, we can have a schema with five tables defined, and then create a new diagram to define two more tables using the visual editor. The diagram will contain only two tables, but those two tables will also be included in the schema, together with the previous five.

    Creating our Tables

    Back to our initial example; we have to rename the default schema by double clicking the name. At this point, we have two possibilities: we can start adding tables to our physical schema using the add table icon, or we can start an EER Diagram and add all the tables there.

    I prefer to add a new diagram from the beginning and create my schema visually; however, in order to show how to do it with both methods, we are going to create the first two tables in the schema tab, and then continue with the EER Diagram.

    When you click the Add Table icon, the table editor opens as a tab below:

    Using the table editor, we change the table name and switch to the columns tab (in the tabs below the editor) to enter our columns. We can choose the data type (there is a drop-down list with all the MySQL data types), assign default value, if needed, and we have seven checkboxes to mark any of the following properties:

    • PK – Primary key
    • NN – Not null
    • UQ – Unique
    • BIN – Binary
    • UN – Unsigned
    • ZF – Zero fill
    • AI – Autoincrement
    Go Visual

    This is one way to add our tables, though we can also create them using the diagrams. If we click the Add Diagram icon now, we will begin a new, empty diagram, and that’s not what we want. We want the two tables that we just created to be in the diagram.

    If we go to the menu, select Model/Create Diagram from Catalog Objects, now we have our diagram, and are ready to continue.

    Select the table icon on the left; the pointer changes to a hand with a little table. Next, click anywhere in the canvas to create a new table.

    Now you just have to double click the table, and the editor tab appears to edit the name, columns, types, etc.- the same way as we did before.

    After entering the column details for the new tables, we’ll be ready to start drawing the relationships.

    Drawing Relationships

    In the vertical tool bar on the left, we have six tools available to create relationships.

    Don’t worry about the last one, we’ll explain it later. For the 1:1 and 1:n relationships, we have two different types of symbols: identifying and non identifying. What does that mean?

    A relationship is considered identifying when one table is entirely dependent on the other to exist.

    A relationship is considered identifying when one table is entirely dependent on the other to exist. A row in that table depends on a row in the other table. A common example is to have a separate table to store phones for users. It may be necessary to have it in another table, because there can be several phones for one user, but each row in that table is entirely dependent on the user – it belongs to the user.

    You should be aware that relationships have some implications. If we want to create the physical tables in MySQL, relationships must be mapped in some way. There are a few rules to map relationships into tables:

    • 1:1 relationships. Primary key for one of the tables is included as foreign key in the other table.
    • 1:n relationships. Primary key of the table in the ‘1′ side is added as foreign key in the table in the ‘n’ side.
    • n:m relationships. A new table (join table) is created. The primary key is composed of the primary keys from the two original tables.

    Identifying relationships are typically used for the join tables created from a many-to-many relationship. These new tables are entirely dependent on the two original tables.

    Also, in the case of 1:1 and 1:n identifying relationships, the foreign key introduced will be part of the primary key for that table, forming a composite primary key.

    The good news is that MySQL Workbench knows these rules better than most of us. We just draw our lines, and the foreign keys or join tables will be automatically be created. We can also choose to do it manually, as we’ll see shortly.

    To draw a relationship, click the icon, and then click the two tables to relate. For one-to-many relationships, click on the “many” side table first, and then on the “one” side table. Let’s see how to do it for the n:m teachers-subjects relationship, and for the 1:n teachers-classes.

    The default name assigned for the foreign keys, and for the join tables can be changed globally in Edit/Preferences/Model Tab, or only for the present project in Model/Model Options.

    If we don’t want tables and foreign keys to be generated in this way, we can use the mysterious “sixth symbol.”

    The “sixth symbol” creates a relationship using existing columns, meaning that you have already included the necessary foreign keys in your tables and created the necessary join tables (n:m mapping tables). Since we’ve already created these Join tables, we don’t need n:m relationships; only 1:n is available.

    When we have all our relationships defined, our diagram should looks like so:

    Be aware that we have been using the default MySQL Workbench notation for the diagrams, but you can change that in Model/Object Notation and Model/Relationship Notation. This is an example of our model in Classic notation:

    At this point, our model is ready, and we can generate the SQL to create the MySQL database.

    Generating SQL

    Select File/Export/Forward Engineer SQL CREATE Script. We are only three wizard screens away from generating our file!

    We even have the option to review and edit the generated SQL before saving it:

    And that’s it. Clicking finish, the SQL script will be generated and saved. Now, we can use it in any way we wish. We can load it using the command-line mysql client:

    mysql> SOURCE scriptName.sql

    Or, we can use MySQL Workbench to finish the work, connecting to our MySQL server and running the script.

    Connecting to a MySQL Server

    Select Database/Manage Connections from the menu, and click NEW.

    If you don’t want to set the password here, you’ll be prompted for it when needed. Click “Test Connection” to check if your parameters are correct, and then click close.

    Now, to load the script, we’ll use the SQL editor. In the main menu select Database/Query Database; a window prompts you to select a connection, and then the SQL editor tab opens.

    Now click the lightning icon to execute the SQL script, and your database will be generated!

    We could also have generated the MySQL database directly from the model, without referencing the actual file, using Database/Forward Engineer from the menu; however, I find it useful to generate the script and then use it how I wish.

    Conclusion

    MySQL Workbench is an impressive tool. We have only seen a few basic possibilities in the data modeling part, and only peeked at the SQL editor in the second half of this tutorial. We learned how to create a database visually and draw diagrams that can be kept as documentation. You can export the diagrams as a PNG, SVg, PDF or PostScript file. Thanks for reading, and let me know what you think!


  • Permalink for 'Crockford on JavaScript: The Complete Series'

    Crockford on JavaScript: The Complete Series

    Posted: April 13th, 2010, 11:18am MDT by Andrew Burgess

    Douglas Crockford has been well described as the world’s foremost authority on JavaScript. His “JavaScript: the Good Parts” talks have been around for a while, but recently he concluded giving a five-part updated series, entitled Crockford on JavaScript. For any JavaScript developer, these videos are a must read; check them out below!

    Volume 1: The Early Years

    View the Slides (slideshare)

    Chapter 2: And Then There Was JavaScript

    Slides (slideshare)

    Act III: Function the Ultimate

    Slides (slideshare)

    Episode IV: The Metamorphosis of Ajax

    Slides (slideshare)

    Part 5: The End of All Things

    Slides (slideshare)


  • Permalink for 'Magento for Designers: Part 2'

    Magento for Designers: Part 2

    Posted: April 13th, 2010, 8:07am MDT by Siddharth

    Magento is a stunningly powerful e-commerce platform. In this miniseries, we’ll learn how to get started with the platform, getting to know the terminologies, setting up a store and all related aspects of it, and finally how to customize it to make it our very own.

    In this second part, we’ll focus on short, simple steps to get your Magento store from installed to ready for deployment, which will cover setting up your products, product categories, taxes, shipping, payment gateways and much more! Excited? Let’s get started!

    The Full Series A Quick Recap

    In the last part, we saw what Magento is, what features it brings to the table, how to install it and finally how to import details regarding your existing data.

    Today, we’ll fast track through the set up process by eliminating all the fat and instead focusing on only the very important elements. In these short, simple steps, your fresh installation of Magento will turn into a fully functional e-commerce web site.

    In the previous part, we looked at how to bulk import products but that method may not be suitable for all scenarios. Hence we’ll build up our catalog and store from scratch.

    Step 1 : Setting up Categories

    Creating categories for products and then using them for organizing them will definitely help you in the long run. Creating a category is very simple. Under the catalog menu, click on Manage Categories

    Tutorial Image Tutorial Image

    The resulting form lets you manage the various properties of the category.

    The Name field lets you set a name for your category. You can always refer to it by ID but a name is always easier to use. You are allowed to use any character here.

    The Is Active toggle lets you decide whether to make it active straight away or wait for later. This is especially useful when you are making advance preparations for a special sale and do not need to make it live right away.

    The Description and Image fields are self explanatory.

    The Page Title, Meta Keywords and Meta Description fields are for SEO purposes and let you set and manage these attributes on a per-category basis.

    For a quick setup, these are all the fields you need to complete. The rest of the options in the other tabs are rather advanced and are beyond the scope of this article.

    Step 2 : Setting up Products

    Products form the base of your store and so we’ll spend a little extra time here. To add a product, click on the catalog menu, click on Manage Products.

    Tutorial Image

    There are a number of types of products you can create in your store:

    • Simple
    • Configurable
    • Grouped
    • Virtual
    • Bundled
    • Downloadable

    In the interest of getting our store up and running as quickly as possible, I’ll cover simple products and downloadable products here. In all honesty though, these are all you’ll need in most cases. We’ll take a look at how to create a simple product first.

    Tutorial Image

    You get a total of eleven tabs chock full of fields to enter data about your product. For now, you can safely ignore most of them and focus instead on the fields that matter.

    Tutorial Image

    The General tab covers the bulk of the necessary information you need to input to get started. Key in values for the name, description, short description, SKU and weight fields.

    The status option lets you decide whether the product is enabled or disabled from the onset. For example, you can set the products status to disabled if it’s a special product that is meant to be sold only in a certain period.

    The visibility options lets you fine tune where the product appears. For instance, you may want a product to appear in the catalog but not in a search or vice versa. You can set that option here.

    Tutorial Image

    In the Prices tab, you only need to fill out two fields. The price field is self explanatory. Tax class lets you define to which tax class the product belongs to. I’ll talk about taxes a little bit later below.

    Tutorial Image

    Setting up images for each product is not necessary but is highly recommended. The Images tab lets you pick out images for the product.

    Each product needs 3 images. A big image, a smaller version and finally a thumbnail for displaying in search listings and so on.

    Each image can have either or neither of these three. You are also allowed to have more than one image for a product. Magento provides a simple Flash based uploaded for you to directly upload the images you need.

    Tutorial Image

    In the Inventory tab, you can fill out the quantity you currently have stocked so the core engine can let the customer know when an item is sold out.

    Tutorial Image

    Finally, you’ll need to define which category the product belongs to. I only have a solitary category in my local server but you can nest it as needed.

    Feel free to explore the others options present in each tab but these are the bare minimum you need to create a simple product.

    For a downloadable product, you’ll need to look into one more tab: the Downloadable Information tab.

    Tutorial Image

    This tab let you do a number of things including letting you upload or point to a file you want as the demo or the main product, decide whether purchasers are allowed to share the link, how many times the purchaser is allowed to download it and so on. Once you’ve filled this out, you can sell digital, downloadable products like, say, music, lesson plans, photographs and so on.

    Step 3 : Setting up Taxes

    Using Magento, you can account for a myriad combinations of different locations and their resulting differing tax percentages. Setting up tax rates is easy. Under the Sales tab, click on Tax -> Manage Tax Zones and Rates and then click on the Add New Tax Rate button.

    Tutorial Image

    Now we’ll configure the core engine so that it adds a sales tax of 6% whenever a customer from Florida purchases an item.

    Tutorial Image

    The Tax Identifier field lets you name the rate to your choice. Next, choose your country and if necessary, drill down to state and finally to the zip code if taxes differ by zip codes.

    You can then specify the tax rates for the location you’ve selected. If instead, the differing taxes only apply to a range of post codes, you can specify them in the range field.

    For basic use, setting up a tax rate alone is sufficient. But if instead you want to drill down further; say, change the tax for different items or offer differ rates for wholesales purchasers, Magento still lets you do that. You need to make use of Customer/Product classes and then define rules for them. This feature, while simple, requires a bit more explanation to get started. We’ll look at this feature in another part of this series.

    Step 4 : Setting up Shipping Rates

    Magento can automatically calculate the shipping rate based from where your warehouse is and the customer’s address. First, you need to tell Magento where you’ll be shipping it from. On the System menu, click on configuration. The shipping settings can be found under the sales section on the left.

    Tutorial Image

    First, you’ll need to let the system know where you are located from or where your warehouse is so Magento can use it as a starting point in calculating the shipping rate.

    Tutorial Image

    Next, click on the shipping methods option. You can find it right under shipping settings.

    Now, you can choose to charge a flat rate or to let Magento query a number of shipping services to find out their rates.

    Tutorial Image

    Here, you can modify a number of options including naming it, choosing whether the rate is calculated per item or per order, how much is to be taken for handling, the price itself and so on.

    And here is where Magento shines. You can specify this is as an option for all allowed countries or just choose the countries you want to allow individually.

    Tutorial Image Tutorial Image

    If instead, you’ve decided to let Magento decide the rate based on what each shipping company charges, you can select the service you like. Each of them, however, share the same options.

    Most of the fields are rather self explanatory so I’ll go over the more pertinent ones here. First up, notice the gateway URL field. This is where the Magento polls for shipping rate data. If by chance, it gets outdated, feel free to update this field. You can also specify which types of shipping methods are allowed. As before, you can allow/disallow each method of each supported shipping company individually.

    Please note that the User ID field is specific to each shipping company and may require registering with them. Depending on the company, DHL for instance, you may also be required to provide an access ID and password.

    Step 5 : Setting up a Payment Gateway

    Magento supports a number of payment methods right off the bat to simplify your life. Only the check/MO method and saved CC method are enabled by default so you’ll have to pop-in and enable the payment methods you need on the settings page.

    You can find this on the sales portion of the configuration page. In case you forgot, you can reach this page through System->Configuration.

    Tutorial Image

    For example, to enable Express Checkout for Paypal account holders, you’d just need to click on the appropriate method and change the enabled field to yes.

    Tutorial Image

    If you’ve chosen a Paypal payment method, you’ll also need to provide your Paypal email address and other credentials depending on which method you chose.

    Tutorial Image

    Google Checkout and Moneybookers both get their own section, in case you’re wondering. Just like with Paypal, enabling them can be done in two simple steps.

    Step 6 : Setting up your Inventory

    Magento provides a robust inventory management system you can use of to avoid problems in the future. You can access it by clicking on the the inventory menu in the catalog section of the configurations page.

    Tutorial Image Tutorial Image

    Here, you can specify a number of options including when to mark an item has sold out, maximum numbers of items allowed in the cart, whether back orders are allowed and so on.

    You can also denote whether you want your inventory to be adjusted when an order has been placed. If instead you want to manually modify your stock when a product has been shipped out, disable this. You can also specify whether sold out items are displayed and the threshold number of items before an item is marked as out of stock.

    Step 7 : Setting up Analytics

    Now that we’ve got the brunt of the work done, we can focus on the smaller, often forgotten things. Analytics, for instance.

    First, you’ll need to enable Google Analytics. You can do so by going to the Google API link of the sales section of the configuration page. Here choose to enable GA and keyin your account number.

    Tutorial Image

    Now, Magento automatically inserts the required Google Analytics code into each page of your web site.

    Step 8 : Setting up Pretty URLs

    The final step now is to make our store as SEO friendly as possible. While most of the onsite parts of SEO are dependant on the theme you use, user friendly, SEO friendly, semantic URLs are something you can do yourself through tools provided by Magento.

    First, you’ll need to enable rewrites. You can do so by clicking on the web link under the general section of the configuration page.

    Tutorial Image

    The relevant option can be found under the SEO link.

    Now, we can create our own custom URLs. Point to catalog->URL Rewrite Management.

    Tutorial Image

    The resulting form lets us manage our rewrite.

    Tutorial Image

    The type, ID path and target path are read-only fields. The request path however lets you keyin our own request path. Essentially, when a URL pointing to request path is requested by the browser, internal rewrites reroute it to the target path.

    You can also denote whether the rewrite is permanent or temporary.

    The Last Word

    And we are done! We looked at how to convert your fresh installation of Magento into a fully working e-commerce powerhouse. We review how to set up your categories, products, taxes, shipping and much more. Hopefully, this has been useful to you. I’ll be closely watching the comments section so chime in if you’re having any concerns or questions.

    Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!


  • Permalink for 'Quick Tip: Notable New Features in Dreamweaver CS5'

    Quick Tip: Notable New Features in Dreamweaver CS5

    Posted: April 12th, 2010, 8:01pm MDT by Jeffrey Way

    If you’re a Twitter user, it was difficult not to be aware of Adobe’s CS5 global launch presentation. While they did an excellent job of promoting Photoshop and Flash, other applications, such as Dreamweaver, only received limited coverage. Nonetheless, take a look at some of the awesome new features in Dreamweaver CS5, slated to be released in mid-May.

    1. BrowserLab Integration Browserlab

    Adobe, for some time now, has offered a helpful, and free, service called Browserlab. For those unfamiliar, Browserlab is a Live service that allows you to view snapshots of your website in a variety of browsers, not too dissimilar from Browsershots.org. Luckily, with CS5, this service is fully integrated into Dreamweaver, even allowing us the ability to stack multiple snapshots of our designs, from various browsers, on top of one another. This is especially helpful for those of us with pedantic attentions to detail.

    “Preview dynamic web pages and local content with multiple viewing, diagnostic, and comparison tools.”

    2. CMS Support CMS Support

    Perhaps the most welcomed and exciting new addition to Dreamweaver, there is now a “live view” option, when working on, for instance, templates for a variety of CMSs, including WordPress! This means that you can browse pages, populated with postings from your database, directly within Dreamweaver. How cool is that?

    “Enjoy authoring and testing support for content management system frameworks like WordPress, Joomla!, and Drupal.”

    3. Site-Specific Code Completion code completion

    This is something to be excited about. WIth this latest release, we now can utilize intellisense on site specific coding. For example, imagine being able to access the various WordPress functions directly from the intellisense pop-up? Pretty cool!

    “Benefit from code hinting on nonstandard files and directories in Dreamweaver..”

    4. Adobe Business Catalyst Integration

    This new feature is being promoted heavily, and, while it might definitely prove to be appealing to some designers and non-programmers, I doubt our particular community will utilize this new addition. Essentially, it allows you to design and build websites with minimal coding experience.

    “Leverage integration between Dreamweaver and the Adobe Business Catalyst® service (available separately) to deliver powerful online businesses without programming.”

    5. Improved CSS Inspection CSS Inspection

    The Dreamweaver team has added a new feature which allows us to, after clicking the “Inspect” button, click on various elements on our page, and immediately view the applicable styling associated with that particular element. If you’re familiar with the Web Developer Toolbar, and Firebug, you’ll be quite familiar with this. Nonetheless, it’s a nice addition to have available from directly within the IDE.

    “Visually display the CSS box model in detail, and easily toggle CSS properties without reading code or needing to use a separate utility.”

    Missed the Launch Video?

    If you didn’t catch the live unveiling, you can watch it here. So what’s the consensus? Has Dreamweaver finally come through for us? Will it take the place of your IDE of choice?


  • Permalink for 'Creative Sessions: A New Set of Educational Posts Every Month'

    Creative Sessions: A New Set of Educational Posts Every Month

    Posted: April 12th, 2010, 6:41pm MDT by Skellie

    We’re very passionate about teaching creative skills here at Tuts+, so over the last year we’ve been planning a new stream of educational content focused on the "Why?" instead of the "How". Today we’re unveiling the newest addition to the Tuts+ family: Creative Sessions.

    Creative Sessions logo.Every month we’ll be running a two week ‘Session’ on a creative topic. Our first Session, beginning today, is on Character Illustration, and future Sessions will be on varied topics like interface design, illustrative typography and creative freelancing. Unlike regular Tuts+ content, Sessions content is more theoretical, opinion based and will often cross many disciplines.

    Depending on the Session, each specific article will fit into one of our ten educational sites (including FreelanceSwitch and WorkAwesome). So they will be published on the appropriate site, while our central site Sessions.tutsplus.com/Creative will provide the hub for each Session. There you will be able to track each Session, grab the monthly wallpaper, participate in a community project, subscribe to the RSS feed, follow CS on Twitter and give feedback (or praise!) for the Session.

    The homepage of Creative Sessions.

    Sessions is a bit of a new take on teaching online and is one we hope will be really successful. It’s going to really take advantage of the increasing diversity of our Tuts+ network, meaning that for example we could have a session on web design that might have a ‘freelance web design’ post on FreelanceSwitch, a ‘build a web design’ post on Nettuts+, a ‘optimize a web design for the iphone’ on the upcoming Mobiletuts+ and much more!

    Because it’s so new, you can expect to see us tweak and improve the model over the next year or so. The content is all free, and like the rest of Tuts+ will remain so. At some point we’ll investigate adding either a bit of premium content to each Session or possibly extended courses for subscribers to help pay for it all!

    Finally each Session will feature cover artwork by a talented designer or illustrator. The artwork will be downloadable as a wallpaper and will help give each of our Sessions a bit of personality!

    Session 1: Character Illustration

    Sessions is already bubbling with activity. You can download a gorgeous desktop wallpaper by Ryan Putnam (Rype), take part in our ‘Create an Antihero’ community project, or dive straight into the fully-illustrated Principles of Cute Character Design by Sascha Preuss, exclusive to Creative Sessions.

    Drawing character's eyes wide apart and low = cuteness! Advertising: FusionAds

    FusionAds logoOur Creative Sessions hub-site displays only one ad on every page – an excellent opportunity for your product to cut through the noise and reach its target market. Create a campaign with FusionAds to be seen on Creative Sessions and many other high quality creative sites.

    If you’d like to advertise elsewhere on the Tuts+ network, we are big fans of BuySellAds and you can purchase ad spots by heading over and searching for your favourite site!


  • Permalink for 'Magento for Designers: Part I'

    Magento for Designers: Part I

    Posted: April 12th, 2010, 10:08am MDT by Siddharth

    Magento is a stunningly powerful e-commerce platform. In celebration of ThemeForest’s new Magento category, this mini-series will you teach how to get started with the platform, getting to know the terminologies, setting up a store and all related aspects of it, and finally how to customize it to make it our very own.

    In this first part, we’ll get to know what Magento is, installing it, and importing some products. This is aimed expressly at the beginner; so you need not worry about lacking the requisite skills. We’ll walk you right through! Excited? Let’s get started!

    The Full Series What exactly is Magento? Magento

    Running an e-commerce site is a daunting task what with almost all of the current platforms being lumbering beasts ill-suited to current standards. Magento promises to fix this and a lot more.

    Magento is an extremely powerful and feature filled e-commerce platform. And it’s open source to boot! It comes filled to the brim with all the features and tools you’d need to get your e-commerce web site up and running as quickly as possible.

    What Features Do You Get? Tutorial Image

    Magento is replete with a number of features which are hard to find or maybe even unheard of in most of its competitors. Salient ones include:

    Flexible Payments

    Often used payment processors including Paypal, Google Checkout, USAePay and Authorize.net are supported along with support for traditional methods such as credit cards, money orders and checks. Plenty of modules are also available to make it works with a myriad other payment processors.

    Robust Checkout Process

    All the features you’d expect out of a mature product including 1-click checkout and full SSL support are present.

    Full Fledged Analytics

    Magento provides complete analytics and reports for your stores. No need to use a third party solution anymore!

    Product Reviews and Ratings

    Out of the box, you can setup the store so that a customer can rate an item up or down and leave a review.

    Search Engine Optimized

    Magento is 100% Google friendly and supports Google Site maps to boot.

    Marketing Promotions

    A number of different promotional options including coupons and discounts can be made use of right off the bat.

    And many, many more

    There are truly too many features to cover in a single article. To be frank, you’d need an entire book to cover what Magento can do. Magento almost has every facet covered.

    Which Version to Choose? Tutorial Image

    Now that you’re excited about Magento, you probably can’t wait to get started. But before that, we need to choose which version to pick.

    Magento comes in two flavors:

    The Enterprise edition is for organizations running mission critical stores. It comes with 24/7 support and numerous features you’d expect out of an en enterprise level platform including a more robust CMS system, support for gift certificates and more. But on the flip side it weighs in at $11,125 per year.

    The Community version meanwhile is completely free to download and use and you’re at complete liberty to modify it to suit your needs. The only thing you’d be giving up will be the robust support but the active community more than makes up for it.

    We’ll be taking a look at the community edition today.

    Server Requirements

    Magento has modest server requirements but it doesn’t hurt to make sure we have everything in order. Here are the official requirements:

    • Apache 1.3+
    • PHP 5.2+
    • mySQl 4.1.2+

    There are ways to make it work with PHP 4 but honestly, it’ll be easier in the long run to just upgrade your PHP installation.

    Prepping for the Installation

    First, you need to obtain a copy of Magento. If you’re a SVN person, checkout a copy from [svn.magentocommerce.com] Else, you can just it get it from here.

    Tutorial Image

    We also need a database for Magento so we’ll set it up as it downloads. I’m assuming you already have a LAMP setup in place.

    Tutorial Image

    On successful database creation:

    Tutorial ImageI’m making a note here. Huge success! Importing the Sample Data

    We’ll need to import some sample data to our newly created database before we install Magento.

    Tutorial Image

    First up, download the SQL for the data.

    Tutorial Image

    Import it through phpMyAdmin and let it do all the rest.

    Tutorial Image Installation

    Now we can move on to the actual installation. Magento, being a mature platform, has a relatively simple installation process. All you need to do is input a few values, click on the continue button and you’ll be on your way to a working Magento installation.

    Tutorial Image

    First, up we need to accept the license agreement. It’s mostly boilerplate but give it a quick read. Finally accept the terms and click on the continue button.

    Tutorial Image

    Set up your location, preferred currency and time zone in the next screen. You can, of course, change all these later through the administration screens.

    Tutorial Image

    Like me, if you’re daft, you might have forgotten to enable some of the PHP extensions Magento needs. In that case, enable the extension Magento needs and then retry.

    Tutorial Image

    You can now input the database credentials Magento needs to set it all up. You can also adjust the base URL of the store and the path to the administrative panel.

    You can also set up clean SEO URLs right off the bat here.

    Tutorial Image

    Finally, you need to setup your admin account so you can manage everything. Magento needs an encryption key for encrypting sensitive data. If you have one at hand, type it in. Else let Magento generate one for you.

    Tutorial Image

    And we’re done. Magento has been successfully been installed.

    Fix for Local Test Servers

    If you’ve tried logging on to your fresh installation, you’ll get errors asking you to enable your cookies. This is because browsers generally tend to not store cookies for URIs without a period in it. localhost thus fails to store a cookie which leads to problems logging in.

    Solutions to this problem range from using 127.0.0.1/magento instead of localhost to modifying Windows’ host file to manually redirect it. Nonetheless, since this is only going to be the test setup, we can just bypass said cookie-check.

    Open up Varien.php at magento\app\code\core\Mage\Core\Model\Session\Abstract and find the following snippet starting at line 77:

    // session cookie params
            $cookieParams = array(
                'lifetime' => $cookie->getLifetime(),
                'path'     => $cookie->getPath(),
                'domain'   => $cookie->getConfigDomain(),
                'secure'   => $cookie->isSecure(),
                'httponly' => $cookie->ge [Httponly()]         );
    
            if (!$cookieParams['httponly']) {
                unset($cookieParams['httponly']);
                if (!$cookieParams['secure']) {
                    unset($cookieParams['secure']);
                    if (!$cookieParams['domain']) {
                        unset($cookieParams['domain']);
                    }
                }
            }
    
            if (isset($cookieParams['domain'])) {
                $cookieParams['domain'] = $cookie->getDomain();
            }
    

    Now comment out the relevant parts like so:

    // session cookie params
            $cookieParams = array(
                'lifetime' => $cookie->getLifetime(),
                'path'     => $cookie->getPath(),
                'domain'   => $cookie->getConfigDomain(),
                'secure'   => $cookie->isSecure(),
                'httponly' => $cookie->ge [Httponly()]         );
    
           /* if (!$cookieParams['httponly']) {
                unset($cookieParams['httponly']);
                if (!$cookieParams['secure']) {
                    unset($cookieParams['secure']);
                    if (!$cookieParams['domain']) {
                        unset($cookieParams['domain']);
                    }
                }
            }
    
            if (isset($cookieParams['domain'])) {
                $cookieParams['domain'] = $cookie->getDomain();
            }*/
    
    Importing Custom Products

    We’re all but done here. We’ve installed Magento and added some sample data to get a taste of the platform. But it’d be more useful if we could import some of our own products before leaving. For a few, manually importing them shouldn’t be a problem. But when they move into the tens, this should be a problem.

    To that end, this simple technique should come in handy. There are, of course, more sophisticated ways to import data but they require a tad more Magento expertise so we’ll be tackling it later on in the series.

    Step 1: Export the Sample Products Tutorial Image Tutorial Image Step 2: Understand the way the CSV is Structured

    Study the structure of the CSV. Once you’re understood it, you can easily just add products directly to the CSV file. Feed it into a spreadsheet program to make this part even more easier.

    Step 3: Import the Updated CSV into Magento Tutorial Image Tutorial Image The Last Word

    And we are done! We looked at what Magento is, the features it offers, how to install it, how to get some sample data in and finally how to get our own product data in. If you think it was a little too beginner level, fret not. This first entry is aimed primarily at the designer who wants to get his/her feet wet with Magento. We’ll be ramping up the difficulty as the series moves forward.

    Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!

    Purchase Magento Themes from ThemeForest ThemeForest

    Did you know that your friendly neighborhood ThemeForest sells premium quality Magento themes? Whether you’re a skilled Magento developer looking to start profiting from your efforts, or a buyer, hoping to build your first eCommerce store, we’ve got you covered!


  • Permalink for 'How to Create an App with the Myows API'

    How to Create an App with the Myows API

    Posted: April 10th, 2010, 6:24pm MDT by Jeffrey Way

    In their own words: “Myows is an easy-to-use app dedicated to providing a full suite of copyright solutions, from registration to management. Myows has been created for designers, photographers, bloggers, writers, musicians and anyone who creates copyrightable work.” In this weekend supplementary tutorial, a member of the Myows team will demonstrate how to create your own apps using the Myows API.

    Take Fuss-Free Copyright Management to the Next Level.

    Get your hands dirty with Myows’ publicly available API, fresh from the desks of our globally-scattered development team. This brings us one step closer to our platform-vision: helping the planet’s switched-on creative community help themselves. We’re looking for Myows members to help us add further functionality to the existing app at Myows.com. The brief is straightforward:

    Registering your Application

    Get the Flash Player to see this player. var so = new SWFObject('http://net.tutsplus.com/wp-content/plugins/flash-player/player.swf','player10','600','494','9'); so.addParam('allowscriptaccess','always'); so.addParam('allowfullscreen','true'); so.addParam('flashvars','&file=http://s3.amazonaws.com/nettuts/631_myows/apiRegister.flv&bufferlength=1&skin=http://net.tutsplus.com/wp-content/plugins/flash-player/silver.swf&fullscreen=true'); so.write('player10');

    Create a Simple Sort and Display App Using the Myows API

    Get the Flash Player to see this player. var so = new SWFObject('http://net.tutsplus.com/wp-content/plugins/flash-player/player.swf','player11','600','494','9'); so.addParam('allowscriptaccess','always'); so.addParam('allowfullscreen','true'); so.addParam('flashvars','&file=http://s3.amazonaws.com/nettuts/631_myows/ApiMain.flv&bufferlength=1&skin=http://net.tutsplus.com/wp-content/plugins/flash-player/silver.swf&fullscreen=true'); so.write('player11');

    4-Steps API Challenge

    In fact, Myows is hosting a competition on their site right now.

    “We’re looking for plug-ins, add-ons and stand alone applications that improve the user experience and add useful functionality. To participate, you’ll need to create a thread before 15th May in our API forum category and provide a link to a demo of you app.”


  • Permalink for 'Photoshop to HTML: Upcoming eBook from Nettuts and Rockable'

    Photoshop to HTML: Upcoming eBook from Nettuts and Rockable

    Posted: April 9th, 2010, 3:10pm MDT by Jeffrey Way

    There’s a reason why our various tutorials on slicing PSDs are consistently among the most popular articles on Nettuts. Every one of us, at one point or another, has needed to convert a PSD into a working website. The only problem is that, until you’ve gotten a few projects under your belt, it can be significantly confusing. As such, I was asked to prepare a book and video series that details the entire process from start to finish for Rockable Press.

    1. What You’ll Learn in this Book and Video Series
    1. Different methods for slicing a PSD.
    2. Create semantic mark-up, and learn how this HTML relates to the original PSD.
    3. How to utilize techniques, such as background replacement and sprite generation.
    4. Use custom fonts with Cufon font replacement.
    5. The differences between absolute and relative positioning.
    6. How to compensate for the dreaded Internet Explorer 6.
    7. Take advantage of advanced CSS3 features.
    8. How to take advantage of a variety of helpful browser extensions to expedite your coding.
    9. Utilize the jQuery library to add a touch of interactivity.
    10. And plenty more…
    2. Accommodates All Learning Styles What we'll be converting to a fully functioning html/css website

    Over the course of the book, we’ll build the fully functioning website, shown above.

    Prefer the written word, perhaps even on your new iPad? If so, the immediately downloadable PDF can be viewed on your computer, or any of your eReaders. On the other hand, if you’re more of a visual learner, like myself, and would prefer to have someone “sit next to you,” so to speak, through the entire process, I’ve also included the book in video form, separated into a dozen chapters, where I slowly and succinctly explain each step.

    3. Rockable Members Receive a Discount Rockable Press

    If you’re not a Rockin’ List member yet, why not? Did you know that, if you sign up (quick and free), you’ll immediately receive Skellie’s – our awesome Tuts manager – “Rockstar Personal Branding” mini-book for free?

    Not only that, but when my book launches (very soon), you’ll receive a discount on the book. Signup for the Rockin’ List.

    So if you’re at the point in your learning where this would be helpful to you, I really do hope you’ll consider picking up this ebook and highly in depth video series when it launches very soon!

    Photoshop to HTML

    In “Photoshop to HTML”, Nettuts+ editor and author Jeffrey Way will take you through the entire process of converting a design from Photoshop into a complete HTML/CSS website! This book also comes with the completed demo site, which you’re free to use as you wish in your own projects. But not only that, you also get an additional series of screencasts where Jeffrey covers the entire process from start to finish. So you have the choice of either reading or viewing!


  • Permalink for 'Quick Tip: Learning about HTML5 Local Storage'

    Quick Tip: Learning about HTML5 Local Storage

    Posted: April 9th, 2010, 10:16am MDT by Jeffrey Way

    In today’s video quick tip, we’re going to build a working, though very basic, to-do list in just a minute or two. Thanks to HTML5’s local storage, we can make advanced browsers “remember” what we type, even after the browser is closed or is refreshed.


    Subscribe to our YouTube page to watch all of the video tutorials!
    Or, watch this video on Screenr.com.

    “localStorage sets fields on the domain. Even when you close the browser, reopen it, and go back to the site, it remembers all fields in localStorage.”
    -QuirksBlog

    While obviously not supported across all browsers, we can expect this method to work, most notably, in Internet Explorer 8, Safari 4, and Firefox 3.5. Note that, to compensate for older browsers that won’t recognize local storage, you should first test to determine whether window.localStorage exists.

    Support matrix

    via [www.findmebyip.com]


  • Permalink for 'Implementing HTML5 Drag and Drop: New Premium Tutorial'

    Implementing HTML5 Drag and Drop: New Premium Tutorial

    Posted: April 8th, 2010, 3:01pm MDT by Andrew Burgess

    One of the new features in HTML5 is native drag and drop. Surprisingly, Internet Explorer has had support for this since version 5.5; in fact, the HTML5 implementation is based on IE’s support. In this week’s Premium tutorial and screencast, we’ll look at how to implement native drag and drop to build a simple shopping cart interface.

    Final Product Not a Premium Member? Get More out of Nettuts+!

    A ONE Premium membership gives you access to members-only content for ALL our Premium sites. Read more about the great value you’ll also get from Psd Premium, Ae Premium, Audio Premium and Vector Premium as part of your membership.

    If you want to experience everything Nettuts+ has to offer, you’ll need to go Premium. Here are three reasons to join our community of over 10,000 happy Premium members:

    1. Exclusive Bonus Tutorials Teaching Professional Web Dev Techniques

    Once a week Premium members gain access to a bonus tutorial at Nettuts+. We understand that joining Premium is an investment in your skills as a web developer. We want to make sure that investment pays off. Because of this, each Premium tutorial teaches skills that professional web developers can use to add extra value for clients and, in doing so, add extra value to your business.

    Premium tutorials are authored by accomplished web developers, industry leaders, Nettuts+ editor Jeffrey Way and other names you’ll recognize. Each tutorial focuses on coding languages and frameworks many web developers are proficient in, such as CSS, XHTML, Javascript, PHP and MySQL.

    • See exactly how the code is built, line by line;
    • Learn sought-after techniques clients will pay big bucks for;
    • Undertake challenging exercises that raise your skills to another level.

    Join Now

    “I did the quarterly deal, not to save money, but to not have to worry about it for 3 months. I wish there was an annual option. $9/month is a steal for the quality of content available here.” — Adam Jackett on Psd Premium

    2. Screencasts Make Learning Complicated Techniques Easy

    Net Premium tutorials will always have accompanying video, whether they are pure screencasts or written tutorials with a video companion. At Tuts+ we’ve found that video lessons provide the clearest and most engaging training platform.

    • Stream or download video lessons to watch at your own pace;
    • Engaging commentary means lessons are never dry.

    Join Now

    “I pay—well, my wonderful parents pay—over $500 for my PCgraphics class, and I have learned more in a $9 subscription period of one month here than all year at school.” — Nico Valencia on Psd Premium

    3. Show Your Love and Contribute to Nettuts+

    Every month we spend many thousands of dollars on this site, sourcing the best tutorial writers, paying for community contributions, keeping hosting and bandwidth running smoothly and adding new features and improvements all designed to create the best possible user experience.

    Our commitment is to provide the best web development site on the web. As a Premium member you’ll be contributing to help make this site even better than it already is.

    Join Now

    “This is the cleanest, most professional PSD tutorial website on the net and the small monthly fee is nothing compared to the quality of material here. Keep up the good work.” — mattems on Premium

    What does it cost?

    Premium membership is $9 a month, or $22 for three months, or $78 for one year. For the cost of a magazine subscription you can get access to all of the following:

    • Weekly video lessons by industry leaders;
    • Access to all past and future video lessons;
    • Sought-after techniques in web development across a range of common coding languages and frameworks;
    • Access to our Tuts+ Dashboard, bonus content and features.
    • Full access to Net Premium, Audio Premium, Ae Premium and Vector Premium.

    “$9 is cheap for what you give me.” — Ryan on Premium

    Worth $9? We think so.

    And that’s why if you’re not satisfied, you can get your money back, in full. It’s our 100% money back guarantee. Just follow these instructions and we’ll give you a full refund.

    Remember, your Net Premium membership also grants you access to Vector Premium, Audio Premium, Ae Premium and Psd Premium. That’s five Premium programs for one small membership fee.

    So what are you waiting for?

    Join Now

    Once you’re a member, login at the Tuts+ Dashboard and go to ‘Premium Content’ to claim your downloads.


  • Permalink for 'Fun with Canvas: Create a Bar Graphing Plugin, Part 2'

    Fun with Canvas: Create a Bar Graphing Plugin, Part 2

    Posted: April 8th, 2010, 10:33am MDT by Siddharth

    In this two-part series, we’ll combine the versatile canvas element with the robust jQuery library to create a bar graphing plugin. In this second part, we are going to convert it in to a jQuery plugin, and then add some eye candy and additional features.

    Concluding the Fun with canvas two-part series, today we are going to create a bar graphing plugin; not an ordinary plug in, mind you. We are going to show some jQuery love to the canvas element to create a very robust plugin.

    In part one, we looked solely at implementing the logic of the plug in as a standalone script. At the end of part one, our bar graph looked like so.


    Result at the end of Part 1

    In this final part, we’ll work on converting our code and making it a proper jQuery plugin, adding some visual niceties and finally including some additional features. Ultimately, our output will look like so:


    Finished product

    All warmed up? Lets dive in!

    Plugin Formalities

    Before we start converting our code into a plugin we first need to look at a few formalities when it comes to plugin authoring.

    Naming the Plugin

    We begin by choosing a name for the plugin. I’ve chosen barGraph and renamed the JavaScript file to jquery.barGraph.js. We now enclose all the code from the previous article inside the following snippet.

    $.fn.barGraph = function(settings) {
    //code here
    }

    Settings contains all of the optional parameters passed to the plugin.

    Working Around the $ Symbol Issue

    In jQuery plugin authoring, it is generally considering a best practice to use jQuery instead of the $ alias in your code, in order to minimize conflicts with other Javascript libraries. Instead of going through all that trouble, we can just use custom aliases as mentioned in the jQuery docs. We enclose all our plugin code within this self executing anonymous function, as shown below:

    (function($) {
    $.fn.barGraph = function(settings) {
    //plugin implementation code here
    }
    })(jQuery);
    

    Essentially, we encapsulate all our code within a function and pass jQuery to it. We are free to use the $ alias as much as we want inside our code now, without having to worry about it potentially conflicting with other JavaScript libraries.

    The Defaults

    When designing a plugin, it is good sense to expose a reasonable number of settings to the user, whilst using sensible default options if the users uses the plugin without passing any options to it. With that in mind, we are going to enable the user to change each of the graph option variables I mentioned in this previous article in this series. Doing so is easy; we just define each of these variables as properties of an object and then access them.

    var defaults = {
    	         barSpacing = 20,
    	 		 barWidth = 20,
    	    	 cvHeight = 220,
    			 numYlabels = 8,
    			 xOffset = 20,
    			 maxVal,
    			 gWidth=550,
    			 gHeight=200;
               }; 

    We finally need to merge the default options with the passed options, giving preference to the passed ones. This line takes care of that.

    var option = $.extend(defaults, settings);  

    Do remember to change the variables names wherever necessary. As in –

    return (param*barWidth)+((param+1)*barSpacing)+xOffset;

    …changes to:

    return (param*option.barWidth)+((param+1)*option.barSpacing)+option.xOffset;
    Refactoring

    This is where the plugin is hammered out. Our old implementation could only produce a single graph in a page, and the ability to create multiple graphs in a page is the main reason we are creating a plugin for this functionality. Plus, we need to make sure that the user doesn’t need to create a canvas element for every graph to be created. With that in mind, we are going to create the canvas elements dynamically as needed. Let’s proceed. We’ll look at the earlier and updated versions of the relevant portions of the code.

    Invoking the Plugin

    Before we start, I’d like to point out how our plugin will be invoked.

    $("#years").barGraph
       ({
    		 barSpacing = 30,
            barWidth = 25,
    		 numYlabels = 12,
       });
    

    Simple as that. years is the ID of the table holding all our values. We pass in the options as needed.

    Obtaining the dataSource

    To start things off, we first need a reference to the source of data for the graphs. We now access the source element and obtain its ID. Add the following line to the bunch of graph variables we declared earlier.

    var dataSource = $(this).attr("id");
    

    We define a new variable and assign it the value of the passed element’s ID attribute. Within our code, this refers to the currently selected DOM element. In our example, it refers to the table with an ID of years.

    In the previous implementation, the ID for the data source was hard coded in. Now we replace that with the ID attribute we extracted earlier. The earlier version of the grabValues function is below:

    function grabValues ()
    	 {
    	 	// Access the required table cell, extract and add its value to the values array.
    		 $("#data tr td:nth-child(2)").each(function(){
    		 gValues.push($(this).text());
    	 	 });
    
    		 // Access the required table cell, extract and add its value to the xLabels array.
    		 $("#data tr td:nth-child(1)").each(function(){
    	 	xLabels.push($(this).text());
    	 	 });
    	 } 

    It is updated to this:

    function grabValues ()
    	 {
         	// Access the required table cell, extract and add its value to the values array.
    	 	$("#"+dataSource+" tr td:nth-child(2)").each(function(){
    		 gValues.push($(this).text());
    	 	 });
    
    		 // Access the required table cell, extract and add its value to the xLabels array.
    		 $("#"+dataSource+" tr td:nth-child(1)").each(function(){
    	 	xLabels.push($(this).text());
    	 	 });
    	 } 
    Injecting the Canvas Element
    function initCanvas ()
    	 {
    		 $("#"+dataSource).after("<canvas id=\"bargraph-"+dataSource+"\" class=\"barGraph\"> </canvas>");
    
             // Try to access the canvas element
         	cv = $("#bargraph-"+dataSource).get(0);
    
    	 	if (!cv.getContext)
    	 	{ return; }
    
         	// Try to get a 2D context for the canvas and throw an error if unable to
         	ctx = cv.getContext('2d');
    	 	if (!ctx)
    	 	{ return; }
    	 }

    We create a canvas element and inject it into the DOM after the table, which acts as the data source. jQuery’s after function comes in really handy here. A class attribute of barGraph and an ID attribute in the format barGraph-dataSourceID is also applied to enable the user to style them all as a group or individually as needed.

    Cycling through the passed elements

    There are two ways you could invoke this plugin actually. You could either create each graph separately passing in only one data source or you could pass in a number of sources. In the latter case, our current construct will encounter an error and quit. To rectify this, we use the each construct to iterate over the set of passed elements.

    (function($){
    	$.fn.barGraph = function(settings) {
    
    	// Option variables
    	var defaults = {
    	         // options here
               };  
    
    	// Merge the passed parameters with the defaults
        var option = $.extend(defaults, settings);  
    
    	// Cycle through each passed object
    	this.each(function() { 
    
    	// Implementation code here
    	});
    
    	// Returns the jQuery object to allow for chainability.
    	return this;
    	}
    })(jQuery);

    We encapsulate all code after obtaining and merging the settings inside the this.each construct. We also make sure to return the jQuery object at the end to enable chainability.

    With this, our refactoring is complete. We should be able to invoke our plugin and create as many graphs as needed.

    Adding Eye Candy

    Now that our conversion is complete, we can work on making it visually better. We are going to do a number of things here. We’ll look at each of them separately.

    Themes

    The older version used a bland gray to draw the graphs. We are going to implement a theming mechanism for the bars now. This, by itself, consists of a series of steps.


    Ocean: The default theme
    Foliage
    Cherry Blossom
    Spectrum Adding it to the Options
    var defaults = {
                 // Other defaults here
    	 	 	 theme: "Ocean",
               }; 

    We add a theme option to the defaults enabling the user to change the theme to any of the four presets available.

    Setting the Currently Selected Theme
    function grabValues ()
    	 {
    	 	// Previous code
    
    		switch(option.theme)
    		{
    			case 'Ocean':
    			gTheme = thBlue;
    			break;
    			case 'Foliage':
    			gTheme = thGreen;
    			break;
    			case 'Cherry Blossom':
    			gTheme = thPink;
    			break;
    			case 'Spectrum':
    			gTheme = thAssorted;
    			break;
    		}
    	 }  

    A simple switch construct looks at the option.theme setting and points the gTheme variable to the necessary colours array. We use descriptive names for the themes instead of generic ones.

    Defining the Colours Array
    // Themes
    	var thPink = ['#FFCCCC','#FFCCCC','#FFC0C0','#FFB5B5','#FFADAD','#FFA4A4','#FF9A9A','#FF8989','#FF6D6D'];
    	var thBlue = ['#ACE0FF','#9CDAFF','#90D6FF','#86D2FF','#7FCFFF','#79CDFF','#72CAFF','#6CC8FF','#57C0FF'];
    	var thGreen = ['#D1FFA6','#C6FF91','#C0FF86','#BCFF7D','#B6FF72','#B2FF6B','#AAFE5D','#A5FF51','#9FFF46'];
    	var thAssorted = ['#FF93C2','#FF93F6','#E193FF','#B893FF','#93A0FF','#93D7FF','#93F6FF','#ABFF93','#FF9B93']; 

    We then define a number of arrays, each holding a series of shades of a specific colours. They start off with the lighter hue and keep on increasing. We’ll loop through these arrays later. Adding themes is as simple as adding an array for the specific colour you need, and then modifying the earlier switch to reflect the changes.

    The Helper Function
    function getColour (param)
          {
             return Math.ceil(Math.abs(((gValues.length/2) -param)));
    	  } 

    This is a tiny function which lets us achieve and apply a gradient like effect to the graphs. Essentially, we compute the absolute difference between half of the number of values to be rendered and the passed parameter, which is the index of the currently selected item in the array. This way, we are able to create a smooth gradient. Since we’ve only defined nine colours in each of the colours array, we are limited to eighteen values a graph. Extending this number should be fairly trivial.

    Setting the fillStyle
    function drawGraph ()
    	 {
    	    for(index=0; index<gValues.length; index++)
    	      {
    		    ctx.save();
    			ctx.fillStyle = gTheme[getColour(index)];
    	        ctx.fillRect( x(index), y(gValues[index]), width(), height(gValues[index]));
    		    ctx.restore();
    	      }
    	 }
    

    This is where we actually theme the graphs. Instead of setting a static value to the fillStyle property, we use the getColour function to retrieve the necessary index of the element in the currently selected theme’s array.

    Opacity

    Next up, we are going to give the user the ability to control the opacity of the bars drawn. Settings this is a two-step process.


    With no transparency
    With a value of 0.8 Adding it to the Options
    var defaults = {
                // Other defaults here
    	 	 	 barOpacity : 0.8,
               }; 

    We add a barOpacity option to the defaults, enabling the user to change the opacity of the graphs to a value from 0 to 1, where 0 is completely transparent, and 1 is completely opaque.

    Setting the globalAlpha
    function drawGraph ()
    	 {
    	    for(index=0; index<gValues.length; index++)
    	      {
    		    ctx.save();
    			ctx.fillStyle = gTheme[getColour(index)];
                ctx.globalAlpha = option.barOpacity;
    	        ctx.fillRect( x(index), y(gValues[index]), width(), height(gValues[index]));
    		    ctx.restore();
    	      }
    	 }

    The globalAlpha property controls the opacity or transparency of the rendered element. We set this property’s value to the passed value or the default value to add a bit of transparency. As a sensible default, we use a value of 0.8 to make it just a tiny bit transparent.

    Grid

    A grid can be extremely useful in processing the data presented in a graph. Though I initially wanted a proper grid, I later settled for a series of horizontal lines lining up with the Y axis labels and completely threw away the vertical lines, since they just got in the way of the data. With that out of way, let’s go implement a way to render it.


    With grid disabled
    With grid enabled

    Creating the lines using paths and the lineTo method seemed to be the most obvious solution for drawing the graphs, but I happened to run into a rendering bug which made this approach unsuitable. Hence I am sticking with the fillRect method to create these lines too. Here is the function in its entirety.

    function drawGrid ()
          {
    		  for(index=0; index<option.numYlabels; index++)
    	      {
    		   ctx.fillStyle = "#AAA";
    		   ctx.fillRect( option.xOffset, y(yLabels[index])+3, gWidth, 1);
    		  }
          }
    

    This is very similar to drawing the Y axis labels, except that instead of rendering a label, we draw a horizontal line spanning the width of graph with a width of 1 px. The y function helps us in the positioning.

    Adding it to the Options
    var defaults = {
                 // Other defaults here
    	 	 	 disableGrid : false,
               }; 

    We add a disableGrid option to the defaults, enabling the user to control whether a grid is rendered or not. By default, it is rendered.

        // Function calls
        	if(!option.disableGrid) { drawGrid(); }    

    We just check whether the user wants the grid to be rendered and proceed accordingly.

    Outlines

    Now that the bars all are coloured, it lacks accent against a lighter background. To rectify this, we need a 1px stroke. There are two ways to do this. The first, and easiest, way would be to just add a strokeRect method to the drawGraph method; or, we could use the lineTo method to quickly stroke the rectangles. I chose the former route since as before the lineTo method threw some weird rendering bug at me.


    With no stroking
    With stroking Adding it to Options

    First we add it to the defaults object to give the user control of whether this is applied or not.

    var defaults = {
                 // Other defaults here
    	 	 	 showOutline : true,
               }; 
    function drawGraph ()
    	 {
    	       // Previous code
    			if (option.showOutline)
    			{
    			ctx.fillStyle = "#000";
    			ctx.strokeRect( x(index), y(gValues[index]), width(), height(gValues[index]));
    			}
    			// Rest of the code
    	      }
    	 }

    We check whether the user wants to render the outlines, and, if yes, we proceed. This is almost the same as rendering the actual bars except that instead of using the fillRect method we use the strokeRect method.

    Shading

    In the original implementation, there is no differentiation between the canvas element itself, and the actual rendering space of the bars. We’ll rectify this now.


    With no shading
    With shading
    function shadeGraphArea ()
          {
    	    ctx.fillStyle = "#F2F2F2";
    	    ctx.fillRect(option.xOffset, 0, gWidth-option.xOffset, gHeight);
          }

    This is a tiny function which shades the required area. We cover the canvas element minus the area covered by the labels of both axes. The first two parameters point to the x and y coordinates of the starting point, and the last two point to the required width and height. By starting at option.offset, we eliminate the area covered by the Y axis labels, and by limiting the height to gHeight, we eliminate the X axis labels.

    Adding Features

    Now that our graph looks pretty enough, we can concentrate on adding some new features to our plugin. We’ll look at each separately.

    Consider this graph of the famous 8K peaks.

    When the highest value is sufficiently high enough, and most of the values fall within 10% of the maximum value, the graph ceases to be useful. We have two ways to rectify this.

    ShowValue

    We are going to start with the easier solution first. By rendering the value of the respective graphs at the top, the problem is virtually solved since the individual values can be easily differentiated. Here is how it is implemented.

    var defaults = {
                 // Other defaults here
    	 	 	 showValue: true,
               }; 

    First we add an entry to the defaults object to enable the user to switch it on and off at will.

        // Function calls
    	if(option.showValue) { drawValue(); }

    We check whether the user wants the value to be shown and proceed accordingly.

    function drawValue ()
          {
    		  for(index=0; index<gValues.length; index++)
    	      {
    		      ctx.save();
    			  ctx.fillStyle= "#000";
    			  ctx.font = "10px 'arial'";
    			  var valAsString = gValues[index].toString();
    		      var valX = (option.barWidth/2)-(valAsString.length*3);
    		      ctx.fillText(gValues[index], x(index)+valX,  y(gValues[index])-4);
    			  ctx.restore();
    		  }
          } 

    We iterate through the gValues array and render each value individually. The computations involving valAsString and valX are nothing but tiny calculations to aid us in the correct indentations, so it doesn’t look out of place.

    Scale

    This the harder of the two solutions. In this method, instead of starting the Y axis labels at 0, we start a lot closer to the minimum value. I’ll explain as we go. Do note that, in the above example, the difference between subsequent values with respect to the maximum value is pretty insignificant and doesn’t show its effectiveness as much. Other data sets should give easier to parse results.

    Adding it to Options
    var defaults = {
                 // Other defaults here
    	 	 	 scale: false
               }; 
    Updating the Scale Function

    Since the scale function is an integral part of the rendering process, we need to update it to allow the scaling feature. We update it like so:

    function scale (param)
          {
    	   return ((option.scale) ? Math.round(((param-minVal)/(maxVal-minVal))*gHeight) : Math.round((param/maxVal)*gHeight));
          }

    I know this looks a little complicated, but it looks that way only due to use of the ternary conditional operator. Essentially, we check the value of option.scale and if it says false, the older code is executed. If it is true, instead of normalizing the value as a function of the maximum value in the array, we now normalize it to be a function of the difference between the maximum and minimum values. Which brings us to:

    Updating the maxValues Function

    We now need to find out both the maximum and minimum value, as opposed to only the maximum we had to before. The function is updated to this:

    function minmaxValues (arr)
         {
    		maxVal=0;
    
    	    for(i=0; i<arr.length; i++)
    	    {
    		 if (maxVal<parseInt(arr[i]))
    		 {
    		 maxVal=parseInt(arr[i]);
    	     }
    	    }
    		minVal=maxVal;
    		for(i=0; i<arr.length; i++)
    	    {
    		 if (minVal>parseInt(arr[i]))
    		 {
    		 minVal=parseInt(arr[i]);
    	     }
    		}
    	   maxVal*= 1.1;
           minVal = minVal - Math.round((maxVal/10));
    	 }

    I am sure you could accomplish the same in a single loop without using as many lines of code as me, but I was feeling particularly uncreative at that time so bear with me. With the calculation formalities out of the way, we issue a 5% increase to the maxVal variable and to the minVal variable, we subtract a value equal to 5% of maxVal’s value. This is to ensure the bars don’t touch the top everytime and the differences between each Y axis labels is uniform.

    Updating the drawYlabels Function

    With all the groundwork done, we now proceed to update the Y axis label rendering routine to reflect the scaling.

    function drawYlabels()
          {
    		 ctx.save();
    	     for(index=0; index<option.numYlabels; index++)
    	      {
    			  if (!option.scale)
    			  {
    		  		 yLabels.push(Math.round(maxVal/option.numYlabels*(index+1)));
    			  }
    			  else
    			  {
    				  var val= minVal+Math.ceil(((maxVal-minVal)/option.numYlabels)*(index+1));
    		  		  yLabels.push(Math.ceil(val));
    			  }
    		   ctx.fillStyle = option.labelColour;
    		   var valAsString = yLabels[index].toString();
    		   var lblX = option.xOffset - (valAsString.length*7);
    		   ctx.fillText(yLabels[index], lblX, y(yLabels[index])+10);
    	      }
    		   if (!option.scale)
    		   {
    	        	ctx.fillText("0", option.xOffset -7, gHeight+7);
    		   }
    		  else
    		  {
    		    var valAsString = minVal.toString();
    		    var lblX = option.xOffset - (valAsString.length*7);
    		    ctx.fillText(minVal, lblX, gHeight+7);
    		  }
    		  ctx.restore();
          } 

    Pretty meaty update if you ask me! The core of the function remains the same. We just check whether the user has enabled scaling and branch off the code as needed. If enabled, we alter the way the Y labels are assigned to make sure they adhere to the new algorithm. Instead of the maximum value divided into n number of evenly spaced numbers, we now compute the difference between the maximum and minimum value, divide it into uniformly spaced numbers, and add it to the minimum value to build our array of Y axis labels. After this, we proceed as normal, rendering each label individually. Since we rendered the bottom-most 0 manually, we have to check whether scaling is enabled and then render the minimum value in its place. Don’t mind the small numerical additions to each passed parameter; it is just to make sure each element of the graph lines up as expected.

    Dynamic Resizing

    In our previous implementation, we hard coded the dimensions of the graph, which presents significant difficulty when the number of values change. We are going to rectify this now.

    Adding it to the Options
    var defaults = {
                // Other defaults here
    	 	 	 cvHeight: 250, //In px
               }; 

    We let the user set the height of the canvas element alone. All other values are calculated dynamically and applied as needed.

    Updating the initCanvas Function

    The initCanvas function handles all the canvas initialization, and, hence, needs to be updated to implement the new functionality.

    function initCanvas ()
    	 {
    		 $("#"+dataSource).after("<canvas id=\"bargraph-"+dataSource+"\" class=\"barGraph\"> </canvas>");
    
    	 	// Try to access the canvas element
         	cv = $("#bargraph-"+dataSource).get(0);
    	 	cv.width=gValues.length*(option.barSpacing+option.barWidth)+option.xOffset+option.barSpacing;
    		cv.height=option.cvHeight;
    		gWidth=cv.width;
    		gHeight=option.cvHeight-20;
    
    	 	if (!cv.getContext)
    	 	{ return; }
    
         	// Try to get a 2D context for the canvas and throw an error if unable to
         	ctx = cv.getContext('2d');
    	 	if (!ctx)
    	 	{ return; }
    	 }

    After injecting the canvas element, we obtain a reference to the created element. The canvas element’s width is calculated as a function of the number of elements in the array – gValues , the space between each bar – option.barSpacing, the width of each bar itself – option.barWidth and finally option.xOffset. The graph’s width changes dynamically based on each of these parameters. The height is user modifiable and defaults to 220px with the rendering area for the bar’s itself being 220px. The 20px is allocated to the X axis labels.

    Hiding the Source

    It makes sense that the user might want to hide the source table once the graph has been created . With this in mind, we let the user decide whether to remove the table or not.

    var defaults = {
                // Other defaults here
    			 hideDataSource: true,
               }; 
    	if (option.hideDataSource) { $("#"+dataSource).remove();}

    We check whether the user wants to hide the table and if yes, we remove it completely form the DOM using jQuery’s remove method.

    Optimizing our Code

    Now that all the hard work has been done, we can review how to optimize our code. Since this code has been written entirely for teaching purposes, most of the work has been encapsulated as separate functions and moreover they are a lot more verbose than they need to be.

    If you really want the leanest code possible, our entire plugin, excluding the initialization and computation, can be rewritten within two loops. One looping through the gValues array to draw the bars themselves and the X axis labels; and the second loop iterating from 0 to numYlabels to render the grid and the Y axis labels. The code would look a lot messier, however, it should lead to a significantly smaller code base.

    Summary

    That’s it folks! We’ve created a high level plugin completely from scratch. We looked at a number of topics in this series including:

    • Looking at the canvas element’s rendering scheme.
    • Some of the canvas element’s rendering methods.
    • Normalizing values enabling us to express it as a function of another value.
    • Some useful data extraction techniques using jQuery.
    • The core logic of rendering the graph.
    • Converting our script to a full-fledged jQuery plugin.
    • How to enhance it visually and extend it even further feature-wise.

    I hope you’ve had as much fun reading this as I had writing it. This being a 270-odd line work, I am sure I left out something. Feel free to hit the comments and ask me. Or criticize me. Or praise me. You know, it’s your call! Happy coding!


  • Permalink for 'Fun With Canvas: Create a Bar Graphing Plugin, Part 1'

    Fun With Canvas: Create a Bar Graphing Plugin, Part 1

    Posted: April 8th, 2010, 8:56am MDT by Siddharth

    In this two-part series, we’ll combine the versatile canvas element with the robust jQuery library to create a bar graphing plugin. In this first part, we are going to code the core logic of the plugin as a standalone version.

    Today, we are going to create a bar graphing plugin. Not an ordinary plugin, mind you. We’ll show some jQuery love to the canvas element to create a very robust plugin.

    In this two-part article, we will start from the beginning by implementing the logic of the plugin as a standalone script, refactoring it into a plugin and then finally adding all the additional eye candy on top of the plugin code. In this first part, we are going to deal solely with implementing the core logic.

    Need an example before we get started? Here you go!


    Different graphs created with supplying different settings to our plugin

    Satisfied? Interested yet? Let’s start.

    Functionality

    Our plugin needs to accomplish some basic things whilst not doing some other things. Let me elucidate:

    • As usual, we are going to utilize only the canvas element and JavaScript. No images of any kind, no broken CSS techniques, no prerendering. Plain old (or is it new?) canvas element along with some jQuery to lighten our workload.
    • With respect to the data source, we are going to pull all of the data directly from a standard table. No arrays to pass on the plugin at startup. This way the user can just put all the data in a table and then invoke our plugin. Plus, it is much more accessible.
    • No special markup for the table acting as the data source and definitely no special classes names for the data cells. We are going to utilize only the ID of the table and pull all our data from there.
    • No flimsy text overlay for rendering the labels and such on the graph. It is not only highly tedious but the rendered text isn’t part of the graph when it is saved. We are going to use the fillText and strokeText as defined by the WHATWG specs.
    Dependencies

    As we are delving into the world of cutting-edge, still not fully specified, technology, we do have some dependencies. For the canvas element to work, most modern browsers are sufficient. But since we make use of the new text rendering API, we need newer builds. Browsers utilizing the Webkit engine r433xx and above or the Gecko engine 1.9.1 and above should be excellent platforms for the plugin. I recommend grabbing a nightly build of Chromium or Firefox.

    Before We Start

    I’d like to mention that our plugin is purely for learning purposes. This plugin is in no way meant to replace other full-fledged graphing plugins like Flot, Plotr and such. Also the code is going to be as verbose as possible. You could write far, far more efficient code but for the sake of learning, everything is going to be as uncomplicated as possible. Feel free to refactor it in favor of efficiency in your production code.

    The HTML Markup
    <!DOCTYPE html>
    <html lang="en-GB">
    <head>
    <title>OMG WTF HAX</title>
    </head>
    
    <body>
    
    <table width="200" border="0" id="data">
    
     <tr>
    	<th>Year</th>
    	<th>Sales</th>
     </tr>
    
     <tr>
    	<td>2009</td>
    	<td>130</td>
     </tr>
    
     <tr>
    	<td>2008</td>
    	<td>200</td>
     </tr>
    
     <tr>
    	<td>2007</td>
    	<td>145</td>
     </tr>
    
     <tr>
    	<td>2006</td>
    	<td>140</td>
     </tr>
    
     <tr>
    	<td>2005</td>
    	<td>210</td>
     </tr>
    
     <tr>
    	<td>2004</td>
    	<td>250</td>
     </tr>
    
     <tr>
    	<td>2003</td>
    	<td>170</td>
     </tr>
    
     <tr>
    	<td>2002</td>
    	<td>215</td>
     </tr>
    
     <tr>
    	<td>2001</td>
    	<td>115</td>
     </tr>
    
     <tr>
    	<td>2000</td>
    	<td>135</td>
     </tr>
     <tr>
    	<td>1999</td>
    	<td>110</td>
     </tr>
    
     <tr>
    	<td>1998</td>
    	<td>180</td>
     </tr>
    
     <tr>
    	<td>1997</td>
    	<td>105</td>
     </tr>
    
    </table>
    
    <canvas id="graph" width="550" height="220"></canvas>
    
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="mocha.js"></script>
    
    </body>
    </html>
    

    Nothing special about the markup. I’ll do a quick overview anyway.

    • We begin by including the requisite doctype. Since we are using the canvas element, we use the appropriate one for HTML 5.
    • The data source table is then defined. Do notice that no special markup is being described or new classes being defined and assigned inside its members.
    • A canvas element is defined and then assigned an ID to later reference it to. This specific canvas element will only be here for the standalone version. In the plugin version, the canvas element and its attributes will be injected dynamically into the DOM and then manipulated as needed. For progressive enhancement this way works out a lot better.
    • Finally, we include the jQuery library and our custom script. As Jeffrey has mentioned time and again, including scripts at the end of the document is always a good idea.
    The Canvas Grid

    Before we start the Javascript, let me explain the canvas coordinate system. The top-left corner acts as the origin i.e. (0, 0). Points are then measured with respect to the origin with x increasing along the right and y increasing along the left. For the mathematically inclined, we are effectively working in the 4th quadrant except that we take the absolute value of y instead of its negative value. If you have worked with graphics in other languages you should be at home here.


    The canvas co-ordinate system The Rectangle Rendering Routine

    Canvas’ rectangle rendering routine will be used extensively through out the article to render the bars, the grid and some other elements. With that in mind, let’s take a short look at those routines.

    Of the three routines available, we will be using the fillRect and strokeRect methods. The fillRect method actually fills the rendered rectangle while the strokeRect method only strokes the rectangles. Other than that, both the methods take the same parameters.

    • x – The x coordinate of the point from where to start drawing.
    • y – The y coordinate with respect to the origin.
    • width – Defines the width of the rectangle to be drawn.
    • height – Defines the height of the rectangle.
    The Javascript Magic

    As always, I highly recommend you to download the source code and have it on the side for reference. It’s easier to look at the big picture and parse each function one by one than look at each function individually and then create the big picture in your mind.

    Variable Declaration
    	var
    		barSpacing = 20,
    	 	barWidth = 20,
    	    cvHeight = 220,
    		numYlabels = 8,
    		xOffset = 20,
    		gWidth=550,
    		gHeight=200;
    
    	var maxVal,
        	gValues = [],
    	    xLabels = [],
    		yLabels = [];
    
        var cv, ctx;
    
    Graph variables
    • xLabels – An array which holds the value of the labels of the X axis.
    • yLabels – Same as above except that it contains the values of the Y axis labels.
    • gValues – Array which holds all the graph data we pull off the data source.
    • cv – Variable to point towards the canvas element.
    • ctx – Variable to refer to the context of the canvas element.
    Graph Option Variables

    These variables hold hard coded values to aid us in positioning and layout of the graph and the individual bars.

    • barSpacing – Defines the spacing between individual bars.
    • barWidth – Defines the width of each individual bar.
    • cvHeight – Defines the height of the canvas element. Hard coded since we created the canvas element beforehand. Plugin version varies in this functionality.
    • numYlabels – Defines the number of labels to be drawn in the Y axis.
    • xOffset – Defines the space between the beginning of the canvas element and the actual graph. This space is utilized for drawing the labels of the Y axis.
    • gWidth, gHeight – Hard coded values holding the dimension of the actual rendering space of the graph itself.

    How each variable controls the appearance of the graph Grabbing the Values

    With jQuery’s strong selector engine it becomes very easy for us to get the data we need. Here we have a number of ways to access the necessary elements. Let me explain a few below:

    $("tr").children("td:odd").each(function(){
    //code here
    });

    The simplest way to access the necessary rows. Looks for a tr element and then accesses every other td element. Fails miserably when you have more than one table on your page.

    $("#data").find("td:odd").each(function(){
    //code here
    });

    A much more straight forward way. We pass in the ID of the table and then access every other row.

    $("#data tr td:odd").each(function(){
    //code here
    });

    Same as above except that we just use CSS style selector syntax.

    $("#data tr td:nth-child(2)").each(function(){
    //code here
    });

    The version we are going to use today. This way is a lot better if we need to grab data from a different row or, if needed, multiple rows.

    The final version looks like so:

    function grabValues ()
    	 {
    	 	// Access the required table cell, extract and add its value to the values array.
    		 $("#data tr td:nth-child(2)").each(function(){
    		 gValues.push($(this).text());
    	 	 });
    
    		 // Access the required table cell, extract and add its value to the xLabels array.
    		 $("#data tr td:nth-child(1)").each(function(){
    	 	xLabels.push($(this).text());
    	 	 });
    	 }
    

    Nothing complicated here. We use the snippet of code mentioned above to add the value of the table cell to the gValues array. Next, we do the same except that we access the first table cell in order to extract the requisite label for the x axis. We’ve encapsulated the data extraction logic to its own function for code reusability and readability.

    Canvas Initialization
    function initCanvas ()
    	 {
    	 	// Try to access the canvas element and throw an error if it isn't available
         	cv = $("#graph").get(0);
    	 	if (!cv)
    	 	{ return; }
    
         	// Try to get a 2D context for the canvas and throw an error if unable to
         	ctx = cv.getContext('2d');
    	 	if (!ctx)
    	 	{ return; }
    	 }
    

    Routine canvas initialization. First we try to access the canvas element itself. We throw an error if unable to. Next up, we try to obtain a reference to the 2d rendering context through the getContext method and throw an error if we’re unable to do so.

    Utility Functions

    Before we step into the actual rendering of the graph itself, we need to look at a number of utility functions which aid us greatly in the process. Each of them are tiny by themselves, but will be used extensively throughout our code.

    Determining the Maximum Value
    function maxValues (arr)
         {
    		maxVal=0;
    
    	    for(i=0; i<arr.length; i++)
    	    {
    		 if (maxVal<parseInt(arr[i]))
    		 {
    		 maxVal=parseInt(arr[i]);
    	     }
    	    }
    
    	   maxVal*= 1.1;
    	 }
    

    A small function which iterates through the passed array and updates the maxVal variable. Do note that we inflate the maximum value by 10% for special purposes. If the maximum value is left as it is, then the bar representing the topmost value will touch the edge of the canvas element which we do not want. With that in mind, a 10% increment is issued.

    Normalizing the Value
    function scale (param)
          {
    	   return  Math.round((param/maxVal)*gHeight);
          }
    

    A small function to normalize the extracted value with respect to the height of the canvas element. This function is used extensively in other functions and directly in our code to express the value as a function of the height of the canvas. Takes a single parameter.

    Returning the X Coordinate
    function x (param)
          {
    	   return (param*barWidth)+((param+1)*barSpacing)+xOffset;
          }
    

    Returns the x ordinate to the fillRect to aid us in the positioning of each individual bar. I’ll explain this a bit more in detail when it is used.

    Returning the Y Coordinate
    function y (param)
          {
    	   return gHeight - scale (param) ;
          }
    

    Returns the y ordinate to the fillRect method to aid us in the positioning of each individual bar. More explanations a bit later.

    Returning the Width
    function width ()
          {
    	   return barWidth;
          }
    

    Returns the width of each individual bar.

    Returning the height
    function height (param)
          {
    	   return scale(param);
          }
    

    Returns the height of the bar to be drawn. Uses the scale function to normalize the value and then returns it to the caller.

    Drawing the X Axis Labels
    function drawXlabels ()
          {
    		 ctx.save();
    		 ctx.font = "10px 'arial'";
    		 ctx.fillStyle = "#000";
    		 for(index=0; index<gValues.length; index++)
    	     {
    		 ctx.fillText(xLabels[index], x(index), gHeight+17);
    		 }
    		 ctx.restore();
          }
    

    A simple function to render the labels of the x axis. We first save the current state of the canvas including all the rendering settings so that anything we do inside the functions never leaks out. Then we set the size and font of the labels. Next, we iterate through the xLabels array and call the fillText method each time to render the label. We use the x function to aid us in the positioning of the labels.

    Drawing the Y Axis Labels
    function drawYlabels()
          {
    		 ctx.save();
    	     for(index=0; index<numYlabels; index++)
    	      {
    		   yLabels.push(Math.round(maxVal/numYlabels*(index+1)));
    		   ctx.fillStyle = "#000";
    		   ctx.fillText(yLabels[index], xOffset, y(yLabels[index])+10);
    	       }
    	       ctx.fillText("0", xOffset, gHeight+7);
    		   ctx.restore();
          }
    

    A slightly more verbose function. We first save the current state of the canvas and then proceed. Next we divide maxVal’s value into n elements where the variable numYlabels dictates n. These values are then added to the yLabels array. Now, as shown above, the fillText method is called to draw the individual labels with the y function aiding us in the positioning of each individual label.

    We render a zero at the bottom of the canvas to finish drawing the Y labels.

    Drawing the Graph
    function drawGraph ()
    	 {
    	    for(index=0; index<gValues.length; index++)
    	      {
    		    ctx.save();
    			ctx.fillStyle = "#B7B7B7";
    	        ctx.fillRect( x(index), y(gValues[index]), width(), height(gValues[index]));
    		    ctx.restore();
    	      }
    	 }
    

    The function which draws the actual bars in the bar graph. Iterates through the gValues array and renders each individual bar. We use the fillRect method to draw the bars. As explained above, the method takes four parameters, each of which is taken care of by our utility functions. The current index of the loop is passed to our functions as parameters along with the actual value held in the array, as needed.

    The x function returns the x co-ordinate of the bar. Each time, it is incremented by the value of the sum of barWidth and barSpacing variables.

    The y function calculates the difference between the height of the canvas element and the normalized data and returns it. I know this sounds a bit topsy turvy, but this is due to the fact that the y values on the canvas grid increase on moving down while in our graph the y values increase on moving up. Thus, we have to do a little work to make it function the way we wish.

    The width function returns the width of the individual bars themselves.

    The height function just returns the normalized value which is going to be used as the height of the bar to be drawn.

    Summary

    In this first part, we’ve implemented the base logic of our plug-in as a standalone version with bare bones looks and features. We reviewed the canvas coordinate system, the rectangle rendering methods, some nifty data extraction using jQuery’s innate awesomeness [Have I mentioned how much I like jQuery?], looked at how the labels are drawn, and finally looked at the logic behind the rendering of the graph itself.

    At the end of this article, the output should look like so.

    Next Up!

    Our current implementation is rather lacking really. It looks bland, can’t create multiple graphs on the same page, and let’s face it, is rather spartan on the features front. We are going to tackle all of that next week. In the next article we will:

    • Refactor our code towards making it a full-fledged jQuery plugin.
    • Add some eye candy.
    • Include some nifty little features.

    Questions? Criticisms? Praises? Feel free to hit the comments. Thanks for reading and, when you’re ready, move on to part two!



  • Permalink for 'How To Build a Widget to Display your Buzzing'

    How To Build a Widget to Display your Buzzing

    Posted: April 7th, 2010, 10:06am MDT by Crysfel Villa

    A couple months ago, Google released a new Twitter-like service, called Buzz. We can use this service to display our latest buzzes on any site. So, in this tutorial, I’ll guide you through the process of building your own Buzz widget.

    Step 1. Reading Public Updates from Buzz

    At the moment, there’s no API to work with the Buzz service; Google is expected to provide one within the next several months, however, for now, the public updates are available as Atom feeds.

    First, we need to get the data from the Buzz service. In order to do so, we’ll setup a PHP script that reads the data from the Buzz service. This script will be a kind of proxy that we’ll use to retrieve the data. By doing this, we can make an AJAX request, and get an XML document that contains desired updates.

    Google buzz flow

    Here’s the initial PHP code:

    header('Content-type: application/xml');	 //Setting up the response content type to XML
    $handle = fopen($_GET['url'], "r");		//Open the given URL
    
    if ($handle) {
        while (!feof($handle)) {
            $buffer = fgets($handle, 4096);		//reading the data
            echo $buffer;
        }
        fclose($handle);
    }
    

    Save this file as “readfeed.php,” and remember that this is just an example. In a real world project, you should clean the url parameter, and make sure the user is not opening something important on your file system.

    Step 2. Creating the Structure of our JavaScript Object

    Once we can read this data, we need to build an object that holds our code in JavaScript. Create a new file and name it “buzz-widget.js”. To extend an object, we need to use the “prototype” property; if you have questions about this you should watch the tutorial where Jeffrey shows us how this works with native objects.

    The structure of our object will be something like this:

    var BuzzReader = function(options){	//Step 1
    	//code for the constructor
    };
    
    BuzzReader.prototype = {			//Step 2
    	renderTo: "",
    	proxy	: "readfeed.php",
    	user	: "",
    	url		: "",
    	items	: 10,
    	onLoad	: function(){},
    	onRender: function(){},
    
    	render	: function(element){
    
    	},
    
    	read	: function(){
    
    	},
    
    	parse	: function(xml,success,response){
    
    	},
    
    	format		: function(date){
    
    	},
    
    	createDate	: function(str){
    
    	}
    };
    

    In step one, we created the constructor function for our object. Now, we’re going to check for the required configurations, and read the updates from our proxy.

    • renderTo : the element where the widget will be rendered; this property can be a jQuery selector too.
    • proxy : the URL where we’ll make an AJAX request call to retrieve our data. We already created the PHP file that reads the information from the Buzz service; by default it is “readfeed.php”.
    • user : the Buzz user we want to get the updates from.
    • items : the number of updates we are going to display in the widget.
    • onLoad : an event we’re going to trigger when the data is loaded into the widget; by default, this is an empty function.
    • onRender : this event is triggered when the widget is about to be rendered in the page; empty function by default.
    Step 3. The Constructor

    Let’s work on the constructor function of our widget.

    var BuzzReader = function(options){
    	var url = "http://buzz.googleapis.com/feeds/{user}/public/posted";	//Step 1
    	jQuery.extend(this,options || {});			//Step 2
    
    	if(this.user === "") throw "The 'user' property is required";	//Step 3
    	if(this.renderTo === "") throw "The 'renderTo' property is required";
    
    	if(this.url === "")this.url = url.replace(/{user}/g,this.user);	//Step 4
    
    	this.read();		//Step 5
    };
    

    In step one, we defined the URL of the Buzz service from which we are going to retrieve the data. We’ll replace the “{user}” string with the user configuration (see step 4).

    In step two, we overrode the default properties with the given options; we used jQuery.extend to do that.

    In step three, we checked for the required configurations, one of them is the “user” and the “renderTo”. If one of these is missing, we throw an exception. This will be useful for the developer who uses our plugin.

    In step four, we searched for the “{user}” string in the variable “url”, and replaced it with the user whose buzzes we wish to display in our widget.

    The last step is very important. Here, we start the process of reading and displaying the information.

    Step 4. Reading the Information

    We’ve setup the PHP script that pulls the data to our server. Now, we only need to make an Ajax request to retrieve the data with jQuery; let’s look at the following code:

    read	: function(){
    	this.el = jQuery(this.renderTo);		//Step 1
    	this.loader = this.el.append("<div class=\"buzz-loading\"></div>");
    	jQuery.ajax({				//Step 2
    		url		: this.proxy,
    		data	: "url="+this.url,
    		context	: this,
    		success	: this.parse
    	});
    },
    

    In step one, we appended a new element to the container, informing the viewer that we’re currently processing information.

    In step two, we made the Ajax request. The most important thing is the “context” property; this configuration will allow you to change the context of the function that is called when the server responds. Finally, we set the context to “this” which is the BuzzReader object.

    Remember that the PHP script expects the “url” parameter. so don’t forget to send it; when the server responds, the method “parse” is executed.

    Step 5. Parsing the XML Document

    The Buzz service delivered the data in an Atom feed format, so we need to parse and extract the information we need.

    This is an example of the XML document that is returned from the Buzz service:

    <?xml version="1.0" encoding="utf-8"?>
      <feed xmlns=" [www.w3.org]         xmlns:thr=" [purl.org]         xmlns:media=" [search.yahoo.com]         xmlns:activity=" [activitystrea.ms]     <link rel="self"
              type="application/atom+xml"
              href=" [buzz.googleapis.com]     <link rel="hub" href=" [pubsubhubbub.appspot.com]     <title type="text">Google Buzz</title>
        <updated>2009-12-14T20:04:39.977Z</updated>
        <id>tag:google.com,2009:buzz-feed/public/posted/117377434815709898403</id>
        <generator>Google - Google Buzz</generator>
        <entry>
          <title type="html">Buzz by A. Googler from Mobile</title>
          <published>2009-12-14T20:04:39.000Z</published>
          <updated>2009-12-14T20:04:39.977Z</updated>
          <id>tag:google.com,2009:buzz/z12bx5v5hljywtfug23wtrrpklnhf3gd3</id>
          <link rel="alternate"
                type="text/html"
                href=" [www.google.com]       <author>
            <name>A. Googler</name>
            <uri> [www.google.com]       </author>
          <content type="html">Bzz! Bzz!</content>
          <activity:verb> [activitystrea.ms]       <activity:object>
            <activity:object-type> [activitystrea.ms]         <id>webupdates:a.googler@gmail.com.1258ecae5db</id>
            <title>Buzz by A. Googler from Mobile</title>
            <content type="html">Bzz!  Bzz!</content>
          </activity:object>
          <link rel="replies"
                type="application/atom+xml"
                href=" [buzz.googleapis.com]             thr:count="0"/>
          <thr:total>0</thr:total>
        </entry>
      </feed>
    

    Once we know the response, we can parse the document quite easily with jQuery.

    parse	: function(xml,status){
    	var that = this;
    	var nodes = jQuery("entry",xml);	//Step 1
    	this.el.empty();
    	var info = [];
    	nodes.each(function(){			//Step 2
    		var date = that.createDate(jQuery("published",this).text());
    		info.push({
    			title		: jQuery("title",this).text(),
    			author		: jQuery("author > name",this).text(),
    			uri			: jQuery("author > uri",this).text(),
    			summary 	: jQuery("summary ").text(),
    			content		: jQuery("content:first",this).text(),
    			published	: that.format(date),
    			updated		: jQuery("updated",this).text(),
    			date		: date,
    			reply		: jQuery("link[rel=replies]",this).attr("href")
    		});
    	});
    	this.data = info;				//Step 3
    	this.onLoad.call(this,info);
    	this.render(this.renderTo);		//Step 4
    },
    

    We received two arguments: the first is the data, in this case a XML document; the second argument is the text status of the request.

    In step one we got all the “entry” nodes; this is the place where our Buzz updates and all the information we need is located. Next, we emptied the container of our widget and created an empty array to store our data as a JavaScript object for each node.

    In step two, we iterated through the “entry” nodes and extracted the “title”, “author”, “content” and so on. This is a really simple process; all we have to do is write the selector and set the root for the search, in this case the root is the node “entry.”

    I’d like to point out the line where we are extracting the “reply” attribute – the selector looks something like this:

    link[rel=replies]
    

    We specified that we want the node “link”, that has an attribute “rel” equal to “replies”. This is important because there are many “link” nodes within each “entry.”

    In step three, we created the “this.data” reference to the array that contains our data. After that, we executed the event “onLoad” and passed the information we extracted.

    In step four, we executed the render method.

    Before we continue with the “render” method, let’s review the “createData” and “format” methods. We call these methods for each entry.

    In the “createDate” method, we’re only going to create a new Date object with the given string. The string has the format “2009-12-14T20:04:39.977Z” so we can create the Date object as follows:

    createDate	: function(str){
    	var date = new Date();
    	date.setDate(str.substring(8,10));
    	date.setMonth(str.substring(5,7) - 1);
    	date.setFullYear(str.substring(0,4));
    	date.setUTCHours(str.substring(11,13));
    	date.setUTCMinutes(str.substring(14,16));
    	date.setUTCSeconds(str.substring(17,19));
    	return date;
    }
    

    Or we can use a simple regexp to format the string and give it to the Date constructor:

    createDate	: function(str){
    	//str = '2009-12-14T20:04:39.977Z'
    	str = str.substring(0,19).replace(/[ZT]/," ").replace(/\-/g,"/");
    	//str = '2009/12/14 20:04:39'
    	return new Date(str);
    }
    

    In the format method we are going to use the date object we just created, and return the time that is between the publication date and the system local time – for example “11 minutes ago” or “3 hours ago.”

    format		: function(date){
    	var diff   = (((new Date()).getTime() - date.getTime()) / 1000),
    		days   = Math.floor(diff / 86400),
    		months = Math.floor(days / 31);
    
    	if (isNaN(days) || days < 0)return date.toString();
    
    	if(days == 0){
    		if(diff < 60)return "Just now";
    		if(diff < 120)return "1 minute ago";
    		if(diff < 3600)return Math.floor( diff / 60 ) + " minutes ago";
    		if(diff < 7200)return "1 hour ago";
    		if(diff < 86400)return  Math.floor( diff / 3600 ) + " hours ago";
    	}else if(days < 31){
    		if(days == 1)return "Yesterday";
    		if(days < 7)return days + " days ago";
    		if(days < 31)return Math.ceil( days / 7 ) + " weeks ago";
    	}else{
    		if(months == 1)return "A month ago";
    		if(months < 12)return Math.ceil( days / 31 ) + " months ago";
    		if(months >=12)return Math.floor( days / 365 ) + " years ago";
    	}
    },
    

    The previous code, though a bit tedious, is pretty straight forward. First, we obtained the difference between the current time, and the publications date in minutes, days and months. After that, we simply compared the results, and returned a string in the correct format.

    Now let’s review the “render” method.

    Step 6. Creating the GUI

    Until now, we’ve only pulled the data from the Buzz server, and parsed the XML document. That means that we are ready to display the information on the screen.

    render	: function(element){
    	this.onRender.call(this,this);		//Step 1
    
    	var html = [];				//Step 2
    	html.push("<ul>");
    
    	for(var i = 0; i < this.items || i < this.data.lenght;i++){
    		html.push("<li><strong><a href=\""+this.data[i].uri+"\">"+this.data[i].author+"</a></strong><span>"+this.data[i].published+"</span>"+this.data[i].content+"</li>");
    	}
    	html.push("</ul>");
    
    	this.el.append(html.join(""));	//Step 3
    },
    

    In the first step, we triggered the event “onRender,” this, again, will be useful for the programmer who uses our plugin.

    In the second step, we created an array to store our dynamic HTML. After that, we created a list “ul” and then we iterated through our data, creating the “li” node for each item; you probably noticed that the “for” condition has an “or” operator; this allow us to stop the iterations when the array of data ends, or when the index “i” has reached the “items” property defined by the developer who is going to use the plugin.

    In the last step, we inserted the HTML into the container using the “append” method.

    Step 7. Using the Widget

    In order to use our widget we need to create an instance of our class “BuzzReader”, but, before doing so, let’s define where we want to render it. Create an HTML file, and, within the body element, and add the following:

    <div id="buzz">
    <div>
    	<div class="reader"></div>
    </div>
    </div>
    

    We are going to render our widget inside the div with the class “reader”, let’s create the instance of our widget as follows:

    $(function(){
    
    	new BuzzReader({
    		renderTo	: "#buzz .reader",
    		user	: "nettutsblog",
    		items	: 3
    	});
    });
    

    Don’t forget to import the jQuery library and the “buzz-widget.js” into your HTML file. If everything was configured and coded correctly, you should see something similar to the following image:

    Google buzz widget Step 8. Styling the Widget

    Well, we can now see the updates, but it doesn’t look very pretty; we need to style it a bit.

    /* step 1 */
    body{font-family:"Trebuchet MS",Arial,sans-serif;line-height:24px;font-size:14px;}
    
    /*Step 2*/
    #buzz{width:300px;margin:100px auto;border:1px solid #AFAFAF;}
    #buzz > div{background-color:#E4E4E4;border:1px solid #F6F6F6;padding:10px;}
    #buzz .reader{height:350px;overflow:auto;border:1px solid #F6F6F6;padding:80px 10px 10px 10px;background:#fff url(title.jpg) center 0 no-repeat;}
    /* Step 3 */
    #buzz ul{margin:0;padding:0;}
    #buzz ul li{list-style-type:none;color:#A3A3A3;border-bottom:1px solid #E4E4E4;margin-bottom:5px;padding-bottom:5px;}
    #buzz ul li div{color:#777;}
    #buzz ul li a{color:#444;text-decoration:none;font-weight:normal;}
    #buzz ul li a:hover{text-decoration:underline;}
    #buzz ul li span{float:right;}
    
    /* Step 4*/
    #buzz .buzz-loading{position:absolute;margin-left:240px;width:16px;height:16px;background:transparent url(ajax-loader.gif) center center no-repeat;}
    

    In the first two steps, we centered the widget on the screen, and set the size, borders and colors for the container; we also added the logo as a header for the widget.

    In the last two steps, we set the styles to the dynamic list, we changed the color of the fonts, and we added some margins, borders and paddings to our links.

    As a result we have a much more appealing product.

    Google buzz widget Step 9. Creating the Plugin

    The last step in this tutorial is to create the jQuery plugin. Let’s modify the “buzz-widget.js” file, adding the following code to the end of the file.

    jQuery.fn.buzzReader = function(options){  	//Step 1
    	return this.each(function(){
    		var opts = options || {};		//Step 2
    		opts.renderTo = this;
    		new BuzzReader(opts);		//Step 3
    	});
    };
    

    In the first step, we simply named our plugin.

    In step two, we created the configuration object if the argument “options” is empty. Next, we defined the property “renderTo” to the actual element.

    In step three, we created a new instance of our widget.

    Now, we can use our plugin in our HTML, like this:

    $(function(){
    	$("#buzz .reader").buzzReader({
    		user	: "nettutsblog",
    		items	: 3
    	});
    });
    
    Google buzz widget Conclusions

    I hope you’ve learned a bit about how to extract data from XML documents, and display your latest Buzzes on any website. Any questions? Thanks for reading!


  • Permalink for 'ASP.NET from Scratch: SQL Server'

    ASP.NET from Scratch: SQL Server

    Posted: April 6th, 2010, 8:15am MDT by Jeremy McPeak

    Part four of this series changes the lesson plan again! This lesson introduces you to Microsoft SQL Server 2008 and SQL Management Studio. Youíll learn how to create a database, add tables to it, and populate it with data. You’ll then use that data and bind it to a template control.

    The Complete Series Lesson 4: SQL Server Sell ASP.NET Components on CodeCanyon
    CodeCanyon

    Did you know that you can sell your ASP.NET scripts and components on CodeCanyon? Simply sign-up for a free author account, and start selling!


  • Permalink for 'Quick Overview: A Few Moments with Titanium'

    Quick Overview: A Few Moments with Titanium

    Posted: April 5th, 2010, 5:24pm MDT by Jeffrey Way

    Those of you who follow us on Twitter might know that I’m currently working on an iPhone app for the tutorial sites. However, there’s just one problem: I have no Objective-C experience! Luckily, a service called Appcelerator allows us to build native desktop and mobile (iPhone in my case) apps using the web technologies that we already know, like JavaScript! Before we launch an in-depth two-part series detailing how to create and sell an iPhone app from scratch later this month, I thought I’d give you a basic overview of how it works.


    Subscribe to our YouTube page to watch all of the video tutorials!


  • Permalink for 'Color Inspiration: Go Green with Envy'

    Color Inspiration: Go Green with Envy

    Posted: April 5th, 2010, 4:02pm MDT by Cameron Chapman

    Green is most often associated with nature, money, and success. Because of this, it’s most often seen on either environmental or financial institution websites. Though it mixes well with a variety of other colors, green is most often paired with neutrals. We’ve compiled twenty five perfect examples of this in today’s inspiration round-up.

    Interactive Logistixs Old Guard Logo Labs bornintents Rype Arts RedBrick Health The Organic Supermarket Candy Bouquet OnePromo Verdeo Tolingo Futurice Plant With Purpose Coachworks Consulting Gowalla Free Gobbler Chris Kaufman Apop.jp Sage Blue Jones and Palmer Shashi Tharoor Nathan Sanders Leetgeek You Grow Girl Evernote


  • Permalink for 'Quick Tip: An Introduction to jQuery Templating'

    Quick Tip: An Introduction to jQuery Templating

    Posted: April 2nd, 2010, 9:02am MDT by Andrew Burgess

    JavaScript Templating is a neat idea: it allows you to easily convert JSON to HTML without having to parse it. At Microsoft’s MIX10 conference, they announced that they are starting to contribute to the jQuery team. One of their efforts is to provide a templating plugin. In this quick tip, I’ll show you how to use it!


    Subscribe to our YouTube page to watch all of the video tutorials!

    You’ll need the data to template; you’ll likely retrieve JSON from your server; of course, Object / Array literals work just as well, so that’s what we use:

    var data = [
    		{ name : "John",  age : 25 },
    		{ name : "Jane",  age : 49 },
    		{ name : "Jim",   age : 31 },
    		{ name : "Julie", age : 39 },
    		{ name : "Joe",   age : 19 },
    		{ name : "Jack",  age : 48 }
    	];
    

    The template is written in <script type="text/html"></script> tags; for each item in your JSON, the template will render the HTML; then, it will return the entire HTML fragment to you. We can get to the JavaScript values from within the template by using {% and %} as tags. We can also execute regular JavaScript within these tags. Here’s our template:

    <li>
    	<span>{%= $i + 1 %}</span>
    	<p><strong>Name: </strong> {%= name %}</p>
    	{% if ($context.options.showAge) {  %}
    		<p><strong>Age: </strong> {%= age %}</p>
    	{% } %}
    </li>
    

    To render the data with the template, call the plugin; pass the data to the plugin method; you can optionally pass in an options object as well. (These aren’t predefined options; they’re values you want to use within the template, perhaps for branching.)

    $("#listTemplate").render(data, { showAge : true }).appendTo("ul");
    

    It’s that easy! Have fun with it! You can get the complete code for this quick tip on Github


  • Permalink for 'CodeIgniter from Scratch: Extending the Framework'

    CodeIgniter from Scratch: Extending the Framework

    Posted: April 2nd, 2010, 8:58am MDT by Burak Guzel

    In today’s screencast we are going to learn how to create our own helpers and libraries. We are also going to learn how to extend the existing helpers and libraries that come with CodeIgniter. At the end of the tutorial we will extend the Form Validation library to give it the ability to check for password strength.

    Catch Up Day 13: Extending the Framework


  • Permalink for '20 Mac Apps You’ll Use Every Day: Editor’s Choice'

    20 Mac Apps You’ll Use Every Day: Editor’s Choice

    Posted: April 1st, 2010, 10:30am MDT by Jeffrey Way

    Mac app round-ups are a dime a dozen across the web. However, there’s one problem when you’re offered 100+ to choose from: you won’t use half of them. That’s why I’ve decided to streamline the process and provide twenty of my most highly recommended Mac apps, tailored for web designers and developers. While not every app relates specifically to development, they’re all essential in your every day workflow.

    1. VMWare Fusion VMware Fusion

    While online services, like Browsershots and Adobe Browserlab are definitely helpful, there really is no substitute for testing your new website in Internet Explorer itself. When you must do so, assuming you only own a Mac, your best option is to use a virtual machine. Again, there are a variety to choose from; however, my preference is VMWare Fusion.

    “With VMware Fusion, run the most demanding Mac and Windows applications side-by-side at maximum speeds without rebooting. With over 50 new features and a new ultra-fast Migration Assistant for Windows, it’s never been easier to run Windows on your Mac.”

    2. The Hit List The Hit List

    As I run Nettuts, ThemeForest, and CodeCanyon, it’s essential that I find the best possible tools for plotting out each day. I’ve used the huge majority of the offerings, ranging from Things, to GQueues, to TeuxDeux. Truthfully, they’re all fantastic, each offering something unique. While, lately, I’ve found myself using GQueues for my day-to-day tasks, I always find myself coming back to The Hit List when preparing a new project.

    “The Hit List is a simple, yet sophisticated application to manage the daily chaos of your modern life. Based on the simple concept of making lists, The Hit List lets you plan, forget, then act when the time is right.”

    Alternative 3. TextMate TextMate

    Perhaps the most obvious choice of the bunch, but, nonetheless, it’s an essential tool for every developer. When considering sheer speed, nothing compares to TextMate.

    “TextMate brings Apple’s approach to operating systems into the world of text editors. By bridging UNIX underpinnings and GUI, TextMate cherry-picks the best of both worlds to the benefit of expert scripters and novice users alike.”

    4. TextExpander TextExpander

    If you find yourself rewriting the same lines of code, the same paragraphs, even the same signature over and over each day, you’re doing it wrong. How many hours each year would you save, simply by turning an eight second repetitive typing task into a keystroke? Especially in my particular circumstance, TextExpander is 100% a necessity.

    “Save time and effort with TextExpander! Whether it’s a simple email signature or several paragraphs of a standard response, you’ll love how easy it is to use TextExpander to avoid typing the same thing over and over.”

    5. Snippely Snippely

    As we switch from language to language, it’s nearly impossible to remember every function for every language. This is when a code collection app becomes a huge help. Need to remember the code that you use for PHP CRUD operations? Simply save it into Snippely, and return when you need it.

    While Snippely isn’t the most glamorous app, and is depressingly simple, it still gets the job done.

    “Snippely is a basic text and code organizational tool. Instead of storing bits of code, quick notes, and memos in text files all over your hard drive, this application will let you save and organize “snippets” in one convenient location. A snippet is a collection of one or more pieces of code and notes. Snippets are stored in groups for organization and quick retrieval.”

    6. Skitch Skitch

    Skitch is easily one of my favorite, and most helpful apps for Mac. Further, it’s one of those apps that you truthfully can’t find on the PC, for some reason. If I need to point out a strange issue on ThemeForest to my boss, I can use Skitch to select a portion of the page as a snapshot, then add some arrows and text describing the problem on the image, and upload it Skitch’s server for hosting – all within a time span of about twenty seconds.

    “Skitch.com is a webservice that works hand in hand with our application Skitch to give you 1-click uploading of images for fast and fun image sharing.”

    7. Sequel Pro Sequel Pro

    When working with MySQL, PHPMyAdmin definitely gets the job done, but it sure is ugly! Sequel Pro is the beautiful, and free alternative!

    “Sequel Pro is a fast, easy-to-use Mac database management application for working with MySQL databases.”

    8. Google Quick Launch Quick Launch

    While QuickSilver has generally has been the quick-launch app tool of choice, Google has a fantastic alternative that’s even better, called Quick Search Box. In addition to loading applications with only a keystroke, you also have the ability to perform Google searches, and search your Gmail account.

    “With Google Quick Search Box you can search for information from just about anywhere. As you type, suggestions will appear that match your query, ranging from applications and local files on your computer, to web search and navigational suggestions, to items from your browser history and contacts.”

    Alternative 9. Photoshop Photoshop

    Obvious choice? Most definitely. However, that’s only a testament to its importance. In addition to Gmail, Photoshop is open on my computer at all times. And while free alternative like Gimp might be helpful, I honestly question your dedication to web design if you’re not using the industry standard.

    “Adobe® Photoshop® CS4 software provides improved access to its unrivaled power through a more intuitive user experience, greater editing freedom, and significant productivity enhancements.”

    Alternative 10. Notify Notify

    For those brief moments when your email client isn’t open, Notify makes for a fantastic alternative. A tiny icon is placed at the top of your desktop, displaying the number of items in your inbox. It also notifies you (obviously) when new emails arrive, and allows you to read, respond to, and delete them with ease.

    “Do you access your email in a browser? Then you’ll love Notify. Notify is an awesome email notifier for Mac OS X. It fits seamlessly into your menubar, only vying for your attention when you have new mail. Notify supports mutliple accounts, including Gmail/Google Apps, MobileMe, and Rackspace Email.”

    11. Mamp Mamp

    For PHP/MySQL development, Mamp makes setting up a local web server on your computer laughably simple.

    “The one-click solution for setting up your web server.”

    12. Forklift Forklift

    Forklift is one of my more recent discoveries this year. I often find myself trying to drag files from one folder to another. Using Mac’s finder, this can be a bit of a pain. Also, every day, I’m transferring files to Envato’s S3 accounts. Forklift makes this process as easy as it can possibly be. While not free, I highly recommend that you pick this one up.

    Alternative

    “Forklift is a powerful file manager and ferociously fast FTP client clothed in a clean and versatile UI that offers the combination of absolute simplicity and raw power expected from a well-executed Mac software”

    13. Dropzone Dropzone

    Dropzone is a helpful little tool that automates the process of common tasks. For example, when you download an app, you must then double click on the app, install it, and finally drag the app to your Applications folder. It’s not a huge time waster, though every thirty seconds matters! With Dropzone, you drag your file into the app, and it automatically performs these tasks for you.

    This is only one of many operations that Dropzone performs. Be sure to check it out!

    “The Swiss army knife of drag-and-drop for the Mac. Dropzone makes it faster and easier to get things done on your Mac.”

    14. Coda Coda

    Perhaps side-by-side with TextMate, Coda is one of the best code editors (if not the best) that the Mac has to offer. Especially when you find yourself editing files stored on your server, there’s no easier tool.

    “So, we code web sites by hand. And one day, it hit us: our web workflow was wonky. We’d have our text editor open, with Transmit open to save files to the server. We’d be previewing in Safari, adjusting SQL in a Terminal, using a CSS editor and reading references on the web. “This could be easier,” we declared. “And much cooler.”

    15. Echofon Echofon

    I’m on Twitter every day, for better or worse. Surprisingly, the app that I most prefer flies right under the radar. Maybe I’m missing something, but it, along with its iPhone companion app, does everything that I could possibly require (excluding scheduled tweets): multiple accounts, search, etc. P.S. If you’re not following us on Twitter, do so before I cut you!

    “Echofon for mac suits those who do intense Twittering, and those who want to something that stays out of their way until they need it. The interface contracts and expands to your ideal size, and the drawer will show you details only when you need it.”

    16. Cinch Cinch

    There’s no denying that Windows 7 is a vast improvement over its predecessor. One of my favorite (though simple) new features is the ability to lock windows to different sides of the screen. I’m sure you’ve seen the commercial of the mechanic advertising this feature on TV. Drag one window to the left-side of the screen, and it automatically expands/contracts to take up 50% width of the monitor. You can then do the same to another window, to quickly allow for a side-by-side view. While the Mac doesn’t natively support this, you can use an app called Cinch to mimic this functionality. I use it every day!

    “Cinch gives you simple, mouse-driven window management by defining the left, right, and top edges of your screen as ‘hot zones’. Drag a window until the mouse cursor enters one of these zones then drop the window to have it cinch into place.”

    17. 1Password 1Password

    According to 1Password, I have over fifty different accounts and passwords on the web. Assuming we’re smart and use unique passwords for each account, it’s nearly impossible to remember every username and password without tearing out your hair. With 1Password, you simply store your login credentials, and use Command + Backslash to automatically login. This single app has saved me dozens and dozens of hours over the last year.

    “1Password can create strong, unique passwords for you, remember them, and restore them, all directly in your web browser.”

    Alternative 18. Dropbox Dropbox

    Ever needed to quickly transfer a file from your laptop over to your desktop? It’s a bit of a drag, isn’t it? What did you do, email yourself with the file? Even burn a CD to transfer it? How old-fashioned is that!? Instead, use DropBox to make the process as simple as it can possibly be. While not specifically a Mac “app,” it’s definitely essential to your work-flow.

    “Dropbox allows you to sync your files online and across your computers automatically.”

    19. WebStorm

    I discovered this new code editor last month, and am very excited about it. Be sure to watch my three minute video above for a quick overview of some of my favorite features.

    “WebStorm is an Integrated Development Environments for web programming, providing a unique user experience for editing HTML, CSS, JavaScript, XMl, as well as for working with VCS and SQL.”

    Conclusion

    While there are countless more offerings available around the web, the items listed above are what I use every single day. Did I miss any? Have any recommendations?


  • Permalink for 'Celebrating the Launch of GIFtuts+'

    Celebrating the Launch of GIFtuts+

    Posted: March 31st, 2010, 7:46pm MDT by Skellie

    Today we’re pleased to introduce the newest member of the Tuts+ family: GIFtuts+. We’ll be publishing tutorials and video training on creating gorgeous animated GIFs in Photoshop, Ulead GIF Animator and Microangelo. If you’ve ever wanted to freely learn how to create ornamental animated GIFs and impressive navigational graphics for Web Pages, now is the time to start! Hit the jump to learn all about GIFtuts+ and check out the newest site in the Tuts+ Network family.

    We care about GIFs Happy artist.

    Creating GIFs is a topic that we often get asked about. Whenever we’ve published a tutorial on creating GIFs on Psdtuts+, like our Animated Snowman Tutorial, it’s been very popular. We thought it was about time we gave this in-demand but under-served aspect of design education its own dedicated Tuts+ site!

    Giftuts+ Logo

    Here’s a sneak peek of what the site will have to offer in the coming weeks:

    • How to Create Hellish Animated Flaming Skulls
    • How to Make a Slick ‘Under Construction’ Sign
    • Make a Blood-spattering Stick-figure Animation

    We want to take a moment to thank our team of developers and designers for all their hard work on the new site: Derek, Fred and Ryan, thanks guys!

    Cowboy on computer. Enough talk… it’s time to get moving and visit GIFtuts+! ENTER ENTER And… our newest Envato marketplace
      Pointing hand.
    • Tying in with the launch of our newest Tuts+ site we’re also debuting a new Envato marketplace to a select group of Beta testers. If you’re interested in making passive income from your GIFs – meaning you make a GIF once, then sell it many times – we have an exciting announcement for you.

    GifHole is looking for talented animated/static GIF artists to help set the standard for a new online GIF marketplace. Envato (the makers of Tuts+) are developing this site for all those who are looking for quality GIF stock and those who want to become authors in this field and earn money by selling their work online, again and again.

    Giftuts+ Logo

    GifHole will complement the existing Envato marketplaces: ActiveDen, AudioJungle, ThemeForest, VideoHive and GraphicRiver.

    Flaming Skull


  • Permalink for 'Generating a Particle System with JavaScript: New Premium Tutorial'

    Generating a Particle System with JavaScript: New Premium Tutorial

    Posted: March 31st, 2010, 5:18pm MDT by Abhin Sharma

    If you’ve ever seen a fireworks effect, created in Flash, I’ll show you how to reproduce the effect using pure JavaScript in this week’s Premium tutorial! Why let the Flash developers have all the fun? Help give back to Nettuts+ by becoming a Premium member.


    Particle System
    Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Join today!


  • Permalink for 'How to Create an Infinite Scroll Web Gallery'

    How to Create an Infinite Scroll Web Gallery

    Posted: March 31st, 2010, 4:30am MDT by Alexandru Pitea

    When working my way through a web gallery, I find it annoying when I must change pages; so in today’s tutorial, we will learn how to create an auto-generating, one-page, infinite scrolling gallery with PHP and AJAX. Let’s get started!

    Step 1: Project Outline

    We’ll begin with a normal gallery page that has a container for our images, and we’ll monitor the scroll position by calling a JavaScript function at a quick interval. Each time the scroll bar is near the bottom, we’ll make an AJAX request to an external PHP file, which returns a list of image names. Now, all we’ll need to do is add these images to our container, thus modifying the page height moving the scroll position higher.

    Step 2: HTML Markup

    We’ll work with a very basic setup: a header and the container for our images. The thumbnails will be grouped in sets of three rows, each will contain a link, referencing the full size image. After each group, we will add some text showing the total number of displayed images, and a link to the top of the page.

    <body>
    	<div id="header">Web Gallery | Infinite Scroll</div>
    	<div id="container">
    		<a href="img/Achievements.jpg"><img src="thumb/Achievements.jpg" /></a>
    		<a href="img/Bw.jpg"><img src="thumb/Bw.jpg" /></a>
    		<a href="img/Camera.jpg"><img src="thumb/Camera.jpg" /></a>
    		<a href="img/Cat-Dog.jpg"><img src="thumb/Cat-Dog.jpg" /></a>
    		<a href="img/CREATIV.jpg"><img src="thumb/CREATIV.jpg" /></a>
    		<a href="img/creativ2.jpg"><img src="thumb/creativ2.jpg" /></a>
    		<a href="img/Earth.jpg"><img src="thumb/Earth.jpg" /></a>
    		<a href="img/Endless.jpg"><img src="thumb/Endless.jpg" /></a>
    		<a href="img/EndlesSlights.jpg"><img src="thumb/EndlesSlights.jpg" /></a>    
    
    		<p>9 Images Displayed | <a href="#header">top</a></p>
    	    <hr />
    	</div>
    </body>
    
    Step 3: CSS

    The CSS is also quite basic. First, we define the page colors and positioning for the header and paragraphs.

    body{
    	background:#222;
    	color:#666;
    }
    #header{
    	font-family:Arial, Helvetica, sans-serif;
    	font-size:24px;
    	font-weight:bold;
    	text-align:left;
    	text-indent:35px;
    	margin: 0 auto;
    	width:800px;
    	margin-bottom:10px;
    }
    hr{
    	margin: 20px;
    	border:none;
    	border-top: 1px solid #111;
    	border-bottom: 1px solid #333;
    }
    p{
    	color:#444;
    	text-align:left;
    	font-size:10px;
    	margin-left: 20px;
    	margin-bottom: -10px;
    }
    a{
    	color:#444;
    }
    
    Step 4

    Then, for the container and images, I used a bit of CSS3 to add round corners and shadows. Don’t forget "-moz-box-shadow" and "-moz-border-radius" for Firefox and "-webkit-box-shadow" and "-webkit-border-radius" for Chrome and Safari.

    #container{
    	margin: 0 auto;
    	width:800px;
    	border:1px solid #333;
    	-moz-border-radius: 10px;
    	-webkit-border-radius: 10px;
    	font-family:Verdana, Geneva, sans-serif;
    	text-align:center;
    }
    img{
    	border:10px solid #444;
    	-moz-border-radius: 5px;
    	-webkit-border-radius: 10px;
    	margin: 15px;
    }
    img:hover{
    	border-color:#555;
    	-moz-box-shadow: 0px 0px 15px #111;
    	-webkit-box-shadow: 0px 0px 15px #111;
    }
    
    Step 5: PHP Script

    This is going to be very short. We need to call the PHP script with the index of the next image we need as a parameter. First of all, we have to retrieve all the available image names from a directory and save them into an array. I organized my images in two folders: "thumb" and "img" which contain the thumbnails and actual images, respectively. Note that the thumbnails must have the exact same name as their corresponding full size images.

    <?php
    
    $dir = "thumb";
    if(is_dir($dir)){
    	if($dd = opendir($dir)){
    		while (($f = readdir($dd)) !== false)
    			if($f != "." && $f != "..")
    				$files[] = $f;
    	closedir($dd);
    	} 
    

    We define a variable for the directory we want to get the image names from, test if it exists, and if we can open it, read all the file names from it. When reading an entire folder, we will always get two extra elements we may not want: "." – this stands for the current directory, and ".." – this stands for the parent directory. To compensate, we have to test if the element read is different from these two, then we can safely add it to our array.

    $files[] = $f;
    

    As a note, when adding an element to an array and not specifying the position to be placed in, it will always push the element to the end of the array.

    Step 6

    Now we have to build our response text. We are going to send back to the JavaScript a single string containing all the necessary file names separated by a semi-colon.

    	$n = $_GET["n"];
    	$response = "";
    

    We get the URL parameter for the index of the next image we need, and we initialize our response text.

    	for($i = $n; $i<$n+9; $i++)
    		$response = $response.$files[$i%count($files)].';';
    	echo $response;
    }
    ?>
    

    As I said before, the images will be grouped in sets of three rows, each containing three images, so we only need nine images to return the file names for a group. We start at the index we got as parameter, $n, and go until $n+9. At each increment, we add our image name followed by ";" to the response text. Here is a little tricky part. We won’t have an infinite number of images; so in order to create the effect of an "infinite" gallery which never ends, each time the index of the next image is greater that the total number of images, we must start over from the beginning. This is done by applying the "modulo" or "%" function between the index and the total number of images.

    	$i%count($files)
    

    As a result, we get the remainder of the division between these two elements. For example, if the index "$i" is "50" and the number of images "count($files)" is "45" the result will be "5". As well, if "$i" is "50" and "count($files)" is "65", the result will be "50". Finally, we have to send back our response text.

    Step 7

    Here is the complete PHP script. Just place your completed code within a new .php file.

    <?php
    
    	$dir = "thumb";
    	if(is_dir($dir)){
    		if($dd = opendir($dir)){
    			while (($f = readdir($dd)) !== false)
    				if($f != "." && $f != "..")
    					$files[] = $f;
    			closedir($dd);
    		} 
    
    	$n = $_GET["n"];
    	$response = "";
    		for($i = $n; $i<$n+9; $i++){
    			$response = $response.$files[$i%count($files)].';';
    		}
    		echo $response;
    	}
    ?>
    
    Step 8: JavaScript

    As usual, first we define some variables we will need later on.

    var contentHeight = 800;
    var pageHeight = document.documentElement.clientHeight;
    var scrollPosition;
    var n = 10;
    var xm [http;] 

    In order to determine weather the scroll bar is near the bottom of the page, we need three variables:

    • "contentHeight" – the height of the initial gallery
    • "pageHeight" – the height of the visible page in the browser
    • "scrollPosition" – the position of the scroll bar measured from the top

    Lastly, we need a variable for the next image index (which we are going to send to the PHP script), and a variable for the Ajax request object.

    Step 9

    We need to define a function that will add the images to our HTML container.

    function putImages(){
    	if (xm [http.readyState==4){]     	if(xm [http.responseText){] 

    A request object goes through different states as the request is made, each of which has a numerical value associated. The one we are interested in is the final state, when the request is complete and the value is "4". We first test if the request is in this state, and then check to see if we received a response.

    Step 10

    If both conditions are fulfilled, we have to tokenize the response text. This means we have to separate the file names into an array. Remember that in the PHP script we returned a single string with the names separated by semi-colons. Here is an example: Achievements.jpg;Bw.jpg;Camera.jpg;Cat-Dog.jpg;CREATIV.jpg;creativ2.jpg;Earth.jpg;Endless.jpg;EndlesSlights.jpg;

    var resp = xm [http.responseText.replace("\r\n",] "");
    var files = resp.split(";");
    

    There is a bit of a problem we have to deal with first; the response text may have at the beginning a new line character which we do not want. This is easily fixed with the "replace" function, that takes two parameters: "\r\n" – the new line character, and "" – empty string that will replace all occurrences of the first parameter. Now all we have to do is to split the string by our delimiter ";".

    Step 11

    Next, we have to add the images to our container.

                var j = 0;
                for(i=0; i<files.length; i++){
                    if(files[i] != ""){
                        document.getElementById("container").innerHTML += '<a href="img/'+files[i]+'"><img src="thumb/'+files[i]+'" /></a>';
                        j++;
    
                        if(j == 3 || j == 6)
                            document.getElementById("container").innerHTML += '';
                        else if(j == 9){
                            document.getElementById("container").innerHTML += '<p>'+(n-1)+" Images Displayed | <a href='#header'>top</a></p><hr />";
                            j = 0;
                        }
                    }
                }

    For every element in our array, we check if it isn’t an empty string, and add the thumbnail with the link on it. We have to keep a counter "j" in order to separate the images in rows. After every third and sixth thumbnail added, we create a new line, and after nine thumbnails added we put the text showing the total number of displayed images and a link to the top of the page.

    Step 12

    Here is the complete function.

    function putImages(){
    	if (xm [http.readyState==4){]     	if(xm [http.responseText){] 			var resp = xm [http.responseText.replace("\r\n",] "");
    			var files = resp.split(";");
    
                var j = 0;
                for(i=0; i<files.length; i++){
                    if(files[i] != ""){
                        document.getElementById("container").innerHTML += '<a href="img/'+files[i]+'"><img src="thumb/'+files[i]+'" /></a>';
    
                        j++;
                        if(j == 3 || j == 6)
                            document.getElementById("container").innerHTML += '';
                        else if(j == 9){
                            document.getElementById("container").innerHTML += '<p>'+(n-1)+" Images Displayed | <a href='#header'>top</a></p><hr />";
                            j = 0;
                        }
                    }
                }
    		}
    	}
    }
    Step 13

    Now we are going to define the function that will check if the scroll position is getting near the bottom, and makes the request to the server.

    function scroll(){
    
    	if(navigator.appName == "Microsoft Internet Explorer")
    		scrollPosition = document.documentElement.scrollTop;
    	else
    		scrollPosition = window.pageYOffset;
    

    First, we have to find the position of the scroll bar. Internet Explorer does this a bit differently, so we have to determine what browser the client is using, then just store the value in the variable we defined earlier.

    Step 14
    	if((contentHeight - pageHeight - scrollPosition) < 500){
    

    Now we check to see if we are about to reach the end of our gallery – if the part of the page visible in the browser is below the bottom 500px of the entire page. This isn’t an exact value, you may use a different one if you find it suitable. If this condition is true, we can continue on and add new images.

    Step 15: Creating the XM [HttpRequest] Object

    We are ready to make the XM [HttpRequest] object and send it. Again, for Internet Explorer the definition is a bit different, so we must compensate for this as well.

    	if(window.XM [HttpRequest)] 			//Firefox, Opera, Safari
    			xmlhttp = new XM [HttpRequest();] 		else
    			if(window.ActiveXObject)
                	//Internet Explorer
    				xmlhttp = new ActiveXObject("Microsoft.XM [HTTP");] 			else
    				alert ("Bummer! Your browser does not support XM [HTTP!");] 
    Step 16

    Before sending the request, we have to specify the PHP script name on the server and insert the parameters we want to give it.

    	var url="getImages.php?n="+n;
    

    This is a simple text variable representing the URL of the page.

    Step 17

    It’s time to send the request.

    		xm [http.open("GET",url,true);] 		xm [http.send();] 

    The URL is set by calling the "open" method. The second parameter is the important one, this being the script’s URL. After doing so, all we need is to send it. This will run the PHP script and put in "xm [http.responseText"] the return value of it.

    Step 18

    The final step is to place the new content on the page by calling the function we defined earlier "putImages" and to prepare our variables for the next request.

    		n += 9;
    		contentHeight += 800;
    		xm [http.onreadystatechange] = putImages;
    	}
    }
    

    We have nine new images in the gallery, so we increment "n" with 9, and we need to change the page height; so increment "contentHeight" with 800.

    Step 19

    Here is the entire JavaScript we’ve used.

    <script>
    var contentHeight = 800;
    var pageHeight = document.documentElement.clientHeight;
    var scrollPosition;
    var n = 10;
    var xm [http;] 
    function putImages(){
    
    	if (xm [http.readyState==4)] 	  {
    		  if(xm [http.responseText){] 			 var resp = xm [http.responseText.replace("\r\n",] "");
    			 var files = resp.split(";");
    			  var j = 0;
    			  for(i=0; i<files.length; i++){
    				  if(files[i] != ""){
    					 document.getElementById("container").innerHTML += '<a href="img/'+files[i]+'"><img src="thumb/'+files[i]+'" /></a>';
    					 j++;
    
    					 if(j == 3 || j == 6)
    						  document.getElementById("container").innerHTML += '';
    					  else if(j == 9){
    						  document.getElementById("container").innerHTML += '<p>'+(n-1)+" Images Displayed | <a href='#header'>top</a></p><hr />";
    						  j = 0;
    					  }
    				  }
    			  }
    		  }
    	  }
    }
    
    function scroll(){
    
    	if(navigator.appName == "Microsoft Internet Explorer")
    		scrollPosition = document.documentElement.scrollTop;
    	else
    		scrollPosition = window.pageYOffset;		
    
    	if((contentHeight - pageHeight - scrollPosition) < 500){
    
    		if(window.XM [HttpRequest)] 			xmlhttp = new XM [HttpRequest();] 		else
    			if(window.ActiveXObject)
    				xmlhttp = new ActiveXObject("Microsoft.XM [HTTP");] 			else
    				alert ("Bummer! Your browser does not support XM [HTTP!");] 	  
    
    		var url="getImages.php?n="+n;
    
    		xm [http.open("GET",url,true);] 		xm [http.send();] 
    		n += 9;
    		xm [http.onreadystatechange=putImages;] 		contentHeight += 800;
    	}
    }
    
    
    
    Step 20

    The final thing that we must do is run the JavaScript at a specified interval.

    <body onload="setInterval('scroll();', 250);">
    

    Just set up the "onload" property of the "body" tag, and set its value to the "setInterval" function. This will run the "scroll" function every quarter of a second. Again, you may change this time value, but I found that it’s optimal for what we need.

    Finished!

    We are done! I hope you found this tutorial to be of help and useful. Please leave a message in the comment section below, should you need further assistance or advice.


  • Permalink for 'Free Ticket to the jQuery Conference in San Francisco'

    Free Ticket to the jQuery Conference in San Francisco

    Posted: March 30th, 2010, 10:26am MDT by Jeffrey Way

    On April 24-25, I’ll be attending the jQuery conference in San Francisco, and I hope many of you will as well! With speakers like John Resig, Steve Souders, Rey Bango, and other highly respected members from the jQuery team, it’s sure to be a fantastic event! Now, if you haven’t purchased your ticket just yet, the team has given me one ticket to give away for free.

    “The San Francisco Bay Area conference is the second of four events planned by the jQuery Project in 2010. The first was the jQuery14 event, and additional conferences are being planned in Europe and on the East Coast for later this year.”

    jQuery Conference Hosted at Microsoft

    “The San Francisco Bay Area conference will be held at the Microsoft Silicon Valley Research Center in Mountain View, California. This venue is the largest that the project has worked with to date (Harvard Law School in ’07, the MIT Stata Center in ’08 and Microsoft New England Research Center in ’09) and we expect to sell out very quickly.”

    jQuery Conference How to Enter

    The winner will receive one complimentary ticket to attend the jQuery conference. He or she will still be responsible for accommodations, and/or travel expenses, per usual. If you’re in or near the Bay area of San Francisco, and would LOVE to attend, leave a comment of no more than three sentences telling us why.

    jQuery conference

    If you aren’t selected to win the free ticket, admission is only $199, which is quite cheap when you consider the level of knowledge that you’ll gain as a result of attending.

    I’ll be attending, and will hope to see you there! Will you be going?


  • Permalink for 'Diving into the Twitter API'

    Diving into the Twitter API

    Posted: March 30th, 2010, 4:30am MDT by Siddharth

    Twitter’s astonishing growth is rivaled only by its intuitive, developer friendly API. In this second part of the series, we are going to learn more about Twitter’s API and how to work with it.

    Too much abstraction is never a good thing.

    In this Web 2.0 era, web applications which have an easy to use, intuitive API have a distinct advantage as it lets developers exploit and build for the platform and thus capture more users. As we move towards the social web and mashups, a good API is not a nice addition anymore: it is downright necessary. And remember, too much abstraction is never a good thing. While there are a number of API kits out there to simplify working with the API in question, wouldn’t it be cool to know what is actually going on under the hood? Wouldn’t it be exciting to deconstruct the actual voodoo going on between the kit and the API? Yeah, I thought so!

    Before we Begin

    For each functionality, I am going to show you how to achieve it in two ways: the first using a server side language, PHP in this case, and the second using only a client side language, JavaScript. Each implementation will function separately and achieve the required functionality. Feel free to mix and match these solutions to create a hybrid. The JavaScript examples will use JSON as the format for the payload while for the PHP example I’ve chosen XML.

    Twitter API Basics

    The first thing you need to know about the Twitter API is that it is RESTful. To cut the jargon, it means you access appropriate URLs using GET or POST requests to modify, request or manipulate the data exposed by the API.

    There are three separate Twitter APIs actually.

    • The normal REST based API
    • The Search API
    • The Stream API

    Each of these APIs have their own distinct set of functionality, quirks, advantages and disadvantages.

    REST API

    The REST methods constitute the core of the Twitter API, and are written by the devs at Twitter itself. It allows other developers to access and manipulate all of Twitter’s main data. You’d use this API to do all the usual stuff you’d want to do with Twitter including retrieving statuses, updating statuses, showing a user’s timeline, sending direct messages and so on.

    Search API

    The search API is actually the brainchild of the guys over at Summize Inc, a company which Twitter acquired for its API. The search API lets you look beyond you and your followers. You need this API if you are looking to view trending topics and so on.

    Stream API

    Finally we have the stream API. This API lets developers sample huge amounts of real time data. Since this API is only available to approved users, we aren’t going to go over this today.

    Authentication and all that Boohockey

    Public data can be freely accessed without an API key. When requesting private data and/or user specific data, Twitter requires authentication. You can authenticate with Twitter using either of two methods.

    Basic Authentication

    This is the default method of authentication Twitter initially launched with and still uses. In this method, you pass the user name and password as Bse64 encoded strings in the header of the HTTP request. A sample GET request would look like so.

    GET /somefolder/index.html [HTTP] Host: net.tutsplus.com
    Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
    

    Looks a tiny bit complicated doesn’t it? Let me explain. The first two lines are part of a standard GET request. The third line is where all of magic happens. We make sure the server knows we are using basic auth to authenticate with it, and then pass in the base 64 encoded string of username:password as the value. The server can then decode the credentials, check them and provide access if everything matches.

    Twitter supporting basic auth is probably one of the reasons it got so big since it let a multitude of developers develop for the platform since the barrier of entry is relatively low. Basic auth is sufficient to retrieve all parts of the API.

    OAuth

    Twitter started supporting OAuth in the second quarter of 2009. Users using OAuth enabled application need not divulge their passwords to the program and can also delegate control to the program with multiple levels of access. However, we’ll not look at Twitter’s OAuth implementation today. OAuth and implementing its workflow is a rather complex topic and requires an article of its own. I’d rather skip over OAuth for this article rather than throw out some half baked explanations and writing code based on those explanations.

    Caution

    “Twitter only lets you make a predefined number of calls to its API.”

    Before we delve in to the coding part, I need to make one thing absolutely clear: Twitter only lets you make a predefined number of calls to its API. The REST API’s limit is 150 for an hour, while the search API’s limit is undisclosed as of now. For authenticated calls, the call is deducted from the authenticating user’s limit, while for unauthenticated calls it is deducted from the calling IP’s quota.

    Remember, when developing an application, make sure you either cache the information or respect the limit and stay within it. If you think the preset limit is insufficient for your application, you could always apply for white listing.

    The Most Common Tasks

    Instead of looking at a number of methods you probably won’t ever use, I’ve decided to show you how to do the three most common tasks.

    • Retrieving your status
    • Updating your status
    • Searching Twitter

    I think this is a proper subset of the API which directly covers what the API is most used for without spreading itself too thin by covering a ton of methods. With that out of the way, let’s get started!

    Retrieving your Status

    The first functionality we are going to look at is displaying a user’s status. This is the most popular use of the API if a web developer wants to display a given user’s status without resorting to a Twitter badge.

    PHP Method #1: Direct Retrieval
    <?php
    $response = new SimpleXMLElement('http://twitter.com/users/show/userid.xml',NULL,TRUE);
    echo $response->status->text.' - '.date("g:i: A D, F jS Y",strtotime($response->status->created_at));
    ?>
    

    The first method utilizes PHP. It’s a relatively simple method where we just grab the user specific XML file, and then parse it to display the current status.

    We first convert the XML file into an object so we can easily traverse through it using the SimpleXML extension which comes standard with PHP. Now that the object has been created, we just find the status node, and print out the status text and creation time.

    Remember, this only displays the current status of the user. If you want a list of recent updates, see below.

    PHP Method #2: cURL

    cURL is a command line tool and comes enabled on most hosted servers. To quote Wikipedia:

    In computing, cURL functions as a command-line tool for transferring files with URL syntax.

    It is a library designed to allow users to connect to different types of servers using different protocols. Using cURL is the method of choice for all the Twitter libraries out there and we’ll be using the same.

    <?php
    
         $username = 'xxx';
    	 $password = 'yyy';
         $curlhandle = curl_init();
    	 curl_setopt($curlhandle, CURLOPT_URL, "http://twitter.com/statuses/user_timeline.xml");
    	 curl_setopt($curlhandle, CURLOPT_USERPWD, $username.':'.$password);
         curl_setopt($curlhandle, CURLOPT_RETURNTRANSFER, 1);
         $response = curl_exec($curlhandle);
         curl_close($curlhandle);
         $xmlobj = new SimpleXMLElement($response); 
    
    	 foreach ($xmlobj->status as $status)
    	 {
        echo $status->text.'<br /> by'.$status->user->screen_name.' at '
        .date("g:i: A D, F jS Y",strtotime($status->created_at)).'<br /> <br /> ' ;
        }
    ?> 
    

    Let me explain. First, we assign our username and password to separate variables to be used later. I then set the URL to the value mentioned above. Since the method requires authentication, we send in our username and password.

    Next, we execute our call and store the response in a seperate variable. We then convert it into a valid XML object and then parse the data, printing out the status and when it was posted.

    I’ve formatted the data and time to look the way I want. If you want fancy dates and times like 3 hours ago or 12 days ago, you either need to look for a snippet or code one yourselves. Twitter only returns normally formatted data and time.

    You’ll receive an output, similar to this:

    I am stupid. Didn't use an IDE and missed a comma wasting 110 minutes.
    Remind me not to try debugging when I am sleepy or tired.
    at 6:01: PM Fri, February 14th 2010
    
    Flood of traffic. :O I must have budgeted for this many visitors. Argh! Hope nothing breaks.
    at 8:51: PM Thu, February 13th 2010
    
    JavaScript

    Using JavaScript to display your status is the most elegant way to go forward since you can load it asynchronously after the page has loaded, which means, even if Twitter is downm or being tardy, your site functions the same.

    We are going to use jQuery’s ajax method to do all our dirty work today.

     $.ajax({
        		url : "http://twitter.com/statuses/user_timeline/userid.json?callback=?",
    			dataType : "json",
    			timeout:15000,
    
    			success : function(data)
    			{
    				  $("#data").html("Data successfully obtained! <br />");
      for (i=0; i<data.length; i++)
    				{
      $("#data").append("<p>" + data[i].text) +"</p>";
      $("#data").append("<p>" + data[i].created_at +"</p>");
    				}
    			},
    
    			error : function()
    			{
    				alert("Failure!");
    			},
    
    		});
    

    Again, a big chunk of code but, broken down, it’s simple really. We use jQuery’s lowest level AJAX function instead of the getJSON method, since the low level call seems to be more versatile.

    First up, we define the URL and the datatype. We also add a callback function to the URL to circumvent the cross domain restriction on most browsers. Without this callback, our script wouldn’t run; it’d just return an error and quit.

    I’ve chosen not to authenticate, because we are specifying an ID in the URL, and hence don’t need authentication – that and because basic auth is not really safe for sensitive information. You don’t want to send out your password over an insecure line.

    Finally, the success function which is called when no errors are encountered. We just parse the returned JSON object and print out the text and the creation time. #data is just a container where we put all our data.

    A Quick Note

    This code is the template for all your methods which access data. Very minimal change is required to modify it to work with other API methods.

    For the PHP example, all you’d need to do is change URL value to point to a new method, and you should be mostly done. If the method requires parameters, you just add them directly to the URL itself. Simple as that.

    Same with the JavaScript example. All you’d need to do is change the URL that the methods request, and you should be done. Be sure to fetch only public data with the JavaScript method.

    Remember, this code is the base for all your other methods which retrieve data. This includes methods getting your direct messages, timelines, friends, followers and mentioned tweets. Just change the url, add in a parameter as needed, and you’re all set! Easy, no?

    Updating your Status

    With any Twitter application you are creating, letting users update their status through it is a no-brainer. Remember, previously applications using basic auth were able to use a custom source string for all tweets sent from their application. Now, implementing OAuth is the only way you get a custom string. In short, if you want all tweets sent from your application to have a link back to your app, use OAuth. With that out of the way, let’s see the code.

    PHP
    <?php
    
        $username = 'xxx';
    	 $password = 'yyy';
        $status= 'Testing out cURL with the Twitter API';
        $curlhandle = curl_init();
    	 curl_setopt($curlhandle, CURLOPT_URL, "http://twitter.com/statuses/update.xml");
    	 curl_setopt($curlhandle, CURLOPT_USERPWD, $username.':'.$password);
        curl_setopt($curlhandle, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curlhandle, CURLOPT_POST, 1);
    	 curl_setopt($curlhandle, CURLOPT_POSTFIELDS, "status=$status");
        $response = curl_exec($curlhandle);
        curl_close($curlhandle);
    
    ?>
    

    We can use cURL just as easily to post to Twitter. The code is almost the same as before except we change the url to the appropriate one. Also, we make sure posting is enabled, and set the fields to be posted. The API method requires a status parameters, and so we set the value of the status variable to this parameter.

    Do remember to make sure the text to be posted is UTF-8 encoded. Otherwise, we’d run into needless errors.

    We now save the response to be used for later. In this example, I’ve chosen to do nothing. But in a practical application you’d definitely want to display a success/error message and/or display the response.

    JavaScript

    Posting a status update to Twitter using only JavaScript seems to be impossible right now since there is no way to pass the user’s id and password. With Flickr, those credentials are passed on as part of the POST request itself. With Twitter, this data needs to be sent in the HTTP headers, and there doesn’t seem to be a way of doing that.

    Even disregarding the fact that you can’t send credentials over to the service, there is still the problem of not being able to make cross domain POST requests with the XMLHttp object. These two points make API methods which require a POST request a strict no-no with JavaScript.

    In case you are interested, a successful post nets you this response.

    <?xml version="1.0" encoding="UTF-8"?>
    <?xml version="1.0" encoding="UTF-8"?>
    <status>
      <created_at>Fri Aug 14 21:31:53 +0000 2009</created_at>
      <id>3316091255</id>
      <text>Testing out cURL with the Twitter API</text>
      <source><a href="http://apiwiki.twitter.com/" rel="nofollow">API</a></source>
      <truncated>false</truncated>
    
      <in_reply_to_status_id></in_reply_to_status_id>
      <in_reply_to_user_id></in_reply_to_user_id>
      <favorited>false</favorited>
      <in_reply_to_screen_name></in_reply_to_screen_name>
      <user>
        <id>18118645</id>
        <name>Tony / Siddharth</name>
    
        <screen_name>lordtottuu</screen_name>
        <location>India</location>
        <description>Gamer, developer, web designer, writer, geek. </description>
        <profile_image_url> [s3.amazonaws.com]     <url> [ssiddharth.com<]     <protected>false</protected>
    
      </user>
    
    </status>
    
    A Quick Note

    The code techniques discussed above consist of the base for all your data which sends data to Twitter. This includes methods which lets you follow/unfollow someone, send direct messages, creating favorites, blocking people, and so on and so forth.

    The only thing you’d need to do is change out these URLs, see whether they require extra parameters, and add them as needed. Nothing else required.

    Searching Twitter

    Letting users search through Twitter for information is potentially an important need of an application. For this purpose, we can use the search API to query Twitter.

    PHP
    <?php
    
        $searchstring = "Envato";
        $curlhandle = curl_init();
    	curl_setopt($curlhandle, CURLOPT_URL, "http://search.twitter.com/search.json?q=$searchstring");
        curl_setopt($curlhandle, CURLOPT_RETURNTRANSFER, 1);
    
        $response = curl_exec($curlhandle);
        curl_close($curlhandle);
    
        $json = json_decode($response);
    	foreach ($json->results as $result)
    	{
    	echo $result->text;
    	}
    
    ?>
    

    The above code lets you search Twitter for tweets which reference Envato. As usual, we change the URL to point to the correct API method and proceed. Since this method is only available in either JSON or ATOM formats, I’ve chosen to go with JSON.

    I’ve used PHP’s built-in json_decode function to convert it into an object so we could parse the response easily. In this example, I’ve only printed out the tweets themselves. In your applications, you’d probably want to display more. A sample response is below.

    [text] => @nsethi check out [www.envato.com] if you want some sick tuts...I'm gonna blog about it later.
    [to_user_id] => 1273919
    [to_user] => nsethi
    [from_user] => thinklime
    [id] => 3315720513
    [from_user_id] => 33020944
    [iso_language_code] => en
    source] => Tweetie
    [profile_image_url] => [s3.amazonaws.com] [created_at] => Fri, 14 Aug 2009 21:10:42 +0000
    

    As you can see, a lot of info about the user and the tweet itself is available. Feel free to mix and match.

    JavaScript
     $.ajax({
    
        		url : "http://search.twitter.com/search.json?q=somestring&callback=?",
    			dataType : "json",
    			timeout:15000,
    
    			success : function(data)
    			{
    				  // parse data here
    			},
    
    			error : function()
    			{
    				alert("Failure!");
    			},
    
    		});
    

    As usual, we use the ajax method to ping Twitter’s search service. Just as in the previous example, we’ve included a callback function to get over the cross domain restriction.

    A sample response, plucked directly from Twitter, looks like so.

    {"results":[
    
         {"text":"@twitterapi  [http:\] 
         "to_user_id":396524,
    
         "to_user":"TwitterAPI",
    
         "from_user":"jkoum",
    
         "id":1478555574,   
    
         "from_user_id":1833773,
    
         ... truncated ...],
    
         "since_id":0,
    
         "max_id":1480307926,
    
         "refresh_url":"?since_id=1480307926&q=%40twitterapi",
    
         "results_per_page":15,
    
         "next_page":"?page=2&max_id=1480307926&q=%40twitterapi",
    
         "completed_in":0.031704,
    
         "page":1,
    
         "query":"%40twitterapi"}
    }
    

    As a side note, the search method can be used in a variety of ways really.

    • ?q=Envato – Searches for tweets containing the string Envato
    • ?q=#Envato – Searches for hashtags of Envato
    • ?phrase=Envato+marketplace – Searches for tweets containing the phrase Envato marketplace
    • ?q=from:NETTUTS – Returns all tweets from NETTUTS
    • ?q=to:NETTUTS – Returns for all tweets to NETTUTS
    Why Other Methods Aren’t Covered

    I’ve decided to limit myself to showing how to read from and write to a service using its API. This way, I can focus only on those specific methods. And also because most methods build on these basics. If you want to return a friend’s timeline, you’d just change the URL and parse through the response with minimal fuss.

    The same occurs if you want to send a direct message to another user or mention another user. The basics of posting is still there. You just need to add in a parameter or two to make it all happen. It doesn’t make sense to cover all that when I can just explain the basics a lot more clearly.

    Conclusion

    I hope you’ve learned more about how to work with Twitter’s API today. As always, let me know, via the comments, if you need any help!


  • Permalink for 'How to Use the jQuery UI Autocomplete Widget'

    How to Use the jQuery UI Autocomplete Widget

    Posted: March 29th, 2010, 4:30am MDT by Dan Wellman

    In this tutorial we’ll be looking at one of jQuery UI 1.8’s newest components – the Autocomplete widget. Auto-completing text fields can be a popular choice with visitors to your site because they make entering information much easier. They can be used on product search fields for example, or when a visitor must enter a country, or a city, or anything else that may be a choice from a common dataset. As well as being popular with visitors, the jQuery UI Autocomplete is popular with developers because it’s easy to use, powerful and flexible.

    I’m not a massive fan of Facebook, I much prefer Twitter (@danwellman btw), but one Facebook feature I do like is the messaging feature which lets you send a message to a friend or friends. I like how the autocomplete is used to make selecting your friend’s names easier, and how the names are formatted once they have been selected and added to the ‘to’ field, e.g. they each have a close link in them that allows the name to be easily removed without having to select any text.

    In this tutorial we’ll use the jQuery UI Autocomplete widget to replicate this aspect of Facebook’s messaging system. We won’t be looking at actually sending messages however. This is what we’re going to create:

    Step 1 Getting Started

    We’ll need to build a custom download of jQuery UI containing just the components we need; head over to the download builder at [jqueryui.com] . We’ll need to use the following core components:

    • Core
    • Widget
    • Position

    We’ll also need the Autocomplete widget itself so ensure that just the above items, as well as Autocomplete, are checked in the Components section at the left. Use the default theme (UI Lightness) and ensure that version 1.8 is selected at the right.

    Once downloaded, create a new folder on your computer and call it autocomplete. Then open the archive and copy the css and js folders into the new folder you just created. This will give you all of the library files required for this example including jQuery itself, so this doesn’t need to be downloaded separately.

    Step 2 The Underlying HTML

    Let’s look at the HTML for the <form> first of all:

    <div id="formWrap">
    	<form id="messageForm" action="#">
    		<fieldset>
    			<legend>New message form</legend>
    			<span>New Message</span>
    			<label id="toLabel">To:</label>
    			<div id="friends" class="ui-helper-clearfix">
    				<input id="to" type="text">
    			</div>
    			<label>Subject:</label>
    			<input id="subject" name="subject" type="text">
    			<label>Message:</label>
    			<textarea id="message" name="message" rows="5" cols="50"></textarea>
    			<button type="button" id="cancel">Cancel</button>
    			<button type="submit" id="send">Send</button>
    		</fieldset>
    	</form>
    </div>

    It’s a pretty standard form; there’s an outer container <div> we can use for styling and the <input> that the Autocomplete will be attached to is also within a <div> element; we’ll style the <input> so that it’s slightly hidden, and we’ll style the <div> so that it looks like the other fields in the form. We give the container for the <input> the ui-helper-clearfix class name to make use of this utility class from jQuery UI’s CSS framework.

    We’ll also need to link to the files we unpacked from the jQuery UI archive, as well as a custom stylesheet; the following files should go into the <head> of the page:

    <link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.8.custom.css">
    <link rel="stylesheet" type="text/css" href="css/autocomplete.css">

    The following files should go at the end of the <body>:

    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="js/jquery-ui-1.8.custom.min.js"></script>
    Step 3 Styling the Form

    We use a very simple, neutral theme in this example, most of which is purely as an example. Very few of the styles are required and most can be changed if necessary. The following CSS is used in the autocomplete.css style sheet (all of the jQuery UI styling is in the jquery-ui-1.8.custom.css style sheet):

    #formWrap {
    	padding:10px; position:absolute; float:left; background-color:#000;
    	background:rgba(0,0,0,.5); -moz-border-radius:10px;
    	-webkit-border-radius:10px; border-radius:10px;
    }
    #messageForm {
     width:326px; border:1px solid #666; background-color:#eee;
    }
    #messageForm fieldset {
    	padding:0; margin:0; position:relative; border:none;
    	background-color:#eee;
    }
    #messageForm legend { visibility:hidden; height:0; }
    #messageForm span {
    	display:block; width:326px; padding:10px 0; margin:0 0 20px;
    	text-indent:20px; background-color:#bbb;
    	border-bottom:1px solid #333;	font:18px Georgia, Serif; color:#fff;
    }
    #friends {
    	width:274px; padding:3px 3px 0; margin:0 auto;
    	border:1px solid #aaa; background-color:#fff; cursor:text;
    }
    #messageForm #to {
    	width:30px; margin:0 0 2px 0; padding:0 0 3px;
    	position:relative; top:0; float:left; border:none;
    }
    #messageForm input, #messageForm textarea {
    	display:block; width:274px; padding:3px; margin:0 auto 20px;
    	border:1px solid #aaa;
    }
    #messageForm label {
    	display:block; margin:20px 0 3px; text-indent:22px;
    	font:bold 11px Verdana, Sans-serif;	color:#666;
    }
    #messageForm #toLabel { margin-top:0; }
    #messageForm button { float:right; margin:0 0 20px 0; }
    #messageForm #cancel { margin-right:20px; }
    #friends span {
    	display:block; margin:0 3px 3px 0; padding:3px 20px 4px 8px;
    	position:relative; float:left; background-color:#eee;
    	border:1px solid #333; -moz-border-radius:7px;
    	-webkit-border-radius:7px; border-radius:7px; color:#333;
    	font:normal 11px Verdana, Sans-serif;
    }
    #friends span a {
    	position:absolute; right:8px; top:2px; color:#666;
    	font:bold 12px Verdana, Sans-serif; text-decoration:none;
    }
    #friends span a:hover { color:#ff0000; }
    .ui-menu .ui-menu-item { white-space:nowrap; padding:0 10px 0 0; }

    To give the form a nice transparent border with rounded corners we use the CSS3 RGBa rule and the -moz-border-radius, -webkit-border-radius and border-radius rules; most popular browsers now support these rules, including Firefox, Safari, Chrome and Opera. IE doesn’t support either of them, and although it can use a filter to implement rudimentary opacity, rounded corners would need to be supported through the use of images. The effectiveness of the RGBa transparency isn’t shown to its fullest in this example; but this type of form would probably be used as a floating modal overlay in a full implementation, which would sit above actual content on the page.

    The container <div> around the <input> field that the Autocomplete text field will be attached to is given the same positioning and styling as the <input> elements, but the <input> within this container has its border removed so that it is hidden. We also reduce its width and float it to the left. This is so that when we add the formatted recipients to the <div> the <input> won’t overflow and increase the height of the <div> unnecessarily.

    We also style the recipients, which will be added to the <div> as <span> elements containing a link. Mostly these are styled to match the basic theme and are also given rounded corners. It’s important that these elements are made block-level and also float so that they stack up correctly. We also need to override some of the Automcomplete styling provided by the jQuery UI theme we are using; the last selector simply prevents the individual suggestions in the menu breaking between words, which happens because we have made the <input> it is associated with so small.

    At this stage, the form should appear like this:

    Step 4 Attaching the Autocomplete

    Next we need to attach the Autocomplete widget to the <input> within the <div>; to do this we can use the following script:

    <script type="text/javascript">
    	$(function(){
    
    		//attach autocomplete
    		$("#to").autocomplete({
    
    			//define callback to format results
    			source: function(req, add){
    
    				//pass request to server
    				$.getJSON("friends.php?callback=?", req, function(data) {
    
    					//create array for response objects
    					var suggestions = [];
    
    					//process response
    					$.each(data, function(i, val){
    					suggestions.push(val.name);
    				});
    
    				//pass array to callback
    				add(suggestions);
    			});
    		},
    
    		//define select handler
    		select: function(e, ui) {
    
    			//create formatted friend
    			var friend = ui.item.value,
    				span = $("<span>").text(friend),
    				a = $("<a>").addClass("remove").attr({
    					href: "javascript:",
    					title: "Remove " + friend
    				}).text("x").appendTo(span);
    
    				//add friend to friend div
    				span.insertBefore("#to");
    			},
    
    			//define select handler
    			change: function() {
    
    				//prevent 'to' field being updated and correct position
    				$("#to").val("").css("top", 2);
    			}
    		});
    	});
    </script>

    The widget is attached to the <input> using the autocomplete() method. We supply an object literal as an argument to the method, which configures the source option and the select and change event callbacks.

    The source option is used to tell the widget where to get the suggestions for the Autocomplete menu from. We use a function as the value of this option, which accepts two arguments; the first is the term entered into the <input>, the second is a callback function which is used to pass the suggestions back to the widget.

    Within this function we use jQuery’s getJSON() method to pass the term to a server-side PHP file. The PHP file will use the term to extract matching contact names from a MySql database. We use a JSONP callback to process the data returned from the server; the callback function that is passed as the second argument to the source option expects to receive the data in an array, so we first create an empty array and then use jQuery’s each() method to process each item in the JSON array returned by the server. We simply iterate over each item in this array, and add each suggestion to our new array. Once our new array is built we pass it to the callback function for the widget to display in the menu.

    We then define a handler for the Autocomplete’s custom select event; this function will be executed by the widget each time a suggestion is selected from the Autocomplete menu. This function is automatically passed two arguments – the event object and a ui object containing the suggestion that was selected. We use this function to format the recipient name and add it to the <div>. We simply create a <span> element to hold the text and an anchor element that can be used to remove the recipient. Once the formatted recipient has been created we just insert it directly before the camouflaged <input>.

    Lastly we add a handler for the change event; this function will be invoked whenever the value of the <input> that the Autocomplete is associated with changes. We just use it to remove the value from the <input> because we’ve already added the formatted version to our container <div>. The carat looks a little high up once a formatted contact name has been added to the <div> so we also use this event handler to correct this.

    This is all the configuration we need for this particular implementation, but there are still a couple of additional functions we need to add to tidy things up a little. After the autocomplete() method add the following code:

    //add click handler to friends div
    $("#friends").click(function(){
    
    	//focus 'to' field
    	$("#to").focus();
    });
    
    //add live handler for clicks on remove links
    $(".remove", document.getElementById("friends")).live("click", function(){
    
    	//remove current friend
    	$(this).parent().remove();
    
    	//correct 'to' field position
    	if($("#friends span").length === 0) {
    		$("#to").css("top", 0);
    	}
    });

    The <input> that our Autocomplete is attached to is partially hidden and its container <div> is styled so that it appears like the other fields on the form; to complete the deception, we add a click handler to the container <div> so that clicking anywhere within it focuses the actual <input>. Visually and functionally now the <div> should be indistinguishable from a regular field.

    We also need to handle clicks on the anchor that is added to each formatted recipient; we use jQuery’s live() method because these elements may or may not exist on the page at any given time and it is easier than binding the handler function each time we create one of these anchors. Whenever one of these anchors is clicked all we do is navigate up to the parent of the anchor that was clicked and then remove it from the page. Remember when we corrected the position of the carat earlier in the script? We just need to check whether all the recipients have been removed and if so, reset its position back to its default.

    Step 5 Additional Code and Resources

    I used a MySql database containing a table listing each of the recipient names, and the following PHP file to accept the data sent by the getJSON() method and pull matching recipients from the database:

    <?php
    
    	//connection information
    	$host = "localhost";
    	$user = "root";
    	$password = "your_mysql_password_here";
    	$database = "test";
    	$param = $_GET["term"];
    
    	//make connection
    	$server = mysql_connect($host, $user, $password);
    	$connection = mysql_select_db($database, $server);
    
    	//query the database
    	$query = mysql_query("SELECT * FROM friends WHERE name REGEXP '^$param'");
    
    	//build array of results
    	for ($x = 0, $numrows = mysql_num_rows($query); $x  $row["name"]);
    	}
    
    	//echo JSON to page
    	$response = $_GET["callback"] . "(" . json_encode($friends) . ")";
    	echo $response;
    
    	mysql_close($server);
    
    ?>

    To run the downloadable example files, you’ll need a development web server with PHP installed and configured, as well as MySql and the appropriate database and table. When a letter is typed into the ‘to’ field, this letter is passed to the server and used to pull out each name that begins with the letter that was typed. The matching names are then passed back to the page as JSON and displayed in the suggestion menu:

    This tutorial showed how to replicate Facebook’s message sending form, specifically, the way friends are added to the messaging form as recipients using an Autocomplete, and how the friend names are formatted once they have been added so that they can easily be removed. Our example form doesn’t actually do anything, but what we would need to do to actually send the form would be to pass the contents of the form to a server-side file for sending using AJAX, which could easily be hooked into the submit event of the send button used on the form.

    The recipients would need to have some kind of meaning to back-end system of course, and would probably be mapped to email addresses in the database. We’d need to retrieve the textual content of each of the <span> elements before passing back to the server, although this would be a fairly trivial matter.

    The jQuery UI Autocomplete widget makes it easy to connect to any datasource and contains a rich suite of event handlers that we can supply functions to in order to react to text being entered into the associated field, or a suggestion being selected from the menu. The widget is styled using jQuery UI’s extensive CSS framework and can easily be changed so that it matches your existing site theme. All in all, it’s an excellent widget that is easy to use and provides great functionality.


  • Permalink for 'Quick Tip: How to Target IE6, IE7, and IE8 Uniquely with 4 Characters'

    Quick Tip: How to Target IE6, IE7, and IE8 Uniquely with 4 Characters

    Posted: March 28th, 2010, 7:25pm MDT by Jeffrey Way

    Two months ago, I, in a video quick tip, demonstrated how to use the underscore and star hacks to target Internet Explorer 6 and 7 in your stylesheets. In today’s quick tip, we’ll take things one step further, as we introduce a new hack that targets IE8 and below as well. It should be noted that this is not a best practice, and conditional comments should be used instead 98% of the time. With that said, it’s always important to know what you can do – plus it’s fun, right?


    Subscribe to our YouTube page to watch all of the video tutorials! IE8 and Below

    The key to targeting Internet Explorer 8 and below, with a hack, is to append “\9″ to the end of your style. For example:

    body {
     color: red; /* all browsers, of course */
     color : green\9; /* IE8 and below */
    }
    

    It’s important to note that it must be “\9″. Unfortunately you can’t replace this with something along the lines of “\IE”, like I attempted to do so. Even “\8″ won’t work; it must be “\9″.

    IE7 and Below

    As we learned in the quick tip from January, we can use the * symbol to target IE7 and below, like so:

    body {
     color: red; /* all browsers, of course */
     color : green\9; /* IE8 and below */
     *color : yellow; /* IE7 and below */
    }
    
    IE6

    Lastly, we have the underscore hack, which most designers are familiar with by now. Rather than the * symbol, we use the underscore. This will target only Internet Explorer 6.

    body {
     color: red; /* all browsers, of course */
     color : green\9; /* IE8 and below */
     *color : yellow; /* IE7 and below */
     _color : orange; /* IE6 */
    }
    
    A Note About CSS Hacks

    It's worth noting that I'm not advocating the use of hacks in your stylesheets in any way. On the contrary, you should almost always use conditional comments. However, that doesn't mean that it isn't helpful to know what you can technically get away with, whether it be for debugging, or showing off to your friends!

    The biggest concern is that hacks aren't future proof, at least not really. For example, what if, with the release of Firefox 4, they, too, recognized properties prepended with the * hack. They probably never would for compatibility reasons, however, if they did, that could potentially ruin a portion of your layout. Ultimately, just be wise when using hacks. If you only need to change one or two properties to make IE6 happy, then I don't see any harm in using the underscore hack directly in your stylesheet. The world won't end. However, if there are a handful of changes, be sure to use conditional comments!

    <!--[if lte IE 7]>
    Make IE7 happy.
    <![endif]-->
    

    Thanks for reading and watching!


  • Permalink for '20 Helpful jQuery Methods you Should be Using'

    20 Helpful jQuery Methods you Should be Using

    Posted: March 26th, 2010, 11:55am MDT by Andrew Burgess

    So you’ve been playing with jQuery for a while now, you’re starting to get the hang of it, and you’re really liking it! Are you ready to take your jQuery knowledge to level two? Today, I’ll demonstrate twenty functions and features you probably haven’t seen before!

    1 after() / before()

    Sometimes you want to insert something into the DOM, but you don’t have any good hooks to do it with; append() or prepend() aren’t going to cut it and you don’t want to add an extra element or id. These two functions might be what you need. They allow you to insert elements into the DOM just before or after another element, so the new element is a sibling of the older one.

    $('#child').after($('<p />')).text('This becomes a sibling of #child'));
    $('#child').before($('<p />')).text('Same here, but this is go about #child'));
    

    You can also do this if you’re working primarily with the element you want to insert; just use the insertAfter() or insertBefore functions.

    $('<p>I\'ll be a sibling of #child</p>').insertAfter($('#child'));
    
    2 change()

    The change() method is an event handler, just like click() or hover(). The change event is for textareas, text inputs, and select boxes, and it will fire when the value of the target element is changed; note that this is different from the focusOut() or blur() event handlers, which fire when the element loses focus, whether its value has changed or not.

    The change() event is perfect for client-side validation; it’s much better than blur(), because you won’t be re-validating fields if the user doesn’t change the value.

    $('input[type=text]').change(function () {
        switch (this.id) {
            /* some validation code here */
        }
    });​​​​​​​​​​
    
    3 Context

    Context is both a parameter and a property in jQuery. When collecting elements, you can pass in a second parameter to the jQuery function. This parameter, the context, will usually be a DOM element, and it limits the elements returned to item matching your selector that are children of the context element. That might sound a bit confusing, so check out this example:

    <p class="hello">Hello World</p>
    <div id="wrap">
        <p class="hello">Hello World</p>
    </div>
    
    var hi1 = $('.hello'),
        hi2 = $('.hello', $('#wrap').get(0));
    
    console.group('hi1');
    console.log("Number of elements in collection:", hi1.length);
    console.log("Context of the collection:", hi1.context);
    console.groupEnd();
    console.group('hi2');
    console.log("Number of elements in collection:", hi2.length);
    console.log("Context of the collection:", hi2.context);
    console.groupEnd();
    
    context example

    So where would this be useful? One place might be inside an event handler function. If you’d like to get an element within the one the event was fired on, you could pass this as the context:

    $('ul#options li').click(function () {
        $('a', this) . . .
    });
    
    4 data() / removeData()

    Have you ever wanted to store some bit of information about an element? You can do that easily with the data() method. To set a value, you can pass in two parameters (a key and a value) or just one (an object).

    $('#wrap').data('myKey', 'myValue');
    $('#container').data({ myOtherKey : 'myOtherValue', year : 2010 });
    

    To get your data back, just call the method with the key of value you want.

    $('#container').data('myOtherKey'); //returns 'myOtherValue'
    $('#container').data('year'); //returns 2010
    

    To get all the data that corresponds with an element, call data without any parameters; you’ll get an object with all the keys and values you’ve given to that item.
    If you want to delete a key/value pair after you’ve added it to an element, just call removeData(), passing in the correct key.

    $('#container').removeData('myOtherKey');
    
    5 queue() / dequeue()

    The queue() and dequeue() functions deal with animations. A queue is list of animations to be executed on an element; be default, an element’s queue is named ‘fx.’ Let’s set up a scenario:

    HTML

    <ul>
      <li id="start">Start Animating</li>
      <li id="reset">Stop Animating</li>
      <li id="add">Add to Queue</li>
    </ul>
    <div style="width:150px; height:150px; background:#ececec;"></div>
    

    JavaScript

    $('#start').click(animateBox);
    
    $('#reset').click(function() {
        $('div').queue('fx', []);
    });
    
    $('#add').click(function() {
        $('div').queue( function(){
            $(this).animate({ height : '-=25'}, 2000);
            $(this).dequeue();
        });
    });
    
    function animateBox() {
      $('div').slideUp(2000)
               .slideDown(2000)
               .hide(2000)
               .show(2000, animateBox);
    }
    

    So, here’s what’s going on: in the animateBox function, we’re setting up a queue of animations; notice that the last one calls back to the function, so this will continually repeat the queue. When we click li#start, the function is called and the queue begins. When we click li#reset, the current animation finishes, and then the div stops animating. What we’ve done with jQuery is set the queue named ‘fx’ (remember, the default queue) to an empty array; essentially, we’ve emptied the queue. And what about when we click li#add? First, we’re calling the queue function on the div; this adds the function we pass into it to the end of the queue; since we didn’t specify a queue as the first parameter, ‘fx’ is used. In that function, we animate the div, and then call dequeue() on the div, which removes this function from the queue and continues the queue; the queue will continue repeating, but this function will not be part of it.

    6 delay()

    When you’re queuing up a chain of animations, you can use the delay() method to pause the animation for a length of time; pass that time as a parameter in milliseconds.

    $('div').hide().delay(2000).show(); // div will stay hidden for 2 seconds before showing.
    
    7 bind(), unbind(), live(), and die()

    Did you know that when you add a click event to an element like this . . .

    $('#el').click(function () { /*******/ });
    

    . . . you’re really just using a wrapper for the bind() method? To use the bind() method itself, you can pass the event type as the first parameter and then the function as the second.

    If you use a lot of events, you can categorize them with namespacing; just add a period after the event name and add your namespace.

    $('#el').bind('click', function () { /*******/ });
    $('#el').bind('click.toolbarEvents', function () { /*******/ }); // namespaced
    

    You can also assign the same function to multiple events at the same time, by separating them with spaces. So if you wanted to make a hover effect, you could start this way:

    $('#el').bind('mouseover mouseout', function () { /*******/ });
    

    You can also pass data to the function if you’d like, by adding a third parameter (in the second position).

    $('#el').bind('click', { status : 'user-ready' }, function () {
        switch(event.data.status) {
        /********/
        }
    });
    

    Sooner or later, you’ll find yourself inserting element into the DOM via an event handler; however, you’ll find that the event handlers you’ve made with bind (or its wrappers) don’t work for inserted elements. In cases like this, you’ll need to use the live() (or delegate) method; this will add the event handlers to the appropriate inserted elements.

    $('.toggle').live(function () {
        /* code */
        $('<span class="toggle">Enable Beta Features</span>').appendTo($('#optionsPanel'));
        /* more code */
    });
    

    To remove event handlers created with bind(), use the unbind() method. If you don’t pass it any parameters, it will remove all the handlers; you can pass in the event type to only remove event handlers of that type; to remove events from a specific namespace, add the namespace, or use it alone. If you just want to remove a certain function, pass its name along as the second parameter.

    $('button').unbind(); // removes all
    $('button').unbind('click'); // removes all clicks
    $('button').unbind('.toolbarEvents'); // removes all events from the toolbarEvents namespace
    $('button').unbind('click.toolbarEvents'); // removes all clicks from the toolbarEvents namespace
    $('button').unbind('click', myFunction); // removes that one handler
    

    Note that you can bind/unbind functions you’ve passed in anonymously; this only works with the functions name.
    If you’re trying to unbind an event from inside the function called by the event, just pass unbind() the event object.

    $('p').bind('click', function (event) {
        $('p').unbind(event);
    } );
    

    You can’t use unbind() for live events; instead, use the die(). Without parameters, it will remove all live events from the element collection; you can also pass it just the event type, of the event type and the function.

    $('span').die(); // removes all
    $('span').die('mouseover'); // removes all mouseovers
    $('span').die('mouseover', fn); // remove that one handler
    

    And now, you can wield jQuery events with deftness and power!

    You should also review the delegate() method, as there can be substantial performance benefits to using it over live().

    8 eq()

    If you’re looking for a specific element within a set of elements, you can pass the index of the element to the eq() method and get a single jQuery element. Pass in a negative index to count back from the end of the set.

    var ps = $('p');
    console.log(ps.length); // logs 3;
    ps.eq(1).addClass('emphasis'); // just adds the class to the second item (index in zero-based)
    

    You can also use :eq() in your selectors; so the previous example could have been done like this:

    $('p:eq(1)').addClass('emphasis');
    
    9 get()

    When getting a collection of element, jQuery returns them as a jQuery object, so you have access to all the methods. If you just want the raw DOM elements, you can use the get() method.

    You can specify an index to get only one element.

    alert( $('p') ); // [object Object] - the jquery object
    alert( $('p').get(1) ); // [object HTMLParagraphElement]
    
    10 grep()

    If you’re not familiar with Unix/Linix shells, you might not have heard the term grep. In a terminal, it’s a text search utility; but here in jQuery, we use it to filter an array of elements. It’s not a method of a jQuery collection; you pass in the array as the first parameter and the filtering function as the second parameter. That filter function takes two parameters itself: an element from the array and its index. That filter function should perform its work and return a true or false value. Be default, all the items that return true will be kept. You can add a third parameter, a boolean, to invert the results and kept the items that return false.

    Jeffrey Way did a great quick tip about the $.grep not long ago; check that out to see how to use it!

    var nums = '1,2,3,4,5,6,7,8,9,10'.split(',');
    
    nums = $.grep(nums, function(num, index) {
      // num = the current value for the item in the array
      // index = the index of the item in the array
      return num > 5; // returns a boolean
    });
    
    console.log(nums) // 6,7,8,9,10
    
    11 Pseudo-Selectors

    Sizzle, the CSS Selector engine inside jQuery, offers quite a few pseudo-selectors to make the job of selecting the elements you want easy. Check out these interesting ones:

    $(':animated'); // returns all elements currently animating
    $(':contains(me)'); // returns all elements with the text 'me'
    $(':empty'); // returns all elements with no child nodes or text
    $(':parent'); // returns all elements with child nodes or text
    $('li:even'); // returns all even-index elements (in this case, <li>s)
    $('li:odd'); // can you guess?
    $(':header'); // returns all h1 - h6s.
    $('li:gt(4)'); // returns all elements with an (zero-based) index greater than the given number
    $('li:lt(4)'); // returns all element with an index less than the given number
    $(':only-child'); // returns all . . . well, it should be obvious
    

    There are more, of course, but these are the unique ones.

    12 isArray() / isEmptyObject() / isFunction() / isPlainObject()

    Sometimes you want to make sure the parameter that was passed to a function was the corrent type; these functions make it easy to do. The first three are pretty self explanatory:

    $.isArray([1, 2, 3]); // returns true
    $.isEmptyObject({}); // returns true
    $.isFunction(function () { /****/ }); // returns true
    

    The next one isn’t as obvious; isPlainObject() will return true if the parameter passed in was created as an object literal, or with new Object().

    function Person(name) {
    	this.name = name
    	return this;
    }
    $.isPlainObject({})); // returns true
    $.isPlainObject(new Object()); // returns true
    $.isPlainObject(new Person()); // returns false
    
    13 makeArray()

    When you create a collection of DOM elements with jQuery, you’re returned a jQuery object; in some situations, you might prefer that this be an array or regular DOM elements; the makeArray() function can do just that.

    var ps = $('p');
    $.isArray(ps); //returns false;
    ps = $.makeArray(ps);
    $.isArray(ps); // returns true;
    
    14 map()

    The map() method is remotely similar to grep(). As you might expect, it takes one parameter, a function. That function can have two parameters: the index of the current element and the element itself. Here’s what happens: the function that you pass in will be run once for each item in the collection; whatever value is returned from that function takes the place of the item it was run for in the collection.

    $('ul#nav li a').map(function() {
      return $(this).attr('title');
    });  // now the collection is the link titles
    // this could be the beginning of a tooltip plugin.
    
    15 parseJSON()

    If you’re using $.post or $.get—and in other situations that you work with JSON strings—you’ll find the parseJSON function useful. It’s nice that this function uses the browsers built-in JSON parser if it has one (which will obviously be faster).

    $.post('somePage.php', function (data) {
        /*****/
    data =  $.parseJSON(data);
        /*****/
    });
    
    16 proxy()

    If you have a function as a property of an object, and that function uses other properties of the object, you can’t call that function from within other functions and get the right results. I know that was confusing, so let’s look at a quick example:

    var person = {
      name : "Andrew",
      meet : function () {
        alert('Hi! My name is ' + this.name);
      }
    };
    person.meet();
    $('#test').click(person.meet);
    

    By itself, person.meet() will alert correctly; but when it’s called by the event handler, it will alert “Hi! My name is undefined.” This is because the function is not being called in the right context. To fix this, we can use the proxy() function:

    $('#test').click($.proxy(person.meet, person));
    // we could also do $.proxy(person, "meet")
    

    The first parameter of the proxy function is the method to run; the second is the context we should run it in. Alternatively, we can pass the context first, and the method name as a string second. Now you’ll find that the function alerts correctly.

    Prefer a video quick tip on $.proxy?

    17 replaceAll() / replaceWith()

    If you’d like to replace DOM elements with other ones, here’s how to do it. We can call replaceAll() on elements we’ve collected or created, passing in a selector for the elements we’d like to replace. In this example, all elements with the error class will be replaced with the span we’ve created.

    $('<span class="fixed">The error has been corrected</span>').replaceAll('.error');
    

    The replaceWith() method just reverses the selectors; find the ones you want to replace first:

    $('.error').replaceWith('<span class="fixed">The error has been corrected</span>');
    

    You can also pass these two methods functions that will return elements or HTML strings.

    18 serialize() / serializeArray()

    The serialize() method is what to use for encoding the values in a form into a string.

    HTML

    <form>
        <input type="text" name="name" value="John Doe" />
        <input type="text" name="url" value="http://www.example.com" />
    </form>
    

    JavaScript

    console.log($('form').serialize());​​​ // logs : name=John+Doe&url=http%3A%2F%2Fwww.example.com
    

    You can use serializeArray() to turn the form values into an array of objects instead of a string:

    console.log($('form').serializeArray());​​​
    // logs : [{ name : 'name', value : 'John Doe'} , { name : 'url', value : 'http://www.example.com' } ]
    
    19 siblings()

    You can probably guess what the siblings() method does; it will return a collection of the siblings of the whatever items are in your original collections:

    <div> . . . </div>
    <p> . . . </p>
    <span> . . . </span>
    
    $('p').siblings(); // returns <div>, <span>
    
    20 wrap() / wrapAll() / wrapInner()

    These three functions make it easy to wrap elements in other elements. First off, I’ll mention that all three take one parameter: either an element (which is an HTML string, a CSS selctor, a jQuery object, or a DOM element) or a function that returns an element.
    The wrap() method wraps each item in the collection with the assigned element:

    $('p').wrap('<div class="warning" />'); // all paragraphs are now wrapped in a div.warning
    

    The wrapAll() will wrap one element around all the elements in the collection; this means that the elements in the collection will be moved to a new spot in the DOM; they’ll line up at the place of the first element in the collection and be wrapped there:

    HTML, Before:

    <p>
        <span> . . . </span>
        <span class="moveMe"> . . . </span>
        <span class="moveMe"> . . . </span>
    </p>
    <p>
        <span> . . . </span>
        <span class="moveMe"> . . . </span>
        <span class="moveMe"> . . . </span>
    </p>
    

    JavaScript

    $('.moveMe').wrapAll(document.createElement('div'));
    

    HTML, After:

    <p>
        <span> . . . </span>
        <div>
            <span class="moveMe"> . . . </span>
            <span class="moveMe"> . . . </span>
            <span class="moveMe"> . . . </span>
            <span class="moveMe"> . . . </span>
        </div>
    </p>
    <p>
        <span> . . . </span>
    </p>
    

    Finally, the wrapInner function wraps everything inside each element in the collecting with the given element:

    HTML, Before:

    <p>
        <span> . . . </span>
        <span> . . . </span>
    </p>
    

    JavaScript:

    $('p').wrapInner($('<div />'));
    

    HTML, After:

    <p>
        <div>
            <span> . . . </span>
            <span> . . . </span>
        </div>
    </p>
    
    Conclusion

    Well, now you’ve got more than twenty new jQuery features to play with on your next project; have fun with them!


  • Permalink for 'CodeIgniter from Scratch: Shopping Cart'

    CodeIgniter from Scratch: Shopping Cart

    Posted: March 25th, 2010, 12:30pm MDT by Burak Guzel

    Today, we are going to take a look at the Shopping Cart library for CodeIgniter. This useful class allows us to add and remove items to a shopping cart, update them, and calculate prices. I will demonstrate how you can build a simple shopping cart system with the help of this library..

    Catch Up Day 12: Shopping Cart Final Project


  • Permalink for 'Build an Awesome Status Board: New Premium Tutorial'

    Build an Awesome Status Board: New Premium Tutorial

    Posted: March 24th, 2010, 8:15pm MDT by Andrew Burgess

    When Panic unveiled their status panel to the world, I was both impressed and inspired. In today’s in depth Premium tutorial and screencast, I’ll show you how to built a similar status board! Help give back to Nettuts+ by joining our Premium program.


    Final Product
    Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Join today!


  • Permalink for 'MVC for Noobs'

    MVC for Noobs

    Posted: March 24th, 2010, 12:05pm MDT by Pablo Pastor

    Model-View-Controller (MVC) is probably one of the most quoted patterns in the web programming world in recent years. Anyone currently working in anything related to web application development will have heard or read the acronym hundreds of times. Today, we’ll clarify what MVC means, and why it has become so popular.


    Ancient History…

    MVC is not a design pattern, it is an Architectural pattern that describes a way to structure our application and the responsibilities and interactions for each part in that structure.

    It was first described in 1979 and, obviously, the context was a little bit different. The concept of web application did not exist. Tim Berners Lee sowed the seeds of World Wide Web in the early nineties and changed the world forever. The pattern we use today for web development is an adaptation of the original pattern.

    The wild popularization of this structure for web applications is due to its inclusion in two development frameworks that have become immensely popular: Struts and Ruby on Rails. These two environments marked the way for the hundreds of frameworks created later.

    MVC for Web Applications

    The idea behind the Model-View-Controller architectural pattern is simple: we must have the following responsibilities clearly separated in our application:

    The application is divided into these three main components, each one in charge of different tasks. Let’s see a detailed explanation and an example.

    Controller

    The Controller manages the user requests (received as HTTP GET or POST requests when the user clicks on GUI elements to perform actions). Its main function is to call and coordinate the necessary resources/objects needed to perform the user action. Usually the controller will call the appropriate model for the task and then selects the proper view.

    Model

    The Model is the data and the rules applying to that data, which represent concepts that the application manages. In any software system, everything is modeled as data that we handle in a certain way. What is a user, a message or a book for an application? Only data that must be handled according to specific rules (date can not be in the future, e-mail must have a specific format, name cannot be more than x characters long, etc).

    The model gives the controller a data representation of whatever the user requested (a message, a list of books, a photo album, etc). This data model will be the same no matter how we may want to present it to the user, that’s why we can choose any available view to render it.

    The model contains the most important part of our application logic, the logic that applies to the problem we are dealing with (a forum, a shop, a bank, etc). The controller contains a more internal-organizational logic for the application itself (more like housekeeping).

    View

    The View provides different ways to present the data received from the model. They may be templates where that data is filled. There may be several different views and the controller has to decide which one to use.

    A web application is usually composed of a set of controllers, models and views. The controller may be structured as a main controller that receives all requests and calls specific controllers that handles actions for each case.

    Let’s See an Example

    Suppose we’re developing an online book store. The user can perform actions such as: view books, register, buy, add items to current order, create or delete books (if he is an administrator, etc.). Let’s see what happens when the user clicks on the fantasy category to view the titles we have available.

    We will have a particular controller to handle all books-related actions (view, edit, create, etc). Let’s call it books_controller.php for this example. We will also have a model, for example book_model.php, handling data and logic related to the items in the shop. Finally we will have a series of views to present, for example, a list of books, a page to edit books, etc.

    The following figure shows how the user request to view the fantasy books list is handled:

    The controller (books_controller.php) receives the user request [1] as an HTTP GET or POST request (we can also have a central controller, for example index.php receiving it and then calling books_controller.php).

    The controller examines the request and the parameters and calls the model (book_model.php) asking him to return the list of available fantasy books [2].

    The model is responsible for getting that information from the database (or wherever it is stored) [3], apply filters or logic if necessary, and return the data representing the list of books [4].

    The controller will use the appropriate view [5] to present these data to the user [6-7]. If the request came from a mobile phone, a view for mobile phones will be used, if the user has a particular skin selected, the corresponding view will be chosen, and so on.

    What are the Advantages?

    The most obvious advantage we gain using MVC is a clear separation of presentation (the interface with the user) and application logic.

    Support for different types of users using different types of devices is a common problem these days. The interface presented must be different if the request came from a desktop computer or from a cell phone. The model returns exactly the same data, the only difference is that the controller will choose a different view to render them (we can think of a different template).

    Apart from isolating the view from the business logic, the M-V-C separation reduces the complexity when designing large applications. The code is much more structured and therefore easier maintain, test and reuse.

    Ok, but Why a Framework?

    When you use a framework, the basic structure for MVC is already prepared and you just have to extend that structure, placing your files in the appropriate directory, to comply with the Model-View-Controller pattern. Also you get a lot of functionality already written and thoroughly tested.

    Take cakePHP as an example MVC framework. Once you have it installed, you’ll see three main directories:

    • app/
    • cake/
    • vendors/

    The app folder is where you place your files. It is your place to develop your part of the application.

    The cake folder is where cakePHP has its files and where they have developed their part (main framework functionality).

    The vendors folder is for third-party PHP libraries if needed.

    Your working place (app directory) has the following structure:

    • app/
      • config/
      • controllers/
      • locale/
      • models/
      • plugins/
      • tests/
      • tmp/
      • vendors/
      • views/
      • webroot/

    Now you have to put your controllers in the controllers directory, your models in the models directory and your views in… the views directory!

    Once you get used to your framework, you’ll be able to know where to look for almost any piece of code you need to modify or create. This organization alone makes maintainability a lot easier.

    Let’s Framework our Example

    Since this tutorial is not intended to show you how to create an application using cakePHP, we’ll use it only to show example code for the model, view and controller components and comment on the benefits of using an MVC framework. The code is oversimplified and not suitable for real applications.

    Remember we had a book store and a curious user who wants to see the complete list of books in the fantasy category. We said that the controller will be the one receiving the request and coordinating the necessary actions.

    So, when the user clicks, the browser will be requesting this url:

     www.ourstore.com/books/list/fantasy

    CakePHP likes to format URLs in the form /controller/action/param1/param2 , where action is the function to call within the controller. In the old classic url format it would be:

     www.ourstore.com/books_controller.php?action=list&category=fantasy
    Controller

    With the help of cakePHP framework, our controller will look something like this:

    
    <?php
    
    class BooksController extends AppController {
    
     function list($category) {
    
     $this->set('books', $this->Book->findAllByCategory($category));
    
     }
    
     function add() { ... ... }
    
     function delete() { ... ... }
    
     ... ... } ?>
    

    Simple, isn’t it?. This controller will be saved as books_controller.php and placed in /app/controllers. It contains the list function, to perform the action in our example, but also other functions to perform other book-related actions (add a new book, delete a new book, etc).

    The framework provides a lot of things for us and only one line is necessary to list the books. We have base classes with the basic controller behavior already defined, so we inherit from them (AppController which inherits from Controller).

    All it has to do in the list action is call the model to get the data and then choose a view to present it to the user. Let’s explain how this is done.

    this->Book is our Model, and this part:

     $this->Book->findAllByCategory($category) 

    is telling the model to return the list of books in the selected category (we’ll see the model later).

    The set method in the line:

     $this->set('books', $this->Book->findAllByCategory($category)); 

    Is the controller way to pass data to the view. It sets the books variable to the data returned by the model and makes it accessible to the view.

    Now we just have to render the view, but this will be done automatically by cakePHP if we want the default view. If we need any other view we just have to call it explicitly using the render method.

    Model

    The model is even more simple:

    
    <?php
    
    class Book extends AppModel { 
    
    }
    
    ?>
    

    Why empty? Because it inherits from a base class that provides necessary functionality and we have followed the CakePHP name conventions to allow the framework to do other tasks automatically. For example, cakePHP knows, based on names, that this model is used in BooksController and that it will access a database table called books.

    With this declaration only we have a book model capable of reading, deleting or saving data from the database

    The code will will be saved as book.php and placed in /app/models.

    View

    All we have to do now is creating a view (at least one) for the list action. The view will have the HTML code and a few (as few as possible) PHP lines to loop through the books array provided by the model.

    
    <table> <tr> <th>Title</th> <th>Author</th> <th>Price</th> </tr>
    
    <?php foreach ($books as $book): ?> <tr> <td> <?php echo $book['Book']['title']; ?> </td> <td> <?php echo $book['Book']['author']; ?> </td> <td> <?php echo $book['Book']['price']; ?> </td> </tr> <?php endforeach; ?>
    
    </table>
    

    As we can see, the view doesn’t produce a complete page, just an HTML fragment (a table in this case). This is because CakePHP provides another way to define the layout of the page, and the views are inserted into that layout. The framework also provides us with some helper objects to make common task easy when creating these HTML excerpts (insert forms, links, Ajax or JavaScript).

    We make this the default view saving it as list.ctp ( list is the name of the action and ctp means cake template) and placing it in /app/views/books (inside books because these are views for books controller actions).

    And this completes the three components with the help of CakePHP framework!

    Conclusion

    We have learned what is probably the most commonly used architectural pattern today. We must be aware though that when we talk about patterns in the programming world, we are talking about flexible frames, to be tailored to the particular problem at hand. We will find implementations introducing variations on the structure we have seen, but the important thing is that, in the end, the pattern helps us gain a clear division between responsibilities and better maintainability, code-reuse, and testing.

    We have also seen the advantages of using an MVC framework that provides us with a basic MVC skeleton and a lot of functionality, improving our productivity and making the development process easier. Thanks for reading!


  • Permalink for 'Setting up a Rails Server and Deploying with Capistrano on Fedora from Scratch'

    Setting up a Rails Server and Deploying with Capistrano on Fedora from Scratch

    Posted: March 23rd, 2010, 9:07pm MDT by Adam Hawkins

    This article and video tutorial will teach you how to setup a basic Fedora server for Rails and PostgreSQL deployments. First, we’ll setup Apache and PostgreSQL. Then, we’ll use phpPgAdmin to create our application’s user and databases. After that, we’ll setup the Ruby platform using Passenger to run our application. Once all the components are installed, we’ll prep our application for deployment using Capistrano.

    I’ll show you how to use Capistrano to automate remote tasks and take advantage of other features.

    On With The Show
    Understanding the Deployment Process

    There is always a lot of confusion around deploying Rails applications. This tutorial hopes to sort some of that out. Most people know LAMP: Linux, Apache, MySQL, and PHP. We will setup LAPR: Linux, Apache, PostgreSQL, and Ruby. Setting up a LAPR server is very similar to setting up a LAMP server. The only wrinkle is getting Rails to talk to Apache. Thankfully, there is Passenger aka mod\_rails. Passenger is like mod\_php. It makes running Rails applications easy as pie. In order to run a Rails application through Apache, create a virtual host pointing the document root to the applications public directory and you’ll be riding on rails.

    Capistrano is another part that people may not be familiar with. Capistrano is a Ruby gem designed to execute tasks on one or more remote machines. You’ll need SSH access to use Capistrano. Capistrano, affectionately known as Cap, automates the deploy process. We can use cap to take our code from some a repo and push it to the server, stop/start/restart the server, write custom tasks required by our application (think install required gems), or disable/enable a maintenance page. Using cap is not required but it sure beats using FTP to copy all the files around! Cap’s real power comes from the ability to write custom tasks in Ruby to manipulate the server. I’ve written a lot of applications that allow user file uploads. Then on the server side, some directory needs to be created with proper permissions for the uploads to succeed. It’s easy enough to write a cap task to create the directory and set the permissions. Then, if you ever change servers, you can simply run the cap task to setup the server again. There are many things you can do with Capistrano. You could even automate this entire tutorial to set up any number of machines at once!

    Tutorial Sandbox

    In order to complete this tutorial, you’ll need SSH + sudo access. If you don’t have a spare server sitting around, you can create one in VirtualBox. You can easily create a new VM and network it with your host system. I did this for the tutorial. When you start your virtual machine, make sure you use a bridged adapter so your VM gets an IP on the same subnet. I started with a fresh install without any customization. If you have access to a VPS like SliceHost, you can use these instructions as well.

    Be sure to view the screencast before analyzing the code below.

    Creating The Deployer
        $ sudo adduser -m deployer
        $ sudo passwd deployer
        $ sudo visudo deployer ALL=(ALL) NOPASSWD: ALL
        $ su deployer
        $ mkdir ~/.ssh
        $ touch ~/.ssh/authorized_keys2
        $ chmod -R 0700 ~/.ssh
        # copy your public key and paste it into the authorized_keys2 file
        $ service sshd start
    
    Setting Up Postgres
        $ sudo yum groupinstall "PostgreSQL Database"
        $ sudo service postgresql initdb
        $ sudo service postgresql start
        $ su - postgres
        $ psql -d template1
        $ alter user postgres with password 'yourpostgresuserpassword';
        $ \q
        # Replace ident in /var/usr/lib/pgsql/data/pg_hba.conf with md5
        $ passwd postgres
        # set extra security in /etc/phpPgAdmin/config.inc.php to false
        # add 'Allow from YOUR_IP_HERE' to vhost in /etc/httpd/conf.d/phpPgAdmin.conf
        # enable http in the firewall
        $ sudo yum install [httpd]     $ sudo service [httpd] start
        $ sudo service postgresql restart
    
    Configuring Ruby, RubyGems, and Passenger
        $ sudo yum groupinstall Ruby
        $ sudo yum install rubygems
        $ sudo gem install gemcutter
        $ sudo yum install postgresql-devel
        $ sudo gem install pg
        $ sudo gem install passenger
        $ yum install gcc-c++ [httpd-devel] apr-devel
        $ sudo passenger-install-apache2-module
        # create this file /etc/http/conf.d/passenger.conf with these contents:
          LoadModule passenger_module     /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9/ext/apache2/mod_passenger.so
          PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9
          PassengerRuby /usr/bin/ruby
    
        $ sudo setenforce 0
        $ sudo service [httpd] restart
    
    Creating the Deployer Folder
        $ sudo mkdir /var/www/html/apps
        $ sudo chown deployer:apache /var/www/html/apps
        $ sudo yum install git
        # at this point, create your databases in phpPgAdmin
     
    Configuring Apache
        # echo "Include vhost.d/*.vhost" >> /etc/httpd/conf/httpd.conf
        $ sudo mkdir /etc/httpd/vhost.d
        $ sudo touch /etc/httpd/vhost.d/nettuts-demo.vhost
        # update that files conttents to:
          
              ServerName www.nettuts-demo.com
              DocumentRoot /var/www/html/apps/nettuts-demo/current/public
              
                Options FollowSymLinks
                  Allow from all
                  Options -MultiViews
              
    
              RewriteEngine On
              RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
              RewriteCond %{SCRIPT_FILENAME} !maintenance.html
              RewriteRule $ /system/maintenance.html [R=302,L]
          
    
    Complete Cap File
        set :application, "nettuts-demo"
        set :repository,  "git://github.com/Adman65/Nettuts-Capistrano-Deployments.git"
    
        set :user, :deployer
    
        set :deploy_to, "/var/www/html/apps/#{application}"
    
        set :use_sudo, false
    
        set :scm, :git
    
        role :web, "192.168.1.112"                          # Your HTTP server, Apache/etc
        role :app, "192.168.1.112"                          # This may be the same as your `Web` server
        role :db,  "192.168.1.112", :primary => true # This is where Rails migrations will run
        role :db,  "192.168.1.112"
    
        default_run_options[:pty] = true
    
        namespace :deploy do
           task :start do ; end
           task :stop do ; end
           task :restart, :roles => :app, :except => { :no_release => true } do
             run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
           end
    
           desc "Installs required gems"
           task :gems, :roles => :app do
             run "cd #{current_path} && sudo rake gems:install RAILS_ENV=production"
           end
           after "deploy:setup", "deploy:gems"   
    
           before "deploy", "deploy:web:disable"
           after "deploy", "deploy:web:enable"
        end
    


  • Permalink for 'Quick Tip: Understanding CSS3 Gradients'

    Quick Tip: Understanding CSS3 Gradients

    Posted: March 23rd, 2010, 6:39pm MDT by Jeffrey Way

    Creating an image only for the purpose of displaying a gradient is inflexible, and is quickly becoming a bad practice. Unfortunately, at the time of this writing, they very well might still be required, but hopefully not for much longer. Thanks to Firefox and Safari/Chrome, we can now create powerful gradients with minimal effort. In this video quick tip, we’ll examine some of the differences in syntax when working with the -moz and -webkit vendor prefixes.


    Subscribe to our YouTube page to watch all of the video tutorials! Webkit

    While Mozilla and Webkit generally adopt the same syntax for CSS3 properties, they unfortunately don’t quite agree when it comes to gradients. Webkit was first to embrace gradients, and uses the following structure:

    /* Syntax, taken from: [webkit.org] */
    -webkit-gradient(<type>, <point> [, <radius>]?, <point> [, <radius>]? [, <stop>]*)
    
    /* In practice... */
    background: -webkit-gradient(linear, 0 0, 0 100%, from(red), to(blue));
    
    Webkit

    Don’t worry if your eyes gloss over at that syntax; mine did too! Just note that we require a comma-separated list of parameters.

    • What type of gradient? (linear)
    • X and Y axis coordinates of where to begin. (0 0 – or left-top corner)
    • X and Y axis coordinates of where to conclude (0 100% – or left-bottom corner)
    • What color to begin with? (from(red))
    • What color to conclude with? (to(blue))
    Mozilla

    Firefox, which implemented gradient support with version 3.6, prefers a slightly different syntax.

    /* Syntax, taken from: [hacks.mozilla.org] */
     -moz-linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* )
    
    /* In Practice */
    background: -moz-linear-gradient(top, red, blue);
    
    Mozilla
    • Note how we’ve placed the type of gradient, linear, within the vendor extension.
    • Where should the gradient begin? (top – we could also pass in degrees, as in -45deg)
    • What color to start with? (red)
    • What color to conclude with? (blue)
    Color-Stops

    What if you don’t need a 100% gradient from one color to another? This is where color stops come into play. A common design technique is to apply a short and subtle gradient, like this:

    Subtle Gradients

    Note the subtle off-white to white gradient at the top.

    In the past, the standard implementation was to create an image, set it as the background of an element, and set it to repeat horizontally. However, with CSS3, this is a cinch.

    background: white; /* fallback for older/unsupporting browsers */
    background: -moz-linear-gradient(top, #dedede, white 8%);
    background: -webkit-gradient(linear, 0 0, 0 8%, from(#dedede), to(white));
    border-top: 1px solid white;
    

    This time, we set the gradient to conclude at 8%, rather than 100%, which is the default. Note that we’re also applying a border top to add contrast; this is very common.

    If we wish to add a third (or Nth) color, we can do:

    background: white; /* fallback for older/unsupporting browsers */
    background: -moz-linear-gradient(top, #dedede, white 8%, red 20%);
    background: -webkit-gradient(linear, 0 0, 0 100%, from(#dedede), color-stop(8%, white), color-stop(20%, red);
    
    • With the -moz version, we designate that, at 20% of the element height, we should now be at the color red.
    • For -webkit, we use color-stop, and pass in two parameters: where the stop should occur, and what the color should be.
    Important Notes About CSS Gradients
    • Use them as much as you can. If it’s okay to let IE users see a solid color, I encourage you to use this method.
    • IE6/7/8, Opera, Safari 3, and Firefox 3 cannot render CSS3 gradients. Firefox and Safari users generally upgrade often, so that’s not as big of a deal.
    • Always apply a default, solid color, background for browsers that won’t understand the vendor prefixes.
    • Never use a red to blue gradient, as I did for the examples.
    • Webpages don’t need to look the same in every browser! )

    Thanks for reading/watching!


  • Permalink for 'A 15 Minute Surreal CMS Integration'

    A 15 Minute Surreal CMS Integration

    Posted: March 22nd, 2010, 3:30am MDT by Cory LaViska

    You’ve already built your website, but how are you going to maintain it? In this tutorial, you’ll learn how to integrate your website with Surreal CMS in under 15 minutes. We’ll go over some of the “gotchas” and have you editing virtually any static website in barely no time at all.

    Overview
    SurrealCMS

    You’re probably wondering how you could possibly integrate your entire website with a CMS in just 15 minutes. The truth is, due to the recent trend of “light” content management systems, it’s becoming easier than ever to get small to mid-sized static websites up and running in them.

    What is a light CMS? For the sake of this tutorial, I’m defining it as an easy-to-use, unobtrusive content management system that you don’t have to install. The nice thing about these systems is that you don’t even have to host them yourself, which is why integration takes very little time.

    There are actually a handful of these CMS products available, including CushyCMS, Pagelime, and SimpleCMS. Most of these systems work off the same basic principle — you add class=”something” to almost any HTML element, link your website up to their system, and you’re done. Best of all, every one of these systems offer a free version.

    Although every light CMS product has its pros and cons, I chose to work with Surreal CMS because of their vast feature set and simple interface. You’ll see exactly what I mean in just a moment, but in the meantime, here is the general process of integrating with any light CMS:

    • Create your website
    • Link it up to the CMS
    • Enable webpages
    • Add one or more editors
    • Begin editing

    Just to familiarize you with the tool that we’ll be working with, here is a quick glimpse of Surreal CMS’ webpage editing screen:

    Design Considerations

    Before you begin working with a light CMS, it’s always good to think about things such as character encoding and the way you link to images and other resources. Surreal CMS prefers that you use UTF-8 character encoding, which is as simple as adding the following meta tag to the <head> section of each webpage:

    <meta [http-equiv="Content-Type"] content="text/html; charset=utf-8" />
    

    It’s also important that you link to documents, images, and other resources in a way that the CMS can understand. Surreal CMS works best when you use root-relative linking or absolute linking:

    <a href="/images/photo.jpg">...</a>
    <a href=" [example.com] 

    The last but probably most important thing to consider before linking your website up to Surreal CMS is the placement of your content regions. Here is an excellent example of a very basic webpage that has a navigation menu, a sidebar, and a main content area:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " [www.w3.org] <html xmlns=" [www.w3.org] 	<head>
    		<title>Example Webpage</title>
    		<meta [http-equiv="Content-Type"] content="text/html;charset=UTF-8" />
    		<meta name="description" content="This is an example webpage" />
    		<meta name="keywords" content="example, examples" />
    		<link href="/css/screen.css" rel="stylesheet" type="text/css" media="screen" />
    	</head>
    
    	<body>
    
    		<div id="header">
    			<h1><a href=" [example.com] 		</div>
    
    		<div id="nav">
    			<?php include("$_SERVER[DOCUMENT_ROOT]/includes/nav.php"); ?>
    		</div>
    
    		<div id="middle">
    
    			<div id="sidebar" class="editable">
    				<p>Sidebar content here</p>
    			</div>
    
    			<div id="main_content" class="editable">
    				<p>Your content here</p>
    			</div>
    
    		</div>
    
    		<div id="footer">
    			<p>&copy;Example.com</p>
    		</div>
    
    	</body>
    
    </html>
    

    You may have noticed that I added editable classes to the sidebar and the main content region. This is how the CMS knows what sections of your page it should allow you to edit. You can add the editable class to almost any HTML tag, and you can have as many as you want on each page.

    Another thing you may have noticed was that the navigation is being included from a separate file via PHP. Surreal CMS allows you to work with included files like this so you can update your entire site’s navigation without having to edit each page individually.

    Once you’ve prepared your pages and setup editable regions, you’ll be ready to integrate your website with Surreal CMS.

    Adding Your Website to the CMS

    Surreal CMS offers both free and paid accounts. The free account has very few restrictions, and will be more than sufficient for the sake of this tutorial. Simply go to their website and create a free account.

    Once your account is created, login to the CMS at [edit-content.com] . This is the gateway to the Surreal CMS application.

    Now that you’re in, select the button that says Add a Website. Here is the form that you will see:

    Enter your website’s URL, server (usually ftp.your-domain.com), FTP username, and FTP password. You can verify that you typed everything correctly by clicking Test Connection.

    For the Website Root, it’s best to click the Browse button and use the browsing tool. Essentially, your website root will be the folder that contains your homepage. It’s important that this folder be the actual folder that has your homepage so the CMS can properly map URLs to images and other files.

    If you want to specify custom paths for documents, images, and media files, select the Advanced option. When you set custom paths, it will tell the CMS where other people who are editing your website are allowed to upload files. For now, you can leave these blank.

    Enabling Your Webpages

    Now that your website has been added to the CMS, the next step is to enable your webpages. In other light CMS products, this can be a bit taxing on your time, but Surreal CMS has a nice scan feature that auto-enables webpages with just a click.

    To begin enabling pages, select your website from the list:

    Next, select Enable Webpages. The following dialog will appear:

    Select the page or pages that you want to be able to edit in the CMS. As you select them, they will appear one-by-one in the background. As a shortcut, you can navigate to any directory on your website and click Scan for Editable Pages. This will tell the CMS to enable any page in the current directory that has a class=”editable” attribute in it. When you’re finished, select Done.

    By default, each page that you enable uses the <title> of the page as a label. You can easily change this to something more CMS-friendly by clicking on Edit Label. For example, you might change the label for index.php to read “Homepage” and the label for nav.php to read “Navigation”.

    Updating Your Content

    Believe it or not, the hard part is over. Now it’s just a matter of getting in there and editing content. Part of the reason I like Surreal CMS so much is that it streamlines most of the setup. That said, let’s move on to editing content.

    After you enable one or more webpages, the next step is to begin editing. Simply select any of the pages that you’ve enabled by clicking on the appropriate page label. This will take you into the webpage editor, where you’ll spend most of your time using this great CMS.

    In the webpage editor, you’ll see four tabs:

    • Content – This is where all your content regions can be found.
    • Properties – You can edit the page title, keywords, and description here.
    • History – View every revision of this page that gets published for up to 90 days.
    • Editors – See a list of all the editors that have access to the page.

    Inside of the Content tab, assuming your page has at least one editable region, you’ll see something like this:

    This particular example has the two editable regions we talked about earlier: sidebar and main_content. You’ll notice that the CMS converted the lowercase, underscore-separated IDs into Camel Case, space-separated labels for aesthetics. If you have more than one editable region on a page, you can switch between them by clicking on the appropriate button.

    At this point, editing works the same way as it does in many other content management systems and word processing applications. You can format text, change alignment, insert images, lists, etc. Surreal CMS even has a built in File Manager that lets you view, upload, rename, and delete files and folders. To top it off, there is also an Image Editor that lets you resize, crop, rotate, and flip images with ease.

    Depending on the type of element that you add class=”editable” to, Surreal CMS will provide an appropriate editing tool. As an example, here is what an editable <img> looks like:

    The Edit Image button launches the Image Editor that I talked about earlier. It’s really easy to use, so you shouldn’t have any trouble at all manipulating your photos. Here’s what it looks like:

    Once you’re finished editing, you can preview your changes by clicking Preview. A new window will open, and you’ll see your page exactly as it will appear when published. Of course, if you’re happy with your changes, clicking Publish will save them to your website.

    Allowing Other People to Edit Your Website

    Now that you know how to setup your website and edit it yourself, wouldn’t it be nice to allow other people access as well? This is especially useful for designers who want to give clients limited access to edit their own websites, and it’s simple to setup.

    First, select the Editors tab from anywhere in the CMS and click on Add an Editor. The following form will appear:

    Simply fill in the person’s name and email address to start. Then, select the website(s) that he or she should be assigned to. If you want, you can open up the Advanced section and allow the editor to clone pages, delete pages, and edit page properties. You can also enable or disable every option in the rich-text editor toolbar from here.

    Once you’ve entered all the necessary information, select Add Editor and the user will be added to the CMS. By default, an email is sent to them containing their username and password. You can disable this, however, and the CMS will show you their temporary password for you to provide them with manually.

    There are a couple things that you need to know about editor accounts. First, they don’t have access to everything that you do as a designer — editors only have access based on the websites and permissions that you assign to them. Second, editors don’t have access to things like full-page source code editing and the Tidy tool, which we’ll talk about shortly. The best way to see what the difference is between a designer and an editor account is to create yourself a test editor with an alternate email address.

    Before we move on, there’s one other feature that you should know about editors. You can block them from editing specific pages on a per-user basis. Simply open any page for editing and select the Editors tab. Next to your editor will be an option to Disable editing. Clicking this will prevent that user from editing the current page.

    Other Handy Features

    So far, we’ve covered everything from integrating Surreal CMS with your website to editing pages. The fun doesn’t stop there, though. Here is a list of features that you can take advantage of once you start to explore deeper into what Surreal CMS offers:

    Cloning Webpages

    You can create new pages by duplicating existing ones. This is especially useful because you can setup one or more blank template pages and let your users create pages as they need to. You can also turn this on or off for each user, so more experienced editors can have more control over the site.

    Styling the Rich-text Editor

    Apply styles from your website to the rich-text editor to give users a similar look and feel similar to the website. To access this feature, select the Websites tab from anywhere in the CMS and choose a website. You’ll see a button labeled Change Editor Styles.

    Editing CSS, JavaScript, and XML Files

    You can enable stylesheets, scripts, and XML files just like any other webpage. Of course, you’ll be editing raw source code, so you might want to block inexperienced users from accessing these types of files if you enable them.

    Editing Full HTML Source Code

    While you’re editing a webpage, you’ll notice a button labeled “Edit Content Regions”. This actually allows you access to the full source code of the page. Editors do not have access to this tool.

    Repairing Messy HTML Code with Tidy

    Surreal CMS has a built in tool that utilizes the popular HTML Tidy library. This is useful for fixing nested tags or invalid HTML code that may cause problems while editing. You can access this tool from within the full source code editing page.

    Viewing Editor Activity

    You can see what your editors have been up to! This includes what pages they’ve accessed, when they were edited, and even the times that they logged in to the CMS. To view this information, select the Editors tab from anywhere in the CMS and choose an editor. Click on the editors name to see their recent activity.

    Pro Features

    Surreal CMS is free to use for up to three websites. After that, they ask you to pay $25 USD per month for their paid service, but Pro accounts have a couple other nice features, too. For example, you can access the CMS from your own domain or subdomain (i.e. cms.your-domain.com).

    With a Pro account, you can also upload your own logo and customize the theme, which is ideal for designers who want to use the CMS as a solution for their clients. Here’s an example of what you can expect when you brand the CMS as your own:

    Additional Resources

    Now that you know all of the basics (and some advanced tips, too!), here are some useful resources for working with Surreal CMS:


  • Permalink for 'Quick Tip: How to Write a Neat FlipNav Script'

    Quick Tip: How to Write a Neat FlipNav Script

    Posted: March 19th, 2010, 3:32pm MDT by Jeffrey Way

    Somehow, I inadvertently started a navigation series over the last few weeks. It’s purely coincidence, mostly spawned by emails and such. This week, we’re going to mimic the neat navigation functionality, found on JohnMayer.com. Simply mouse over one of the navigation items to see the effect. However, we’re going to make it a bit more flexible by removing the need for images. We’ll achieve the effect using only CSS and JavaScript.

    Other Viewing Options


  • Permalink for 'Inspiration: Awesome Dark Portfolio Sites'

    Inspiration: Awesome Dark Portfolio Sites

    Posted: March 19th, 2010, 11:49am MDT by Tyler Denis

    These days, a portfolio is a must. What we have here is a list of dark portfolio websites that are split up into common groups that most portfolios fall in. The last group will be for those experimental dark layouts, where the designer tries something different.

    Rotating Image/Static Featured Image

    We’ll start out with perhaps the most popular forms of portfolio design. This is the jQuery rotating image. The great thing about this kind of portfolio is that you can show a lot of work, with minimal space, saving room for other information.

    Also falling into this group is the static featured image. While similar to the rotating image, it may not be quite as effective as the rotating image because of the lack of animation and interaction. On the plus side, a static featured image could also be used as a teaser to get people to look at the rest of your work.

    antonpeck.com bressane.com intuitivedesigns.net jayhollywood.com.au jilion.com neutroncreations.com oysterdesign.co.uk projectkoreck.com rocknsites.com Tagline/Bio

    With this kind of portfolio, the viewer goes to the website and sees exactly what the website is about or who the designer is. If what you are offering or your tagline peaks their interest, they will look around your website. It usually helps and makes it more effective if the tagline is paired with another one of these styles of portfolio website, unless the typography can stand on its own as a visual element.

    alt-design.net bythepond.co.uk chanellehenry.com wedesignwise.com joshhemsley.com justincline.com liftux.com markjmaloney.com moxiesozo.comindex.php phynk.net radiiate.com rareview.com studio7designs.com tonychester.com visualgroove.net Text/Feature Image

    What makes this kind of portfolio website effective is that the viewer gets a little information about the website, as well as a sampling of what the portfolio has to offer.

    ba21.us harryjh.com nosleepforsheep.com sawyerhollenshead.com slovaczech.com thingsthatarebrown.com Portfolio Grid

    This type of website gets to the point like the tagline/bio and text/image, except the viewer gets bombarded (in a good way) with the designer’s work. This keeps the interest of the viewer, because they don’t have to look around the actual portfolio pieces.

    design-dps.com jannek.fi jonahl.com onvo.co.uk phantomcandy.com phunkn.com thehousemedia.com Non-Portfolio Image Large Header

    This website basically shows the viewer what the designer can do without actually showing specific examples. A stand-out photo manipulation/illustration/photo catches the eye and gets the point across.

    arsum.com bogdanteodorescu.com loscoloresolvidados.com ronniewright.co.uk subhaus.org weightshift.com Blog Style

    This is a great way to provide viewers a more personal feel, which gives the website a lot more personality. It also gives the website a more current feel (if it is updated regularly), giving the viewer a reason to come back.

    billytamplin.com dougneiner.com demainjarrete.stpo.fr ismaelburciaga.com Other

    These websites don’t have the traditional layout that we saw above. Lets look at these one at a time to see why they are so different.

    badabingdesign.nl

    The portfolio part of this website has a slide show much like rotated image designs, but this one is flipped so they scroll vertically, with the project description to the left. This website gives a new look to a common layout.

    constantinpotorac.com

    Although the two-column layout isn’t uncommon, it’s not usually used like this in portfolio designs. A bio on the left and portfolio on the right takes a combination of the grid and tagline/bio portfolio, and gives it a new twist.

    duplos.org

    I almost put this website in the tagline/bio category, however, since the tagline looks like a part of the illustration, and doesn’t really say too much, I decided to put it here instead. There isn’t really much on the home part of the website, so you have to explore to learn more.

    gomedia.us

    This website, too, almost went into the tagline/bio section, but I felt that the portfolio image on the right had just as much importance. The idea of putting information in columns rather than rows gives equal importance to each section, rather than having a common website where there is a row-based hierarchy of the most important to the least.


  • Permalink for 'Image Resizing Made Easy with PHP'

    Image Resizing Made Easy with PHP

    Posted: March 18th, 2010, 11:44am MDT by Jarrod Oberto

    Ever wanted an all purpose, easy to use method of resizing your images in PHP? Well that’s what PHP classes are for – reusable pieces of functionality that we call to do the dirty work behind the scenes. We’re going to learn how to create our own class that will be well constructed, as well as expandable. Resizing should be easy. How easy? How about three steps!

    Introduction

    To give you a quick glimpse at what we’re trying to achieve with our class, the class should be:

    • Easy to use
    • Format independent. I.E., open, resize, and save a number of different images formats.
    • Intelligent sizing – No image distortion!

    Note: This isn’t a tutorial on how to create classes and objects, and although this skill would help, it isn’t necessary in order to follow this tutorial.

    There’s a lot to cover – Let’s begin.

    Step 1 Preparation

    We’ll start off easy. In your working directory create two files: one called index.php, the other resize-class.php

    Step 2 Calling the Object

    To give you an idea of what we’re trying to achieve, we’ll begin by coding the calls we’ll use to resize the images. Open your index.php file and add the following code.

    As you can see, there is a nice logic to what we’re doing. We open the image file, we set the dimensions we want to resize the image to, and the type of resize.
    Then we save the image, choosing the image format we want and the image quality. Save and close your index.php file.

    		// *** Include the class
    		include("resize-class.php");
    
    		// *** 1) Initialize / load image
    		$resizeObj = new resize('sample.jpg');
    
    		// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
    		$resizeObj -> resizeImage(150, 100, 'crop');
    
    		// *** 3) Save image
    		$resizeObj -> saveImage('sample-resized.gif', 100);
    

    From the code above you can see we’re opening a jpg file but saving a gif. Remember, it’s all about flexibility.

    Step 3 Class Skeleton

    It’s Object-Oriented Programming (OOP) that makes this sense of ease possible. Think of a class like a pattern; you can encapsulate the data – another jargon term that really just means hiding the data. We can then reuse this class over and over without the need to rewrite any of the resizing code – you only need to call the appropriate methods just as we did in step two. Once our pattern has been created, we create instances of this pattern, called objects.

    “The construct function, known as a constructor, is a special class method that gets called by the class when you create a new object.”

    Let’s begin creating our resize class. Open your resize-class.php file. Below is a really basic class skeleton structure which I’ve named ‘resize’. Note the class variable comment line; this is were we’ll start adding our important class variables later.

    The construct function, known as a constructor, is a special class method (the term “method” is the same as function, however, when talking about classes and objects the term method is often used) that gets called by the class when you create a new object. This makes it suitable for us to do some initializing – which we’ll do in the next step.

    		Class resize
    		{
    			// *** Class variables
    
    			public function __construct()
    			{
    
    			}
    		}
    

    Note that’s a double underscore for the construct method.

    Step 4 The Constructor

    We’re going to modify the constructor method above. Firstly, we’ll pass in the filename (and path) of our image to be resized. We’ll call this variable $fileName.

    We need to open the file passed in with PHP (more specifically the PHP GD Library) so PHP can read the image. We’re doing this with the custom method ‘openImage’. I’ll get to how this method
    works in a moment, but for now, we need to save the result as a class variable. A class variable is just a variable – but it’s specific to that class. Remember the class variable comment I mentioned previously? Add ‘image’ as a private variable by typing ‘private $image;’. By setting the variable as ‘Private’ you’re setting the scope of that variable so it can only be accessed by the class. From now on we can make a call to our opened image, known as a resource, which we will be doing later when we resize.

    While we’re at it, let’s store the height and width of the image. I have a feeling these will be useful later.

    You should now have the following.

    		Class resize
    		{
    			// *** Class variables
    			private $image;
    			private $width;
    			private $height;
    
    			function __construct($fileName)
    			{
    			    // *** Open up the file
    			    $this->image = $this->openImage($fileName);
    
    			    // *** Get width and height
    			    $this->width  = imagesx($this->image);
    			    $this->height = imagesy($this->image);
    			}
    		}
    

    Methods imagesx and imagesy are built in functions that are part of the GD library. They retrieve the width and height of your image, respectively.

    Step 5 Opening the Image

    In the previous step, we call the custom method openImage. In this step we’re going to create that method. We want the script to do our thinking for us, so depending on what file type is passed in, the script should determine what GD Library function it calls to open the image. This is easily achieved by comparing the files extension with a switch statement.

    We pass in our file we want to resize and return that files resource.

    		private function openImage($file)
    		{
    		    // *** Get extension
    		    $extension = strtolower(strrchr($file, '.'));
    
    		    switch($extension)
    		    {
    		        case '.jpg':
    		        case '.jpeg':
    		            $img = @imagecreatefromjpeg($file);
    		            break;
    		        case '.gif':
    		            $img = @imagecreatefromgif($file);
    		            break;
    		        case '.png':
    		            $img = @imagecreatefrompng($file);
    		            break;
    		        default:
    		            $img = false;
    		            break;
    		    }
    		    return $img;
    		}
    
    Step 6 How to Resize

    This is where the love happens. This step is really just an explanation of what we’re going to do – so no homework here. In the next step, we’re going to create a public method that we’ll call to perform our resize; so it makes sense to pass in the width and height, as well as information about how we want to resize the image. Let’s talk about this for a moment. There will be scenarios where you would like to resize an image to an exact size. Great, let’s include this. But there will also be times when you have to resize hundreds of images and each image has a different aspect ratio – think portrait images. Resizing these to an exact size will cause severe distortion.If we take a look at our options to prevent distortion we can:

    1. Resize the image as close as we can to our new image dimensions, while still keeping the aspect ratio.
    2. Resize the image as close as we can to our new image dimensions and crop the remainder.

    Both options are viable, depending on your needs.

    Yep. we’re going to attempt to handle all of the above. To recap, we’re going to provide options to:

    1. Resize by exact width/height. (exact)
    2. Resize by width – exact width will be set, height will be adjusted according to aspect ratio. (landscape)
    3. Resize by height – like Resize by Width, but the height will be set and width adjusted dynamically. (portrait)
    4. Auto determine options 2 and 3. If you’re looping through a folder with different size photos, let the script determine how to handle this. (auto)
    5. Resize, then crop. This is my favourite. Exact size, no distortion. (crop)
    Step 7 Resizing. Let’s do it!

    There are two parts to the resize method. The first is getting the optimal width and height for our new image by creating some custom methods – and of course passing in our resize ‘option’ as described above. The width and height are returned as an array and set to their respective variables. Feel free to ‘pass as reference’- but I’m not a huge fan of that.

    The second part is what performs the actual resize. In order to keep this tutorial size down, I’ll let you read up on the following GD functions:

    We also save the output of the imagecreatetruecolor method (a new true color image) as a class variable. Add ‘private $imageResized;’ with your other class variables.

    Resizing is performed by a PHP module known as the GD Library. Many of the methods we’re using are provided by this library.

    		// *** Add to class variables
    		private $imageResized;
    
    		public function resizeImage($newWidth, $newHeight, $option="auto")
    		{
    
    			// *** Get optimal width and height - based on $option
    			$optionArray = $this->getDimensions($newWidth, $newHeight, strtolower($option));
    
    			$optimalWidth  = $optionArray['optimalWidth'];
    			$optimalHeight = $optionArray['optimalHeight'];
    
    			// *** Resample - create image canvas of x, y size
    			$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
    			imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
    
    			// *** if option is 'crop', then crop too
    			if ($option == 'crop') {
    				$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
    			}
    		}
    
    Step 8 The Decision Tree

    The more work you do now, the less you have to do when you resize. This method chooses the route to take, with the goal of getting the optimal resize width and height based on your resize option. It’ll call the appropriate method, of which we’ll be creating in the next step.

    		private function getDimensions($newWidth, $newHeight, $option)
    		{
    
    		   switch ($option)
    		    {
    		        case 'exact':
    		            $optimalWidth = $newWidth;
    		            $optimalHeight= $newHeight;
    		            break;
    		        case 'portrait':
    		            $optimalWidth = $this->getSizeByFixedHeight($newHeight);
    		            $optimalHeight= $newHeight;
    		            break;
    		        case 'landscape':
    		            $optimalWidth = $newWidth;
    		            $optimalHeight= $this->getSizeByFixedWidth($newWidth);
    		            break;
    		        case 'auto':
    		            $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
    					$optimalWidth = $optionArray['optimalWidth'];
    					$optimalHeight = $optionArray['optimalHeight'];
    		            break;
    				case 'crop':
    		            $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
    					$optimalWidth = $optionArray['optimalWidth'];
    					$optimalHeight = $optionArray['optimalHeight'];
    		            break;
    		    }
    			return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
    		}
    
    Step 9 Optimal Dimensions

    We’ve already discussed what these four methods do. They’re just basic maths, really, that calculate our best fit.

    		private function getSizeByFixedHeight($newHeight)
    		{
    		    $ratio = $this->width / $this->height;
    		    $newWidth = $newHeight * $ratio;
    		    return $newWidth;
    		}
    
    		private function getSizeByFixedWidth($newWidth)
    		{
    		    $ratio = $this->height / $this->width;
    		    $newHeight = $newWidth * $ratio;
    		    return $newHeight;
    		}
    
    		private function getSizeByAuto($newWidth, $newHeight)
    		{
    		    if ($this->height width)
    		    // *** Image to be resized is wider (landscape)
    		    {
    		        $optimalWidth = $newWidth;
    		        $optimalHeight= $this->getSizeByFixedWidth($newWidth);
    		    }
    		    elseif ($this->height > $this->width)
    		    // *** Image to be resized is taller (portrait)
    		    {
    		        $optimalWidth = $this->getSizeByFixedHeight($newHeight);
    		        $optimalHeight= $newHeight;
    		    }
    			else
    		    // *** Image to be resizerd is a square
    		    {
    				if ($newHeight getSizeByFixedWidth($newWidth);
    				} else if ($newHeight > $newWidth) {
    					$optimalWidth = $this->getSizeByFixedHeight($newHeight);
    				    $optimalHeight= $newHeight;
    				} else {
    					// *** Sqaure being resized to a square
    					$optimalWidth = $newWidth;
    					$optimalHeight= $newHeight;
    				}
    		    }
    
    			return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
    		}
    
    		private function getOptimalCrop($newWidth, $newHeight)
    		{
    
    			$heightRatio = $this->height / $newHeight;
    			$widthRatio  = $this->width /  $newWidth;
    
    			if ($heightRatio height / $optimalRatio;
    			$optimalWidth  = $this->width  / $optimalRatio;
    
    			return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
    		}
    
    Step 10 Crop

    If you opted in for a crop – that is, you’ve used the crop option, then you have one more little step. We’re going to crop the image from the
    center. Cropping is a very similar process to resizing but with a couple more sizing parameters passed in.

    		private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
    		{
    			// *** Find center - this will be used for the crop
    			$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
    			$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
    
    			$crop = $this->imageResized;
    			//imagedestroy($this->imageResized);
    
    			// *** Now crop from center to exact requested size
    			$this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
    			imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
    		}
    
    Step 11 Save the Image

    We’re getting there; almost done. It’s now time to save the image. We pass in the path, and the image quality we would like ranging from 0-100, 100 being the best, and call the appropriate method. A couple of things to note about the image quality: JPG uses a scale of 0-100, 100 being the best. GIF images don’t have an image quality setting. PNG’s do, but they use the scale 0-9, 0 being the best. This isn’t good as we can’t expect ourselves to remember this every time we want to save an image. We do a bit of magic to standardize everything.

    		public function saveImage($savePath, $imageQuality="100")
    		{
    			// *** Get extension
            	$extension = strrchr($savePath, '.');
            	$extension = strtolower($extension);
    
    			switch($extension)
    			{
    				case '.jpg':
    				case '.jpeg':
    					if (imagetypes() & IMG_JPG) {
    						imagejpeg($this->imageResized, $savePath, $imageQuality);
    					}
    		            break;
    
    				case '.gif':
    					if (imagetypes() & IMG_GIF) {
    						imagegif($this->imageResized, $savePath);
    					}
    					break;
    
    				case '.png':
    					// *** Scale quality from 0-100 to 0-9
    					$scaleQuality = round(($imageQuality/100) * 9);
    
    					// *** Invert quality setting as 0 is best, not 9
    					$invertScaleQuality = 9 - $scaleQuality;
    
    					if (imagetypes() & IMG_PNG) {
    						imagepng($this->imageResized, $savePath, $invertScaleQuality);
    					}
    					break;
    
    				// ... etc
    
    				default:
    					// *** No extension - No save.
    					break;
    			}
    
    			imagedestroy($this->imageResized);
    		}
    

    Now is also a good time to destroy our image resource to free up some memory. If you were to use this in production, it might also be a good idea to capture and return the result of the saved image.

    Conclusion

    Well that’s it, folks. Thank you for following this tutorial, I hope you find it useful. I’d appreciate your feedback, via the comments below.


  • Permalink for 'How to Generate PDFs with PHP: New Plus Tutorial'

    How to Generate PDFs with PHP: New Plus Tutorial

    Posted: March 17th, 2010, 9:20pm MDT by Jeffrey Way

    PDFs may well be the best format for distributing documents on the web. In today’s tutorial and screencast, I’ll show you how you can generated PDFs with PHP. Help give back to Nettuts+ by becoming a Premium member!

    Example PDF Created with PHP!
    Sample PDF

    By subscribing and becoming a Premium member, you’ll gain access to the best tutorial, screencasts, and freebies that every Tuts sites has to offer – all for a measly $9 a month.

    Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    For those unfamiliar, the family of TUTS sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, and Vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Help give back to Nettuts+ by becoming a Premium member!


  • Permalink for 'Quick Tip: Cross Domain AJAX Request with YQL and jQuery'

    Quick Tip: Cross Domain AJAX Request with YQL and jQuery

    Posted: March 17th, 2010, 7:27pm MDT by Jeffrey Way

    For security reasons, we cannot make cross-domain AJAX requests with jQuery. For example, I can’t call the load() method, and pass in ‘cnn.com’. As we’d be loading in scripts and such, as well as our desired content, this would present a significant security risk. Nonetheless, there may be times when this is specifically what you require. Thanks to YQL, we can allow for this functionality rather easily!


    Subscribe to our YouTube page to watch all of the video tutorials! The Script
    // Accepts a url and a callback function to run.
    function requestCrossDomain( site, callback ) {
    
    	// If no url was passed, exit.
    	if ( !site ) {
    		alert('No site was passed.');
    		return false;
    	}
    
    	// Take the provided url, and add it to a YQL query. Make sure you encode it!
    	var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + site + '"') + '&format=xml&callback=?';
    
    	// Request that YSQL string, and run a callback function.
    	// Pass a defined function to prevent cache-busting.
    	$.getJSON( yql, cbFunc );
    
    	function cbFunc(data) {
    	// If we have something to work with...
    	if ( data.results[0] ) {
    		// Strip out all script tags, for security reasons.
    		// BE VERY CAREFUL. This helps, but we should do more.
    		data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
    
    		// If the user passed a callback, and it
    		// is a function, call it, and send through the data var.
    		if ( typeof callback === 'function') {
    			callback(data);
    		}
    	}
    	// Else, Maybe we requested a site that doesn't exist, and nothing returned.
    	else throw new Error('Nothing returned from getJSON.');
    	}
    }
    
    Call the Function
    requestCrossDomain('http://www.cnn.com', function(results) {
       $('#container').html(results);
    });
    
    Stripping Out the Script Tags

    I had to progress rather quickly in the video, so perhaps the regular expression that strips out the <script> tags require further detail.

    .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
    

    When we load our desired page, it’s also going to load scripts! You must be very careful when making cross domain request. It definitely helps to strip out the <script> tags, but you should do more in an actual project.

    Let’s take the regular expression step by step.

    <script[^>]*>
    

    Find all open script tags; however, they could come in many forms: <script type=”text/javascript” src=”bla.js”></script> , or <script type=”text/javascript”>lots of code here…</script> . For this reason, we add a character class ( [^>]* ), which mean, “Find zero or more of anything that IS NOT a closing bracket. This will take care of the attributes and values.

    [\s\S]*?
    

    Next, we want to strip out all code, as well as any spacing. \s refers to a space. \S refers to anything that IS NOT a space. Once again, we add a * after the character class to designate that we want zero or more occurrences.

    <\/script>
    

    Finally, find the closing script tags.

    Further Reading

    This is only meant to provide a glimpse of how we can achieve this functionality. Only so much can be covered in a five minute video. Feel free to discuss in the comments, and you’re always encouraged to fork the source code to improve upon it!


  • Permalink for 'How to Create a PHP/MySQL Powered Forum from Scratch'

    How to Create a PHP/MySQL Powered Forum from Scratch

    Posted: March 17th, 2010, 12:23pm MDT by Evert Padje

    In this tutorial, we’re going to build a PHP/MySQL powered forum from scratch. This tutorial is perfect for getting used to basic PHP and database usage. Let’s dive right in!