Categories
Uncategorized WordPress

Building Child Themes

On June 5, 2010 I spoke at WordCamp Chicago on Building Child Themes. Below are some resources on child themes that I thought might be useful if you are setting out to build a child theme.

If you have any questions about my slides, feel free to ask them here.

Categories
Code Uncategorized WordPress

PHPXref for WordPress, BuddyPress, bbPress and Thematic: Local and Updated

I often am working on a variety of WordPress, BuddyPress, and BBPress projects and enjoy working from a lot of not internet connected locations such as trains, buses, parks and the occasional rooftop. As such it’s very handy for me to a local version of PHPXref documents for the current trunk of these products. I’ve written a handy bash script to handle this for me.

[bash]
#!/bin/bash

# define locations
PHPXREFLOCATION=’/full/path/to/phpxref/folder/with/no/trailing/slash’

# check our internet connection
wget -q –tries=10 –timeout=5 http://core.svn.wordpress.org/trunk/ -O /tmp/wordpress.svn &> /dev/null
if [ ! -s /tmp/wordpress.svn ];then

# Remove old version
rm -r $PHPXREFLOCATION/output/*

# SVN up each piece
cd $PHPXREFLOCATION/source/thematic
svn up
cd $PHPXREFLOCATION/source/wordpress
svn up
cd $PHPXREFLOCATION/source/bbpress
svn up
cd $PHPXREFLOCATION/source/buddypress
svn up
cd $PHPXREFLOCATION/

# Build our new phpxref
perl phpxref.pl

#remove the tmp file so it’s not there for next time
rm /tmp/wordpress.svn

fi
[/bash]

I have a cron set up to run this at a few intervals that are least likely to bother me (currently 5am and 4pm). I hope this script helps you out. If you have a similar or better one, please let me know.

Categories
Uncategorized WordPress

I’m speaking at WordCamp Chicago

I’m excited to announce that I’m going to be headed to my childhood home metropolitan area to speak at WordCamp Chicago (and not just because it is happening only a few blocks from Mr. Beef on Orleans) . I’ll be presenting a talk entitled Building Child Themes that will be geared toward helping beginning developers take the next step in their child theme development, and solidify best practices for intermediate and advanced developers.  The talk will take place at 2:00pm and is part of the developer track.

I haven’t decided exactly what areas I’ll be addressing, but I plan to draw upon the Thirty Ten and Dirty Ten themes published on this site and the Thematic Theme Options theme that I’ve been working on recently. As I write my talk over the next month, you’ll find more information here. You can can follow my WordPress Feed if you’re looking to keep up to date on it. If you have any specific child theme questions that you’d like for me to address, please comment below.  Chicago, I can’t wait to see you!

Categories
Code Uncategorized WordPress

Dirty Ten, a Twenty Ten Child Theme using Output Buffers

After making Thirty Ten, my first Twenty Ten Child Theme, Devin Price asked for an example of a child theme that used output buffers.I’m not a big fan of using output buffers in my themes, but it’s a worthwhile trick to have in your bag. There are two main reasons for this:

  1. It makes code harder to read.
  2. It makes it so html isn’t being sent immediately to the browser, which often means your loading time increases

That being said, you shouldn’t be afraid to use them. Just make sure you are documenting your code (which you should be doing anyway), and that you are using some sort of caching so you don’t have to regenerate the page on every load (also something you should be doing anyway).

I’m going to do a quick example and show you how to make a twenty-ten child theme that adds a widget area above the image and below the Site title and Description. To do this we are going to start our buffer at wp-head and then use the filters used for the header image as an action to end it and add our widget.

[php]<br><br>add_action(‘wp_head’, ‘head_buffer’);
/**
* Start our buffer and Use filters as actions and add them to end our buffer depending on the header image
*
*/
function head_buffer(){
ob_start();
if ( is_singular() && has_post_thumbnail( $post-&gt;ID ) && $width > HEADER_IMAGE_WIDTH ) :
add_filter(‘post_thumbnail_html’, ‘clear_buffer_post_thumbnail’);
else :
add_filter(‘theme_mod_header_image’, ‘clear_buffer_header_image’);
endif;
}

/**
* Our filter is really an action
*
*/
function clear_buffer_header_image($html){
clear_buffer();
return $html;
}

/**
* The Buffer ender. Clear it, add to it, echo it.
*
* Replace the blank space after our site description div with our header widget. This is called by both
* of our action psuedo filters
*/
function clear_buffer(){
$buffer = ob_get_clean();
$header = preg_replace(‘#&lt;div id="site-description"&gt;.*&lt;/div&gt;#’,"$0".new_header_widget() ,$buffer);
echo $header;
}

function clear_buffer_post_thumbnail($html){
clear_buffer();
return $html;
}
[/php]

Our next step is to register our widget and add a function that will add the content of our widget.

[php]
/**
* This adds the content of our widget. Could we use a new sidebar-*.php file? yes, but it’s easier to keep all of this in one file
*
*/

function new_header_widget(){
ob_start();
?>
<div id="headerwidget" class="widget-area">
<ul class="xoxo">
<?php if ( ! dynamic_sidebar( ‘header-widget-area’ ) ) : // begin Header widget area ?>
<li id="search" class="widget-container widget_search">
<?php get_search_form(); ?&>
</li>
<li id="archives" class="widget-container">
<h3 class="widget-title"&><?php _e( ‘The Maker’, ‘dirtyten’ ); ></h3>
</ul>
&lt;li&gt;&lt;a href=’http://aaron.jorb.in’&gt;Wordpress Developer Aaron Jorbin&lt;/a&gt; creates themes and plugins for both the masses and the individual&lt;/li&gt;<br> &lt;li&gt;&lt;a href=’http://aaron.jorb.in/thirtyten’&gt;Thirty Ten&lt;/a&gt; is a Twenty Ten Child theme designed to teach you how to make child themes&lt;/li&gt;<br> &lt;/ul&gt;<br> &lt;/li&gt;<br><br> &lt;li id="meta" class="widget-container"&gt;<br> &lt;h3 class="widget-title"&gt;&lt;?php _e( ‘Meta’, ‘twentyten’ ); ?&gt;&lt;/h3&gt;<br> &lt;ul&gt;<br> &lt;?php wp_register(); ?&gt;<br> &lt;li&gt;&lt;?php wp_loginout(); ?&gt;&lt;/li&gt;<br> &lt;?php wp_meta(); ?&gt;<br> &lt;/ul&gt;<br> &lt;/li&gt;<br>&lt;?php endif; // end Header widget area ?&gt;<br> &lt;/ul&gt;<br> &lt;/div&gt;&lt;!– #headerwidget .widget-area –&gt;<br>&lt;?<br> $widget_area = ob_get_clean();<br> return $widget_area;<br>}<br><br>add_action( ‘init’, ‘dirtyten_widgets_init’ );<br><br>/**<br>* Register our widget<br>*<br>*/<br>function dirtyten_widgets_init() {<br> // Area 1<br> register_sidebar( array (<br> ‘name’ =&gt; ‘Header Widget Area’,<br> ‘id’ =&gt; ‘header-widget-area’,<br> ‘description’ =&gt; __( ‘The widget area in the Header. Optimized to use three widgets’ , ‘dirtyten’ ),<br> ‘before_widget’ =&gt; ‘&lt;li id="%1$s" class="widget-container %2$s"&gt;’,<br> ‘after_widget’ =&gt; "&lt;/li&gt;",<br> ‘before_title’ =&gt; ‘&lt;h3 class="widget-title"&gt;’,<br> ‘after_title’ =&gt; ‘&lt;/h3&gt;’,<br> ) );<br><br>}<br><br>[/php]

And that’s about it. It’s 111 lines after comments and white space. I’d strongly encourage you to add your own widgets, unless you want to be advertising for me ;).

The only other part is our css to style the widgets. This is also simple:

[css]<br>@import url('../twentyten/style.css');<br><br>#headerwidget{<br>clear:both;<br>width: 100%;<br>}<br><br>#headerwidget ul li{<br>float: left;<br>width: 280px;<br>margin-right: 30px;<br><br>}<br>[/css]

You can check out Dirty Ten, or Download it and use it.  You can also clone it from the mercurial repository.

Categories
Code Programming Uncategorized WordPress

Introducing Thirty Ten, my guide to creating a Twenty Ten Child Theme

WordPress 3.0 is introducing a new theme that is light years ahead of Kubrick (also known as the old WordPress default), that looks so good you won’t even mind running it on a live site. In addition to being a beautiful theme in it’s own right, it’s also easy to build upon and create your own child themes for. I’ll show you just how easy it is to make some substantial changes. We are going to move the two column Twenty Ten to a three column theme I’m going to call Thirty Ten.

I’m going to lay out a couple of ground rules for myself when building this theme:

  1. I’m not allowed to override any of the template files with my own version. I want this to be as easy to maintain as possible. This means that I have to use footer.php, header.php and all of the other files.
  2. No output buffers This means I can’t use an output buffer and then regular expressions to get around rule number one.
  3. I want the reader of this article to be able to take and borrow any piece of this theme and use it to modify their own theme Every part of this theme and tutorial is licensed under the GNU public license, just like WordPress

The first step is to create a theme folder and put a blank style.css and functions.php in it. This is where the bulk of the changes are going to come in. into our style.css document we are going to insert our header that looks like:

[css]
/*
Theme Name: Thirty Ten
Theme URI: http://aaron.jorb.in/thirty-ten
Description: A child theme of the 2010 default theme for WordPress.
Author: Aaron Jorbin based on work by the WordPress team
Author url: http://aaron.jorb.in/
Version: 1.0
Tags: black, blue, white, three-columns, fixed-width, custom-header, theme-options, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style
Template: twentyten
*/
@import url(‘../twentyten/style.css’);
[/css]

My next step is to follow the sage advice: “good artists borrow, great artists steal” and will use the 3c-fixed.css layout style from thematic. I also need to add a fix to make it work with the current Twenty Ten style in all browsers.

[css]
@import url(‘3c-fixed.css’);
#access{overflow: visible;}
#main{clear: both;}
[/css]

So in four lines of css, I’ve switched Twenty Ten from a two column theme to a three column theme. SWEET!

That’s how flexible twenty-ten is. I want to do more then that though, because that alone is boring. Let’s now move our navigation menu to be above our image. This step we are going to be almost as easy.

[css]
#header #access{
top: -240px;
position: relative;
}
#site-title {
margin:0 0 44px;
}
[/css]

All we are doing this time is making the site-title have a bit more of a bottom margin to bump down the image, and then filling that space with our menu. I also want to make a few cosmetic changes to the default link colors and also change the formatting in the footer a bit (which will make a lot more sense after you’ve read the rest of this tutorial) To do this I added the following css:

[css]
/* Change our default link colors */
a:link{
color:#fdb120;
}
a:visited{
color:#d00c0d;
}
a:hover{
color:#1143d8;
}
a:active{
color:#a67942;
}
/* Modify the footer to allow for a bigger description and nicer looking links */
#site-info{
width:250px;
}
#site-generator{
width: 535px;
}

#site-generator a{
background: none;
padding: 0 7px;
}

#jorbin-link a:link, #jorbin-link a:visited, #jorbin-link a:hover,#jorbin-link a:active {
color:#990000;

}
#generator-link a{
-moz-background-clip:border;
-moz-background-inline-policy:continuous;
-moz-background-origin:padding;
background:transparent url(../twentyten/images/wordpress.png) no-repeat scroll left center;
color:#666666;
display:inline-block;
line-height:16px;
margin-left:1px;
padding-left:19px;
text-decoration:none;
}
[/css]

Speaking of the header image, as much as I like the default ones, I want to include some of my own. That’s incredibly easy and leads us to our first additions to the functions.php file.

For this component, Aaron Hockley of Hockley Photography was nice enough to let me use a few of his photos that are available for you to download and use with Thirty Ten. To register some additional headers I’m using the following function:

[php]
add_action( ‘after_setup_theme’, ‘thirtyten_setup’ );
function thirtyten_setup(){

/* Add additional default headers All Photos are by Aaron Hockley of Hockley Photography */
$thirty_ten_dir = get_bloginfo(‘stylesheet_directory’);
register_default_headers( array (
‘lights’ => array (
‘url’ => "$thirty_ten_dir/images/lights.jpg",
‘thumbnail_url’ => "$thirty_ten_dir/images/lights-thumbnail.jpg",
‘description’ => __( ‘Lights by Aaron Hockley’, ‘thirtyten’ )
),
‘train’ => array (
‘url’ => "$thirty_ten_dir/images/train.jpg",
‘thumbnail_url’ => "$thirty_ten_dir/images/train-thumbnail.jpg",
‘description’ => __( ‘Train by Aaron Hockley’, ‘thirtyten’ )
),
‘bridge’ => array (
‘url’ => "$thirty_ten_dir/images/bridge.jpg",
‘thumbnail_url’ => "$thirty_ten_dir/images/bridge-thumbnail.jpg",
‘description’ => __( ‘Bridge by Aaron Hockley’, ‘thirtyten’ )
)

));
}
[/php]

This will add three choices for default headers to your site. It keeps all of the original default headers that come with Twenty Ten. If I wanted to get rid of any, I could use unregister_default_headers and just pass the name of the one I wanted to get ride of. Another option would be to create my own version of twentyten_setup. If you do that, make sure you include all the parts of that function you want to keep.

Another change that I want to make is the read more link. Twenty Ten uses the function twentyten_excerpt_more to make the link say ” …Continue reading → “. I’m going to make my own version that says ” …finish reading ” followed by the blog title. I do this by first adding the following function:

[php]
function thirtyten_excerpt_more($more){
return ‘&nbsp;… <a href="’. get_permalink() . ‘">’ . __(‘finish reading ‘.get_the_title() .”, ‘twentyten’) . ‘</a>’;
}
[/php]

Next I just have to deregister twentyten_excerpt_more and register my own. By adding the following lines to the function thirtyten_setup that I created earlier, I make sure that we remove twentyten_excerpt_more after it’s been created:

[php]
remove_filter( ‘excerpt_more’, ‘twentyten_excerpt_more’ );
add_filter (‘excerpt_more’, ‘thirtyten_excerpt_more’ );
[/php]

The Next change I want to make is to some of the strings. I want to have a slightly unique footer and I also want to change the meta text on single pages. As I learned in mangling strings for fun and profit/by WordPress lead Developer Peter Westwood, using the WordPress internationalization functions allows me to change almost any string in WordPress (or in this case, Twenty Ten). I use the following code for that purpose:

[php]
class Thirty_Ten_Text_Wrangler {
function site_generator($translation, $text, $domain) {
$translations = &get_translations_for_domain( $domain );
if ( $text == ‘Proudly powered by <span id="generator-link">%s</span>.’ ) {
return $translations->translate( ‘Proudly powered by<span id="jorbin-link"><a href="http://aaron.jorb.in">Aaron Jorbin\’s Idea</a></span>, <apan id="hockley-link"><a href="http://www.flickr.com/photos/ahockley">Aaron Hockley / Hockley Photography</a>, and <span id="generator-link"> </span>’ );
}
return $translation;
}
function single_meta($translation, $text, $domain) {
$translations = &get_translations_for_domain( $domain );
// With Tags
if ( $text == ‘This entry was posted in %1$s and tagged %2$s. Bookmark the <a title="Permalink to %4$s" rel="bookmark" href="%3$s">permalink</a>. Follow any comments here with the <a title="Comments RSS to %4$s" rel="alternate" type="application/rss+xml" href="%5$s">RSS feed for this post</a>.’ ) {
return $translations->translate( ‘This entry was posted in %1$s and tagged %2$s. It can always be found at <a title="Permalink to %4$s" rel="bookmark" href="%3$s">it\’s permalink</a>. Follow any comments left here with the <a title="Comments RSS to %4$s" rel="alternate" type="application/rss+xml" href="%5$s">RSS feed for this post</a>.’ );
}
//Without
elseif( $text == ‘This entry was posted in %1$s. Bookmark the <a title="Permalink to %4$s" rel="bookmark" href="%3$s">permalink</a>. Follow any comments here with the <a title="Comments RSS to %4$s" rel="alternate" type="application/rss+xml" href="%5$s">RSS feed for this post</a>.’ ) {
return $translations->translate( ‘This entry was posted in %1$s. It can always be found at <a title="Permalink to %4$s" rel="bookmark" href="%3$s">it\’s permalink</a>. Follow any comments left here with the <a title="Comments RSS to %4$s" rel="alternate" type="application/rss+xml" href="%5$s">RSS feed for this post</a>.’ );
}

return $translation;
}

}
add_filter(‘gettext’, array(‘Thirty_Ten_Text_Wrangler’, ‘site_generator’), 10, 4);
add_filter(‘gettext’, array(‘Thirty_Ten_Text_Wrangler’, ‘single_meta’), 10, 4);
[/php]

The final change is that I want to change how my authors page looks, or at least how posts show up on them. Twenty-ten makes it easy for child themes to have their own loop on a specific page type. All it takes is creating a loop-templatename.php  file and inserting your loop there.  So I made loop-author.php file and my custom loop lives there.

If you want to download this theme and use it for your own, you can Download thirtyten here. Also, take a look at to see this Twenty Ten Child Theme in action. And I’ve added all the code to a mercurial Google code site for you to easily make changes to. And finally make sure to comment below if you use it or do something cool with it so I can check it out.

UPDATE: I’ve added the ability to pick which style of three column theme you want.  Check out http://aaron.jorb.in/thirtyten/three-columns-three-ways/ to see the options.  And Follow the Thirty Ten subsite for more changes

Categories
Jorb.in Uncategorized WordPress

Constructing my new theme with Thematic

EDIT: I’ve switched to a Twenty Ten Child Theme

When I heard Ian Stewart’s announcement that he become an Automattician I figured it was a good idea to take a look at Thematic and see what it could do. I’ve mostly built my themes from scratch, but Thematic looked like it could streamline my work and hasten the development of sites. I figured if I’m going to try it out, I might as well give my site some love an a new theme. Thus Aaron.Jorb.In 3.0 was born.

I couldn’t believe how easy it was. Essentially Thematic makes theme development as easy as plugin development. Find the appropriate hook/filter and make the changes needed. For example, I wanted a slightly different loop for My Clients Category Page that also doubles as my Portfolio. By adding an action to wp_head, I am able to check if it is the My-Clients Category, and if so I can remove the default loop, add my own, and also add a notice to appear above the loop.

It’s also super easy to remove the sidebar. All I had to do was add an action to thematic_sidebar that returned false. Essentially Thematic has removed my need to make custom page templates when I want to keep 90% of the page the same.

Overall, redoing my site took about a third of the time that it took me to construct the last version. I would encourage anyone familiar with the plugin architecture of WordPress to take a look at Thematic. And the best part about it? It’s 100% gpl compatible and doesn’t cost a penny.

If you have any question how I added or did anything on here, please comment below.

Categories
Uncategorized WordPress

WordPress 3.0 sneak peak presentation from the Portland WordPress User Group

Last night I presented at Portland WordPress user group on some of the features and changes coming in WordPress 3.0. In case you weren’t in attendance, my slides are below, and what I went over can be summed up in a couple of points:

  • The changes taking place are going to make things easier for you, but nothing is groundbreaking
  • It’s still Alpha at this point. Things can and will change before it’s released.
  • Multisite in a true sense is not going to work on a lot of shared hosting plans. You can still use Sub Directories though

After my presentation I gave a quick case study of what would happen if the A-team decided to use WordPress Multisite. I figured BA would be put in charge and would create the initial site theateam.tld. The next step for him would be to create a site for himself, ba.theateam.tld . And of course when the time came, he would create a site for a film they were using as cover, Boots and Bikinis. He would use the domain mapping plugin and thus would have just created three sites in a matter of minutes.

Continuing with my case study, I built a quick plugin to demonstrate just how easy it is to add a new post type. Figuring that the team would want to show off their missions, that’s what it does.

[php]
/*
Plugin Name: A-Team Missions
Description: I love it when a plan comes together
Author: Aaron Jorbin
Version: 1.0
Author URI: http://aaron.jorb.in/
*/

function post_type_missions() {
register_post_type( ‘missions’,
array( ‘label’ => __(‘missions’), ‘public’ => true, ‘show_ui’ => true ) );
register_taxonomy_for_object_type(‘post_tag’, ‘movies’);
}
add_action(‘init’, ‘post_type_missions’);

function loop_missions(){
$missions = get_posts(‘post_type=missions’);
ob_start();
echo "<ul>";
foreach ($missions as $mission){
echo "<li>".$mission->post_title."</li>";
}
echo "</ul>";
}

add_shortcode(‘missions’, ‘loop_missions’);

[/php]

It’s just that easy. Two functions. The first adds our post type, and the second adds a shortcode to display the title of each mission so it’s embeddable anywhere.

If you want to know more about my presentation, Kathleen Mcdade was live tweeting it.

I’m going to have some more posts in the coming weeks about WordPress 3.0. If you have any questions, please ask below.

View more presentations from aaronjorbin.
Categories
Code Uncategorized WordPress

More Twitter Shortcodes for WordPress

Building on my WordPress Shortcode How To, here are two more Twitter shortcodes. I’ve also added a new project on google code to track all of my shortcodes.

The first new shortcode is for twitter search. It’s logically enough

 [twitter-search phrase='#haikufriday']

Like my last twitter shortcode, it caches the results for two minutes. It also includes some other options. You can specify the number of tweets using the number attribute. There is a default of 20. You can also specify a max and min tweet id using max_id and since_id . Finally, you can specify the language with the lang attribute. This defaults to English.
[sourcecode language=”php”]
function jorbin_firestream_search($atts){
extract(shortcode_atts(array(
‘phrase’ => false,
‘lang’ =&gt; ‘en’,
‘max_id’ =&gt; false,
‘since_id’ =&gt; false,
‘number’ =&gt; ’20’
), $atts));
if (‘phrase’ == false){
return false;
}
//*/ Build our search url and transient name
$transient = ‘tweet-‘. esc_sql($phrase) . ‘&l=’ . esc_sql($lang);
$url = ‘http://search.twitter.com/search.json?q=’. urlencode($phrase) . ‘&show_user=true〈=’. urlencode($lang) .’&rpp=’ . $number;

if ($max_id != false){
$url .= ‘&max_id=’ . (int) $max_id;
$transient .= ‘&m=’ . (int) $max_id;
}
if ($since_id != false){
$url .= ‘&since_id=’ . (int) $since_id;
$transient .= ‘&s=’ . (int) $since_id;
}

if ( $tweet_display = get_transient($transient) ){
// It’s allready been brought
}
else {

if ($search = wp_remote_get( $url ) ){

$results = json_decode($search[‘body’]);

ob_start();
$tweets = $results-&gt;results;
//*/
foreach ( (array) $tweets as $tweet){
$tweetcontent = $tweet-&gt;text;
$newcontent = preg_replace(‘%@([^\s]*)%’, "<a href="http://twitter.com/\\1">@\\1</a>", $tweetcontent);
echo "<div class="twitter_shortcode"><p>
<img class="twitter_shortcode_image" src="&quot;.esc_url($tweet-&gt;profile_image_url).&quot;"><span class="twitter_shotcode_username"><a href="http://twitter.com/&quot;.$tweet-&gt;from_user.&quot;">".$tweet-&gt;from_user."</a>&nbsp;—&nbsp;</span>". $newcontent ."</p>
</div>";

}
$tweet_display = ob_get_clean();
set_transient($transient, $tweet_display, 300);
}
else
{
$tweet_display = "I’m sorry, no tweets are availailable at this time";
}
}
return apply_filters(‘jorbin_tweet_content’, $tweet_display) ;
}
add_filter(‘jorbin_tweet_content’, ‘make_clickable’ );
add_shortcode(‘twitter-search’, ‘jorbin_firestream_search’);

[/sourcecode]
Like before, there are some classes for you to work with that should make it easy for you to theme these shortcodes. If you want for me to add more, comment below.

The second shortcode allows you to get and display a list of the most recent trends on twitter using the shortcode:

[twitter-trends]

This one doesn’t have any attribute. The output is in an unordered list with the class of twitter-trends.
[sourcecode language=”php”]
function jorbin_twitter_trends(){

$transient=’twitter-trends’;
$url = ‘http://search.twitter.com/trends.json’;

if ( $tweet_display = get_transient($transient) ){

}
else{
$search = wp_remote_get( $url );

$results = json_decode($search[‘body’]);
$trends = $results-&gt;trends;
ob_start();
echo "<ul class="twitter-trends">";
foreach ($trends as $trend){
echo ‘<li><a href="’ . esc_url($trend-&gt;url) . ‘"> ‘. esc_html($trend-&gt;name) . ‘</a></li>’;
}
echo "</ul>";
$tweet_display = ob_get_clean();
set_transient($transient, $tweet_display, 120);
}
return $tweet_display;
}

add_shortcode(‘twitter-trends’, ‘jorbin_twitter_trends’);

[/sourcecode]
If you use any of these, let me know. If there are any improvements or more you want to see, comment below.

Categories
Uncategorized WordPress

Portland WordPress User Group Presentation Upcoming

I’m going to be speaking at the March Portland WordPress User Group Meeting on March 18th at 6:00pm at Webtrends and demonstrating some of the features that are coming up in 3.0. I’m aiming for this to be beneficial for both users and developers.

Right now, I plan on covering:

  • What the Multisite features mean to both users and developers
  • How to enable Multisite once you’ve upgraded
  • How to add and customize custom menus on your site
  • How to add a custom post type

If there is anything else that you would like for me to cover, please comment on the post there. I hope to see you there!

Categories
Programming Uncategorized WordPress

Commit: The Story of Writing a WordPress Patch

Hanging out in the #WordPress irc channel or on the wp-hackers mailing list, a question that comes up from time to time is “How do I get a bug patched”. I recently had a patch committed, so I thought I would detail the process from start to finish to help others get an idea of the process. I can’t guarantee that others will have the same experience, or that even I will have the same experience next time, but this was how I had my first substantial patch committed to WordPress.

The process for me started by seeing a post by Jane Wells talking about a few UX enhancements she wanted to see handled during the recent patch sprint. One that I noticed hadn’t received any attention was Showing the status of an admin attempts an e-mail change under the new multisite configuration. I took a quick look at the relevent code and figured this was something I could patch.

Lesson 1: Make it easy for coders and non-coders to see the change

After I wrote my first iteration of a patch, I hopped into #wordpress-dev and Andrew Nacin recommended that I add a screenshot to make it easier for Jane to see the change.  I couldn’t agree more that this was a great idea. After all, why should you need to apply my patch & test it, or understand the code behind it just to comment on it.

Lesson 2: Just because you write the patch, doesn’t mean others don’t have good ideas for it

I then waited till I was in #wordpress-dev at the same time as Jane and brought up the ticket. This led to a conversation between Jeremy Clarke, jane and myself about the best way to let users know. During this time I went thought a few other iterations and shared those on the ticket. We didn’t come to a firm conclusion, and the next morning Nacin commented with a suggestion on the ticket.

Lesson 3: Sometimes one small change leads to another

The next day I once again headed to #wordpress-dev where Jane, Nacin, and I took another stab at it and decided that an inline warning box would give the proper notification without being distracting. While writing the final version of the patch I noticed that all warning boxes automatically moved to the top of the screen. Nacin took ownership of fixing this, made a few minor changes to my patch and committed changeset #13446.  Now not only will users be able to see pending admin e-mail changes, but developers can use the existing UI warnings inline.

Overall, the process to fix this UX bug took four people and multiple iterations.  I want to thank all three others for assisting me. While there are times that errors make it into the released version of WordPress, I hope this story gives you the idea of the effort that the core development team takes to make sure only the highest quality code and user experience for users.