将页面属性元框和页面模板添加到帖子编辑页面?


14

主持人注意:标题最初是“如何向POSTS编辑器添加“页面属性”和/或“页面属性>模板”选择器”)

WP当前仅允许将“模板”分配给Pages(即post_type=='page'。),我也想将此功能扩展到Posts(即,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以使其使用所选模板。


@Scott B:好吧,我在看到您也正在研究它之前就写下了我的全部答案,看来您朝着与原始问题稍有不同的方向前进,即您没有跟踪,也没有索引选项。希望我所做的仍然对您有价值。如果没有,也许会帮助别人。
MikeSchinkel 2010年

是的,您已经回答了问题。当我意识到我不需要解析目录并且可以为我的特定模板硬编码值时,我确实采取了一些不同的方法。我仍然可能需要借用一些代码来实际获得WP,以使用正确的帖子分配模板。
Scott B 2010年

Answers:


12

讨厌成为坏消息的承担者,但WordPress至少在v3.0 中将页面模板功能硬编码为“页面”帖子类型(在将来的版本中可能会更改,但是我不知道有具体的措施可以更改它)因此,这是我极少数尝试弄清楚如何在不破坏内核的情况下解决问题的机会之一。

我想出的解决方案是基本上从WordPress核心复制相关代码并将其修改为我们的需求。这是步骤(行号来自v3.0.1):

  1. 复制page_attributes_meta_box() 535行功能/wp-admin/includes/meta-boxes.php并进行修改以适合。

  2. 编写一个代码add_meta_boxes钩子,以添加在#1中创建的metabox。

  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挂钩添加metabox :

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()正确地工作,但是无论如何!)的检查。剩下的唯一事情就是更改对该词的引用,pagepost确保以后的维护可读性:

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的操作后,您可以看到“帖子模板”元框出现在帖子编辑器页面上:

添加到WordPress 3.0时的Post Templates Metabox外观
(来源: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

@ sorich87-您知道那句老话:“贪睡,您放松!” 认真地说,只是在开玩笑。实际上只有一种合理的方法可以使它起作用,所以也就不奇怪您的代码会是一样的!
MikeSchinkel 2010年

迈克,你继续惊讶。非常感谢您抽出宝贵的时间解决此问题。
Scott B 2010年

@ sorich87-感谢您的努力。我非常感谢您的努力。
Scott B 2010年

1
@Scott B:没问题,很高兴我能帮上忙。我在寻找合理的通用问题,这些问题可能会帮助很多人,并不仅针对提出问题的人,而且针对可能追随的人回答这些问题。
MikeSchinkel

0

Wordpress允许您使用插件将Meta添加到Category:

为此,您需要添加将元数据添加到类别的各种扩展之一(模仿开箱即用的页面),“ 简单术语元”可以很好地完成这项工作。

注意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/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.