既存の投稿のドロップダウンによってカスタムフィールド/メタが入力されますか?


11

(これまでに尋ねた私の最初のWPの質問!優しくしてください!)

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

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

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

  • 「promo-box」というカスタム投稿タイプを作成します。(通常の投稿のタグと同じくらい簡単にできますが。)
  • カスタムフィールドテンプレートなどのツールを使用して、ページエディターでドロップダウンを作成します。ドロップダウンオプションの値は、既存のすべてのプロモーションボックスの投稿のリストから動的に生成されます。(これは私がどうすればいいかわからない部分です。
  • ページテンプレートの結果のメタデータにアクセスします(ポスト番号は本当に必要なすべてであり、それから他のすべてを取得できます)。

ここでの他の質問への回答に基づいて、私はWPAlchemy MetaBox、Posts-2-Posts、およびSLT Custom Fieldsを最初に調べましたが、それぞれのドキュメントは私よりも少しマニアックであることを告白しているので、掘り下げていません深すぎます。

助言?上記のツールの1つは私にとって適切なソリューションであり、それを理解する必要がありますか?ここに何かが足りませんか?


うわー、すべてのサポートに感謝します!とにかくMikeSchinkelの時間と寛大さを切り下げていないことを願っていますが、「公式」の回答としてWPAlchemyの回答を選びました。私はまだPHP / Wordpressに慣れていないので、クラスやフック、静的関数などにはまだ慣れていません。いつかみんなと同じくらい上手になりたいです!
Nic Warmenhovenが2010

回答:


7

著者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ファイルです。この場合はドロップダウンです。ドロップダウンを生成するには、カスタムwpクエリを実行してすべてのカスタム投稿を取得します。タイプ。WPAlchemyには、フォーム要素の作成に役立つ特別なヘルパー関数があります。

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

WPAlchemyの主な目的は、スタイリング(ルックアンドフィール)からメタボックスのコンテンツ定義まで、開発者の手に渡る制御を維持することでした。

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


1
いい答えですが、追加のスタイルシート要求を特に投稿編集画面にフックすることをお勧めします。また、理想的に引っ掛けれるべきであること、metaboxの作成のために同じとすることができるdo_meta_boxesいくつかの条件ロジックでまたは代わりにadd_meta_boxes_{%TYPE%}...
t31os

14

へへ、あなたは初心者です!シュレッドに引き裂くつもりだ...!

j / k :) ここですべての初心者を温かく歓迎します。

したがって、これは私がこの要件を3回目に聞いたものであり、クライアントからは2回であり、あなた(およびあなたのクライアント)からは2回は聞いていません。

3つのドロップダウンを表示するWordPressカスタムメタボックス

私はあなたの分析が好きだったので、2つ目のポイントに対処するためにクラスをコード化することにしました。彼らのおかげで、この歌を頭からLittlePromoBoxes出せないので、私はそれを呼び出しました。基本的には、クラスを使用してカプセル化することで、作成する必要がある関数との名前の競合の可能性を回避しています。

このクラスは、テーマのfunctions.phpファイルまたは作成しているプラ​​グインの.PHPファイルに配置できます(ただし、心配しないでください。実際よりもはるかに複雑に見えます)。

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

  1. init登録するフックpromo-boxポストタイプを、

  2. add_meta_boxes_postあなたがmetaboxを定義することができるようにするフックと、

  3. wp_insert_post_data選択したプロモーションボックスをキャプチャしてデータベースに保存するためのフック。

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

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

このaction_add_meta_boxes_post()関数は、WordPressコア関数を使用してメタボックスを登録add_meta_box()し、それぞれに渡したものを渡した理由を説明するために、パラメーターにコメントを付けました。the_little_promo_boxes_metabox()もちろん、コールバック関数はクラスのもう1つの静的関数であり、メタボックスにコンテンツを実際に表示するものです。主に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])、実際に値の1つが以前に選択されていた場合は、選択された値()を設定する必要があります。

また、WordPressコア関数get_post_type_object()を使用して投稿タイプからラベルを取得する方法を示し、WordPressコア関数get_post_meta()を使用して、カスタムフィールドキー '_promo_boxes'を使用してプロモーションボックスIDの配列を取得します。次に保存します'_promo_boxes'ユーザーが投稿を編集しているときにWordPressが標準のカスタムフィールドUIから非表示になるようにするために、名前に前の下線を使用したことに注意してください)

コードを表示する前に説明する最後の関数filter_wp_insert_post_data()は、最初のパラメーター($data)で既存の投稿データを受け取り$_POST、2番目のパラメーター($postarr)としてWordPressのおかげで配列の内容を受け取ります。この関数内で、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ようなコードでテーマファイル内のこれらの関数の1つまたは両方を呼び出すことができます(このコードはループで記述されている可能性がありますが、ほとんどの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>';
?>

1
あなたはあなたの答え、コードを作成するために費やす努力、そして各ステップを説明する努力で私を驚かせ続けることは決してありません。
t31os 2010

1
@ t31os-ありがとう!答え始めると、自分を止めることはできません。強迫的/強迫的だと思います。しかし、少なくとも私はうまく利用しています!
MikeSchinkel

@toscho-ありがとう。はい、私がユーモアを加えることはめったにないので、私のことになると、抵抗することができません。:-)
MikeSchinkel 2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.