Category Archives: Templates

Changes and additions to template files

Theme Change

WordPress has just released 3.5 beta 1, and with it the Twenty Twelve theme. As this blog is about WordPress, it seems fitting to use it as the blog’s theme.

EDIT: Temporary change to a dark theme because of the falling snow feature đŸ™‚

Podcast Feed

Since my site has weekly MP3 uploads, it makes sense to create a podcast feed for it. Unfortunately, those updates were implemented with custom post types, which don’t generate podcast feeds automatically with the <enclosure> tags. Thus I would have to generate a custom feed myself.

The Codex page on Customizing Feeds explains how to get a custom post type to use my own custom feed. Since I’m using a child theme, I used get_stylesheet_directory() instead of get_template_directory().

When I first setup the custom post type and imported the existing content, the meta value _wp_attached_file included the full URL. It still does as the custom insert post functions for the custom post type have been written that way. Thus to generate the path to the file (to get the filesize for the RSS feed), I had to modify the output of get_attached_file() by using the get_attached_file filter.

Using the default RSS2 template as a starting point, I modified the template to produce a feed which more or less follows the iTunes format. The major challenge was getting the filesize of the MP3 files, this was done with the PHP filesize() function.

$size = filesize( get_attached_file( $child->ID ) );

The author and subtitle fields were field with the available post meta stored with the custom post type.

A strange problem I encountered was that this worked perfectly with iTunes on my test setup, but iTunes refused to recognize the feed properly on the live site. This was solved by using feedburner, and subscribing to the feedburner feed instead. However, this still doesn’t explain what’s wrong with the feed on the actual site which prevents iTunes from getting it properly.

Adding Links

This should be an easy thing to do. I added a page and created an unordered list of links. Done!

While looking at the WordPress admin options, I noticed a section for Links. That seemed a much better way to insert links. After all, if the functionality is already built in, why write the HTML code manually?

The problem is that the collection of links only seem to be used by the built in Links widget. This will limit it to the sidebars, which isn’t what I want. I want the list to be displayed on a page.

The solution is the wp_list_bookmarks() function. Create a page template then insert that function into the template.

Create a page and set the Links template you just created as the page template. There’s no need to put anything in the content section. Populate the Links area and WordPress will do the rest.

Another advantage of this method is that the task of keeping the links list updated can now be passed over to a non technical user as the interface is pretty simple.

Adding another Custom Post Type

A new requirement came in for the site I manage. There was a need to add about 3 years worth of question and answer PDF files to the site. The nature of this was similar to the newsletters. Each post would contain a link to a PDF file. The title would hold the question, but the writing area would not be deactivated so the question could be split if it is too long.

It is very likely that there would be similar files in the future, so I decided to make this a custom post type so a non techie administrator can handle future uploads. I considered doing this as a plugin, but I’m still not sure how to include page templates as part of plugins, so I decided to just incorporate it into my custom theme, like the other post types.

The first thing to do was to register the post type using the register_post_type() function. Straightforward stuff.

In the following paragraphs, {cpt} should be replaced with the name of the post type. If the custom post type is named “Books”, loop-{cpt}.php means loop-books.php.

The loop-{cpt}.php template file is where I customize the look of each custom post type. This is where I choose what to display and how to show it. In this case, I printed the words “Download the answer: “, followed by a link to the PDF file with the answer. As this is handled by the template, the look of every post will be consistent and this will not depend on the uploader entering the proper wording into the content area.

Next came the {cpt}-template.php file. This modifies the query so it only selects posts of the custom post type I’m interested in displaying. It then calls the loop template file using get_template_part( 'loop', {cpt} ); A blank page is then created in the admin area and assigned this page template. A link is added to the menu so this page shows up in the menu system.

A single-{cpt}.php file is also created. It calls the loop template using get_template_part() as well.

I also had to edit the sidebar.php file. My sidebar shows date archives for each custom post type. Which one to show depends on which post type is currently displayed. I registered a new widget area in functions.php, then modified the if-elseif statements in the sidebar.php file so it could support new post type. To see which post type is currently displayed, the get_post_type() WordPress function is used. I can’t remember what I was previously using, but it wasn’t good enough.

Another change was to style.css. Instead of targeting each widget area by ID to make them align right and set the sidebar width, I realized I could just use the widget-area class instead.

On the admin side, a meta box had to be added. I had already done this before so it was a simple matter of copying and editing the existing code. The meta_box class described in earlier posts is flexible enough to handle this with no problems. I did make sure to look through the save() function to make sure it could support the new file name format without any unpleasant surprises.

After all these code additions, I now have a new custom post type I can use to add question and answer PDF files through the admin interface. I added the existing content manually, and will teach the administrator to upload future ones.

The new custom post type gave 404 errors when first used. I found that it was necessary to place flush_rewrite_rules() into the functions.php file as the usual method of resaving the permalinks didn’t work. However, after refreshing the page, the 404 errors went away and I could take out the flush_rewrite_rules() line. It is important to remove this line once the site works, or the site will be severely slowed by the constant regeneration of rewrite rules.


This post is on internationalization, specifically for the Chinese subsite. Those who have been following along will know that I have a custom post type for newsletters, and that this is displaying a link to the PDF file to be downloaded by getting the URL from the _wp_attached_file meta value. For the English version, it displays some text before the link (“Download MM: “). Obviously, this text should be in Chinese for the Chinese subsite. Looks like internationalization is a good way to achieve this.

Declare Theme Text Domain

Put this on top of the functions.php file.

load_theme_textdomain('theme_name', STYLESHEETPATH . '/languages');

Mark String as Translatable

The next step is to mark the ‘Download MM’ string as something to be translated. This is done by putting it in a special function __()

__( 'Download MM', 'theme_name' )


This is a program which will get all the translatable strings out of the source code and create a .po file. It also provides an interface for supplying the translation and automatically generates the .mo file.

Rename Files

The final step is to copy the .po and .mo files to the theme’s languages folder (newly created). It is also necessary to rename them to and zh_CN.po so that the translated string would get picked up correctly.

Resources Used

The link on the WordPress Codex to the guides on the Urban Giraffe are excellent.

Additional Widget Areas

In my theme, the sidebar is filled populated by using widgets. It would make sense for the links there to change depending on the type of content in the main window. If sermons are shown, then links for speakers, themes and sermon archives should be displayed. If it is newsletters, then categories and newsletter archives should be shown. For pages, a list of all the pages should be displayed. This was accomplished by adding more widget areas to the theme, then displaying the relevant widget area depending on what the main content is.

Adding Widget Areas

First, remove the existing action to initialize the default twenty ten widgets. The twenty ten function will be called later.

remove_action('widgets_init', 'twentyten_widgets_init');

Write a new function to call the default twenty ten widget function, and add the extra code for the additional widget areas.

function mbpc_widgets_init() {

	// Area 3, will show up when certain conditions are met, see sidebar.php 
	register_sidebar( array(
		'name' => __( 'Third Widget Area', 'twentyten' ),
		'id' => 'third-widget-area',
		'description' => __( 'The third widget area', 'twentyten' ),
		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
		'after_widget' => '</li>>,
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );

	// Area 4, will show up when certain conditions are met, see sidebar.php 
	register_sidebar( array(
		'name' => __( 'Fourth Widget Area', 'twentyten' ),
		'id' => 'fourth-widget-area',
		'description' => __( 'The fourth widget area', 'twentyten' ),
		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
		'after_widget' => '</li>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>',
	) );


Hook the function onto the widgets_init action.

add_action('widgets_init', 'mbpc_widgets_init');

There will now be additional widget areas which can be customized from the admin interface.

Loading Sidebars

This is relatively easy. WordPress already has the functions to check if a sidebar is active and to include it in a theme. In fact, it’s all there in the existing sidebar.php code. Use the is_active_sidebar('widget-name'); and dynamic_sidebar('widget-name'); functions.

Conditional Widgets

At each point in the code where a widget is loaded, there is a conditional check. To check for custom post types, use is_post_type_archive('cpt-name');. To check if it’s a custom taxonomy, is_tax(). For page templates, is_page_template('template-name.php');

By modifying the conditions to check for categories, pages, etc, I could choose a widget to display depending on the main content.

Add the Widgets

Now go into the admin interface and setup the widgets!

Built in Categories with Custom Post Types

How to do that is covered in detail in this post on adding a new custom post type.

However, view by category doesn’t work by default with custom post types. This is because the query doesn’t cater for it, thus I had to override category.php and modify the query.

Copy category.php from the twenty ten theme and paste it in my own theme folder. Add the following code before the loop is called.

global $wp_query;
$args = array_merge($wp_query>query,array('post_type'=>array('post','newsletter'),'paged'=>get_query_var('paged')));

This file has also been modified the call the custom loop for newsletters because that post type will have some extra meta data for display.

Custom Post Type Archives Part 4

Phew, custom post type archives are causing lots of problems. Three separate posts about them already, and the plugin was the one which broke WordPress 3.1. Well the updated version doesn’t. However, this led to a thought. Since it’s supposed to be built in, could I do it without using the plugin? After all, I was just after some very basic functionality. The answer turns out to be yes, well, almost.

Enabling the Feature

There is an attribute has_archive in the register_post_type() function which activates the archives feature, but it defaults to false. I added the code in to set this to true. This information was from Mark McWilliams, the same post also gave some hints on how the permalinks would look like.

Disabling the Plugin

The next step was to disable the plugin and see what stops working. Looks like the sidebar has some problems, which also prevents the admin bar from loading properly. The month listing from the custom widget wasn’t appearing at all.

Fixing the Widget

The widget depends on the custom get_post_type_archives() function, explained in Part 2, to do its magic.

Using a debug echo statement and commenting out suspect lines, I found the problem in one of the custom functions provided by the plugin. It returns the permalink of the post type. This can actually be generalized as

get_bloginfo('url') . '/' . $post_type . '/';

Now I get output with a link to the archives by date, but it wasn’t showing the correct number of months. Why??

Filter getarchives_where

Even the plugin just let the built in WordPress function wp_get_archives() do the hard work, so why did it work with the plugin activated? A closer look at the function itself, and the way it was used by the plugin, revealed that wp_get_archives() was insufficient to get archives by post type. It applies a filter to get the correct SQL Where clause. This was used by the plugin.

Since I only want that function, I copied the entire thing over to my own functions.php file.

function pta_wp_get_archives_filter($where, $options) {
	if(!isset($options['post_type'])) return $where; // OK - this is regular wp_get_archives call - don't do anything
	global $wpdb; // get the DB engine
	$post_type = $wpdb->escape($options['post_type']); // escape the passed value to be SQL safe
	if($post_type == 'all') $post_type = ''; // if we want to have archives for all post types
	else $post_type = "post_type = '$post_type' AND"; // otherwise just for specific one
	$where = str_replace('post_type = \'post\' AND', $post_type, $where);
	return $where;
add_filter('getarchives_where', 'pta_wp_get_archives_filter', 10, 2);

Now the archive links work and the correct number of links are displayed, depending on what the post type is!

Archive Templates

This approach led to my custom post types being displayed incorrectly as they now use the archive.php template file. It only displays the excerpts for archives, so the shortcodes and meta data no longer show up. As each post will be very short in length, I want the full content and meta data to show up, just like it does on the main page listings.

The solution to this was simply to copy archive.php to the child theme, rename it archive-{post-type}.php, and change the function call to the loop so that it calls my previously written custom loops.

Page Templates

{post-type}-template.php were previously used for both the display of the full listing as well as the archive pages. With WordPress 3.1, archives are handled by the archive template pages. Thus, the if-else conditions which handled query_posts() can be removed. The page templates will be used just for display of all the custom posts.


With all these changes, I can now use one less plugin and use more of the functionality available in WordPress Core.

Custom Post Type Archives Part 5

Adding a new Custom Post Type

As before, use the register_post_type() function to register a new custom post type. This will be named ‘newsletter’ and will be for the weekly messengers. The name ‘newsletter’ was chosen as it is the most generic description of this type of content. Using the specific name would make it more troublesome should I need to reuse this code in the future.

The key thing I wanted to do here is to let it use the built in categories. This is done by adding 'taxonomies' => array('category') to the array of arguments passed into the registration function. Additional taxonomies can be added to the array if necessary. This tip was found at deluxeblogtips

The rest of the steps are a repeat of what was done for the sermon post type. A custom loop file was created, the main feature in this loop is the code to get the memory verse from the custom fields and display it in a blockquote.

Similar to the sermon post type, all the newsletter entries will be displayed with a custom page template. This modifies the Query so that it only gets the newsletter post type. The same trick of checking for the existence of the pagename array key is used to check if the template is being used for the chronological archives or the normal display page.

A custom template file is also needed for single posts. It’s the same as the sermon one except that it calls a different loop.

I also had to enable post type archives in the Custom Post Type Archives plugin for my new custom post type.

Testing for Post Type Archives

The Custom Post Types plugin provides the function is_post_type_archive() which allows me to check if I’m on an archive page for a custom post type.

By using this, I can load different sidebars depending on whether I’m viewing custom post types or normal blog posts. The sermon post type is displayed with sermon-template.php, has views by taxonomy and also chronological archives. To cover these cases, the current code is

if(is_post_type_archive('sermon') || is_tax() || is_page_template('sermon-template.php'))

The is_tax() function will probably have to be made more specific when new post types and taxonomies are added. This line is placed in my own version of sidebar.php, which will override the default. The idea is to show the primary widget area for sermon types, and the secondary sidebar for other things. The widgets will be arranged so that this makes sense.