用现有帖子的选择列表填充元框,并将其分配给自定义帖子类型

时间:2013-02-08 作者:ragdollpanda

我的问题部分基于以下答案:https://wordpress.stackexchange.com/a/5778/27135

Mike的回答非常好,解决方案运行良好,直到我需要在自定义帖子类型中包含我的元框。我试图修改代码,直到成功,但没有成功。我也不需要每页超过一个选择元框(Mike的代码添加了3个)。

所以我从零开始,剥离一切。直到我需要将数据保存到表单中为止。

我现在的主要问题是,在发布/保存时,我不知道如何保存当前选定的选项标记。我不确定应该在选项标记中获取哪些数据,以及应该向update\\u post\\u meta()输入什么

我还尝试使用query\\u posts()创建自己的循环,希望能够更好地控制需要保存的数据。。但也没有运气。

下面的代码是Mike代码的一个非常简单的版本。我的目标是把它剥去,这样它就只包含了基本的东西,具有讽刺意味的是,我一定是把它剥去太多了,弄不清楚是什么。我想知道需要添加什么才能保存当前选择。:)

add_action( \'add_meta_boxes\', \'select_box_add_meta_box\' );
add_action( \'save_post\', \'select_box_save_postdata\' );

// Create the meta box
function select_box_add_meta_box() {
      add_meta_box(
          \'select_item\',
          \'Select Item\',
          \'select_box_content\',
          \'custom_post_type\'
      );
}

// Create the meta box content
function select_box_content() {
    $static_args = array(
        \'post_type\' => \'another_custom_post_type\', 
        \'show_option_none\' => \'Choose item\'
    );
    $selected_item = get_post_meta($post->ID,\'_selected_item\', true);
    for($i=0; $i<=2; $i++) {
        $incrementing_args = array(
            \'id\' => "selected_item_{$i}",
            \'name\' => \'selected_item[]\',
            \'selected\' => (empty($selected_item[$i]) ? 0 : $selected_item[$i]),
        );
    }   

    wp_dropdown_pages(array_merge($static_args,$incrementing_args));


}

// Save the selection
function select_box_save_postdata($data, $postarr) {    
    update_post_meta($postarr[\'ID\'], \'_selected_item\', $postarr[\'selected_item\']);
    return $data;
}

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

我相信这就是你一直在寻找的。

我转而使用类,因为您所使用的内容很容易与决定使用函数名的其他人的代码发生冲突select_box_add_meta_box(), select_box_content() 和/或select_box_save_postdata(), 这是相当可能的。类名WPSE_85107 只会与回答此问题的其他人发生冲突!当然,我建议您为实际插件选择一个更好的名称,但至少要选择一些与冲突不同的名称。

使用类还允许我们使用简短而清晰的方法名,这些方法名(通常)只能与钩子名匹配。这使得编写和理解代码变得更加容易add_action() 但您只需学习一次:

add_action( \'add_meta_boxes\', \'select_box_add_meta_box\' );
vs:

add_action( \'add_meta_boxes\', array( $this, \'add_meta_boxes\' ) );
你滥用了\'save_post\'; 它需要两个参数,这就是210 其中10 只是默认优先级,仅因为我们必须指定参数的数量才需要:

add_action( \'save_post\', array( $this, \'save_post\' ), 10, 2 );
正确的参数save_post() 这是:

function save_post( $post_id, $post )
与此相比:

function select_box_save_postdata($data, $postarr) 
也在save_post() 我测试了方法,以确保它是我们关心的帖子类型,并且确实存在$_POST[\'selected_post\'] 其中应包含所选的帖子ID。

我选择创建(伪)常量和实例变量,以便您更容易看到各种函数所需的参数,例如add_meta_box()wp_dropdown_pages(). 我没有添加评论,因为我想如果我添加了,你会发现它更复杂,因此像另一个例子一样势不可挡。

请注意wp_dropdown_pages() 需要\'hierarchical\' 帖子类型,这就是为什么我必须在这里对其进行黑客攻击才能将其列入列表$post_type==\'post\'. 我用来测试这个示例的测试站点只有\'post\'\'page\' 岗位类型;您应该能够使用$FOR_POST_TYPE$SELECT_POST_TYPE 获取所需的帖子类型。

我使用了翻译功能__() 如果您正在创建一个需要在其他语言中工作的插件,请使用标签。

我用过admin_init() 因此,其他代码仅在admin中运行,而不在前端运行。这没什么大不了的,但每一点都有帮助。

仅此而已。代码如下:

<?php
/**
 * Plugin Name: @WPSE 85107
 * Description: <a target="_blank" href="http://wordpress.stackexchange.com/q/85107/89">WPSE 85107</a>
 */

class WPSE_85107 {
  var $FOR_POST_TYPE = \'page\';
  var $SELECT_POST_TYPE = \'post\';
  var $SELECT_POST_LABEL = \'Post\';
  var $box_id;
  var $box_label;
  var $field_id;
  var $field_label;
  var $field_name;
  var $meta_key;
  function __construct() {
    add_action( \'admin_init\', array( $this, \'admin_init\' ) );
  }
  function admin_init() {
    add_action( \'add_meta_boxes\', array( $this, \'add_meta_boxes\' ) );
    add_action( \'save_post\', array( $this, \'save_post\' ), 10, 2 );
    $this->meta_key     = "_selected_{$this->SELECT_POST_TYPE}";
    $this->box_id       = "select-{$this->SELECT_POST_TYPE}-metabox";
    $this->field_id     = "selected-{$this->SELECT_POST_TYPE}";
    $this->field_name   = "selected_{$this->SELECT_POST_TYPE}";
    $this->box_label    = __( "Select {$this->SELECT_POST_LABEL}", \'wpse-85107\' );
    $this->field_label  = __( "Choose {$this->SELECT_POST_LABEL}", \'wpse-85107\' );
  }
  function add_meta_boxes() {
    add_meta_box(
      $this->box_id,
      $this->box_label,
      array( $this, \'select_box\' ),
      $this->FOR_POST_TYPE,
      \'side\'
    );
  }
  function select_box( $post ) {
    $selected_post_id = get_post_meta( $post->ID, $this->meta_key, true );
    global $wp_post_types;
    $save_hierarchical = $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical;
    $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical = true;
    wp_dropdown_pages( array(
      \'id\' => $this->field_id,
      \'name\' => $this->field_name,
      \'selected\' => empty( $selected_post_id ) ? 0 : $selected_post_id,
      \'post_type\' => $this->SELECT_POST_TYPE,
      \'show_option_none\' => $this->field_label,
    ));
    $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical = $save_hierarchical;
  }
  function save_post( $post_id, $post ) {
    if ( $post->post_type == $this->FOR_POST_TYPE && isset( $_POST[$this->field_name] ) ) {
      update_post_meta( $post_id, $this->meta_key, $_POST[$this->field_name] );
    }
  }
}
new WPSE_85107();
我知道你希望它简单易懂,但鉴于你所要求的功能,这几乎是你对插件的最低要求。少吃一点,你就会切掉肉而不是脂肪。

我没有做的是添加一些功能,我认为如果你正在构建一个插件供其他人使用,这些功能是必须的。但你可以了解这些功能here.

SO网友:jevets

这个save_post 操作将调用您的函数并向其发送$post\\u id,而不是$data和$postarr。

你的select_box_save_postdata 函数需要接受$post\\u id作为其唯一参数:

add_action( \'save_post\', \'select_box_save_postdata\' );

function select_box_save_postdata( $post_id ) {
    $selected_item = null;

    // your form data is in the $_POST array
    if ( isset( $_POST[\'selected_item\'] ) && $_POST[\'selected_item\'] ) {
        $selected_item = $_POST[\'selected_item\'];
    }

    // then use the $post_id to save your post meta
    update_post_meta( $post_id, \'_selected_item\', $selected_item );
}
请参见codex page for save_post 了解更多信息。

结束

相关推荐

从Metabox返回值的函数

我已经使用Meta Box插件为我的cpt books创建了两个自定义Metabox,我对如何输出值感到困惑。这些值需要在我的一个模板中的特定位置使用。我试过使用get_post_custom() 和get_post_meta() 但无法使其工作。这是我的metabox模板:add_action(\'admin_init\', \'rw_register_meta_boxes\'); function rw_register_meta_boxes() { $prefix