Ajout de la métaboxe des attributs de page et des modèles de page à la page d'édition des publications?


14

( Note des modérateurs: le titre était à l'origine "Comment puis-je ajouter le sélecteur" Attributs de page "et / ou" Attributs de page> Modèle "à l'éditeur POSTS")

WP n'autorise actuellement que l'attribution d'un "modèle" aux pages (c'est-à-dire post_type=='page'.) J'aimerais également étendre cette fonctionnalité aux publications (c'est-à-dire post_type=='post'.)

Comment puis-je ajouter la boîte de méta "Attributs de page" et plus spécifiquement, le sélecteur de modèle à l'éditeur de messages?

Je suppose que c'est du code que je mettrai dans mon functions.phppour mon thème.

MISE À JOUR: J'ai réussi à ajouter le menu déroulant des modèles codés en dur à mon éditeur de publication, en ajoutant simplement la case de sélection html à ma boîte de méta-options personnalisée existante. Voici le code que j'utilise pour cela ...

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

Et voici la fonction qui écrit les options et la boîte de sélection de modèle ...

//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
}

Et enfin, le code pour capturer les valeurs sélectionnées lors de la sauvegarde ...

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;
}

Maintenant, je crois que tout ce qui reste est (1) capturer le modèle sélectionné et l'ajouter à la méta du post pour ce post et (2) modifier index.php et single.php pour qu'il utilise le modèle choisi.


@Scott B : Eh bien, j'ai écrit toute ma réponse avant de voir que vous y travailliez aussi, et il semble que vous l'ayez prise dans une direction quelque peu différente de celle de votre question d'origine avec vos options sans suivi et sans index. J'espère que ce que j'ai fait a encore de la valeur pour vous. Sinon, cela aidera peut-être les autres.
MikeSchinkel

Oui, vous avez répondu à la question. J'ai pris une approche un peu différente une fois que j'ai réalisé que je n'avais pas besoin d'analyser le répertoire et que je pouvais coder en dur les valeurs de mes modèles spécifiques. Je devrai probablement encore emprunter une partie de votre code pour que WP utilise le modèle attribué correctement pour la publication.
Scott B

Réponses:


12

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):

  1. Copiez la page_attributes_meta_box()fonction de la ligne 535 de /wp-admin/includes/meta-boxes.phpet modifiez-la en conséquence.

  2. add_meta_boxesCodez un hook pour ajouter la métabox créée en # 1.

  3. Copiez la get_page_templates()fonction de la ligne 166 de /wp-admin/includes/theme.php et modifiez-la en conséquence.

  4. Copiez la page_template_dropdown()fonction de la ligne 2550 /wp-admin/includes/template.phpet modifiez-la en fonction.

  5. Ajoutez un modèle de publication à votre thème.

  6. Codez un save_postcrochet pour activer le stockage du nom de fichier du modèle de publication lors de l'enregistrement.

  7. Codez un single_templatecrochet 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.phpet 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_templateproprié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_boxescrochet

L'étape suivante consiste à ajouter la métabox à l'aide du add_meta_boxescrochet:

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 pageassurer la postlisibilité 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.phppour 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.phppartir de votre thème dans single-test.phpet ajoutez l'en-tête de commentaire suivant ( assurez-vous de modifier quelque chose single-test.phppour 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:

À quoi ressemblait une Metabox de modèles de publication lorsqu'elle était ajoutée à WordPress 3.0
(source: mikeschinkel.com )

6. Codez un save_postcrochet

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_templatecrochet

Et enfin, vous devez réellement obtenir WordPress pour utiliser vos nouveaux modèles de publication. Pour ce faire, vous accrochez single_templateet 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.


Génial! Je me suis endormi avec un code presque complet dans mon éditeur avec la même approche de copie des fonctions WordPress par défaut (c'était complet, mais je ne le posterais pas car je n'ai pas testé). :)
sorich87

@ sorich87 - Vous connaissez le vieil adage, "Vous répétez, vous perdez!" Sérieusement, je plaisante UNIQUEMENT . Il n'y a vraiment qu'une seule façon raisonnable de le faire fonctionner, il n'est donc pas étonnant que votre code soit le même!
MikeSchinkel

Mike, vous continuez d'étonner. Merci beaucoup d'avoir pris le temps de mettre cela au point.
Scott B

@ sorich87 - Merci d'avoir travaillé dessus. J'apprécie vraiment l'effort.
Scott B

1
@Scott B : Pas de problème, je suis content d'avoir pu aider. Je cherche des questions raisonnablement génériques qui pourraient potentiellement aider beaucoup de gens et j'essaye d'y répondre non seulement pour la personne qui pose la question mais aussi pour ceux qui peuvent venir après.
MikeSchinkel

0

Wordpress vous permet d'ajouter des méta aux catégories à l'aide d'un plugin:

Pour ce faire, vous devez ajouter l'une des différentes extensions qui ajoutent des méta aux catégories (imitant les pages qui sortent de la boîte), Simple Term Meta fait bien le travail.

NB WordPress 3.x est nécessaire pour étendre les catégories.

Après cela, vous pouvez utiliser:

  • add_term_meta
  • update_term_meta
  • get_term_meta

Utilisez Functions.php pour ajouter des méthodes pour faire ce que vous voulez, par exemple

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']);                  
}

Appeler de nouveaux champs dans des thèmes est facile:

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

Plus de détails et d'exemples: http://www.wphub.com/adding-metadata-taxonomy-terms/

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.