Шорткод для вывода пользовательских типов записей

18 июл. 2012 г., 17:06:16
Просмотры: 17.4K
Голосов: 3

У меня проблема с создаваемым шорткодом.

У меня есть 5-10 различных пользовательских типов записей, и вместо создания шаблона для каждого типа записей, я хочу использовать обычную страницу и выводить записи через шорткод.

Чтобы объяснить подробнее: у меня есть страница "Достопримечательности" и тип записи 'Attraction'. На странице я вставляю шорткод -> [feed type="attraction" limit="5"]

Это выводит все записи типа "attraction".

Проблема, с которой я столкнулся - правильная работа пагинации. Я прочитал множество способов реализации пагинации для пользовательских типов записей, и используемый мной код, по словам многих, должен работать. Однако внутри шорткода он не работает. Есть ли для этого причина?

Сейчас страница отображается корректно, показывая пять записей, но не выводит ссылки "Следующая/Предыдущая страница". Если я введу в URL /page/2, вторая страница правильно отображается со следующими пятью записями. Получается, пагинация работает, но я не могу получить к ней доступ, так как ссылки не появляются.

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

Надеюсь, все понятно.

Вот мой код шорткода:

    function section_feed_shortcode( $atts ) {
    extract( shortcode_atts( array( 'limit' => -1, 'type' => 'post'), $atts ) );

    global $paged;
    $q = new WP_Query(  array ( 
        'posts_per_page' => $limit, 
        'post_type' => $type, 
        order => 'ASC', 
        orderby =>'menu_order', 
        'paged' => $paged ) );

    $list = ' ';

    while ( $q->have_posts() ) { $q->the_post();

        $list .= '<article class="listing-view clearfix">' 
        . '<div class="listing-content">' 
        . '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>' 
        .'<p>' . get_the_excerpt() . '</p>'
        . '<a href="' . get_permalink() . '">' . 'Просмотр »' . '</a>'
        . '</div>'
        . '<a class="listing-thumb" href="' . get_permalink() . '">' . get_the_post_thumbnail($page->ID, 'listing-thumb')  . '<span></span></a>'
        . '</article>';
    }

    return 
    '<div class="listings clearfix">' 
    . $list 
    . '<div class="nav-previous">' . next_posts_link( __( '<span class="meta-nav">←</span> Предыдущие записи' ) ) . '</div>'
    . '<div class="nav-next">' . previous_posts_link( __( 'Следующие записи <span class="meta-nav">→</span>' ) ) . '</div>'
    . '</div>' .
    wp_reset_query();

}
add_shortcode( 'feed', 'section_feed_shortcode' );
2
Комментарии

Какое преимущество у такого подхода? Кажется, что это требует много усилий, когда WordPress уже поддерживает архивы пользовательских типов записей с правильной пагинацией. Кроме того, неэффективно выполнять второй запрос, когда в этом нет необходимости. Вам даже не нужно создавать специальный шаблон, так как WordPress будет использовать archives.php или даже index.php. Если вам нужно просто добавить их в меню, есть http://wordpress.org/extend/plugins/cpt-archives-in-nav-menus/

helgatheviking helgatheviking
18 июл. 2012 г. 17:27:41

Преимущество в том, что я могу разместить их где угодно, и если я могу добавить их на обычную страницу в WordPress, я могу добавить контент выше и ниже шорткода. Каждый раздел имеет контент до и после списка записей. Если я создам шаблон, весь этот контент придется жестко прописывать в шаблоне, что затрудняет оперативное обновление. Мне нужно, чтобы контент на этих страницах разделов можно было легко обновлять.

Aaron Aaron
18 июл. 2012 г. 17:36:20
Все ответы на вопрос 1
4

Хорошо, мне все еще не нравится идея второго запроса, но ты прав, добавить контент на страницы архивов действительно сложно.

Я обнаружил 3 проблемы:

  1. Функции next_posts_link и previous_posts_link выводят результат напрямую, тебе нужны их аналоги с get_.

  2. Когда смотришь документацию get_next_posts_link, оказывается что она зависит от глобальной переменной $wp_query... которая в твоем случае всегда относится к "странице", а не к запросу шорткода. Тебе нужно использовать query_posts и перезаписать оригинальный запрос. Надеюсь, сброс запроса сработает, но я не уверен на 100%. Это нужно протестировать.

  3. Не уверен, что это была проблема, но обычно я вижу переменную $paged определенной таким образом, поэтому использовал этот вариант.

    function section_feed_shortcode( $atts ) {
    extract( shortcode_atts( array( 'limit' => -1, 'type' => 'post'), $atts ) );
    
    $paged = get_query_var('paged') ? get_query_var('paged') : 1;  
    
    query_posts(  array ( 
        'posts_per_page' => $limit, 
        'post_type' => $type, 
        'order' => 'ASC', 
        'orderby' =>'menu_order', 
        'paged' => $paged ) );
    
    $list = ' ';   
    
    while ( have_posts() ) { the_post();
    
        $list .= '<article class="listing-view clearfix">' 
        . '<div class="listing-content">' 
        . '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>' 
        .'<p>' . get_the_excerpt() . '</p>'
        . '<a href="' . get_permalink() . '">' . 'Просмотр &raquo;' . '</a>'
        . '</div>'
        . '<a class="listing-thumb" href="' . get_permalink() . '">' . get_the_post_thumbnail($page->ID, 'listing-thumb')  . '<span></span></a>'
        . '</article>';
    }
    
    return 
    '<div class="listings clearfix">' 
    . $list 
    . '<div class="nav-previous">' . get_next_posts_link( __( '<span class="meta-nav">&larr;</span> Старые записи' ) ) . '</div>'
    . '<div class="nav-next">' . get_previous_posts_link( __( 'Новые записи <span class="meta-nav">&rarr;</span>' ) ) . '</div>'
    . '</div>' .
    wp_reset_query();
    
    }
    add_shortcode( 'feed', 'section_feed_shortcode' );
    
18 июл. 2012 г. 20:40:26
Комментарии

Большое спасибо @helgatheviking! Я еще не пробовал это, но сообщу о результате, когда доберусь до этого. Очень признателен за вашу помощь в этом вопросе.

Aaron Aaron
19 июл. 2012 г. 14:54:03

Конечно, если это действительно сработает, пожалуйста, отметьте как ответ. Если нет, дайте мне знать, что происходит вместо этого.

helgatheviking helgatheviking
19 июл. 2012 г. 17:12:52

Спасибо! Это сработало идеально. Просто интересно, почему так, я немного новичок в WordPress, однако я всегда думал, что использование wp_query мощнее и имеет больше функциональности, чем query_posts. Еще раз спасибо!

Aaron Aaron
20 июл. 2012 г. 17:20:23

насколько я знаю, они одинаковы. new WP_query просто сохраняет 'новый' объект вместо перезаписи оригинального запроса страницы, что в целом безопаснее в плане избежания проблем с пагинацией/циклами. но поскольку ссылки "назад" и "вперед" зависят от глобальной переменной $wp_query, вам нужно изменять её через query_posts

helgatheviking helgatheviking
20 июл. 2012 г. 19:14:59