在文章《为WordPress主题增加幻灯片功能》中提到可以用custom post type制作主题幻灯片功能,一位朋友觉得用custom post type不方便,不能将幻灯片归属到当前网站的分类中,在发布文章时直接将文章推送到幻灯片中展示中更为方便,本文就来介绍实现这种功能的第一种方法,利用post meta box实现。

可用资源

实现这种功能,没有什么新东西,将以前用到的代码重新组装一下就行了。这些方法包括:

为WordPress主题增加幻灯片功能》- 重用其中创建首页幻灯片的脚本的slider.php,更改其中的查询语句即可。

Meta Box vs. Custom Fields》 – 文中介绍了一个可以重用的创建/保存post meta box的代码,只需要用我们要创建的box内容填充$fields数组就行了。

Nivo Slider实例展示》- 内有17款Nivo Slider皮肤,这次换一个皮肤——Theme1204

最后,将幻灯片功能写入twentyeleven的child theme中

创建Post Meta Box

<?php
/* Fire our meta box setup function on the post editor screen. */
add_action( 'load-post.php', 'sola_post_meta_boxes_setup' );
add_action( 'load-post-new.php', 'sola_post_meta_boxes_setup' );
  
/* 这是需要修改的两处之一,本功能只需要一个checkbox,将checkbox的title、id等属性填充到$fields数组中,
后面的代码会自动根据数组填充的内容创建Post Meta Box */
$fields = array(
    array(
        'name' => __('Use as slide'),
        'desc' => 'Check this box and make the post a slider',
        'id' => 'sola-post-slider',
        'type' => 'checkbox',
        'default' => ''
    )
);
/* Meta box setup function. */
function sola_post_meta_boxes_setup() {
  
    /* Add meta boxes on the 'add_meta_boxes' hook. */
    add_action( 'add_meta_boxes', 'sola_add_post_meta_boxes' );
  
    add_action( 'save_post', 'sola_save_post_meta_boxes', 10, 2 );
}
  
/* Create one or more meta boxes to be displayed on the post editor screen. */
/* 这里也需要改一下,设置需要创建的Post Meta Box叫什么名字,显示在什么位置 */
function sola_add_post_meta_boxes() {
  
    add_meta_box(
        'sola-post-slider-class',   // Unique ID
        __('Slideshow'),        // Title
        'sola_seo_box_format',      // Callback function
        'post',             // Admin page (or post type)
        'side',             // Context
        'default'           // Priority
    );
  
}
  
function sola_seo_box_format(){
    global $fields,$post;
  
  // Use nonce for verification
  echo '<input type="hidden" name="sola_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';
  
  echo '<table class="form-table">';
  
  foreach ($fields as $field) {
   // get current post meta data
   $meta = get_post_meta($post->ID, $field['id'], true);
  
   echo '<tr>'.
     '<th><label for="'. $field['id'] .'">'. $field['name']. '</strong></label></th>'.
     '<td>';
   switch ($field['type']) {
    case 'text':
     echo '<input type="text" name="'. $field['id']. '" id="'. $field['id'] .'" value="'. ($meta ? $meta : $field['default']) . '" size="30" style="width:97%" />'. '
'. $field['desc'];
     break;
    case 'textarea':
     echo '<textarea name="'. $field['id']. '" id="'. $field['id']. '" cols="60" rows="4" style="width:97%">'. ($meta ? $meta : $field['default']) . ''. '
'. $field['desc'];
     break;
    case 'select':
     echo '<select name="'. $field['id'] . '" id="'. $field['id'] . '">';
     foreach ($field['options'] as $option) {
      echo '<option '. ( $meta == $option ? ' selected="selected"' : '' ) . '>'. $option . '</option>';
     }
     echo '</select>';
     break;
    case 'radio':
     foreach ($field['options'] as $option) {
      echo '<input type="radio" name="' . $field['id'] . '" value="' . $option['value'] . '"' . ( $meta == $option['value'] ? ' checked="checked"' : '' ) . ' />' . $option['name'];
     }
     break;
    case 'checkbox':
     echo '<input type="checkbox" name="' . $field['id'] . '" id="' . $field['id'] . '"' . ( $meta ? ' checked="checked"' : '' ) . ' />';
     break;
   }
   echo  '<td>'.'</tr>';
  }
  
  echo '</table>';
  
}
  
  
function sola_save_post_meta_boxes($post_id) {
    global $fields, $post;
  
 //Verify nonce
 if (!wp_verify_nonce($_POST['sola_meta_box_nonce'], basename(__FILE__))) {
  return $post_id;
 }
  
 //Check autosave
 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
  return $post_id;
 }
    //Get the post type object.
    $post_type = get_post_type_object( $post->post_type );
 //Check permissions
 if ( !current_user_can( $post_type->cap->edit_post, $post_id ) )
        return $post_id;
  
 foreach ($fields as $field) {
  $old = get_post_meta($post_id, $field['id'], true);
  $new = $_POST[$field['id']];
  
  if ($new && $new != $old) {
   update_post_meta($post_id, $field['id'], $new);
  } elseif ('' == $new && $old) {
   delete_post_meta($post_id, $field['id'], $old);
  }
 }
}
?>

这段代码会在文章创建和编辑页面创建如下所示的Post Meta Box

Slideshow Post Meta Box

写文章时,勾选Use as slide,这篇文章就会自动推送到首页幻灯片中。

读取幻灯片文章

接下来修改slider.php,过去只需要查询custom post type,现在使用post meta box实现,就需要根据post的meta信息搜索幻灯片,代码如下

$args = array(
    'meta_query' => array(
        array(
            'key' => 'sola-post-slider',
            'value' => 'on',
        )
    )
);
$slides = get_posts($args);

用get_posts()和meta_query参数结合,就可以达到目的,有了数据,直接循环输出就行了,最终效果如下

slideshow-based-on-meta-box

源代码下载

这是twentyeleven的child theme,确保安装twentyeleven主题安装的情况下激活此主题,就能看到上图效果

Twentyeleven Child Theme 增加post-meta-box和slideshow 已下载 358 次

Note:使用时需要手动创建特色图像(Featured Image),如果连这个的都想省略的话,参考《自动为WordPress文章设置特色图像》。

16条留言

  1. 博主的代码有点问题,测试发现根本就没有判断表单的值,而是不管有没有勾选都是输出文章到幻灯片

    1. 这段代码是刚学php和wordpress时的学习贴,还望见谅。没有判断请加一个,我当时可能写的蛮吃力的。
      另外这文章有些过时,比如显示幻灯片用wp_query更好些。

    2. 这里说一个我的错误,经过测试,发现博主php并不是没有判断表单值,而是查询语句把返回的文章对象赋值给了变量,使得下面输出的时候就不能个首页一样了,需要修改。不好意思哈

  2. 我按照方法设置了,在后台可以添加幻灯片文章,但是如果勾选幻灯片然后过会再去取消勾选,但是为什么幻灯片还是在呢?是不是说文章一旦添加到幻灯片就不能取消下来?

  3. 能不能把文件分开。详细说明下。我有一个主题想加上幻灯。总报错

    1. 这段代码已经有些过时了,你为什么不用插件呢,比如这个http://wordpress.org/plugins/slideshow-jquery-image-gallery/

  4. 如果可以的话,可以给我您的电邮,我把我简陋的Child Theme发给您帮我看看哪里出了问题?谢谢

    1. 我的电邮就写在右侧边栏里,找找看

  5. 请问为何我的幻灯片可以在本地WAMP中跑,但是放到MediaTemple却又不行?
    我用Twenty Twelve来跑的。服务器并没有给出任何Warning或者Error,真是百思不得其解啊。

    1. 服务器的错误信息一般写在错误日志里,找找服务器根目录有没有errorlog之类的

  6. 我的网站已经恢复了http://www.seo-tmall.com/,请再加上链接吧,美女!~

  7. SolagirL太给力了,谢谢

评论功能已关闭