一 基础
1. 让WordPress识别到主题
- 找到主题所在的目录:
wp-content/themes/
,然后新建目录(目录名及主题名)Theme_Dev - 新建
index.php
和style.css
// style.css
/*
Theme Name: Theme_Dev
Theme URI: http://yizihan.github.io
Author: 翌子涵
Author URI: http://yizihan.github.io
Description: 一个基于Bootstrap架构的WordPress主题
Version: 1.0
*/
2. 主题预览图-screenshot.png
将设计图尺寸改为600px*450px并命名screenshot.png,然后保存在Theme_Dev文件夹内
3. 解构模板
首页构成
- index.php
- header.php
- footer.php
4. 在页面模板文件中加载不同部分的模板文件
// index.php
<?php get_header(); ?>
<?php get_sidebar('right'); ?> // 更改载入默认模板
<?php get_footer(); ?>
三 页头
5. 页头部分的模板-header.php
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<!-- language_attributes():根据网站的设置动态的生成语言环境 -->
<head>
<meta <?php bloginfo('charset'); ?>>
<!-- bloginfo('charset'):获取网站的字符集 -->
<title><?php wp_title(); ?></title>
<!-- wp_title():根据不同的页面动态的生成标题 -->
<?php wp_head(); ?>
<!-- wp_head():一般插件向主题头部<head>标签加入CSS和JS文件,都是通过它 -->
<!-- echo get_template_directory_uri():获得主题的位置 -->
<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style.css">
<script src="<?php echo get_template_directory_uri(); ?>/bootstrap/js/bootstrap.js"></script>
<script src="<?php echo get_template_directory_uri(); ?>/js/fenikso.js"></script>
</head>
6.网站标志
<div class="span6">
<!-- esc_url():用于URL过滤,消除无效字符和删除危险字符 -->
<!-- esc_attr_e():显示翻译的文本-->
<a href="<?php echo esc_url(home_url('/')); ?>" title="<?php esc_attr_e('Jump to the front page', 'fenikso'); ?>">
<!-- esc_attr():将 < > & " '(小于号,大于号,&,双引号,单引号)编码,转成HTML实体 -->
<img id="logo" src="<?php echo get_template_directory_uri(); ?>/images/logo.png" alt="<?php echo esc_attr(get_bloginfo('name', 'display')); ?>">
</a>
</div>
7. 搜索框
<div class="span6">
<?php get_search_form(); ?>
</div>
在functions.php文件中,写一个自定义函数,并通过钩子挂载这个函数到get_search_form这个动作钩子。
8. 主题支持定制菜单的功能
注册菜单
register_nav_menu( 'primary', __( 'Primary Menu', 'fenikso' ) );
后台设置菜单分类
使用注册的菜单
<div class="navbar">
<?php wp_nav_menu( array(
'theme_location' => 'primary',// 使用注册的菜单
'menu_class' => 'nav', // 为导航菜单添加nav类
'container' => false,
'walker' => new fenikso_Nav_Walker,
) ); ?>
</div>
四 循环
9. 循环
<?php if(have_posts()) : ?>
<!-- if(have_posts()):判断当前页面是否还有要显示的文章 -->
<?php while(have_posts()) : the_post()?>
<!-- while(have_posts()):重复执行下面的代码 -->
<!-- the_post():准备要显示的文章 -->
<p><?php the_title(); ?></p>
<!-- the_title():模板标签显示文章的标题 -->
<?php endwhile ?>
<?php endif; ?>
10. 条件判断标签
<p>
<!-- in_category():判断文章是否在指定分类内 -->
<?php if(in_category('6')): ?>
<i class="icon-star"></i>
<?php else: ?>
<i class="icon-heart"></i>
<?php endif; ?>
<?php the_title(); ?>
</p>
11. 自定义查询-WP_Query
<?php $myqueryargs = array(
'post_type' => 'post', // 设置显示文章的类型
'posts_per_page' => 5, // 设置每页显示多少条
'orderby' => 'date', // 设置排序
'order' => 'ASC', // 排序方法
'category__in' => array(6,7), // 根据分类限定
); ?>
<?php $myquery = new WP_Query($myqueryargs); ?>
<?php if($myquery -> have_posts()) : ?>
<?php while($myquery -> have_posts()) : $myquery -> the_post()?>
<?php the_title(); ?>
<?php endwhile ?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
五 主体
1. 主内容列表块的设计
<article class="span6">
<div class="media-box">
<?php the_post_thumbnail(); ?>
<!-- the_post_thumbnail():文章缩略图 -->
</div>
<div class="content-box">
<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<!-- the_permalink():文章链接 -->
<!-- the_title():文章标题 -->
<footer class="content-meta">
<span>
<a href="<?php echo esc_url(get_author_posts_url(get_the_author_meta('ID'))) ?>" rel="tooltip" data-placement="left" data-original-title="<?php echo esc_attr(get_the_author()); ?>">
<!-- get_author_posts_url():获取当前作者的所有文章,参数为作者的ID值 -->
<!-- get_the_author_meta():获取作者的ID -->
<?php echo get_avatar(get_the_author_meta('user_email')); ?>
<!-- get_avatar():获取用户的头像,参数是用户的id或email -->
<!-- get_the_author_meta():获取用户信息 -->
</a>
</span>
<time><?php echo get_the_date('Y-m-d'); ?></time>
<!-- get_the_data():获取文章发布日期 -->
<span><?php the_category(' '); ?></span>
<!-- the_category():获取文章的分类,使用'空格'参数分割分类 -->
<div class="btn-group pull-right">
<a href="#" class="btn btn-mini" rel="popover"
data-original-title="<?php esc_attr_e('Summary', 'fenikso') ?>"
data-content="<?php echo esc_attr(get_the_excerpt()) ?>" data-placement="top" data-trigger="hover"><i class="icon-info-sign"></i></a>
<!-- get_the_excerpt():获取文章摘要 -->
<?php comments_popup_link('<i class="icon-comment"></i>','<i class="icon-comment"></i> 1', '<i class="icon-comment"></i> %', 'btn btn-mini') ?>
<!-- comments_popup_link():设置文章评论按钮,并添加评论数和class -->
</div>
</footer>
</div>
</article>
六 分页导航
1. 分页导航按钮
<ul class="pager">
<li class="previous">
<?php previous_posts_link(__('← Previous', 'fenikso')); ?>
</li>
<li class="next">
<?php next_posts_link(__('Next →', 'fenikso')); ?>
</li>
</ul>
2. 面包屑导航
安装Breadcrumb NavXT插件
<?php if(function_exists('bcn_display')) : ?>
<!-- function_exists():判断函数是否存在 -->
<ul class="breadcrumb">
<?php bcn_display(); ?>
<!-- bcn_display():调用Breadcrumb NavXT插件,显示当前页面的导航面包屑 -->
</ul><!-- end .breadcrumb -->
<?php endif; ?>
七 页脚
1. 注册区域来显示小工具
function fenikso_widgets_init(){
register_sidebar(array(
'name' => __('Sidebar Bottom', 'fenikso'), // 小工具名称
'id' => 'sidebar-bottom', // 小工具ID
'description' => __('Sidebar Bottom', 'fenikso'),
'before_widget' => '<div id="%1$s" class="%2$s"><section>', // widget前的包裹标签
'after_widget' => '</section></div>', // widget后的包裹标签
'before_title' => '<h3><span>', // 标题前的包裹标签
'after_title' => '</span></h3>',
));
}
add_action('widgets_init', 'fenikso_widgets_init');
2. 边栏里的小工具的设计
<?php if(is_active_sidebar('sidebar-bottom')) : ?>
<!-- is_active_sidebar():如果有内容发布到sidebar_bottom这个区域上,则显示 -->
<?php dynamic_sidebar('sidebar-bottom'); ?>
<?php endif; ?>
3. 小工具的布局
安装Widget CSS Classes插件,为小工具添加class
4. 页脚
<footer id="footer">
<div class="container">
© <?php echo date('Y'); ?> <?php bloginfo('name'); ?>
</div>
</footer><!-- end #footer -->
<?php wp_footer(); ?>
<!-- 很多插件依靠wp_footer()函数才能起作用,标准的WordPress主题这个函数是不可或缺的 -->
七 文章
1. 文章内容的模板
新建single.php模板
<?php get_header(); ?>
<div id="main-content">
<div class="container">
<div class="row">
<div class="span8"></div>
<div class="span4"></div>
</div>
</div>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
2. 文章内容
<?php if(have_posts()) : ?>
<?php while(have_posts()) : the_post(); ?>
<h1 class="article-title"><?php the_title(); ?></h1>
<!-- the_title():文章标题 -->
<footer class="content-meta">
<time><i class="icon-calendar"></i> <?php the_date(); ?></time>
<!-- the_date():文章发布日期 -->
<span><i class="icon-book"></i> <?php the_category(' '); ?></span>
<!-- the_category():文章所在分类,参数空格为分类之间的连接符 -->
<span><i class="icon-tags"></i> <?php the_tags(' ', ' '); ?></span>
<!-- the_tags():文章标签 -->
<span> <?php comments_popup_link('<i class="icon-comment"></i>', '<i class="icon-comment"></i> 1', '<i class="icon-comment"></i> %') ?></span>
<!-- comments_popup_link():文章评论 -->
</footer>
<div id="content">
<?php the_content(); ?>
</div><!-- end #content -->
<?php endwhile; ?>
<?php endif; ?>
3. 显示文章的自定义字段
<?php fenikso_the_meta(); ?>
<!-- fenikso_the_meta():在the_meta()函数输出自定义字段列表的基础上添加了css类 -->
// functions.php
/*
* 自定义字段列表的显示
*/
function fenikso_the_meta() {
if ( $keys = get_post_custom_keys() ) {
echo "<dl class='dl-horizontal'>\n";
foreach ( (array) $keys as $key ) {
$keyt = trim($key);
if ( is_protected_meta( $keyt, 'post' ) )
continue;
$values = array_map('trim', get_post_custom_values($key));
$value = implode($values,', ');
echo apply_filters('the_meta_key', "<dt>$key</dt><dd>$value</dd>\n", $key, $value);
}
echo "</dl>\n";
}
}
4. 文章的导航
<ul class="pager">
<li class="previous">
<?php previous_post_link('%link', '←' . '%title'); ?>
<!-- previous_post_link():上一篇文章 -->
<!-- %link:目标文章的链接 -->
<!-- %title:目标文章的标题 -->
</li>
<li class="next">
<?php next_post_link('%link', '%title' . '→'); ?>
<!-- next_post_link():下一篇文章 -->
</li>
</ul><!-- end .pager -->
八 评论
1. 评论的模板
新建comments.php文件,并在需要的地方使用comments_template();
引入
// comments.php
<section id="comments">
<h2>
<?php printf(
// _n():用来进行单复数编译的,常见于WordPress的评论功能模块,用来区分一条或多条评论
_n('“ %2$s ” comment %1$s',
'“ %2$s ” comments %1$s',
'fenikso'),
'<span class="badge badge-important">' . get_comments_number() . '</span>',
// 返回留言的数量
get_the_title()
// 文章的标题
); ?>
</h2>
<!-- wp_list_comments():循环输出当前文章或页面每个评论的函数 -->
<?php wp_list_comments(array(
'avatar_size' => 64,
)); ?>
</section>
2. 重新设计评论列表
定义fenikso_comment()函数,并设置评论显示的格式
// functions.php => fenikso_comment();
/*
* 评论列表的显示
*/
if ( ! function_exists( 'fenikso_comment' ) ) :
function fenikso_comment( $comment, $args, $depth ) {
$GLOBALS['comment'] = $comment;
switch ( $comment->comment_type ) :
case 'pingback' :
case 'trackback' :
// 用不同于其它评论的方式显示 trackbacks 。
?>
<li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
<p><?php _e( 'Pingback:', 'fenikso' ); ?> <?php comment_author_link(); ?> <?php edit_comment_link( __( '(Edit)', 'fenikso' ), '<span class="edit-link">', '</span>' ); ?>
</p>
<?php
break;
default :
// 开始正常的评论
global $post;
?>
<li <?php comment_class(); ?> id="li-comment-<?php comment_ID(); ?>">
<article id="comment-<?php comment_ID(); ?>" class="media comment">
<div class="pull-left">
<?php // 显示评论作者头像
echo get_avatar( $comment, 64 );
?>
</div>
<?php // 未审核的评论显示一行提示文字
if ( '0' == $comment->comment_approved ) : ?>
<p class="comment-awaiting-moderation">
<?php _e( 'Your comment is awaiting moderation.', 'fenikso' ); ?>
</p>
<?php endif; ?>
<div class="media-body">
<h4 class="media-heading">
<?php // 显示评论作者名称
printf( '%1$s %2$s',
get_comment_author_link(),
// 如果当前文章的作者也是这个评论的作者,那么会出现一个标签提示。
( $comment->user_id === $post->post_author ) ? '<span class="label label-info"> ' . __( 'Post author', 'fenikso' ) . '</span>' : ''
);
?>
<small>
<?php // 显示评论的发布时间
printf( '<a href="%1$s"><time datetime="%2$s">%3$s</time></a>',
esc_url( get_comment_link( $comment->comment_ID ) ),
get_comment_time( 'c' ),
// 翻译: 1: 日期, 2: 时间
sprintf( __( '%1$s %2$s', 'fenikso' ), get_comment_date(), get_comment_time() )
);
?>
</small>
</h4>
<?php // 显示评论内容
comment_text();
?>
<?php // 显示评论的编辑链接
edit_comment_link( __( 'Edit', 'fenikso' ), '<p class="edit-link">', '</p>' );
?>
<div class="reply">
<?php // 显示评论的回复链接
comment_reply_link( array_merge( $args, array(
'reply_text' => __( 'Reply', 'fenikso' ),
'after' => ' <span>↓</span>',
'depth' => $depth,
'max_depth' => $args['max_depth'] ) ) );
?>
</div>
</div>
</article>
<?php
break;
endswitch; // end comment_type check
}
endif;
// comments.php
<!-- wp_list_comments():循环输出当前文章或页面每个评论的函数 -->
<ol>
<?php wp_list_comments(array(
'callback' => 'fenikso_comment',
)); ?>
</ol>
3. 添加评论的表单
建立评论分页
<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : ?>
<!-- 满足两个条件,评论个数大于一个且设置了分页数量 -->
<ul class="pager">
<li class="previous">
<?php previous_comments_link( __( '← Older Comments', 'fenikso' ) ); ?>
<!-- 上一页评论 -->
</li>
<li class="next">
<?php next_comments_link( __( 'Newer Comments →', 'fenikso' ) ); ?>
<!-- 下一页评论 -->
</li>
</ul>
<?php endif; ?>
评论的参数
<?php
$comment_form_args = array(
// 添加评论内容的文本域表单元素
'comment_field' => '<label for="comment" class="control-label">' .
_x( 'Comment', 'noun' ) .
'</label>
<textarea id="comment" name="comment" cols="45" rows="5" class="span8" aria-required="true"></textarea>',
// 评论之前的提示内容
'comment_notes_before' => ' ',
// 评论之后的提示内容
'comment_notes_after' => ' ',
// 默认的字段,用户未登录时显示的评论字段
'fields' => apply_filters( 'comment_form_default_fields', array(
// 作者名称字段
'author' => '<label for="author" class="control-label">' .
__( 'Name', 'fenikso' ) .
'</label> ' .
'<div class="controls">' .
'<input id="author" name="author" type="text" value="' .
esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . ' />' .
( $req ? '<span class="required help-inline">*</span>' : '' ) .
'</div>',
// 电子邮件字段
'email' => '<label for="email" class="control-label">' .
__( 'Email', 'fenikso' ) .
'</label> ' .
'<div class="controls">' .
'<input id="email" name="email" type="text" value="' .
esc_attr( $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . ' />' .
( $req ? '<span class="required help-inline">*</span>' : '' ) .
'</div>',
// 网站地址字段
'url' => '<label for="url" class="control-label">' .
__( 'Website', 'fenikso' ) .
'</label>' .
'<div class="controls">' .
'<input id="url" name="url" type="text" value="' .
esc_attr( $commenter['comment_author_url'] ) . '" size="30" /></div>' )
) );
?>
调用comment_form(),并传入参数
<?php comment_form($comment_form_args); ?>
点击回复时移动回复框
// functions.php
/*
* 脚本与样式
*/
function fenikso_scripts_styles() {
global $wp_styles;
// 需要时加载回复评论的脚本文件
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) )
wp_enqueue_script( 'comment-reply' );
}
add_action( 'wp_enqueue_scripts', 'fenikso_scripts_styles' );
九 右边栏
1. 右边栏
注册右边栏
// functions.php
function fenikso_widgets_init(){
// 注册右边栏小工具
register_sidebar(array(
'name' => __('Sidebar Right', 'fenikso'), // 小工具名称
'id' => 'sidebar-right', // 小工具ID
'description' => __('Sidebar Right', 'fenikso'),
'before_widget' => '<div id="%1$s" class="%2$s"><section>', // widget前的包裹标签
'after_widget' => '</section></div>', // widget后的包裹标签
'before_title' => '<div class="title-line"><h3>', // 标题前的包裹标签
'after_title' => '</h3></div>',
));
}
add_action('widgets_init', 'fenikso_widgets_init');
新建右边栏文件sidebar-right.php
<div class="span4">
<aside id="sidebar-right">
<?php if(is_active_sidebar('sidebar-right')) : ?>
<!-- is_active_sidebar():如果有内容发布到sidebar-right这个区域上,则显示 -->
<?php dynamic_sidebar('sidebar-right'); ?>
<?php endif; ?>
</aside>
</div>
十 页面
1. 图像附件页面的模板-image.php
2. 页面内容的模板-page.php
新建full-page.php
<?php
/*
* Template Name: Full Width // 让WordPress识别模板
*/
?>
// 宽屏模板
<?php get_header(); ?>
<div id="main-content">
<div class="container">
<?php if(have_posts()) : ?>
<?php while(have_posts()) : the_post(); ?>
<!-- the_title():文章标题 -->
<h1 class="article-title"><?php the_title(); ?></h1>
<!-- 文章主体内容 -->
<div id="content">
<?php the_content(); ?>
</div><!-- end #content -->
<!-- 面包屑导航 -->
<?php if(function_exists('bcn_display')) : ?>
<!-- function_exists():判断函数是否存在 -->
<ul class="breadcrumb">
<?php bcn_display(); ?>
<!-- bcn_display():显示当前页面的导航面包屑 -->
</ul><!-- end .breadcrumb -->
<?php endif; ?>
<!-- 评论模块 -->
<?php comments_template(); ?>
<?php endwhile; ?>
<?php endif; ?>
</div>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
3. 归档页面的模板-archive.php
新建archive.php文件并使用index.php文件代码
// 按照不同的分类特征进行分类归档
<h4 class="archives-title">
<?php
/* 查询第一个文章,这样我们就知道整个页面的作者是谁。
* 在下面我们使用 rewind_posts() 重置了一下,这样一会儿我们才能正确运行循环。
*/
the_post();
?>
<?php
if ( is_day() ) :
printf( __( 'Daily Archives: %s', 'fenikso' ), '<span>' . get_the_date() . '</span>' );
elseif ( is_month() ) :
printf( __( 'Monthly Archives: %s', 'fenikso' ), '<span>' . get_the_date( _x( 'F Y', 'monthly archives date format', 'fenikso' ) ) . '</span>' );
elseif ( is_year() ) :
printf( __( 'Yearly Archives: %s', 'fenikso' ), '<span>' . get_the_date( _x( 'Y', 'yearly archives date format', 'fenikso' ) ) . '</span>' );
elseif ( is_category() ) :
printf( __( 'Category Archives: %s', 'fenikso' ), '<span>' . single_cat_title( '', false ) . '</span>' );
elseif ( is_tag() ) :
printf( __( 'Tag Archives: %s', 'fenikso' ), '<span>' . single_tag_title( '', false ) . '</span>' );
elseif ( is_author() ) :
printf( __( 'Author Archives: %s', 'fenikso' ), '<span>' . get_the_author() . '</span>' );
else :
_e( 'Archives', 'fenikso' );
endif;
?>
<?php
/* 把循环恢复到开始,
* 这样下面的循环才能正常运行。
*/
rewind_posts();
?>
</h4>
3. 搜索结果模板-search.php
新建search.php文件
<?php printf( __( 'Search Results for: %s', 'fenikso' ), '<span>' . get_search_query() . '</span>' ); ?>
十 结尾
1. 激活菜单项
安装Context Manager插件并创建规则
When these conditions match : in_category(7)&& is_single()
Apply this rule : Emulate current page as a child but do not create a menu item.
To these menu items : 真实婚礼
2. 最后整理
// 为文章和评论在 <head> 标签上添加 RSS feed 链接。
add_theme_support( 'automatic-feed-links' );
// 主题支持的文章格式形式。
// add_theme_support( 'post-formats', array( 'aside', 'image', 'link', 'quote', 'status' ) );
// 主题为特色图像使用自定义图像尺寸,显示在 '标签' 形式的文章上。
add_theme_support( 'post-thumbnails' );
set_post_thumbnail_size( 650, 9999 );
翻译定义字符
安装插件Codestyling Localization(失败)