在层次结构的一个页面上显示所有类别和帖子

Posted

技术标签:

【中文标题】在层次结构的一个页面上显示所有类别和帖子【英文标题】:Displaying all categories and posts on one page in a hierarchy 【发布时间】:2015-04-23 14:46:20 【问题描述】:

我的客户坚持将所有类别和帖子显示在一个页面上。坏主意,我知道,但我必须这样做。

反正结构是这样的:

1 级分类标题 > 2 级分类标题 > ... > 第 n 级分类标题 > 帖子内容。

这将在 html 中构造,例如:

<div class="cat primary">
    <h2>1st Level Category Title</h2>
    <div class="cat secondary">
        <h3>2nd Level Category Title</h3>
        <div class="cat tertiary">
            <h4>3rd Level Category Title</h4>
            ...
                <div class="cat tertairy">
                    <h4>nth Level Category Title</h4>
                    <div class="product">
                        <p>Post Content</p>
                    </div>
                </div>
            ...
        </div>
    </div>
    <div class="cat secondary">
        <h3>2nd Level Category Title</h3>
        <div class="product">
            <p>Post Content</p>
        </div>
    </div>
</div>

功能说明:

第一个类别获得“主要”类,第二个“次要”,以及所有后续的“第三类”。如果需要,我可以使用 CSS 解决这个问题。 &lt;h2&gt; 用于主标题,&lt;h3&gt; 用于辅助标题,&lt;h4&gt; 用于所有后续标题。如果需要,我可以使用 CSS 解决这个问题。 树中最深的类别显示该类别中的所有产品。

我用get_terms()get_categories() 尝试了几件事,但我不知道如何判断一个类别是否处于最深层次,我不知道如何无限深入到一个类别树(我最终不得不为每个新层复制我的代码)。

我目前正在尝试这个:

$categories = get_terms("product-category"); 
if ($categories && !is_wp_error($categories)) 
    foreach($categories as $category) 
        $children = get_terms("product-category", array(
            "parent"   => $category->term_id,
        ));
        if (count($children) == 0) 
            echo $category->name;
        
    

这确实会检查它是否是树中最深的,但它实际上并没有构建树。我会继续玩弄它并报告任何进展。非常感谢您的帮助。


更新 4: 在@Nemutaisama 的大力帮助下,我能够解决这个问题!这是我的最终代码(根据他们的回答稍作修改):

function loadCategories($categories, $level) 
    foreach($categories as $category) 
        $cat_class = "";
        $heading_tag = "";
        if ($level == 1) 
            $cat_class = "primary";
            $heading_tag = "h2 style='text-align:center;'";
         elseif ($level == 2) 
            $cat_class = "secondary";
            $heading_tag = "h3";
         else 
            $cat_class = "tertiary";
            $heading_tag = "h4";
        
        echo "<section class='cat $cat_class'>";
        echo "<header>";
        echo "<$heading_tag>$category->name<button>Expand</button></$heading_tag>";
        if ($level == 1) 
            echo "<hr  class='short' />";
        
        echo "</header>";
        if ($level > 1) 
            echo "<div class='expander'>";
        
        $children = get_terms("product-category", array(
            "parent"   => $category->term_id,
        ));
        if (count($children) == 0) 
            $posts = get_posts(array(
                "post_type" => "products",
                "tax_query" => array(
                    array(
                        "field"    => "term_id",
                        "taxonomy" => "product-category",
                        "terms"    => $category->term_id,
                )),
            ));
            foreach ($posts as $post) 
                if ($level < 2) 
                    $cat_class = "secondary";
                    $heading_tag = "h3";
                 else 
                    $cat_class = "tertiary";
                    $heading_tag = "h4";
                
                echo "<section class='cat $cat_class'>";
                echo "<header><$heading_tag>$post->post_title<button>Expand</button></$heading_tag></header>";
                echo "<div class='expander'>";
                echo "<article>";
                if (get_field("product_number", $post->ID)) 
                    echo "<div class='productNumber'><p># " . get_field("product_number", $post->ID) . "</p></div>";
                
                echo "<div class='content'>";
                echo wpautop($post->post_content);
                echo "</div><!--/.content-->";
                echo "</article>";
                echo "</div><!--/.expander-->";
                echo "</section><!--/.cat.$cat_class-->";
            
        
        loadCategories($children, $level+1);
        if ($level > 1) 
            echo "</div><!--/.expander-->";
        
        echo "</section><!--/.cat.$cat_class-->";
    

$categories = get_terms("product-category", array(
    "parent" => 0,
));
if ($categories && !is_wp_error($categories)) 
    loadCategories($categories, 1);

【问题讨论】:

【参考方案1】:

我认为递归函数会帮助你。 像这样的

function loadCategories($categories, $level) 
    foreach($categories as $category) 
        $children = get_terms("product-category", array(
            "parent"   => $category->term_id,
        ));
        $cat_class = "";
        $heading_tag = "";
        if ($level == 1) 
            $cat_class = "primary";
            $heading_tag = "h2 style='text-align:center;'";
         elseif ($level == 2) 
            $cat_class = "secondary";
            $heading_tag = "h3";
         else 
            $cat_class = "tertiary";
            $heading_tag = "h4";
        
        echo "<section class='cat $cat_class'>";
        echo "<header>";
        echo "<$heading_tag>$category->name<button>Expand</button></$heading_tag>";
        if ($level == 1) 
            echo "<hr  class='short' />";
        
        echo "</header>";
        if ($level > 1) 
            echo "<div class='expander'>";
        
        if (count($children) == 0) 
            $posts = get_posts(array(
                "post_type" => "products",
                "tax_query" => array(
                    array(
                        "field"    => "term_id",
                        "taxonomy" => "product-category",
                        "terms"    => $category->term_id,
                )),
            ));
            foreach ($posts as $post) 
                if ($level < 2) 
                    $cat_class = "secondary";
                    $heading_tag = "h3";
                 else 
                    $cat_class = "tertiary";
                    $heading_tag = "h4";
                
                echo "<section class='cat $cat_class'>";
                echo "<header><$heading_tag>$post->post_title<button>Expand</button></$heading_tag></header>";
                echo "<div class='expander'>";
                echo "<article>";
                if (get_field("product_number", $post->ID)) 
                    echo "<div class='productNumber'><p># " . get_field("product_number", $post->ID) . "</p></div>";
                
                echo "<div class='content'>";
                echo wpautop($post->post_content);
                echo "</div><!--/.content-->";
                echo "</article>";
                echo "</div><!--/.expander-->";
                echo "</section><!--/.cat.$cat_class-->";
            
        
        loadCategories($children, $level+1);
        if ($level > 1) 
            echo "</div><!--/.expander-->";
        
        echo "</section><!--/.cat.$cat_class-->";
    

$categories = get_terms("product-category");
if ($categories && !is_wp_error($categories)) 
    loadCategories($categories, 1);

【讨论】:

似乎没有做我想要的。看来您必须传递一个级别变量,并且每个帖子都嵌套在上一个帖子中。我需要它来工作有点像组合存档页面,其中所有内容都按类别组织,但在分层 div 中。我现在会继续工作。 您只需要传递级别变量一次,并且仅用于处理h1, h2, h3 标签。 我明白了,我做了一些修改(原帖中的更新 2),但我仍然有一些问题。它在正确的位置和***列表中输出类别。我仍然看到帖子与此重复,我猜是因为它们都出现在每个类别中,而不仅仅是他们自己的。 你能展示一下 html 输出示例它是怎样的以及应该怎样吗? 该死的。忘记。 $categories = get_terms("product-category"); 是返回所有类别还是仅返回***?您只需要此函数的***类别。

以上是关于在层次结构的一个页面上显示所有类别和帖子的主要内容,如果未能解决你的问题,请参考以下文章

PHP 在页面上以随机顺序显示特定类别的所有帖子

Wordpress 类别模板显示来自所有类别的帖子,而不是特定类别的帖子

如何在具有帖子类型的自定义页面上显示所有图像字段

在类别页面 Wordpress 中显示帖子列表

在 Wordpress Datewise 中为特定类别创建存档

链接到显示所有帖子的存档页面