Добавление атрибутов страницы Metabox и шаблонов страниц на страницу редактирования сообщений?


14

( Примечание модераторов: заголовок изначально был «Как добавить селектор« Атрибуты страницы »и / или« Атрибуты страницы> Шаблон »в редактор POSTS»)

В настоящее время WP разрешает присваивать «шаблоны» только страницам (т post_type=='page'. Е. ). Я бы хотел расширить эту функциональность и на посты (т post_type=='post'. Е. )

Как добавить мета-поле «Атрибуты страницы» и, в частности, переключатель шаблонов в редактор сообщений?

Я предполагаю, что это код, который я добавлю в functions.phpмою тему.

ОБНОВЛЕНИЕ: мне удалось добавить выпадающее меню жестко запрограммированных шаблонов в мой редактор сообщений, просто добавив html окна выбора в существующее поле пользовательских мета-параметров. Вот код, который я использую для этого ...

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

А вот функция, которая записывает параметры и поле выбора шаблона ...

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

И, наконец, код для захвата выбранных значений при сохранении ...

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

Теперь я считаю, что осталось только (1) захватить выбранный шаблон и добавить его к мета поста для этого поста и (2) изменить index.php и single.php, чтобы он использовал выбранный шаблон.


@ Скотт Б : Ну, я написал весь свой ответ прежде, чем увидел, что вы тоже над ним работали, и, кажется, вы взяли его в несколько ином направлении, чем ваш первоначальный вопрос, в котором нет подписки и вариантов индекса. Надеюсь, то, что я сделал, все еще имеет ценность для тебя. Если нет, возможно, это поможет другим.
— MikeSchinkel

Да, вы ответили на вопрос. Я сделал несколько иной шаг, когда понял, что мне не нужно анализировать каталог и могу жестко закодировать значения для моих конкретных шаблонов. Мне все еще, вероятно, придется позаимствовать часть вашего кода для того, чтобы заставить WP использовать правильный назначенный шаблон для поста.
— Скотт Б

Ответы:


12

Ненавижу быть носителем плохих новостей, но WordPress жестко кодирует функциональность шаблона страницы в тип публикации "страница" , по крайней мере, в версии 3.0 (это может измениться в будущих версиях, но я не знаю какой-либо конкретной инициативы по ее изменению). пока что. Так что это один из немногих случаев, когда я пытаюсь понять, как обойти что-то без взлома ядра.)

Решение, которое я придумала, заключается в том, чтобы в основном скопировать соответствующий код из ядра WordPress и модифицировать его для наших нужд. Вот шаги (номера строк взяты из версии 3.0.1):

  1. Скопируйте page_attributes_meta_box()функцию из строки 535 /wp-admin/includes/meta-boxes.phpи измените ее в соответствии с требованиями.

  2. Кодекс add_meta_boxesхук, чтобы добавить метабокс, созданный в # 1.

  3. Скопируйте get_page_templates()функцию из строки 166 /wp-admin/includes/theme.php и измените ее в соответствии с требованиями.

  4. Скопируйте page_template_dropdown()функцию из строки 2550 /wp-admin/includes/template.phpи измените ее в соответствии с требованиями.

  5. Добавьте шаблон сообщения в вашу тему.

  6. Код save_postхук, чтобы включить сохранение имени файла шаблона поста при сохранении.

  7. Код single_templateхук, чтобы разрешить загрузку шаблона сообщения для связанных сообщений.

Теперь с этим!


1. Скопируйте page_attributes_meta_box()функцию

В качестве первого шага вам нужно скопировать page_attributes_meta_box()функцию из строки 535, /wp-admin/includes/meta-boxes.phpи я решил переименовать ее post_template_meta_box(). Поскольку вы запрашивали только шаблоны страниц, я пропустил код для указания родительского поста и для определения порядка, который делает код намного проще. Я также решил использовать postmeta для этого, а не пытаться повторно использовать page_templateсвойство объекта, чтобы избежать и потенциальных несовместимостей, вызванных непреднамеренной связью. Итак, вот код:

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. Код add_meta_boxesкрючок

Следующим шагом является добавление метабокса с помощью add_meta_boxesхука:

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. Скопируйте get_page_templates()функцию

Я предположил, что будет иметь смысл только различать шаблоны страниц и шаблоны сообщений, таким образом, необходимость в get_post_templates()функции, основанной на get_page_templates()строке 166 /wp-admin/includes/theme.php. Но вместо использования Template Name:маркера, какие шаблоны страниц используют эту функцию, Post Template:вместо этого используется маркер, который вы можете увидеть ниже.

Я также отфильтровываюсь осмотр functions.php (не знаю , как get_page_templates()никогда правильно работали без этого, но что угодно!) И единственное , что осталось сделать ссылки изменения на слово pageк postдля обслуживания читаемости вниз по дороге:

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. Скопируйте page_template_dropdown()функцию

Аналогично скопируйте page_template_dropdown()строку 2550 /wp-admin/includes/template.phpдля создания post_template_dropdown()и просто измените ее на вызов get_post_templates()вместо этого:

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. Добавить шаблон сообщения

Следующим шагом является добавление шаблона сообщения для тестирования. Используя Post Template:маркер, упомянутый в шаге 3, скопируйте single.phpиз своей темы single-test.phpи добавьте следующий заголовок комментария ( обязательно измените что-то, single-test.phpчтобы вы могли сказать, что он загружается вместо single.php) :

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

После того, как вы сделали шаги с 1 по 5, вы можете увидеть, что ваше метабокс «Шаблоны сообщений» появится на странице вашего редактора сообщений:

Как выглядел Metabox пост-шаблонов при добавлении в WordPress 3.0
(источник: mikeschinkel.com )

6. Код save_postкрючка

Теперь, когда у вас есть редактор, вы должны сохранить имя файла шаблона страницы в postmeta, когда пользователь нажимает «Опубликовать». Вот код для этого:

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. Код single_templateкрючок

И, наконец, вам нужно заставить WordPress использовать ваши новые шаблоны сообщений. Вы делаете это, перехватывая single_templateи возвращая желаемое имя шаблона для тех сообщений, которым назначен один:

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

И это все!

Примечание , что я не принимать во внимание ТАМОЖЕННЫЙ ПОСТ типы , только post_type=='post'. По моему мнению, обращение к пользовательским типам постов потребовало бы разграничения между разными типами постов, и, хотя это было не слишком сложно, я не пытался сделать это здесь.


Большой! Я пошел спать с почти полным кодом в моем редакторе с тем же подходом копирования функций WordPress по умолчанию (это было завершено, но я не буду публиковать его, так как я не тестировал). :)
— sorich87 11.10.10

@ sorich87 - Вы знаете старую поговорку: «Вы дремлет, вы потеряете! Если серьезно, ТОЛЬКО шучу. На самом деле есть только один разумный способ заставить его работать, поэтому не удивительно, что ваш код будет таким же!
— MikeSchinkel

Майк, ты продолжаешь удивлять. Большое спасибо, что нашли время, чтобы выработать это.
— Скотт Б

@ sorich87 - Спасибо за работу над этим. Я действительно ценю усилия.
— Скотт Б

1
@ Скотт Б : Нет проблем, рад, что смог помочь. Я ищу достаточно общие вопросы, которые потенциально могут помочь многим людям, и пытаюсь ответить на них не только для человека, задающего вопрос, но и для тех, кто может прийти после.
— MikeSchinkel

0

Wordpress позволяет добавлять Meta к категориям с помощью плагина:

Для этого вам нужно добавить одно из различных расширений, которое добавляет мета к категориям (имитируя, какие страницы выходят из коробки), Simple Term Meta прекрасно справляется со своей задачей.

NB WordPress 3.x необходим для расширения категорий.

После этого вы можете использовать:

  • add_term_meta
  • update_term_meta
  • get_term_meta

Используйте Functions.php для добавления методов, чтобы делать то, что вы хотите, например

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

Называть новые поля в темах легко:

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

Более подробная информация и примеры: http://www.wphub.com/adding-metadata-taxonomy-terms/

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.