2012-12-16 4 views
9

Ich habe den folgenden Code, der einen eigenen Posttyp Admin-Strich und eine benutzerdefinierten Meta-Box zum Fenster Post bearbeiten fügt hinzu:Hinzufügen mehrere Meta-Box zu einer benutzerdefinierten Post Art in Wordpress

function teasers_custom_init() { 
    $labels = array(
    'name' => 'Teasers', 
    'singular_name' => 'Teaser', 
    'add_new' => 'Add New', 
    'add_new_item' => 'Add New Teasers', 
    'edit_item' => 'Edit Teaser', 
    'new_item' => 'New Teaser', 
    'all_items' => 'All Teasers', 
    'view_item' => 'View Teaser', 
    'search_items' => 'Search Teasers', 
    'not_found' => 'No teasers found', 
    'not_found_in_trash' => 'No teasers found in Trash', 
    'parent_item_colon' => 'Parent Page', 
    'menu_name' => 'Teasers' 
); 

    $args = array(
    'labels' => $labels, 
    'description' => 'set slider panels with loop times', 
    'public' => true, 
    'publicly_queryable' => true, 
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true, 
    'rewrite' => array('slug' => 'Teasers'), 
    'capability_type' => 'page', 
    'has_archive' => true, 
    'hierarchical' => true, 
    'menu_position' => 60, 
    'supports' => array('title', 'thumbnail', 'page-attributes'), 

); 

    register_post_type('teasers', $args); 
} 
add_action('init', 'teasers_custom_init'); 


//adding the meta box when the admin panel initialises 
add_action("admin_init", "admin_init"); 
// this adds the save teaser function on save post 
add_action('save_post', 'save_teaser'); 

function admin_init(){ 
    add_meta_box('teaser_loop', 'Loop Time', 'loop_meta', 'teasers', 'normal', 'default'); 
} 
// callback function of add meta box that displays the meta box in the post edit screen 
function loop_meta($post, $args){ 

    $teaser_loop = get_post_meta($post->ID, 'teaser_loop', true); 

?> 
    <label>Teaser Loop: </label><input type="text" name="teaser_loop" value="<?php echo $teaser_loop; ?>" /><br/> 

<?php 

} 

// saving the teaser 
function save_teaser(){ 
    global $post; 
    update_post_meta($post->ID, 'teaser_loop', $_POST['teaser_loop']); 
} 

Meine Frage Wenn ich eine zusätzliche Metabox hinzufügen möchte, was ist der beste Ansatz?

Ich habe versucht, einen weiteren Aufruf von add_meta_box in der Funktion admin_init hinzuzufügen und habe auch eine zusätzliche Callback-Funktion für diese Metabox html erstellt, aber am Frontend wurde nichts generiert. Alle Hinweise wären toll.

EDIT: Also das ist, wie ich es getan habe für mehr als eine Meta-Box (das funktioniert):

//adding the meta box when the admin panel initialises 
    add_action("admin_init", "admin_init"); 
    // this adds the save teaser function on save post 
    add_action('save_post', 'save_teaser'); 
    function admin_init(){ 
     add_meta_box('teaser_loop', 'Loop Time', 'loop_meta_1', 'teasers', 'normal', 'default'); 
     add_meta_box('teaser_link', 'Teaser Link', 'loop_meta_2', 'teasers', 'normal', 'default'); 
    } 
    // back function of add meta box that displays the meta box in the post edit screen 
    function loop_meta_1($post, $args){ 


     $teaser_loop = get_post_meta($post->ID, 'teaser_loop', true); 

?> 
    <label>Teaser Loop: </label><input type="text" name="teaser_loop" value="<?php echo $teaser_loop; ?>" /><br/> 

<?php 

} 

    function loop_meta_2($post, $args){ 

     $teaser_link = get_post_meta($post->ID, 'teaser_link', true); 

?> 
    <label>Teaser Link: </label><input type="text" name="teaser_link" value="<?php echo $teaser_link; ?>" /><br/> 

<?php 

} 

// saving the teaser 
function save_teaser(){ 
    global $post; 
    update_post_meta($post->ID, 'teaser_loop', $_POST['teaser_loop']); 
    update_post_meta($post->ID, 'teaser_link', $_POST['teaser_link']); 
} 
+0

Sie könnten auch diese unter http fragen: //wordpress.stackex change.com/ – Joren

+0

Oder bei [codereview.se], wie dies funktioniert Code optimiert werden soll. – brasofilo

+0

Ich habe die Bounty eingereicht, weil es nirgendwo im Internet eine dynamische Herangehensweise an dieses Problem gibt. Ich habe mich gefragt, was die optimale Lösung wäre, die alle Formelemente enthält. – Joren

Antwort

3

Sie metabox, um benutzerdefinierte Post-Typ mit folgenden Code hinzufügen können.

Zuerst metabox

add_action('admin_init', 'my_theme_on_admin_init'); 

function my_theme_on_admin_init() { 
    add_meta_box('my_metabox', 
     __('My metabox', 'textdomain'), 
     'my_metabox_render', 
     'my_custom_post_type', 'normal', 'high' 
    ); 
} 

Hinweis schaffen, dass my_custom_post_type ist ein Name, der Sie benutzerdefinierte Post Art und my_metabox_render - Name einer Funktion, die metabox macht.

Rendering-Funktion sollte erstellen alle nessesary Felder

function my_metabox_render($post) { 
    $data = get_post_meta($post->ID, '_meta_key', true); 
    // Use nonce for verification 
    wp_nonce_field('add_my_meta', 'my_meta_nonce'); 
?> 
<div class="inside"> 
    <table class="form-table"> 
     <tr valign="top"> 
      <th scope="row"><label for="my_meta_value"><?php _e('My meta', 'textdomain'); ?></label></th> 
      <td><textarea id="my_meta_value" name="my_meta_value" cols="40" rows="5"><?php echo (isset($data)) ? $data : ''; ?></textarea></td> 
     </tr> 
    </table> 
</div> 
<?php 
} 

als Sie sollten Sie Metadaten aktualisieren, wenn Benutzer Post spart

add_action('wp_insert_post', 'save_my_meta', 10, 2); 

function save_my_meta($id) { 
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) 
     return $id; 
    if (!current_user_can('edit_posts')) 
     return; 

    if (!isset($id)) 
     $id = (int) $_REQUEST['post_ID']; 

    if (isset($_POST['my_meta_value']) && wp_verify_nonce($_POST['my_meta_value'], 'add_my_meta')) { 
     $data = $_POST['my_meta_value']; 
     if (isset($data)) { 
      update_post_meta($id, '_meta_key', $data); 
     } 
     else { 
      delete_post_meta($id, '_meta_key'); 
     } 
    } 
} 
+0

Hallo Vladimir. Danke für die Antwort. Das Hinzufügen eines Meta-Felds ist in Ordnung, aber wie füge ich einem benutzerdefinierten Post-Typ mehr als ein Meta-Feld hinzu? Das ist das Problem, das ich habe. – BIOS

+0

Rufen Sie die Funktion 'add_meta_box' für jede Metabox auf, die Sie erstellen möchten. Und natürlich sollte jede Metabox eine eigene Renderfunktion haben. – Vladimir

+0

Können Sie den Code anzeigen, den Sie versuchen, mehrere Meta-Boxen hinzuzufügen? – Vladimir

7

Es kann vollständig in einer Klasse gekapselt werden. Hier habe ich es nicht mit dem Hinzufügen des Custom Post Type zu tun, und es gibt nur zwei einfache Ausgabefelder, Text und Checkbox. Ein voll funktionsfähiger Code sollte sich um jeden gewünschten Eingabe-Typ kümmern.

<?php 
/** 
* Plugin Name: Sample Dynamic Meta Boxes 
* Plugin URI: http://stackoverflow.com/q/13903529/1287812 
* Author:  brasofilo 
*/ 
class B5F_Dynamic_Meta_Boxes 
{ 
    private $boxes; 

    # Safe to start up 
    public function __construct($args) 
    { 
     $this->boxes = $args; 
     add_action('plugins_loaded', array($this, 'start_up')); 
    } 

    public function start_up() 
    { 
     add_action('add_meta_boxes', array($this, 'add_mb')); 
    } 

    public function add_mb() 
    { 
     foreach($this->boxes as $box) 
      add_meta_box( 
       $box['id'], 
       $box['title'], 
       array($this, 'mb_callback'), 
       $box['post_type'], 
       isset($box['context']) ? $box['context'] : 'normal', 
       isset($box['priority']) ? $box['priority'] : 'default', 
       $box['args'] 
      ); 
    } 

    # Callback function, uses helper function to print each meta box 
    public function mb_callback($post, $box) 
    { 
     switch($box['args']['field']) 
     { 
      case 'textfield': 
       $this->textfield($box, $post->ID); 
      break; 
      case 'checkbox': 
       $this->checkbox($box, $post->ID); 
      break; 
     } 
    } 

    private function textfield($box, $post_id) 
    { 
     $post_meta = get_post_meta($post_id, $box['id'], true); 
     printf(
      '<label>%s: <input type="text" name="%s" value="%s" /></label> <small>%s</small><br/>', 
      $box['title'], 
      $box['id'], 
      $post_meta, 
      $box['args']['desc'] 
     ); 
    } 

    private function checkbox($box, $post_id) 
    { 
     $post_meta = get_post_meta($post_id, $box['id'], true); 
     printf(
      '<label>%s: </label><input type="checkbox" name="%s" %s /> <small>%s</small><br/>', 
      $box['title'], 
      $box['id'], 
      checked(1, $post_meta, false), 
      $box['args']['desc'] 
     ); 
    } 
} 

# ADD TWO META BOXES - DIFFERENT POST TYPES - DIFFERENT CONTEXTS AND PRIORITIES 
$args = array(
    array(
     'id' => 'teaser_loop', 
     'title' => 'Loop Time', 
     'post_type' => 'post', 
     'args' => array(
      'desc' => 'Enter the time', 
      'field' => 'textfield', 
     ) 
    ), 
    array(
     'id' => 'teaser_link', 
     'title' => 'Loop Link', 
     'post_type' => 'page', 
     'context' => 'side', 
     'priority' => 'high', 
     'args' => array(
      'desc' => 'Open link', 
      'field' => 'checkbox', 
     ) 
    ), 
); 
new B5F_Dynamic_Meta_Boxes($args); 

# ADD ANOTHER META BOX TO ANOTHER POST TYPE 
$more_args = array(
    array(
     'id' => 'extra_box', 
     'title' => 'And another one', 
     'post_type' => 'teaser', 
     'args' => array(
      'desc' => 'Open link', 
      'field' => 'textfield', 
     ) 
    ), 
); 
new B5F_Dynamic_Meta_Boxes($more_args); 

Dies ist nur ein Skelett, von hier gibt es eine Menge zu schreiben. Einige Beispiele:

+0

Dies ist auf Texteingabe beschränkt. Dies funktioniert nicht, wenn Sie mit Radio/Kontrollkästchen, Dropdown-Menüs oder anderen Formularelementen arbeiten. Der erste Teil mag ich tho, aber scheint ein bisschen überentwickelt – Joren

+0

@Joren, nun ja, es ist nur ein Umriss. Eine Klasse zu verwenden wäre angemessener. Feinabstimmung ist Sache des Benutzers. Sie haben keine benutzerdefinierte Beschreibung in das Kopfgeld eingegeben. Können Sie in der Frage einen Kommentar abgeben, in dem Sie angeben, was Sie erwarten? – brasofilo

+0

@brasofilo: Ist es möglich, Ihre 'Klasse' zu ​​verwenden? Ich kann mehrere Meta-Felder innerhalb einer einzelnen Metabox hinzufügen und dort auch Tab-Funktionalität hinzufügen? –