Notes on the 2010 WordPress Theme

Here are some of my random thoughts after going through the files of the new TwentyTen (2010) theme which will be introduced in WordPress 3.0.

header.php isn’t poetry at all

The content of the <title> should be generated within functions.php by using the wp_title filter, so that plugins and users can overwrite it. In header.php we would have only:

<title><?php wp_title('|', true, 'right'); ?></title>

and in functions.php something like:

add_filter('wp_title', 'twentyten_title', 10, 2);

function twentyten_title($title, $sep) {
	global $post;

	$title = wptexturize($title);
	$page_no = get_query_var('paged');

	if (is_front_page())
		$title = get_bloginfo('title') . ' ' . $sep . ' ' . get_bloginfo('description');
	elseif (!is_feed())
		$title .= ' ' . get_bloginfo('title');

	if ($page_no > 1)
		$title .= ' (page ' . $page_no . ')';

	return $title;

Theme’s stylesheet style.css should be loaded after the wp_head() call, so that users can overwrite styles added by the plugins.

Header image should be a CSS background image not an <img>. It should also be added through an action call so that plugins or users can remove or alter it.

Doctype is the only HTML5

Why not use at least <header>, <footer>, <nav> and <aside> if we have decided go with HTML5? If it’s because of IE6 then we can use conditional comments and that little amount of javascript that is necessary to construct those unknown elements.

Everything is <div>s

Site title and description should be placed inside paragraphs. Additionally <strong> and <em> could be used to represent their hierarchy:

<p id="site-title"><strong><a href="...">...</a></strong></p>
<p id="site-description"><em>...</em></p>

The same goes for .entry-meta, .site-info and .site-generator. It is better to use paragraphs instead of generic divs whenever possible.

Widgets are not lists

It is totally not semantic to place block type content inside inline elements (which lists are). Nested lists can also cause some unexpected and not-so-easy-to-work-around styling and targeting issues. Let’s avoid them.

Function Exists

Why are we calling function_exists('twentyten_unique_function') before every function that is unique to the theme?

Relative vs. 72 pixels per inch

Web is meant to be flexible and accessible on all devices. Thus, I suggest we:

  • don’t use pixels for sizes, and
  • include a mobile stylesheet.

Currently the baseline — font size × line height × paragraph spacing — is 16 px × 24 px × 24 px, which is equal to 1 × 1.5 ×1.5 = 2.25 in relative values. The default font size should also be a relative value — medium — which is equal to 16px in most of the browsers.

Every element should have a 2.25 baseline — entry meta, for example, is currently set at 12 px or 0.75 of the base font size. With the same line height of 1.5, it would need a 2.25/0.75/1.5 = 2 em paragraph spacing (bottom margin).

Heading line height of 1.5 is too much. It should be around 1.25 which allows to have wider bottom margin.

When spacing individual HTML elements, it is good to think that every element is responsible for the spacing below it.

Order of comment input fields

I have read the post and now I want to leave a comment — why do we increase the chance of me loosing that great idea by asking for my name and email address before the comment itself?

Use Contact Form 7 to collect business leads and enquiries? I created Storage for Contact Form 7 plugin which stores them safely in WordPress database.

Get it now for only $19 →


  1. Ryan says:

    There are mixed views on whether things like typical widget areas should be as list items or not. Many people have differing opinions on this.

    The HTML5 spec. isn’t released yet, so I wouldn’t like to see HTML5 elements being used yet. Inserting conditional comments to hack around lack of support in IE for not supporting a standard which isn’t even a standard yet is not a good either IMO.

    I definitely agree with your sizing and title ideas though.

    • Kaspars says:

      Ryan, I think list implies a relationship between the list items and in case of widgets there is none. Secondly, block elements are not allowed inside lists. Lastly, there is the <aside> element in HTML5 which sounds like a good choice for widgets.

      If we are not using any of the HTML5 than it doesn’t make sense to specify an HTML5 doctype.

  2. Matt says:

    The functions in functions.php are wrapped in a function_exists check so that child themes can completely and easily override the functions.

    • Kaspars says:

      Matt, why not use filters? Something like:

      function twentyten_function($args) {
      	if ($custom_return = apply_filters('twentyten_function', $args))
      		return $custom_return;
      	// Here goes the default behavior of the function
  3. Jeff Waugh says:

    I disagree with your point about the header image — given that it’s customisable in the admin backend, surely it’s better to use the method that is faster to display on the client side, ie. the <img> element?

  4. Kaspars says:

    Jeff, that header image is not part of the content — it used mainly for illustration purposes and thus CSS would be more appropriate (presentation vs. content). I think even inline CSS, such as:

    <div id="header" style="background-image:url(...)"></div>

    would be better than <img>.

  5. Otto says:

    I dislike twentyten myself, but for different reasons than you do.

    1. Adding filter functions for front page display to the functions.php file is the wrong way to do it. That function and filter should be in the header.php file. Why? Because functions.php is loaded on every page load, even admin page loads. A function should be close to where it is used, and not loaded when it’s not used. To that end, putting the code that generates the header into the header makes the most sense, is the fastest, and makes it easy to find things. If somebody wants to change the title, then making them search through a big ass functions.php instead of simply looking in the header.php is stupid.

    2. HTML 5 elements = I agree. However, IE doesn’t cope too well with them. Yes, you can use the HTML5 shiv from Google and the IE8.js to make things work (see ), but why go to all that trouble? We can move to real HTML 5 when IE catches up. In the meantime, this works fine.

    3. P vs. DIV – This is questionable. Actually, I’d say that they should be in H1 and H2, respectively. Post titles and such should be H3 and below.

    4. Actually, Lists are the *only* correct way to build sidebars. Anybody doing it any other way is wrong. Furthermore, Lists are not inline. UL, OL, and DL, are all block-level elements.

    5. All the function_exists bits are there to allow child themes to override those functions by simply redefining them, if necessary. This is not a valid critique in any way.

    6. I agree with both mobile stylesheet and not using px values. In practice, the px thing isn’t going away, too many theme designers are overly sensitive about this one.

    7. I don’t understand the Comment input fields thing. Fields should be before the comment block, not after. If they’re after, then it’s more likely that a user will submit a comment without a name on it, and the comment will be lost. He’s got his UI design ideas totally reversed here. Your comment form is confusing, in fact, because it’s asking for data not only after the fact, but in a different order from every other site on the internet. You need to standardize, man.

  6. Ryan says:

    If we are not using any of the HTML5 than it doesn’t make sense to specify an HTML5 doctype.

    There is no such thing as an HTML5 doctype. It’s just a blank doctype.

    An IMG tag certainly isn’t sensible for the header, although an inline styling on a DIV tag is also a bit nasty, so unless dynamically modifies the CSS you are always going to get nasty code for a changeable header image.

    Otto is correct that lists can most definitely be block elements, and in fact they are block by default. I see no reason why they need to be an unordered list though and many markup specialists find it a bit hacky to even refer to them as lists at all. The late Dan Schulz who was probably the leading expert on WordPress markup until his death not long ago, often complained about the shonky list markup used in sidebars and comments areas in popular themes. There’s plenty of others who feel differently though. I think the problem there is that there is currently no good option, and so there are a combination of different ways that things could be done.

  7. Kaspars says:

    Otto, thanks for your thoughtful comment.

    Re: title filter. That would be another way of doing it, although I think it’s already way too much of a PHP & HTML soup in one boul. And that big ass functions.php file is also a problem which should be addressed.

    Re: HTML5. So you think it would be better to specify another doctype?

    Re: p vs. div. I think h1 and h2 should never be used for site title and description (the only exception could be the front page, although I don’t see enough semantic reasoning for that either).

    Re: Widgets as lists. We’ll have to disagree on this one. I really don’t see how widgets that are in no way related to each other must be linked together in a list. In addition, no block elements are allowed inside list-item (which is neither an inline nor a block type element).

    Re: function_exists. To me this sounds like a goto solution to a bigger problem.

    Re: comment input field order. I prefer to put the most important stuff first and I don’t understand why others do it the other way around. However, you raise an even more important problem with comment input validation — that blank page with “Please fill in all required fields” and the need for back button is a huge usability issue.

    Again, thanks for your comment.

  8. Kaspars says:

    Ryan, doctype is supposed to instruct the browser which HTML standard to use. HTML5 doctype says — do whatever you want.

    Re: header background. I agree that inline CSS is not the best solution, but it certainly the easiest of the semantic ones. WordPress doesn’t have a built-in mechanism for generating and caching dynamic stylesheets which would be ideal for this kind of a theme feature.

    Re: widgets & lists. There is a better solution and it doesn’t include unordered lists. Just choose anything else and it’ll be better than lists ;)

  9. My take on themes is that the template files should only contain HTML and presentation logic.

    And really don’t like themes that got a mangled title tag. Sometimes you can’t even override the default title with a plugin.

    HTML5: Why use it at all?

    div: Agree. The most important headline should be h1 and that is never the homepage name except for on the front page some times.

    widgets list: Its very ugly to use lists that way. List are to display text I think. like grocery list. But list items can contain block elements. Check the standards both 3.2 and 4.01 say they can contain block.

    function_exists: I agree. WP has hooks for a reason. They are there to make it easy to override.

  10. Ryan says:

    I really don’t get the function_exists() approach. I thought that was what action hooks were for.

  11. Otto says:


    Doctype: HTML5 is the way of the future, so using that doctype is just fine. But the use of elements such as header and such, which are not well supported by current browsers, makes little sense. The idea that you have to go whole-hog-or-none is flawed. It’s perfectly valid to use an HTML5 doctype without using every possible HTML5 element.

    Lists: Think again, List Items (LI) can indeed contain block-level elements just fine. I think you need to brush up on the HTML specs.

    function_exists: No, it’s not a goto solution, it’s a standard php programming technique for making functions that can be overridden. WordPress calls them “pluggable” functions.

    Comments: The most important part of a comment is the name and email address. Not the comment. I don’t understand why anybody would think different. Comments are part of a conversation, and the first part of having a conversation is knowing who you are talking to and how to reply to them.

    • Kaspars says:

      Indeed, Otto, lists can contain block level elements. I did overlook that for some reason.

      However, I think you’ll also agree that lists do imply some kind of relationship between its items, and with widgets there is none.

      Re: function_exists: I think of it as a ‘goto-like’ solution because if you have the same function defined by a user after the initial function_exists call, it will call the original. In other words — the output of function_exists depends on the order of the code.

      Regarding the rest — I agree that there is no single argument for either of the approaches and therefore both are in a way viable.

  12. LeBen says:

    I totally agree with your position and I hope WordPress’ developers are going to improve these points.

Leave a Reply