Category Archives: WordPress

http://wordpress.org/ WordPress: Semantic personal publishing platform

WordPress presentation hacks

One thing missing from the default WordPress setup is the lack of previous/next links. Fixing this is not really a problem though, as WordPress includes a number of template functions, among which are next_post and previous_post. Both of these take care of all the necessary logic, so that the correct links are displayed, and only when necessary, i.e. only when displaying a single post. I decided to put the links at the top of the post page, next to the post metadata such as categories and author (in the file /index.php):

<div class="meta"> 
    <span class="nav-prev"><?php previous_post('&laquo; %', ''); ?></span> 
    <span class="nav-next"><?php next_post('% &raquo;', ''); ?></span> 
    <?php _e("Filed under:"); ?> <?php the_category() ?> &#8212; <?php the_author() ?> @ <?php the_time() ?> <?php edit_post_link(); ?> 
</div>

Another thing that I thought would be nice, was only showing excerpts on pages with a large number of posts. This is also quite easy, thanks to the get_excerpt template function:

<?php if(sizeof($posts)>get_settings('posts_per_page')) : ?>
  <div class="storyexcerpt"> 
    <?php the_excerpt(); ?> 
  </div>  
<?php else: ?>
  <div class="storycontent"> 
    <?php the_content(); ?> 
  </div>  
  <div class="feedback"> 
    <?php wp_link_pages(); ?> 
    <?php comments_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?> 
  </div>  
<?php endif; ?>

Finally, I wanted to fiddle a little with the CSS, styling the posts so that a category specific icon is displayed next to posts in that category. To accomplish this, I had to add some category information to the class attribute of the div containing the post:

<div class="post<? foreach(get_the_category() as $cat){ print(' post-category-'.$cat->category_nicename);}; ?>">

With this in place, the CSS is easily tweaked to display an icon next to the post title (note that only the last one of the rules will be in effect for posts in multiple categories, so ordering is important):

.post-category-wordpress h3 { 
  background: url(/images/wp-button.png) no-repeat right;
}
.post-category-foaf h3 { 
  background: url(/images/foaf-tiny.png) no-repeat right;
}

Improving this approach to be able to handle more than one category icon at a time is left as an exercise for the reader…

WordPress and i18n

While WordPress gives you choices for translating the names of the weekdays for use with the post calendar, it’s not possible by configuration to choose which day a week starts with. Being used to starting the week on a monday – there’s a reason saturday and sunday are referred to as weekend, I just had to tweak the PHP code to generate output suitable for non-US bloggers.

The template function responsible for the calendar output is called get_calendar, and is located in the file /wp-includes/template-functions-general.php. The code that generates the actual output is located near the end of that function, and starts with a comment: // See how much we should pad in the beginning.

On the line following the comment is a calculation of the padding to be performed before the first day of the month. This should be changed by substracting 1 from the existing result:

$pad = intval(date('w', $unixmonth)) - 1;

Following the initial padding is the loop that outputs each of the cells containing a day of the month. At the end of the loop it is decided whether to skip to the next row, originally done after outputting saturdays, now changed to skipping after sunday (weekday zero):

if (60 == date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear)))
    $newrow = true;

Then, after the loop is finished, the padding after the last day of the month is determined. Just as the padding before the first day was decreased by one, the padding after the last day should be increased by one:

$pad = 78 - date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear));

The last thing to fix is the ordering of the labels in the calendar, and fortunately this is much easier. In the file wp-includes/locale.php, simply move the line assigning value to $weekday[0] (sunday) to the end of the list, after assignment to $weekday[6] (saturday):

$weekday[6] = __('Saturday');
$weekday[0] = __('Sunday');

The calendar should now display each week starting with monday.

Improving RSS output from WordPress

The default syndication output from WordPress is okay, but does leave room for improvement – even though it “defaults” to RSS 2.0, there’s RSS 1.0 hidden behind the scenes.

The first order of action is to fix the default page template to point to the RDF/XML output instead of RSS 2.0. In the file /index.php there are link elements in the head section of the HTML output, switching to RSS 1.0 is quite easy, simply change the RSS 2.0 line to the following (and remove the link to the 0.92 version):

<link rel="alternate" type="application/rdf+xml" title="RSS 1.0" href="<?php bloginfo('rdf_url'); ?>" />

In the meta section there is also a couple of links, one for RSS 2.0 that will be replaced by a link to RSS 1.0, and one for comments that is just dropped (an RDF/XML version may be added at a later date):

<li><a href="<?php bloginfo('rdf_url'); ?>" title="<?php _e('Syndicate this site using RSS'); ?>"><?php _e('<abbr title="RDF Site Summary">RSS</abbr> 1.0'); ?></a></li>

Now to the actual content of the RSS file: The default template includes, for each post, a dc:creator property that looks like this:

<dc:creator>mortenf (mailto:mort&#101;n&#64;&#119;as&#97;b.dk)</dc:creator>

That’s not terribly helpful for the Semantic Web, so I’ve hacked the template wp-rdf.php to include the following FOAF structure instead:

<foaf:maker>
  <foaf:Person>
    <foaf:name><?php the_author_firstname(); print ' '; the_author_lastname() ?></foaf:name>
    <foaf:nick><?php the_author_login() ?></foaf:nick>
    <foaf:mbox_sha1sum><?php print(bin2hex(mhash(MHASH_SHA1,'mailto:'.$authordata->user_email))) ?></foaf:mbox_sha1sum>
    <foaf:weblog rdf:resource="<?php bloginfo_rss('url') ?>"/>
  </foaf:Person>
</foaf:maker>

In addition to this improvement, the indication of categories could also use a little tune-up. The default output shows categories through the use of dc:subject, which is quite allright but somewhat too vague – how could anyone know that my category SemWeb/FOAF is essentially the same as Danny AyersKnowledge/FOAF category? To make up for this, it is possible to use the Description field in WordPress’ category system to assign a URI to each (or some) of the categories, and then generate appropriate statements by adding two lines to the the_category_rss template function in /wp-includes/template-functions-category.php:

if(preg_match('|^w+:.+/|',$category->category_description))
    $the_list .= '<foaf:topic rdf:parseType="Resource"><dc:title>'.$category->cat_name.'</dc:title><foaf:page rdf:resource="'.$category->category_description.'"/></foaf:topic>';

The results of these tweakings should show up nicely in the RSS feed – check it out here.