根据用户输入选择复杂类别

时间:2018-02-11 作者:Janith Chinthana

这将是一个很大的解释,因为我没有任何捷径来解释整个场景。

假设我有以下类别结构。(类别ID在每个类别前面都有一个括号)

First Level 1 (100)
    Second Level 1 (104)
        Third Level 1 (108)
        Third Level 2 (109)
        Third Level 3 (110)
        Third Level 4 (111)
    Second Level 2 (105)
        Third Level 1 (112)
        Third Level 2 (113)
First Level 2 (101)
    Second Level 1 (106)
        Third Level 1 (114)
        Third Level 2 (115)
        Third Level 3 (116)
    Second Level 2 (107)
        Third Level 1 (117)
        Third Level 2 (118)
First Level 3 (102)
First Level 4 (103)
我要求用户可以自由选择他们需要在博客中看到的类别(我称之为过滤器)。因此,我通过预先选择所有类别为用户提供了相同的结构,如果有人需要排除某个类别,那么用户可以取消对其的锁定。

但我有一定的逻辑,可以根据下面的过滤器显示帖子。

How filters work:

Second Level 是一个与用户选择无关的内部级别,尽管它有助于保持层次结构。用户只能勾选Third Level 通过勾选其父类别First Level. 如果用户取消勾选First Level 子项将自动锁定。

LOGIC: (为了便于解释,我会考虑发一篇帖子)

FIRST RULE:

如果有人打勾First Level 类别,如果它有孩子,我应该进入下面的第二步。

只有当至少有一个Third Level 帖子的类别也在用户的过滤器中打勾。但我们需要在每个Second Level 各部分分开。

E、 g。Third Level 1Third Level 2 在邮寄中打钩(在First Level 1 &;Second Level 1)

用户未选中Third Level 1 但勾选了Third Level 2, 然后仍将显示(绿灯)

但用户只勾选了Third Level 3 (根据First Level 1 &;Second Level 1) 在过滤器中,则不会显示帖子。(红灯)

因此,只有在所有Second Level 部分显示绿灯。在上述示例中Second Level 1Second Level 2 (根据First Level 1) 应符合上述逻辑以显示帖子。

例如:用户感兴趣First Level 1 (来自过滤器)。职位也分类为First Level 1

然后我应该进入第二步,我需要检查所有Second Level 满足上述逻辑的部分。

  • Second Level 1
  • Second Level 2Second Level 部分显示红灯,交易将不会显示。

    SECOND RULE:

    如果其中一个First Level 类别没有任何子级,那么勾选它本身就认为满足了筛选要求。

    THIRD RULE:

    任何职位至少完成一项First Level 被视为帖子的要求将显示在博客上。

    这就是根据用户过滤输入在博客上显示帖子的逻辑。现在我真正需要的是WP_Query. 老实说,我甚至不知道如何开始,因为我在Wordpress方面没有太多经验。但我最初的尝试是category__in 所有勾选的类别ID不符合新逻辑。

    任何帮助都将不胜感激,因为我已经被困在这几天了。

    提前谢谢。

    UPDATE 1:

    如果有人解开110 &;111 rest all被认为是勾选的,然后sameple算法tax_query 就像贝娄一样。但在现实中,这根本不是加载。

    $args = array(
        \'post_type\' => \'post\',
        \'tax_query\' => array(
            \'relation\' => \'OR\',
            array(
                \'relation\' => \'AND\',
                array(
                    \'taxonomy\' => \'category\',
                    \'field\'    => \'term_id\',
                    \'terms\'    => array( 108,109 ),
                    \'operator\' => \'IN\',
                ),
                array(
                    \'taxonomy\' => \'category\',
                    \'field\'    => \'term_id\',
                    \'terms\'    => array( 112,113 ),
                    \'operator\' => \'IN\',
                )
            ),
            array(
                \'relation\' => \'AND\',
                array(
                    \'taxonomy\' => \'category\',
                    \'field\'    => \'term_id\',
                    \'terms\'    => array( 114,115,116 ),
                    \'operator\' => \'IN\',
                ),
                array(
                    \'taxonomy\' => \'category\',
                    \'field\'    => \'term_id\',
                    \'terms\'    => array( 117,118 ),
                    \'operator\' => \'IN\',
                )
            ),
            array(
                \'taxonomy\' => \'category\',
                \'field\'    => \'term_id\',
                \'terms\'    => array( 102, 103 ),
                \'operator\' => \'IN\',
            ),
        ),
    );
    

2 个回复
最合适的回答,由SO网友:Janith Chinthana 整理而成

经过长时间的研究,我找到的唯一方法是,使用自定义sql查询获得以下结果。

SELECT SQL_CALC_FOUND_ROWS blog_posts.* FROM (
SELECT blog_posts.* FROM blog_posts 
INNER JOIN blog_term_relationships AS tt0 ON (blog_posts.ID = tt0.object_id AND tt0.term_taxonomy_id IN (108,109)) 
INNER JOIN blog_term_relationships AS tt1 ON (blog_posts.ID = tt1.object_id AND tt1.term_taxonomy_id IN (112,113)) 
WHERE blog_posts.post_type = \'post\' AND (blog_posts.post_status = \'publish\') 
UNION 
SELECT blog_posts.* FROM blog_posts 
INNER JOIN blog_term_relationships AS tt3 ON (blog_posts.ID = tt3.object_id AND tt3.term_taxonomy_id IN (114,115,116)) 
INNER JOIN blog_term_relationships AS tt4 ON (blog_posts.ID = tt4.object_id AND tt4.term_taxonomy_id IN (117,118)) 
WHERE blog_posts.post_type = \'post\' AND (blog_posts.post_status = \'publish\') ) blog_posts 
GROUP BY blog_posts.ID ORDER BY blog_posts.post_date DESC LIMIT 0, 12;
以下代码用于根据https://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query

$pageposts = $wpdb->get_results($querystr, OBJECT);

SO网友:Vlad Olaru

您需要使用的查询并没有那么复杂,因为您基本上只需要从特定的分类中获取帖子。你是对的,你应该使用tax_query.

您应该做的第一件事是只在一个数组中整理所有类别ID,因为您只使用IN 条件(即至少属于列表中一个类别的帖子)。如果一个税务查询就足够了,那么多个税务查询就很容易出错,而且速度也很慢。

查询的问题是您使用的是AND 在你的情况下,这种关系从来都不是真的(即,你没有一篇文章同时出现在108或109类、112或113类中)。

因此,我建议您使用WP\\u Query args,如下所示:

$args = array(
    \'post_type\' => \'post\',
    \'tax_query\' => array(
        array(
            \'taxonomy\' => \'category\',
            \'field\'    => \'term_id\',
            \'terms\'    => array( 108, 109, 112, 113, 114, 115, 116, 117, 118, 102, 103 ),
            \'operator\' => \'IN\',
        ),
    ),
);
我知道您有一个多步骤逻辑来选择要在某些类别中显示的帖子。我对此进行了一些思考,通过各种和/或关系在税务查询中实现此逻辑将非常麻烦。我认为您应该在PHP中完成所有类别选择,并最终得到一个类别ID数组,您可以像上面那样使用它。这将允许您将逻辑与实际的帖子选择分开。

结束

相关推荐

wp_list_categories + widget

使用下面的代码,我添加了一个span标记,并将类别计数放置在链接中。add_filter(\'wp_list_categories\', \'cat_count_span\'); function cat_count_span($links) { $links = str_replace(\'</a> (\', \'<span>\', $links); $links = str_replace(\')\', \'<