기존 게시물을 드롭 다운하여 채워진 맞춤 입력란 / 메타?


11

(내 첫 번째 WP 질문은 이제까지 물었다! 부드럽게!)

WP를 CMS로 사용하여 주로 페이지 (정적) 인 사이트를 만들고 있습니다. 여러 페이지의 맨 아래에는 기본적으로 사이트의 다른 부분에 연결되는 단추 이미지 인 1, 2 또는 3 개의 "프로모 상자"가 나타납니다. 특정 페이지에 최대 3 개의 프로모션 상자 만 표시되지만 선택할 수있는 항목은 ~ 30 가지입니다.

고객이 새 페이지를 만들 때 가능한 모든 프로모션 상자의 드롭 다운 목록에서 프로모션 상자를 선택할 수 있기를 바랍니다.

나에게 이것은 다음과 같이 작동해야합니다 :

  • "프로모 박스"라는 맞춤 게시물 유형을 만듭니다. (일반 게시물에 대한 태그 일 수는 있지만)
  • 사용자 정의 필드 템플릿 과 같은 도구를 사용 하여 페이지 편집기에서 드롭 다운 옵션을 작성하십시오. 여기서 드롭 다운 옵션의 값은 기존의 모든 프로모션 상자 게시물 목록에서 동적으로 생성됩니다. ( 이것은 내가 어떻게 해야할지 모르겠습니다. )
  • 페이지 템플릿에서 결과 메타 데이터 (게시물 번호가 실제로 필요한 모든 것 외에 다른 모든 것을 얻을 수 있음)에 액세스하십시오.

여기에 다른 질문에 대한 답변을 바탕으로 WPAlchemy MetaBox, Posts-2-Posts 및 SLT Custom Fields를 처음 살펴 보았지만 각 문서에 대한 문서가 나보다 약간 더 괴롭다는 것을 고백합니다. 너무 깊이.

조언? 위의 도구 중 하나가 나에게 적합한 솔루션입니까? 그냥 알아 내야합니까? 여기에 뭔가 빠졌습니까?


와, 모든 지원 감사합니다! 어쨌든 MikeSchinkel의 시간과 관대함을 평가하지 않기를 희망하지만 WPAlchemy 답변을 "공식적인"답변으로 선택했습니다. 나는 여전히 PHP / Wordpress에 익숙하지 않아서 클래스와 후크, 정적 함수 등에 익숙하지 않다. 언젠가 당신만큼 능숙 해지기를 바랍니다!
Nic Warmenhoven

답변:


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
좋은 답변이지만 추가 스타일 시트 요청을 포스트 편집 화면에 연결하는 것이 좋습니다. 메타 박스 생성에 대해서도 마찬가지입니다. 이상적으로는 do_meta_boxes조건부 논리를 사용하거나 다른 방법으로 add_meta_boxes_{%TYPE%}..
t31os

14

Hehe, 당신은 초보자입니다! 우리는 갈가리 찢어 버릴거야 ...!

j / k :) 우리는 모든 초보자에게 따뜻한 환영을 제공합니다.

따라서이 요구 사항을 고객으로부터 두 번, 다시는 귀하 (및 귀하의 고객)로부터 두 번 들었던 것은 이번이 세 번째입니다.

3 개의 드롭 다운을 표시하는 WordPress 사용자 정의 메타 박스

나는 당신의 분석을 좋아해서 두 번째 요점을 다루기 위해 수업을 코딩하기로 결정했습니다. 나는 그들 덕분 에이 노래 를 내 머리에서 LittlePromoBoxes절대로 꺼낼 수 없기 때문에 그것을 불렀 습니다 . 기본적으로 클래스를 사용하여 작성해야 할 함수와의 잠재적 인 이름 충돌을 피하기 위해 캡슐화합니다.

이 클래스를 테마 functions.php파일이나 작성중인 플러그인의 .PHP 파일에 넣을 수 있습니다 (하지만 걱정하지 마십시오. 실제보다 훨씬 복잡해 보입니다).

첫 번째 함수 on_load()는 클래스 선언이 끝날 때 호출하여 필요한 세 가지 후크를 초기화하는 정적 함수입니다. 정적 함수는 기본적으로 인스턴스가 아닌 클래스와 관련된 함수입니다 .

  1. init후크는 등록 promo-box후 유형을,

  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에서 각각 고유 한 ID ( "promo_box_{$i}") 를 제공해야 하지만 대괄호 ( 'promo_boxes[]') 와 같은 이름을 사용하여 PHP가 $_POST변수 (WordPress가 우리를 위해 액세스하는) 내의 배열로 수집 할 수 있도록해야 합니다. 당신은 분에 방법을 볼 수 있습니다) . 물론 (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])실제로 값 중 하나가 이미 선택된 경우 선택한 값 ( ) 을 설정해야합니다 .

또한 WordPress 핵심 기능 get_post_type_object()을 사용하여 게시물 유형에서 라벨을 가져 오는 방법을 보여 get_post_meta()주었고 WordPress 핵심 기능 을 사용하여 사용자 정의 필드 키 '_promo_boxes'를 사용하여 프로모션 상자 ID 배열을 검색했습니다. 다음에 저장하기 위해 ( '_promo_boxes'사용자가 게시물을 편집 할 때 WordPress가 표준 사용자 정의 필드 UI에서 숨겨지게 하는 이름에 앞의 밑줄을 사용했습니다 ) .

코드를보기 전에 설명 할 마지막 함수 filter_wp_insert_post_data()는 첫 번째 매개 변수 ( $data)로 기존 게시물 데이터를 수신 $_POST하고 두 번째 매개 변수 ( $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파일 에 추가 할 수있는 두 개의 래퍼 함수가 있습니다 (포스트를 매개 변수로 전달할 수는 있지만 루프의 게시물과 다른 게시물을 사용하지 않는 한 필요하지 않습니다 ) :

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>';
?>

1
당신은 당신의 대답, 코드를 만들고 각 단계를 설명하기 위해 겪는 노력으로 나를 놀라게하는 것을 결코 멈추지 않습니다.
t31os

1
@ t31os-감사합니다! 대답을 시작할 때 나는 스스로를 멈출 수 없다. 강박 관념 그러나 적어도 나는 잘 사용하고 있습니다!
MikeSchinkel

@toscho-감사합니다. 그렇다. 나는 유머를 거의 추가하지 않는다. :-)
MikeSchinkel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.