Aggiunta di attributi di pagina Metabox e modelli di pagina alla pagina di modifica dei post?


14

( Nota dei moderatori: il titolo era originariamente "Come posso aggiungere il selettore" Attributi di pagina "e / o" Attributi di pagina> Modello "all'editor POSTS")

WP attualmente consente solo l'assegnazione di un "modello" a Pages (ad es post_type=='page'.) Vorrei estendere questa funzionalità anche ai Post (ad es post_type=='post'.)

Come posso aggiungere la meta-box "Attributi di pagina" e, più specificamente, il selettore di modelli nell'editor dei post?

Suppongo che questo sia un codice che inserirò nel functions.phpmio tema.

AGGIORNAMENTO: Sono riuscito ad aggiungere il menu a discesa dei modelli hardcoded al mio editor di post, semplicemente aggiungendo la casella di selezione html alla mia casella di opzioni meta personalizzata esistente. Ecco il codice che sto usando per quello ...

add_meta_box('categorydiv2', __('Post Options'), 'post_categories_meta_box_modified', 'post', 'side', 'high');

Ed ecco la funzione che scrive le opzioni e la casella di selezione del modello ...

//adds the custom categories box
function post_categories_meta_box_modified() {
    global $post;
    if( get_post_meta($post->ID, '_noindex', true) ) $noindexChecked = " checked='checked'";
    if( get_post_meta($post->ID, '_nofollow', true) ) $nofollowChecked = " checked='checked'";
?>
<div id="categories-all" class="ui-tabs-panel">
    <ul id="categorychecklist" class="list:category categorychecklist form-no-clear">
        <li id='noIndex' class="popular-category"><label class="selectit"><input value="noIndex" type="checkbox" name="chk_noIndex" id="chk_noIndex"<?php echo $noindexChecked ?> /> noindex</label></li> 
        <li id='noFollow' class="popular-category"><label class="selectit"><input value="noFollow" type="checkbox" name="chk_noFollow" id="chk_noFollow"<?php echo $nofollowChecked ?> /> nofollow</label></li>
    </ul>

    <p><strong>Template</strong></p> 
    <label class="screen-reader-text" for="page_template">Post Template</label><select name="page_template" id="page_template"> 
    <option value='default'>Default Template</option> 
    <option value='template-wide.php' >No Sidebar</option>
    <option value='template-salespage.php' >Salespage</option>
    </select>
</div>
<?php
}

E infine, il codice per acquisire i valori selezionati su save ...

function save_post_categories_meta($post_id) {
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
    $noIndex = $_POST['chk_noIndex'];
    $noFollow = $_POST['chk_noFollow'];
    update_post_meta( $post_id, '_noindex', $noIndex );
    update_post_meta( $post_id, '_nofollow', $noFollow );
    return $post_id;
}

Ora, credo che tutto ciò che rimane sia (1) catturare il modello selezionato e aggiungerlo al meta meta per questo post e (2) modificare index.php e single.php in modo che utilizzi il modello scelto.


@Scott B : Beh, ho scritto tutta la mia risposta prima di vedere che ci stavi lavorando anche tu, e sembra che tu l'abbia presa in una direzione un po 'diversa dalla tua domanda originale con le tue opzioni di non seguire e senza indice. Spero che ciò che ho fatto abbia ancora valore per te. Altrimenti, forse aiuterà gli altri.
MikeSchinkel,

Sì, hai risposto alla domanda. Ho preso una virata un po 'diversa quando mi sono reso conto che non avevo bisogno di analizzare la directory e potevo codificare i valori per i miei modelli specifici. Probabilmente dovrò ancora prendere in prestito parte del tuo codice per far sì che WP utilizzi il modello assegnato corretto per il post.
Scott B,

Risposte:


12

Odio essere il portatore di cattive notizie ma WordPress codifica la funzionalità del modello di pagina sul tipo di post "pagina" , almeno nella v3.0 (che potrebbe cambiare nelle versioni future ma non c'è un'iniziativa specifica di cui sono a conoscenza per cambiarla ancora. Quindi questa è una delle pochissime volte che sto lottando per capire come aggirare qualcosa senza hacking core.)

La soluzione che ho trovato è sostanzialmente di copiare il codice rilevante dal core di WordPress e modificarlo in base alle nostre esigenze. Ecco i passaggi (i numeri di riga sono dalla v3.0.1):

  1. Copia la page_attributes_meta_box()funzione dalla riga 535 di /wp-admin/includes/meta-boxes.phpe modificala per adattarla.

  2. Codifica un add_meta_boxeshook per aggiungere il metabox creato nel numero 1.

  3. Copia la get_page_templates()funzione dalla riga 166 di /wp-admin/includes/theme.php e modificala per adattarla.

  4. Copia la page_template_dropdown()funzione dalla riga 2550 di /wp-admin/includes/template.phpe modificala per adattarla.

  5. Aggiungi un modello di post al tuo tema.

  6. Codificare un save_posthook per abilitare la memorizzazione del nome del file modello post al momento del salvataggio.

  7. Codificare un single_templatehook per abilitare il caricamento del modello di post per i post associati.

Adesso avanti!


1. Copia la page_attributes_meta_box()funzione

Come primo passo devi copiare la page_attributes_meta_box()funzione dalla riga 535 di /wp-admin/includes/meta-boxes.phpe ho scelto di rinominarla post_template_meta_box(). Dato che hai richiesto solo modelli di pagina, ho omesso il codice per specificare un post principale e per specificare l'ordine che rende il codice molto più semplice. Ho anche scelto di usare Postmeta per questo piuttosto che provare a riutilizzare la page_templateproprietà dell'oggetto per evitare potenziali incompatibilità causate da accoppiamento involontario. Quindi ecco il codice:

function post_template_meta_box($post) {
  if ( 'post' == $post->post_type && 0 != count( get_post_templates() ) ) {
    $template = get_post_meta($post->ID,'_post_template',true);
    ?>
<label class="screen-reader-text" for="post_template"><?php _e('Post Template') ?></label><select name="post_template" id="post_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php post_template_dropdown($template); ?>
</select>
<?php
  } ?>
<?php
}

2. Codificare un add_meta_boxesgancio

Il prossimo passo è aggiungere metabox usando l' add_meta_boxeshook:

add_action('add_meta_boxes','add_post_template_metabox');
function add_post_template_metabox() {
    add_meta_box('postparentdiv', __('Post Template'), 'post_template_meta_box', 'post', 'side', 'core');
}

3. Copia la get_page_templates()funzione

Ho pensato che avrebbe senso distinguere tra modelli di pagina e modello di post, quindi la necessità di una get_post_templates()funzione basata sulla get_page_templates()riga 166 di /wp-admin/includes/theme.php. Ma invece di utilizzare l' Template Name:indicatore quali modelli di pagina utilizzano questa funzione utilizza Post Template:invece un indicatore che puoi vedere di seguito.

Ho anche filtrati ispezione functions.php (non so come get_page_templates()mai ha funzionato correttamente senza che, ma qualunque cosa!) E l'unica cosa rimasta è quella di riferimenti di modifica per la parola pageper postla manutenzione leggibilità lungo la strada:

function get_post_templates() {
  $themes = get_themes();
  $theme = get_current_theme();
  $templates = $themes[$theme]['Template Files'];
  $post_templates = array();

  if ( is_array( $templates ) ) {
    $base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) );

    foreach ( $templates as $template ) {
      $basename = str_replace($base, '', $template);
      if ($basename != 'functions.php') {
        // don't allow template files in subdirectories
        if ( false !== strpos($basename, '/') )
          continue;

        $template_data = implode( '', file( $template ));

        $name = '';
        if ( preg_match( '|Post Template:(.*)$|mi', $template_data, $name ) )
          $name = _cleanup_header_comment($name[1]);

        if ( !empty( $name ) ) {
          $post_templates[trim( $name )] = $basename;
        }
      }
    }
  }

  return $post_templates;
}

4. Copia la page_template_dropdown()funzione

Allo stesso modo copia page_template_dropdown()dalla linea 2550 di /wp-admin/includes/template.phpper creare post_template_dropdown()e semplicemente cambiarlo per chiamare get_post_templates()invece:

function post_template_dropdown( $default = '' ) {
  $templates = get_post_templates();
  ksort( $templates );
  foreach (array_keys( $templates ) as $template )
    : if ( $default == $templates[$template] )
      $selected = " selected='selected'";
    else
      $selected = '';
  echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>";
  endforeach;
}

5. Aggiungi un modello di post

Il prossimo passo è aggiungere un modello di post per il test. Usando il Post Template:marker menzionato nel passaggio n. 3 copia single.phpdal tuo tema single-test.phpe aggiungi la seguente intestazione del commento ( assicurati di modificare qualcosa in single-test.phpmodo da poter dire che sta caricando invece di single.php) :

/**
 * Post Template: My Test Template
 */

Una volta completati i passaggi da 1 a 5, puoi vedere il tuo metabox "Modelli di post" sulla tua pagina di post editor:

Che aspetto avevano i post Metabox quando aggiunto a WordPress 3.0
(fonte: mikeschinkel.com )

6. Codificare un save_posthook

Ora che hai il quadrato dell'editor, devi effettivamente salvare il nome del file del modello di pagina in postmeta quando l'utente fa clic su "Pubblica". Ecco il codice per questo:

add_action('save_post','save_post_template',10,2);
function save_post_template($post_id,$post) {
  if ($post->post_type=='post' && !empty($_POST['post_template']))
    update_post_meta($post->ID,'_post_template',$_POST['post_template']);
}

7. Codificare un single_templatehook

E infine devi effettivamente ottenere WordPress per utilizzare i tuoi nuovi modelli di post. Puoi farlo agganciando single_templatee restituendo il nome del modello desiderato per quei post a cui è stato assegnato uno:

add_filter('single_template','get_post_template_for_template_loader');
function get_post_template_for_template_loader($template) {
  global $wp_query;
  $post = $wp_query->get_queried_object();
  if ($post) {
    $post_template = get_post_meta($post->ID,'_post_template',true);
    if (!empty($post_template) && $post_template!='default')
      $template = get_stylesheet_directory() . "/{$post_template}";
  }
  return $template;
}

E questo è tutto!

NOTA : non ho preso in considerazione solo i tipi di posta personalizzatipost_type=='post' . A mio avviso, affrontare i tipi di post personalizzati richiederebbe una differenziazione tra i diversi tipi di post e, sebbene non eccessivamente difficile, non ci ho provato qui.


Grande! Sono andato a dormire con un codice quasi completo nel mio editor con lo stesso approccio della copia delle funzioni predefinite di WordPress (era completo, ma non l'avrei pubblicato dal momento che non avevo testato). :)
sorich87,

@ sorich87 - Conoscete il vecchio detto, " Posticipate , perdete !" Scherzi a parte, scherzando SOLO . C'è davvero solo un modo ragionevole per farlo funzionare, quindi non c'è da meravigliarsi che il tuo codice sia lo stesso!
MikeSchinkel,

Mike, continui a stupire. Grazie mille per aver dedicato del tempo a martellare.
Scott B,

@ sorich87 - Grazie per averci lavorato. Apprezzo molto lo sforzo.
Scott B,

1
@Scott B : nessun problema, felice di poterti aiutare. Cerco domande ragionevolmente generiche che potrebbero potenzialmente aiutare molte persone e cerco di rispondere non solo alla persona che pone la domanda, ma a coloro che potrebbero venire dopo.
MikeSchinkel,

0

Wordpress ti consente di aggiungere Meta alle categorie usando un plugin:

Per fare questo è necessario aggiungere una delle varie estensioni che aggiungono meta alle categorie (imitando le pagine che escono fuori dalla scatola), Simple Term Meta fa il lavoro bene.

NB WordPress 3.x è necessario per estendere le categorie.

Dopodiché puoi usare:

  • add_term_meta
  • update_term_meta
  • get_term_meta

Usa Functions.php per aggiungere metodi per fare ciò che vuoi, ad es

add_action('category_add_form_fields', 'category_metabox_add', 10, 1);

function category_metabox_add($tag) { ?>
    <div class="form-field">
        <label for="image-url"><?php _e('Image URL') ?></label>
        <input name="image-url" id="image-url" type="text" value="" size="40" aria-required="true" />
        <p class="description"><?php _e('This image will be the thumbnail shown on the category page.'); ?></p>
    </div>
<?php } 

add_action('created_category', 'save_category_metadata', 10, 1);

function save_category_metadata($term_id)
{
    if (isset($_POST['image-url'])) 
        update_term_meta( $term_id, 'image-url', $_POST['image-url']);                  
}

Chiamare nuovi campi nei temi è facile:

<?php echo get_term_meta(get_query_var('cat'), 'image-url', true); ?>

Maggiori dettagli ed esempi: http://www.wphub.com/adding-metadata-taxonomy-terms/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.