Hinzufügen von Seitenattributen Metabox und Seitenvorlagen zu den Beiträgen Seite bearbeiten?

14

( Hinweis für Moderatoren: Der Titel lautete ursprünglich "Wie kann ich den Selektor" Seitenattribute "und / oder" Seitenattribute> Vorlage "zum POSTS-Editor hinzufügen")

WP erlaubt derzeit nur die Zuordnung einer "Vorlage" zu Pages (d post_type=='page'. H.). Ich möchte diese Funktionalität auch auf Posts (d post_type=='post'. H.) Erweitern .

Wie kann ich das Metafeld " Seitenattribute" und insbesondere den Vorlagenumschalter zum Beitragseditor hinzufügen ?

Ich gehe davon aus, dass dies der Code ist, den ich functions.phpfür mein Thema in my einfügen werde .

UPDATE: Ich habe es geschafft, das Pulldown-Menü für hartcodierte Vorlagen zu meinem Post-Editor hinzuzufügen, indem ich einfach das Auswahlfeld HTML zu meinem vorhandenen benutzerdefinierten Meta-Optionsfeld hinzufügte. Hier ist der Code, den ich dafür benutze ...

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

Und hier ist die Funktion, die die Optionen und das Auswahlfeld für die Vorlage ausgibt ...

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

Und schließlich der Code, um die ausgewählten Werte beim Speichern zu erfassen ...

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

Jetzt glaube ich, dass alles, was übrig bleibt, ist, (1) die ausgewählte Vorlage zu erfassen und sie dem Post-Meta für diesen Post hinzuzufügen und (2) index.php und single.php so zu ändern, dass sie die ausgewählte Vorlage verwenden.

Scott B
quelle
@Scott B : Nun, ich habe meine ganze Antwort geschrieben, bevor ich gesehen habe, dass Sie auch daran gearbeitet haben, und es scheint, als hätten Sie es in eine etwas andere Richtung gebracht als Ihre ursprüngliche Frage mit Ihrem Nein-Verfolgen und keinen Indexoptionen. Hoffentlich hat das, was ich getan habe, noch Wert für Sie. Wenn nicht, hilft es vielleicht anderen.
MikeSchinkel
Ja, du hast die Frage beantwortet. Als ich merkte, dass ich das Verzeichnis nicht analysieren musste, nahm ich einen anderen Kurs und konnte die Werte für meine spezifischen Vorlagen fest codieren. Ich muss wahrscheinlich noch einen Teil Ihres Codes ausleihen, damit WP die richtige zugewiesene Vorlage für den Beitrag verwendet.
Scott B

Antworten:

12

Ich hasse es, der Überbringer von schlechten Nachrichten zu sein, aber WordPress codiert die Seitenvorlagenfunktionalität fest auf den Post-Typ "Seite" , zumindest in Version 3.0 (das könnte sich in zukünftigen Versionen ändern, aber es gibt keine spezifische Initiative, die ich kenne, um sie zu ändern Dies ist also eines der wenigen Male, bei denen ich Probleme habe, herauszufinden, wie ich etwas umgehen kann, ohne den Kern zu hacken.)

Die Lösung, die ich mir ausgedacht habe, besteht darin, den relevanten Code aus dem WordPress-Kern zu kopieren und an unsere Bedürfnisse anzupassen. Hier sind die Schritte (die Zeilennummern sind von v3.0.1):

  1. Kopieren Sie die page_attributes_meta_box()Funktion aus Zeile 535 von /wp-admin/includes/meta-boxes.phpund passen Sie sie an.

  2. Code einen add_meta_boxesHaken , um die in # 1 erstellte Metabox hinzuzufügen.

  3. Kopieren Sie die get_page_templates()Funktion aus Zeile 166 von /wp-admin/includes/theme.php und passen Sie sie an.

  4. Kopieren Sie die page_template_dropdown()Funktion aus Zeile 2550 von /wp-admin/includes/template.phpund passen Sie sie an.

  5. Fügen Sie Ihrem Thema eine Post-Vorlage hinzu .

  6. Codieren Sie einen save_postHook , um das Speichern des Post-Template-Dateinamens beim Speichern zu ermöglichen.

  7. Codieren Sie einen single_templateHook , um das Laden der Beitragsvorlage für die zugeordneten Beiträge zu ermöglichen.

Nun weiter damit!


1. Kopieren Sie die page_attributes_meta_box()Funktion

Als ersten Schritt müssen Sie die page_attributes_meta_box()Funktion aus Zeile 535 von kopieren, /wp-admin/includes/meta-boxes.phpund ich habe beschlossen, sie umzubenennen post_template_meta_box(). Da Sie nur nach Seitenvorlagen gefragt haben, habe ich den Code für die Angabe eines übergeordneten Posts und für die Angabe der Reihenfolge weggelassen, wodurch der Code viel einfacher wird. Ich entschied mich auch dafür, Postmeta zu verwenden, anstatt zu versuchen, die page_templateObjekteigenschaft wiederzuverwenden , um mögliche Inkompatibilitäten durch unbeabsichtigtes Koppeln zu vermeiden. Also hier ist der 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. Code einen add_meta_boxesHaken

Der nächste Schritt ist das Hinzufügen der Metabox mit dem add_meta_boxesHook:

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. Kopieren Sie die get_page_templates()Funktion

Ich ging davon aus, dass es nur Sinn machen würde, zwischen Seitenvorlagen und Beitragsvorlagen zu unterscheiden, daher die Notwendigkeit einer get_post_templates()auf get_page_templates()Zeile 166 basierenden Funktion /wp-admin/includes/theme.php. Anstatt den Template Name:Marker zu verwenden, für welche Seitenvorlagen diese Funktion verwendet wird Post Template:, wird stattdessen ein Marker verwendet, den Sie unten sehen können.

Ich gefiltert auch aus Inspektion von functions.php (nicht sicher , wie get_page_templates()immer richtig , ohne dass gearbeitet, aber was auch immer!) Und das einzige , was links ist zu ändern Verweise auf das Wort , pageum postfür die Wartung Lesbarkeit auf der Straße:

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. Kopieren Sie die page_template_dropdown()Funktion

Kopieren Sie in ähnlicher Weise page_template_dropdown()aus Zeile 2550 von /wp-admin/includes/template.php, um post_template_dropdown()es zu erstellen, und ändern Sie es einfach, um get_post_templates()stattdessen aufzurufen :

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. Fügen Sie eine Post-Vorlage hinzu

Im nächsten Schritt fügen Sie eine Post-Vorlage zum Testen hinzu. Verwenden Sie die Post Template:in Schritt 3 erwähnte Markierung, kopieren Sie sie single.phpaus Ihrem Design single-test.phpund fügen Sie den folgenden Kommentar-Header hinzu (stellen Sie sicher, single-test.phpdass Sie etwas daran ändern, damit Sie erkennen können, dass es geladen wird, anstatt single.php) :

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

Sobald Sie die Schritte 1 bis 5 ausgeführt haben, wird Ihre Metabox "Post Templates" auf Ihrer Post-Editor-Seite angezeigt:

Wie eine Metabox für Post-Vorlagen aussah, wenn sie zu WordPress 3.0 hinzugefügt wurde
(Quelle: mikeschinkel.com )

6. Code einen save_postHaken

Nachdem Sie den Editor entfernt haben, müssen Sie den Dateinamen Ihrer Seitenvorlage tatsächlich auf Postmeta speichern, wenn der Benutzer auf "Veröffentlichen" klickt. Hier ist der Code dafür:

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. Code einen single_templateHaken

Und zu guter Letzt müssen Sie WordPress installieren, um Ihre neuen Post-Vorlagen verwenden zu können. Sie tun dies, indem single_templateSie den gewünschten Vorlagennamen für die Posts anhängen und zurückgeben, denen einer zugewiesen wurde:

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

Und das war's auch schon!

HINWEIS , dass ich nicht in Betracht ziehen Benutzerdefinierte Beitragstypen , nur post_type=='post'. Meiner Meinung nach erfordert das Adressieren von benutzerdefinierten Beitragstypen die Unterscheidung zwischen den verschiedenen Beitragstypen, und obwohl dies nicht allzu schwierig ist, habe ich es hier nicht versucht.

MikeSchinkel
quelle
Groß! Ich bin mit einem fast vollständigen Code in meinem Editor eingeschlafen, mit dem gleichen Ansatz wie beim Kopieren der Standard-WordPress-Funktionen (er war vollständig, aber ich würde ihn nicht posten, da ich ihn nicht getestet habe). :)
Sorich87
@ sorich87 - Du kennst das alte Sprichwort: "Du schläfst, du bist los!" Im Ernst, nur ein Scherz. Es gibt wirklich nur einen vernünftigen Weg, um es zum Laufen zu bringen, es ist also kein Wunder, dass Ihr Code derselbe wäre!
MikeSchinkel
Mike, du wirst immer wieder staunen. Vielen Dank, dass Sie sich die Zeit genommen haben, dies herauszufinden.
Scott B
@ sorich87 - Danke, dass du daran gearbeitet hast. Ich weiß die Mühe wirklich zu schätzen.
Scott B
1
@Scott B : Kein Problem, froh, dass ich helfen konnte. Ich suche nach einigermaßen allgemeinen Fragen, die möglicherweise vielen Menschen helfen könnten, und versuche, sie nicht nur für die Person zu beantworten, die die Frage stellt, sondern auch für diejenigen, die danach kommen könnten.
MikeSchinkel
0

Mit Wordpress können Sie Meta zu Kategorien hinzufügen, indem Sie ein Plugin verwenden:

Um dies zu tun , müssen eine der verschiedenen Erweiterungen hinzufügen , die Meta - Kategorien ergänzt (imitiert , welche Seiten der Box raus), einfache Begriff Meta macht den Job gut.

NB WordPress 3.x wird zum Erweitern von Kategorien benötigt.

Danach können Sie verwenden:

  • add_term_meta
  • update_term_meta
  • get_term_meta

Verwenden Sie Functions.php, um Methoden hinzuzufügen, mit denen Sie tun können, was Sie möchten, z

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

Das Aufrufen neuer Felder in Themen ist einfach:

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

Weitere Details und Beispiele: http://www.wphub.com/adding-metadata-taxonomy-terms/

Jay
quelle