Chapter 12 265 add_action('parse_request','wptc_save_user_cat_order'); function wptc_save_user_cat_order($wp) { if( isset( $_POST['save-user-cat-order'] ) ) { $args = wp_parse_args(stripslashes($_POST['user-cat-order'])); $cats = (array)$args['user_cat']; setcookie('user-cat- order',maybe_serialize($cats),time()+3600*24*31); exit(); } } global $user_cat_order; $user_cat_order = unserialize(stripslashes($_COOKIE['user-cat- order'])); $user_cat_order = is_array($user_cat_order) ? $user_cat_order : false; function wptc_sort_categories($categories) { global $user_cat_order,$current_categories; if(!$user_cat_order) { $current_categories = array(); foreach($categories as $category) { $current_categories[] = $category->term_id; } $user_cat_order = $current_categories; } usort($categories,'wptc_order_category_overview'); return $categories; } function wptc_order_category_overview($catA, $catB) { global $user_cat_order,$current_categories; if($user_cat_order) { $posA = array_search($catA->term_id,$user_cat_order); if(false === $posA) { $posA = -1; } $posB = array_search($catB->term_id,$user_cat_order); if( false === $posB) { $posB = -1; } return $posA - $posB; } else { return -1; } } Layout 266 This code intercepts the save request that you'll make use of when a user nishes sorting the categories. Also, you've added a custom sorting function that makes sure that the categories are in the correct order before rendering them to the browser. Next, open up your JavaScript le scripts.js, and change your code to the following. This code adds an event handler that res when your user nishes sorting the categories on the front-end. The handler res off a request when the user nishes sorting. The request contains the necessary variables to save the categories being sorted. Particular areas of interest have been marked in bold: jQuery(document).ready(function($) { $('#content').sortable({ stop:wptc_user_cat_order, items:'div.piece', handle:'h2', placeholder:'piece ui-sortable-placeholder' }); function wptc_user_cat_order(event,ui) { jQuery.post( '/', { 'save-user-cat-order':1, 'user-cat-order':$(this).sortable('serialize') } ); } }); To test this functionality, refresh the category overview page that you've been working on. You'll notice that the categories are in the order that they were before. We took special care to ensure that if the user hasn't sorted the categories previously, they'll be rendered in the order determined by number of posts in a category. Next, sort the categories by dragging and dropping them into the position that you desire. Refresh the page, and the category boxes should remain in their custom-sorted positions. See also Creating a simple page template Chapter 12 267 Creating a global toolbar for your theme Having a great site is one thing, but building a community is quite another. To really push your site's community efforts, it can pay to put the most desirable actions right at the top of your site's theme. This is what WordPress.com does, and in this recipe, is what you'll do. Getting started You need to have a basic theme constructed and, for the best experience, you need to have separated your header elements out into header.php. How to do it First, you need to decide what components you wish to put into your site's toolbar. For this recipe, we'll follow the lead of WordPress.com. The toolbar on that site allows users to perform the following actions: Access the currently logged-in user's prole Log in and log out Search the site Access a random post The WordPress.com toolbar also allows for a variety of other actions, but these won't be discussed in this recipe. Next, you need to create the HTML for the toolbar. To keep the toolbar markup as clear as possible, you'll create a new le and then include it where necessary. Inside your theme's directory, create a subdirectory called components. Inside this new subdirectory create a le called toolbar.php. Insert the following markup into the new toolbar.php le: <ul id="toolbar"> <?php if( is_user_logged_in() ) { ?> <li> <a href="<?php echo esc_url(admin_url('profile.php')); ?>"> <?php _e('My Profile'); ?> </a> </li> <li> <a href="<?php echo esc_url(wp_logout_url(site_url('/'))); ?>"> <?php _e('Log Out'); ?> </a> Layout 268 </li> <?php } else { ?> <li> <form name="loginform" id="loginform" action="<?php echo site_url('wp-login.php', 'login_post'); ?>" method="post"> <label><span class="hidden"><?php _e('Username'); ?></span> <input type="text" name="log" id="user_login" class="input" /> </label> <label><span class="hidden"><?php _e('Password') ?></span> <input type="password" name="pwd" id="user_pass" class="input" /> </label> <input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="<?php esc_attr_e('Log In'); ?>" /> <label> <input name="rememberme" type="checkbox" id="rememberme" value="forever" /> <?php esc_attr_e('Remember Me'); ?> </label> <input type="hidden" name="redirect_to" value="<?php echo esc_attr(site_url('/')); ?>" /> <input type="hidden" name="testcookie" value="1" /> </form> </li> <?php } ?> Chapter 12 269 <?php $random_posts = get_posts(array('orderby'=>'rand')); if( !empty($posts) ) { $random_post = array_shift($random_posts); ?> <li> <a href="<?php echo esc_url(get_permalink($random_post->ID)); ?>"> <?php _e('Random Post'); ?> </a> </li> <?php } ?> <li class="right"> <form method="get"> <input type="text" name="s" id="s" /> <input type="submit" name="search" id="search-submit" value="<?php _e( 'Search' ); ?>" /> </form> </li> </ul> The markup does a few things. First, it checks to see if a user is logged in. If they are, then a link to the logged-in user's account prole page, and a link for logging out, are rendered. Otherwise, a login form is output to the browser. Next, the toolbar retrieves a random post that has been published and links to it. Finally, a search form is placed in the toolbar, allowing the user to search the blog. After you've constructed your toolbar, it is time to put it in the appropriate place. Open up header.php le (or the index.php le, depending on your template structure) and insert the following code directly after the opening body tag: <?php include( TEMPLATEPATH . '/components/toolbar.php' ); ?> This line references the toolbar le, and makes PHP include it in line with the rest of your template's content. Layout 270 Open your site in a browser window (making sure that you are not logged in) and take a look at the results. If you've done everything correctly up to this point, you're likely to have something that looks like the following, if you're logged out: Chapter 12 271 Now log in to your site to test the view when users are logged in. If you're logged in, your site should look like the following screenshot: Now that the markup is complete, it's time to style the toolbar. Open up your theme's stylesheet, style.css le, and insert the following styles. These styles will x the toolbar to the top of the browser window, and ensure that, as the user scrolls down, the toolbar always remains in place. In addition, the styles dene text, background colors and appropriate margin and padding for all elements: /*note: you may have to increase the padding (top) of the header div as shown below:*/ #header { background: #90a090; border-bottom: 3px double #aba; border-left: 1px solid #9a9; border-right: 1px solid #565; border-top: 1px solid #9a9; Layout 272 font: italic normal 230% 'Times New Roman', Times, serif; letter-spacing: 0.2em; margin: 0; padding: 50px 10px 15px 60px; } /* menu top changed from 0 to 120px;*/ #menu { background: #fff; border-left: 1px dotted #ccc; border-top: 3px solid #e0e6e0; padding: 20px 0 10px 30px; position: absolute; right: 2px; top: 120px; width: 11em; } /* note: you may have to adjust the placement of the top of your sidebar /side menu since this toolbar runs across the top of the theme. */ #toolbar a { color: #ffffff; display: block; text-decoration: none; padding: 4px 6px; } #toolbar a:hover { background: #666666; } #toolbar form { padding: 0 5px; } #toolbar li { display: block; float: left; margin: 0; padding: 0; } #toolbar .right { float: right; Chapter 12 273 } #toolbar .hidden { display: none; } Refresh your browser, and you should see something similar to the following screenshot, assuming that you are logged out: Layout 274 When you're logged in, your display should resemble the following screenshot: How it works The concepts here are simple, but we'll go through them one by one. First, you created a separate PHP le that contains the entire toolbar component. In this case, you made the toolbar relevant both to site functions (logging in and out) and to site content (random post and search toolbar). To do so, you took advantage of a few WordPress functions to get the necessary conditions and content. First, you used is_user_logged_in to determine whether to show the log-in form, or to give the user the option to modify their prole, or log out. You used wp_logout_ url to retrieve the appropriate log-out URL for the site in question, rather than manually constructing it. You also created two forms. The rst was a log-in form mimicking the one shown at your site's wp-login.php page. The second was a search form containing a single input, as required by WordPress. . href="<?php echo esc_url(admin_url('profile.php')); ?>"> <?php _e('My Profile'); ?> </a> </li> <li> <a href="<?php echo esc_url(wp_logout_url(site_url('/')));. right; Chapter 12 273 } #toolbar .hidden { display: none; } Refresh your browser, and you should see something similar to the following screenshot, assuming that you are logged out: Layout 274 When. you wish to put into your site's toolbar. For this recipe, we'll follow the lead of WordPress. com. The toolbar on that site allows users to perform the following actions: Access the