Enhanced Image Navigation

An awesome code snippet that I just found in Automattic’s _s Theme:

/**
 * Filter in a link to a content ID attribute for the next/previous image links on image attachment pages
 *
 * @since _s 1.0
 */
function _s_enhanced_image_navigation( $url, $id ) {
    if ( ! is_attachment() && ! wp_attachment_is_image( $id ) )
        return $url;

    $image = get_post( $id );
    if ( $image->post_parent && $image->post_parent != $id )
        $url .= '#main';

    return $url;
}
add_filter( 'attachment_link', '_s_enhanced_image_navigation', 10, 2 );

This adds the #main attribute to image attachment links, so that the enduser always sees the attachment instantly and doesn’t have to scroll down. Especially handy in when you click through a post gallery!

Error Messages with WordPress Settings API

WordPress’ Settings API makes it fairly simple to display error messages or notices in the admin backend.

To let WordPress know that there is a message that you want to display, call the add_settings_error() function:

add_settings_error( $setting, $code, $message, $type );

This function adds your message to a queue of messages, linked to the slug provided with the first parameter. You can register multiple messages to one slug – they will be displayed underneath of each other. The second parameter specifies a unique error code, which will be added to the id attribute of the <div> holding the message (so make sure to sanitize it properly). Then you pass on the actual message (remember to always make strings translatable ūüėČ ).¬† And with the last parameter you can specify, whether it is an error message or a notice. The parameter defaults to ‘error’.

So lets add a notice message:

add_settings_error(
    'unique_identifyer',
    esc_attr('settings_updated'),
    __('Settings saved.'),
    'updated'
);

On every page load in the admin, the admin_notices hook fires, giving plugin and theme authors a possibility to add and display their messages. And here is how:

function unique_identifyer_admin_notices() {
     settings_errors( 'unique_identifyer' );
}
add_action( 'admin_notices', 'unique_identifyer_admin_notices' );

All parameters to the settings_errors function are optional, but since you probably only want to show your registered messages, you should specify the slug you used when adding the message.

And that’s all there is to it! Two simple functions to add and display error messages and notices in the admin area. Try it out and let me know what you think!

Sitemap: The WordPress Way

Due to the popularity of my earlier article about creating a WordPress Sitemap without a Plugin and my growing familiarity with the WordPress core, I decided to introduce another possibility. With this one, there are no custom database queries necessary, it solely depends on  already existing WordPress functions:

/**
 * Builds the Sitemap and echoes the HTML
 *
 * @echo Sitemap
 */
function sitemap() {

    $category_array = get_categories(array(
        'exclude_tree'    =>    24
    ));

    $sitemap =    "<h3>" . __( 'Posts','domain' ) . "</h3><ul>";

foreach ( $category_array as $category ) {
    $sitemap .= "<li>".__('Category: ', 'domain').'<a href="'.get_category_link($category->cat_ID).'" title="' . sprintf( __( "View all posts in %s" , 'domain'), $category->name ) . '">'.$category->name."</a><ul>n";
    $post_array = get_posts(array(
        'post_type'    =>    'post',
        'cat'        =>    $category->cat_ID
    ));

    foreach ( $post_array as $post ) {
        $post->post_title = apply_filters( 'the_title', $post->post_title, $post->ID );
        $sitemap .= "<li><a href="" . get_permalink($post->ID) . '" title="' . esc_attr($post->post_title) . '">' . $post->post_title . "</a></li>";
    }
    $sitemap .= "</ul>";
}

$sitemap .= "</li></ul>";
$sitemap .= "<h3>" . __( 'Pages','domain' ) . "</h3><ul>";
$sitemap .= wp_list_pages(array(
    'echo'        =>    false,
    'title_li'    =>    false,
    'exclude'    =>    '343,487,491'
))."</ul>";

 echo $sitemap;
}

The first function obviously grabs all the category objects from the database. This function has a number of possibilites to customize – read about them in the WordPress Codex.

$category_array = get_categories(array(
    'exclude_tree'    =>    24
));

Next, wie go through the categorie objects and fetch the associated posts. Now we can build the unordered list. I slotted the “the_title” filter ahead of the link, to give my plugins the opportunity to work their magic.

foreach($category_array as $category){
    $sitemap .= "<li>" . __('Category: ', 'domain') . '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '">' . $category->name . "</a><ul>";
    $post_array = get_posts(array(
        'post_type'  =>    'post',
        'cat'        =>    $category->cat_ID
    ));

    foreach ( $post_array as $post ) {
        $post->post_title = apply_filters( 'the_title', $post->post_title, $post->ID );
        $sitemap .= '<li><a href="' . get_permalink($post->ID) . '" title="' . esc_attr($post->post_title) . '">' . $post->post_title . '</a></li>';
    }
    $sitemap .= "</ul>";
}

And after all posts have been taken care of, there are only the pages missing (ich exluded the footer pages to only display pages with relevant content):

$sitemap .= wp_list_pages(array(
    'echo'       =>    false,
    'title_li'   =>    false,
    'exclude'    =>    '343,487,491'
))."</ul>";

That’s all there is to it!