使用POSTS_WHERE或类似的命令从所有查询中排除特定术语

时间:2014-09-12 作者:Wes Moberly

基本上,我想做的是排除所有属于某一特定术语集的帖子,除非您实际查看该帖子或页面。基本上就像YouTube的“未登录”功能是如何与视频协同工作的。我想知道最好的办法是什么。下面是我目前使用的内容,尽管我觉得这可能会在性能方面有所改进(SQL不是我最擅长的)。

add_filter( \'posts_where\', \'exclude_terms_posts_where\' );
function exclude_terms_posts_where( $clause = \'\' ) {
    global $wpdb;

    // Returns an array of term IDs to exclude from
    $excluded_terms = get_excluded_terms();

    if ( empty( $excluded_terms ) ) {
        return $clause;
    }

    // Filter out the current page / post
    if ( false !== ( $key = array_search( $post->ID, $excluded_terms ) ) ) {
        unset( $excluded_terms[$key] );
    }

    $excluded_terms = implode( \',\', $excluded_terms );
    $clause .= "
        AND {$wpdb->posts}.ID NOT IN (
            SELECT {$wpdb->posts}.ID FROM {$wpdb->posts}
            INNER JOIN {$wpdb->term_relationships} ON (
                {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id
            )
            INNER JOIN $wpdb->term_taxonomy ON (
                {$wpdb->term_relationships}.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id
                AND {$wpdb->term_taxonomy}.taxonomy = \'placement\'
                AND {$wpdb->term_taxonomy}.term_id IN ( {$excluded_terms} )
            )
        )
    ";

    return $clause;
}
如果有人有任何想法或建议,我将不胜感激。

谢谢

1 个回复
SO网友:Pieter Goosen

我应该承认,我的SQL知识很差,所以我将使用非SQL方法来实现这一点。

Here is my idea:

使用pre_get_posts 在执行主查询之前更改查询变量。因为所有查询变量都已按时间设置pre_get_posts 运行时,您只需根据需要更改它们,而且条件标记也可用,因此您可以有条件地执行所需的操作。

例如,您说需要排除某个术语,因此可以使用tax_query 要从主查询中排除术语,请使用is_tax 在特定分类页面上允许该术语

像这样的东西可能有用请注意:这未经测试

function wpse_exclude_term( $query ) {
    if ( !is_admin() && $query->is_main_query() && !is_tax( \'TAXONOMY_NAME\', \'TERM_NAME/SLUG/ID\' ) ) {
        $tax_query = array(
            array(
                \'taxonomy\' => \'TAXONOMY_NAME\',
                \'field\'    => \'slug\',
                \'terms\'    => \'TERM_SLUG\',
                \'operator\' => \'NOT IN\'
            ),
        );
        $query->set( \'tax_query\', $tax_query );
    }
}
add_action( \'pre_get_posts\', \'wpse_exclude_term\' );

RUNDOWN ON SOME OF THE IMPORTANT CODE

  • !is_tax( \'TAXONOMY_NAME\', \'TERM_NAME/SLUG/ID\' ) 条件检查,检查您是否not 在特定分类页面上。注意NOT运算符(!)

  • !is_admin() && $query->is_main_query() 基本上只需确保只在主查询和前端进行更改

  • \'operator\' => \'NOT IN\' 这不包括tax_query

结束
使用POSTS_WHERE或类似的命令从所有查询中排除特定术语 - 小码农CODE - 行之有效找到问题解决它

使用POSTS_WHERE或类似的命令从所有查询中排除特定术语

时间:2014-09-12 作者:Wes Moberly

基本上,我想做的是排除所有属于某一特定术语集的帖子,除非您实际查看该帖子或页面。基本上就像YouTube的“未登录”功能是如何与视频协同工作的。我想知道最好的办法是什么。下面是我目前使用的内容,尽管我觉得这可能会在性能方面有所改进(SQL不是我最擅长的)。

add_filter( \'posts_where\', \'exclude_terms_posts_where\' );
function exclude_terms_posts_where( $clause = \'\' ) {
    global $wpdb;

    // Returns an array of term IDs to exclude from
    $excluded_terms = get_excluded_terms();

    if ( empty( $excluded_terms ) ) {
        return $clause;
    }

    // Filter out the current page / post
    if ( false !== ( $key = array_search( $post->ID, $excluded_terms ) ) ) {
        unset( $excluded_terms[$key] );
    }

    $excluded_terms = implode( \',\', $excluded_terms );
    $clause .= "
        AND {$wpdb->posts}.ID NOT IN (
            SELECT {$wpdb->posts}.ID FROM {$wpdb->posts}
            INNER JOIN {$wpdb->term_relationships} ON (
                {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id
            )
            INNER JOIN $wpdb->term_taxonomy ON (
                {$wpdb->term_relationships}.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id
                AND {$wpdb->term_taxonomy}.taxonomy = \'placement\'
                AND {$wpdb->term_taxonomy}.term_id IN ( {$excluded_terms} )
            )
        )
    ";

    return $clause;
}
如果有人有任何想法或建议,我将不胜感激。

谢谢

1 个回复
SO网友:Pieter Goosen

我应该承认,我的SQL知识很差,所以我将使用非SQL方法来实现这一点。

Here is my idea:

使用pre_get_posts 在执行主查询之前更改查询变量。因为所有查询变量都已按时间设置pre_get_posts 运行时,您只需根据需要更改它们,而且条件标记也可用,因此您可以有条件地执行所需的操作。

例如,您说需要排除某个术语,因此可以使用tax_query 要从主查询中排除术语,请使用is_tax 在特定分类页面上允许该术语

像这样的东西可能有用请注意:这未经测试

function wpse_exclude_term( $query ) {
    if ( !is_admin() && $query->is_main_query() && !is_tax( \'TAXONOMY_NAME\', \'TERM_NAME/SLUG/ID\' ) ) {
        $tax_query = array(
            array(
                \'taxonomy\' => \'TAXONOMY_NAME\',
                \'field\'    => \'slug\',
                \'terms\'    => \'TERM_SLUG\',
                \'operator\' => \'NOT IN\'
            ),
        );
        $query->set( \'tax_query\', $tax_query );
    }
}
add_action( \'pre_get_posts\', \'wpse_exclude_term\' );

RUNDOWN ON SOME OF THE IMPORTANT CODE

  • !is_tax( \'TAXONOMY_NAME\', \'TERM_NAME/SLUG/ID\' ) 条件检查,检查您是否not 在特定分类页面上。注意NOT运算符(!)

  • !is_admin() && $query->is_main_query() 基本上只需确保只在主查询和前端进行更改

  • \'operator\' => \'NOT IN\' 这不包括tax_query