Mevcut yayınların açılır listesiyle doldurulmuş özel alan / meta?


11

(İlk WP sorumu sordu! Nazik ol!)

Ben WMS CMS kullanarak çoğunlukla sayfaları (yani, statik) olan bir site inşa ediyorum. Sayfaların birkaçının altında 1, 2 veya 3 "promosyon kutusu" görünecektir - temel olarak sitenin diğer bölümlerine bağlantı veren düğme resimleri. Herhangi bir sayfada en fazla 3 promosyon kutusu görünmesine rağmen, aralarından seçim yapabileceğiniz ~ 30 farklı reklam kutusu olacaktır.

Müşterim yeni bir sayfa oluşturduğunda, tüm olası promosyon kutularının açılır listesi gibi bir şeyden promosyon kutuları seçebilmesini istiyorum.

Bana öyle geliyor ki böyle çalışmalı:

  • "Tanıtım kutusu" adı verilen özel bir yayın türü oluşturun. (Yine de normal gönderiler için kolayca bir etiket olabilir.)
  • Sayfa düzenleyicide bir açılır liste oluşturmak için Özel Alan Şablonu gibi bir araç kullanın ; burada açılır seçeneklerin değerleri, mevcut tüm promosyon kutusu gönderileri listesinden dinamik olarak oluşturulur. ( Bu nasıl yapılacağını bilmediğim kısım. )
  • Sonuçta elde edilen meta verilere erişin (sayfa numarası gerçekten ihtiyacım olan tek şey, o zaman her şeyi alabilirim).

Buradaki diğer soruların yanıtlarına dayanarak, WPAlchemy MetaBox, Gönderiler-2-Gönderiler ve SLT Özel Alanlarına ilk bakışları aldım, ancak her birinin belgelerinin benden biraz geekier olduğunu itiraf ediyorum, bu yüzden delirdim çok derinden.

Tavsiye? Yukarıdaki araçlardan biri benim için doğru çözüm mü? Burada bir şey mi eksik?


Vay canına, tüm destek için teşekkürler! Umarım MikeSchinkel'in zamanını ve cömertliğini devalüe etmiyorum, ama WPAlchemy cevabını "resmi" cevap olarak seçtim. Hala sınıflar ve kancalar ve statik fonksiyonlar ve benzeri ile süper rahat değilim PHP / Wordpress için yeterince yeniyim. Bir gün hepiniz kadar yetkin olmayı umuyorum!
Nic Warmenhoven

Yanıtlar:


7

Gibi yazar ve WPAlchemy , biraz önyargı değilim, ama aslında iyi bir çalışma modelini tercih Hiç ne rota bağlı takip etmek özetlenen var.

Ancak, WPAlchemy kullanıyorsanız, temelde aşağıdakine benzer bir şey yaparsınız (adım # 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.cssformunuzu biçimlendirebileceğiniz stiller içerebilir ve custom/meta.phptemelde meta kutusunun FORM içeriğine sahip bir HTML dosyasıdır, bu durumda açılır listeniz, açılır menünüzü oluşturmak için tüm özel postanızı almak için özel bir wp sorgusu yaparsınız türleri. WPAlchemy'nin form öğelerinizi oluşturmanıza yardımcı olacak bazı özel yardımcı işlevleri vardır.

Şablonda çalışırken size yardımcı olacak ek belgeler vardır .

WPAlchemy'nin temel amacı, stilden (görünüm + his) meta kutu içerik tanımlamasına kadar geliştiricinin kontrolünü elinde tutmaktı.

Ve ben ve diğerleri her zaman yorum yapan ve soru soranlara yardım etmeye istekli.


1
Güzel cevap, ama ben ekstra stil sayfası isteği özellikle yazı editörü ekranına kanca öneririz. Aynı şey metabox oluşturma için de söylenebilir, ideal do_meta_boxesolarak bazı koşullu mantık veya alternatif olarak üzerine add_meta_boxes_{%TYPE%}
kanca

14

Hehe, sen bir acemisin! Seni parçalara ayıracağız ...!

j / k :) Biz burada tüm yeni başlayanlar sıcak bir karşılama sunuyoruz, mutluyuz.

Bu, bu gerekliliği duyduğum 3. kez, müşterilerden iki kez ve sizden (ve müşterinizden değil). Bu bana oldukça yaygın bir ihtiyaç olduğunu söylüyor.

Üç (3) Açılır menü gösteren WordPress Özel Meta Kutusu

Analizinizi beğendim, bu yüzden 2. noktanıza hitap etmek için bir sınıfı kodlamaya karar verdim. Aradım LittlePromoBoxesçünkü onlar sayesinde bu şarkıyı asla aklımdan çıkaramıyorum . Temelde yazmam gereken işlevlerle olası adlandırma çakışmalarını önlemek için sınıfı kapsüllemek için kullanıyorum.

Bu sınıfı temanızın functions.phpdosyasına veya yazdığınız bir eklentinin bir .PHP dosyasına koyabilirsiniz (ancak endişelenmeyin, olduğundan çok daha karmaşık görünüyor).

İlk işlev on_load(), ihtiyacınız olan üç (3) kancayı başlatmak için sınıf bildiriminin sonunda çağırdığım statik bir işlevdir (fyi statik işlevleri temelde sınıfla ilgili işlevlerdir , örneğin değil) :

  1. initKanca kayıt promo-boxsonrası türünü,

  2. add_meta_boxes_postKanca Eğer METABOX tanımlamak için olanak tanıyacak

  3. wp_insert_post_dataKanca, seçilen promo kutuları yakalamak ve veritabanına kaydetmek için izin vermek.

Bu kancaların her biri sınıftaki başka bir statik fonksiyona atıfta bulunur (bunlar sınıfı oluşturarak kapsüllediğim fonksiyonlardı.)

Soruyu temel alarak bir yazı türünün nasıl kaydedileceğini bildiğinizi varsayarak action_init()işlevi ve make_labels()yardımcı işlevimi açıklamayı atlayacağım .

action_add_meta_boxes_post()Fonksiyon WordPress çekirdek işlevini kullanarak METABOX kaydeder add_meta_box()ve ben her biri için geçti Ne geçti neden açıklamak için 's parametreleri yorumladı ettik. Geri arama işlevi the_little_promo_boxes_metabox(), elbette, sınıfın başka bir statik işlevidir ve gerçekte içeriği meta kutuda görüntüler. Öncelikle wp_dropdown_pages()promosyon kutularının bir listesini görüntülemek için WordPress çekirdek işlevini kullanır ('sayfa' dışında başka yazı türlerini de göstereceğini unutmayın, ancak yalnızca 'hierarchical'=>trueyazı tipi kayıtlarında oldukları işaretlenirse . Neden sadece hiyerarşik? yazdı, bu yüzden! :)

Üç (3) açılır menü gösterdiğimizden, her birine HTML ( "promo_box_{$i}") içinde benzersiz bir kimlik vermeliyiz, ancak köşeli parantez ( 'promo_boxes[]') ile aynı adı vermeliyiz, böylece PHP bunları $_POSTdeğişken içindeki bir dizide toplayacaktır (WordPress bizim için erişir; nasıl olduğunu bir dakika içinde göreceksiniz) . Ve elbette (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])değerlerden biri daha önce seçilmişse , seçilen değeri ( ) ayarlamamız gerekir .

Ayrıca get_post_type_object(), bir yazı türünden etiketlerin nasıl alınacağını göstermek için WordPress çekirdek işlevini kullandım ve ayrıca get_post_meta()sahip olduğunuzu göstereceğim '_promo_boxes' özel alan anahtarını kullanarak bir dizi promosyon kutusu kimliği almak için WordPress çekirdek işlevini kullandım. sonraki kaydetmek için (not '_promo_boxes'WordPress kullanıcı yayın düzenlerken standart özel alan UI gizlemek neden adında önceki bir alt çizgi kullandım .) .

Kodu görmeden önce açıklanacak son işlev , ikinci parametre ( ) olarak WordPress sayesinde filter_wp_insert_post_data()ilk parametre ( $data) ve $_POSTdizinin içeriğini varolan posta verilerini alan işlevdir $postarr. Bu işlevin içinde WordPress çekirdek işlevini çağırırız ve update_post_meta()dizi tarafından belirtilen gönderinin $postarr['promo_boxes']anahtarının özel alan değerine kaydetmek için promosyon kutuları dizisini ( ) ayıklarız (yani ).'_promo_boxes'$_POST$postarr['ID']

Bununla birlikte, LittlePromoBoxessınıfın kodu :

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();

Hala belirtilmeyen iki (2) statik işlev vardır: get_promo_boxes() ve get_promo_box(); bunlar, post_type='promo-box'sıra sayılarıyla postaları almanıza yardımcı olacak yardımcı işlevlerdir 1..3. Ancak onları daha fazla WordPress yapmak için, temanızın functions.phpdosyasına eklemek için iki sarıcı işlevi vardır (bir gönderiyi parametre olarak iletebileceğinizi unutmayın, ancak The Loop'takinden farklı bir gönderi kullanmadığınız sürece bunu yapmanız gerekmez ) :

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);
}

Artık bu işlevlerden birini veya her ikisini single.php tema dosyanızdaki şöyle görünebilecek bir kodla (bu kod bir döngüde yazılmış olabilir, ancak çoğu WordPress teması, yedeklemeyi ortadan kaldırmak yerine okuyabilmeleri için kodu çoğaltmak ister. Yani, Roma'dayken ...):

<?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
Cevaplarınızla, kodu oluşturmak ve her adımı açıklamak için harcadığınız çaba ile beni şaşırtmaktan asla vazgeçmeyeceksiniz .. harika! .. (küçük kutulardan bahsetmek de en sevdiğim TV dizilerinden birini düşünmemi sağlıyor) ..
t31os

1
@ t31os - Teşekkürler! Cevaplamaya başladığımda kendimi durduramıyorum. Obsesif / kompulsif sanırım. Ama en azından iyi kullanıyorum!
MikeSchinkel

@toscho - Teşekkürler. Evet, o kadar nadiren mizah ekliyorum ki bana gelince dayanamıyorum. :-)
MikeSchinkel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.