My colleague Rachel Smith presented a nice little WordPress challenge to re-create what she had done previously as old skool manual HTML page updating into her WordPress blog (see Postcards back through time). In the spirit of previous documentation of WordPress Theme hacking, here is the under the hood things I did, some variations on ones I have written previously WordPressing Dissected: Pachyderm Services and Making of a New Site: NMC Virtual Worlds.
This current write up includes a custom category template, direct database querying, custom fields, and maybe a little elbow grease.
Firstly, the original site of Rachel’s postcards features her original artwork, with the most recent one at the top, and icon links to previous works below. I would guess creating a new one is making a new HTML page, copying some source code to the top of the index, and updating the icons below.
Maybe it’s not all that onerous, but it is all manual writing of HTML, etc, and to me, really screamed for re-doing the WordPress Way, meaning that authoring is done via the simple WP interface, and pages and archives are automatically created. Plus you get comments (well if someone leaves some); Plus it is integrated into her current blog, not a hanging appendage.
Even in what she did before by hand is pretty much what one might define as blogging, and the resulting new site really sets up nicely.
The way it works now is that every new postcard is created as a regular blog post, marked by a special category. A custom category template, detailed below, generates the archive or main entry view. Database queries are thne used to generate a random set of 6 to go on the sidebar of her main template, and a special sidebar for the category page.
Here’s the juice on the code….
Custom Category Template
When you assign a WordPress post to a category, your regular stock template is designed to generate a category view, which is usually just a copy o the normal reverse chronological posting of your blog main page, just with filtering out just the posts in the category. But with very little expertise needed, you can modify the appearance (or functionality) of a category archive by creating a Category Template specific for that category. This can be done by copying the guts of the main
index.php or an
archive.php template, and rename it
category-XX.php where XX is the ID number for that category (you can find it be going to the control panel where you edit the post categories, and hover over the edit link- the URL reveals an id=XX in it as a unique identifier.
This means when WordPress is asked ti generate a category archive for Category XX it first sees if there is a specific one, and if not it uses
index.php. So her “postcards” category is id 129, so her template now includes a
In there I has able to add the intro block of text that appears at the top. The trick on this one was making it so it would pull only the single most recent blog post in this category.
The core of understanding WordPress is getting into the Zen of The Loop. In essence (at least my wording of it), when you are accessing different parts of WP content (the main page, an RSS feed, a category page, a tag page, etc), WP knows and automatically does a database query to get the appropriate posts, and then the templates “do something” with them, by cycling through The Loop (so your control panel has a place to tell it how many times to loop- if you want 3 recent posts on the front page or 50). This typically looks like in a template:
<?php if(have_posts()) : ?> <?php while(have_posts()) : the_post(); ?> .. do stuff <?php endwhile; ?> <?php endif?>
It already has done the correct database query without the template having to ask for it.
So to become a WordPress Jedi Master (maybe) one key is learning how to make your Own Loops. The gateway is the query_posts command which lets you steer The Loop. So for the category template, I want to make sure I grab posts just from the category I want and specify only 1 post (which by default is the most recent; so it means just inserting this above the code show above:
On the first iteration I put all the icons to previous posts below the current post card (like the original site), but then we decided to replace the regular sidebar content with this (see below). The way sidebars are customized var with the template design; with this one, it was just easier to replace the standard:
<?php get_sidebar(); ?>
with my own include statement:
<?php include (TEMPLATEPATH . "/sidebar-postcards.php"); ?>
All Postcards on the Sidebar
The sidebar on the Postcards page is designed to place icons and links to all previous postcards, in reverse chronological order. To associate an icon for each post, we used custom fields. Rachel already had a directory of these images, so we just uploaded a directory named squares to her
Since she had named the files systematically (2 digit month + 2 digit year) the easiest thing to do would have been to parse the post publish date to automatically retrieve the correct icon (we back dated the older post cards). The only problem was some of her icons were named *.gif and some were *.jpg, and while we could have converted them all to one format, I suggested using aq custom field named square to hold the name of the icon file for that post (this also allows them to be named anything and to have more than one per month).
The sidebar code also uses the same wp_query command as the category template- so you can have More Than One The Loop. I also use the Get Custom Field Values plugin to retrieve the info we need. The lop query this time calls for posts from this category, and using the value of -1 for
showposts to return all posts in the category:
For this one, all we need is the name of the custom field value (name of the icon file name) and link it to the post, so the code for
postcards-sidebar.php (new file added to template directory) looks like:
<h2 class="widgettitle"> <?php _e('All Postcards'); ?></h2> <div align="center"> <?php $my_query = new WP_Query('category_name=postcards&showposts=-1');?> <?php while ($my_query->have_posts()) : $my_query->the_post();?> <?php $postcard_icon = c2c_get_custom('square');?> <a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"> <img src="/wp-content/squares/<?php echo $postcard_icon ?>" border="0" alt="" style="margin:8px" /></a> <?php endwhile; ?> </div>
Random Postcards for the Main Sidebars
I figured while I was tossing loops, I could make one that pulled X number of postcard icon/links at random for the main sidebar.
Unfortunately, as an experiment showed, while the query_posts command has an option for
order= the only options are ASC or DESC (these are just part of the MySQL query; trying a value of
order=RAND() which works in mySQL queries did not work here.
So this called for a more low level loop creation, of calling the MySQL database directly. This involved a bit of playing with the syntax in phpMyAdmin, and sorting out finding the right structure to get the category (the relict category column in table wp_posts is not used; it is buried in the taxonomy and term relationship tables. The winning query to pull 6 random posts from category 139 was:
SELECT wposts.* FROM wp_posts wposts LEFT JOIN wp_term_relationships rel ON wposts.ID=rel.object_id WHERE rel.term_taxonomy_id = 139 AND wposts.post_type = 'post' AND wposts.post_status='publish' ORDER BY RAND() LIMIT 6
Using a custom select query I added this block to the main sidebar template:
<?php $postcards = $wpdb->get_results( "SELECT wposts.* FROM $wpdb->posts wposts LEFT JOIN $wpdb->term_relationships rel ON wposts.ID=rel.object_id WHERE rel.term_taxonomy_id = 139 AND wposts.post_type = 'post' AND wposts.post_status='publish' ORDER BY RAND() LIMIT 6", OBJECT); ?> <?php if ($postcards): ?> <?php foreach ($postcards as $post): ?> <?php setup_postdata($post); ?> <?php $postcard_icon = c2c_get_custom('square');?> <a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"> <img src="/wp-content/squares/ <?php echo $postcard_icon ?>" border="0" alt="" style="margin:1px;width:44%" /></a> <?php endforeach; ?> <?php endif; ?> <ul> <li><a href="/category/postcards/">all postcards...</a></li> </ul>
which produces six random icons in each reload.
the last touch was adding a tab link to the main template. Since most templates are done by cycling the WordPress Pages, and the link I wanted to add was a category, I just hard coded it into the part of the template that does the navigation heck the home page is hard linked so I just added another list item there.
That’s all! I think it took longer to write this up than to code it.
WordPress Theme Hacking (fun): Ninmah’s Postcards by CogDogBlog, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.