Odio ser el portador de malas noticias, pero WordPress codifica la funcionalidad de la plantilla de página para el tipo de publicación de "página" , al menos en v3.0 (eso podría cambiar en futuras versiones, pero no hay una iniciativa específica que conozca para cambiarlo) todavía. Así que esta es una de las pocas veces que estoy luchando para encontrar la manera de sortear algo sin hackear el núcleo).
La solución que se me ocurrió es básicamente copiar el código relevante del núcleo de WordPress y modificarlo según nuestras necesidades. Estos son los pasos (los números de línea son de v3.0.1):
Copie la page_attributes_meta_box()
función de la línea 535 de /wp-admin/includes/meta-boxes.php
y modifíquela según convenga.
Codifique un add_meta_boxes
gancho para agregar el metabox creado en el n. ° 1.
Copie la get_page_templates()
función de la línea 166 /wp-admin/includes/theme.php
y modifíquela para adaptarla.
Copie la page_template_dropdown()
función de la línea 2550 /wp-admin/includes/template.php
y modifíquela según convenga.
Agregue una plantilla de publicación a su tema.
Codifique un save_post
gancho para permitir el almacenamiento del nombre del archivo de plantilla de publicación al guardar.
Codifique un single_template
gancho para permitir la carga de la plantilla de publicación para las publicaciones asociadas.
Ahora con eso!
1. Copie la page_attributes_meta_box()
función
Como primer paso, debe copiar la page_attributes_meta_box()
función de la línea 535 /wp-admin/includes/meta-boxes.php
y he elegido cambiarle el nombre post_template_meta_box()
. Como solo solicitó plantillas de página, omití el código para especificar una publicación principal y para especificar el orden que hace que el código sea mucho más simple. También elegí usar postmeta para esto en lugar de intentar reutilizar la page_template
propiedad del objeto para evitar posibles incompatibilidades causadas por un acoplamiento involuntario. Así que aquí está el código:
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. Codifique un add_meta_boxes
gancho
El siguiente paso es agregar el metabox usando el add_meta_boxes
gancho:
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. Copie la get_page_templates()
función
Supuse que solo tendría sentido diferenciar entre las plantillas de página y la plantilla de publicación, por lo tanto, la necesidad de una get_post_templates()
función basada en la get_page_templates()
línea 166 de /wp-admin/includes/theme.php
. Pero en lugar de usar el Template Name:
marcador, qué plantillas de página usan esta función, usa un Post Template:
marcador que puede ver a continuación.
También me filtrada a cabo la inspección de functions.php
(no sé cómo get_page_templates()
nunca ha funcionado correctamente sin eso, pero lo que sea!) Y lo único que queda es cambiar las referencias a la palabra page
que post
para facilitar la lectura de mantenimiento en el futuro:
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. Copie la page_template_dropdown()
función
Del mismo modo, copie page_template_dropdown()
desde la línea 2550 de /wp-admin/includes/template.php
para crear post_template_dropdown()
y simplemente cámbielo para llamar en su get_post_templates()
lugar:
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. Agregar una plantilla de publicación
El siguiente paso es agregar una plantilla de publicación para probar. Usando el Post Template:
marcador mencionado en el paso 3 copia single.php
de tu tema single-test.php
y agrega el siguiente encabezado de comentario ( asegúrate de modificar algo single-test.php
para que puedas decir que se está cargando en lugar de single.php
) :
/**
* Post Template: My Test Template
*/
Una vez que haya realizado los pasos 1 al 5, puede ver su metabox "Publicar plantillas" en su página de editor de publicaciones:
(fuente: mikeschinkel.com )
6. Codifique un save_post
gancho
Ahora que tiene el editor ajustado, debe guardar el nombre del archivo de plantilla de página en postmeta cuando el usuario hace clic en "Publicar". Aquí está el código para eso:
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. Codifique un single_template
gancho
Y, por último, debe obtener WordPress para usar sus nuevas plantillas de publicación. Para ello, engancha single_template
y devuelve el nombre de la plantilla deseada para las publicaciones a las que se les ha asignado una:
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;
}
¡Y eso es todo!
TEN EN CUENTA que no tomé en cuenta solo los tipos de publicaciones personalizadaspost_type=='post'
. En mi opinión, abordar los tipos de publicaciones personalizadas requeriría diferenciar entre los diferentes tipos de publicaciones y, aunque no es demasiado difícil, no lo intenté aquí.