web-dev-qa-db-ja.com

既存の投稿のドロップダウンによって作成されたカスタムフィールド/メタデータ

(私の最初のWP質問は今までにありませんでした。優しくしてください!)

CMSとしてWPを使用し、主にページ(つまり静的)であるサイトを構築しています。いくつかのページの下部には、1、2、または3つの「プロモボックス」が表示されます - 基本的にはサイトの他の部分にリンクしているボタン画像です。どのページにも3つまでのプロモーションボックスしか表示されませんが、選択できるものは30種類ほどあります。

私のクライアントが新しいページを作成するとき、私は彼がすべての可能なプロモーションボックスのドロップダウンリストのようなものからプロモーションボックスを選択できるようにしたいです。

私にはこれは次のように機能するはずです。

  • "promo-box"という名前のカスタム投稿タイプを作成します。 (ただし、通常の投稿のタグにするのも簡単です。)
  • カスタムフィールドテンプレート のようなツールを使用して、ページエディタにドロップダウンを作成します。ドロップダウンオプションの値は、既存のすべてのプロモーションボックスの投稿のリストから動的に生成されます。 (これは私がやり方がわからない部分です。
  • ページテンプレートで、結果のメタデータにアクセスします(投稿番号が実際に必要なすべてのもので、それ以外のものはすべて入手できます)。

ここでの他の質問への回答に基づいて、私はWPAlchemy MetaBox、Posts-2-Posts、およびSLT Custom Fieldsを最初に調べましたが、それぞれについてのドキュメントは私のものよりも少しオシャクですので、私は好きではありません深すぎる。

助言?上記のツールのうちの1つは私にとって正しいソリューションです、そして私はそれを理解しなければなりませんか?私はここに何かが足りないのですか?

11
Nic Warmenhoven

作者 of 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は基本的にはメタボックスのFORMコンテンツを含むHTMLファイルです。この場合はドロップダウンです。カスタム投稿タイプWPAlchemyには、フォーム要素を作成する際に役立つ特別なヘルパー関数がいくつかあります。

テンプレートで作業するときに役立つ追加の ドキュメント があります。

WPAlchemyの主な目的は、スタイリング(外観と感触)からメタボックスのコンテンツ定義まで、開発者が制御できるようにすることでした。

そして、私自身や他の人たちは、コメントしたり質問をしたりする人々を常に喜んで助けています。

7
farinspace

Hehe、あなたは初心者です!切り裂きます...!

j/k:)ここにいるすべての初心者を歓迎します。

したがって、この要件を聞いたのはクライアントから2回であり、お客様(およびクライアント)からではなく、これが3回目です。これは、かなり一般的なニーズであることを示しています。

WordPress Custom Metabox showing Three (3) Dropdowns

私はあなたの分析が好きだったので、2番目のポイントに対処するためにクラスをコーディングすることにしました。 them のおかげで この曲 を頭から出すことができないので、LittlePromoBoxesと呼びました。基本的には、クラスを使用してカプセル化し、そうしないと、記述する必要がある関数との潜在的な名前の競合を回避します。

このクラスは、テーマのfunctions.phpファイルまたは記述しているプラ​​グインの.PHPファイルに配置できます(ただし、心配する必要はありません。実際よりもずっと複雑に見えます。)

最初の関数on_load()は、必要な3つのフックを初期化するためにクラス宣言の最後に呼び出す静的関数です(fyi静的関数は基本的に 関数関連インスタンス)ではなく、クラス に対して:

  1. promo-box投稿タイプを登録するinitフック、

  2. add_meta_boxes_postフックにより、メタボックスを定義できます。

  3. wp_insert_post_dataフックを使用すると、選択したプロモーションボックスをキャプチャしてデータベースに保存できます。

これらの各フックは、クラスの別の静的関数を参照します(これらは、クラスを作成することでカプセル化した関数でした。)

あなたが質問に基づいて投稿タイプを登録する方法を知っていると仮定して、action_init()関数と私のmake_labels()ヘルパー関数の説明をスキップします。

action_add_meta_boxes_post()関数は、WordPressコア関数add_meta_box()を使用してメタボックスを登録し、それぞれに渡したものを渡した理由を説明するパラメーターをコメントしました。コールバック関数the_little_promo_boxes_metabox()はもちろんクラスの別の静的関数であり、メタボックス内のコンテンツを実際に表示するものです。主にWordPressコア関数wp_dropdown_pages()を使用してプロモーションボックスのリストを表示します(「ページ」以外の投稿タイプが表示されることに注意してください。投稿タイプの登録で'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)で既存の投稿データを受け取り、2番目のパラメーターとしてWordPressのおかげで$_POST配列の内容を受け取ります( $postarr)。この関数内でWordPressコア関数update_post_meta()を呼び出し、プロモーションボックス配列($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..3で取得するのに役立つヘルパー関数です。しかし、それらをより多くするためにWordPressのように、テーマのfunctions.phpファイルに追加する2つのラッパー関数(パラメーターとして投稿を渡すことができますが、 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>';
?>
14
MikeSchinkel