有没有办法禁用一个术语而不是删除它?

时间:2017-02-23 作者:jsanc623

我的情况是,我必须从分类法中删除一个术语。但是,有些项目链接到该分类法。有时,这些删除是暂时的(即,我们停止向某个国家发货,但如果我们再次开始向该国家发货,希望物品与这些国家保持联系)。

有没有办法“禁用”一个术语而不是wp\\u delete\\u term?谢谢

2 个回复
最合适的回答,由SO网友:Paul \'Sparrow Hawk\' Biron 整理而成

不是直接的,但我也需要这个功能,作为我为客户端编写的插件的一部分,我认为这是实现的一个很好的开始。

我采用的方法是在禁用术语时存储一个术语元,然后连接到get_terms_defaults 筛选以剥离WP Core调用返回的禁用条款get_terms(), get_the_terms(), 等

我的插件将所有这些封装到一个类中,作为register_taxonomy(). 下面是该类的精简版本(对于我正在编写的插件,这个包装器对自定义分类法做了更多的工作)。

看见Custom_Taxonomy::enable_term()Custom_Taxonmy::disable_term() 用于添加/删除相关术语meta的代码;并查看Custom_Taxonomy::strip_disabled_terms() 用于删除禁用术语的代码。

希望,当我去掉不适用于这个问题的东西时,我已经留下了这个类的所有相关代码:-)

/**
 * this class is a wrapper around register_taxonomy(), that adds additional functionality
 * to allow terms in the taxonomy so registered to be "disabled".
 *
 * Disabled terms will NOT be returned by the various WP Core functions like get_terms(),
 * get_the_terms(), etc.
 *
 * TODO: make sure that this works correctly given WP Core\'s object caching, see Custom_Taxonomy::strip_disabled_terms()
 */
class
Custom_Taxonomy
{
    const DISABLED_TERM_META_KEY = \'_shc_disabled\' ;

    public $name ;
    public $can_disable_terms = false ;

    /**
     * construct an instance of Custom_Taxonomy
     *
     * @param $taxonomy string Taxonomy key, must not exceed 32 characters
     * @param $post_types array|string post type or array of post types with which the taxonomy should be associated
     * @param $args array Array or query string of arguments for registering a taxonomy
     *
     * params are the same as WP\'s register_taxonomy() except that $args may have extra keys:
     *
     *  \'can_disable_terms\' => true|false
     */
    function
    __construct ($taxonomy, $post_types, $args)
    {
        $this->name = $taxonomy ;

        // modify args, if needed
        $default_args = array (
            \'can_disable_terms\' => false,
            ) ;
        $args = wp_parse_args ($args, $default_args) ;

        $this->can_disable_terms = $args[\'can_disable_terms\'] ;
        unset ($args[\'can_disable_terms\']) ;

        if ($this->can_disable_terms) {
            // TODO: is there a better filter to hook into than \'get_terms_defaults\'?
            // I\'ve tried \'get_terms_args\', but that seems to be called too late
            // in the process of builing the WP_Term_Query used by get_terms(), etc
            // to have the meta_query that is added by $this->strip_disabled_terms()
            add_filter (\'get_terms_defaults\', array ($this, \'strip_disabled_terms\'), 10, 2) ;
            }

        // register the taxonomy
        register_taxonomy ($taxonomy, $post_types, $args) ;

        return ;
    }

    /**
     * disable a term
     *
     * disabling a term will make it appear as if the term does not exist, without actually deleting it
     *
     * @param $term int|string|WP_Term the term to disable
     * @param $taxonomy string the taxonomy term is in
     * @return int|WP_Error|bool Meta ID on success. WP_Error when term_id is ambiguous between taxonomies. False on failure
     */
    function
    disable_term ($term, $taxonomy = \'\', $field = \'name\')
    {
        if (!$this->can_disable_terms) {
            return ;
            }

        $taxonomy = $taxonomy ? $taxonomy : $this->name ;
        if (is_string ($term)) {
            $term = get_term_by ($field, $term, $taxonomy) ;
            }
        else {
            $term = get_term ($term, $taxonomy) ;
            }

        return (add_term_meta ($term->term_id, self::DISABLED_TERM_META_KEY, true, true)) ;
    }

    /**
     * enable a term
     *
     * @param $term int|WP_Term the term to disable
     * @param $taxonomy string the taxonomy term is in
     * @return bool True on success, false on failure
     */
    function
    enable_term ($term, $taxonomy = \'\', $field = \'name\')
    {
        if (!$this->can_disable_terms) {
            return ;
            }

        $taxonomy = $taxonomy ? $taxonomy : $this->name ;
        if (is_string ($term)) {
            $term = get_term_by ($field, $term, $taxonomy) ;
            }
        else {
            $term = get_term ($term, $taxonomy) ;
            }

        return (delete_term_meta ($term->term_id, self::DISABLED_TERM_META_KEY)) ;
    }

    /**
     * strip disabled terms from e.g., get_terms() and get_the_terms()
     *
     * TODO: make sure that this works correctly given WP Core\'s object caching
     *
     * @param $term int|WP_Term the term to disable
     * @param $taxonomy string the taxonomy term is in
     * @return bool True on success, false on failure
     */
    function
    strip_disabled_terms ($args, $taxonomies)
    {
        if (!$this->can_disable_terms) {
            return ($args) ;
            }

        // I *think* the count(\'taxonomy\') check is necesary because get_terms_args() is
        // applied by the WP Core object_term caching infrastructure by
        // passing all taxonomies for a given post_type, and we only want to
        // add this restriction when we are getting the terms for just the
        // this taxonomy
        if (count ($args[\'taxonomy\']) != 1 || !in_array ($this->name, $args[\'taxonomy\'])) {
            return ($args) ;
            }

        $args[\'meta_query\'] = array (
            array (
                \'key\' => self::DISABLED_TERM_META_KEY,
                \'compare\' => \'NOT EXISTS\',
                )
            ) ;

        return ($args) ;
    }
}
我的用例我有两种自定义帖子类型,type_atype_b. type_b 具有自定义分类,taxonomy_b, 其条款是所有类型的帖子的post\\u标题type_a.

只有type_a 谁的post_statuspublish 应在taxonomy_b 已启用。我通过save_post_type_a 插入术语(如果它们不存在)并启用/禁用它们,然后挂接到delete_post 删除它们。

如果禁用术语的用例非常相似,那么以上内容至少应该为您指明一个可能的方向。

我仍然有一些问题,我仍在开发这个插件,在它的实现方面还有一些悬而未决的问题。

get_terms_defaults 用于将meta\\u查询添加到的筛选器WP_Term_Query 最好的钩子是什么?我试过了get_terms_args, 但是,在构建get\\u terms()等使用的WP\\u Term\\u查询的过程中,这似乎调用得太晚,无法正确处理由Custom_taxonomy::strip_disabled_terms().

我不确定这是如何与WP Core的对象缓存交互的。例如,如果在调用get_terms() 缓存分类法中的术语,并在相同的执行中启用这些术语wp() 是否将后续呼叫get_terms() 包括术语,或者它将返回缓存的术语。。。不包括这个词。但目前为止,我所做的测试似乎都在起作用。

如果有人读到这篇文章,对这个类有任何改进建议,特别是关于对象缓存方面,请插话!

SO网友:Max Yudin

您可以暂时从查询中排除术语。这意味着您将它们隐藏在某些列表页等上。所有排除的术语将不会被删除,项目链接将保持不变。

获取除亚特兰蒂斯、埃尔多拉多和利莫里亚以外的所有国家/地区:

<?php
$args = array(
    \'post_type\'  => \'A_POST_TYPE\', // change this
    \'tax_query\' => array(
        array(
            \'taxonomy\' => \'countries\',
            \'field\'    => \'slug\',
            \'operator\' => \'NOT IN\', // operator to test
            \'terms\'    => array( // countries to exclude
                \'atlantis\',
                \'el-dorado\',
                \'lemuria\'
            ) 
        )
    )
);

$result = new WP_Query($args);
请参见WP_Query() Taxonomy Parameters 更多信息。

Edit

自4.4起term meta 比如说,在那里你可以标记你的方式。“禁用”、“隐藏”等。

https://www.smashingmagazine.com/2015/12/how-to-use-term-meta-data-in-wordpress/

无论如何,您必须更好地重新思考您的查询。

相关推荐

什么时候应该/不应该使用wp_get_post_Terms与Get_the_Terms?

一位用户在codex中提供了一条注释,指出唯一的区别是get\\u术语使用缓存的数据,我已经知道wp\\u get\\u post\\u术语可以让您通过slug检索数据,但我仍然想知道使用其中一个与另一个的最佳情况是什么。