Je déteste être porteur de mauvaises nouvelles, mais WordPress code en dur la fonctionnalité de modèle de page au type de publication "page" , au moins dans la version 3.0 (qui pourrait changer dans les futures versions mais il n'y a pas d'initiative spécifique à ma connaissance pour la changer) C'est donc l'une des très rares fois où j'ai du mal à trouver comment contourner quelque chose sans pirater le cœur.)
La solution que j'ai trouvée consiste à copier le code pertinent à partir du noyau WordPress et à le modifier selon nos besoins. Voici les étapes (les numéros de ligne proviennent de la v3.0.1):
Copiez la page_attributes_meta_box()
fonction de la ligne 535 de /wp-admin/includes/meta-boxes.php
et modifiez-la en conséquence.
add_meta_boxes
Codez un hook pour ajouter la métabox créée en # 1.
Copiez la get_page_templates()
fonction de la ligne 166 de /wp-admin/includes/theme.php
et modifiez-la en conséquence.
Copiez la page_template_dropdown()
fonction de la ligne 2550 /wp-admin/includes/template.php
et modifiez-la en fonction.
Ajoutez un modèle de publication à votre thème.
Codez un save_post
crochet pour activer le stockage du nom de fichier du modèle de publication lors de l'enregistrement.
Codez un single_template
crochet pour permettre le chargement du modèle de publication pour les publications associées.
Maintenant avec!
1. Copiez la page_attributes_meta_box()
fonction
Comme première étape, vous devez copier la page_attributes_meta_box()
fonction de la ligne 535 de /wp-admin/includes/meta-boxes.php
et j'ai choisi de la renommer post_template_meta_box()
. Puisque vous n'avez demandé que des modèles de page, j'ai omis le code pour spécifier un article parent et pour spécifier l'ordre qui rend le code beaucoup plus simple. J'ai également choisi d'utiliser postmeta pour cela plutôt que d'essayer de réutiliser la page_template
propriété de l' objet afin d'éviter les incompatibilités potentielles causées par un couplage involontaire. Voici donc le code:
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. Codez un add_meta_boxes
crochet
L'étape suivante consiste à ajouter la métabox à l'aide du add_meta_boxes
crochet:
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. Copiez la get_page_templates()
fonction
J'ai supposé qu'il serait logique de faire la différence entre les modèles de page et le modèle de publication, d'où la nécessité d'une get_post_templates()
fonction basée sur la get_page_templates()
ligne 166 de /wp-admin/includes/theme.php
. Mais au lieu d'utiliser le Template Name:
marqueur, les modèles de page qui utilisent cette fonction utilisent un Post Template:
marqueur à la place que vous pouvez voir ci-dessous.
J'ai également filtré l'inspection de functions.php
(get_page_templates()
je ne sais pas comment cela a jamais fonctionné correctement sans cela, mais peu importe!) Et la seule chose qui reste est de changer les références au mot pour page
assurer la post
lisibilité de la maintenance sur la route:
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. Copiez la page_template_dropdown()
fonction
De même, copiez à page_template_dropdown()
partir de la ligne 2550 de /wp-admin/includes/template.php
pour créer post_template_dropdown()
et changez-le simplement pour appeler à la get_post_templates()
place:
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. Ajoutez un modèle de publication
L'étape suivante consiste à ajouter un modèle de publication pour les tests. À l'aide du Post Template:
marqueur mentionné à l'étape 3, copiez à single.php
partir de votre thème dans single-test.php
et ajoutez l'en-tête de commentaire suivant ( assurez-vous de modifier quelque chose single-test.php
pour pouvoir dire qu'il se charge au lieu de single.php
) :
/**
* Post Template: My Test Template
*/
Une fois que vous avez effectué les étapes # 1 à # 5, vous pouvez voir votre métabox "Post Templates" apparaître sur la page de votre éditeur de publication:
(source: mikeschinkel.com )
6. Codez un save_post
crochet
Maintenant que l'éditeur est au carré, vous devez réellement enregistrer le nom de votre fichier de modèle de page dans postmeta lorsque l'utilisateur clique sur "Publier". Voici le code pour cela:
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. Coder un single_template
crochet
Et enfin, vous devez réellement obtenir WordPress pour utiliser vos nouveaux modèles de publication. Pour ce faire, vous accrochez single_template
et renvoyez le nom de modèle souhaité pour les publications qui en ont un affecté:
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;
}
Et c'est tout!
REMARQUE que je n'ai pas pris en compte uniquement les types de publication personnaliséspost_type=='post'
. À mon avis, pour aborder les types de messages personnalisés, il faudrait faire la différence entre les différents types de messages et, bien que ce ne soit pas trop difficile, je n'ai pas tenté cela ici.