В продолжение статьи Custom Fields Hacks For WordPress хочу поделиться своим опытом использования пользовательских полей поста.

Автор и оригинал поста

Не секрет, что на сайте в основном опубликованы переводы статей, чтобы удобно указать автора и дать ссылку на оригинал я использую дополнительные поля author и original.

Пользовательские поля

Работа с этими полями выделена в плагин dfmAuthorOriginal.php

Автора подменяем с помощью фильтра:

add_filter('the_author', 'dfm_author_filter');

function dfm_author_filter($author) {
    global $post;

    $custom_author = get_post_meta($post->ID, 'author', true);
    if($custom_author) {
        if(is_feed()) {
            $custom_author = strip_tags($custom_author);
        }
        return $custom_author;
    } else {
        return $author;
    }
}

Для оригинала вводим функцию dfm_original:

function dfm_original($before = '<p>', $after = '</p>') {
    global $post;

    $original = get_post_meta($post->ID, 'original', true);
    if($original) {
        echo $before . $original . $after;
    }
}

и вставляем ее в нужном месте шаблона:

<?php if(function_exists('dfm_original'))
    dfm_original('<p>Оригинал: ', '</p>'); ?>

Краткие заголовки постов

Для списка «Последние статьи» в сайдбаре используются краткие заголовки из поля short_title. В общем случае код должен выглядеть так:

function dfm_recent_posts($before='<li>', $after='</li>')
{
    $posts = get_posts(array('numberposts' => 10));
    echo dfm_posts_list($posts, $before, $after);
}

function dfm_posts_list($posts, $before='<li>', $after='</li>')
{
    $result = array();
    
    foreach($posts as $post) {
        $permalink = get_permalink($post);
        $title = get_post_meta($post->ID, 'short_title', true);
        $title = empty($title) ? $post->post_title : $title;
        
        $result[] = sprintf('%s<a href="%s" rel="bookmark">%s</a>%s',
                            $before, $permalink, $title, $after);
    }

    return implode("\n", $result);
}

К сожалению, get_posts это 4 запроса к БД и если таким способом выводить блоки «Последние статьи», «Лучшие статьи» и «Похожие статьи» то количество запросов на сборку страницы будет более чем удвоено (22 вместо 10), благодаря чему хостер отключит сайт как раз в тот момент, когда на него появиться ссылка на популярном ресурсе, поэтому я использую менее универсальный, но быстрый метод:

function dfm_recent_posts($before='<li>', $after='</li>')
{
    global $wpdb;
    
    $posts = $wpdb->get_results(
        "SELECT COALESCE({$wpdb->postmeta}.meta_value, post_title) AS post_title, post_name " .
        "FROM {$wpdb->posts} " .
        "LEFT JOIN {$wpdb->postmeta} ON post_id = ID AND {$wpdb->postmeta}.meta_key = 'short_title' " .
        "WHERE post_status='publish' ORDER BY post_date DESC LIMIT 10"
    );
    
    echo dfm_posts_list($posts, $before, $after);
}

function dfm_posts_list($posts, $before='<li>', $after='</li>')
{
    $siteurl = get_bloginfo('siteurl');
    $result = array();
    
    foreach($posts as $post) {
        $permalink = $siteurl . '/posts/' . $post->post_name;
        $result[] = sprintf('%s<a href="%s" rel="bookmark">%s</a>%s',
                            $before, $permalink, $post->post_title, $after);
    }
    
    return implode("\n", $result);
}

Функцию dfm_recent_posts вставляем в шаблоне sidebar.php:

<?php if(function_exists('dfm_recent_posts')) : ?>
<h3>Последние статьи</h3>
<ul class="favorite">
    <?php dfm_recent_posts(); ?>
</ul>
<?php endif; ?>

Похожие статьи

Для похожих статей используется поле related со списком идентификаторов похожих постов:

add_filter('the_content', 'dfm_related_articles_filter');

function dfm_related_articles_filter($content) {
    global $post, $wpdb;

    $result = '';
    
    if(is_single() || is_feed()) {
        $related_IDs = get_post_meta($post->ID, 'related', true);    
        if(!empty($related_IDs)) {
            $related_posts = $wpdb->get_results(
                "SELECT post_title,post_name FROM {$wpdb->posts} " .
                "WHERE post_status='publish' AND ID IN ($related_IDs) " .
                "ORDER BY post_date DESC;"
            );

            if(!empty($related_posts)) {
                $result = '<h2>Похожие статьи</h2><ul>';
                
                foreach($related_posts as $p) {
                    $href = get_bloginfo('siteurl') . '/posts/'. $p->post_name;
                    $result .= sprintf('<li><a href="%s">%s</a></li>',
                                       $href, $p->post_title);
                }
                $result .= '</ul>';
            }
        }
    }

    return $content . $result;
}

Идентификаторы смотрю на карте сайта с помощью FireBug, конечно, хорошо бы автоматизировать этот процесс, но все руки не доходят, да и не так уж часто приходится этим заниматься.

make4you Форум Web 2.0 и блоггинг
Дружелюбный форум о создании сайтов и ведении блогов. Присоединяйтесь.