mcleodm
  • 0
Новичок

Пользовательская нумерация страниц для пользовательских типов сообщений (по именам)

  • 0

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

В частности, меня попросили создать ссылки на страницы для людей, которые выглядят следующим образом:

  • АГ
  • ХМ
  • НК
  • RQ

Моя проблема — я не могу понять, как я могу запрашивать пользовательские типы сообщений по первой букве одного поля. Тогда я не уверен, как я могу создать разбиение на страницы таким образом. У кого-нибудь есть предложения? Спасибо!

Share
  1. Интересно.. Попробую, но не скоро. У меня есть свободный слот через пару дней. Поделитесь своим решением, если вы найдете что-нибудь до этого. Просто для начала просмотрите фильтр posts_where для изменения поиска и разбивки на страницы, которые вам нужно поиграть с правилами перезаписи, взгляните на query_vars, query_posts и класс WP_Rewrite. Я уверен, что вы справитесь с этими вещами.

    • 0
  2. Интересный вопрос! Я решил это, расширив 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 ).

    Добавление ссылок на страницы оставляется читателю в качестве упражнения 🙂

    • 0
  3. Это поможет вам начать работу. Я не знаю, как вы могли бы разбить запрос на определенную букву, а затем сообщить 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;
    
    • 0
  4. Ответ на примере @kaiser с настраиваемым типом сообщения в качестве функции, принимающей альфа-параметры начала и конца. Этот пример, очевидно, предназначен для короткого списка элементов, поскольку он не включает вторичную разбивку на страницы. Я публикую его, чтобы вы могли включить эту концепцию в свою 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;
        }
    }
    
    • 0
  5. Вот как это сделать с помощью фильтров query_vars и :posts_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

    • 0
  6. Это не столько ответ, сколько указатель направления, в котором нужно двигаться. Это, вероятно, должно быть на 100% индивидуальным — и будет очень сложным. Вам нужно будет создать собственный SQL-запрос (используя классы wpdb), а затем для разбивки на страницы вы передадите эти параметры в свой собственный запрос. Вероятно, вам также потребуется создать новые правила перезаписи для этого. Некоторые функции для изучения:

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

Оставить ответ

You must login to add an answer.