Cum să creezi un blogroll categorizat cu categorii principale și subcategorii pentru toate articolele?

15 mai 2013, 02:41:37
Vizualizări: 13.6K
Voturi: 0

Aș dori ajutor pentru a afișa toate articolele site-ului meu într-un blogroll organizat pe categorii și subcategorii.

Rezultatul HTML final pe care aș dori să-l văd afișat ar fi ceva de genul acesta:

<div id="content">

    <div id="category1">

        <ul id="posts">
            <li>post1</li>
            <li>post2</li>
            <li>post3</li>
        </ul><!-- #posts -->

    </div><!-- #category1 -->

    <div id="category2">

        <div id="sub-category1">

            <ul id="posts">
                <li>post4</li>
                <li>post5</li>
                <li>post6</li>
            </ul><!-- #posts -->

        </div><!-- #sub-category1 -->

        <div id="sub-category2">

            <ul id="posts">
                <li>post7</li>
                <li>post8</li>
                <li>post9</li>
            </ul><!-- #posts -->

        </div><!-- #sub-category2 -->

    </div><!-- #category2 -->

</div><!-- #content -->

Structura fișierelor pe care am prevăzut-o pentru aceasta ar fi ceva de genul:

custom-category.php //acest fișier ar extrage categoriile, le-ar sorta și ar crea div-urile container pentru #category și #sub-category și ar apela informațiile despre articol din interiorul buclei/interogării cu get_template_part( 'content', get_post_format() );

content.php //acest fișier ar organiza ul#posts și toate tipurile de informații pe care aș dori să le adaug referitoare la articolul în sine

Principalele probleme pe care le am în acest moment sunt că nu știu de unde să încep pentru a încerca să rezolv singur această problemă. Continui să mă uit la fișierul implicit category.php și simt că va arăta complet diferit.

Am încercat să mă uit la plugin-uri, dar unele sortează categoriile doar în bare laterale, altele permit crearea de câmpuri personalizate pentru categorii, dar recenziile menționează că nu poți apela acele valori. Am încercat funcția wp_list_categories(); pentru a încerca să încep de undeva, dar nici măcar nu listează subcategoriile.

Am citit despre crearea propriei query_posts(); sau get_posts(); dar nu știu cu adevărat de unde să încep cu acestea.

Deoarece aceasta nu este chiar o singură întrebare, aș dori să încerc să subliniez întrebările pentru claritate, dar simțiți-vă liberi să adăugați alte informații pe care le considerați utile, deoarece s-ar putea să pun întrebările greșite xD

1- Cum încep "Bucla" pentru a obține categoriile/subcategoriile?
2- Cum sortez categoriile și păstrez subcategoriile imbricate?
3- Cum mă asigur că articolele vor ajunge în div-urile corecte? Pentru cazul în care WP face ceva ciudat.

Mulțumesc pentru ajutor.

--- Actualizare ---

Am căutat pe internet încercând să găsesc soluții și încep să ajung undeva, dar nu chiar acolo unde trebuie. Iată ce am până acum:

<?php
        // obținem toate categoriile din baza de date
        $args1 = array(
          'orderby' => 'ID',
          'order' => 'ASC',
          'hierarchical' => true,
          );
        $cats = get_categories( $args1 ); 


            // parcurgem categoriile
            foreach ($cats as $cat) {
                // configurăm ID-ul categoriei
                $cat_id= $cat->term_id;
                // Creăm un antet pentru categorie
                echo "<h2>".$cat->name."</h2><p>".$cat->term_id."</p>";
                // creăm o interogare WordPress personalizată
                $args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
                query_posts( $args2 );
                // începem bucla WordPress!
                if (have_posts()) : while (have_posts()) : the_post(); ?>

                    <?php // creăm link-ul nostru acum că articolul este configurat ?>
                    <a href="<?php the_permalink();?>"><?php the_title(); ?></a>
                    <?php echo '<hr/>'; ?>

                <?php endwhile; endif; // am terminat bucla WordPress. Va începe din nou pentru fiecare categorie ?>
            <?php } // am terminat instrucțiunea foreach ?>

Am găsit acest cod pe acest site web. Afișează toate categoriile și pune articolele sub ele, dar replică articolele pentru categoria părinte astfel:

<h2>Category1</h2><p>2</p> 
    <a href="http://localhost/wordpress/2013/05/06/test0/">test0</a>
                    <hr> 
<h2>Category2</h2><p>3</p>
    <a href="http://localhost/wordpress/2013/05/15/test2/">test2</a>
                    <hr> 
    <a href="http://localhost/wordpress/2013/05/14/test1/">test1</a>
                    <hr> 
<h2>Sub-category1</h2><p>4</p>
    <a href="http://localhost/wordpress/2013/05/14/test1/">test1</a>
                    <hr> 
<h2>Sub-category2</h2><p>5</p>
    <a href="http://localhost/wordpress/2013/05/15/test2/">test2</a>
                    <hr> 

După cum puteți vedea, articolele test1 și test2 sunt afișate în Category2 și asta nu e chiar ceea ce doream, așa cum am descris în întrebarea inițială (HTML-ul final dorit).

Cred că trebuie să adaug o instrucțiune condițională pentru a verifica dacă categoria curentă are copii și, dacă da, să treacă la categoriile copil, dacă nu, să o populeze. Dar încă încerc să-mi dau seama cum să fac asta. Nu am ajuns la un punct în care să mă simt suficient de confortabil să încep să implementez div-urile pe care intenționez să le am în HTML-ul final, dar am sentimentul că voi avea o problemă și cu asta. În acest moment, practic încerc să învăț mai multe despre această "chestiune cu bucla" până când obțin un rezultat decent care îmi va permite să înțeleg întregul concept.

Sunt conștient de aceste 2 linkuri A și B, dar sunt încă începător și nu pot ajunge chiar acolo încă, deci lucrez practic cu codul pe care îl văd că funcționează și voi încerca să-l îmbunătățesc pe măsură ce avansez.

--- Actualizare ---

Aceasta pare să afișeze articolele în ordinea corectă și fără a se repeta pentru categoriile părinte.

<?php
        // obținem toate categoriile din baza de date
        $args1 = array(
          'orderby' => 'ID',
          'order' => 'ASC',
          'hierarchical' => true
          );
        $cats = get_categories( $args1 ); 

            // parcurgem categoriile
            foreach ($cats as $cat) {
                $cat_id= $cat->term_id;// configurăm ID-ul categoriei
                $cat_name= $cat->name;// configurăm numele categoriei
                $parent= $cat->category_parent;// configurăm categoria părinte
                $cat_child= get_term_children( $cat_id, 'category' ); //funcția pe care o aveam get_category_children(); era depreciată... am rezolvat asta

                $has_child=bool; //
                if( empty($cat_child)) { $has_child= false; }
                else { $has_child= true; }

                if ( $parent == 0 && $has_child == true ) { //este părinte && are copil -> afișează titlul
                    echo "<h2>".$cat_name."</h2>";
                    echo '<hr/>'; }
                elseif ( $parent == 0 && $has_child == false ) { //este părinte && nu are copil -> bucla articolelor
                    echo "<h2>".$cat_name."</h2>";
                    // creăm o interogare WordPress personalizată
                    $args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
                    query_posts( $args2 );
                    // începem bucla WordPress!
                    if (have_posts()) : while (have_posts()) : the_post(); ?>
                        <?php the_title(); ?>
                        <?php echo '<hr/>'; ?>
                    <?php endwhile; endif; }
                else { //este copil -> bucla articolelor
                    echo "<h2>".$cat_name."</h2>";
                    // creăm o interogare WordPress personalizată
                    $args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
                    query_posts( $args2 );
                    // începem bucla WordPress!
                    if (have_posts()) : while (have_posts()) : the_post(); ?>
                        <?php the_title(); ?>
                        <?php echo '<hr/>'; ?>
                    <?php endwhile; endif;   // am terminat bucla WordPress. Va începe din nou pentru fiecare categorie ?>
            <?php }} // am terminat instrucțiunea foreach ?>

Am împărțit acest cod în 3 condiții: este părinte și are copil, este părinte dar nu are copil și este copil. Funcția care mi-a permis să ajung aici este get_category_children();.

Citind codul acum, mă gândesc că aș fi putut verifica direct dacă $cat_child era gol în instrucțiunile principale if/elseif, evitând structura suplimentară cu $has_child.

0
Toate răspunsurile la întrebare 1
0

Bine, după multă căutare am ajuns la un cod care face exact ce am cerut. Totuși, nu cred că acest cod este frumos/eficient/reutilizabil în vreun fel. Îl postez doar pentru că execută ceea ce era de așteptat. Aș aprecia un răspuns care să mă îndrepte spre metoda "best practice" de codare, ca să pot învăța din el, așa că nu voi marca întrebarea mea ca răspunsă pentru aproximativ o săptămână, pentru a aștepta niște soluții mai bune de codare.

Acesta este rezultatul la care am ajuns:

<?php
        $isOdd = true; // setează boolean pentru a determina id-ul div-ului părinte pentru CSS
        $args1 = array(
          'orderby' => 'ID',
          'order' => 'ASC',
          'hierarchical' => true
          );
        $cats = get_categories( $args1 ); // obține toate categoriile din baza de date

            // parcurge categoriile
            foreach ($cats as $cat) {
                $cat_id= $cat->term_id;// setează ID-ul categoriei
                $cat_name= $cat->name;// setează numele categoriei
                $parent= $cat->category_parent;// setează părintele categoriei
                $cat_child= get_term_children( $cat_id, 'category' ); // returnează un șir cu categoriile copil din taxonomie

                $has_child=bool; // creează o variabilă care va permite verificarea dacă o categorie are copii
                if( empty($cat_child)) { $has_child= false; }
                else { $has_child= true; }

                if ( $parent == 0 && $has_child == false ) { //este părinte && nu are copii -> parcurge postările
                    echo "<div class=\"parent-wrap\" id=\"". ( $isOdd ? 'odd' : 'even') . "\">";
                        echo "<h2>".$cat_name."</h2>";
                        echo "<div class=\"post-wrap\">";
                            echo "<ul class=\"post-list\">";
                                echo "<li class=\"back-button\"><</li>";

                                    // creează o interogare WordPress personalizată
                                    $args2 = 'cat=' . $cat_id . '&orderby=date&order=DESC&post_per_page=-1';
                                    query_posts( $args2 );
                                    // începe bucla WordPress!
                                    if (have_posts()) : while (have_posts()) : the_post(); 
                                        get_template_part( 'content', get_post_format() ); //obține șablonul postării din content.php
                                    endwhile; endif;

                                echo "<li class=\"front-button\">></li>";
                            echo "</ul><!-- .post-list -->";
                        echo "</div><!-- .post-wrap -->";
                    echo "</div><!-- .parent-wrap -->";
                    $isOdd = !$isOdd;
                    }
                elseif ( $parent == 0 && $has_child == true ) { //este părinte && are copii -> afișează titlul postării
                    echo "<div class=\"parent-wrap\" id=\"". ( $isOdd ? 'odd' : 'even') . "\">";
                        echo "<h2>".$cat_name."</h2>";

                        // parcurge categoriile ÎN INSTRUCȚIUNEA ELSEIF
                        foreach ($cats as $cat) {
                            $cat_id_new= $cat->term_id;// setează noul ID al categoriei
                            $cat_name_new= $cat->name;// setează noul nume al categoriei
                            $parent_new= $cat->category_parent;// setează noul părinte al categoriei
                            $cat_child_new= get_term_children( $cat_id_new, 'category' ); // returnează un șir cu categoriile copil din taxonomie

                            $has_child_new=bool; // creează o nouă variabilă care va permite verificarea dacă o categorie are copii
                            if( empty($cat_child_new)) { $has_child_new= false; }
                            else { $has_child_new= true; }

                            if ($parent_new != 0 && $has_child_new == false && cat_is_ancestor_of($cat_id, $cat_id_new) ) { //este copil -> parcurge postările
                                echo "<div class=\"child-wrap\">";
                                    echo "<h3>".$cat_name_new."</h3>";
                                    echo "<div class=\"post-wrap\">";
                                        echo "<ul class=\"post-list\">";
                                            echo "<li class=\"back-button\"><</li>";

                                                // creează o interogare WordPress personalizată
                                                $args2 = 'cat=' . $cat_id_new . '&orderby=date&order=DESC&post_per_page=-1';
                                                query_posts( $args2 );
                                                // începe bucla WordPress!
                                                if (have_posts()) : while (have_posts()) : the_post(); 
                                                    get_template_part( 'content', get_post_format() ); //obține șablonul postării din content.php
                                                endwhile;
                                                endif; // gata cu bucla WordPress. Va începe din nou pentru fiecare categorie

                                            echo "<li class=\"front-button\">></li>";
                                        echo "</ul><!-- .post-list -->";
                                    echo "</div><!-- .post-wrap -->";
                                echo "</div><!-- .child-wrap -->";
                            } // închide if ($parent_new != 0...
                        } // închide foreach în elseif
                    echo "</div><!-- .parent-wrap -->";
                    $isOdd = !$isOdd;
                } // închide if ($parent == 0...
            } // închide prima instrucțiune foreach ?>

Simt că unele lucruri din acest cod ar putea fi mai bine organizate dacă s-ar crea funcții și apoi s-ar reutiliza în tot codul și încă mă gândesc să înlocuiesc query_posts(); cu get_posts(); sau pre_get_posts();.

17 mai 2013 18:22:37