将分类过滤器添加到自定义帖子类型的管理列表?
-
16-10-2019 - |
题
我创建了一个名为的自定义帖子类型 'listing'
并添加了一个名为的自定义分类法 'businesses'
. 。我想将企业下拉列表添加到列表的管理列表中。
这是此功能在帖子管理列表中的样子 (我希望我的自定义帖子类型也如此):
这是我当前的代码 (这是 Gist 上的相同代码。):
<?php
/*
Plugin Name: Listing Content Item
Plugin URI:
Description:
Author:
Version: 1.0
Author URI:
*/
class Listing {
var $meta_fields = array("list-address1","list-address2","list-country","list-province","list-city","list-postcode","list-firstname","list-lastname","list-website","list-mobile","list-phone","list-fax","list-email", "list-profile", "list-distributionrange", "list-distributionarea");
public function loadStyleScripts() {
$eventsURL = trailingslashit( WP_PLUGIN_URL ) . trailingslashit( plugin_basename( dirname( __FILE__ ) ) ) . 'css/';
wp_enqueue_style('listing-style', $eventsURL.'listing.css');
}
function Listing() {
// Register custom post types
register_post_type('listing', array(
'labels' => array(
'name' => __('Listings'), 'singular_name' => __( 'Listing' ),
'add_new' => __( 'Add Listing' ),
'add_new_item' => __( 'Add New Listing' ),
'edit' => __( 'Edit' ),
'edit_item' => __( 'Edit Listing' ),
'new_item' => __( 'New Listing' ),
'view' => __( 'View Listing' ),
'view_item' => __( 'View Listing' ),
'search_items' => __( 'Search Listings' ),
'not_found' => __( 'No listings found' ),
'not_found_in_trash' => __( 'No listings found in Trash' ),
'parent' => __( 'Parent Listing' ),
),
'singular_label' => __('Listing'),
'public' => true,
'show_ui' => true, // UI in admin panel
'_builtin' => false, // It's a custom post type, not built in
'_edit_link' => 'post.php?post=%d',
'capability_type' => 'post',
'hierarchical' => false,
'rewrite' => array("slug" => "listings"), // Permalinks
'query_var' => "listings", // This goes to the WP_Query schema
'supports' => array('title','editor')
));
add_filter("manage_edit-listing_columns", array(&$this, "edit_columns"));
add_action("manage_posts_custom_column", array(&$this, "custom_columns"));
// Register custom taxonomy
#Businesses
register_taxonomy("businesses", array("listing"), array(
"hierarchical" => true,
"label" => "Listing Categories",
"singular_label" => "Listing Categorie",
"rewrite" => true,
));
# Region
register_taxonomy("regions", array("listing"), array(
'labels' => array(
'search_items' => __( 'Search Regions' ),
'popular_items' => __( 'Popular Regions' ),
'all_items' => __( 'All Regions' ),
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => __( 'Edit Region' ),
'update_item' => __( 'Update Region' ),
'add_new_item' => __( 'Add New Region' ),
'new_item_name' => __( 'New Region Name' ),
'separate_items_with_commas' => __( 'Separate regions with commas' ),
'add_or_remove_items' => __( 'Add or remove regions' ),
'choose_from_most_used' => __( 'Choose from the most used regions' ),
),
"hierarchical" => false,
"label" => "Listing Regions",
"singular_label" => "Listing Region",
"rewrite" => true,
));
# Member Organizations
register_taxonomy("organizations", array("listing"), array(
'labels' => array(
'search_items' => __( 'Search Member Organizations' ),
'popular_items' => __( 'Popular Member Organizations' ),
'all_items' => __( 'All Member Organizations' ),
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => __( 'Edit Member Organization' ),
'update_item' => __( 'Update Member Organization' ),
'add_new_item' => __( 'Add New Member Organization' ),
'new_item_name' => __( 'New Member Organization Name' ),
'separate_items_with_commas' => __( 'Separate member organizations with commas' ),
'add_or_remove_items' => __( 'Add or remove member organizations' ),
'choose_from_most_used' => __( 'Choose from the most used member organizations' ),
),
"hierarchical" => false,
"label" => "Member Organizations",
"singular_label" => "Member Organization",
"rewrite" => true,
));
# Retail Products
register_taxonomy("retails", array("listing"), array(
'labels' => array(
'search_items' => __( 'Search Retail Products' ),
'popular_items' => __( 'Popular Retail Products' ),
'all_items' => __( 'All Retail Products' ),
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => __( 'Edit Retail Product' ),
'update_item' => __( 'Update Retail Product' ),
'add_new_item' => __( 'Add New Retail Product' ),
'new_item_name' => __( 'New Retail Product Name' ),
'separate_items_with_commas' => __( 'Separate retail products with commas' ),
'add_or_remove_items' => __( 'Add or remove retail products' ),
'choose_from_most_used' => __( 'Choose from the most used retail products' ),
),
"hierarchical" => false,
"label" => "Retail Products",
"singular_label" => "Retail Product",
"rewrite" => true,
));
# Farming Practices
register_taxonomy("practices", array("listing"), array(
'labels' => array(
'search_items' => __( 'Search Farming Practices' ),
'popular_items' => __( 'Popular Farming Practices' ),
'all_items' => __( 'All Farming Practices' ),
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => __( 'Edit Farming Practice' ),
'update_item' => __( 'Update Farming Practice' ),
'add_new_item' => __( 'Add New Farming Practice' ),
'new_item_name' => __( 'New Farming Practice Name' ),
'separate_items_with_commas' => __( 'Separate farming practices with commas' ),
'add_or_remove_items' => __( 'Add or remove farming practices' ),
'choose_from_most_used' => __( 'Choose from the most used farming practices' ),
),
"hierarchical" => false,
"label" => "Farming Practices",
"singular_label" => "Farming Practice",
"rewrite" => true,
));
# Products
register_taxonomy("products", array("listing"), array(
'labels' => array(
'search_items' => __( 'Search Products' ),
'popular_items' => __( 'Popular Products' ),
'all_items' => __( 'All Products' ),
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => __( 'Edit Product' ),
'update_item' => __( 'Update Product' ),
'add_new_item' => __( 'Add New Product' ),
'new_item_name' => __( 'New Product Name' ),
'separate_items_with_commas' => __( 'Separate products with commas' ),
'add_or_remove_items' => __( 'Add or remove products' ),
'choose_from_most_used' => __( 'Choose from the most used products' ),
),
"hierarchical" => false,
"label" => "Products",
"singular_label" => "Product",
"rewrite" => true,
));
// Admin interface init
add_action("admin_init", array(&$this, "admin_init"));
add_action("template_redirect", array(&$this, 'template_redirect'));
// Insert post hook
add_action("wp_insert_post", array(&$this, "wp_insert_post"), 10, 2);
}
function edit_columns($columns) {
$columns = array(
"cb" => "<input type=\"checkbox\" />",
"title" => "Business Name",
"description" => "Description",
"list-personal" => "Personal Information",
"list-location" => "Location",
"list-categorie" => "Categorie",
);
return $columns;
}
function custom_columns($column) {
global $post;
switch ($column) {
case "description":
the_excerpt();
break;
case "list-personal":
$custom = get_post_custom();
if(isset($custom["list-firstname"][0])) echo $custom["list-firstname"][0]."<br />";
if(isset($custom["list-lastname"][0])) echo $custom["list-lastname"][0]."<br />";
if(isset($custom["list-email"][0])) echo $custom["list-email"][0]."<br />";
if(isset($custom["list-website"][0])) echo $custom["list-website"][0]."<br />";
if(isset($custom["list-phone"][0])) echo $custom["list-phone"][0]."<br />";
if(isset($custom["list-mobile"][0])) echo $custom["list-mobile"][0]."<br />";
if(isset($custom["list-fax"][0])) echo $custom["list-fax"][0];
break;
case "list-location":
$custom = get_post_custom();
if(isset($custom["list-address1"][0])) echo $custom["list-address1"][0]."<br />";
if(isset($custom["list-address2"][0])) echo $custom["list-address2"][0]."<br />";
if(isset($custom["list-city"][0])) echo $custom["list-city"][0]."<br />";
if(isset($custom["list-province"][0])) echo $custom["list-province"][0]."<br />";
if(isset($custom["list-postcode"][0])) echo $custom["list-postcode"][0]."<br />";
if(isset($custom["list-country"][0])) echo $custom["list-country"][0]."<br />";
if(isset($custom["list-profile"][0])) echo $custom["list-profile"][0]."<br />";
if(isset($custom["list-distributionrange"][0])) echo $custom["list-distributionrange"][0]."<br />";
if(isset($custom["list-distributionarea"][0])) echo $custom["list-distributionarea"][0];
break;
case "list-categorie":
$speakers = get_the_terms(0, "businesses");
$speakers_html = array();
if(is_array($speakers)) {
foreach ($speakers as $speaker)
array_push($speakers_html, '<a href="' . get_term_link($speaker->slug, 'businesses') . '">' . $speaker->name . '</a>');
echo implode($speakers_html, ", ");
}
break;
}
}
// Template selection
function template_redirect() {
global $wp;
if (isset($wp->query_vars["post_type"]) && ($wp->query_vars["post_type"] == "listing")) {
include(STYLESHEETPATH . "/listing.php");
die();
}
}
// When a post is inserted or updated
function wp_insert_post($post_id, $post = null) {
if ($post->post_type == "listing") {
// Loop through the POST data
foreach ($this->meta_fields as $key) {
$value = @$_POST[$key];
if (empty($value)) {
delete_post_meta($post_id, $key);
continue;
}
// If value is a string it should be unique
if (!is_array($value)) {
// Update meta
if (!update_post_meta($post_id, $key, $value)) {
// Or add the meta data
add_post_meta($post_id, $key, $value);
}
}
else
{
// If passed along is an array, we should remove all previous data
delete_post_meta($post_id, $key);
// Loop through the array adding new values to the post meta as different entries with the same name
foreach ($value as $entry)
add_post_meta($post_id, $key, $entry);
}
}
}
}
function admin_init() {
// Custom meta boxes for the edit listing screen
add_meta_box("list-pers-meta", "Personal Information", array(&$this, "meta_personal"), "listing", "normal", "low");
add_meta_box("list-meta", "Location", array(&$this, "meta_location"), "listing", "normal", "low");
}
function meta_personal() {
global $post;
$custom = get_post_custom($post->ID);
if(isset($custom["list-firstname"][0])) $first_name = $custom["list-firstname"][0];else $first_name = '';
if(isset($custom["list-lastname"][0])) $last_name = $custom["list-lastname"][0];else $last_name = '';
if(isset($custom["list-website"][0])) $website = $custom["list-website"][0];else $website = '';
if(isset($custom["list-phone"][0])) $phone = $custom["list-phone"][0];else $phone = '';
if(isset($custom["list-mobile"][0])) $mobile = $custom["list-mobile"][0];else $mobile = '';
if(isset($custom["list-fax"][0])) $fax = $custom["list-fax"][0];else $fax = '';
if(isset($custom["list-email"][0])) $email = $custom["list-email"][0];else $email = '';
?>
<div class="personal">
<table border="0" id="personal">
<tr><td class="personal_field"><label>Firstname:</label></td><td class="personal_input"><input name="list-firstname" value="<?php echo $first_name; ?>" /></td></tr>
<tr><td class="personal_field"><label>Lastname:</label></td><td class="personal_input"><input name="list-lastname" value="<?php echo $last_name; ?>" /></td></tr>
<tr><td class="personal_field"><label>Email:</label></td><td class="personal_input"><input name="list-email" value="<?php echo $email; ?>" size="40"/></td></tr>
<tr><td class="personal_field"><label>Website:</label></td><td class="personal_input"><input name="list-website" value="<?php echo $website; ?>" size="40"/></td></tr>
<tr><td class="personal_field"><label>Phone:</label></td><td class="personal_input"><input name="list-phone" value="<?php echo $phone; ?>" /></td></tr>
<tr><td class="personal_field"><label>Mobile:</label></td><td class="personal_input"><input name="list-mobile" value="<?php echo $mobile; ?>" /></td></tr>
<tr><td class="personal_field"><label>Fax:</label></td><td class="personal_input"><input name="list-fax" value="<?php echo $fax; ?>" /></td></tr>
</table>
</div>
<?php
}
// Admin post meta contents
function meta_location() {
global $post;
$custom = get_post_custom($post->ID);
if(isset($custom["list-address1"])) $address1 = $custom["list-address1"][0];else $address1 = '';
if(isset($custom["list-address2"])) $address2 = $custom["list-address2"][0];else $address2 = '';
if(isset($custom["list-country"])) $country = $custom["list-country"][0];else $country = '';
if(isset($custom["list-province"])) $province = $custom["list-province"][0];else $province = '';
if(isset($custom["list-city"])) $city = $custom["list-city"][0];else $city = '';
if(isset($custom["list-postcode"])) $post_code = $custom["list-postcode"][0];else $post_code = '';
if(isset($custom["list-profile"])) $profile = $custom["list-profile"][0];else $profile = '';
if(isset($custom["list-distributionrange"])) $distribution_range = $custom["list-distributionrange"][0];else $distribution_range = '';
if(isset($custom["list-distributionarea"])) $distribution_area = $custom["list-distributionarea"][0];else $ddistribution_area = '';
?>
<div class="location">
<table border="0" id="location">
<tr><td class="location_field"><label>Address 1:</label></td><td class="location_input"><input name="list-address1" value="<?php echo $address1; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Address 2:</label></td><td class="location_input"><input name="list-address2" value="<?php echo $address2; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>City:</label></td><td class="location_input"><input name="list-city" value="<?php echo $city; ?>" /></td></tr>
<tr><td class="location_field"><label>Province:</label></td><td class="location_input"><input name="list-province" value="Ontario" readonly /></td></tr>
<tr><td class="location_field"><label>Postal Code:</label></td><td class="location_input"><input name="list-postcode" value="<?php echo $post_code; ?>" /></td></tr>
<tr><td class="location_field"><label>Country:</label></td><td class="location_input"><input name="list-country" value="Canada" readonly /></td></tr>
<tr><td class="location_field"><label>Profile:</label></td><td class="location_input"><input name="list-profile" value="<?php echo $profile; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Distribution Range:</label></td><td class="location_input"><input name="list-distributionrange" value="<?php echo $distribution_range; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Distribution Area:</label></td><td class="location_input"><input name="list-distributionarea" value="<?php echo $distribution_area; ?>" size="60" /></td></tr>
</table>
</div>
<?php
}
}
// Initiate the plugin
add_action("init", "ListingInit");
function ListingInit() {
global $listing;
$listing = new Listing();
$add_css = $listing->loadStyleScripts();
}
如何将企业下拉列表添加到列表的管理列表中?
解决方案
更新: 我已经包含了一个新的完整答案,但即便如此,我还是将最初的回复留在了前几条评论引用的底部。
你好 @塔拉斯姆:
虽然我说这不应该很难,但还是有点复杂。但在我们深入研究代码之前......
截图:
...让我们看看成品的一些屏幕截图:
清单列表页面 不 过滤:
(来源: mikeschinkel.com)
房源列表页面 和 过滤:
(来源: mikeschinkel.com)
代码
那么我们开始吧...(笔记: 我使用单数形式作为分类名称 business
;我希望与你的相符。根据过去 WordPress 和数据库开发的大量经验,我相信最好这样做。)
步骤1:这 restrict_manage_posts
动作挂钩。
您需要做的第一件事就是挂钩 restrict_manage_posts
没有参数并且被调用的动作 /wp-admin/edit.php
(在 v3.0.1 中,该调用位于第 378 行。)这将允许您在列表帖子列表上方的适当位置生成下拉选择。
<?php
add_action('restrict_manage_posts','restrict_listings_by_business');
function restrict_listings_by_business() {
global $typenow;
global $wp_query;
if ($typenow=='listing') {
$taxonomy = 'business';
$business_taxonomy = get_taxonomy($taxonomy);
wp_dropdown_categories(array(
'show_option_all' => __("Show All {$business_taxonomy->label}"),
'taxonomy' => $taxonomy,
'name' => 'business',
'orderby' => 'name',
'selected' => $wp_query->query['term'],
'hierarchical' => true,
'depth' => 3,
'show_count' => true, // Show # listings in parens
'hide_empty' => true, // Don't show businesses w/o listings
));
}
}
我们首先检查 $typenow
变量以确保我们实际上处于 post_type
的 listing
. 。如果您不这样做,您将获得所有帖子类型的下拉列表,这在某些情况下是您想要的,但在这种情况下不是。
接下来,我们使用以下方式加载有关业务分类的信息 get_taxonomy()
. 。我们需要它来检索分类法的标签(即”企业”;我们可以进行硬编码,但如果您稍后需要国际化,那就不太好。)然后我们调用 wp_dropdown_categories()
与所有适当的参数 $args
生成下拉列表的数组
<?php
return wp_dropdown_categories(array(
'show_option_all' => __("Show All {$business_taxonomy->label}"),
'taxonomy' => $taxonomy,
'name' => 'business',
'orderby' => 'name',
'selected' => $wp_query->query['term'],
'hierarchical' => true,
'depth' => 3,
'show_count' => true, // Show # listings in parens
'hide_empty' => true, // Don't show businesses w/o listings
));
但什么是适当的论据呢?让我们分别看看:
show_optional_all
- 非常简单,这是下拉列表中首先显示的内容以及未应用过滤时的内容。在我们的例子中,事情会是这样 “显示所有企业“但我们可以称之为 “所有企业的清单” 或者任何你喜欢的东西。taxonomy
- 这个参数告诉函数从什么分类中提取术语,即使函数有categories
以它的名义。在 v2.8 及更早版本中,WordPress 没有自定义分类法,但当添加它们时,团队决定向此函数添加分类法参数比创建另一个具有其他名称的函数更容易。name
- 此参数允许您指定 WordPress 使用的值name
为下拉列表生成的 <select> 元素的属性。以防万一,这也是过滤时将在 URL 中使用的值。orderby
- 此参数告诉 WordPress 如何按字母顺序对结果进行排序。在我们的例子中,我们指定订购name
分类学中的术语,即本例中的公司名称。selected
- 需要此参数,以便下拉列表可以显示下拉列表中的当前过滤器。应该是term_id
来自所选的分类术语。在我们的例子中,它可能是term_id
从 “业务#2”. 。我们从哪里得到这个值?来自 WordPress 的全局变量$wp_query
;它有一个属性query
包含所有 URL 参数及其值的数组(当然,除非某些任性的插件已经修改了它。)鉴于 WordPress 处理事物的方式,将会有一个term
如果用户选择了有效术语(即,用户单击过滤器按钮),则 URL 参数会在 URL 上传递。上市企业之一)。hierarchical
- 通过将其设置为true
您告诉该函数尊重分类法的层次性质,如果术语(企业)实际上有子项,则将它们显示在树视图中。有关屏幕截图以了解其外观,请参见下文。depth
- 这个论点与hierarchical
参数来确定函数在显示子项时应深入多少层。show_count
- 如果true
此参数将在下拉列表中术语名称左侧的括号内显示帖子计数。在这种情况下,它将显示与企业相关的列表计数。有关屏幕截图以了解其外观,请参见下文。hide_empty
- 最后,如果分类中有术语 不是 与帖子相关(即与列表无关的企业)然后将其设置为true
将省略它们,使其不包含在下拉列表中。
(来源: mikeschinkel.com)
第2步:这 parse_query
过滤钩。
接下来我们请大家注意 parse_query
过滤钩子有一个参数($query
) 并被调用 /wp-includes/query.php
(在 v3.0.1 中,该调用位于第 1549 行。)当 WordPress 完成检查 URL 并在当前活动中设置所有适当的值时调用它。 $wp_query
包括诸如此类的事情 $wp_query->is_home
和 $wp_query->is_author
, , ETC。
之后 parse_query
过滤钩子运行 WordPress 会调用 get_posts()
并根据当前活动中指定的内容加载帖子列表 $wp_query
. 。所以 parse_query
通常是让 WordPress 改变要加载哪些帖子的想法的好地方。
在您的用例中,我们希望 WordPress 根据所选企业进行过滤;IE。仅显示与所选企业关联的那些列表(我想说 “......只有那些已被 “已分类” 由所选企业” 但这在技术上是不正确的; category
它有自己的同行分类法吗 business
除了那个 category
内置于 WordPress 中并且 business
是定制的。但对于那些熟悉帖子分类的人来说,这可能会帮助您理解,因为它们的工作原理几乎相同。但我离题了……)
继续看代码。我们做的第一件事是获取对当前活动的引用 $wp_query
的 query_vars
这样使用起来更方便,就像在 WordPress 自己的内部完成的一样 parse_query()
功能。不像 $wp_query->query
它用于镜像 URL 上传递的参数 $wp_query->query_vars
数组用于控制 WordPress 运行并预期被修改的查询。所以如果你需要修改一个,那就是那个(至少我是这样的) 思考 这就是两者的区别;如果有人知道的话 请 请告诉我,以便我更新!)
<?php
add_filter('parse_query','convert_business_id_to_taxonomy_term_in_query');
function convert_business_id_to_taxonomy_term_in_query($query) {
global $pagenow;
$qv = &$query->query_vars;
if ($pagenow=='edit.php' &&
isset($qv['taxonomy']) && $qv['taxonomy']=='business' &&
isset($qv['term']) && is_numeric($qv['term'])) {
$term = get_term_by('id',$qv['term'],'business');
$qv['term'] = $term->slug;
}
}
接下来我们测试一下 $pagenow
确保我们确实从 URL 路径加载 WordPress /wp-admin/edit.php
. 。我们这样做是为了避免意外搞砸其他页面上的查询。我们还检查以确保我们都拥有 business
作为一个 taxonomy
元素和一个 term
元素也。(笔记 taxonomy
和 term
是一对;它们一起使用以允许查询分类术语;必须两者都有,否则 WordPress 不知道要检查哪个分类法。)
你可能想知道如何 business
出现在 taxonomy
的元素 query_vars
大批。我们在我们的 parse_query
钩子触发了 WordPress 的内部魔法,当您注册“business
" 通过设置分类 query_var
是真实的 (register_taxonomy()
将分类法的名称复制为它的名称 query_var
;您当然可以更改它,但除非有冲突,否则最好坚持相同):
<?php
add_action('init','register_business_taxonomy');
function register_business_taxonomy() {
register_taxonomy('business',array('listing'),array(
'label' => 'Businesses',
'public'=>true,
'hierarchical'=>true,
'show_ui'=>true,
'query_var'=>true
));
}
现在,WordPress 的 $wp_query 被编写为使用 slugs 进行标准分类过滤查询,而不是分类术语 ID。对于这个用例,我们真正需要使过滤查询工作的是:
taxonomy
: 商业
term
: 商业-1 (IE。这slug
)
不是这些:
taxonomy
: 商业
term
: 27 (IE。这term_id
)
有趣但不幸的是,生成的下拉菜单 wp_dropdown_categories()
设置 <option>
的 value
术语's(/business')的属性 term_id
, 不是 期限 slug
. 。所以我们需要转换 $wp_query->query_vars['term']
从数字 term_id
到它的字符串 slug
如下所示(请注意,这不是查询数据库的最高效方法,但在 WordPress 将 term_ids 支持添加到其查询中之前,这是我们能做的最好的方法!):
<?php
$term = get_term_by('id',$qv['term'],'business');
$qv['term'] = $term->slug;
就是这样!通过这两个功能,您可以获得所需的过滤。
但是等等,还有更多!:-)
我继续添加了一个 「企业」 列到您的列表中,因为,嗯,我知道这将是您的下一个问题。如果没有用于过滤内容的列,最终用户可能会感到非常困惑。(我自己也曾为此苦苦挣扎,而且我是编码员!)你当然已经可以看到 「企业」 上面前面的屏幕截图中的列。
步骤#3:这 manage_posts_columns
过滤钩。
要将列添加到帖子列表需要调用另外两 (2) 个挂钩。第一个是 manage_posts_columns
或帖子类型特定的版本 manage_listing_posts_columns
我打电话来代替。它接受一个参数(posts_columns
) 并被调用 /wp-admin/includes/template.php
(在 v3.0.1 中,该调用位于第 623 行):
<?php
add_action('manage_listing_posts_columns', 'add_businesses_column_to_listing_list');
function add_businesses_column_to_listing_list( $posts_columns ) {
if (!isset($posts_columns['author'])) {
$new_posts_columns = $posts_columns;
} else {
$new_posts_columns = array();
$index = 0;
foreach($posts_columns as $key => $posts_column) {
if ($key=='author')
$new_posts_columns['businesses'] = null;
$new_posts_columns[$key] = $posts_column;
}
}
$new_posts_columns['businesses'] = 'Businesses';
return $new_posts_columns;
}
你的 manage_posts_columns
钩子函数传递一个列数组,其中值是显示的列标题,键是内部列标识符。标准列标识符可以包括这些以及更多: 'cb'
, 'title
', 'author'
, 、``'日期'`等
'cb'
, , 是个 checkbox
列和两者 'title'
和 'date'
参考 post_title
和 post_date
来自 wp_posts
表,分别。 'author'
当然是 post_author
从作者姓名检索后的字段 wp_users
桌子。
(来源: mikeschinkel.com)
为了 manage_posts_columns
钩子我们只是想插入我们的列 businesses
进入 $posts_columns
之前的数组 'author'
, ,假设其他一些插件尚未删除 author
还没有从名单中出来!
$new_posts_columns['businesses'] = 'Businesses';
(笔记 正如我所写 add_businesses_column_to_listing_list()
我突然想到 PHP 必须 有更简单的方法以正确的顺序将值插入关联数组吗?!?或者至少 WordPress 核心中必须有一个函数来做到这一点?但由于谷歌让我失望,所以我选择了有效的方法。如果有人有任何建议的替代方案,我会提前倾听并表示感谢!)
这最终让我们...
步骤4:这 manage_posts_custom_column
动作挂钩
为了使我们的企业显示在列中,我们需要做的两 (2) 件事中的第二件事是使用以下命令实际输出每个关联企业的名称: manage_posts_custom_column
动作挂钩。该钩子接受两 (2) 个参数 (column_id
和 post_id
)并且也被称为 /wp-admin/includes/template.php
(在 v3.0.1 中,该调用位于第 1459 行。):
<?php
add_action('manage_posts_custom_column', 'show_businesses_column_for_listing_list',10,2);
function show_businesses_column_for_listing_list( $column_id,$post_id ) {
global $typenow;
if ($typenow=='listing') {
$taxonomy = 'business';
switch ($column_name) {
case 'businesses':
$businesses = get_the_terms($post_id,$taxonomy);
if (is_array($businesses)) {
foreach($businesses as $key => $business) {
$edit_link = get_term_link($business,$taxonomy);
$businesses[$key] = '<a href="'.$edit_link.'">' . $business->name . '</a>';
}
//echo implode("<br/>",$businesses);
echo implode(' | ',$businesses);
}
break;
}
}
}
每个帖子(/业务)行的每一列都会调用此挂钩。我们首先验证我们确实只与 listing
自定义帖子类型,然后我们使用 switch
测试的声明 column_id
. 。我选择了 switch
因为这个钩子通常用于为许多不同的列生成输出,特别是如果我们对许多不同的帖子类型使用一个函数,它可能看起来像这样:
<?php
add_action('manage_posts_custom_column', 'my_manage_posts_custom_column',10,2);
function my_manage_posts_custom_column( $column_id,$post_id ) {
global $typenow;
switch ("{$typenow}:{$column_id}") {
case 'listing:business':
echo '...whatever...';
break;
case 'listing:property':
echo '...whatever...';
break;
case 'agent:listing':
echo '...whatever...';
break;
}
}
仔细检查我们的用例,您会发现 get_the_terms()
函数仅返回该分类的术语列表(即此列表中的企业。)在这里获取 永久链接 该术语的前端网页通常列出与该术语相关的帖子,但当然可能会有所不同,具体取决于安装的主题和/或插件。
我们使用永久链接来超链接该术语只是因为我喜欢超链接事物。然后,我们将所有超链接术语(/企业)合并在一起,并用竖线('|
') 字符并输出到 PHP 缓冲区,PHP 缓冲区将其发送到用户的浏览器/HTTP 客户端:
<?php
$businesses = get_the_terms($post_id,$taxonomy);
if (is_array($businesses)) {
foreach($businesses as $key => $business) {
$edit_link = get_term_link($business,$taxonomy);
$businesses[$key] = '<a href="'.$edit_link.'">' . $business->name . '</a>';
}
//echo implode("<br/>",$businesses);
echo implode(' | ',$businesses);
}
现在 我们终于完成了。
概括
因此,总而言之,您需要使用以下四 (4) 个挂钩来获取自定义帖子列表页面中的过滤器和相关列(哦,它也适用于帖子和页面。)它们是:
- 步骤1:这
restrict_manage_posts
动作挂钩。 - 第2步:这
parse_query
过滤钩。 - 步骤#3:这
manage_posts_columns
过滤钩。 - 步骤4:这
manage_posts_custom_column
动作挂钩
代码在哪里下载
但如果我强迫你阅读以上所有内容,那么如果我还让你挖出代码只是为了能够尝试一下,那么我肯定不是一个很好的人!但与某些人所说的相反,我很好。所以你开始吧:
注@tarasm: :我包括了一个钩子 register_post_type()
和 register_taxonomy()
这样其他人就可以尝试这个而不必重新创建它们。在测试之前,您可能需要删除这两个函数调用。
结束
原始回复:
你好 @塔拉斯姆:
您在寻找吗 顶部有一个下拉 喜欢这个屏幕或者您正在寻找 每个帖子记录一个下拉列表 如果是这样,您期望后者如何工作?
(来源: mikeschinkel.com)
如果是前者,请看一下这个问题的答案 如何按自定义字段对 WordPress 自定义帖子类型的管理区域进行排序? 如果这是您所需要的,我可以提供与分类学相关的更多细节。
其他提示
只是想分享另一种实现。当我弄清楚这一点时,我没有Mike令人难以置信的教程,所以我的解决方案有些不同。具体来说,我要简化迈克的 步骤1 和 排除 第2步 - 其他步骤仍然适用。
在Mike的教程中,使用 wp_dropdown_categories()
为我们节省了一些手动列表构建,但需要一些复杂的条件查询修改(第2步)处理其对ID而不是slug的使用。更不用说修改该代码来处理其他方案的困难,例如多个分类滤波器。
另一种方法是简单不使用缺陷 wp_dropdown_categories()
完全,但要构建我们自己的下拉列表从头开始选择列表。这不是那么复杂,需要少于30行的代码,也不需要挂钩 parse_query
完全:
add_action( 'restrict_manage_posts', 'my_restrict_manage_posts' );
function my_restrict_manage_posts() {
// only display these taxonomy filters on desired custom post_type listings
global $typenow;
if ($typenow == 'photos' || $typenow == 'videos') {
// create an array of taxonomy slugs you want to filter by - if you want to retrieve all taxonomies, could use get_taxonomies() to build the list
$filters = array('plants', 'animals', 'insects');
foreach ($filters as $tax_slug) {
// retrieve the taxonomy object
$tax_obj = get_taxonomy($tax_slug);
$tax_name = $tax_obj->labels->name;
// retrieve array of term objects per taxonomy
$terms = get_terms($tax_slug);
// output html for taxonomy dropdown filter
echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
echo "<option value=''>Show All $tax_name</option>";
foreach ($terms as $term) {
// output each select option line, check against the last $_GET to show the current option selected
echo '<option value='. $term->slug, $_GET[$tax_slug] == $term->slug ? ' selected="selected"' : '','>' . $term->name .' (' . $term->count .')</option>';
}
echo "</select>";
}
}
}
通过简单地将所需的分类法插入 $filters
数组,您可以快速输出多个分类过滤器。它们看起来与Mike的屏幕截图完全相同。然后你可以跟随 步骤#3 和 #4.
这是一个版本,它会自动创建和应用所有分类法的过滤器,这些分类法适用于所有使用它们的自定义帖子类型。 (真是太好了)无论如何,我也对其进行了调整,以便与wp_dropdown_categories()和WordPress 3.1一起使用。我正在进行的项目称为TODO,您可以将功能重命名为对您有意义的事物,但这对所有事物都可以自动起作用。
function todo_restrict_manage_posts() {
global $typenow;
$args=array( 'public' => true, '_builtin' => false );
$post_types = get_post_types($args);
if ( in_array($typenow, $post_types) ) {
$filters = get_object_taxonomies($typenow);
foreach ($filters as $tax_slug) {
$tax_obj = get_taxonomy($tax_slug);
wp_dropdown_categories(array(
'show_option_all' => __('Show All '.$tax_obj->label ),
'taxonomy' => $tax_slug,
'name' => $tax_obj->name,
'orderby' => 'term_order',
'selected' => $_GET[$tax_obj->query_var],
'hierarchical' => $tax_obj->hierarchical,
'show_count' => false,
'hide_empty' => true
));
}
}
}
function todo_convert_restrict($query) {
global $pagenow;
global $typenow;
if ($pagenow=='edit.php') {
$filters = get_object_taxonomies($typenow);
foreach ($filters as $tax_slug) {
$var = &$query->query_vars[$tax_slug];
if ( isset($var) ) {
$term = get_term_by('id',$var,$tax_slug);
$var = $term->slug;
}
}
}
return $query;
}
add_action( 'restrict_manage_posts', 'todo_restrict_manage_posts' );
add_filter('parse_query','todo_convert_restrict');
请注意,我正在使用添加“ TERM_ORDER”作为订购项的插件,您必须更改该插件,或将该参数删除以退回默认值。
迟到的答案
编辑
我写了 Filterama, ,将以最简单的方式添加此功能的插件。
更新WordPress 3.5+
现在事情变得容易得多,这是 非常 简单解决方案作为插件或Mu-Plugin。
它使用尽可能少的资源,仅在所需的屏幕上加载,并为每个自定义分类法添加列 +过滤器。
add_action( 'plugins_loaded', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
class WCM_Admin_PT_List_Tax_Filter
{
private static $instance;
public $post_type;
public $taxonomies;
static function init()
{
null === self::$instance AND self::$instance = new self;
return self::$instance;
}
public function __construct()
{
add_action( 'load-edit.php', array( $this, 'setup' ) );
}
public function setup()
{
add_action( current_filter(), array( $this, 'setup_vars' ), 20 );
add_action( 'restrict_manage_posts', array( $this, 'get_select' ) );
add_filter( "manage_taxonomies_for_{$this->post_type}_columns", array( $this, 'add_columns' ) );
}
public function setup_vars()
{
$this->post_type = get_current_screen()->post_type;
$this->taxonomies = array_diff(
get_object_taxonomies( $this->post_type ),
get_taxonomies( array( 'show_admin_column' => 'false' ) )
);
}
public function add_columns( $taxonomies )
{
return array_merge( taxonomies, $this->taxonomies );
}
public function get_select()
{
$walker = new WCMF_walker;
foreach ( $this->taxonomies as $tax )
{
wp_dropdown_categories( array(
'taxonomy' => $tax,
'hide_if_empty' => true,
'show_option_all' => sprintf(
get_taxonomy( $tax )->labels->all_items
),
'hide_empty' => true,
'hierarchical' => is_taxonomy_hierarchical( $tax ),
'show_count' => true,
'orderby' => 'name',
'selected' => '0' !== get_query_var( $tax )
? get_query_var( $tax )
: false,
'name' => $tax,
'id' => $tax,
'walker' => $walker,
) );
}
}
}
然后,您只需要定制的步行者课。
class WCMF_walker extends Walker_CategoryDropdown
{
public $tree_type = 'category';
public $db_fields = array(
'parent' => 'parent',
'id' => 'term_id',
);
public $tax_name;
public function start_el( &$output, $term, $depth, $args, $id = 0 )
{
$pad = str_repeat( ' ', $depth * 3 );
$cat_name = apply_filters( 'list_cats', $term->name, $term );
$output .= sprintf(
'<option class="level-%s" value="%s" %s>%s%s</option>',
$depth,
$term->slug,
selected(
$args['selected'],
$term->slug,
false
),
$pad.$cat_name,
$args['show_count']
? " ({$term->count})"
: ''
);
}
}
我只是想快速记下。在较新版本的WP版本上,Admin上的帖子列表由WP_POSTS_LIST_TABL类处理。 apply_filters代码现在如下:
if ( 'page' == $post_type )
$posts_columns = apply_filters( 'manage_pages_columns', $posts_columns );
else
$posts_columns = apply_filters( 'manage_posts_columns', $posts_columns, $post_type );
$posts_columns = apply_filters( "manage_{$post_type}_posts_columns", $posts_columns );
因此,要添加新列add_filter钩子应该这样:
add_filter( 'manage_posts_columns', 'my_add_columns', 10, 2);
这里是一个示例:
function my_add_columns($posts_columns, $post_type)
{
if ('myposttype' == $post_type) {
$posts_columns = array(
"cb" => "<input type=\"checkbox\" />",
"title" => "Title",
"anothercolumn" => "Bacon",
"date" => __( 'Date' )
);
return $posts_columns;
}
}
现在,对于帖子行。这是处理列表上列数据的代码:
default:
?>
<td <?php echo $attributes ?>><?php
if ( is_post_type_hierarchical( $post->post_type ) )
do_action( 'manage_pages_custom_column', $column_name, $post->ID );
else
do_action( 'manage_posts_custom_column', $column_name, $post->ID );
do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID );
?></td>
<?php
为了检索我们的帖子数据,我们必须添加一个类似的操作钩子:
add_action( "manage_(here_goes_your_post_type)_posts_custom_column", "my_posttype_add_column", 10, 2);
示例(此示例使用分类法,但您可以查询任何其他内容):
function my_posttype_add_column($column_name, $post_id)
{
switch ($column_name) {
case 'anothercolumn':
$flavours = get_the_terms($post_id, 'flavour');
if (is_array($flavours)) {
foreach($flavours as $key => $flavour) {
$edit_link = get_term_link($flavour, 'flavour');
$flavours[$key] = '<a href="'.$edit_link.'">' . $flavour->name . '</a>';
}
echo implode(' | ',$flavours);
}
break;
default:
break;
}
}
在WP 3.2中工作!
custom_post_type: 图书custom_taxonomy: 类型
只有修改说: //在这里更改
function restrict_books_by_genre() {
global $typenow;
$post_type = 'books'; // change HERE
$taxonomy = 'genre'; // change HERE
if ($typenow == $post_type) {
$selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
$info_taxonomy = get_taxonomy($taxonomy);
wp_dropdown_categories(array(
'show_option_all' => __("Show All {$info_taxonomy->label}"),
'taxonomy' => $taxonomy,
'name' => $taxonomy,
'orderby' => 'name',
'selected' => $selected,
'show_count' => true,
'hide_empty' => true,
));
};
}
add_action('restrict_manage_posts', 'restrict_books_by_genre');
function convert_id_to_term_in_query($query) {
global $pagenow;
$post_type = 'books'; // change HERE
$taxonomy = 'genre'; // change HERE
$q_vars = &$query->query_vars;
if ($pagenow == 'edit.php' && isset($q_vars['post_type']) && $q_vars['post_type'] == $post_type && isset($q_vars[$taxonomy]) && is_numeric($q_vars[$taxonomy]) && $q_vars[$taxonomy] != 0) {
$term = get_term_by('id', $q_vars[$taxonomy], $taxonomy);
$q_vars[$taxonomy] = $term->slug;
}
}
add_filter('parse_query', 'convert_id_to_term_in_query');
这是一种使用drestrict_manage_posts操作进行操作的方法。它似乎对我来说很好,并补充了所有邮政类型和相关分类法的分类法过滤的能力。
// registers each of the taxonomy filter drop downs
function sunrise_fbt_add_taxonomy_filters() {
global $typenow; // the current post type
$taxonomies = get_taxonomies('','objects');
foreach($taxonomies as $taxName => $tax) {
if(in_array($typenow,$tax->object_type) && $taxName != 'category' && $taxName != 'tags') {
$terms = get_terms($taxName);
if(count($terms) > 0) {
//Check if hierarchical - if so build hierarchical drop-down
if($tax->hierarchical) {
$args = array(
'show_option_all' => 'All '.$tax->labels->name,
'show_option_none' => 'Select '.$tax->labels->name,
'show_count' => 1,
'hide_empty' => 0,
'echo' => 1,
'hierarchical' => 1,
'depth' => 3,
'name' => $tax->rewrite['slug'],
'id' => $tax->rewrite['slug'],
'class' => 'postform',
'depth' => 0,
'tab_index' => 0,
'taxonomy' => $taxName,
'hide_if_empty' => false);
$args['walker'] = new Walker_FilterByTaxonomy;
wp_dropdown_categories($args);
} else {
echo "<select name='".$tax->rewrite['slug']."' id='".$tax->rewrite['slug']."' class='postform'>";
echo "<option value=''>Show All ".$tax->labels->name."</option>";
foreach ($terms as $term) {
echo '<option value="' . $term->slug . '"', $_GET[$taxName] == $term->slug ? ' selected="selected"' : '','>' . $term->name .' (' . $term->count .')</option>';
}
echo "</select>";
}
}
}
}
}
add_action( 'restrict_manage_posts', 'sunrise_fbt_add_taxonomy_filters', 100 );
/**
* Create HTML dropdown list of Categories.
*
* @package WordPress
* @since 2.1.0
* @uses Walker
*/
class Walker_FilterByTaxonomy extends Walker {
var $tree_type = 'category';
var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
function start_el(&$output, $category, $depth, $args) {
$args['selected'] = get_query_var( $args['taxonomy'] );
$pad = str_repeat(' ', $depth * 3);
$cat_name = apply_filters('list_cats', $category->name, $category);
$output .= "\t<option class=\"level-$depth\" value=\"".$category->slug."\"";
if ( $category->slug == $args['selected'] )
$output .= ' selected="selected"';
$output .= '>';
$output .= $pad.$cat_name;
if ( $args['show_count'] )
$output .= ' ('. $category->count .')';
if ( $args['show_last_update'] ) {
$format = 'Y-m-d';
$output .= ' ' . gmdate($format, $category->last_update_timestamp);
}
$output .= "</option>\n";
}
}
一个注意事项 - 我尝试限制深度,因为我的某些层次分类法很大,但它不起作用 - 可能是WP_Dropdown_categories功能中的错误吗?
我猜这还不众所周知,但是从WordPress 3.5开始,您可以通过 'show_admin_column' => true
至 register_taxonomy
. 。这做2件事:
- 将分类列添加到管理邮政类型列表视图中
- 通过单击“分类法”列中的术语名称, 实际上,它会将列表过滤到该术语.
因此,与选择的功能几乎完全相同,但宽度仅是一行代码。
https://make.wordpress.org/core/2012/12/11/wordpress-3-5-5-5-5-ADMIN-COLUMNS-for-custom-taxonomies/
另外,正如您可以阅读的那样,还有一个针对手动添加分类列的新过滤器(如果您真的需要)。
按照@kevin的要求, @somatic答案的层次结构版本:
<?php
add_action( 'restrict_manage_posts', 'my_restrict_manage_posts' );
function my_restrict_manage_posts() {
// only display these taxonomy filters on desired custom post_type listings
global $typenow;
if ($typenow == 'photos' || $typenow == 'videos') {
// create an array of taxonomy slugs you want to filter by - if you want to retrieve all taxonomies, could use get_taxonomies() to build the list
$filters = array('plants', 'animals', 'insects');
foreach ($filters as $tax_slug) {
// retrieve the taxonomy object
$tax_obj = get_taxonomy($tax_slug);
$tax_name = $tax_obj->labels->name;
// output html for taxonomy dropdown filter
echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
echo "<option value=''>Show All $tax_name</option>";
generate_taxonomy_options($tax_slug,0,0);
echo "</select>";
}
}
}
function generate_taxonomy_options($tax_slug, $parent = '', $level = 0) {
$args = array('show_empty' => 1);
if(!is_null($parent)) {
$args = array('parent' => $parent);
}
$terms = get_terms($tax_slug,$args);
$tab='';
for($i=0;$i<$level;$i++){
$tab.='--';
}
foreach ($terms as $term) {
// output each select option line, check against the last $_GET to show the current option selected
echo '<option value='. $term->slug, $_GET[$tax_slug] == $term->slug ? ' selected="selected"' : '','>' .$tab. $term->name .' (' . $term->count .')</option>';
generate_taxonomy_options($tax_slug, $term->term_id, $level+1);
}
}
?>
我基本上删除了创建选项的代码,并将其放在其自己的功能中。函数“ generate_taxonomy_options”(除了拿出tax_slug)还采用父级和级别参数。该函数假设其为父0创建选项,该选项将选择所有根级项。在循环中,函数将递归地调用自身,将当前项作为父级,并将级别提高一个。它会自动将壁虱添加到侧面,因为您越深入树,瞧!
@Drew Gourley的WP 3.3.1答案的更新(并合并来自 http://wordpress.org/support/topic/wp_dropdown_categories-generation-generating-url-id-number-inmber-instead-slug?replies=6#post-2529115):
add_action('restrict_manage_posts', 'xyz_restrict_manage_posts');
function xyz_restrict_manage_posts() {
global $typenow;
$args = array('public'=>true, '_builtin'=>false);
$post_types = get_post_types($args);
if(in_array($typenow, $post_types)) {
$filters = get_object_taxonomies($typenow);
foreach ($filters as $tax_slug) {
$tax_obj = get_taxonomy($tax_slug);
$term = get_term_by('slug', $_GET[$tax_obj->query_var], $tax_slug);
wp_dropdown_categories(array(
'show_option_all' => __('Show All '.$tax_obj->label ),
'taxonomy' => $tax_slug,
'name' => $tax_obj->name,
'orderby' => 'term_order',
'selected' => $term->term_id,
'hierarchical' => $tax_obj->hierarchical,
'show_count' => false,
// 'hide_empty' => true,
'hide_empty' => false,
'walker' => new DropdownSlugWalker()
));
}
}
}
//Dropdown filter class. Used with wp_dropdown_categories() to cause the resulting dropdown to use term slugs instead of ids.
class DropdownSlugWalker extends Walker_CategoryDropdown {
function start_el(&$output, $category, $depth, $args) {
$pad = str_repeat(' ', $depth * 3);
$cat_name = apply_filters('list_cats', $category->name, $category);
$output .= "\t<option class=\"level-$depth\" value=\"".$category->slug."\"";
if($category->term_id == $args['selected'])
$output .= ' selected="selected"';
$output .= '>';
$output .= $pad.$cat_name;
$output .= "</option>\n";
}
}
对于一个新用户,我无法发布评论,但我可以发布答案...
从WordPress 3.1(RC 1)开始,Mike的答案(过去几个月来一直为我服务)不再对我有用;任何分类儿童的限制都会取得空洞的结果。我尝试了Somatic的更新,并且效果很好。更好的是,它可以与 多个分类查询 该版本已完成。
只是尝试了Mike和Somatic的这两个代码,并想知道如何从每种技术中获取一件事:
使用Mike的代码,它显示了与 分层 选项,这有很大帮助。但是,为了显示两个下拉列表,我必须复制 if ($typenow=='produtos') {...}
功能中的语句 restrict_listings_by_business()
还有 if ($pagenow=='edit.php' && ... }
在里面 convert_business_id_to_taxonomy_term_in_query($query)
现在提供大量代码的功能。
有了Somatic的代码,我只需要指定我想将下拉和BAM的分类法指定。 $filters = array('taxo1', 'taxo2');
问题:我可以得到躯体的方法,还可以 分层 选项?
无论如何,这本教程都非常感谢!
迈克(Mike)的教程很棒!如果我不得不自己弄清楚,我可能不会在我的媒体类别插件中添加此功能。
就是说,我认为使用 parse_query
然后获取该术语的查询。创建自己的自定义步行者课是清洁的。也许当他写自己的帖子时不可能 - 在我写这篇文章时3岁。
在Github上查看此大片段。就像魅力一样的工作,将下拉值中的ID更改为slugs,因此它只是本地工作的而无需修改查询即可。