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):
Copia la page_attributes_meta_box()
funzione dalla riga 535 di /wp-admin/includes/meta-boxes.php
e modificala per adattarla.
Codifica un add_meta_boxes
hook per aggiungere il metabox creato nel numero 1.
Copia la get_page_templates()
funzione dalla riga 166 di /wp-admin/includes/theme.php
e modificala per adattarla.
Copia la page_template_dropdown()
funzione dalla riga 2550 di /wp-admin/includes/template.php
e modificala per adattarla.
Aggiungi un modello di post al tuo tema.
Codificare un save_post
hook per abilitare la memorizzazione del nome del file modello post al momento del salvataggio.
Codificare un single_template
hook 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.php
e 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_template
proprietà 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_boxes
gancio
Il prossimo passo è aggiungere metabox usando l' add_meta_boxes
hook:
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 page
per post
la 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.php
per 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.php
dal tuo tema single-test.php
e aggiungi la seguente intestazione del commento ( assicurati di modificare qualcosa in single-test.php
modo 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:
(fonte: mikeschinkel.com )
6. Codificare un save_post
hook
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_template
hook
E infine devi effettivamente ottenere WordPress per utilizzare i tuoi nuovi modelli di post. Puoi farlo agganciando single_template
e 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.