You are on page 1of 109

WordPress Reference

By Jan Zumwalt NeatInfo.com


based on blogs by Ian Stewart http://themeshaper.com/2009/06/22/wordpress-themes-templates-tutorial/ Amber Weinberg http://sixrevisions.com/wordpress/beginning-wordpress-development-a-look-at-common-functions/ Many other developer Cheat Sheets available from http://www.neatinfo.com/dev_notes/_cheat-sheets

Here are the features the finished theme will have: Enhanced search-engine optimization (SEO) SEO Google-supported Microformat markup - see appendix A Logical markup structure than can be adapted to ANY layout Smart default CSS layouts Dynamic Body, post and comment classes Separated trackbacks and threaded comments 2 widget areas that disappear if they are empty Full standard WordPress functionality

Notes
______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________
by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference May 15, 2012 Copyright 2005-2012

Page 2 of 109

Table of Contents
Section 1 Introduction .................................................................................................................. 9
How does WordPress work? .......................................................................................................................... 9

Section 2 Development Tools .................................................................................................... 10


Local Test Server: XAMP or MAMP.............................................................................................................. 10 WordPress ................................................................................................................................................... 10 Dummy Content ........................................................................................................................................... 10 A Text Editor ................................................................................................................................................ 10 Firefox ......................................................................................................................................................... 11 PHP, HTML, and CSS Tutorials ................................................................................................................... 11 Installation ................................................................................................................................................... 11

Section 3 HTML Structure .......................................................................................................... 12


Good HTML Structure .................................................................................................................................. 12 The HTML Structure for Your WordPress Theme ......................................................................................... 12 Understanding the HTML Theme ................................................................................................................. 13

Section 4 Template & Directory Structure ................................................................................ 14


Building In Your HTML Structure .................................................................................................................. 15 header.php .................................................................................................................................................. 15 index.php ..................................................................................................................................................... 15 footer.php .................................................................................................................................................... 16 Finishing index.php ...................................................................................................................................... 16

Section 5 Header Template ........................................................................................................ 17


functions.php ............................................................................................................................................... 17 What is translatable Code? .......................................................................................................................... 17 The Head Section ........................................................................................................................................ 18 XFN Protocol ............................................................................................................................................... 19 <title>........................................................................................................................................................... 19 meta information .......................................................................................................................................... 20

Section 6 Page description and Menu ....................................................................................... 22


Page description .......................................................................................................................................... 22

Section 7 index.php .................................................................................................................... 24


The Loop ..................................................................................................................................................... 24

Section 8 Navigation .................................................................................................................. 29 Section 9 Single Post ................................................................................................................. 31


The Template for Templates ........................................................................................................................ 31 Single Post Navigation ................................................................................................................................. 31 Single Post Titles ......................................................................................................................................... 32 Single Post Entry Utility Links ....................................................................................................................... 32 Single Post Content ..................................................................................................................................... 33

Section 10 Post Attachment....................................................................................................... 34


Post Attachments ......................................................................................................................................... 34

Section 11 404 Error Templates................................................................................................. 36 Section 12 Comments Template ................................................................................................ 38


Custom Callbacks for Comments and Trackbacks ........................................................................................ 38 The Comments Template ............................................................................................................................. 39

Section 13 Search Template ...................................................................................................... 43


The Search Template ................................................................................................................................... 43

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 3 of 109

May 15, 2012 Copyright 2005-2012

Section 14 Page Template .......................................................................................................... 47


The Page Template...................................................................................................................................... 47

Section 15 Archive Template ..................................................................................................... 48


The Archive Template .................................................................................................................................. 48

Section 16 Author Template....................................................................................................... 52


The Author Template ................................................................................................................................... 52

Section 17 Category Template ................................................................................................... 53 Section 18 Tags Template .......................................................................................................... 55


The Tags Template ...................................................................................................................................... 55

Section 19 Sidebar Template ..................................................................................................... 57


Custom Sidebar Functions ........................................................................................................................... 57 Coding The Sidebar Template ...................................................................................................................... 58

Section 21 Reset & Rebuild CSS ............................................................................................... 60


Reset CSS ................................................................................................................................................... 60 Rebuild CSS ................................................................................................................................................ 60 The Basic WordPress Styles ........................................................................................................................ 61

Section 22 Custom Defined Layouts ......................................................................................... 62


All The Layouts Youll Ever Need ................................................................................................................. 62 Styling The Menu ......................................................................................................................................... 62

Section 23 Custom Post Types .................................................................................................. 63


Default Types ............................................................................................................................................... 63 Custom Types .............................................................................................................................................. 63 Naming Best Practices ................................................................................................................................. 64 Reserved Post Type Names ......................................................................................................................... 64 Admin UI ...................................................................................................................................................... 64 URLs ........................................................................................................................................................... 65 URLs with Namespaced Custom Post Types................................................................................................ 65 Template Files ............................................................................................................................................. 65 Single template ............................................................................................................................................ 65 Archive template .......................................................................................................................................... 66 Querying by post type .................................................................................................................................. 66

Section 24 Theme File Execution Hierarchy ............................................................................. 67


Home Page .................................................................................................................................................. 68 WordPress Post Detail ................................................................................................................................. 68 WordPress Page Detail ................................................................................................................................ 68 Category Page ............................................................................................................................................. 69 Tag Page ..................................................................................................................................................... 69 Taxonomy Page ........................................................................................................................................... 70 Author Page ................................................................................................................................................. 70 Attachment Page ......................................................................................................................................... 70 Date Page.................................................................................................................................................... 70 Archive Page ............................................................................................................................................... 71 Search Page ................................................................................................................................................ 71 404 Page ..................................................................................................................................................... 71 Single page categories ................................................................................................................................. 71 Conclusion ................................................................................................................................................... 71

Appendix A Microformat ............................................................................................................ 72


What is microformats ................................................................................................................................... 72 Using microformats with html tags ................................................................................................................ 72 Appendix B Template Hierarchy .............................................................................................................. 73 Template Files List ....................................................................................................................................... 73 The Template Hierarchy In Detail ................................................................................................................. 75

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 4 of 109

May 15, 2012 Copyright 2005-2012

Home Page display ...................................................................................................................................... 75 Front Page display ....................................................................................................................................... 76 Single Post display ....................................................................................................................................... 76 Page display ................................................................................................................................................ 76 Category display .......................................................................................................................................... 76 Tag display .................................................................................................................................................. 76 Custom Taxonomies display ........................................................................................................................ 76 Custom Post Types display .......................................................................................................................... 76 Author display .............................................................................................................................................. 76 Date display ................................................................................................................................................. 76 Search Result display .................................................................................................................................. 77 404 (Not Found) display ............................................................................................................................... 77 Attachment display ....................................................................................................................................... 77

Appendix C XFN Protocol .......................................................................................................... 78


Introduction............................................................................................................................................... 78 Examples ................................................................................................................................................... 78 A Short Blogroll ............................................................................................................................................ 78

Appendix D Testing A New Theme ............................................................................................ 80


Setup ........................................................................................................................................................... 80 Test Environment Setup ............................................................................................................................... 80 WordPress Settings ..................................................................................................................................... 80 Template Hierarchy Index Pages ................................................................................................................. 80 Static Front Page ......................................................................................................................................... 80 404 Page ..................................................................................................................................................... 81 Search Results Page ................................................................................................................................... 81 Blog Posts Index Page ................................................................................................................................. 81 Scheduled Post ............................................................................................................................................ 81 Draft Post..................................................................................................................................................... 81 Layout Test .................................................................................................................................................. 81 Readability Test ........................................................................................................................................... 81 Post Format Tests (All)................................................................................................................................. 81 Post Format Test: Gallery ............................................................................................................................ 81 Post Format Test: Image (Linked) ................................................................................................................ 81 Post Format Test: Image (Attached) ............................................................................................................. 81 Post Format Test: Video............................................................................................................................... 81 This Post Has No Body ................................................................................................................................ 81 (no title) ....................................................................................................................................................... 82 Many Categories & Many Tags .................................................................................................................... 82 Protected Test With Secret Password .......................................................................................................... 82 Single Post .................................................................................................................................................. 82 Layout Test .................................................................................................................................................. 82 Page 2 ......................................................................................................................................................... 82 Page 3 ......................................................................................................................................................... 82 Readability Test ........................................................................................................................................... 82 Images Test ................................................................................................................................................. 83 Post Format Tests (All)................................................................................................................................. 83 Post Format Test: Gallery ............................................................................................................................ 83 Post Format Test: Image (Linked) ................................................................................................................ 83 Post Format Test: Image (Attached) ............................................................................................................. 83 Post Format Test: Video............................................................................................................................... 83 Post Format Test: Audio............................................................................................................................... 83 Post With Long Title ..................................................................................................................................... 83 This Post Has No Body ................................................................................................................................ 84 (no title) ....................................................................................................................................................... 84 Many Categories / Many Tags ...................................................................................................................... 84 Protected Test With Secret Password .......................................................................................................... 84 Comment Test ............................................................................................................................................. 84

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 5 of 109

May 15, 2012 Copyright 2005-2012

Comments Disabled ..................................................................................................................................... 84 Many Trackbacks ......................................................................................................................................... 84 Pages .......................................................................................................................................................... 84 Page With Comments .................................................................................................................................. 84 Page With Comments Disabled .................................................................................................................... 84 Parent Page / Child Page 1 / Child Page 2 ................................................................................................... 85 Clearing Floats ............................................................................................................................................. 85 Misc Pages .................................................................................................................................................. 85 Search Results ............................................................................................................................................ 85 Not Found .................................................................................................................................................... 85 General ........................................................................................................................................................ 85 Menus .......................................................................................................................................................... 85 Widgets ....................................................................................................................................................... 85 Screenshot .................................................................................................................................................. 85 Anchor Text and Credit Links ....................................................................................................................... 85

Appendix E Common Procedures & Functions ........................................................................ 86


Listing All Pages .......................................................................................................................................... 86 Listing Specific Pages .................................................................................................................................. 86 Excluding Specific Pages from a List ............................................................................................................ 86 Sorting Pages .............................................................................................................................................. 86 Specifying the Depth .................................................................................................................................... 86 Enabling Navigation Menu ........................................................................................................................... 87 Site URL ...................................................................................................................................................... 87 URL to the Current Theme ........................................................................................................................... 87 Getting the URL of Your RSS Feed .............................................................................................................. 87 POST Loop .................................................................................................................................................. 87 Displaying Posts in a Category ..................................................................................................................... 87 Aside: Passing Multiple Parameters into Functions ....................................................................................... 88 Excluding Posts ........................................................................................................................................... 88 Post title ....................................................................................................................................................... 88 Post URL ..................................................................................................................................................... 88 Post conetent ............................................................................................................................................... 88 Post excerpt ................................................................................................................................................ 88 Post category ............................................................................................................................................... 88 Post tags used in the post ............................................................................................................................ 88 Post publish date ......................................................................................................................................... 88 Working with Custom Fields ......................................................................................................................... 88 Thumbnails - Portfolio .................................................................................................................................. 89 Thumbnails - Post ........................................................................................................................................ 89 Custom Fields For Thumbnails ..................................................................................................................... 89 Add feed links to header............................................................................................................................... 90 Automatic jQuery inclusion ........................................................................................................................... 90 Enable threaded comments.......................................................................................................................... 90 Remove unwanted crap from the head section ............................................................................................. 91 Add Google Analytics to the footer ............................................................................................................... 91 Custom excerpt length ................................................................................................................................. 91 Custom excerpt continue string .................................................................................................................. 92 No more jumping for the read more link ................................................................................................... 92 Add a favicon to your wordpress .................................................................................................................. 92 Add a different favicon for your blogs Admin area ........................................................................................ 93 Custom Admin Login logo ............................................................................................................................ 93 Disable unused widget areas ....................................................................................................................... 93 Kill the WordPress update nag ..................................................................................................................... 93 Include category ID in body_class and post_class ........................................................................................ 94 Get the first category ID ............................................................................................................................... 94 Insert custom content after postS ................................................................................................................. 94 Insert custom content in feeds ...................................................................................................................... 95 remove version number from pages and feeds ............................................................................................. 95

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 6 of 109

May 15, 2012 Copyright 2005-2012

Customize admin footer message ................................................................................................................ 96 Enable HTML markup in user profiles ........................................................................................................... 96 Delay feed update after posting .................................................................................................................... 96 Add an Admin link to the WordPress All-Settings page ............................................................................... 97 Remove all nofollow attributes from comments ............................................................................................. 97 Enable easy display of your posts word count.............................................................................................. 97 Enable delete and spam links for comments ................................................................................................. 98 Disable all WordPress feeds ........................................................................................................................ 98 Customize gravatars .................................................................................................................................... 99 Disable automatic formatting OF post content .............................................................................................. 99 Escape HTML entities in comments ........................................................................................................... 100 Custom comments display callback function ............................................................................................... 100

Menus ............................................................................................................................................. 102


Horizontal menus ....................................................................................................................................... 102 Without CSS .............................................................................................................................................. 102 More Information on Horizontal Menus ....................................................................................................... 102

Functions by category .................................................................................................................. 103


Posts ......................................................................................................................................................... 103 POST-Custom Post Type ........................................................................................................................... 103 POST-Post insertion/removal ..................................................................................................................... 103 POST-Pages .............................................................................................................................................. 103 POST-Custom Fields (postmeta) ................................................................................................................ 103 POST-Attachments .................................................................................................................................... 103 POST-Bookmarks ...................................................................................................................................... 103 POST-Terms .............................................................................................................................................. 103 POST-Other ............................................................................................................................................... 103 Categories ................................................................................................................................................. 103 Category-Creation ...................................................................................................................................... 103 Category-Tags ........................................................................................................................................... 103 Category-Taxonomy................................................................................................................................... 103 Admins, Roles and Capabilities .................................................................................................................. 104 Users and Authors ..................................................................................................................................... 104 User meta .................................................................................................................................................. 104 User insertion/removal ............................................................................................................................... 104 Login / Logout ............................................................................................................................................ 104 Feed Functions .......................................................................................................................................... 104 Comment, Ping, and Trackback Functions ................................................................................................. 104 Comments Loop......................................................................................................................................... 104 Comments Pagination ................................................................................................................................ 104 Filters......................................................................................................................................................... 104 Actions ....................................................................................................................................................... 104 Plugins ....................................................................................................................................................... 104 Shortcodes ................................................................................................................................................ 105 Include functions ........................................................................................................................................ 105 Other functions .......................................................................................................................................... 105 Formatting Functions ................................................................................................................................. 105 Time/Date Functions .................................................................................................................................. 105 Serialization ............................................................................................................................................... 105 Options ...................................................................................................................................................... 105 Admin Menu Functions............................................................................................................................... 105 Toolbar Functions ...................................................................................................................................... 105 Form Helpers ............................................................................................................................................. 106 Nonces and Referers (Security) ................................................................................................................. 106 XMLRPC .................................................................................................................................................... 106 Localization ................................................................................................................................................ 106 Cron (Scheduling) ...................................................................................................................................... 106 Conditional Tags Index............................................................................................................................... 106

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 7 of 109

May 15, 2012 Copyright 2005-2012

Miscellaneous ............................................................................................................................................ 106 Multisite functions ...................................................................................................................................... 106 Multisite Site/blog functions ........................................................................................................................ 106 Multisite API ............................................................................................................................................... 107 needed to load Multisite ............................................................................................................................. 107

Back Page ...................................................................................................................................... 109


Theme Design ........................................................................................................................................... 109 WordPress and CSS .................................................................................................................................. 109 Cheat Sheets ............................................................................................................................................. 109 Tutorials ..................................................................................................................................................... 109 Documenation ............................................................................................................................................ 109

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 8 of 109

May 15, 2012 Copyright 2005-2012

Section 1 Introduction
In just a few short lessons you will write your own powerful, up-to-date, WordPress Theme from scratch. We will also learn new techniques and understand the advantages of certain options. When we have completed, you will know everything you need to know about WordPress Theme development. You can even think of the finished Theme as your own personal website development framework for WordPress. This is an impressive accomplishment for such a short period of time. This theme is the basis for a very nice one called The Shape Theme. Download it and check it out if youd like to see what the finished code is like. Alternately, you can browse through the up-to-date source code for the entire tutorial on Google Code. HOW DOES WORDPRESS WORK? WordPress has many prebuilt code modules (called Tags) that does most of the work. We can take a simple HTML structure and use PHP to call WordPress Template Tags (code modules / functions / procedures / hooks) to fill in content. It is really that simple! Its really just a matter of getting used to seeing the WordPress Template Tags along with some PHP language statements and a few PHP loops (well cover all of this). (If you are familiar with PHP, think of WordPress as a comprehensive library of PHP procedures.) For example:
<h1><?php bloginfo('description'); ?></h1>

Will print the blog description as a bold page title.

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 9 of 109

May 15, 2012 Copyright 2005-2012

Section 2 Development Tools


Before we get started building any WordPress Theme were going to need a development environment and the tools for the job. Everything we need is FREE, so lets get started. LOCAL TEST SERVER: XAMP OR MAMP The best place to develop your custom WordPress Theme is off the web, on your home computer or laptop. To do that youll need to create a local server on your computer. This erver will act just like the internet. To mimic the internet we need Apache, PHP, and MySql. Your browser should have Javascript enabled. Installing these separate server programs can be technically challenging but luckily for us there are a couple of free programs that will install and manage all this for us. I strongly recommend using XAMPP for either Windows or Linux. Prior to about 2007, WAMP had more features and less installation problems than XAMPP, but that is no longer true. I have used both XAMPP and WAMP for many years and find that XAMPP currently has less installation problems. A few years ago XAMPP had some control panel issues which seem to have all been fixed. For downloads and further reading, see the links below.
http://www.apachefriends.org/en/xampp.html http://www.wampserver.com/en/

WORDPRESS We also need a copy of the latest version of WordPress. If youre using XAMP follow these instruction for installing WordPress on your local test server. If youre using MAMP follow these instructions for installing WordPress on your local test server. DUMMY CONTENT Your WordPress installation is going to need some sample, or dummy, content. In your WordPress admin navigate to Tools > Import and choose WordPress from the list of options. Now we only need a WXR post data file to import. There are a couple options: The Theme Unit Test data WPCandy Sample Content Each of these test data sets has their pluses and minuses. One thing I like to do is import all the dummy content I can. Everything. That way nothing gets missed. When you think youre done your theme, use the post navigation to browse through each post. Check out the archives for the month and year and category. With robust dummy content itll be easy to see if somethings amiss. A TEXT EDITOR

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 10 of 109

May 15, 2012 Copyright 2005-2012

You wont need any special graphics software for creating WordPress Themes just a good text editor. For Windows, you can try Notepad++ http://notepad-plus-plus.org/. Its free and open-source. For the Mac, I recommend Text Wrangler. FIREFOX Of course, you can use any browser for web development but the one I recommend is Firefox. Especially with the following 2 add-ons that will make your life a whole lot easier when it comes to developing with WordPress. The Web Developer Add-on for Firefox adds a toolbar that gives you a whole host of options for inspecting and debugging your code, from disabling all CSS styles to validating local HTML (thats the stuff happening on the browser screen of your test server). The Firebug Add-on for Firefox is indispensable. With Firebug enabled you can click on any element in your browser window and seein a window at the bottom of the screenhow it looks in the source code and how its being affected by CSS. PHP, HTML, AND CSS TUTORIALS You will do best if you have a basic understanding of HTML PHP and CSS. I recommend reading through the HTML Dog HTML Beginner Tutorial and the HTML Dog CSS Beginner Tutorial . A nice one hour PHP tutorial is on WebMonkey.com Reading through these three tutorials is completely optional but it wont hurt and will help you grasp some basic concepts. INSTALLATION 1. Download and unzip the latest version from http://wordpress.org/download/ 2. Copy the files to appropriate document root dir such as /wordpress 3. Create a blank database for WordPress in Mysql or on your web server; i.e wp or wordpress. 4. Create a db user who has all privileges for accessing and modifying the db. i.e. wpadmin, wpuser, etc. Think of a password for the db such as wppwd, wpaccess, etc. 5. Rename the wp-config-sample.php file to wp-config.php. 6. Open wp-config.php in a text editor and fill in your database details as explained in Editing wpconfig.php to generate and use your secret key password. Note that most local development AND remote servers install Mysql as localhost. 7. Upload the WordPress files in the desired location on your web server: 8. If you want to integrate WordPress into the root of your domain (e.g. http://example.com/), move or upload all contents of the unzipped WordPress directory (but excluding the directory itself) into the root directory of your web server. 9. If you want to have your WordPress installation in its own subdirectory on your web site (e.g. http://example.com/blog/), create the blog directory on your server and upload WordPress to the directory via FTP. 10. Run the WordPress installation script by accessing wp-admin/install.php in a web browser. 11. If you installed WordPress in the root directory, you should visit: http://example.com/wpadmin/install.php 12. If you installed WordPress in its own subdirectory called blog, for example, you should visit: http://example.com/blog/wp-admin/install.php

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 11 of 109

May 15, 2012 Copyright 2005-2012

Section 3 HTML Structure


GOOD HTML STRUCTURE When coding a web site you should have 2 goals in mind: lean code and meaningful code. That is, using as little markup (HTML tags) as possible and making sure that the markup is meaningful by using semantic class and ID names that refer to their content, not how they look. Calling a class fading_box is better than left_image. If a page is reformatted or a class is reused for something else, the latter left_image is meaningless. Good judgment is always needed when striking a balance between lean markup, with very little structure, and whats called Divitis; including too many unnecessary div elements in your code. Think of a div tag as containers for manipulating HTML and CSS formatting code. We want enough structureusing the div tagthat we can reuse our code for multiple web site layouts. THE HTML STRUCTURE FOR YOUR WORDPRESS THEME Lets take a look at the HTML structure well be using for the body of our Theme.
<html> <head> <title></title> </head> <body> <div id="wrapper" class="hfeed"> <div id="header"> <div id="masthead"> <div id="branding"> </div> <div id="access"> </div> </div> </div> <div id="main"> <div id="container"> <div id="content"> </div> </div>

<!-- #branding -->

<!-- #access --> <!-- #masthead --> <!-- #header -->

<!-- #content --> <!-- #container -->

<div id="primary" class="widget-area"> </div> <!-- #primary .widget-area --> <div id="secondary" class="widget-area"> </div> <!-- #secondary --> </div> <!-- #main -->

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 12 of 109

May 15, 2012 Copyright 2005-2012

<div id="footer"> <div id="colophon"> <div id="site-info"> </div> </div> </div> </div> </body> </html>
Listing 3.1

<!-- #site-info --> <!-- #colophon --> <!-- #footer --> <!-- #wrapper -->

Paste this code into your text editor and save it somewhere handy. Well be using it later when we build the file structure for our Theme. But before we do that, there are a few things well want to take a look at. UNDERSTANDING THE HTML THEME First, the class attribute on the wrapper hfeed is part of the hatom Microformat schema used by Google search engines. In plain English, this means that adding that hfeed class to our page tells any search engine that our site publishes syndicated content, like blog posts. Youll be seeing a lot of class names like this as we go along. Looking at the div structure for the header and footer, youll notice we use what is called an innerouter structure. By borrowing class names from the publishing world, Ive added some meaning to the markup in these containers. In the main area of our HTML youll notice that we have 2 widget areas that come after our content area. You will also notice our content rests inside a container div. These points are key. Search engines will see our main content come before the sidebars, but by using a CSS technique involving negative margins we can turn the format into a 1, 2, or 3 column theme with only a few lines of CSS. This HTML structure is going to future-proof your WordPress Theme and give you the opportunity to do powerful stuff with CSS. Its a good one.

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 13 of 109

May 15, 2012 Copyright 2005-2012

Section 4 Template & Directory Structure


A minimal WordPress Theme only needs an index.php Template and a style.css file. But, to have full functionality, more is needed. Our minimal Theme will include 6 files. Now is a good time to make a folder in the Wordpress directory wp-content/themes/<theme name>. For this tutorial Ill be using mini_theme but it can be whatever you want. Our Theme project can be separated into two halves. Each column below represents the files in each half.

1st half 404.php attachment.php footer.php functions.php header.php index.php single.php style.css

2nd half archive.php author.php category.php comments.php page.php search.php sidebar.php tag.php

Now is a good time to create all of these files in a new Theme folder. Of course they will all have blank contents until we fill them with code. Dont let all these files scar you. Most of these files are copied with a few changes from work that we will do. It goes really quick. OK. Lets get started! Open style.css, in a text editor. We need to add some information in a comment at the top of this file. Wordpress reads and understands this. Without it, your theme wont show up in the themes panel.
/* Theme Name: Mini Theme Theme URI: http://example.com/example/ Description: A search engine optimized website framework for WordPress. Author: Your name Author URI: http://example.com/ Version: 1.0 Tags: Comma-separated tags that describe your theme. License: Like WordPress, this work is released under GNU General Public License, version 2 (GPL). License URI: http://www.gnu.org/licenses/gpl-3.0.html General comments (optional).

by Jan Zumwalt (NeatInfo.com) Wordpress Theme Reference

Page 14 of 109

May 15, 2012 Copyright 2005-2012

*/ Listing 4.1

Some of this information is optional, all that is really needed is the Theme Name. But if you ever plan on releasing your theme, or if youre making a custom theme for someone, youll want to start out including most, if not all, of the rest. Once youve got this information in your style.css, you can activate your theme and navigate to your test site. Weve made the ultimate blank theme! You wont see anything but its there! BUILDING IN YOUR HTML STRUCTURE As mentioned before, WordPress really only needs one Theme template file index.php. We will add more template files later, but for now index.php is all we need. It is a good idea to separate our web pages into a beginning, middle, and an end. When we write templates like index.php file we usually only work on the middle and just copy the beginning and end. When its time to make a new template, we supply the middle, and copy the beginning and end. We are going to separate the html code we created in the previous section into three parts (files). header.php index.php footer.php the beginning the middle the end

Using the text editor, cut and paste the code so that the three files look like this HEADER.PHP
<html> <head> <title></title> </head> <body> <div id="wrapper" class="hfeed"> <div id="header"> <div id="masthead"> <div id="branding"> </div> <div id="access"> </div> </div> </div> <div id="main"> Listing 4.2 header.php

<!-- #branding -->

<!-- #access --> <!-- #masthead --> <!-- #header -->

INDEX.PHP
<div id="container"> <div id="content"> </div>

<!-- #content -->

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 15 of 109

33

May 15, 2012 Copyright 2005-2012

</div>

<!-- #container -->

<div id="primary" class="widget-area"> </div> <!-- #primary .widget-area --> <div id="secondary" class="widget-area"> </div> <!-- #secondary --> Listing 4.3 index.php

FOOTER.PHP
</div> <div id="footer"> <div id="colophon"> <div id="site-info"> </div><!-- #site-info --> </div> </div> </div> </body> </html> Listing 4.4 footer.php <!-- #colophon --> <!-- #footer --> <!-- #wrapper --> <!-- #main -->

Thats all that is needed to have a basic html code skeleton in our Wordpress Theme! FINISHING INDEX.PHP We need to call in the header.php and footer.php into our index.php Theme. At the top of index.php, before anything else, add the following template tag.
<?php get_header(); // include header ?> Listing 4.5

This tells Wordpress to copy the header. Alright! Can you guess what function call were going to use to copy the footer? At the bottom of index.php, after everything else add the following template tag.
<?php get_footer(); // include footer ?> Listing 4.6

Index.php is our main Template file and it adds the header and footer. If you reload you web page in Wordpress you will still see a blank page. But, if you view the browsers source code you will see the header and footer code is now included. Firefox source code - (View > Page Source). Internet Explorer source code (right click on page> select view source)

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 16 of 109

33

May 15, 2012 Copyright 2005-2012

Section 5 Header Template


Now we need to build up the header.php and validate the Theme with a HTML Doctype. Therell be a lot of PHP in this lesson but dont despair. Were also going to do two, essential, and kinda neat, search engine optimization tricks and start tricking out your theme with a functions.php file. FUNCTIONS.PHP Open up your functions.php file. Were going to add two helper function there, thatll come in handy when were creating the document title. Your functions.php file should look like this
<?php // Make theme available for language translations // Translations can be filed in the /languages/ directory load_theme_textdomain('your-theme', TEMPLATEPATH . '/languages'); $locale = get_locale(); $locale_file = TEMPLATEPATH . "/languages/$locale.php"; if (is_readable($locale_file)) require_once($locale_file); // Get the page number function get_page_number() { if (get_query_var('paged')) { print ' | ' . __('Page ', 'your-theme') . get_query_var('paged'); } //get_query_var('paged') } // end get_page_number ?> Listing 5.1

The first function tells WordPress we want to make our theme available for translation and that translation files can be found in our theme folder in a folder called languages. If youre going to create a WordPress Theme you should always try your best to make sure everything is translatable. You never know when someone else is going to need hard-coded content available in another language. WHAT IS TRANSLATABLE CODE? For foreign language translating, were going to use the php gettext functions. GetText has two functions: _e and __(two underscores). The e function is used to print simple text, and the __ function is used when the text to be displayed is already wrapped in php tags. Examples:
<?php _e("The page you're looking for doesn't exist", "Cats Who Code"); ?> <?php the_content(__('Read more...', "Cats Who Code")); ?>

Notice again the text domain name (Cats Who Code) above, remember that it should be the same as in the functions.php file.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 17 of 109

33

May 15, 2012 Copyright 2005-2012

The boring part is that you have to replace each single string by the required function. Depending on how many strings your theme have, this can take a lot of time. Some developers use GNU tools to easily extract strings from files, but as I never tried it I cant say anything about it. For those interested, take a look at google xgettext. In our next function, get_the_page_number(), youll see some translatable text. It looks like this:
__('Page ', 'your-theme') Listing 5.2

The text ready for translation is Page followed by the directory name of our theme; in this case, your-theme. Pretty straightforward but there are couple other ways to write translatable text. Well get to them when we come to them. Can you guess what get_page_number() is doing? If you take a look inside the function you can see that were checking with an IF statement to see if were on a paged page, you know, where you are when you click older posts. If you are, this function will print a bar separator and the current page number. THE HEAD SECTION Right now the blank WordPress Theme is technically invalid because its missing a Doctype telling the browser what type of code is in the file. Open up header.php and paste the following code there, before anything else.
<!DOCTYPE HTML> Listing 5.3 doc type

Now were going to get into the get into the <head> section of your Theme. The <head> section contains meta-information about a web page. Typically stuff like the document title seen at the top of your browser (and in search engine results), and links to style sheets and RSS feeds. Replace from the beginning of <head> to the end of </head> tag with the following code:
<head profile="http://gmpg.org/xfn/11"> <title> <?php if (is_single()) { single_post_title(); } elseif (is_home() || is_front_page()) { bloginfo('name'); print ' | '; bloginfo('description'); get_page_number(); } elseif (is_page()) { single_post_title(''); } elseif (is_search()) { bloginfo('name'); print ' | Search results for ' . wp_specialchars($s); get_page_number(); } elseif (is_404()) { bloginfo('name'); print ' | Not Found'; } else {

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 18 of 109

33

May 15, 2012 Copyright 2005-2012

bloginfo('name'); wp_title('|'); get_page_number(); } ?> </title> <meta http-equiv="content-type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); // page content info ?>" /> <link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_url'); // link to style sheet ?>" /> <?php if (is_singular()){ wp_enqueue_script('comment-reply'); } // threaded comments ?> <?php wp_head(); // allow plugins and customization ?> <link rel="alternate" type="application/rss+xml" href="<?php bloginfo('rss2_url'); // links for rss feeds ?>" title="<?php printf(__('%s latest posts', 'your-theme'), wp_specialchars(get_bloginfo('name'), 1)); ?>" /> <link rel="alternate" type="application/rss+xml" href="<?php bloginfo('comments_rss2_url'); ?>" title="<?php printf(__('%s latest comments', 'your-theme'), wp_specialchars(get_bloginfo('name'), 1)); ?>" /> <link rel="pingback" href="<?php bloginfo('pingback_url'); // links for pingbacks ?>" /> </head> Listing 5.4 page head

If all this looks like gobbledygook to you thats OK. Ill explain the main sections. XFN PROTOCOL The first line informs Wordpress that the XFN protocol for blog information is used. For now, you can ignore this (see appendix C).
<head profile="http://gmpg.org/xfn/11"> Listing 5.5 head profile

<TITLE> Next we create a search engine optimized title tag that shows only the post title on single posts and pages. And, of course, adds page numbers with get_page_number() on older post pages.
<title> <?php if (is_single()) { single_post_title(); } elseif (is_home() || is_front_page()) { bloginfo('name'); print ' | '; bloginfo('description'); get_page_number(); } elseif (is_page()) { single_post_title('');

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 19 of 109

33

May 15, 2012 Copyright 2005-2012

} elseif (is_search()) { bloginfo('name'); print ' | Search results for ' . wp_specialchars($s); get_page_number(); } elseif (is_404()) { bloginfo('name'); print ' | Not Found'; } else { bloginfo('name'); wp_title('|'); get_page_number(); } ?> </title> Listing 5.5 page title

META INFORMATION Some meta information about our page content.


<meta http-equiv="content-type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); // content information ?>" /> Listing 5.6 content information

A link to our stylesheet.


<link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_url'); // style sheet link ?>" /> Listing 5.7 stylesheet link

A script call so we can use threaded comments when we get to our comments section.
<?php if ( is_singular() ) wp_enqueue_script( 'comment-reply' ); // allow threaded comments ?> Listing 5.8 threaded comment support

A hook for WordPress plugins and other cool stuff.


<?php wp_head(); // allow plugins and customization ?> Listing 5.9 plugin support

Links for RSS Feeds (live news and information) and pingbacks. A pingback is a code module that provides notification to authors when somebody links to one of their documents. This enables authors to keep track of who is linking to, or referring to their articles. WordPress supports automatic pingbacks where all the links in a published article can be pinged when the article is published.
<link rel="alternate" type="application/rss+xml" href="<?php bloginfo('rss2_url'); // links for rss feeds ?>" title="<?php printf(__('%s latest posts', 'your-theme'), wp_specialchars(get_bloginfo('name'), 1)); ?>" /> <link rel="alternate" type="application/rss+xml" href="<?php bloginfo('comments_rss2_url'); ?>"

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 20 of 109

33

May 15, 2012 Copyright 2005-2012

title="<?php printf(__('%s latest comments', 'your-theme'), wp_specialchars(get_bloginfo('name'), 1)); ?>" /> <link rel="pingback" href="<?php bloginfo('pingback_url'); // links for pingbacks ?>" /> Listing 5.10 RSS feeds and Pingbacks

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 21 of 109

33

May 15, 2012 Copyright 2005-2012

Section 6 Page description and Menu


PAGE DESCRIPTION In header.php move down to the #branding div. This is where well add the blog title and description. The blog title will act as a link to our home page, blog description, and menu. Were going to do something different from most WordPress themes. Most Themes tell search engines that the most important thing on every page is your blog title by wrapping it in an <h1> html tag. Instead, I think the most important thing is the page title. On our home page, really, the most important thing is the description of the blog, not the title of the blog. The page title provides a better description of ALL the content on a page. To do this were going to use some WordPress conditional tags and some easy HTML code. Heres what it looks like:
<div id="branding"> <!-- #branding --> <div id="blog-title"> <span> <a href="%3C?php%20bloginfo(%20'url'%20)%20?%3E/" title=" <?php bloginfo( 'name' ) ?>" rel="home"><?php bloginfo( 'name' ) ?></a> </span> </div> <?php if ( is_home() || is_front_page() ) { ?> <h1 id="blog-description"><?php bloginfo( 'description' ) ?></h1> <?php } else { ?> <div id="blog-description"> <?php bloginfo( 'description' ) ?> </div> <?php } ?> </div> Listing 6.1 blog and page description

<!-- #branding -->

We set the blog title in a regular div tag. Our blog description is set, using PHP IF statements and some WordPress conditional tags. If the page is either the home page or front page, the description gets wrapped in a very important <h1> tag. In the code above we used a WordPress Template Tag called bloginfo(). You can see were using it to get the URL of our WordPress blog, the name of our blog, and the description. It can be used to get over 20 different pieces of information about the blog. It takes that information and prints it in your template. This is an excellent example of how WordPress works; we take an HTML structure and use PHP to call WordPress Template Tags (code modules) to fill in content. It is really simple! Its just a matter of getting used to seeing the Template Tags, along with some PHP if statements and a few PHP loops (well get to those too). Move on down to the #access div. Change it to look like this. NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference Pg 22 of 109 33 May 15, 2012 Copyright 2005-2012

<div id="access"> <!-- #access --> <div class="skip-link"> <! link to skip to content --> <a href="#content" title=" <?php _e( 'Skip to content', 'your-theme' ) ?>"> <?php _e( 'Skip to content', 'your-theme' ) ?> </a> </div> <?php wp_page_menu( 'sort_column=menu_order' ); ?> <!page menu --> </div> <!-- #access --> Listing 6.1 access div

Here is what we have done. The first part adds a link that lets folks using a screen reader to skip right to the content.
<div class="skip-link"> <a href="#content" title=" <?php _e( 'Skip to content', 'your-theme' ) ?>" > <?php _e( 'Skip to content', 'your-theme' ) ?> </a> </div> Listing 6.2 skip to content

Next we added the page menu. It is just one template tag, with only one argument:
<?php wp_page_menu( 'sort_column=menu_order' ); ?> Listing 6.3 page menu

Our web site has a lot of bones but still not much flesh. If you look at it in your browser you should see something like this.

Now its time to start working on some of the content. And there is more good news. Your WordPress Theme Header Template is search engine optimized and coded up.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 23 of 109

33

May 15, 2012 Copyright 2005-2012

Section 7 index.php
index.php is the most crucial WordPress Theme Template. It serves as the default template and is used in place of any missing templates. Getting this template right, will help us breeze through the rest of our templates (except for the Comments Template). Open index.php and follow the next steps. THE LOOP The majority of work accomplished by index.php is done through the use of a PHP loop statement. Heres what it looks like.
<?php while ( have_posts() ) : the_post() ?> <?php endwhile; ?> Listing 7.1

This tells the Theme to loop through each post and do something with it. For the next examples I suggest you import or type in some sample post messages. We can test the loop by using the code below. Place it between the content div in index.php. Once we have this working, we can add more code to it. (warning: the code below causes an unformatted piled up output!)
<div id="content"> <!-- #content --> <?php while ( have_posts() ) : the_post() ?> <?php the_content(); ?> <?php endwhile; ?> </div> <!-- end #content --> listing 7.2 simple message loop

Output of listing 7.2 with test post messages

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 24 of 109

33

May 15, 2012 Copyright 2005-2012

What happened? The messages are listed in a big smashed pile. So lets improve on this. Replace the code we just used with this.
<div id="content"> <!-- #content --> <ul> <?php while ( have_posts() ) : the_post() ?> <li> <?php the_excerpt(); ?> </li> <?php endwhile; ?> </ul> </div> <!-- end #content --> listing 7.3

Output of listing 7.3 with test post messages

OK! That looks a lot better. Do you see what we did? Now weve got a better looking format, and you get to see what the_content() and the_excerpt() do. Basically, you make a loop (starts with while ends with endwhile) and put some stuff in itstuff being WordPress Template Tags that pull information out of the posts were looping though, just like bloginfo() pulled information out of our WordPress settings in the last lesson. Alright, lets make a really awesome loop. Lets start with our basic, smushed up one. But well make sure its ready for the More Tag and the Next Page Tag. Well also put it in its own div and let machines know its the content of a blog post with the microformat class entry-content.
<div class="entry-content"> <?php the_content( __( 'Continue reading <span class="meta-nav">&raquo;</span>', 'yourtheme' ) ); ?> <?php wp_link_pages('before=<div class="page-link">' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?> </div><!-- .entry-content --> Listing 7.4

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 25 of 109

33

May 15, 2012 Copyright 2005-2012

How about the post title? Thats pretty simple too. Well use the Template Tag the_title() to get the title of the post and wrap it in an <a> tag that links to the_permalink() (thats the permanent link to any particular post). Well also add in a title attribute and another microformat (bookmark) that tells machines (like Google) that this is the permalink to a blog post. Try putting the following just above the .entry-content div.
<h2 class="entry-title"> <a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'your-theme'), the_title_attribute('echo=0') ); ?> " rel="bookmark"><?php the_title(); ?> </a> </h2> listing 7.5

Now for all the extra bits that attend to any blog post: who wrote it, the time it was published, categories, tags, comments links. I like to break all this up into two sections: the meta stuff (author and entry date) which I put before the post content, and the utility stuff (categories, tags and comments link) that I put after the content. And both sections Well also put the post in its own containing div with the title. Lets take a look at the whole loop together. Ive inserted some PHP comments in here to help guide you along.
<div id="content"> <!-- #content -->

<?php /* The Loop with comments! */ ?> <?php while (have_posts()): the_post(); ?> <?php /* Create a div with a unique ID thanks to the_ID() and semantic classes with post_class() */ ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <?php /* an h2 title */ ?> <h2 class="entry-title"> <a href="<?php the_permalink(); ?>" title="<?php printf(__('Permalink to %s', 'your-theme'), the_title_attribute('echo=0')); ?>" rel="bookmark"> <?php the_title(); ?> </a> </h2> <?php /* Microformatted, translatable post meta */ ?> <div class="entry-meta"> <span class="meta-prep meta-prep-author"> <?php _e('By ', 'your-theme'); ?> </span> <span class="author vcard"> <a class="url fn n" href="<?php echo get_author_link(false, $authordata>ID, $authordata->user_nicename); ?> " title="<?php printf(__('View all posts by %s', 'your-theme'), $authordata->display_name); ?>"> <?php the_author(); ?> </a> </span> <span class="meta-sep"> | </span> <span class="meta-prep meta-prep-entry-date"><?php _e('Published ', 'yourtheme'); ?></span>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 26 of 109

33

May 15, 2012 Copyright 2005-2012

<span class="entry-date"><abbr class="published" title="<?php the_time('Ym-d\TH:i:sO'); ?>"> <?php the_time(get_option('date_format')); ?></abbr> </span> <?php edit_post_link(__('Edit', 'your-theme'), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"editlink\">", "</span>\n\t\t\t\t\t"); ?> </div><!-- .entry-meta --> <?php /* The entry content */ ?> <div class="entry-content"> <?php the_content(__('Continue reading <span class="metanav">&raquo;</span>', 'your-theme')); ?> <?php wp_link_pages('before=<div class="page-link">' . __('Pages:', 'yourtheme') . '&after=</div>'); ?> </div><!-- .entry-content --> <?php /* Microformatted category and tag links along with a comments link */ ?> <div class="entry-utility"> <span class="cat-links"> <span class="entry-utility-prep entry-utility-prep-cat-links"> <?php _e('Posted in ', 'your-theme'); ?> </span> <?php echo get_the_category_list(', '); ?> </span> <span class="meta-sep"> | </span> <?php the_tags('<span class="tag-links"> <span class="entry-utility-prep entry-utility-prep-tag-links">' . __('Tagged ', 'your-theme') . '</span>', ", ", "</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n"); ?> <span class="comments-link"> <?php comments_popup_link(__('Leave a comment', 'your-theme'), __('1 Comment', 'your-theme'), __('% Comments', 'your-theme')); ?> </span> <?php edit_post_link(__('Edit', 'your-theme'), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"editlink\">", "</span>\n\t\t\t\t\t\n"); ?> </div><!-- #entry-utility --> </div><!-- #post-<?php the_ID(); ?> --> <?php /* Close up the post div and then end the loop with endwhile */ ?> <?php endwhile; ?> </div> listing 7.6 <!-- end #content -->

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 27 of 109

33

May 15, 2012 Copyright 2005-2012

Output of listing 7.6 with fully formatted messages

A final word about listing 7.6. Please dont let the length of this code be intimidating. We dont have the space to go through each line of code, but if you took the time to look at each block of code, they each accomplish something simple. Often times it is a good idea to look at code as bricks in a building. The building may look huge like the Empire State building. But if you look closely, it is made out of many small bricks that are easily understood and work together. Some programmers refer to this type of programming as the black box approach. They rely on other programmers to work out the fine details, once it works they way they want they only concern themselves with how to implement (use) it.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 28 of 109

33

May 15, 2012 Copyright 2005-2012

Section 8 Navigation
Now we need a way to navigate back through our posts. Well do this with 2 WordPress Template Tags: next_posts_link() and previous_posts_link(). WARNING: These 2 functions work opposite of there label Ouch!!! I think the WordPress codex says it best. next posts link This creates a link to the previous posts. Yes, it says next posts, but its named that way just to confuse you. previous posts link This creates a link to the next posts. Yes, it says previous posts, but its named that way just to confuse you. Just like everything in index.php, post navigation needs to be given some careful thought when were building it for the first time because were going to wind up using it on almost every page in our blog. I like to have post navigation the first and last thing inside the content tags. It can be placed as needed for any particular situation. There may be situations you dont need it. If we need to disable it, we can add some CSS code to do this.
single #nav-above { display:none; } Listing 8.1- disabling an ID tag

That CSS will hide post navigation above the content on single posts. Well also want to hide any navigation code IF theres nothing to navigate too. That is, if, say, on a search, there are no older pages of posts, we dont want to output any navigation code at all to the browser. Well do that by wrapping our code in the following statement:
<?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?> <?php } ?> Listing 8.2 no display if end of page count

What were doing is checking to see what the maximum number of pages is in any loop were going to be looking at and if the number of pages is greater than 1, well output our navigation. Alright, heres the code well need for your navigation, top and bottom, just before, and just after the loop.
<div id="content"> <?php /* Top post navigation */ global $wp_query;

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 29 of 109

33

May 15, 2012 Copyright 2005-2012

$total_pages = $wp_query->max_num_pages; if ($total_pages > 1) { ?> <div id="nav-above" class="navigation"> <div class="nav-previous"> <?php next_posts_link(__('<span class="meta-nav">&laquo;</span> Older posts', 'your-theme')); ?> </div> <div class="nav-next"> <?php previous_posts_link(__('Newer posts <span class="meta-nav">&raquo;</span>', 'your-theme')); ?> </div> </div> <!-- #nav-above --> <?php } ?> listing 8.3 - top post navigation (relative to content tag) <?php /* Bottom post navigation */ ?> <?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ($total_pages > 1) { ?> <div id="nav-below" class="navigation"> <div class="nav-previous"><?php next_posts_link(__('<span class="meta-nav">&laquo;</span> Older posts', 'yourtheme')); ?> </div> <div class="nav-next"><?php previous_posts_link(__('Newer posts <span class="meta-nav">&raquo;</span>', 'your-theme')); ?> </div> </div><!-- #nav-below --> <?php } ?> </div> <! content --> listing 8.4 - bottom post navigation (relative to content tag)

One last thing and were done with index.php. Youll be itching to see what we can do with it, but for now were just going to put in the function call just before get_footer().
<?php get_sidebar(); ?> Listing 8.5

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 30 of 109

33

May 15, 2012 Copyright 2005-2012

Section 9 Single Post


Youve built an index of all your posts, now you need to create a template to frame each piece of content (or missing content) on its own. THE TEMPLATE FOR TEMPLATES Create a new file named single.php and copy the code from listing 9.1 into it . The structure of single.php (and almost all the other templates well be creating) is largely the same as index.php. In fact you can think of it as our template-template.
<?php get_header(); ?> <div id="container"> <div id="content"> <div id="nav-above" class="navigation"> </div> <!-- #container --> <!-- #content --> <!-- #nav top --> <!-- end #nav top --> <!-- #post --> <!-- end #post -->

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?> > </div><!-- #post-<?php the_ID(); ?> --> <div id="nav-below" class="navigation"> </div><!-- #nav-below -</div><!-- #content --> </div><!-- #container --> <?php get_sidebar(); ?> <?php get_footer(); ?> Listing 9.1

<!-- #nav bottom --> <!end #nav bottom --> <!-- end #content --> <!-- end #container -->

But there are going to be some notable differences. Starting with the_post() and comments_template(). Well be calling the_post() near the top of our page just after the opening of the content div and just before the navigation. We wont need a loop in this template as WordPress knows just what post were looking at thanks to the_permalink(). And since this is a single post, well need the comments_template(). And because well be separating our comments and trackbacks when we come to coding up comments.php, we need to call it just like so:
<?php comments_template('', true); ?> Listing 9.2

comments_template() will need to go just before the close of the #content div right after the
navigation. SINGLE POST NAVIGATION

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 31 of 109

33

May 15, 2012 Copyright 2005-2012

Instead of using the poorly named next_posts_link() and previous_posts_link() well be using the mostly accurately named previous_post_link() and next_post_link(). They do just what you think they do.
<div id="nav-above" class="navigation"> <!-- #nav-above --> <div class="nav-previous"><?php previous_post_link( '%link', '<span class="metanav">&laquo;</span> %title' ) ?></div> <div class="nav-next"><?php next_post_link( '%link', '%title <span class="metanav">&raquo;</span>' ) ?></div> </div> <!-- end #nav-above --> <div id="nav-below" class="navigation"> <!-- #nav-below --> <div class="nav-previous"><?php previous_post_link( '%link', '<span class="metanav">&laquo;</span> %title' ) ?></div> <div class="nav-next"><?php next_post_link( '%link', '%title <span class="metanav">&raquo;</span>' ) ?></div> </div> <!-- end #nav-below --> Listing 9.3

SINGLE POST TITLES If you remember from our header.php lesson, we used a dynamic IF statement to clear the way for our Single post titles to take precedence on the page in the eyes of screen readers. We take advantage of this in this and all the rest of our Theme Templates by wrapping the title in and h1 tag.
<h1 class="entry-title"><?php the_title(); ?></h1> Listing 9.4

Youll notice that our post title code is a little simpler too. The benefit of not having to link to anything now. SINGLE POST ENTRY UTILITY LINKS The entry utility is complicated. Here I think youll see the benefit of getting something right once and standing on the shoulders of others. Before we take a look at the code we should think about why it is complicated. Because of the way comments work in WordPress we need to account for a few different scenarios: Open comments and trackbacks; only trackbacks open; only comments open; comments and trackbacks closed. And that means what looks like a mess of IF statements. It can be daunting. The code is commented but remember to look for the blocks of IF and ELSEIF statements and youll be fine. We also want to print a link to our permalink here for bookmarking purposes and the RSS for this particular single postuseful for tracking developing conversations.
<div class="entry-utility"> <?php printf( __( 'This entry was posted in %1$s%2$s. Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>. Follow any comments here with the <a href="%5$s" title="Comments RSS to %4$s" rel="alternate" type="application/rss+xml">RSS feed for this post</a>.', 'your-theme' ), get_the_category_list(', '), get_the_tag_list( __( ' and tagged ', 'your-theme' ), ', ', '' ), get_permalink(), the_title_attribute('echo=0'), comments_rss() ) ?> <?php if ( ('open' == $post->comment_status) && ('open' == $post->ping_status) ) : // Comments and trackbacks open ?> <?php printf( __( '<a class="comment-link" href="#respond" title="Post a comment">Post a comment</a> or leave a trackback: <a class="trackback-link" href="%s"

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 32 of 109

33

May 15, 2012 Copyright 2005-2012

title="Trackback URL for your post" rel="trackback">Trackback URL</a>.', 'your-theme' ), get_trackback_url() ) ?> <?php elseif ( !('open' == $post->comment_status) && ('open' == $post->ping_status) ) : // Only trackbacks open ?> <?php printf( __( 'Comments are closed, but you can leave a trackback: <a class="trackback-link" href="%s" title="Trackback URL for your post" rel="trackback">Trackback URL</a>.', 'your-theme' ), get_trackback_url() ) ?> <?php elseif ( ('open' == $post->comment_status) && !('open' == $post->ping_status) ) : // Only comments open ?> <?php _e( 'Trackbacks are closed, but you can <a class="comment-link" href="#respond" title="Post a comment">post a comment</a>.', 'your-theme' ) ?> <?php elseif ( !('open' == $post->comment_status) && !('open' == $post->ping_status) ) : // Comments and trackbacks closed ?> <?php _e( 'Both comments and trackbacks are currently closed.', 'your-theme' ) ?> <?php endif; ?> <?php edit_post_link( __( 'Edit', 'your-theme' ), "\n\t\t\t\t\t<span class=\"editlink\">", "</span>" ) ?> </div><!-- .entry-utility --> Listing 9.5

SINGLE POST CONTENT Unlike index.php, single.php content is pretty simple. Just one plain function call followed by wp_link_pages().
<?php the_content(); ?> <?php wp_link_pages('before=<div class="page-link">' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?> Listing 9.6

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 33 of 109

33

May 15, 2012 Copyright 2005-2012

Section 10 Post Attachment


POST ATTACHMENTS Very few people use post attachments but we want our Theme to be complete. When you add an image to your post youre actually attaching it to the post. And, of course, you can attach more than just images. Were going to make an attachment.php template that can be adapted to cover other types of attachments like video, audio, and applications. Normally they would be called video.php, audio.php, and application.php templates. The easiest way to proceed is by copying single.php, renaming it attachment.php, and making the following changes. First of all, delete the top navigation. We wont need it at all here. Replace it with a page title that links back to your parent post.
<h1 class="page-title"> <a href="<?php echo get_permalink($post->post_parent) ?>" title="<?php printf( __( 'Return to %s', 'your-theme' ), wp_specialchars( get_the_title($post->post_parent), 1 ) ) ?>" rev="attachment"> <span class="meta-nav">&laquo; </span> <?php echo get_the_title($post->post_parent) ?> </a> </h1> Listing 10.1

Since the page title is now wrapped in h1 tags that means our post title should be wrapped in h2 tags.
<h2 class="entry-title"> <?php the_title(); ?> </h2> Listing 10.2

Now, because our attachment template needs to actually show the attachment, our content needs to reflect that. And since most attachments are going to be images, well want to check for that and cover that scenario with an IF statement.
<div class="entry-content"> <div class="entry-attachment"> <?php if ( wp_attachment_is_image( $post->id ) ) : $att_image = wp_get_attachment_image_src( $post->id, "medium"); ?> <p class="attachment"> <a href="<?php echo wp_get_attachment_url($post->id); ?>" title="<?php the_title(); ?>" rel="attachment"> <img src="<?php echo $att_image[0];?>" width="<?php echo $att_image[1];?>" height="<?php echo $att_image[2];?>" class="attachment-medium" alt="<?php $post->post_excerpt; ?>" /> </a> </p> <?php else : ?> <a href="<?php echo wp_get_attachment_url($post->ID) ?>"

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 34 of 109

33

May 15, 2012 Copyright 2005-2012

title="<?php echo wp_specialchars( get_the_title($post->ID), 1 ) ?>" rel="attachment"><?php echo basename($post->guid) ?> </a> <?php endif; ?> </div> <!-- end entry-attachment --> <div class="entry-caption"><?php if ( !empty($post->post_excerpt) ) the_excerpt() ?></div> <?php the_content( __( 'Continue reading <span class="meta-nav">&raquo;</span>', 'your-theme' ) ); ?> <?php wp_link_pages('before=<div class="page-link">' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?> </div><!-- .entry-content --> Listing 10.3

Delete the bottom navigation from what was once your old single.php, and youre done your attachment.php Template.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 35 of 109

33

May 15, 2012 Copyright 2005-2012

Section 11 404 Error Templates


A 404 error is when the server cant find a page. The page may have been renamed, deleted, or never existed. The user may have typed the url incorrectly or you unpublish a blog post? When any of this happens, the server shows the 404 error template. Luckily, WordPress has a template for that. Its called, 404.php. A good technique is to say youre sorry and include a search form. There are many creative solutions but this is short and provides the assistance the visitor needs. Here is the code to say we are sorry and show a search form.
<div id="post-0" class="post error404 not-found"> <h1 class="entry-title"><?php _e( 'Not Found', 'shape' ); ?></h1> <div class="entry-content"> <p> <?php _e( 'Sorry, but we were unable to find what you were looking for. Perhaps searching will help.', 'shape' ); ?> </p> <?php get_search_form(); ?> </div><!-- .entry-content --> </div><!-- #post-0 --> listing 11.1 say youre sorry and provide a search form

The complete 404 error template is based on the skeleton provided in the previous section. All you have to do is drop the navigation and add the message and search form content. Here is the complete template.
<?php get_header(); ?> <div id="container"> <div id="content"> <div id="post-0" class="post error404 not-found"> <h1 class="entry-title"><?php _e( 'Not Found', 'shape' ); ?></h1> <div class="entry-content"> <p> <?php _e( 'Sorry, but we were unable to find what you were looking for. Perhaps searching will help.', 'shape' ); ?> </p> <?php get_search_form(); ?> </div><!-- .entry-content --> </div><!-- #post-0 --> </div><!-- #content --> </div><!-- #container --> <?php get_sidebar(); ?>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 36 of 109

33

May 15, 2012 Copyright 2005-2012

<?php get_footer(); ?> listing 11.2 the complete server 404 error template

Copy the code from listing 11.2 into a file named 404.php and you are done!

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 37 of 109

33

May 15, 2012 Copyright 2005-2012

Section 12 Comments Template


Ok! Im going to be honest; the Comment template is the hardest part of this project. WordPress has a simple way of producing Comments Templateswhich is no help if you want to separate your comments and trackbacks or have custom comment markup. On a positive thought, when we are done with this template, its an easy road all the way ahead. Our project will be more than 60% complete. So lets get this behind us. For the Comments Template Im going to walk you through it. Well start by adding some helper functions to functions.php. Hopefully, itll make sense and the end product will be a really good Comment template. Lets take a look at whats happening in this Template. 1. 2. 3. 4. 5. 6. Prevent loading for bots and on password protected posts Check if there are comments Count the number of comments and trackbacks (or pings) If there are comments, show the commentswith navigation for paginated comments If there are trackbacks, show the trackbacks If comments are open, show the comments respond form

Thats a lot of stuff going on for one template but if we take it a section at a time its pretty straightforward. CUSTOM CALLBACKS FOR COMMENTS AND TRACKBACKS WordPress has a function wp_list_comments() that conveniently spits out an ordered list of comments and trackbacks markup for the post (threaded too). Convenient if you want that, but unfortunately we dont. We want separated threaded comments and trackbacks, with our own custom markup. We need a set of custom callbacks for your list of Comments and Trackbacks. So add the following two functions to your theme functions.php file.
// Custom callback to list comments in the your-theme style function custom_comments($comment, $args, $depth) { $GLOBALS['comment'] = $comment; $GLOBALS['comment_depth'] = $depth; ?> <li id="comment-<?php comment_ID() ?>" <?php comment_class() ?>> <div class="comment-author vcard"><?php commenter_link() ?></div> <div class="comment-meta"><?php printf(__('Posted %1$s at %2$s <span class="metasep">|</span> <a href="%3$s" title="Permalink to this comment">Permalink</a>', 'yourtheme'), get_comment_date(), get_comment_time(), '#comment-' . get_comment_ID() ); edit_comment_link(__('Edit', 'your-theme'), ' <span class="meta-sep">|</span> <span class="edit-link">', '</span>'); ?></div> <?php if ($comment->comment_approved == '0') _e("\t\t\t\t\t<span class='unapproved'>Your comment is awaiting moderation.</span>\n", 'your-theme') ?> <div class="comment-content"> <?php comment_text() ?> </div> <?php // echo the comment reply link if($args['type'] == 'all' || get_comment_type() == 'comment') : comment_reply_link(array_merge($args, array(

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 38 of 109

33

May 15, 2012 Copyright 2005-2012

'reply_text' => __('Reply','your-theme'), 'login_text' => __('Log in to reply.','your-theme'), 'depth' => $depth, 'before' => '<div class="comment-reply-link">', 'after' => '</div>' ))); endif; ?> <?php } // end custom_comments Listing 12.1

// Custom callback to list pings function custom_pings($comment, $args, $depth) { $GLOBALS['comment'] = $comment; ?> <li id="comment-<?php comment_ID() ?>" <?php comment_class() ?>> <div class="comment-author"><?php printf(__('By %1$s on %2$s at %3$s', 'your-theme'), get_comment_author_link(), get_comment_date(), get_comment_time() ); edit_comment_link(__('Edit', 'your-theme'), ' <span class="meta-sep">|</span> <span class="edit-link">', '</span>'); ?></div> <?php if ($comment->comment_approved == '0') _e('\t\t\t\t\t<span class="unapproved">Your trackback is awaiting moderation.</span>\n', 'your-theme') ?> <div class="comment-content"> <?php comment_text() ?> </div> <?php } // end custom_pings Listing 12.2

Those look kind of hairy dont they? But youre better off for it. Now you have access to the comments markup. I think the markup Ive got in there is pretty sweet and will let you make a lot of changes with just CSS alone, but if you do want to alter the markup, well, there it is. Well also need a special custom function that the custom_comments() is calling. This function will markup the gravatar were using so it fits into the microformat schema for hcard.
// Produces an avatar image with the hCard-compliant photo class function commenter_link() { $commenter = get_comment_author_link(); if ( ereg( '<a[^>]* class=[^>]+>', $commenter ) ) { $commenter = ereg_replace( '(<a[^>]* class=[\'"]?)', '\\1url ' , $commenter ); } else { $commenter = ereg_replace( '(<a )/', '\\1class="url "' , $commenter ); } $avatar_email = get_comment_author_email(); $avatar = str_replace( "class='avatar", "class='photo avatar", get_avatar( $avatar_email, 80 ) ); echo $avatar . ' <span class="fn n">' . $commenter . '</span>'; } // end commenter_link Listing 12.3

If you want to change the default size of your gravatar just change the 80 in get_avatar( $avatar_email, 80 ) ). The 80 is the size in pixels of your gravatar. THE COMMENTS TEMPLATE NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference May 15, 2012 Copyright 2005-2012

Pg 39 of 109

33

I havent scared you away have I? Heres the comments template with some helpful PHP comments that should guide you along in understanding whats happening.
<?php /* The Comments Template with, er, comments! */ ?> <div id="comments"> <?php /* Run some checks for bots and password protected posts */ ?> <?php $req = get_option('require_name_email'); // Checks if fields are required. if ( 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']) ) die ( 'Please do not load this page directly. Thanks!' ); if ( ! empty($post->post_password) ) : if ( $_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password ) : ?> <div class="nopassword"><?php _e('This post is password protected. Enter the password to view any comments.', 'your-theme') ?></div> </div><!-- .comments --> <?php return; endif; endif; ?> <?php /* See IF there are comments and do the comments stuff! */ ?> <?php if ( have_comments() ) : ?> <?php /* Count the number of comments and trackbacks (or pings) */ $ping_count = $comment_count = 0; foreach ( $comments as $comment ) get_comment_type() == "comment" ? ++$comment_count : ++$ping_count; ?> <?php /* IF there are comments, show the comments */ ?> <?php if ( ! empty($comments_by_type['comment']) ) : ?> <div id="comments-list" class="comments"> <h3><?php printf($comment_count > 1 ? __('<span>%d</span> Comments', 'your-theme') : __('<span>One</span> Comment', 'your-theme'), $comment_count) ?></h3> <?php /* If there are enough comments, build the comment navigation */ ?> <?php $total_pages = get_comment_pages_count(); if ( $total_pages > 1 ) : ?> <div id="comments-nav-above" class="comments-navigation"> <div class="paginated-comments-links"><?php paginate_comments_links(); ?></div> </div><!-- #comments-nav-above --> <?php endif; ?> <?php /* An ordered list of our custom comments callback, custom_comments(), in functions.php */ ?> <ol> <?php wp_list_comments('type=comment&callback=custom_comments'); ?> </ol> <?php /* If there are enough comments, build the comment navigation */ ?> <?php $total_pages = get_comment_pages_count(); if ( $total_pages > 1 ) : ?> <div id="comments-nav-below" class="comments-navigation"> <div class="paginated-comments-links"><?php paginate_comments_links(); ?></div> </div><!-- #comments-nav-below --> <?php endif; ?> </div><!-- #comments-list .comments --> <?php endif; /* if ( $comment_count ) */ ?> <?php /* If there are trackbacks(pings), show the trackbacks */ ?> <?php if ( ! empty($comments_by_type['pings']) ) : ?> <div id="trackbacks-list" class="comments"> <h3><?php printf($ping_count > 1 ? __('<span>%d</span> Trackbacks', 'your-theme') : __('<span>One</span> Trackback', 'your-theme'), $ping_count) ?></h3> <?php /* An ordered list of our custom trackbacks callback, custom_pings(), in functions.php */ ?> <ol> <?php wp_list_comments('type=pings&callback=custom_pings'); ?> </ol> </div><!-- #trackbacks-list .comments -->

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 40 of 109

33

May 15, 2012 Copyright 2005-2012

<?php endif /* if ( $ping_count ) */ ?> <?php endif /* if ( $comments ) */ ?> <?php /* If comments are open, build the respond form */ ?> <?php if ( 'open' == $post->comment_status ) : ?> <div id="respond"> <h3><?php comment_form_title( __('Post a Comment', 'your-theme'), __('Post a Reply to %s', 'your-theme') ); ?></h3> <div id="cancel-comment-reply"><?php cancel_comment_reply_link() ?></div> <?php if ( get_option('comment_registration') && !$user_ID ) : ?> <p id="login-req"><?php printf(__('You must be <a href="%s" title="Log in">logged in</a> to post a comment.', 'your-theme'), get_option('siteurl') . '/wp-login.php?redirect_to=' . get_permalink() ) ?></p> <?php else : ?> <div class="formcontainer"> <form id="commentform" action="<?php echo get_option('siteurl'); ?>/wp-commentspost.php" method="post"> <?php if ( $user_ID ) : ?> <p id="login"><?php printf(__('<span class="loggedin">Logged in as <a href="%1$s" title="Logged in as %2$s">%2$s</a>.</span> <span class="logout"><a href="%3$s" title="Log out of this account">Log out?</a></span>', 'your-theme'), get_option('siteurl') . '/wp-admin/profile.php', wp_specialchars($user_identity, true), wp_logout_url(get_permalink()) ) ?></p> <?php else : ?> <p id="comment-notes"><?php _e('Your email is <em>never</em> published nor shared.', 'your-theme') ?> <?php if ($req) _e('Required fields are marked <span class="required">*</span>', 'your-theme') ?></p> <div id="form-section-author" class="form-section"> <div class="form-label"><label for="author"><?php _e('Name', 'your-theme') ?></label> <?php if ($req) _e('<span class="required">*</span>', 'your-theme') ?></div> <div class="form-input"><input id="author" name="author" type="text" value="<?php echo $comment_author ?>" size="30" maxlength="20" tabindex="3" /></div> </div><!-- #form-section-author .form-section --> <div id="form-section-email" class="form-section"> <div class="form-label"><label for="email"><?php _e('Email', 'your-theme') ?></label> <?php if ($req) _e('<span class="required">*</span>', 'your-theme') ?></div> <div class="form-input"><input id="email" name="email" type="text" value="<?php echo $comment_author_email ?>" size="30" maxlength="50" tabindex="4" /></div> </div><!-- #form-section-email .form-section --> <div id="form-section-url" class="form-section"> <div class="form-label"><label for="url"><?php _e('Website', 'your-theme') ?></label></div> <div class="form-input"><input id="url" name="url" type="text" value="<?php echo $comment_author_url ?>" size="30" maxlength="50" tabindex="5" /></div> </div><!-- #form-section-url .form-section --> <?php endif /* if ( $user_ID ) */ ?> <div id="form-section-comment" class="form-section"> <div class="form-label"><label for="comment"><?php _e('Comment', 'your-theme') ?></label></div> <div class="form-textarea"><textarea id="comment" name="comment" cols="45" rows="8" tabindex="6"></textarea></div> </div><!-- #form-section-comment .form-section --> <div id="form-allowed-tags" class="form-section"> <p><span><?php _e('You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes:', 'your-theme') ?></span> <code><?php echo allowed_tags(); ?></code></p> </div> <?php do_action('comment_form', $post->ID); ?> <div class="form-submit"><input id="submit" name="submit" type="submit" value="<?php _e('Post Comment', 'your-theme') ?>" tabindex="7" /><input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" /></div> <?php comment_id_fields(); ?> <?php /* Just end everything. We're done here. Close it up. */ ?> </form><!-- #commentform --> </div><!-- .formcontainer --> <?php endif /* if ( get_option('comment_registration') && !$user_ID ) */ ?>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 41 of 109

33

May 15, 2012 Copyright 2005-2012

</div><!-- #respond --> <?php endif /* if ( 'open' == $post->comment_status ) */ ?> </div><!-- #comments --> Listing 12.4

And thats it. Youve got a pretty sweet custom Comments Template to call your very own.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 42 of 109

33

May 15, 2012 Copyright 2005-2012

Section 13 Search Template


The Search Template and The Page Template are vital to any complete WordPress Theme. And theyre both really easy to code. For both these two Templates well start with our template-template again.
<?php get_header(); ?> <div id="container"> <div id="content"> <div id="nav-above" class="navigation"> </div> <!-- #container --> <!-- #content --> <!-- #nav-above --> <!-- #nav-above --> <!-- #post --> <!-- #post -->

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?> > </div><!-- #post-<?php the_ID(); ?> --> <div id="nav-below" class="navigation"> </div> </div> </div> <?php get_sidebar(); ?> <?php get_footer(); ?> Listing 13.1 <!-- #nav-below --> <!-- #nav-below --> <!-- #content --> <!-- #container -->

But, of course, each one is going to take its own different path. THE SEARCH TEMPLATE In search.php were going to reintroduce the loop back into our Template. This time with an IF statementin case we dont have any posts to loop through. Heres how itll work: IF we have posts, or, in other words, if there are posts that match the terms were searching for, THEN loop through them, sorta just like in index.php, but IF we dont have posts to loop through, or, if there arent any posts that match our search terms, give our searchers another chance at this searching business. In code, it would look like this:
<?php get_header(); ?> <div id="container"> <div id="content"> <!-- #container --> <!-- #content -->

<?php if ( have_posts() ) : ?> <?php while ( have_posts() ) : the_post() ?> <!-- this is our loop --> <?php endwhile; ?> <?php else : ?> <!-- here's where we'll put a search form if there're no posts --> <?php endif; ?> </div> </div> <!-- #content --> <!-- #container -->

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 43 of 109

33

May 15, 2012 Copyright 2005-2012

<?php get_sidebar(); ?> <?php get_footer(); ?> Listing 13.2

Pretty straightforward, right? Almost. I like to keep all my index-ey Templates the same: Post Title, Meta, Content (or excerpt), Utility links. But when WordPress searches for posts it also searches through Pages, which dont need the post meta or utility links displayed. So, in our loop, were going to check and see if were dealing with a post or a page.
<?php if ( $post->post_type == 'post' ) { ?> <?php } ?> Listing 13.3

Wrap any code with that IF statement and it will only show if were dealing with a page. Now that we understand whats going on, heres what thecomplete search template will look like:
<?php if (have_posts()): ?> <h1 class="page-title"><?php _e('Search Results for: ', 'your-theme'); ?><span><?php the_search_query(); ?></span></h1> <?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ($total_pages > 1) { ?> <div id="nav-above" class="navigation"> <div class="nav-previous"><?php next_posts_link(__('<span class="meta-nav">&laquo;</span> Older posts', 'yourtheme')); ?></div> <div class="nav-next"><?php previous_posts_link(__('Newer posts <span class="meta-nav">&raquo;</span>', 'yourtheme')); ?></div> </div><!-- #nav-above --> <?php } ?> <?php while (have_posts()): the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf(__('Permalink to %s', 'your-theme'), the_title_attribute('echo=0')); ?>" rel="bookmark"><?php the_title(); ?></a></h2>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 44 of 109

33

May 15, 2012 Copyright 2005-2012

<?php if ($post->post_type == 'post') { ?> <div class="entry-meta"> <span class="meta-prep meta-prep-author"><?php _e('By ', 'your-theme'); ?></span> <span class="author vcard"><a class="url fn n" href="<?php echo get_author_link(false, $authordata->ID, $authordata->user_nicename); ?>" title="<?php printf(__('View all posts by %s', 'your-theme'), $authordata->display_name); ?>"><?php the_author(); ?></a></span> <span class="meta-sep"> | </span> <span class="meta-prep meta-prep-entry-date"><?php _e('Published ', 'your-theme'); ?></span> <span class="entry-date"><abbr class="published" title="<?php the_time('Y-m-d\TH:i:sO'); ?>"><?php the_time(get_option('date_format')); ?></abbr></span> <?php edit_post_link(__('Edit', 'your-theme'), "<span class=\"metasep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t"); ?> </div><!-- .entry-meta --> <?php } ?> <div class="entry-summary"> <?php the_excerpt(__('Continue reading <span class="meta-nav">&raquo;</span>', 'yourtheme')); ?> <?php wp_link_pages('before=<div class="page-link">' . __('Pages:', 'your-theme') . '&after=</div>'); ?> </div><!-- .entry-summary --> <?php if ($post->post_type == 'post') { ?> <div class="entry-utility"> <span class="cat-links"><span class="entry-utility-prep entry-utility-prep-catlinks"><?php _e('Posted in ', 'your-theme'); ?></span><?php echo get_the_category_list(', '); ?></span> <span class="meta-sep"> | </span> <?php the_tags('<span class="tag-links"><span class="entry-utility-prep entry-utilityprep-tag-links">' . __('Tagged ', 'your-theme') . '</span>', ", ", "</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n"); ?> <span class="comments-link"><?php comments_popup_link(__('Leave a comment', 'your-theme'), __('1 Comment', 'yourtheme'), __('% Comments', 'your-theme')); ?></span> <?php edit_post_link(__('Edit', 'your-theme'), "<span class=\"metasep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t\n");

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 45 of 109

33

May 15, 2012 Copyright 2005-2012

?> </div><!-- #entry-utility --> <?php } ?> </div><!-- #post-<?php the_ID(); ?> --> <?php endwhile; ?> <?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ($total_pages > 1) { ?> <div id="nav-below" class="navigation"> <div class="nav-previous"><?php next_posts_link(__('<span class="meta-nav">&laquo;</span> Older posts', 'yourtheme')); ?></div> <div class="nav-next"><?php previous_posts_link(__('Newer posts <span class="meta-nav">&raquo;</span>', 'yourtheme')); ?></div> </div><!-- #nav-below --> <?php } ?> <?php else: ?> <div id="post-0" class="post no-results not-found"> <h2 class="entry-title"><?php _e('Nothing Found', 'your-theme'); ?></h2> <div class="entry-content"> <p><?php _e('Sorry, but nothing matched your search criteria. Please try again with some different keywords.', 'your-theme'); ?></p> <?php get_search_form(); ?> </div><!-- .entry-content --> </div> <?php endif; ?> Listing 13.4 complete search template

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 46 of 109

33

May 15, 2012 Copyright 2005-2012

Section 14 Page Template


THE PAGE TEMPLATE We think of it as, well a page but WordPress treats it as a post out of chronological order. But what makes it useful is that it does not have the normal blog (post) content except comments are sometimes used. Ordinarily we dont use comments but if they are needed they can be added with a custom field with Name and Value of comments on the page. Heres what youll need for the complete Page Template:
<?php get_header(); ?> <div id="container"> <div id="content"> <?php the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?> > <h1 class="entry-title"><?php the_title(); ?></h1> <!-- #container --> <!-- #content -->

<!-- post --> <!-- page title -->

<div class="entry-content"> <!-- entry-content --> <?php the_content(); ?> <?php wp_link_pages('before=<div class="page-link">' . __( 'Pages:', 'yourtheme' ) . '&after=</div>') ?> <?php edit_post_link( __( 'Edit', 'your-theme' ), '<span class="edit-link">', '</span>' ) ?> </div> </div> the_ID(); ?> --> <!-- .entry-content --> <!-- #post-<?php

<!-- Add a custom field with Name and Value of "comments" to enable comments on this page --> <?php if ( get_post_custom_values('comments') ) comments_template() ?> </div> </div> <?php get_sidebar(); ?> <?php get_footer(); ?> Listing 14.1 <!-- #content --> <!-- #container -->

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 47 of 109

33

May 15, 2012 Copyright 2005-2012

Section 15 Archive Template


While index.php has served us well as a master template, we are going to need another one. What archive.php does (and all its related templates) is show posts based on a select criteria. A date range, or posts by a certain author, a category, or a tag. So, basically, its a lot like index.php. If you can read the name of the template you can figure out what its going to spit out. Lets start again with our template-template from the previous lessons and build on top of it.
<?php get_header(); ?> <div id="container"> <div id="content"> <div id="nav-above" class="navigation"> </div> <!-- #container --> <!-- #content --> <!-- #nav top --> <!-- end #nav top --> <!-- #post --> <!-- end #post -->

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?> > </div><!-- #post-<?php the_ID(); ?> --> <div id="nav-below" class="navigation"> </div><!-- #nav-below -</div><!-- #content --> </div><!-- #container --> <?php get_sidebar(); ?> <?php get_footer(); ?> Listing 15.1

<!-- #nav bottom --> <!end #nav bottom --> <!-- end #content --> <!-- end #container -->

THE ARCHIVE TEMPLATE Heres the scheme of an Archive Template: 1. 2. 3. 4. 5. Call the_post() Check to see what kind of template this is Produce an appropriate template Rewind the posts with rewind_posts() Do the usual loopy WordPress stuff

Heres the #content of your archive.php Template. Note the Conditional Tags at the top for checking to see what kind of template were in.
<?php get_header(); ?> <div id="container"> <div id="content"> <?php the_post(); ?> <?php if ( is_day() ) : ?> <h1 class="page-title"> <?php printf( __( 'Daily Archives: <span>%s</span>', 'shape' ), get_the_time(get_option('date_format')) ) ?> </h1>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 48 of 109

33

May 15, 2012 Copyright 2005-2012

<?php elseif ( is_month() ) : ?> <h1 class="page-title"> <?php printf( __( 'Monthly Archives: <span>%s</span>', 'shape' ), get_the_time('F Y') ) ?> </h1> <?php elseif ( is_year() ) : ?> <h1 class="page-title"> <?php printf( __( 'Yearly Archives: <span>%s</span>', 'shape' ), get_the_time('Y') ) ?> </h1> <?php elseif ( isset($_GET['paged']) && !empty($_GET['paged']) ) : ?> <h1 class="page-title"><?php _e( 'Blog Archives', 'shape' ) ?></h1> <?php endif; ?> <?php rewind_posts(); ?> <?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?> <div id="nav-above" class="navigation"> <div class="nav-previous"> <?php next_posts_link(__( '<span class="meta-nav">&laquo;</span> Older posts', 'shape' )) ?> </div> <div class="nav-next"> <?php previous_posts_link(__( 'Newer posts <span class="metanav">&raquo;</span>', 'shape' )) ?> </div> </div><!-- #nav-above --> <?php } ?> <?php while ( have_posts() ) : the_post(); ?> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <h2 class="entry-title"> <a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'shape'), the_title_attribute('echo=0') ); ?>" rel="bookmark"> <?php the_title(); ?> </a> </h2> <div class="entry-meta"> <span class="meta-prep meta-prep-author"><?php _e('By ', 'shape'); ?></span> <span class="author vcard"> <a class="url fn n" href=" <?php echo get_author_link( false, $authordata->ID, $authordata->user_nicename ); ?>" title="<?php printf( __( 'View all posts by %s', 'shape' ), $authordata->display_name ); ?>"><?php the_author(); ?> </a> </span> <span class="meta-sep"> | </span>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 49 of 109

33

May 15, 2012 Copyright 2005-2012

<span class="meta-prep meta-prep-entry-date"> <?php _e('Published ', 'shape'); ?> </span> <span class="entry-date"> <abbr class="published" title="<?php the_time('Y-m-d\TH:i:sO') ?>"> <?php the_time( get_option( 'date_format' ) ); ?> </abbr> </span> <?php edit_post_link( __( 'Edit', 'shape' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t" ) ?> </div><!-- .entry-meta --> <div class="entry-summary"> <?php the_excerpt( __( 'Continue reading <span class="meta-nav">&raquo;</span>', 'shape' ) ); ?> </div><!-- .entry-summary --> <div class="entry-utility"> <span class="cat-links"> <span class="entry-utility-prep entry-utility-prep-cat-links"> <?php _e( 'Posted in ', 'shape' ); ?> </span> <?php echo get_the_category_list(', '); ?> </span> <span class="meta-sep"> | </span> <?php the_tags( '<span class="tag-links"> <span class="entry-utility-prep entry-utility-prep-tag-links">' . __('Tagged ', 'shape' ) . '</span>', ", ", "</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n" ) ?> <span class="comments-link"> <?php comments_popup_link( __( 'Leave a comment', 'shape' ), __( '1 Comment', 'shape' ), __( '% Comments', 'shape' ) ) ?> </span> <?php edit_post_link( __( 'Edit', 'shape' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t\n" ) ?> </div><!-- #entry-utility --> </div><!-- #post-<?php the_ID(); ?> --> <?php endwhile; ?> <?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?> <div id="nav-below" class="navigation"> <div class="nav-previous"> <?php next_posts_link(__( '<span class="meta-nav">&laquo;</span> Older posts', 'shape' )) ?> </div> <div class="nav-next"> <?php previous_posts_link(__( 'Newer posts <span class="meta-nav">&raquo;</span>',

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 50 of 109

33

May 15, 2012 Copyright 2005-2012

'shape' )) ?> </div> </div><!-- #nav-below --> <?php } ?> </div><!-- #content --> </div><!-- #container --> <?php get_sidebar(); ?> <?php get_footer(); ?> Listing 15.2

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 51 of 109

33

May 15, 2012 Copyright 2005-2012

Section 16 Author Template


THE AUTHOR TEMPLATE Not a lot is going to change with our Author Template. Youre going to like this one. Copy archive.php and rename it author.php. All we need to change is the page title section.
<h1 class="page-title author"> <?php printf( __( 'Author Archives: <span class="vcard">%s</span>', 'your-theme' ), "<a class='url fn n' href='$authordata->user_url' title='$authordata->display_name' rel='me'>$authordata->display_name</a>" ) ?> </h1> <?php $authordesc = $authordata->user_description; if ( !empty($authordesc) ) echo apply_filters( 'archive_meta', '<div class="archivemeta">' . $authordesc . '</div>' ); ?> Listing 16.1

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 52 of 109

33

May 15, 2012 Copyright 2005-2012

Section 17 Category Template


The Category Template is another simple template now that we have a proper Archive Template. Copy archive.php and rename it category.php. Now open up functions.php. Were going to drop a custom functionfrom the brilliant Sandbox Themein there thats going to make our Category Template a little more usable.
// For category lists on category archives: Returns other categories except the current one (redundant) function cats_meow($glue) { $current_cat = single_cat_title( '', false ); $separator = "\n"; $cats = explode( $separator, get_the_category_list($separator) ); foreach ( $cats as $i => $str ) { if ( strstr( $str, ">$current_cat<" ) ) { unset($cats[$i]); break; } } if ( empty($cats) ) return false; return trim(join( $glue, $cats )); } // end cats_meow Listing 17.1

Our custom function cats_meow() removes the current category from category pages. In other words, it gets rid of redundant categories in that list of categories we have just underneath the excerpt of our post. Now, back in category.php, replace the page title section with the following code:
<h1 class="page-title"> <?php _e( 'Category Archives:', 'your-theme' ) ?> <span><?php single_cat_title() ?></span></span> </h1> <?php $categorydesc = category_description(); if ( !empty($categorydesc) ) { echo apply_filters( 'archive_meta', '<div class="archive-meta">' . $categorydesc . '</div>' ); ?> Listing 17.2

And in the .entry-utility div, replace


<span class="cat-links"><span class="entry-utility-prep entry-utility-prep-catlinks"><?php _e( 'Posted in ', 'your-theme' ); ?></span><?php echo get_the_category_list(', '); ?></span> Listing 17.3

with the modified


<?php if ( $cats_meow = cats_meow(', ') ) : // Returns categories other than the one queried ?> <span class="cat-links"><?php printf( __( 'Also posted in %s', 'your-theme' ), $cats_meow ) ?></span> <span class="meta-sep"> | </span>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 53 of 109

33

May 15, 2012 Copyright 2005-2012

<?php endif ?> Listing 17.4

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 54 of 109

33

May 15, 2012 Copyright 2005-2012

Section 18 Tags Template


THE TAGS TEMPLATE The Tags Template is almost identical to the Category Template, except, well, its for Tags. You know the drill: copy archive.php and rename it tag.php. Weve also got a custom functionagain, from the brilliant Sandbox Themefor our functions.php called tag_ur_it(). It works just like cats_meow() except it removes redundant tags.
// For tag lists on tag archives: Returns other tags except the current one (redundant) function tag_ur_it($glue) { $current_tag = single_tag_title( '', '', false ); $separator = "\n"; $tags = explode( $separator, get_the_tag_list( "", "$separator", "" ) ); foreach ( $tags as $i => $str ) { if ( strstr( $str, ">$current_tag<" ) ) { unset($tags[$i]); break; } } if ( empty($tags) ) return false; return trim(join( $glue, $tags )); } // end tag_ur_it Listing 10.8

Now, in tag.php, replace your page title with:


<h1 class="page-title"> <?php _e( 'Tag Archives:', 'your-theme' ) ?> <span><?php single_tag_title() ?> </span> </h1> Listing 10.9

and in .entry-utility, replace


<?php the_tags( '<span class="tag-links"> <span class="entry-utility-prep entry-utility-prep-tag-links">' . __('Tagged ', 'yourtheme' ) . '</span> ', ", ", " </span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span> \n" ) ?> Listing 10.10

with the modified


<?php if ( $tag_ur_it = tag_ur_it(', ') ) : // Returns tags other than the one queried ?> <span class="tag-links"><?php printf( __( 'Also tagged %s', 'your-theme' ), $tag_ur_it ) ?></span> <?php endif; ?> Listing 10.11

And thats it! NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference May 15, 2012 Copyright 2005-2012

Pg 55 of 109

33

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 56 of 109

33

May 15, 2012 Copyright 2005-2012

Section 19 Sidebar Template


As this article is somewhat older and perhaps even past its prime, please proceed with a sense of adventure and in a spirit of good cheer. There are some amazing ideas here but the code may need some tender love and care. Good luck!

I know youve been waiting patiently for this one. Everybody loves the Sidebar Template. But were going to do ours a little differently than everyone else. Ours is going to be better. CUSTOM SIDEBAR FUNCTIONS First things first. With a WordPress Sidebar Template, we need to make sure its widgetized. Ours is going to have two widget areas. That way we can re-use this code for 2-column or 3-column themes (on a 2-column theme the sidebars are stacked, one on top of the other). This is pretty straightforward. In our functions.php file were going to register our widget areas with the following code.
// Register widgetized areas function theme_widgets_init() { // Area 1 register_sidebar( array ( 'name' => 'Primary Widget Area', 'id' => 'primary_widget_area', 'before_widget' => '<li id="%1$s" class="widget-container %2$s">', 'after_widget' => "</li>", 'before_title' => '<h3 class="widget-title">', 'after_title' => '</h3>', ) ); // Area 2 register_sidebar( array ( 'name' => 'Secondary Widget Area', 'id' => 'secondary_widget_area', 'before_widget' => '<li id="%1$s" class="widget-container %2$s">', 'after_widget' => "</li>", 'before_title' => '<h3 class="widget-title">', 'after_title' => '</h3>', ) ); } // end theme_widgets_init add_action( 'init', 'theme_widgets_init' ); Listing 11.1

Now weve got two widget areas: Primary Widget Area and Secondary Widget Area. Theres no point naming them Primary Sidebar or Secondary Sidebar. In some layouts they might not even be sidebarsbut theyll always be widget areas. Now, still in functions.php were going to add two more super-cool custom code snippets. Firstly, were going to pre-set our default widgets: The Search, Pages, Categories, Archives, Links and Meta Widgets. We wont be coding them in manually to sidebar.php. Well be telling WordPress to add them to our dynamic widget area in the settings (thank Ptah Dunbar for this).
$preset_widgets = array (

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 57 of 109

33

May 15, 2012 Copyright 2005-2012

'primary_widget_area' => array( 'search', 'pages', 'categories', 'archives' ), 'secondary_widget_area' => array( 'links', 'meta' ) ); if ( isset( $_GET['activated'] ) ) { update_option( 'sidebars_widgets', $preset_widgets ); } // update_option( 'sidebars_widgets', NULL ); Listing 11.2

Now, in our Primary Widget Area (primary_widget_area) weve got the Search Widget, the Pages Widget, the Categories Widget, and the Archives Widget. The Secondary Widget Area (secondary_widget_area) has the Links and Meta Widgets. Theyre all loaded up there in our WordPress options, ready and waiting. Did you see // update_option( 'sidebars_widgets', NULL ); in the last line? Uncomment that line if you need to reset your widgets for any reason. As Im sure you can guess, NULL means no widgets. Now secondly, were going to create a new conditional that will check to see if there are any widgets in a given widget area. This will be incredibly useful (with props to Chaos Kaizer) when we code up our Sidebar Template.
// Check for static widgets in widget-ready areas function is_sidebar_active( $index ){ global $wp_registered_sidebars; $widgetcolums = wp_get_sidebars_widgets(); if ($widgetcolums[$index]) return true; return false; } // end is_sidebar_active Listing 11.3

Now we need to put these custom code snippets to work. CODING THE SIDEBAR TEMPLATE With our dynamic widget areas registered and pre-set widgets, our Sidebar Template is going to be one of the simplest templates youll ever see. But remember, were also going to want to wrap our sidebars in an IF statement using our new conditional is_sidebar_active(). Heres what itll look like:
<?php if ( is_sidebar_active('primary_widget_area') ) : ?> <div id="primary" class="widget-area"> <ul class="xoxo"> <?php dynamic_sidebar('primary_widget_area'); ?> </ul> </div><!-- #primary .widget-area --> <?php endif; ?> <?php if ( is_sidebar_active('secondary_widget_area') ) : ?> <div id="secondary" class="widget-area"> <ul class="xoxo"> <?php dynamic_sidebar('secondary_widget_area'); ?> </ul> </div><!-- #secondary .widget-area --> <?php endif; ?> Listing 11.4

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 58 of 109

33

May 15, 2012 Copyright 2005-2012

Now if you go into the widget admin page and pull all those widgets out of any one of those widget areas the conditional statement guarding the markup will fail. Big time. And to our benefit. No widgets. No markup. Dead simple. Just the way we like things around here.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 59 of 109

33

May 15, 2012 Copyright 2005-2012

Section 21 Reset & Rebuild CSS


CSS can be tricky. It can also be incredibly easy. I had a lot of help getting my head wrapped around CSS when I was first starting out and I take great pleasure in helping others the same way I was first helped: with solid code examples to learn from. Here were going to layout a WordPress Theme CSS development arsenal for you: A stylesheet that resets default CSS across all web browsers and makes a sane standard we can work from Another stylesheet that rebuilds our typographical foundations in a smart way A stylesheet just for WordPress classes (keeping the first two pure so we can use them for nonWordPress projects) A series of 6 fluid stylesheets that will create ALL the common blog and website layouts you expectand each one ready to adapt into a fixed width layout. All the code well talk about is open-source, under the GPL, and browse-able at the Your Theme Project Page. View the raw source for any one of these files and copy-paste at your leisure. First things first, make a style directory in your Theme folder. Thats where well be putting everything. Your CSS quiver, as it were. Ready to hit the target? RESET CSS Our Reset CSS is adapted from Eric Meyers famous Reset CSS with some minor, minor changes. Basically what it does is take all the typographical defaults of every browser and obliterates them. Youre left with a squashy, gray mess. Its beautiful. What this does is equalize the rendering of every browser, leaving you free to ignore countless individual quirks particular to each one. Using it is simple. Add the following lines to your style.css, at the very top, immediately after the initial comments section.
/* Reset default browser styles */ @import url('styles/reset.css'); Listing 12.1

Reload, your page and check it what reset.css does in multiple browsers (if you can). Its wonderfully gross, isnt it? REBUILD CSS Our Rebuild CSS is my own personal invention adapted from an early version of the Blueprint CSS typography stylesheet and refined in the Thematic Project. What it does is swing back some vertical rhythm in our pages, but in a really smart way.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 60 of 109

33

May 15, 2012 Copyright 2005-2012

What Ive tried to do with this iteration of my typography-rebuild CSS is combine the best of both worlds for web typography: using Pixels for font height, with relative line-height for the main declaration on the body element, and Ems for all subsequent vertical margins (like for paragraphs and lists). What does this mean? Its really easy to set your font height laterwithout doing any math workand have all of your typographical elements follow suit with an appropriate vertical rhythm (the vertical space between type elements like paragraphs and lists). Using rebuild.css is also really easy. Just add the following lines immediately after your reset.css import.
/* Rebuild default browser styles */ @import url('styles/rebuild.css'); Listing 12.2

THE BASIC WORDPRESS STYLES There are some elements in WordPress that youre just going to have to style every time. What Ive done is taken those styles and put them in there own little corner called wp.css. Right now, what weve got in there are styles for floating all the imagesincluding handling captions and image galleries. And! preset styles for simple pull-quotes. All you need to do is add a class of left or right to the blockquote tag and youre ready to roll. Can you guess how were going to use wp.css?
/* Basic WordPress Styles */ @import url('styles/wp.css'); Listing 12.3

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 61 of 109

33

May 15, 2012 Copyright 2005-2012

Section 22 Custom Defined Layouts


ALL THE LAYOUTS YOULL EVER NEED For your new theme, Ive taken the rock-solid, indestructible layouts that shipped with the Sandbox Theme and adapted them for your new HTML structure. There are 6 in total. Each is a fluid layout (that stretches to fill the width of your browser window) but each one is easily adaptable to a fixed width layout. Using anyone of these layouts is simple. Immediately after your basic WordPress styles import, import one of these layouts. Heres how to import the 3 column layout, with the content in the center.
/* Import a basic layout */ @import url('styles/3c-b.css'); Listing 13.1

The simplest method of turning any one of these layouts into a fixed-width layout is to add a width and centering margin to the #wrapper div.
#wrapper { margin: 0 auto; width: 960px; } Listing 13.2

STYLING THE MENU If youve never taken an unordered list (thats the smart markup generated by wp_page_menu) and styled it to look like a menu before it can seem kinda weird. As a bonus, heres the CSS I use when I start out creating menus for WordPress Themes.
#access { margin: 0 0 1.5em 0; overflow: auto; } .skip-link { position:absolute; left:-9000px; } .menu ul { list-style: none; margin: 0; } .menu ul ul { display: none; } .menu li { display: inline; } .menu a { display: block; float: left; } Listing 13.3

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 62 of 109

33

May 15, 2012 Copyright 2005-2012

Section 23 Custom Post Types


http://codex.wordpress.org/Post_Types

DEFAULT TYPES
For referance, here are the five major types that WordPress uses by default.

Post

A "post" in WordPress is the main type used by the blog. Posts are normally displayed in the blog in reverse sequential order by time (newest posts first). Posts are also used for creating the feeds.
A "page" in WordPress is like a post, but it lives outside the normal time based structure of posts. They have their own URLs directly off the main site URL. They can also use special Page Templates to display them. Pages can also be organized in a hierarchical structure, with Pages being parents to other Pages. An "attachment" is a special post that holds information about files uploaded through the Media upload system. They hold all the description and name and other information about uploaded files. For images, this is also linked to metadata information about the size of the images and thumbnails generated from the images, the location of the files, and even information obtained from EXIF data embedded in the images. A "revision" is used to hold draft posts as well as any past revisions of existing posts or pages. These are basically identical to the main post/page that they are for, but have that post/page as their parent. The "nav_menu_item" type holds information about a single item in the Navigation Menu system. These are the first examples of entries in the posts table to be used for something other than an otherwise displayable content on the blog.

Page

Attachment

Revisions

Nav Menus

CUSTOM TYPES
Adding a custom type to WordPress is done via the register_post_type function. This function allows you to define the post type and how it operates within WordPress. Here's a basic example of adding a custom post type:
add_action( 'init', 'create_post_type' ); function create_post_type() { register_post_type( 'acme_product', array( 'labels' => array( 'name' => __( 'Products' ), 'singular_name' => __( 'Product' ) ), 'public' => true, 'has_archive' => true, ) ); }

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 63 of 109

33

May 15, 2012 Copyright 2005-2012

This creates a post type named "Product". It has two major arguments with it. The first one is the "labels", which define the name of the type in both plural and singular forms. The second one is "public", which is a predefined flag to show the post type in the admin section and to make it show up on the main site itself, if it's queried for. There are many more parameters you can add to the register_post_type function, to do things like set up hierarchy, show the new post type in searches, change the URLs of the new posts, and to hide or show meta boxes in the post editing screen. These parameters are optional, and you can use them to configure your post type on a detailed level.

NAMING BEST PRACTICES


While it's convenient to name your custom post type a simple name like "product" which is consistent with the core post types "post", "page", "revision", "attachment" and "nav_menu_item", it is better if you prefix your name with a short "namespace" that identifies your plugin, theme or website that implements the custom post type. For example: "acme_product" or "aw_product" - Products post type used by hypothetical ACMEWidgets.com. "eightfold_product" or "eft_product" - Products post type provided by the hypothetical "EightFold" Theme. "ai1m_product" - Products post type provided by the hypothetical "All-in-One Merchant" Plugin. Without namespacing of your custom post types your website's post types will more likely conflict with custom post types defined in a theme you fall in love with later or a plugin you realize that you absolutely need to use. Or if you are developing custom post types or themes there's a much greater chance your plugin or theme will conflict with custom post types defined in other plugins or themes and/or custom post types defined for your prospective user's website. Namespacing your custom post type won't guarantee against conflicts but will certainly minimize their likelihood. Do pay close attention to not having your namespace exceed 20 characters though, as the post_type column in the DB is currently a varchar field of the latter length.

RESERVED POST TYPE NAMES


Although the core development team has yet to make a final decision on this, it has been proposed on the wphackers list that future core post type names will be namespaced with "wp_", i.e. if the core team decides to add an "Event" post type then according to this suggestion they would use the internal name "wp_event." Even though this hasn't been finalized, it'll be a good idea to avoid any custom post types whose name begins with "wp_."

ADMIN UI
When a post type is created like this, it gets a new top level entry in the Admin section to create posts of that new type. From there, you'll have a full post editor and everything that comes along with it by default. You can customize the UI for a post type with several hooks and filters, see this Custom Post Type snippets post by Yoast for an explanation and code examples.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 64 of 109

33

May 15, 2012 Copyright 2005-2012

URLS
The new post type will also get its own special section of the site layout. In the above example, posts of this new "product" type can be displayed at http://example.com/product/%product_name% (where %product_name% is the URL-ized name of your product, i.e. http://example.com/product/foobrozinator.) You can see this link appear in the edit pages for your new type, just like other posts.

URLS WITH NAMESPACED CUSTOM POST TYPES


When you namespace a URL and still want to use a "clean" URL structure, you need to add the "rewrite" element to the array. For example, assuming the "ACME Widgets" example from above:
add_action( 'init', 'create_post_type' ); function create_post_type() { register_post_type( 'acme_product', array( 'labels' => array( 'name' => __( 'Products' ), 'singular_name' => __( 'Product' ) ), 'public' => true, 'has_archive' => true, 'rewrite' => array('slug' => 'products') ) ); }

The above will result in a URL like http://example.com/products/%product_name% (see description of %product_name% above.) Note that we used a plural form here which is a format that some people prefer because it implies a more logical URL for a page that embeds a list of products, i.e. http://example.com/products/. Also note using a generic name like "products" here can potentially conflict with other plugins or themes that use the same name but most people would dislike longer and more obscure URLs like http://example.com/acme_products/foobrozinator and resolving the URL conflict between two plugins is easier simply because the URL structure is not stored persistently in each post record in the database in the same way custom post type names are stored.

TEMPLATE FILES
The theme system supports post types too. WordPress added support for single-type-template in Version 3.0 and for archive-type-template in Version 3.1. Note: In some cases the permalink structure must be updated in order for the new template files to be accessed when viewing a custom post type. To do this go to the permalink menu, change the option to a different option, save the changes, and change it back to the desired option.

SINGLE TEMPLATE
In the form of the single-type-template. In the same way that posts are shown on their own page with single.php, custom post types will use single-{posttype}.php if it's available.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 65 of 109

33

May 15, 2012 Copyright 2005-2012

So for the above example, you could create a single-acme_product.php file and the product posts would be shown using that template.

ARCHIVE TEMPLATE
In the form of the archive-type-template. In the same way that posts are shown on their own archive with archive.php, custom post types will use archive-{posttype}.php if it's available. So for the above example, you could create a archive-acme_product.php file and the product posts would be shown using that template. Note: Use the is_post_type_archive() function to check if the query shows post type archive page, and the post_type_archive_title() to echo the post type title.

QUERYING BY POST TYPE


In the rest of the theme system, you can also create new queries to display posts from a specific post type. This is done via the "post_type" parameter to a WP_Query. Example:
$args = array( 'post_type' => 'product', 'posts_per_page' => 10 ); $loop = new WP_Query( $args ); while ( $loop->have_posts() ) : $loop->the_post(); the_title(); echo '<div class="entry-content">'; the_content(); echo '</div>'; endwhile;

This simply loops through the latest 10 product posts and displays the title and content of them.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 66 of 109

33

May 15, 2012 Copyright 2005-2012

Section 24 Theme File Execution Hierarchy


http://wp.tutsplus.com/tutorials/the-wordpress-theme-files-execution-hierarchy/

This article will show the WordPress theme file execution hierarchy. In short, well look at which files get served up when you load a page in WordPress. You might already know that detail post is served by single.php and detail page is served by page.php, but WordPress will search for different files depending on a variety of factors, so well be looking at how this works! First thing we should establish is this: without index.php and style.css your theme is no longer a valid WordPress theme so it stands to reason that if all you have is those two files, each page will you try to load will be served up by index.php. Take a quick peek at this cheatsheet to see what Im referring to:

Notice that the flow for each page types will end up with the index.php. That is the reason why index.php is required file for the WordPress theme. If we are missing any other files in WordPress theme (for instance, if there is no search.php file included in the theme), then index.php will be served instead.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 67 of 109

33

May 15, 2012 Copyright 2005-2012

Now lets look at some details about the execution order. I am going to show you the flow in which WordPress will search for files in your active theme folder. I hope this will be useful when you create a WordPress theme from now on: I will go through each type of files one by one and will show the execution hierarchy for the same.

HOME PAGE

This is the first and most important page of any website. So WordPress has provided the scope to customize the page. Lets have a look at the file hierarchy for the home page. 1. front-page.php 2. home.php 3. index.php While serving the home page, WordPress will search for front-page.php. If that is not found, it will use home.php. If home.php exists, itll use that. If not, it will simply default to using index.php. Note: home.php always refers to the home of the default blog, which need not to be on the actual homepage. By default the blog of posts sits on the homepage, but if it doesnt, then home.php is never used on the frontpage, but on the page the blog sits on.

WORDPRESS POST DETAIL

1. single-[post-type].php 2. single.php 3. index.php WordPress can have as many post types as we need. So this will be easier to get different design for all/some post types. By default post is the main and default post type of the WordPress. So for example, if your custom post type is product then it will be single-product.php To know more how to add new post types in WordPress you can refer to this link.

WORDPRESS PAGE DETAIL

1. 2. 3. 4.

[custom-template].php page-[slug].php page-[id].php page.php


Pg 68 of 109 33 May 15, 2012 Copyright 2005-2012

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

5. index.php

Just the same as with post types, we can have a different page layout using the custom page template. So WordPress first searches for the files of the selected Page template (if it exists). If none are found, it will search for the file with the slug of the current page. Basically, if the slug is aboutus, then it will search for the file page-aboutus.php in active theme folder. WordPress will search for the files with the ID just like searching for the files with slug.

CATEGORY PAGE

1. 2. 3. 4. 5.

category-[slug].php category-[id].php category.php archive.php index.php

From the above flow, you can understand that how you can have different templates used for the category page. For instance, you could have a custom page based on slug and id, and then use a default category.php file for the rest of your categories..

TAG PAGE

1. 2. 3. 4. 5.

tag-[slug].php tag-[id].php tag.php archive.php index.php

This will be same case as the category. You can have different pages for tag slug and tag id also.
NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference May 15, 2012 Copyright 2005-2012

Pg 69 of 109

33

TAXONOMY PAGE

1. 2. 3. 4. 5.

taxonomy-[tax]-[term].php taxonomy-[tax].php taxonomy.php archive.php index.php

Here goes the different file hierarchy for the taxonomy Pages.

AUTHOR PAGE

1. 2. 3. 4. 5.

author-[author-nicname].php author-[author-id].php author.php archive.php index.php

Here you come to know that you can have different designs based on users also. Same as category and tags we can have different files based on slug and ID of the user.

ATTACHMENT PAGE

1. 2. 3. 4.

[mime-type].php attachment.php single.php index.php

Here you can see that you can have different page layout for different types of attachment. These can be differentiate from the mime type of the attached file.

DATE PAGE

1. date.php 2. archive.php 3. index.php For the date specific layout we can create date.php in theme folder. Then the flow goes to archive.php and then at last index.php.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 70 of 109

33

May 15, 2012 Copyright 2005-2012

ARCHIVE PAGE

1. archive.php 2. index.php As we come downwards to the type of files, number of files are reduced in the hierarchy. So this are the basic or we can say most used files in any WordPress themes.

SEARCH PAGE

1. search.php 2. index.php You can customize your search result with the search.php first. If search.php is not available then index.php will be served.

404 PAGE

1. 404.php 2. index.php In the case of page or post not found, WordPress will search for 404.php then if not found then it will serve index.php.

SINGLE PAGE CATEGORIES

theres on thing lacking in the hierarchy of WordPress in my opinion; a template for single pages of certain categories. I search and found the code to implement this:
add_filter(single_template, create_function($t, foreach( (array) get_the_category() as $cat ) { if ( file_exists(TEMPLATEPATH . /single-{$cat->category_nicename}.php) ) return TEMPLATEPATH . /single-{$cat->category_nicename }.php; } return $t; ));

CONCLUSION

You can obviously use this information in a wide range of ways to load up custom templates for various pages In many cases, even if youre using an existing theme, you can get a custom solution without modifying the existing files. You will just need to create new file and give it a new name using the information above.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 71 of 109

33

May 15, 2012 Copyright 2005-2012

Appendix A Microformat
WHAT IS MICROFORMATS Microformats are simple conventions (known as entities) used on web pages to describe a specific type of information for example, a review, an event, a product, a business, or a person. Each entity has its own properties. For example, a Person has the properties name, address, job title, company, and email address. USING MICROFORMATS WITH HTML TAGS In general, microformats use the class attribute in HTML tags (often <span> or <div>) to assign brief and descriptive names to entities and their properties. Here's an example of a short HTML block showing basic contact information for Bob Smith.
<div> <img src="www.example.com/bobsmith.jpg" /><br> <strong>Bob Smith</strong><br> Senior editor at ACME Reviews<br> 200 Main St<br> Desertville, AZ 12345<br> </div>
Listing A.1

Here is the same HTML marked up with the hCard (Person) microformat.
<div class="vcard"> <img class="photo" src="www.example.com/bobsmith.jpg" /> <strong class="fn">Bob Smith</strong> <span class="title">Senior editor</span> at <span class="org">ACME Reviews</span> <span class="adr"> <span class="street-address">200 Main St</span> <span class="locality">Desertville</span>, <span class="region">AZ</span> <span class="postal-code">12345</span> </span> </div>
Listing A.2

Here's how this sample works. In the first line, class="vcard" indicates that the HTML enclosed in the <div> describes a Person. (The microformat used to describe people is called hCard and is referred to in HTML as vcard. This isn't a typo.) The sample describes properties of the Person item, such as a photo, name, title, organization, and address. To label properties about the person described by the vcard, each element containing one of these properties (such as <span>, <img>, or <title>) is assigned a class attribute indicating a property. For example, fn describes a person's name; title describes job title. (The Help article for each information type includes a full list of recognized properties.)

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 72 of 109

33

May 15, 2012 Copyright 2005-2012

Properties can contain other properties. In the example above, the property adr describes the address of the person, and includes the subproperties street-address, locality, region and postal-code).

APPENDIX B TEMPLATE HIERARCHY TEMPLATE FILES LIST


Here is the list of the Theme files recognized by WordPress. Of course, your Theme can contain any other stylesheets, images, or files. Just keep in mind that the following have special meaning to WordPress -- see Template Hierarchy for more information. style.css The main stylesheet. This must be included with your Theme, and it must contain the information header for your Theme. rtl.css The rtl stylesheet. This will be included automatically if the website's text direction is right-to-left. This can be generated using the the RTLer plugin. index.php The main template. If your Theme provides its own templates, index.php must be present. comments.php The comments template. front-page.php The front page template, it is only used if you use a static front page. home.php The home page template, which is the front page by default. If you use a static front page this is the template for the page with the latest posts. single.php The single post template. Used when a single post is queried. For this and all other query templates, index.php is used if the query template is not present. single-<post-type>.php The single post template used when a single post from a custom post type is queried. For example, singlebooks.php would be used for displaying single posts from the custom post type books. index.php is used if the query template for the custom post type is not present. page.php The page template. Used when an individual Page is queried. category.php The category template. Used when a category is queried. tag.php The tag template. Used when a tag is queried. taxonomy.php

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 73 of 109

33

May 15, 2012 Copyright 2005-2012

The term template. Used when a term in a custom taxonomy is queried. author.php The author template. Used when an author is queried. date.php The date/time template. Used when a date or time is queried. Year, month, day, hour, minute, second. archive.php The archive template. Used when a category, author, or date is queried. Note that this template will be overridden by category.php, author.php, and date.php for their respective query types. search.php The search results template. Used when a search is performed. attachment.php Attachment template. Used when viewing a single attachment. image.php Image attachment template. Used when viewing a single image attachment. If not present, attachment.php will be used. 404.php The 404 Not Found template. Used when WordPress cannot find a post or page that matches the query.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 74 of 109

33

May 15, 2012 Copyright 2005-2012

THE TEMPLATE HIERARCHY IN DETAIL The following sections describe the order in which template files are being called by WordPress for each query type. HOME PAGE DISPLAY 1. home.php 2. index.php

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 75 of 109

33

May 15, 2012 Copyright 2005-2012

FRONT PAGE DISPLAY 1. front-page.php - Used for both Your latest posts or A static page as set in the Front page displays section of Settings -> Reading 2. Page display rules - When Front page is set in the Front page displays section of Settings -> Reading 3. Home Page display rules - When Posts page is set in the Front page displays section of Settings -> Reading SINGLE POST DISPLAY 1. single-{post_type}.php - If the post type were product, WordPress would look for single-product.php. 2. single.php 3. index.php PAGE DISPLAY 1. custom template file - The Page Template assigned to the Page. See get_page_templates(). 2. page-{slug}.php - If the page slug is recent-news, WordPress will look to use page-recent-news.php 3. page-{id}.php - If the page ID is 6, WordPress will look to use page-6.php 4. page.php 5. index.php CATEGORY DISPLAY 1. category-{slug}.php - If the category's slug were news, WordPress would look for category-news.php 2. category-{id}.php - If the category's ID were 6, WordPress would look for category-6.php 3. category.php 4. archive.php 5. index.php TAG DISPLAY 1. tag-{slug}.php - If the tag's slug were sometag, WordPress would look for tag-sometag.php 2. tag-{id}.php - If the tag's ID were 6, WordPress would look for tag-6.php 3. tag.php 4. archive.php 5. index.php CUSTOM TAXONOMIES DISPLAY 1. taxonomy-{taxonomy}-{slug}.php - If the taxonomy were sometax, and taxonomy's slug were someterm WordPress would look for taxonomy-sometax-someterm.php. In the case of Post Formats, the taxonomy is 'post_format' and the terms are 'post-format-{format}. i.e. taxonomy-post_format-post-format-link.php 2. taxonomy-{taxonomy}.php - If the taxonomy were sometax, WordPress would look for taxonomy-sometax.php 3. taxonomy.php 4. archive.php 5. index.php CUSTOM POST TYPES DISPLAY 1. archive-{post_type}.php - If the post type were product, WordPress would look for archive-product.php. 2. archive.php 3. index.php (when displaying a single custom post type see the Single Post display section above.) AUTHOR DISPLAY 1. author-{nicename}.php - If the author's nice name were rami, WordPress would look for author-rami.php. 2. author-{id}.php - If the author's ID were 6, WordPress would look for author-6.php. 3. author.php 4. archive.php 5. index.php DATE DISPLAY 1. date.php 2. archive.php 3. index.php

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 76 of 109

33

May 15, 2012 Copyright 2005-2012

SEARCH RESULT DISPLAY 1. search.php 2. index.php 404 (NOT FOUND) DISPLAY 1. 404.php 2. index.php ATTACHMENT DISPLAY 1. MIME_type.php - it can be any MIME type (image.php, video.php, application.php). For text/plain, in order: 1. text.php 2. plain.php 3. text_plain.php 2. attachment.php 3. single-attachment.php 4. single.php 5. index.php

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 77 of 109

33

May 15, 2012 Copyright 2005-2012

Appendix C XFN Protocol


XFN (XHTML Friends Network) is a simple way to represent human relationships using hyperlinks. In recent years, blogs and blogrolls have become the fastest growing area of the Web. XFN enables web authors to indicate their relationship(s) to the people in their blogrolls simply by adding a 'rel' attribute to their <a href> tags. INTRODUCTION XFN puts a human face on linking. As more people have come online and begun to form social networks, services such as Technorati and Feedster have arisen in an attempt to show how the various nodes are connected. Such services are useful for discovering the mechanical connections between nodes, but they do not uncover the human relationships between the people responsible for the nodes. XFN outlines the relationships between individuals by defining a small set of values that describe personal relationships. In HTML and XHTML documents, these are given as values for the rel attribute on a hyperlink. XFN allows authors to indicate which of the weblogs they read belong to friends, whom they've physically met, and other personal relationships. Using XFN values, which can be listed in any order, people can humanize their blogrolls and links pages, both of which have become a common feature of weblogs. In sufficiently modern browsers, authors using XFN can easily style all links of a particular type; thus, friends could be boldfaced, co-workers italicized, and so on. It is also the hope of the authors that this practice becomes widespread enough to allow the creation of a service that charts personal (as opposed to purely mechanical) links between weblogs and the people responsible for them. EXAMPLES A SHORT BLOGROLL Joe is just getting started in the blogging world, and has a set of five links in his blogroll: his girlfriend Jane; his friends Dave and Darryl; industry expert James, who Joe briefly met once at a conference; and MetaFilter. The links in Joe's blogroll would look something like this:
<a href="http://jane-blog.example.org/" rel="sweetheart date met">Jane</a> <a href="http://dave-blog.example.org/" rel="friend met">Dave</a> <a href="http://darryl-blog.example.org/" rel="friend met">Darryl</a> <a href="http://www.metafilter.com/">MetaFilter</a> <a href="http://james-blog.example.com/" rel="met">James Expert</a>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 78 of 109

33

May 15, 2012 Copyright 2005-2012

MetaFilter gets no value since it does not represent an actual person. The others in the list are given space-separated values appropriate to the link target. Thus, since Joe is dating his sweetheart Jane (who he has, perhaps not surprisingly, also met in person) he gives the link to her the values sweetheart date met. If Joe were not as committed to Jane, and in fact dated other people from time to time, then the sweetheart value would be dropped. See http://gmpg.org/xfn/intro for more info.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 79 of 109

33

May 15, 2012 Copyright 2005-2012

Appendix D Testing A New Theme


This step in Theme testing correlates to a WordPress export (WXR) file that you can import into a WordPress installation to test your Theme. To be clear, this is only one step in testing your Theme. See Theme testing for a full guide. SETUP TEST ENVIRONMENT SETUP
1. Download test data: https://wpcom-themes.svn.automattic.com/demo/test-data.2011-01-17.xml 2. Import test data into your WordPress install. Do this by going to Tools -> Import. 3. Read How To Join WPTRT, and follow all test-environment setup instructions

WORDPRESS SETTINGS
Adjust WordPress settings as follows: 1. Settings -> General: set the Site Title to something fairly long, and set the Tagline to something even longer. These settings will facilitate testing how the Theme handles these values. 2. Settings -> Reading: set "Blog pages show at most" to 5. This setting will ensure that index/archive pagination is triggered. 3. Settings -> Discussion: enable Threaded Comments, at least 3 levels deep. This setting will facilitate testing of Theme comment list styling. 4. Settings -> Discussion: enable Break comments into pages, and set 5 comments per page. This setting will facilitate testing of Theme paginating link markup/styling. 5. Settings -> Media: ensure that no values are set for max width or height of Embedded media. This setting will facilitate testing of the Theme $content_width setting/implementation. 6. Settings -> Permalinks: ensure that a non-default permalink setting is selected, e.g. "Month and name". This setting will facilitate stepping through the Theme Unit Tests. Create at least two Custom Menus: 1. Long Menu: all included Pages 2. Short Menu: a menu of 2-3 Pages

TEMPLATE HIERARCHY INDEX PAGES


When viewing any Template Hierarchy Index page, including the default index page (index.php), and (if applicable) Blog Posts Index (home.php), Date Archives (archive.php), Category Archives (category.php), Tag Archives (tag.php), or Author Archives (author.php): 1. 2. 3. 4. 5. 6. Posts display correctly, with no apparent visual problems or errors. Posts display in correct order. Correct number of posts display (as per setting in Settings > Reading). Page navigation displays and works correctly. Debugger returns no PHP errors, warnings, or notices The browser reports no JavaScript errors

STATIC FRONT PAGE


If the Theme includes either a front-page.php or a home.php template file, go to Dashboard -> Settings -> Reading, and set the Front Page to display a Static Page (use any existing Page), and set the Blog Posts index to another Static Page (e.g. "Lorem Ipsum"). 1. 2. 3. 4. The Front Page displays properly, and as intended The Blog Posts index page displays properly Debugger returns no PHP errors, warnings, or notices The browser reports no JavaScript errors

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 80 of 109

33

May 15, 2012 Copyright 2005-2012

404 PAGE
1. The 404 page displays properly 2. Some content is displayed, more than merely the basic "Error 404 - Page Not Found" message - such as some helpful text, a search form, a list of Post or Pages, etc. 3. Debugger returns no PHP errors, warnings, or notices 4. The browser reports no JavaScript errors

SEARCH RESULTS PAGE


1. The Search Results page displays properly, with search query results displayed. 2. Debugger returns no PHP errors, warnings, or notices 3. The browser reports no JavaScript errors

BLOG POSTS INDEX PAGE


Test the following posts when viewing the Blog Posts Index page. Post Titles in the test data correlate with section titles below.

SCHEDULED POST
Should not be displayed by the Theme (status "scheduled", rather than "published").

DRAFT POST
Should not be displayed by the Theme (status "draft", rather than "published").

LAYOUT TEST
1. Displays properly as a "Sticky Post." 2. Page navigation links display and work properly.

READABILITY TEST
1. Displays "Read More" link properly. 2. "Read More" link works properly (links to single post at "More" tag location).

POST FORMAT TESTS (ALL)


If Theme supports Post Format Type, Post displays as intended in the index view

POST FORMAT TEST: GALLERY


Gallery images display as intended in the index view

POST FORMAT TEST: IMAGE (LINKED)


1. Image displays as intended in the index view 2. Image does not overflow the content area

POST FORMAT TEST: IMAGE (ATTACHED)


1. Image displays as intended in the index view 2. Image does not overflow the content area

POST FORMAT TEST: VIDEO


1. Video displays as intended in the index view 2. Video does not overflow the content area

THIS POST HAS NO BODY NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference Pg 81 of 109 33 May 15, 2012 Copyright 2005-2012

Lack of body text should not adversely impact the layout.

(NO TITLE)
1. Lack of post title should not adversely impact layout. 2. Post permalink should be displayed. Making the post date a permalink is a great solution. See Twenty Ten for an example.

MANY CATEGORIES & MANY TAGS


1. Theme must incorporate both the "Tag" and the "Category" taxonomies in some manner. 2. Large number of categories/tags should not adversely impact layout.

PROTECTED TEST WITH SECRET PASSWORD


1. 2. 3. 4. Password form should be displayed. Post content should not be displayed. Comments should not be displayed. Once password is entered, post or excerpt displays properly.

SINGLE POST
Test the following posts when viewing a single post (single.php). Each section title matches a post title in the test data.

LAYOUT TEST
1. Displays page navigation links properly. 2. Page navigation links work properly (link to correct page). 3. Post permalink links to Page 1.

PAGE 2
1. Paragraphs are styled correctly. 2. Left, Center, Right, Justify aligned paragraphs align properly.

PAGE 3
1. h1-h6 elements are styled (as appropriate). 2. blockquote, cite styled (as appropriate). Block quotes should be indented or otherwise distinct from paragraph text. If the Theme uses a background image or quote symbol, make sure displays correctly on both short and long quotes. 3. span with style and ASCII characters should display properly. 4. table, tr, th, td are styled (as appropriate). 5. dl (dt, dd), ul, ol, li styled (as appropriate). Nested lists should be indented correctly. 6. The following HTML tags should be styled appropriately to ensure semantic meaning of each tag is preserved: address, a, big, cite, code, del, em, ins, kbd, pre, q, s, strong, sub, sup, tt, var. Note: abbr and acronym require no special styling. Also, s may be address but was deprected with HTML 4 and can be left with no special styling as well. 7. div, span maintain proper block or inline display, and styled (as appropriate).

READABILITY TEST
1. The content should be generally readable. 2. Styling should not negatively impact readability: foreground/background contrast, font family, font size, line height, paragraph width, paragraph spacing.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 82 of 109

33

May 15, 2012 Copyright 2005-2012

IMAGES TEST
Page 1 1. 2. 3. 4. Page 2 1. 2. 3. 4. Page 3 Un-Captioned Image Alignment Tests Images are aligned properly: Center, Left, Right, None. Check caption styles on first image. Images should not have a border unless it's part of design. Captioned Image Alignment Tests Images are aligned properly: Center, Left, Right, None. Check caption styles on first image. Images should not have a border unless it's part of design.

1. Other Image Tests 2. Wide Image (Resized) Test Image should display properly, and should be resized as specified. Sidebar must not be pushed to the bottom of the page. 3. Wide Image (Not Resized) Test Wide image overflows properly (such as using max-width CSS rule or overflow CSS rule). Sidebar must not be pushed below content due to image overlap. 4. Thumbnails display properly. Page 4 Floats are cleared properly for floated element (thumbnail image) at the end of the Post Content

POST FORMAT TESTS (ALL)


If Theme supports Post Format type, Post displays as intended in the single-post view.

POST FORMAT TEST: GALLERY


1. Gallery displays correctly (check for spacing after gallery). 2. Gallery image thumbnails link to image post.

POST FORMAT TEST: IMAGE (LINKED)


1. Image displays as intended in single-post view 2. Image does not overflow the content area

POST FORMAT TEST: IMAGE (ATTACHED)


1. Image displays as intended in single-post view 2. Image does not overflow the content area

POST FORMAT TEST: VIDEO


1. 2. 3. 4. Video embeds work. Embedded videos do not overlap each other. Embedded videos do not push sidebar(s) below content due to overlap. $content_width should have an appropriate value defined.

POST FORMAT TEST: AUDIO


Enclosure links work properly.

POST WITH LONG TITLE NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference May 15, 2012 Copyright 2005-2012

Pg 83 of 109

33

Long Post Title with long non-breaking string: If you say it loud enough, youll always sound precocious; Supercalifragilisticexpialidocious! 1. Test title line height 2. Look for potential overflow issues if the theme has a small title area

THIS POST HAS NO BODY


Post displays properly and should not impact the layout.

(NO TITLE)
1. Post displays properly. 2. A link to the singular view of the post is recommended to be displayed. Making the post date a permalink (see Twenty Ten for an example) is a great solution.

MANY CATEGORIES / MANY TAGS


1. 2. 3. 4. 5. Theme incorporates both the "Tag" and "Category" taxonomies in some manner Category links work correctly. Categories display properly without adversely impacting design. Tag links work correctly. Tags display properly without adversely impacting design.

PROTECTED TEST WITH SECRET PASSWORD


1. Password input form displays properly. 2. When correct password (secret) is entered, the post and comments are displayed.

COMMENT TEST
1. 2. 3. 4. 5. 6. 7. 8. Comments are displayed correctly. Threaded comments display correctly. Comment pagination displays correctly. Author comment is styled (as appropriate). User avatars are displayed properly. Comment form displays properly for both logged in/logged out users. When logged in as admin, edit links are displayed and work correctly. HTML is displayed properly in comments, especially lists and block quotes

COMMENTS DISABLED
1. Comment form does not display. 2. "Comments are disabled" notice is displayed.

MANY TRACKBACKS
All trackbacks are displayed properly, with no overlap.

PAGES
Test the following pages (page.php) by viewing the page that matches the section titles below.

PAGE WITH COMMENTS


1. Tags, Categories, and Post date/time stamp should not be displayed. 2. Comment list and comment reply form are displayed.

PAGE WITH COMMENTS DISABLED


1. Comment list and comment reply form are not displayed.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 84 of 109

33

May 15, 2012 Copyright 2005-2012

2. No "Comments Disabled" message should be displayed. 3. Layout not adversely impacted by minimal page content.

PARENT PAGE / CHILD PAGE 1 / CHILD PAGE 2


Extra credit for displaying parent and/or child when viewing pages within hierarchy.

CLEARING FLOATS
The last item in this page's content is a floated image. Make sure any elements after it are clearing properly.

MISC PAGES
Tests for search.php and 404.php.

SEARCH RESULTS
1. Search results page is helpful. 2. Search query is displayed.

NOT FOUND
404 page is present, and has helpful information.

GENERAL MENUS
1. Test with a large number of categories or pages in the menu, and test with multiple levels deep in the menus. 2. If custom menus are enabled, test the layout both with custom menus enabled and with the fallback navigation menus (no custom menu enabled).

WIDGETS
1. All widgets display correctly. 2. The default WordPress widgets should work correctly in all widgetized areas. 3. If the Theme uses custom widgets, they should work correctly. (Custom widgets are programmatically added by the Theme to the list of available widgets in Appearance > Widgets.) 4. Test all available widgets in all available widgetized areas in the Theme layout. 5. Content that appears in widgetized areas by default (hard-coded into the sidebar, for example) should disappear when widgets are enabled from Appearance > Widgets.

SCREENSHOT
1. The screenshot should accurately show the Theme design. 2. Make sure it doesn't show customized header colors or an uploaded logo that wouldn't appear by default.

ANCHOR TEXT AND CREDIT LINKS


Theme authors should only be using links that point directly to a website specifically for the theme; an appropriate website page for the theme; or a reasonably related URL giving more information about the theme. Using anchor text for search engine gains will not be accepted.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 85 of 109

33

May 15, 2012 Copyright 2005-2012

Appendix E Common Procedures & Functions


As a developer, one of my favorite things about WordPress is its built-in functions, which allow you to easily manipulate and extend WordPress with just a few lines of code. LISTING ALL PAGES If you want to list all of the pages youve got (note that pages and posts have different meanings in WordPress vernacular), theres a simple function for that called wp_list_pages. When used without any parameters, it will list all of your pages in alphabetical order.
<?php wp_list_pages(); ?>

LISTING SPECIFIC PAGES As with many WordPress functions, the wp_list_pages function takes several parameters. For example, the include parameter allows you to list specific pages by referencing their page IDs, separated by commas (,). The following example will only list two pages (the pages have IDs of 4 and 5).
<?php wp_list_pages('include=4,5'); ?>

EXCLUDING SPECIFIC PAGES FROM A LIST You can also exclude specific pages using the exclude parameter:
<?php wp_list_pages('exclude=4,5'); ?>

SORTING PAGES As discussed earlier, the default sorting order of wp_list_pages is alphabetical. You can, however, change the order of the listing using the sort_column parameter. The sort_column parameter can have 1 of 7 values:
post_title Sort alphabetically (default value) menu_order Sort by page order post_date Sort by date of creation post_modified Sort by time last modified ID Sort by page ID post_author Sort by the page author ID post_name Sort alphabetically by post slug

Here is the code for sorting by creation date instead of the default alphabetical order:
<?php wp_list_pages('sort_column=post_date'); ?>

SPECIFYING THE DEPTH Pages can have subpages, and subpages can have subpages. What if you only wanted to list toplevel pages but exclude their subpages? Controlling the depth works great when using it to generate dropdown menus with submenus. You can use the depth parameter like so:
<?php wp_list_pages('depth=1'); ?>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 86 of 109

33

May 15, 2012 Copyright 2005-2012

ENABLING NAVIGATION MENU If youre wanting absolute control over your navigation, using WordPress 3.0s new menu function, wp_nav_menu, is the way to go. With this function, you can add categories in menus, submenus and even insert external links into navigation menus. To take advantage of the built-in navigation menu functionality, first you need to enable it in your theme. In your functions.php file located in the theme directory, youll need to add the following:
<?php add_theme_support( 'menus' ); ?>

Next, place the following code in the location where you want the menu to show on your site (this could be in your standard theme template files such as header.php or single.php):
<?php wp_nav_menu( array('menu' => '[Menu Name]' )); ?>

Replace [Menu Name] with what you want your menu to be named. Youll then need to navigate to Appearance > Menus and create your menu with the same exact name. Everything from there is simply drag and drop! SITE URL Lets say your sites URL is http://example.com. If you want to print this out in the source, you can use the url parameter.
<?php bloginfo('url'); ?>

This works great for absolute link references. For example, if you wanted to reference your logo (lets say the file name is logo.png) that is in a directory called images, you would do the following:
<img src="<?php bloginfo('url'); ?>/images/logo.png" />

The above outputs:


<img src=" http://example.com/images/logo.png" />

URL TO THE CURRENT THEME


<?php bloginfo('template_url'); ?>

GETTING THE URL OF YOUR RSS FEED


<?php bloginfo('rss2_url'); ?>

If you wanted to create a link to your RSS feed, you could use the following:
<a href="<?php bloginfo('rss2_url'); ?>">Link to RSS feed</a>

POST LOOP The POST loop is not much to look at by itself, but its whats inside the loop that really matters.
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?><?php endwhile; endif; ?>

DISPLAYING POSTS IN A CATEGORY NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 87 of 109

33

May 15, 2012 Copyright 2005-2012

Keeping with our Featured category example above, heres how wed show the three newest posts from the Featured category:
<?php query_posts('category_name=Featured&posts_per_page=3'); ?>

ASIDE: PASSING MULTIPLE PARAMETERS INTO FUNCTIONS Notice that we passed two parameters into the query_post function. The parameters we passed were category_name and post_per_page. In functions with more than one parameter, you can pass multiple parameters all at once by separating them with an ampersand (&). You can pass as many parameters as you want. Doing so allows you to increase the specificity of your desired outputs. EXCLUDING POSTS Similar to wp_list_pages, query_posts has a way to exclude items from being displayed. To do so, you just place a minus character (-) in front of the ID of the items you want to exclude.
<?php query_posts('cat=-97,-34'); ?>

POST TITLE
<?php the_title(); ?>

POST URL
<?php the_permalink(); ?>

POST CONETENT
<?php the_content(); ?>

POST EXCERPT
<?php the_excerpt(); ?>

POST CATEGORY
<?php the_category(); ?>

POST TAGS USED IN THE POST


<?php the_tags(); ?>

POST PUBLISH DATE


<?php the_time(); ?>

WORKING WITH CUSTOM FIELDS One of the most powerful functions that WordPress has that seems to take developers a long time to learn is the use of custom fields. Custom fields allow users to add custom name/value pairs typically used for post metadata. For example, users can add a post_thumbnail_url key that has a URL value pointing to the thumbnail image.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 88 of 109

33

May 15, 2012 Copyright 2005-2012

Users can add custom fields while they are creating posts and pages in Posts > Add new or Pages > Add new.

Ive used custom fields for everything from post thumbnails and changing the background of the individual post to adding custom link and layout areas. It becomes very powerful once youve learned it properly. Getting custom fields can be done from inside or outside of the loop. If you use it outside the loop, you have to reference the ID of the post or page you want the custom field name/value pair from. THUMBNAILS - PORTFOLIO I use timthumb with custom fields for my portfolio section.
<img src="timthumb.php?src=<?php echo get_post_meta($post->ID, 'Thumbnail',true);?>&amp;h=456&amp;w=506&amp;zc=1" />

THUMBNAILS - POST
add_theme_support( post-thumbnails );

CUSTOM FIELDS FOR THUMBNAILS Lets say you want to display an image thumbnail in a post. First, you must create a new post (Posts > Add new). Under the Custom Fields fieldset, type Thumbnail into the Name field and a URI for the Value field. Then publish the post. Wherever in the loop you want the URI to be displayed, simply use the echo statement to output the result of
get_post_meta (which is a function for getting custom fields).
<?php echo get_post_meta($post->ID, 'Thumbnail', true); ?>

To use get_post_meta outside the loop, change $post->ID to the ID of the post. For example, heres how to print the URI of the thumbnail image for the post with ID of 6. NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference May 15, 2012 Copyright 2005-2012

Pg 89 of 109

33

<?php echo get_post_meta(6, 'Thumbnail', true); ?>

Since we want to display an image, what we actually need to do is use the echo statement inside the src attribute of an img element:
<img src="<?php echo get_post_meta(6, 'Thumbnail', true); ?>" />

The code from above should output the following:


<img src="/images/thumbnail.jpg" />

ADD FEED LINKS TO HEADER


Since version 2.8, WordPress can add all relevant feed links (main, comments, categories, et al) to your <head> area. It doesnt happen by default, however, because you have to add the following snippet to make it work: // add feed links to header if (function_exists('automatic_feed_links')) { automatic_feed_links(); } else { return; }

This will check to see if youre using a version of WordPress that is compatible, and then enable the automatic feed links. A couple of notes: first, this method assumes that you are not manually including any feed links in your <head>. Also, seems this functionality was being integrated with add_theme_support, so keep your eyes open for that.

AUTOMATIC JQUERY INCLUSION


Here is a way to do it from your themes functions.php file: // smart jquery inclusion if (!is_admin()) { wp_deregister_script('jquery'); wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"), false); wp_enqueue_script('jquery'); }

This code ensures that only one copy of jQuery is included, and calls it from Googles servers to save bandwidth and take advantage of any primed caches that happen to be visiting. Note that this function needs to be located before the threaded-comments function in order for it to work.

ENABLE THREADED COMMENTS


Enabling threaded comments requires adding a snippet of code into your <head> area just before the wp_head tag. After a little experimenting, We discovered that we can include this snippet from the functions.php file: // enable threaded comments function enable_threaded_comments(){ if (!is_admin()) {

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 90 of 109

33

May 15, 2012 Copyright 2005-2012

if (is_singular() AND comments_open() AND (get_option('thread_comments') == 1)) wp_enqueue_script('comment-reply'); } } add_action('get_header', 'enable_threaded_comments');

This helps keep your document <head> a little cleaner. Note that this function needs to be located after the jQuery-inclusion function in order for it to work.

REMOVE UNWANTED CRAP FROM THE HEAD SECTION


As weve mentioned before, WordPress spits out a ton of crap in the document <head> stuff like the version number and WLW, RSD, and index links. To clean things up, we add this nice little snippet into the functions.php template: // remove junk from head remove_action('wp_head', remove_action('wp_head', remove_action('wp_head', remove_action('wp_head', remove_action('wp_head', remove_action('wp_head', remove_action('wp_head', remove_action('wp_head', remove_action('wp_head',

'rsd_link'); 'wp_generator'); 'feed_links', 2); 'index_rel_link'); 'wlwmanifest_link'); 'feed_links_extra', 3); 'start_post_rel_link', 10, 0); 'parent_post_rel_link', 10, 0); 'adjacent_posts_rel_link', 10, 0);

ADD GOOGLE ANALYTICS TO THE FOOTER


Another annoying task that has to be done for all of the sites we create is adding Google Analytics code to the footer.php file. Recently it occurred to us to just add the code to our functions.php and never worry about it again: // add google analytics to footer function add_google_analytics() { echo '<script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>'; echo '<script type="text/javascript">'; echo 'var pageTracker = _gat._getTracker("UA-XXXXX-X");'; echo 'pageTracker._trackPageview();'; echo '</script>'; } add_action('wp_footer', 'add_google_analytics');

A couple of notes here: first, obviously you want to replace the UA-123456-1 with your actual GA code. Second, you may want to check out the three currently available Analytics options and modify the code accordingly. Currently, this function is using the newer ga.js tracking code, but that is easily changed to either of the other methods.

CUSTOM EXCERPT LENGTH


Instead of using the default 55-word limit, this function enables you to specify any length for your excerpts. // custom excerpt length function custom_excerpt_length($length) { return 80; } add_filter('excerpt_length', 'custom_excerpt_length');

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 91 of 109

33

May 15, 2012 Copyright 2005-2012

Just set your preferred number of words by editing the 80 to whatever you wish.

CUSTOM EXCERPT CONTINUE STRING


Or whatever they call that funky bracketed ellipses thing [...] that is appended to your post excerpts by default. Maybe you like to remove the brackets, but with this functions.php snippet you can change it to anything: // custom excerpt ellipses for 2.9+ function custom_excerpt_more($more) { return '...'; } add_filter('excerpt_more', 'custom_excerpt_more'); /* custom excerpt ellipses for 2.8function custom_excerpt_more($excerpt) { return str_replace('[...], , $excerpt); } add_filter(wp_trim_excerpt, custom_excerpt_more); */

As you can see, there are two different versions of this code, depending on your version of WordPress. We like to stay current, so we commented out the older method but left it there in case you need it. For either version of this technique, just replace the with pants on the ground or whatever happens to suit your needs.

NO MORE JUMPING FOR THE READ MORE LINK


One of the weirdest things that WordPress does is jump the reader to the location of the <!more&grt; tag on the singlepost-view when the read more link is clicked. Its just awkward if the jump was on the same page, it would make sense, but to load a new page and then take the reader halfway down without explaining anything is just wrong. In any case, here is a nice little function that will stop the jumping once and for all: // no more jumping for read more link function no_more_jumping($post) { return '<a href="'.get_permalink($post->ID).'" class="read-more">'.'Continue Reading'.'</a>'; } add_filter('excerpt_more', 'no_more_jumping');

Nothing else needs to be done for this to work just plug it in and enjoy your new jumpless functionality. Note that this is also a convenient place to customize the read more link with whatever attributes or custom text you wish.

ADD A FAVICON TO YOUR WORDPRESS


You just gotsta have a favicon for your wordpress, and this code makes it super easy to do. Just create your image and upload to sites root directory. The following code in your functions.php file makes it so by adding the required line to your <head> area: // add a favicon to your function blog_favicon() { echo '<link rel="Shortcut Icon" type="image/x-icon" href="'.get_bloginfo('wpurl').'/favicon.ico" />'; } add_action('wp_head', 'blog_favicon');

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 92 of 109

33

May 15, 2012 Copyright 2005-2012

Feel free to change the directory to whatever you desire. Also make sure that the wp_head is present within your themes header.php file.

ADD A DIFFERENT FAVICON FOR YOUR BLOGS ADMIN AREA


While were here, lets add a unique favicon to our Admin pages, so that they are easier to recognize when bookmarked or working with tabs. Just create a favicon and upload to your themes /images/ directory. This code takes care of the rest: // add a favicon for your admin function admin_favicon() { echo '<link rel="Shortcut Icon" type="image/x-icon" href="'.get_bloginfo('stylesheet_directory').'/images/favicon.png" />'; } add_action('admin_head', 'admin_favicon');

As before, feel free to change the directory to whatever you desire. It might be best to keep your admin favicon in a separate directory than your wordpress favicon.

CUSTOM ADMIN LOGIN LOGO


You know that snazzy blue WordPress logo that is branding your various login pages? Yeh, you can change that to whatever you want. Just create your custom login image, name it custom-login-logo.png, and upload it to your themes /images/ directory. This code will take care of the rest: // custom admin login logo function custom_login_logo() { echo '<style type="text/css"> h1 a { background-image: url('.get_bloginfo('template_directory').'/images/customlogin-logo.png) !important; } </style>'; } add_action('login_head', 'custom_login_logo');

The key here is to make sure that the path and image names match that of your setup. Also, when creating your image, you may want to keep in mind the properties of the original: 30px length, 31px height, transparent GIF format, and header background color of #464646 (for the image matte).

DISABLE UNUSED WIDGET AREAS


This handy function is for removing unwanted widget areas from our theme a must for customizing existing themes: // disable all widget areas function disable_all_widgets($sidebars_widgets) { //if (is_home()) $sidebars_widgets = array(false); return $sidebars_widgets; } add_filter('sidebars_widgets', 'disable_all_widgets');

This code is plug-&-play no other modifications need to be made. Note: if you only want to disable widgets on your Home page, then remove the two comment slashes (//) from the third line.

KILL THE WORDPRESS UPDATE NAG NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference May 15, 2012 Copyright 2005-2012

Pg 93 of 109

33

This is one of someone favorites, but its not for everyone. In any case, you know that Please update now.. message that appears on every page in the WordPress Admin when new versions are available? This sweet little function kills it dead (or disables it, actually): // kill the admin nag if (!current_user_can('edit_users')) { add_action('init', create_function('$a', "remove_action('init', 'wp_version_check');"), 2); add_filter('pre_option_update_core', create_function('$a', "return null;")); }

Feel free to comment this one out or remove it if you rely on the Admin nag to keep you informed of changes.

INCLUDE CATEGORY ID IN BODY_CLASS AND POST_CLASS


By default, WordPress body_class and post_class do not include the ID of the category of the current post. This custom function changes all that: // category id in body and post class function category_id_class($classes) { global $post; foreach((get_the_category($post->ID)) as $category) $classes [] = cat- . $category->cat_ID . -id; return $classes; } add_filter(post_class, category_id_class); add_filter(body_class, category_id_class);

Even if you arent using it, its a nice function to have around, which is why its included here for this custom functions.php template of essential functions.

GET THE FIRST CATEGORY ID


Another useful function when working with different categories is the ability to get the first category ID of the current post. This function makes it happen: // get the first category id function get_first_category_ID() { $category = get_the_category(); return $category[0]->cat_ID; }

Strictly plug-&-play: just use <?php get_first_category_ID(); ?> in your theme template file to access the data.

INSERT CUSTOM CONTENT AFTER POSTS


If you look at the different things contained within a typical post, you will find many common and repetitive items, such as feed links, copyright information, and social-media bookmarks. While theres nothing wrong with inserting this content into your single.php template, it is sometimes easier to manage things from the functions.php file. For example, we include a brief copyright statement at the end of each post. By including the following code in our functions.php template, its something that happens automatically: // add custom post content

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 94 of 109

33

May 15, 2012 Copyright 2005-2012

function add_post_content($content) { if(!is_feed() && !is_home()) { $content .= '<p>This article is copyright '.date('Y').' '.bloginfo('name').'</p>'; } return $content; } add_filter('the_content', 'add_post_content');

The trick here is an old one, but its extremely useful. By changing the line beginning with $content., you can add just about any content you like.

INSERT CUSTOM CONTENT IN FEEDS


Just as with the previous method, this function makes it possible to automatically add any content to your feeds. Yes, we know there are plugins that will make your feed footers do backflips, but for a simple copyright message or other info, We think it is easier and more efficient to simply toss a few lines into your custom functions.php template: // add custom feed content function add_feed_content($content) { if(is_feed()) { $content .= '<p>This article is copyright '.date('Y').' '.bloginfo('name').'</p>'; } return $content; } add_filter('the_excerpt_rss', 'add_feed_content'); add_filter('the_content', 'add_feed_content');

As before, you can change the added content to whatever you want by editing the $content variable. Once in place, this will append a dynamic copyright message to each post in your feed. Note: if you happen to be adding the same content to your web pages (using the previous method) and your feeds (using this method), you may combine the two functions like so: // add custom content to feeds and posts function add_custom_content($content) { if(!is_home()) { $content .= '<p>This article is copyright '.date('Y').' '.bloginfo('name').'</p>'; } return $content; } add_filter('the_excerpt_rss', 'add_custom_content'); add_filter('the_content', 'add_custom_content');

Remember that if you use this combined function that you should remove or comment out both of the individual ones to avoid duplicate output. It will be included but commented out in the complete functions.php template file.

REMOVE VERSION NUMBER FROM PAGES AND FEEDS


A commonly cited security measure for WordPress-powered sites involves removing the automatically generated version number from appearing in the <head> section of your pages source code. This type of security technique is referred to as security through obscurity, and aims at hiding potentially sensitive information from a would-be attacker. Heres a function that does the job:

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 95 of 109

33

May 15, 2012 Copyright 2005-2012

// remove version info from head and feeds function complete_version_removal() { return ''; } add_filter('the_generator', 'complete_version_removal');

This will remove your sites version and generator information from all of your pages and feeds, making it a little bit harder for the bad guys and a little bit safer for you and your visitors.

CUSTOMIZE ADMIN FOOTER MESSAGE


Customization is what makes your online experience something special. For your own sites and for your clients sites, it is nice to customize the generic admin footer message with something a little more useful, informative, and inspiring. This little gem makes it easy: // customize admin footer text function custom_admin_footer() { echo '<a href="http://www.livexp.net/">Live Experience</a>'; } add_filter('admin_footer_text', 'custom_admin_footer');

Here, for the sake of example, we are including a link to my site, but you can customize the content with just about anything you wish.

ENABLE HTML MARKUP IN USER PROFILES


When customizing their profiles, users may want to include a hyperlink, bold text, or some other HTML markup. By default, WordPress prevents this from happening, but you can easily enable it with this friendly little snippet: // enable html markup in user profiles remove_filter('pre_user_description', 'wp_filter_kses');

Note: Enabling HTML may be best left to sites that have open user-registration disabled. Use with discretion.

DELAY FEED UPDATE AFTER POSTING


As a chronic perfectionist, Maybe we hate it when we post something only to discover an error a few minutes later. // delay feed update function publish_later_on_feed($where) { global $wpdb; if (is_feed()) { // timestamp in WP-format $now = gmdate('Y-m-d H:i:s'); // value for wait; + device $wait = '5'; // integer // http://dev.mysql.com/doc/refman/5.0/en/date-and-timefunctions.html#function_timestampdiff $device = 'MINUTE'; // MINUTE, HOUR, DAY, WEEK, MONTH, YEAR // add SQL-sytax to default $where $where .= " AND TIMESTAMPDIFF($device, $wpdb->posts.post_date_gmt, '$now') > $wait ";

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 96 of 109

33

May 15, 2012 Copyright 2005-2012

} return $where; } add_filter('posts_where', 'publish_later_on_feed');

This code quietly and automatically gives us an extra five minutes before my post is added to our feeds. If you need more or less than five minutes, just edit the $wait variable with the integer of your choice.

ADD AN ADMIN LINK TO THE WORDPRESS ALL-SETTINGS PAGE


As weve explained before, WordPress makes it easy to view and edit your blog settings from the Admin area. Thanks to a file named options.php, WordPress will display all of your database settings and enable you to edit a majority of them. To view this page, you need to log in as Admin and enter this URL in your browsers address bar: http://domain.tld/wp-admin/options.php

Having access to your All-Settings page can be extremely helpful, so its nice to display a direct link for easy access. The following slice of code in your functions.php file is all thats needed: // admin link for all settings function all_settings_link() { add_options_page(__('All Settings'), __('All Settings'), 'administrator', 'options.php'); } add_action('admin_menu', 'all_settings_link');

Once in place, you will see a link to your All Settings page in the WordPress Admin. You can change the name of the link to whatever you prefer by editing the two instances of All Settings.

REMOVE ALL NOFOLLOW ATTRIBUTES FROM COMMENTS


There are a million ways to remove nofollow from your comments, but nothing is as easy as this method : // remove nofollow from comments function xwp_dofollow($str) { $str = preg_replace( '~<a ([^>]*)\s*(["|\']{1}\w*)\s*nofollow([^>]*)>~U, <a ${1}${2}${3}>, $str); return str_replace(array( rel=", rel=), , $str); } remove_filter(pre_comment_content, wp_rel_nofollow); add_filter (get_comment_author_link, xwp_dofollow); add_filter (post_comments_link, xwp_dofollow); add_filter (comment_reply_link, xwp_dofollow); add_filter (comment_text, xwp_dofollow);

That code will remove all instances of the nefarious nofollow attribute from all comment items, including the author link and comment text. This is a great way to automatically remove nofollow with no plugins or hacking required.

ENABLE EASY DISPLAY OF YOUR POSTS WORD COUNT


This function enables you to display your posts word count without cluttering up the WordPress loop. To display the word count of your posts, first place this in your functions.php file:

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 97 of 109

33

May 15, 2012 Copyright 2005-2012

// count words in posts function word_count() { global $post; echo str_word_count($post->post_content); } Then, simply place this anywhere in your loop where you would like the number to appear:

So for example, you could display your posts word count to your visitors with something like: <p>This post contains a whopping <?php word_count(); ?> words.</p> We can also easily display the word count of other items, such as the post title: <?php echo str_word_count($post->post_title); ?> Likewise, we can exclude the function from functions.php and get the word count with a single line of code in the loop: <?php echo str_word_count($post->post_content); ?>

Just slap em anywhere in your post loop to display your word count. Not always needed, but nice to have available.

ENABLE DELETE AND SPAM LINKS FOR COMMENTS


Managing your comments is easily done via the Admin, but we also like to see things from the outside, as they appear to the public. Browsing through comments as they appear on your site helps you catch things that may have eluded routine approvals in the Admins comment listings. To help facilitate this process, I like to include a backwards-compatible set of spam and delete links next to each comment. This makes it super-easy to cultivate comments live on the site. // spam & delete links for all versions of wordpress function delete_comment_link($id) { if (current_user_can('edit_post')) { echo '| <a href="'.get_bloginfo('wpurl').'/wpadmin/comment.php?action=cdc&c='.$id.'">del</a> '; echo '| <a href="'.get_bloginfo('wpurl').'/wpadmin/comment.php?action=cdc&dt=spam&c='.$id.'">spam</a>'; } } Once this is included in your functions.php file, displaying the links is as easy as adding this to your comments loop: <?php delete_comment_link(get_comment_ID()); ?>

DISABLE ALL WORDPRESS FEEDS


It is easy to disable all feed functionality for your site. Here is the functions.php code: Note: Only use this function if you want to disable your feeds! This function will be commented out of the complete functions.php file. // disable all feeds function fb_disable_feed() { wp_die(__('<h1>Feed not available, please visit our <a href="'.get_bloginfo('url').'">Home Page</a>!</h1>')); } add_action('do_feed', 'fb_disable_feed', 1); add_action('do_feed_rdf', 'fb_disable_feed', 1);

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 98 of 109

33

May 15, 2012 Copyright 2005-2012

add_action('do_feed_rss', 'fb_disable_feed', 1); add_action('do_feed_rss2', 'fb_disable_feed', 1); add_action('do_feed_atom', 'fb_disable_feed', 1);

This function will quietly and completely disable all of your sites feeds, including all different formats. With this code in place, any request for your feed will return the following message in a nice, big set of h1 tags: Feed not available, please visit our Home Page! This message is easily customized by editing the wp_die argument in the function.

CUSTOMIZE GRAVATARS
Instead of suffering with the rather dull default gravatars, use this code to customize your own: // customize default gravatars function custom_gravatars($avatar_defaults) { // change the default gravatar $customGravatar1 = get_bloginfo('template_directory').'/images/gravatar-01.png'; $avatar_defaults[$customGravatar1] = Default; // add a custom user gravatar $customGravatar2 = get_bloginfo(template_directory)./images/gravatar-02.png; $avatar_defaults[$customGravatar2] = Custom Gravatar; // add another custom gravatar $customGravatar3 = get_bloginfo(template_directory)./images/gravatar-03.png; $avatar_defaults[$customGravatar3] = Custom gravatar; return $avatar_defaults; } add_filter(avatar_defaults, custom_gravatars);

Of course, you can manually choose a default gravatar by specifying its location via the get_avatar template tag, but this method makes it so much easier. Not only does it replace the default with multiple custom gravatars, but it also goes the extra mile by displaying them in the WordPress Admin area under Settings > Discussion. From there, you can select any of your custom gravatars by simply selecting it and clicking the Update button. Nothing could be easier. A few notes about this function: 1. As is, it adds three new gravatars to choose as defaults. 2. Each gravatar should be located in your themes images directory. 3. You can add as many default gravatars as you would like by emulating the code pattern. 4. If you keep your custom gravatars someplace else, be sure and edit the image paths accordingly.

DISABLE AUTOMATIC FORMATTING OF POST CONTENT


How to prevent WordPress from automatically formatting chunks of post content by using a shortcode. This is very useful for posting code, poetry, or anything else that you would like to display in raw format. To do this, we add the following snippet to our functions.php file: // disable auto formatting in posts function my_formatter($content) { $new_content = ''; $pattern_full = '{(\[raw\].*?\[/raw\])}is; $pattern_contents = {\[raw\](.*?)\[/raw\]}is; $pieces = preg_split($pattern_full, $content, -1, PREG_SPLIT_DELIM_CAPTURE);

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 99 of 109

33

May 15, 2012 Copyright 2005-2012

foreach ($pieces as $piece) { if (preg_match($pattern_contents, $piece, $matches)) { $new_content .= $matches[1]; } else { $new_content .= wptexturize(wpautop($piece)); } } return $new_content; } remove_filter(the_content, wpautop); remove_filter(the_content, wptexturize); add_filter(the_content, my_formatter, 99);

With that code in place, you can insert unformatted code into your posts via the [raw] shortcode, for example: [raw]Unformatted content[/raw]

Anything contained within those shortcodes will be left unformatted when displayed in your posts.

ESCAPE HTML ENTITIES IN COMMENTS


How to automatically escape encoded HTML entities in the comments that readers leave on your posts? This is especially useful for blogs that deal in heavy code exchanges on post threads. This enables your commentators to simply wrap their code in <code> tags and not have to worry about manually converting characters such as angled brackets (< & >) into their encoded equivalents (< & >). // escape html entities in comments function encode_code_in_comment($source) { $encoded = preg_replace_callback('/<code>(.*?)<\/code>/ims', create_function('$matches', '$matches[1] = preg_replace(array(/^[\r|\n]+/i, /[\r|\n]+$/i), , $matches[1]); return <code> . htmlentities($matches[1]) . </.code>;), $source); if ($encoded) return $encoded; else return $source; } add_filter(pre_comment_content, encode_code_in_comment);

Once in place in your functions.php file, simply tell your commentators to wrap their code snippets in <code> tags. In other words, any content wrapped in <code> tags will be encoded automatically. Plus, in order to prevent unwanted <br /> tags, this function also automatically removes line breaks after the opening <code> tag and before the closing <code> tag.

CUSTOM COMMENTS DISPLAY CALLBACK FUNCTION


When designing your themes comments.php file, you can use either WordPress default code or create your own for full control over your comments display. If youre rolling your own, it is often easiest to grab a solid comments-display template and customize it to suit your needs. After many iterations and much refining, here is the comments callback function that We usually begin with: // custom comments callback function function custom_comments_callback($comment, $args, $depth) { $GLOBALS['comment'] = $comment; ?>

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 100 of 109

33

May 15, 2012 Copyright 2005-2012

<li <?php comment_class(); ?> id=comment-<?php comment_ID(); ?>> <div class=comment-wrap> <?php echo get_avatar(get_comment_author_email(), $size = 50, $default = bloginfo(stylesheet_directory)./images/gravatar.png); ?> <div class=comment-intro> <?php printf(__(%s), get_comment_author_link()); ?> <a class=comment-permalink href=<?php echo htmlspecialchars(get_comment_link($comment>comment_ID)); ?>><?php comment_date(F j, Y); ?> @ <?php comment_time(); ?></a><?php edit_comment_link(Edit, , ); ?> </div> <?php if ($comment->comment_approved == 0) : ?> <p class=comment-moderation><?php _e(Your comment is awaiting moderation.); ?></p> <?php endif; ?> <div class=comment-text><?php comment_text(); ?></div> <div class=reply id=comment-reply-<?php comment_ID(); ?>> <?php comment_reply_link(array_merge($args, array(reply_text=>Reply, login_text=>Log in to Reply, add_below=>commentreply, depth=>$depth, max_depth=>$args['max_depth']))); ?> </div> </div> <?php } // WP adds the closing </li>

Theres a lot going on here, so lets highlight the important stuff: 1. 2. 3. Do not add the closing </li> element WordPress does this for you. This function calls for a default gravatar in your themes images directory. Either ensure youve got the required image in place or edit the code to reflect your sites reality. Once this function is included in your functions.php file, you can display it by using the following comments loop in your comments.php file: <?php if (have_comments()) : ?> <ol class="commentlist"> <?php wp_list_comments('type=comment&style=ol&callback=custom_comments_callback'); ?> </ol> <?php else : ?>

Notice the third parameter for the wp_list_comments template tag? thats what makes it go. Also important is the style=ol parameter, which tells WordPress that we are using an ordered list for comments and that it should automatically close the markup with a </li> element.

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 101 of 109

33

May 15, 2012 Copyright 2005-2012

Menus
HORIZONTAL MENUS http://codex.wordpress.org/Creating_Horizontal_Menus
Okay, we can't resist. Let's take this another step further and give our new horizontal menu list some real jazz. See if you can tell what is being done to change the look.
#navmenu ul {margin: 0; padding: 0; list-style-type: none; list-style-image: none; } #navmenu li {display: inline; } #navmenu ul li a {text-decoration:none; margin: 4px; padding: 5px 20px 5px 20px; color: blue; background: pink;} #navmenu ul li a:hover {color: purple; background: yellow; }

If we did this all correctly, your list should look like this:

WITHOUT CSS
One should note that the all the above will fail in browsers with CSS turned off: the <li> lists will still be formatted vertically, not horizontally. Therefore, if one wishes to be portable to such browsers, one might use e.g.,
<p>Archives:<?php wp_get_archives('format=custom&show_post_count=1&type=yearly&after=;'); ?> Categories:<?php echo str_replace('<br />',';', wp_list_categories('style=&show_count=1&echo=0'));?></p>

MORE INFORMATION ON HORIZONTAL MENUS


Dynamic Menu Highlighting Maxdesign's Listamatic Maxdesign's Listutorial 2D Web Design - Create Stylish Menus with CSS Web Page Designer's CSS Rollovers with Single Image Horizontal Menu Bar Using Style Sheets Your HTML Source: CSS Text Formatting Your HTML Source: CSS Link Formatting CSS-2 Pure CSS Menus with No Javascript Camera On the Road's CSS Fun with Lists CSS Experiments with Lists and Menus

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 102 of 109

33

May 15, 2012 Copyright 2005-2012

Functions by category
POSTS get_adjacent_post get_boundary_post get_children get_extended get_next_post get_next_posts_link get_permalink get_the_excerpt get_the_post_thumbnail get_post get_post_ancestors get_post_mime_type get_post_status get_post_format get_edit_post_link get_delete_post_link get_previous_post previous_posts_link get_posts is_post (deprecated) is_single is_sticky the_ID the_date wp_get_recent_posts wp_get_single_post POST-CUSTOM POST TYPE register_post_type is_post_type_archive post_type_archive_title add_post_type_support remove_post_type_support post_type_supports set_post_type post_type_exists get_post_type get_post_types get_post_type_archive_link get_post_type_object get_post_type_capabilities get_post_type_labels is_post_type_hierarchical POST-POST INSERTION/REMOVAL wp_delete_post wp_insert_post wp_publish_post wp_update_post POST-PAGES get_all_page_ids get_ancestors get_page get_page_link get_page_by_path get_page_by_title get_page_children get_page_hierarchy get_page_uri get_pages is_page page_uri_index wp_list_pages wp_page_menu POST-CUSTOM FIELDS (POSTMETA) add_post_meta delete_post_meta get_post_custom get_post_custom_keys get_post_custom_values get_post_meta update_post_meta POST-ATTACHMENTS get_attached_file is_attachment is_local_attachment update_attached_file wp_attachment_is_image wp_insert_attachment wp_delete_attachment wp_get_attachment_image wp_get_attachment_link wp_get_attachment_image_src wp_get_attachment_metadata wp_get_attachment_thumb_file wp_get_attachment_thumb_url wp_get_attachment_url wp_check_for_changed_slugs wp_count_posts wp_mime_type_icon wp_generate_attachment_metadata wp_update_attachment_metadata POST-BOOKMARKS get_bookmark get_bookmarks wp_list_bookmarks POST-TERMS wp_get_post_categories wp_set_post_categories wp_get_post_tags wp_set_post_tags wp_get_post_terms wp_set_post_terms get_the_ID get_the_author get_the_content get_the_title wp_trim_excerpt CATEGORIES cat_is_ancestor_of get_all_category_ids get_ancestors get_cat_ID get_cat_name get_categories get_category get_category_by_path get_category_by_slug get_the_category_by_ID get_category_link get_category_parents get_the_category single_cat_title in_category is_category the_category wp_category_checklist wp_list_categories CATEGORY-CREATION wp_create_category wp_delete_category wp_insert_category CATEGORY-TAGS get_tag get_tag_link get_tags get_the_tag_list get_the_tags is_tag the_tags CATEGORY-TAXONOMY get_taxonomies get_term get_the_term_list get_term_by the_terms get_the_terms get_term_children get_term_link get_terms is_taxonomy (deprecated) is_taxonomy_hierarchical is_term (deprecated) taxonomy_exists term_exists register_taxonomy register_taxonomy_for_object_type

POST-OTHER add_meta_box remove_meta_box

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 103 of 109

33

May 15, 2012 Copyright 2005-2012

wp_get_object_terms wp_set_object_terms wp_insert_term wp_update_term wp_delete_term wp_terms_checklist ADMINS, ROLES AND CAPABILITIES add_cap add_role author_can current_user_can current_user_can_for_blog get_role get_super_admins is_super_admin map_meta_cap remove_cap remove_role user_can USERS AND AUTHORS auth_redirect count_users count_user_posts count_many_users_posts email_exists get_currentuserinfo get_current_user_id get_profile get_userdata get_userdatabylogin get_usernumposts get_users get_users_of_blog set_current_user user_pass_ok username_exists validate_username wp_get_current_user wp_set_current_user get_author_posts_url USER META add_user_meta delete_user_meta get_user_meta update_user_meta get_the_author_meta USER INSERTION/REMOVAL FILTERS has_filter add_filter apply_filters current_filter merge_filters remove_filter remove_all_filters

wp_create_user wp_delete_user wp_insert_user wp_update_user LOGIN / LOGOUT is_user_logged_in wp_login_form wp_signon wp_logout FEED FUNCTIONS bloginfo_rss comment_author_rss comment_link comment_text_rss do_feed do_feed_atom do_feed_rdf do_feed_rss do_feed_rss2 fetch_feed fetch_rss (deprecated) get_author_feed_link get_bloginfo_rss get_category_feed_link get_comment_link get_comment_author_rss get_post_comments_feed_link get_rss (deprecated) get_search_comments_feed_link get_search_feed_link get_the_category_rss get_the_title_rss permalink_single_rss post_comments_feed_link rss_enclosure the_title_rss the_category_rss the_content_rss the_excerpt_rss wp_rss (deprecated) COMMENT, PING, AND TRACKBACK FUNCTIONS add_ping add_comment_meta check_comment comment_text comment_form comments_number discover_pingback_server_uri ACTIONS has_action add_action do_action do_action_ref_array did_action remove_action remove_all_actions

delete_comment_meta do_all_pings do_enclose do_trackbacks generic_ping get_approved_comments get_avatar get_comment get_comment_text get_comment_meta get_comments wp_list_comments get_enclosed get_lastcommentmodified get_pung get_to_ping have_comments is_trackback pingback privacy_ping_filter sanitize_comment_cookies trackback trackback_url trackback_url_list update_comment_meta weblog_ping wp_allow_comment wp_count_comments wp_delete_comment wp_filter_comment wp_get_comment_status wp_get_current_commenter wp_insert_comment wp_new_comment wp_set_comment_status wp_throttle_comment_flood wp_update_comment wp_update_comment_count COMMENTS LOOP comment_class comment_ID comment_author comment_date comment_time COMMENTS PAGINATION paginate_comments_links previous_comments_link next_comments_link

PLUGINS plugin_basename plugins_url get_plugin_data register_activation_hook register_deactivation_hook register_setting settings_fields

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 104 of 109

33

May 15, 2012 Copyright 2005-2012

unregister_setting menu_page_url SHORTCODES add_shortcode do_shortcode do_shortcode_tag get_shortcode_regex remove_shortcode remove_all_shortcodes shortcode_atts shortcode_parse_atts strip_shortcodes INCLUDE FUNCTIONS comments_template get_footer get_header get_sidebar get_search_form OTHER FUNCTIONS add_custom_background add_custom_image_header add_theme_support body_class current_theme_supports dynamic_sidebar get_404_template get_archive_template get_attachment_template get_author_template get_category_template|get_category _template get_comments_popup_template get_current_theme get_date_template get_header_image get_header_textcolor get_home_template get_locale_stylesheet_uri get_page_template get_paged_template get_query_template get_search_template get_single_template get_stylesheet get_stylesheet_directory get_stylesheet_directory_uri get_stylesheet_uri get_tag_template get_taxonomy_template get_template get_template_directory get_template_directory_uri get_template_part get_theme get_theme_data get_theme_support get_theme_mod get_theme_root

get_theme_root_uri get_themes header_image header_textcolor is_child_theme load_template locale_stylesheet locate_template post_class preview_theme preview_theme_ob_filter preview_theme_ob_filter_callback register_nav_menu register_nav_menus register_sidebar register_sidebars register_theme_directory remove_theme_mod remove_theme_mods require_if_theme_supports search_theme_directories set_theme_mod switch_theme validate_current_theme unregister_nav_menu wp_get_archives wp_get_nav_menu_items wp_nav_menu wp_page_menu wp_title FORMATTING FUNCTIONS add_magic_quotes addslashes_gpc antispambot attribute_escape backslashit balanceTags clean_pre clean_url convert_chars convert_smilies ent2ncr esc_attr esc_html esc_js esc_textarea esc_url force_balance_tags format_to_edit format_to_post funky_javascript_fix htmlentities2 is_email js_escape (deprecated) make_clickable popuplinks remove_accents sanitize_email sanitize_file_name sanitize_user sanitize_title sanitize_title_with_dashes

seems_utf8 stripslashes_deep trailingslashit untrailingslashit url_shorten utf8_uri_encode TIME/DATE FUNCTIONS current_time date_i18n get_calendar get_date_from_gmt get_lastpostdate get_lastpostmodified get_day_link get_gmt_from_date get_month_link the_time get_the_time the_modified_time get_the_modified_time get_weekstartend get_year_link human_time_diff is_new_day iso8601_timezone_to_offset iso8601_to_datetime mysql2date SERIALIZATION is_serialized is_serialized_string maybe_serialize maybe_unserialize OPTIONS add_option delete_option form_option get_alloptions get_site_option get_site_url get_user_option get_option update_option update_user_option ADMIN MENU FUNCTIONS add_menu_page remove_menu_page add_submenu_page remove_submenu_page add_object_page add_utility_page TOOLBAR FUNCTIONS add_node remove_node add_group get_node

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 105 of 109

33

May 15, 2012 Copyright 2005-2012

get_nodes FORM HELPERS checked disabled selected NONCES AND REFERERS (SECURITY) check_admin_referer check_ajax_referer wp_create_nonce wp_explain_nonce wp_get_original_referer wp_get_referer wp_nonce_ays wp_nonce_field wp_nonce_url wp_original_referer_field wp_referer_field wp_verify_nonce XMLRPC xmlrpc_getpostcategory xmlrpc_getposttitle xmlrpc_removepostdata user_pass_ok LOCALIZATION __ _x _n _nx _e _ex _ngettext (deprecated) esc_attr__ esc_attr_e get_locale load_default_textdomain load_plugin_textdomain load_textdomain load_theme_textdomain CRON (SCHEDULING) spawn_cron wp_clear_scheduled_hook wp_cron wp_get_schedule wp_get_schedules wp_next_scheduled wp_reschedule_event wp_schedule_event wp_schedule_single_event wp_unschedule_event CONDITIONAL TAGS INDEX comments_open has_nav_menu

has_tag in_category is_404 is_admin is_archive is_attachment is_author is_category is_comments_popup is_date is_day is_feed is_front_page is_home is_month is_page is_page_template is_paged is_preview is_search is_single is_singular is_sticky is_tag is_tax is_time is_trackback is_year pings_open MISCELLANEOUS add_query_arg admin_url bool_from_yn cache_javascript_headers content_url do_robots get_bloginfo get_num_queries get_query_var home_url includes_url is_blog_installed is_main_site is_main_query is_ssl log_app make_url_footnote (deprecated) nocache_headers remove_query_arg site_url status_header wp wp_check_filetype wp_clearcookie wp_die wp_footer wp_get_cookie_login wp_get_http_headers wp_hash wp_head wp_mail wp_mkdir_p

wp_new_user_notification wp_notify_moderator wp_notify_postauthor wp_parse_args wp_redirect wp_reset_postdata wp_reset_query wp_remote_fopen wp_salt wp_set_auth_cookie wp_upload_bits wp_upload_dir MULTISITE FUNCTIONS admin_notice_feed avoid_blog_page_permalink_collision check_import_new_users check_upload_size choose_primary_blog confirm_delete_users dashboard_quota display_space_usage format_code_lang get_site_allowed_themes get_space_allowed get_upload_space_available grant_super_admin is_upload_space_available ms_deprecated_blogs_file mu_dropdown_languages new_user_email_admin_notice redirect_user_to_blog refresh_user_details revoke_super_admin secret_salt_warning send_confirmation_on_profile_email show_post_thumbnail_warning site_admin_notice sync_category_tag_slugs update_option_new_admin_email update_user_status upload_size_limit_filter upload_space_setting wpmu_delete_blog wpmu_delete_user wpmu_get_blog_allowedthemes _admin_notice_multisite_activate_plu gins_page MULTISITE SITE/BLOG FUNCTIONS add_blog_option delete_blog_option get_blogaddress_by_domain get_blogaddress_by_id get_blogaddress_by_name get_blog_details get_blog_option get_blog_status get_id_from_blogname get_last_updated is_archived refresh_blog_details

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 106 of 109

33

May 15, 2012 Copyright 2005-2012

restore_current_blog switch_to_blog update_archived update_blog_details update_blog_option update_blog_status wpmu_update_blogs_date ms_cookie_constants ms_file_constants ms_subdomain_constants ms_upload_constants MULTISITE API add_existing_user_to_blog add_new_user_to_blog add_user_to_blog check_upload_mimes create_empty_blog domain_exists filter_SSL fix_import_form_size fix_phpmailer_messageid force_ssl_content get_active_blog_for_user get_admin_users_for_domain get_blogs_of_user get_blog_count get_blog_id_from_url get_blog_permalink get_blog_post get_current_site get_dashboard_blog get_dirsize get_most_recent_post_of_user get_sitestats get_user_count get_user_id_from_string global_terms

insert_blog install_blog install_blog_defaults is_blog_user is_email_address_unsafe is_user_member_of_blog is_user_option_local is_user_spammy maybe_add_existing_user_to_blog maybe_redirect_404 newblog_notify_siteadmin newuser_notify_siteadmin recurse_dirsize redirect_mu_dashboard redirect_this_site remove_user_from_blog signup_nonce_check signup_nonce_fields update_blog_public update_posts_count upload_is_file_too_big upload_is_user_over_quota users_can_register_signup_filter welcome_user_msg_filter wordpressmu_wp_mail_from wpmu_activate_signup wpmu_admin_redirect_add_updated _param wpmu_create_blog wpmu_create_user wpmu_log_new_registrations wpmu_signup_blog wpmu_signup_blog_notification wpmu_signup_user wpmu_signup_user_notification wpmu_validate_blog_signup wpmu_validate_user_signup wpmu_welcome_notification wpmu_welcome_user_notification

NEEDED TO LOAD MULTISITE found in file wp-includes/ms-load.php (since 3.0.0). get_current_site_name is_subdomain_install ms_not_installed ms_site_check wpmu_current_site wpautop wptexturize wp_filter_kses wp_filter_post_kses wp_filter_nohtml_kses wp_iso_descrambler wp_kses wp_kses_array_lc wp_kses_attr wp_kses_bad_protocol wp_kses_bad_protocol_once wp_kses_bad_protocol_once2 wp_kses_check_attr_val wp_kses_decode_entities wp_kses_hair wp_kses_hook wp_kses_html_error wp_kses_js_entities wp_kses_no_null wp_kses_normalize_entities wp_kses_normalize_entities2 wp_kses_split wp_kses_split2 wp_kses_stripslashes wp_kses_version wp_make_link_relative wp_rel_nofollow wp_richedit_pre wp_specialchars wp_trim_words zeroise

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 107 of 109

33

May 15, 2012 Copyright 2005-2012

Notes
______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________ ______________________________________________________________

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 108 of 109 33

May 15, 2012 Copyright 2005-2012

Back Page
THEME DESIGN Adding Navigation Menu support to a theme Developing a Colour Scheme Designing Headers CSS Horizontal Menus Dynamic Menu Highlighting Good Navigation Links Next and Previous Links Styling for Print Styling for Mobile Designing Your Post Meta Data Section Separating Categories in Post Meta Data Section Using Custom Fields with Post-Meta Customizing the Read More Customizing the Login Form Adding Administration Menus Formatting Date and Time Styling Lists with CSS Designing Headings Playing With Fonts Using Images Wrapping Text Around Images Fun Character Entities Smilies How to Use Gravatars in WordPress Adding Asides Protecting Your Email Address from Harvesters Theme Development Theme Review Theme Functions File Explained WORDPRESS AND CSS CSS - CSS within WordPress, and list of resources Know Your Sources - HTML, PHP, and CSS in general CSS Coding Standards - Best practices for coding CSS CSS Troubleshooting - Examining and debugging CSS CHEAT SHEETS http://creativeoverflow.net/4-advanced-wordpress-3-0-cheatsheets/ TUTORIALS http://wp.tutsplus.com/ http://codex.wordpress.org/Blog_Design_and_Layout www.siteground.com/tutorials/wordpress/ http://codex.wordpress.org/WordPress_Lessons http://themeshaper.com/2009/06/22/wordpress-themestemplates-tutorial/ First Steps With WordPress Using WordPress Themes Theme Development FAQ Themes, Layout and Design WordPress Lessons Lessons: Designing Your WordPress Site Lessons: Customizing Template Files WordPress Site Reviews DOCUMENATION http://codex.wordpress.org/Function_Reference http://www.dbswebsite.com/design/wordpress-reference/V3/ http://wpcandy.com/made/wordpress-reference-guide http://www.dailydocumentation.com/wordpress/ http://adambrown.info/p/wp_hooks

NeatInfo.com - by Jan Zumwalt Wordpress Theme Reference

Pg 109 of 109 33

May 15, 2012 Copyright 2005-2012

You might also like