While I’m definitely not the designer that any of the people who created these beautiful hCards, I was greatly impressed by them. In particular, I liked the personal hCard created by Tim Van Damme and decided to make my own version of it. Only since I’m using WordPress rather; than a static site, I wanted the page to be generated automatically from info stored with my user profile within WordPress. Unfortunately WordPress does not by default store all the information I wanted to display as part of the user profile.

Initially when I setup the author page, I used the Cimy User Extra Fields plugin to get those extra fields; however in the words of Lord Downey, “It, uh … lacked elegance.” Don’t get me wrong, Marco Cimmino has created a very powerful and useful plugin. My problem is that it’s too complicated for what I want to do. Then almost as though the WordPress developers read my mind, the release of WordPress 2.9 included a new filter making it simple to add/remove new fields to the user profile page.  So easy in fact that the following bit of PHP code added to my theme’s function.php file was all that was required to add the fields I needed.

function vl2_contactmethods( $contactmethods ) {
 // Add Twitter
 $contactmethods['twitter'] = 'Twitter';
 //add Facebook
 $contactmethods['facebook'] = 'Facebook';
 //add flickr
 $contactmethods['flickr'] = 'Flickr';
 //add linkedin
 $contactmethods['linkedin'] = 'LinkedIn';
 //add delicious
 $contactmethods['delicious'] = 'Delicious';
 //add phone
 $contactmethods['phone'] = 'Phone';
 //add phone-type
 $contactmethods['phonetype'] = 'Phone Type';
 //add locality
 $contactmethods['locality'] = 'Locality';
 //add region
 $contactmethods['region'] = 'Region';
 //add postalcode
 $contactmethods['postalcode'] = 'Postal Code';
 //add country
 $contactmethods['country'] = 'Country';

 return $contactmethods;
 }
 add_filter('user_contactmethods','vl2_contactmethods',10,1);

Of course just storing the info with the user’s profile isn’t enough; we also need to be able to pull it back out. This can be done using either the_author_meta or get_the_author_meta. I ended up using get_the_author_meta for two reasons:

1. I’m pulling the author’s meta info outside of the Loop.
2. I wanted to return, not echo the values, so I can manipulate them before displaying them.

But that still wasn’t complicated enough, after all I started this project wanting to generate an hCard, using some jQuery UI to give it a fancy accordion effect. First we load the javascript for that accordion effect, by adding the following to our author.php file.

<script type="text/javascript">
 $(function() {
 $("#accordion").accordion();
 });
 </script>

Next we get all the user fields by:

<?php if(isset($_GET['author_name'])) :
 // NOTE: 2.0 bug requires: get_userdatabylogin(get_the_author_login());
 $curauth = get_userdatabylogin($author_name);
 $id = $curauth->ID;
 else :
 $curauth = get_userdata(intval($author));
 $id = $curauth->ID;
 endif;

 $twitter = get_the_author_meta('twitter', $id);
 $flickr = get_the_author_meta('flickr', $id);
 $linkedin = get_the_author_meta('linkedin', $id);
 $delicious = get_the_author_meta('delicious', $id);
 $lastfm = get_the_author_meta('lastfm', $id);
 $phone = get_the_author_meta('phone', $id);
 $ptype = get_the_author_meta('phone-type', $id);
 $addr = get_the_author_meta('addr', $id);
 $locality = get_the_author_meta('locality', $id);
 $region = get_the_author_meta('region', $id);
 $postalcode = get_the_author_meta('postalcode', $id);
 $country = get_the_author_meta('country', $id);
 ?>

Now that we’ve got the data and the JavaScript; we need to combine it

<div id="authorbox">
 <?php if (function_exists('get_avatar')) { echo get_avatar((get_the_author_meta('user_email', $id)), '120'); }?>
 <div id="accordion">
 <h3><a href="#">About</a> <span><span><?php echo $curauth->first_name; ?></span> <span><?php echo $curauth->last_name; ?></span></span></h3>
 <div id="about">
 <p><?php echo $curauth->description; ?></p>
 </div> <!-- #about -->
 <h3><a href="#">Contact</a></h3>
 <div id="contact">
 <p><span><span><?php echo $ptype; ?></span><a href="callto:<?php echo $phone; ?>"><?php echo $phone; ?></a></span></p>
 <p"><a href="<?php echo get_the_author_meta('user_url', $id); ?>" rel="me"><?php echo get_the_author_meta('user_url', $id); ?></a></p>
 <p><span><?php echo $addr; ?></span><br/>
 <span><?php echo $locality; ?></span>, <span><?php echo $region; ?></span> <span><?php echo $postalcode; ?></span><br/><span><?php echo $country; ?></span></p>
 </div> <!-- #contact -->
 <h3><a href="#">Networks</a></h3>
 <div id="social-networks">
 <ul>
 <li><a title="View <?php echo $curauth->first_name; ?> <?php echo $curauth->last_name; ?>'s Profile" href="http://www.linkedin.com/in/<?php echo $linkedin ?>"><img src="<?php bloginfo('template_directory'); ?>/images/linkedin.png" alt="LinkedIn" width="48" height="48" /></a></li>
 <li><a title="Follow <?php echo $twitter ?> on Twitter" href="http://twitter.com/<?php echo $twitter ?>"><img src="<?php bloginfo('template_directory'); ?>/images/twitter.png" width="48" height="48" alt="Twitter" /></a></li>
 <li><a title="See <?php echo $flickr ?>'s photostream" href="http://www.flickr.com/photos/<?php echo $flickr ?>"><img src="<?php bloginfo('template_directory'); ?>/images/flickr.png" alt="Flickr" width="48" height="48" /></a></li>
 <li><a title="<?php echo $delicious ?>'s Bookmarks" href="http://delicious.com/<?php echo $delicious ?>"><img src="<?php bloginfo('template_directory'); ?>/images/delicious.png" alt="Delicious" width="48" height="48" /></a></li>
 </ul>
 </div> <!-- #social-networks -->
 <h3><a href="#"><?php echo $curauth->first_name; ?>'s Last 5 Posts</a></h3>
 <?php $my_query = new WP_Query('showposts=5&author='.$id); ?>
 <div id="5posts">
 <ul>
 <?php if ($my_query->have_posts()) : while ($my_query->have_posts()) : $my_query->the_post(); ?>
 <li><a href="<?php the_permalink(); ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a> <?php the_time('j F Y'); ?></li>
 <?php endwhile; ?>
 </ul>
 </div> <!-- #5posts -->
 </div><!-- #accordion -->
 </div><!-- #authorbox -->
 <?php else : ?>
 <h2>Not Found</h2>
 <p>Sorry, but you are looking for something that isn't here.</p>
 <?php endif; ?>

Oops, I almost forgot to mention; we need to make sure we’re loading jQuery & jQuery UI on the author page. Since I separate out the header stuff into it’s own file (header.php); I added this bit of code before the closing </head> tag in that file:

<?php //if (is_author()) wp_enqueue_script('jquery-ui-core');
if (is_author()) {
 wp_deregister_script('jquery');
 wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"), false, '');
 wp_deregister_script('jquery-ui-core');
 wp_register_script('jquery-ui-core', ("http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"), array('jquery'), '');
 wp_enqueue_script('jquery');
 wp_enqueue_script('jquery-ui-core');
} ?>

And that’s that. Now my author page will by default display my gravatar next to the Biographical Info entered in my profile. There will also be three other section available…

* Contact: Gives selected contact information for me.
* Networks: Displays icons for some social networks I use with links to my profiles on those networks.
* Last 5 Posts: Shows my latest posts.

Later when I have more time, I’ll update the zipped copy of the VectorLover2 theme on this site for people who want to download a complete copy of the code I used for the author pages.

Update: I forgot to thank Joost de Valk for his excellent article, User Contact Fields in WordPress 2.9.
Update 2: I changed the code to register jquery-ui-core, so that it recognizes jquery as a dependency. This tutorial had been working fine; but for whatever reason, it suddenly was trying to load jQuery after jQuery-UI (which doesn’t work so good).
Update 3: Hmm, now that I look back at this old post I realize a couple of things: 1) several of the links I’d intended to be here are missing (since corrected) and 2) this post was written worse than I thought it was.

I like using Now-Reading to track what books I’m currently reading, have read and want to read on my website. Unfortunately the plugin’s author has been too busy of late to update the plugin and one of the recent updates to WordPress caused Now-Reading’s admin menu to break (when using the single menu option). PHP is not a programming language that I’m really familiar with but I did some poking around in Now-Reading’s code and found if I changed this snip of code:

	if ( $options['menuLayout'] == NR_MENU_SINGLE ) {

		add_menu_page('Now Reading', 'Now Reading', 9, 'admin.php?page=add_book', 'now_reading_add');

		

		add_submenu_page('admin.php?page=add_book', 'Add a Book', 'Add a Book',$nr_level , 'add_book', 'now_reading_add');

		add_submenu_page('admin.php?page=add_book', 'Manage Books', 'Manage Books', $nr_level, 'manage_books', 'nr_manage');

		add_submenu_page('admin.php?page=add_book', 'Options', 'Options', 9, 'nr_options', 'nr_options');

To read like this:

	if ( $options['menuLayout'] == NR_MENU_SINGLE ) {

		add_menu_page('Now Reading', 'Now Reading', 9, 'add_book', 'now_reading_add');
		
		add_submenu_page('add_book', 'Add a Book', 'Add a Book',$nr_level , 'add_book', 'now_reading_add');
		add_submenu_page('add_book', 'Manage Books', 'Manage Books', $nr_level, 'manage_books', 'nr_manage');
		add_submenu_page('add_book', 'Options', 'Options', 9, 'nr_options', 'nr_options');

Then Now-Reading’s single admin menu worked properly again.

Ever since upgrading to the latest version of Rob Miller’s Now-Reading plugin, I noticed my single book pages were working but not displaying everything correctly. Specifically books I’d marked having been borrowed from my local library were being displayed as:

  • I borrowed this book fromlibrary

When they should simply have a line reading “I borrowed this book from my local library”. I had spent much
time fiddling with my templates trying to figure out how the upgrade broke them and today I figured it out. The truth is my template was just fine. The problem is the newer version of Now-Reading was applying a new filter to book-meta1. That filter is wpautop and it was wrapping my variable in <p> … </p> tags. Those tags screwed up the display and made my variable checks fail. To correct the problem, I went into now-reading/default-filters.php and commented out add_filter('book_meta_val', 'wpautop');. Now my single book pages look like they’re supposed to again. Yeah!

1 This is a custom field available in the back-end of the plugin and it is where I store the information telling my template if I borrowed the book and from whom I borrowed it.

I use Rob Miller’s excellent Now-Reading plugin to track all the books I’ve read and am reading here at CoffeeBear. After my recent site upgrade I decided to tweak the single book template for my library. I noticed that the latest version of Now-Reading allows you to note who read a given book on multiuser sites. As my wife occassionally posts here I wanted my reads to be marked as mine, but the default output of the function Rob implemented only displays the user’s login name. Seriously Rob, what were you thinking? If you did not want to give end users the option to select how they want their name to print out why wouldn’t you go with display_name?

I looked at the code Rob used and with a little help from the Practical PHP I hacked together my own function based on Rob’s. By default print_reader2 works the exactly the same as print_reader1 but by feeding it an additional parameter, you get your choice of what to use to display as reader’s name:

  • 0: Prints out the user_login aka the username you use to log into WordPress.
  • 1: Prints user_nicename, appears to simply be an all lower case version of the user’s nickname2.
  • 2: Prints display_name, from the “Display name publicly as” field in your WordPress profile.
  • 3: Prints first_name, from the “First name” field in your WordPress profile.
  • 4: Prints nickname, from the “Nickname” field in your WordPress profile.
function print_reader2( $echo=true, $reader_id = 0, $display = 0 ) {
	global $userdata;

	$username='';

	switch($display) {
		case "1": if (!$reader_id) { get_currentuserinfo(); $username = $userdata->user_nicename; } else { $user_info = get_userdata($reader_id); $username = $user_info->user_nicename; }; break;
		case "2": if (!$reader_id) { get_currentuserinfo(); $username = $userdata->display_name; } else { $user_info = get_userdata($reader_id); $username = $user_info->display_name; }; break;
		case "3": if (!$reader_id) { get_currentuserinfo(); $username = $userdata->first_name; } else { $user_info = get_userdata($reader_id); $username = $user_info->first_name; }; break;
		case "4": if (!$reader_id) { get_currentuserinfo(); $username = $userdata->nickname; } else { $user_info = get_userdata($reader_id); $username = $user_info->nickname; }; break;
		default: if (!$reader_id) { get_currentuserinfo(); $username = $userdata->user_login; } else { $user_info = get_userdata($reader_id); $username = $user_info->user_login;};
   }
	if ($echo)
		echo $username;
	return $username;
}

Side note: WordPress 2.5.1 got released today and it includes a security fix, be sure to update your blogs!

1 At least, I think it does. I’m not a programmer and I only know enough PHP to be dangerous to myself.
2 The WordPress Codex does not appear to define what this field is used for or why it exists, so that’s just my guess.

Text-Link-Ads is a nice service which I use to help pay the bills for running this site. They just released a new version of their WordPress plugin which I use to put their adverts on this site, so I installed it but in doing so it overwrote a couple of changes I’d made to the old plugin. I had made those changes as I like the service and I definitely like the additional income1, but I don’t like how the plugin makes the ad links less than obviously ads. So my changes in the plugin add a specific class which I can then style via CSS. Since I don’t want to have to keep redoing my customizations from scratch each time they release the plugin; I’m posting the code changes I make here.

Under function outputHtmlAds(), I changed the following line of code from:
echo "\n<ul>\n";</ul>

to:
echo "\n<ul class=\"tla_sponsor_link\">\n";</ul>

Also under function returnPostAd($postId), I changed:
return "\n\n<em>".$prefixes[$prefixIndex].":</em> $ad->before_text <a href=\"$ad->url\">$ad->text</a> $ad->after_text";

to:
return "\n\n<div class=\"tla_sponsor_link\"><em>".$prefixes[$prefixIndex].":</em> $ad->before_text <a href=\"$ad->url\">$ad->text</a> $ad->after_text</div>";

Side note: TLA, you guys should change the Our Blog to be called something else as the link doesn’t actually take users to your blog.

1 I don’t make enough from these ads to get rich mind you. Just enough to cover the costs of running CoffeeBear.net and maybe a cup of good coffee from my local coffee shop.