不是直接的,但我也需要这个功能,作为我为客户端编写的插件的一部分,我认为这是实现的一个很好的开始。
我采用的方法是在禁用术语时存储一个术语元,然后连接到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_a
和
type_b
.
type_b
具有自定义分类,
taxonomy_b
, 其条款是所有类型的帖子的post\\u标题
type_a
.
只有type_a
谁的post_status
是publish
应在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()
包括术语,或者它将返回缓存的术语。。。不包括这个词。但目前为止,我所做的测试似乎都在起作用。
如果有人读到这篇文章,对这个类有任何改进建议,特别是关于对象缓存方面,请插话!