自定义域/元由现有帖子的下拉列表填充?

时间:2010-12-22 作者:Nic Warmenhoven

(我第一次问WP问题!要温柔!)

我正在建立一个网站,主要是网页(即静态),使用WP作为CMS。在几个页面的底部,会出现1、2或3个“促销框”——基本上是链接到网站其他部分的按钮图像。虽然任何给定页面上最多只会出现3个促销框,但会有大约30个不同的促销框可供选择。

当我的客户创建新页面时,我希望他能够从所有可能的促销框的下拉列表中选择促销框。

在我看来,这应该是这样的:

创建一个名为“promo box”的自定义帖子类型。(尽管它可以很容易地成为常规帖子的标签。)Custom Field Template 要在页面编辑器上创建下拉列表,下拉选项的值将从所有现有促销框帖子的列表中动态生成。(这是我不知道该怎么做的部分。

  • 访问页面模板上的结果元数据(我只需要post number,然后我就可以获得其他所有内容)
  • 根据对这里其他问题的回答,我初步查看了WPAlchemy MetaBox、Posts-2-Posts和SLT自定义字段,但我承认每个字段的文档都比我略显古怪,所以我没有深入研究。

    劝告上述工具之一对我来说是正确的解决方案吗?我只需要找出它?我错过什么了吗?

    2 个回复
    最合适的回答,由SO网友:farinspace 整理而成

    作为author 属于WPAlchemy, 我有点偏袒你,但根据你选择的路线,你基本上有一个好的工作模式可以遵循。

    但是,如果使用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 本质上是一个HTML文件,其中包含元框的表单内容,在本例中是您的下拉列表,要生成下拉列表,您需要执行自定义wp查询以获取所有自定义帖子类型。WPAlchemy有一些特殊的帮助函数来帮助创建表单元素。

    还有其他documentation 在模板中工作时提供帮助。

    WPAlchemy的主要目标是将控制权掌握在开发人员手中,从样式(外观+感觉)到元框内容定义。

    我和其他人总是愿意帮助那些评论和提问的人。

    SO网友:MikeSchinkel

    呵呵,你是个菜鸟!我们要把你撕成碎片

    j/k :) 我们热烈欢迎所有的新手来到这里,很高兴有你。

    这是我第三次听到这个要求,两次是从客户那里听到的,而不是从你(和你的客户)那里听到的这告诉我这是一个相当普遍的需求。

    WordPress Custom Metabox showing Three (3) Dropdowns

    我喜欢你的分析,所以我决定编写一个类来解决你的第二点。我叫它LittlePromoBoxes 因为我永远无法this song 我想不出来了,多亏了them. 基本上,我使用该类进行封装,以避免与我需要编写的函数发生潜在的命名冲突。

    你可以把这个类放在你的主题中functions.php 文件或中的。您可能正在编写的插件的PHP文件(但别担心,它看起来要复杂得多。)

    第一个函数on_load() 是一个静态函数,我在类声明末尾调用它来初始化您需要的三(3)个挂钩(仅供参考,静态函数基本上是functions related to the class, 不是实例):

    init 钩子以注册promo-box 岗位类型,

    add_meta_boxes_post 钩子以允许您定义元框,以及

    wp_insert_post_data 钩子以允许您捕获选定的促销框并保存到数据库。

    这些钩子中的每一个都引用类中的另一个静态函数(这些是我通过创建类封装的函数)

    我将跳过描述action_init() 功能和我的make_labels() 助手函数,假设您知道如何根据您的问题注册帖子类型。

    这个action_add_meta_boxes_post() 函数使用WordPress核心函数注册metaboxadd_meta_box() 我已经对它的参数进行了注释,以解释为什么我传递了我为每个参数传递的内容。回调函数the_little_promo_boxes_metabox() 当然是类的另一个静态函数,它实际上是在元数据库中显示内容的函数。它主要使用WordPress核心功能wp_dropdown_pages() 显示促销框列表(请注意,它将显示除“页面”之外的其他帖子类型,但仅当它们标记为\'hierarchical\'=>true 在他们的岗位类型注册。为什么只有层次结构?因为他们就是这样写的,这就是为什么!:)

    由于我们显示了三(3)个下拉列表,我们需要在HTML中为每个下拉列表指定一个唯一的ID("promo_box_{$i}") 但名称相同,带方括号(\'promo_boxes[]\') 以便PHP将它们收集到内部的数组中$_POST 变量(WordPress为我们访问该变量;您将在一分钟内看到它是如何访问的)。当然,我们需要设置所选的值((empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])) 如果之前确实选择了其中一个值。

    我还使用了WordPress的核心功能get_post_type_object() 演示如何从帖子类型中获取标签,以及如何使用WordPress核心函数get_post_meta() 要使用自定义字段键“\\u promo\\u box”检索促销框ID数组,我将显示您必须在下一步保存它(注意,我在名称中使用了前面的下划线\'_promo_boxes\' 这会导致WordPress在用户编辑帖子时从标准自定义字段UI中隐藏。)。

    在看到代码之前要描述的最后一个函数是filter_wp_insert_post_data() 它接收第一个参数中的现有post数据($data) 以及$_POST 数组,因为WordPress是第二个参数($postarr). 在这个函数中,我们称之为WordPress核心函数update_post_meta() 并提取promo Box数组($postarr[\'promo_boxes\']) 保存到键的自定义字段值\'_promo_boxes\' 对于$_POST 阵列(即。$postarr[\'ID\']).

    也就是说,下面是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\' 按其序号1。。但是为了让它们更像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>\';
    ?>
    

    结束

    相关推荐

    使用自定义类别Metabox在管理中未保存的页面类别?

    我对此不知所措。您是否看到以下特定于noindex、nofollow复选框的代码有任何错误?元框可以很好地绘制到屏幕上,但值不会粘住。自定义页面标题和自定义摘录的代码工作正常。// =================== // = POST OPTION BOX = // =================== add_action(\'admin_menu\', \'my_post_options_box\'); function my_post_op