问题描述
(我的第一个 WP 问题曾经问过!温柔!)
我正在构建一个主要是页面 (即静态) 的网站,使用 WP 作为 CMS 。在几页的底部,将出现 1,2 或 3 个”promo boxes” – 基本上 button-images 链接到站点的其他部分。虽然在任何给定的页面上只能出现 3 个促销框,但可以选择 30 个不同的促销框。
当我的客户创建一个新页面时,我希望他能够从所有可能的促销框的下拉列表中选择促销框。
看来我应该这样工作:
-
创建名为”promo-box” 的自定义帖子类型。 (尽管它可以很容易地成为常规帖子的标签。)
-
使用类似 Custom Field Template 的工具在页面编辑器上创建一个下拉列表,其中从所有现有的 promo-box 帖子的列表中动态生成下拉选项的值。 (这是我不知道该怎么做的部分)
-
访问生成的元数据 (发布号真的是我需要的,然后我可以得到所有其他) 在页面模板上。
根据对其他问题的回应,我已经初步看过 WPAlchemy MetaBox,Post-2-Posts 和 SLT Custom Fields,但是我承认每个文档的文档比我都微乎其微,所以我还没有被挖掘出来太深了
建议吗?上面的工具之一是我正确的解决方案,我只需要弄清楚?我在这里遗漏了什么吗?
最佳解决方案
作为 WPAlchemy 的 author,我有点偏见,但您基本上有一个很好的工作模式概述遵循,根据你选择的路线。
但是,如果使用 WPAlchemy,您将基本上执行以下操作 (步骤#2):
// functions.php
include_once 'WPAlchemy/MetaBox.php';
if (is_admin())
{
// a custom style sheet if you want to do some fancy styling for your form
wp_enqueue_style('custom_meta_css', TEMPLATEPATH . '/custom/meta.css');
}
// define the meta box
$custom_metabox = new WPAlchemy_MetaBox(array
(
'id' => '_custom_meta',
'title' => 'My Custom Meta',
'template' => TEMPLATEPATH . '/custom/meta.php'
));
custom/meta.css
可以包含样式,您可以使用 custom/meta.php
样式,custom/meta.php
本质上是一个具有元数据框的 FORM 内容的 HTML 文件,在这种情况下,您的下拉菜单将生成您的下拉菜单,您将执行一个自定义 wp 查询来获取所有的自定义帖子类型。 WPAlchemy 有一些特殊的帮助函数来帮助创建表单元素。
另外还有一个 documentation 来帮助你在模板中工作。
WPAlchemy 的主要目标是将开发者掌握控制权,从造型 (外观+感觉) 到元框内容定义。
我和他人总是乐意帮助那些发表评论和提问的人。
次佳解决方案
呵呵,你是个新手!我们要撕裂你的碎片…!
j /k :) 我们热烈欢迎这里的所有新手,很高兴有你。
所以这是我第三次听到这个要求,两次来自客户,不再来自你 (和你的客户) 。这告诉我这是一个很常见的需要。
我喜欢你的分析,所以我决定编写一个类来解决你的第二点。我调用 LittlePromoBoxes
,因为我不能让 this song 出来,感谢 them 。基本上我使用类来封装,以避免与我需要编写的函数发生潜在的命名冲突。
您可以将此类放在主题的 functions.php
文件中,或者在您可能正在编写的插件的.PHP 文件中 (但不要担心,它看起来比它复杂得多) 。
第一个函数 on_load()
是一个静态函数,我在类声明的末尾调用初始化你需要的三 (3) 个钩子 (fyi 静态函数本质上是 functions related to the class,而不是实例):
-
init
挂钩注册promo-box
帖子类型, -
add_meta_boxes_post
钩子允许您定义 metabox,和 -
wp_insert_post_data
钩子允许您捕获所选的促销框并保存到数据库。
这些钩子中的每一个引用了类中的另一个静态函数 (这些是我通过创建类封装的函数) 。
我将跳过描述 action_init()
函数和 make_labels()
帮助函数,假设您知道如何根据您的问题注册一个帖子类型。
action_add_meta_boxes_post()
功能使用 WordPress 核心函数 add_meta_box()
注册 metabox,我已经评论过它的参数,以解释为什么我通过了我为每个通过了。回调函数 the_little_promo_boxes_metabox()
当然是该类的另一个静态函数,它实际上是在 metabox 中显示的内容。它主要使用 WordPress 核心函数 wp_dropdown_pages()
来显示一个促销框列表 (注意它将显示除了’page’ 之外的其他帖子类型,但只有在他们的帖子类型注册中被标记为'hierarchical'=>true
,为什么只有层次结构?因为这样写了,这就是为什么!:)
由于我们显示了三 (3) 个下拉列表,所以我们需要在 HTML("promo_box_{$i}"
) 中给出每个唯一的 ID,但是使用方括号 ('promo_boxes[]'
) 赋予相同的名称,以便 PHP 将它们收集到 $_POST
变量中的数组 (WordPress 访问对我们来说,你会看到如何在一分钟内) 。当然,我们需要设置选择的值 ((empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])
),如果其中一个值以前被选中。
我还使用 WordPress 核心函数 get_post_type_object()
来显示如何从帖子类型获取标签,并且还使用 WordPress 核心函数 get_post_meta()
从使用自定义字段键’_promo_boxes’ 来检索一个促销框 ID 数组,我会显示你有保存下一个 (注意我使用名称'_promo_boxes'
中的一个前面的下划线,导致 WordPress 在用户编辑帖子时从标准自定义字段 UI 隐藏) 。
在您看到代码之前,描述的最后一个功能是 filter_wp_insert_post_data()
,它接收第一个参数 ($data
) 中的现有帖子数据以及 $_POST
数组的内容,这得益于 WordPress 作为第二个参数 ($postarr
) 。在这个功能里面,我们称之为 WordPress 核心函数 update_post_meta()
,并提取促销框数组 ($postarr['promo_boxes']
),以保存 $_POST
数组 (即 $postarr['ID']
) 指定的帖子'_promo_boxes'
的自定义字段值。
也就是说,这是 LittlePromoBoxes
类的代码:
class LittlePromoBoxes {
static function on_load() {
add_action('init',array(__CLASS__,'action_init'));
add_action('add_meta_boxes_post',array(__CLASS__,'action_add_meta_boxes_post'));
add_filter('wp_insert_post_data',array(__CLASS__,'filter_wp_insert_post_data'),10,2);
}
static function action_init() {
register_post_type('promo-box',array(
'labels' => self::make_labels('Promo Box','Promo Boxes'),
'public_queryable'=> false,
'hierarchical' => true, // IMPORTANT!!! wp_dropdown_pages() requires 'hierarchical'=>true
'show_ui' => true,
'query_var' => false,
'supports' => array('title','editor','thumbnail','custom-fields'),
'show_in_nav_menus'=>true,
'exclude_from_search'=>true,
));
}
static function make_labels($singular,$plural=false,$args=array()) {
if ($plural===false)
$plural = $singular . 's';
elseif ($plural===true)
$plural = $singular;
$defaults = array(
'name' =>_x($plural,'post type general name'),
'singular_name' =>_x($singular,'post type singular name'),
'add_new' =>_x('Add New',$singular),
'add_new_item' =>__("Add New $singular"),
'edit_item' =>__("Edit $singular"),
'new_item' =>__("New $singular"),
'view_item' =>__("View $singular"),
'search_items' =>__("Search $plural"),
'not_found' =>__("No $plural Found"),
'not_found_in_trash'=>__("No $plural Found in Trash"),
'parent_item_colon' =>'',
);
return wp_parse_args($args,$defaults);
}
static function action_add_meta_boxes_post($post) {
add_meta_box(
'little-promo-boxes', // Metabox Name, used as the "id" for a wrapping div
'Little Promo Boxes', // Metabox Title, visible to the user
array(__CLASS__,'the_little_promo_boxes_metabox'), // Callback function
'post', // Add to the Edit screen for Post Types of 'post'
'side', // Show it in the sidebar (if center then it would be 'normal'
'low' // Show it below metaboxes that specify 'high'
);
}
static function the_little_promo_boxes_metabox($post) {
$pto = get_post_type_object('promo-box');
$default_options = array(
'post_type' => 'promo-box',
'show_option_none' => "Select a {$pto->labels->singular_name}",
);
$promo_boxes = get_post_meta($post->ID,'_promo_boxes',true);
for($i=0; $i<=2; $i++) {
wp_dropdown_pages(array_merge($default_options,array(
'id' => "promo_box_{$i}",
'name' => 'promo_boxes[]',
'selected' => (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i]),
)));
}
}
static function filter_wp_insert_post_data($data, $postarr) {
update_post_meta($postarr['ID'],'_promo_boxes',$postarr['promo_boxes']);
return $data;
}
static function get_promo_boxes($post=false) {
static $promo_boxes=array();
if (!$post)
$post = $GLOBALS['post'];
if (!isset($promo_boxes[$post->ID])) {
$promo_boxes[$post->ID] = get_post_meta($post->ID,'_promo_boxes',true);
$index = 0;
foreach($promo_boxes[$post->ID] as $promo_box_id) {
$promo_boxes[$post->ID][$index++] = (is_numeric($promo_box_id) ? get_post($promo_box_id) : false);
}
}
return $promo_boxes[$post->ID];
}
static function get_promo_box($number,$post=false) {
$promo_boxes = self::get_promo_boxes($post);
return $promo_boxes[$number-1];
}
}
LittlePromoBoxes::on_load();
还没有提到两个 (2) 静态功能:get_promo_boxes()
和 get_promo_box()
; 这些是帮助函数,帮助您通过其序号查找 post_type='promo-box'
的帖子。但是要让他们更多的 WordPress 像这里是两个包装函数添加到您的主题的 functions.php
文件 (注意,你可以传递一个参数,但你不必,除非你使用不同的帖子,一个在 The Loop) :
function get_little_promo_boxes($post=false) {
return LittlePromoBoxes::get_promo_boxes($post);
}
function get_little_promo_box($number,$post=false) {
return LittlePromoBoxes::get_promo_box($number,$post);
}
现在您可以在 single.php
主题文件中调用这些函数中的一个或两个,其代码可能类似于此 (此代码可能已经被写入循环中,但大多数 WordPress 主体似乎喜欢重复代码,以便他们可以读取它而不是消除冗余,所以,当在罗马…):
<?php
$promo_boxes = get_little_promo_boxes();
if (isset($promo_boxes[1]))
echo '<div id="promo-box1" class="promo-box">' . get_the_title($promo_boxes[1]->ID) . '</div>';
if (isset($promo_boxes[2]))
echo '<div id="promo-box2" class="promo-box">' . get_the_title($promo_boxes[2]->ID) . '</div>';
if (isset($promo_boxes[3]))
echo '<div id="promo-box3" class="promo-box">' . get_the_title($promo_boxes[3]->ID) . '</div>';
?>
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。