Publicaciones en grupo por la primera letra del título

3

Estoy trabajando en un sitio web que utiliza publicaciones como una forma de administrar artículos de glosario similares al sitio web de ejemplo a continuación. Me gustaría encontrar una manera de mostrar los artículos alfabéticamente y agrupados por una letra seleccionada (como la letra 'F' en el ejemplo). Me gustaría que el proceso fuera automático.

Ejemplo de salida deseada: enlace

¿Alguien puede sugerir una forma de hacer esto?

    
pregunta Nohl 08.02.2012 - 22:02

2 respuestas

10

una vez una vez, hice un proyecto de cliente en el que tenía que tener archivos por primera letra. Pensando de nuevo, me pregunto si no debería haber creado una taxonomía oculta y luego guardar la primera letra como un término en esa taxonomía.

de todos modos, esto es lo que realmente hice:

/*
 * Function Create Array of Letters that have post titles (for archive)
 */

/* When the post is saved, saves our custom data */
function kia_save_first_letter( $post_id ) {
    // verify if this is an auto save routine. 
    // If it is our form has not been submitted, so we dont want to do anything
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
        return;

    //check location (only run for posts)
    $limitPostTypes = array('post');
    if (!in_array($_POST['post_type'], $limitPostTypes)) return;

    // Check permissions
    if ( !current_user_can( 'edit_post', $post_id ) )
        return;


    // OK, we're authenticated: we need to find and save the data
    $alphabet = get_option( 'kia_alphabet_archive' );

    $alphabet = is_array($alphabet) ? $alphabet : array($alphabet);

    // pop off first letter of post title
    $letter = substr($_POST['post_title'], 0, 1);

    // if it doesn't exist, add it to array
    if(!in_array($letter, $alphabet))
        $alphabet[] = $letter;
        sort($alphabet);

    $alphabet = is_array($alphabet) ? array_unique($alphabet) : array($alphabet);

    update_option( 'kia_alphabet_archive', $alphabet );
}
add_action( 'save_post', 'kia_save_first_letter' );

si ya tienes publicaciones antes de agregar esto, deberás ejecutar lo siguiente una vez para obtener las primeras letras de las publicaciones existentes:

//create array from existing posts
function kia_run_once(){
    $alphabet = array();
    $posts = get_posts(array(   
            'numberposts'     => -1
            ) );

    foreach($posts as $p) :  
        $alphabet[] = strtoupper(substr($p->post_title, 0, 1)); //first letter of post title, capitalized 
    endforeach;

    sort($alphabet);

    update_option( 'kia_alphabet_archive', array_unique($alphabet) );

}
add_action('init','kia_run_once');

ahora necesitamos algunas cosas para descifrar cuándo estábamos en una página de archivo personalizada y qué hacer de manera diferente

/*
 * Custom Archives by KIA
 */

function archive_queryvars( $qvars ) {
    $qvars[] = 'showarchive';
    return $qvars;
}
add_filter('query_vars', 'archive_queryvars' );


function is_custom_archive() {
    global $wp_query;
    return isset( $wp_query->query_vars['showarchive'] );
}

function archive_search_where( $where ){
    global $wpdb;

    if( is_custom_archive() ) {
        $char = get_query_var('showarchive');
        if ( ! empty($char) ) {
            $where .= "AND {$wpdb->posts}.post_title LIKE '{$char}%'";
        }
    } 
  return $where;
}
add_filter('posts_where', 'archive_search_where' );

pequeña función de ayuda para crear enlaces

/* 
 * add archive query arg to link
 */
function get_custom_archive_link($char = '') {
    $params = array(
            'showarchive' => $char,
            );
    return add_query_arg( $params, home_url('/') );
}

ahora crea nuestro menú de archivo personalizado

$alphabet = get_option ('kia_alphabet_archive');

if(count($alphabet)>0){ ?>
    <div id="archive-menu" class="menu">
    <?php for ($i=65; $i < 91; $i++) : 
            $current = (chr($i) == get_query_var('showarchive')) ? "current-menu-item" : "menu-item";

            if (is_array($alphabet) && in_array(chr($i), $alphabet)){ ?>
                <li class="az-char <?php echo $current;?>">
                    <?php printf('<a href="%s">%s</a>', get_custom_archive_link(chr($i)), chr($i) ) ?>
                </li>
            <?php } else { ?>
                <li class="az-char <?php echo $current;?>">
                    <?php echo chr($i); ?>
                </li>
            <?php } ?>  

            <?php endfor; ?>
    </div>
<?php }

hacer clic en los enlaces debería llevarte a una página que solo muestra las publicaciones que se muestran con esa letra.

mirando hacia atrás, creo que la idea de la taxonomía sería mucho menos código y tendría un soporte de reescritura más limpio incorporado desde el principio (es decir, ... no se verán las vars de consulta, aunque se podrían volver a escribir ... no lo hago) No sé cómo). el enfoque de taxonomía también agregaría datos de impuestos al DB, mientras que esto solo agrega una opción. Entonces, ¿compensación?

*EDIT**

ok, probé la ruta de la taxonomía y es un poco más elegante como esperaba

primero registra la taxonomía. Solo se ejecuta en las publicaciones, pero puede modificarlo fácilmente para que se adapte al tipo de publicación que desee.

// Add new taxonomy, NOT hierarchical (like tags)
function kia_create_glossary_taxonomy(){
    if(!taxonomy_exists('glossary')){
        register_taxonomy('glossary',array('post'),array(
        'show_ui' => false
      ));
     }
}
add_action('init','kia_create_glossary_taxonomy');

función de guardar similar para almacenar nuestros datos fiscales cuando se guarda una publicación

/* When the post is saved, saves our custom data */
function kia_save_first_letter( $post_id ) {
    // verify if this is an auto save routine. 
    // If it is our form has not been submitted, so we dont want to do anything
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
        return;

    //check location (only run for posts)
    $limitPostTypes = array('post');
    if (!in_array($_POST['post_type'], $limitPostTypes)) return;

    // Check permissions
    if ( !current_user_can( 'edit_post', $post_id ) )
        return;


    // OK, we're authenticated: we need to find and save the data
    $taxonomy = 'glossary';

    //set term as first letter of post title, lower case
    wp_set_post_terms( $post_id, strtolower(substr($_POST['post_title'], 0, 1)), $taxonomy );

    //delete the transient that is storing the alphabet letters
    delete_transient( 'kia_archive_alphabet');
}
add_action( 'save_post', 'kia_save_first_letter' );

nuevamente debes ejecutar algo una vez para capturar publicaciones antiguas, eliminar cuando haya terminado

//create array from existing posts
function kia_run_once(){
    $taxonomy = 'glossary';

    $alphabet = array();
    $posts = get_posts(array('numberposts' => -1) );

    foreach($posts as $p) :  
        //set term as first letter of post title, lower case
        wp_set_post_terms( $p->ID, strtolower(substr($p->post_title, 0, 1)), $taxonomy );
    endforeach;     
}
add_action('init','kia_run_once');

agregar el menú esta fue la única parte que no fue totalmente elegante, ya que no fue sencillo probar si un término tenía publicaciones sin el bucle foreach extra. pero lo he mitigado almacenándolo en un transitorio que solo se restablece en el guardado posterior.

$taxonomy = 'glossary';  

// save the terms that have posts in an array as a transient
if ( false === ( $alphabet = get_transient( 'kia_archive_alphabet' ) ) ) {
    // It wasn't there, so regenerate the data and save the transient
    $terms = get_terms($taxonomy);

    $alphabet = array();
    if($terms){
        foreach ($terms as $term){
            $alphabet[] = $term->slug;
        }
    }
     set_transient( 'kia_archive_alphabet', $alphabet );
}

?>

<div id="archive-menu" class="menu">
    <?php foreach(range('a', 'z') as $i) : 
            $current = ($i == get_query_var($taxonomy)) ? "current-menu-item" : "menu-item";

            if (in_array( $i, $alphabet )){ ?>
                <li class="az-char <?php echo $current;?>">
                    <?php printf('<a href="%s">%s</a>', get_term_link( $i, $taxonomy ), strtoupper($i) ) ?>
                </li>
            <?php } else { ?>
                <li class="az-char <?php echo $current;?>">
                    <?php echo strtoupper($i); ?>
                </li>
            <?php } ?>  

        <?php endforeach; ?>
</div>

por lo que hay 2 soluciones. este último obtendrá sus URL para decir site.com/glossary/l sin ninguna regla htaccess para volver a escribir las variables de consulta de su parte. Espero que ayude.

    
respondido por el helgatheviking 09.02.2012 - 15:59
0

Le sugiero que utilice WP_Query para este propósito. Un ejemplo de esta consulta se encuentra aquí en este complemento que obtiene solo las publicaciones relevantes en lugar de utilizar otras funciones de PHP.

Puede elegir una forma más rápida de continuar, Complemento de paginación alfabética

    
respondido por el WordPress Mechanic 07.05.2015 - 03:46

Lea otras preguntas en las etiquetas