it-swarm.com.de

Beiträge nach Anfangsbuchstaben gruppieren

Ich arbeite an einer Website, auf der Posts verwendet werden, um Glossarartikel zu verwalten, die der folgenden Beispielwebsite ähneln. Ich möchte eine Möglichkeit finden, Artikel alphabetisch und nach einem ausgewählten Buchstaben gruppiert anzuzeigen (z. B. den Buchstaben 'F' im Beispiel). Ich möchte, dass der Prozess automatisch abläuft.

Beispiel für die gewünschte Ausgabe: http://www.retirementdictionary.com/glossary/f

Kann jemand einen Weg vorschlagen, dies zu tun?

3
Nohl

einmal habe ich ein Kundenprojekt gemacht, bei dem ich Archive nach Anfangsbuchstaben haben musste. Wenn ich zurückdenke, frage ich mich, ob ich nicht einfach eine versteckte Taxonomie hätte erstellen und dann den ersten Buchstaben als Begriff in dieser Taxonomie speichern sollen.

Jedenfalls ist hier, was ich tatsächlich getan habe:

/*
 * 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' );

wenn Sie bereits Posts haben, bevor Sie diese hinzufügen, müssen Sie Folgendes einmal ausführen, um die ersten Buchstaben für die vorhandenen Posts zu erhalten:

//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');

Jetzt brauchen wir ein paar Dinge, um zu entschlüsseln, wann wir uns auf einer benutzerdefinierten Archivseite befinden und was wir anders machen sollen

/*
 * 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' );

kleine Hilfsfunktion, um Links zu machen

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

Jetzt erstelle unser benutzerdefiniertes Archiv-Menü

$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 }

klicken Sie auf die Links, um zu einer Seite zu gelangen, auf der nur Beiträge mit diesem Buchstaben angezeigt werden.


rückblickend denke ich, dass die Taxonomieidee viel weniger Code und eine sauberere, von Anfang an integrierte Umschreibunterstützung wäre (dh ... keine Abfragevariablen, obwohl diese umgeschrieben werden könnten ... ich weiß nicht wie ). Der Taxonomie-Ansatz würde auch Steuerdaten zur DB hinzufügen, während dies nur die eine Option hinzufügt. so ein Kompromiss?

*EDIT**

ok, ich habe einen Stich in die Taxonomie-Route gemacht und sie ist etwas eleganter, als ich erwartet hatte

registrieren Sie zuerst die Taxonomie. Ich habe dies nur auf Posts ausgeführt, aber Sie können es leicht so ändern, dass es zu jedem Post-Typ passt, den Sie möchten.

// 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');

ähnliche Speicherfunktion zum Speichern unserer Steuerdaten beim Speichern eines Beitrags

/* 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' );

wieder müssen Sie etwas einmal ausführen, um alte Beiträge zu greifen, entfernen, wenn Sie fertig sind

//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');

füge das Menü hinzu dies war der einzige Teil, der nicht ganz elegant war, da es nicht einfach war zu testen, ob ein Begriff Beiträge ohne die zusätzliche foreach-Schleife enthielt. aber ich habe das gemildert, indem ich es in einem Übergang speicherte, der nur beim Speichern nach dem Speichern zurückgesetzt wird.

$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>

es gibt also 2 lösungen. Letzteres bringt Ihre URLs dazu, site.com/glossary/l ohne Zugriffsregeln anzugeben, um die Abfragevariablen von Ihrer Seite neu zu schreiben. hoffentlich hilft das.

10
helgatheviking

Ich würde Ihnen vorschlagen, WP_Query für diesen Zweck zu verwenden. Ein Beispiel für diese Abfrage finden Sie hier in diesem Plugin, das nur relevante Posts abruft, anstatt weitere PHP -Funktionen zu verwenden.

Sie können einen schnelleren Weg wählen, um fortzufahren, Alphabetic Pagination Plugin

0