自定义帖子类型的自定义分页(按名称)

时间:2011-05-30 作者:mcleodm3

我有两种处理人名的自定义帖子类型。现在,在浏览视图时,它只是按字母顺序列出所有视图,分页按数字进行划分,这对您查找特定的人没有太大帮助。

具体来说,我被要求为如下人员创建分页链接:

我的问题是,我不知道如何通过一个字段的第一个字母来查询自定义帖子类型。然后,我不确定如何以这种方式创建分页。有人有什么建议吗?非常感谢。

5 个回复
SO网友:Jan Fabry

有趣的问题!我通过扩展WHERE 使用一组post_title LIKE \'A%\' OR post_title LIKE \'B%\' ... 条款。您也可以使用正则表达式进行范围搜索,但我相信数据库届时将无法使用索引。

这是解决方案的核心:在WHERE 条款:

add_filter( \'posts_where\', \'wpse18703_posts_where\', 10, 2 );
function wpse18703_posts_where( $where, &$wp_query )
{
    if ( $letter_range = $wp_query->get( \'wpse18703_range\' ) ) {
        global $wpdb;
        $letter_clauses = array();
        foreach ( $letter_range as $letter ) {
            $letter_clauses[] = $wpdb->posts. \'.post_title LIKE \\\'\' . $letter . \'%\\\'\';
        }
        $where .= \' AND (\' . implode( \' OR \', $letter_clauses ) . \') \';
    }
    return $where;
}
当然,您不希望在查询中允许随机的外部输入。这就是为什么我有一个输入净化步骤pre_get_posts, 将两个查询变量转换为有效范围。(如果你想办法打破这一点,请留下评论,以便我可以更正)

add_action( \'pre_get_posts\', \'wpse18703_pre_get_posts\' );
function wpse18703_pre_get_posts( &$wp_query )
{
    // Sanitize input
    $first_letter = $wp_query->get( \'wpse18725_first_letter\' );
    $last_letter = $wp_query->get( \'wpse18725_last_letter\' );
    if ( $first_letter || $last_letter ) {
        $first_letter = substr( strtoupper( $first_letter ), 0, 1 );
        $last_letter = substr( strtoupper( $last_letter ), 0, 1 );
        // Make sure the letters are valid
        // If only one letter is valid use only that letter, not a range
        if ( ! ( \'A\' <= $first_letter && $first_letter <= \'Z\' ) ) {
            $first_letter = $last_letter;
        }
        if ( ! ( \'A\' <= $last_letter && $last_letter <= \'Z\' ) ) {
            if ( $first_letter == $last_letter ) {
                // None of the letters are valid, don\'t do a range query
                return;
            }
            $last_letter = $first_letter;
        }
        $wp_query->set( \'posts_per_page\', -1 );
        $wp_query->set( \'wpse18703_range\', range( $first_letter, $last_letter ) );
    }
}
最后一步是创建一个非常好的重写规则,以便example.com/posts/a-g/example.com/posts/a 查看所有以此(一系列)字母开头的帖子。

add_action( \'init\', \'wpse18725_init\' );
function wpse18725_init()
{
    add_rewrite_rule( \'posts/(\\w)(-(\\w))?/?\', \'index.php?wpse18725_first_letter=$matches[1]&wpse18725_last_letter=$matches[3]\', \'top\' );
}

add_filter( \'query_vars\', \'wpse18725_query_vars\' );
function wpse18725_query_vars( $query_vars )
{
    $query_vars[] = \'wpse18725_first_letter\';
    $query_vars[] = \'wpse18725_last_letter\';
    return $query_vars;
}
您可以更改重写规则模式以从其他内容开始。如果这是自定义帖子类型,请确保添加&post_type=your_custom_post_type 替换(第二个字符串,以开头index.php).

添加分页链接留作读者练习:-)

SO网友:kaiser

这将帮助您开始。我不知道你如何在特定的字母处打破查询,然后告诉WP,还有一页有更多的字母,但下面的内容占了其余部分的99%。

不要忘记发布您的解决方案!

query_posts( array( \'orderby\' => \'title\' ) );

// Build an alphabet array
foreach( range( \'A\', \'G\' ) as $letter )
    $alphabet[] = $letter;

foreach( range( \'H\', \'M\' ) as $letter )
    $alphabet[] = $letter;

foreach( range( \'N\', \'Q\' ) as $letter )
    $alphabet[] = $letter;

foreach( range( \'R\', \'Z\' ) as $letter )
    $alphabet[] = $letter;

if ( have_posts() ) 
{
    while ( have_posts() )
    {
        global $wp_query, $post;
        $max_paged = $wp_query->query_vars[\'max_num_pages\'];
        $paged = $wp_query->query_vars[\'paged\'];
        if ( ! $paged )
            $paged = (int) 1;

        the_post();

        $first_title_letter = (string) substr( $post->post_title, 1 );

        if ( in_array( $first_title_letter, $alphabet ) )
        {
            // DO STUFF
        }

        // Pagination
        if ( $paged !== (int) 1 )
        {
            echo \'First: \'._wp_link_page( 1 );
            echo \'Prev: \'._wp_link_page( $paged - 1 );
        }
        while ( $i = 1; count($alphabet) < $max_paged; i++; )
        {
            echo $i._wp_link_page( $i );
        }
        if ( $paged !== $max_paged )
        {
            echo \'Next: \'._wp_link_page( $paged + 1 );
            echo \'Last: \'._wp_link_page( $max_paged );
        }
    } // endwhile;
} // endif;

SO网友:Tyrus

使用@kaiser示例的答案,带有一个自定义post类型作为接受alpha开始和结束参数的函数。这个示例显然是针对一个简短的项目列表,因为它不包括辅助分页。我正在发布它,以便您可以将该概念纳入您的functions.php 如果你喜欢的话。

// Dr Alpha Paging
// Tyrus Christiana, Senior Developer, BFGInteractive.com
// Call like alphaPageDr( "A","d" );
function alphaPageDr( $start, $end ) {
    echo "Alpha Start";
    $loop = new WP_Query( \'post_type=physician&orderby=title&order=asc\' );      
    // Build an alphabet array of capitalized letters from params
    foreach ( range( $start, $end ) as $letter )
        $alphabet[] = strtoupper( $letter );    
    if ( $loop->have_posts() ) {
        echo "Has Posts";
        while ( $loop->have_posts() ) : $loop->the_post();              
            // Filter by the first letter of the last name
            $first_last_name_letter = ( string ) substr( get_field( "last_name" ), 0, 1 );
            if ( in_array( $first_last_name_letter, $alphabet ) ) {         
                //Show things
                echo  "<img class=\'sidebar_main_thumb\' src= \'" . 
                    get_field( "thumbnail" ) . "\' />";
                echo  "<div class=\'sidesbar_dr_name\'>" . 
                    get_field( "salutation" ) . " " . 
                    get_field( \'first_name\' ) . " " . 
                    get_field( \'last_name\' ) . "</div>";
                echo  "<div class=\'sidesbar_primary_specialty \' > Primary Specialty : " . 
                    get_field( "primary_specialty" ) . "</div>";                
            }
        endwhile;
    }
}

SO网友:Styledev

下面是使用query_varsposts_where 过滤器:

public  function range_add($aVars) {
    $aVars[] = "range";
    return $aVars;
}
public  function range_where( $where, $args ) {
    if( !is_admin() ) {
        $range = ( isset($args->query_vars[\'range\']) ? $args->query_vars[\'range\'] : false );
        if( $range ) {
            $range = split(\',\',$range);
            $where .= "AND LEFT(wp_posts.post_title,1) BETWEEN \'$range[0]\' AND \'$range[1]\'";
        }
    }
    return $where;
}
add_filter( \'query_vars\', array(\'atk\',\'range_add\') );
add_filter( \'posts_where\' , array(\'atk\',\'range_where\') );
来源:https://gist.github.com/3904986

SO网友:dwenaus

这与其说是一个答案,不如说是一个指向方向的指针。这可能必须是百分之百的定制,而且会非常复杂。您需要创建一个自定义sql查询(使用wpdb类),然后为了分页,您需要将这些参数传递给自定义查询。您可能还需要为此创建新的重写规则。需要研究的一些功能:

add_rewrite_tag( \'%byletter%\', \'([^/]+)\');
add_permastruct( \'byletter\', \'byletter\' . \'/%byletter%\' );
$wp_rewrite->flush_rules();
paginate_links()

结束

相关推荐

Pagination with custom loop

我的问题可能是Pagination not working with custom loop, 但有一种不同。我使用自定义循环来显示flash游戏。我想按类别在游戏页面上分页。类别php:<?php if ($cat) { $cols = 2; $rows = 4; $paged = ((\'paged\')) ? get_query_var(\'paged\') : 1; $post_per_page = $cols * $rows; // -1 s