¿Agregar atributos de página Metabox y plantillas de página a la página de edición de publicaciones?

11

( Nota para los moderadores: el título fue originalmente "¿Cómo puedo agregar los" Atributos de página "y / o" Atributos de página > Plantilla "al selector de POSTS")

Actualmente, WP solo permite la asignación de una "plantilla" a las páginas (es decir, post_type=='page' ). También me gustaría extender esta funcionalidad a las publicaciones (es decir, post_type=='post' .)

¿Cómo puedo agregar el meta box "Atributos de página" y, más específicamente, el selector de plantillas al editor de publicaciones?

Supongo que este es el código que colocaré en mi functions.php para mi tema.

ACTUALIZACIÓN: me las arreglé para agregar el menú desplegable de las plantillas codificadas a mi editor de publicaciones, simplemente agregando el cuadro de selección html a mi caja existente de meta opciones personalizadas. Aquí está el código que estoy usando para eso ...

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

Y aquí está la función que escribe las opciones y el cuadro de selección de plantilla ...

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

Y finalmente, el código para capturar los valores seleccionados al guardar ...

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

Ahora, creo que todo lo que queda es (1) capturar la plantilla seleccionada y agregarla al meta meta para esta publicación y (2) modificar index.php y single.php para que use la plantilla elegida.

    
pregunta Scott B 10.10.2010 - 19:40

2 respuestas

11

Odio ser el portador de malas noticias pero WordPress codifica la funcionalidad de la Plantilla de Página a la "página" tipo de publicación , al menos en v3.0 ( eso podría cambiar en las versiones futuras, pero no hay una iniciativa específica de la que deba cambiarlo todavía. Por lo tanto, esta es una de las pocas veces que estoy luchando para descubrir cómo sortear algo sin hackear el núcleo.)

La solución que he encontrado es básicamente copiar el código relevante del núcleo de WordPress y modificarlo según nuestras necesidades. Aquí están los pasos (los números de línea son de v3.0.1):

  1. Copie la función page_attributes_meta_box() de la línea 535 de /wp-admin/includes/meta-boxes.php y modifíquela para adaptarla.

  2. Codifique un gancho add_meta_boxes para agregar el metabox creado en el # 1.

  3. Copie la función get_page_templates() de la línea 166 de /wp-admin/includes/theme.php y modificar para adaptarse.

  4. Copie la función page_template_dropdown() de la línea 2550 de /wp-admin/includes/template.php y modifíquela para adaptarla.

  5. Agrega una plantilla de publicación a tu tema.

  6. Codifique un gancho save_post para habilitar el almacenamiento del nombre del archivo de la plantilla de publicación al guardar.

  7. Codifique un gancho single_template para habilitar la carga de la plantilla de publicaciones para las publicaciones asociadas.

¡Ahora en marcha!

1. Copie la función page_attributes_meta_box()

Como nuestro primer paso, necesita copiar la función page_attributes_meta_box() de la línea 535 de /wp-admin/includes/meta-boxes.php y he elegido cambiarle el nombre a post_template_meta_box() . Como solo pidió plantillas de página, omití el código para especificar una publicación principal y para especificar el orden, lo que hace que el código sea mucho más sencillo. También opté por usar postmeta para esto en lugar de intentar reutilizar la propiedad de objeto page_template para evitar posibles incompatibilidades causadas por el 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 gancho add_meta_boxes

El siguiente paso es agregar el metabox usando el 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. Copie la función get_page_templates()

Supuse que solo tendría sentido diferenciar entre plantillas de página y plantilla de publicación, por lo tanto, la necesidad de una función get_post_templates() basada en get_page_templates() de la línea 166 de /wp-admin/includes/theme.php . Pero en lugar de usar el marcador Template Name: , las plantillas de página que usan esta función usan un marcador Post Template: en lugar de lo que puede ver a continuación.

También filtré la inspección de functions.php (no estoy seguro de cómo get_page_templates() funcionó correctamente sin eso, ¡pero lo que sea!) Y lo único que queda es cambiar las referencias a la palabra page a post para facilitar la lectura 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 función page_template_dropdown()

De forma similar, copie page_template_dropdown() de la línea 2550 de /wp-admin/includes/template.php para crear post_template_dropdown() y simplemente cámbielo para llamar a get_post_templates() en su 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. Añadir una plantilla de publicación

El siguiente paso es agregar una plantilla de publicación para la prueba. Usando el marcador Post Template: mencionado en el paso # 3, copie single.php de su tema en single-test.php y agregue el siguiente encabezado de comentario ( asegúrese de modificar algo en single-test.php para que pueda saber que se está cargando en lugar de single.php ) :

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

Una vez que haya realizado los pasos del 1 al 5, podrá ver su metabox "Plantillas de publicación" en su página de editor de publicación:

6.Codifiqueunganchosave_post

Ahoraquetieneeleditoralcuadrado,debeguardarelnombredearchivodesuplantilladepáginaenpostmetacuandoelusuariohagaclicen"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 gancho single_template

Y, por último, necesitas que WordPress use tus nuevas plantillas de publicaciones. Para hacerlo, conecte single_template y devuelva el nombre de la plantilla deseada para aquellas publicaciones que hayan tenido una asignada:

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!

NOTA de que no consideré Tipos de publicaciones personalizadas , solo post_type=='post' . En mi opinión, abordar tipos de publicaciones personalizados requeriría diferenciar los diferentes tipos de publicaciones y, aunque no es demasiado difícil, no lo intenté aquí.

    
respondido por el MikeSchinkel 11.10.2010 - 01:11
0

Wordpress le permite agregar Meta a Categorías usando un complemento:

Para hacer esto, debe agregar una de las varias extensiones que agrega meta a las categorías (imitando qué páginas salen de la caja), Simple Term Meta hace el trabajo muy bien.

N.B. WordPress 3.x es necesario para ampliar las categorías.

Después de eso puedes usar:

  • add_term_meta
  • update_term_meta
  • get_term_meta

Usa Functions.php para agregar métodos para hacer lo que quieras, por ejemplo

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

Llamar nuevos campos en temas es fácil:

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

Más detalles y ejemplos: enlace

    
respondido por el Jay 14.09.2013 - 16:27

Lea otras preguntas en las etiquetas