鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > cms安装教程 > WordPress > >

WordPress 的文章导航

来源:互联网 作者:佚名 时间:2015-10-18 05:56
文章 导航 是什么? 一个外国朋友告诉我, 他们管它叫 Breadcrumb trail 或者 Breadcrumb navigation, 翻译过来就是 文章 导航 或者 文章 路径, 对吧? 具体叫什么我真不确定, 或者看看下面的截图你就会知道我在说什么了. 这个友好的 导航 功能, 我最先是在论坛

文章导航是什么? 一个外国朋友告诉我, 他们管它叫 Breadcrumb trail 或者 Breadcrumb navigation, 翻译过来就是文章导航或者文章路径, 对吧? 具体叫什么我真不确定, 或者看看下面的截图你就会知道我在说什么了.

WordPress 的面包屑

这个友好的导航功能, 我最先是在论坛上看到的, 形式一般如下:
首页 > 模块 > 文章

有了它, 访客就可以方便地访问同类的文章, 并明确文章的所属, 对提高用户体验和网站的 PV 值都很有帮助. 我在制作 iNove 主题的时候也加上了这个功能, 但是只能处理子分类, 形式如下:
首页 > 分类 > 文章

最近我在制作一个主题, 客户要求能实现多层次的文章导航, 形式如下:
首页 > 分类 > 子分类 > 第二层子分类 > ... > 第 N 层子分类 > 文章

一般我们会在 the_post() 后面调用 the_category() 生成分类内容. 为此我翻了一下 WordPress 的源代码, 发现 the_category() 方法可能会用到 category-template.php 文件里的另两个方法. 下面我将以注释的形式讲解一下这两个方法, 如发现误解之处, 请指正.

获取父级分类 get_category_parents

/**
 * 获取父级分类 (包含分隔符).
 *
 * @since 1.2.0
 *
 * @param int $id 分类 ID.
 * @param bool $link 默认为 false, 为真时返回的分类包含链接.
 * @param string $separator 分类间分隔符, 默认是 '/'.
 * @param bool $nicename 默认为 false, 为真时返回分类显示为分类别名, 否则显示分类名.
 * @param array $visited 防止分类重复显示 (调用该方法时请不用理会这个参数, 本人认为这只是为了顺利完成迭代处理).
 * @return string
 */
function get_category_parents( $id, $link = false, $separator = '/', $nicename = false, $visited = array() ) {
	// 准备返回的 HTML 字符串
	$chain = '';
 
	// 通过 ID 获取分类
	$parent = &get_category( $id );
 
	// 如果该分类已经定义过, 立即返回
	if ( is_wp_error( $parent ) )
		return $parent;
 
	// 以分类别名或者分类名作为分类链接的显示文本
	if ( $nicename )
		$name = $parent->slug;
	else
		$name = $parent->cat_name;
 
	// 如果该分类还有父分类, 分类不是连向自己, 并且还没有处理过
	if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {
		// 把当前分类的父分类添加到已处理的数组中, 避免以后被重复处理
		$visited[] = $parent->parent;
		// 迭代处理父分类
		$chain .= get_category_parents( $parent->parent, $link, $separator, $nicename, $visited );
	}
 
	// 以链接或者文本形式 (包含分隔符) 将分类拼接到准备返回的 HTML 字符串中
	if ( $link )
		$chain .= '<a href="' . get_category_link( $parent->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $parent->cat_name ) . '">'.$name.'</a>' . $separator;
	else
		$chain .= $name.$separator;
 
	// 返回 HTML 字符串 (结果)
	return $chain;
}

获取父级分类 get_the_category_list

/**
 * 获取分类列表, 并以 HTML 列表方式或者自定义格式返回.
 *
 * @since 1.5.1
 *
 * @param string $separator 默认为空, 显示在各分类之间的分隔符.
 * @param string $parents 指示如何显示父级的分类.
 * @param int $post_id 获取某一文章 ID 对应的分类.
 * @return string
 */
function get_the_category_list( $separator = '', $parents='', $post_id = false ) {
	global $wp_rewrite;
 
	// 找到当前文章对应的分类 (数组, 因为文章可以属于多个分类)
	$categories = get_the_category( $post_id );
 
	// 如果分类数组为空, 在 the_category 方法中当作 '未分类' 进行处理
	if ( empty( $categories ) )
		return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents );
 
	$rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
 
	// 准备返回的 HTML 字符串
	$thelist = '';
 
	// 如果分隔符为空, 返回分类的 HTML 列表
	if ( '' == $separator ) {
		// 列表的开头, 是一个 unordered list
		$thelist .= '<ul class="post-categories">';
 
		// 循环处理所有分类
		foreach ( $categories as $category ) {
			// 每个分类项的开头
			$thelist .= "\n\t<li>";
			switch ( strtolower( $parents ) ) {
 
				// 如果以 'multiple' 模式显示父分类, 每层的分类会独立成一个链接
				case 'multiple':
					// 父分类存在的话, 获取父分类的 HTML 代码并拼接到准备输出的 HTML 字符串中
					if ( $category->parent )
						$thelist .= get_category_parents( $category->parent, true, $separator );
					// 最后把当前分类的 HTML 代码和分类也拼接到准备输出的 HTML 字符串中
					$thelist .= '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . $rel . '>' . $category->name.'</a></li>';
					break;
 
				// 如果以 'single' 模式显示父分类, 所有分类作为一个链接
				case 'single':
					// 链接的开头
					$thelist .= '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . $rel . '>';
					// 父分类存在的话, 获取父分类的 HTML 代码并拼接到准备输出的 HTML 字符串中
					if ( $category->parent )
						$thelist .= get_category_parents( $category->parent, false, $separator );
					// 当然分类的名字和链接的结尾
					$thelist .= $category->name.'</a></li>';
					break;
 
				// 如果以默认模式显示父分类, 即不显示父分类
				case '':
				default:
					$thelist .= '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . $rel . '>' . $category->cat_name.'</a></li>';
			}
		}
 
		// 列表的结尾
		$thelist .= '</ul>';
 
	// 如果分隔符不为空, 返回一段格式化的 HTML
	} else {
		// 计数器
		$i = 0;
 
		// 循环处理所有分类
		foreach ( $categories as $category ) {
			// 第一个分类的前面不显示分隔符
			if ( 0 < $i )
				$thelist .= $separator . ' ';
			switch ( strtolower( $parents ) ) {
 
				// 如果以 'multiple' 模式显示父分类, 每层的分类会独立成一个链接
				case 'multiple':
					if ( $category->parent )
						$thelist .= get_category_parents( $category->parent, true, $separator );
					$thelist .= '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . $rel . '>' . $category->cat_name.'</a>';
					break;
 
				// 如果以 'single' 模式显示父分类, 所有分类作为一个链接
				case 'single':
					$thelist .= '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . $rel . '>';
					if ( $category->parent )
						$thelist .= get_category_parents( $category->parent, false, $separator );
					$thelist .= "$category->cat_name</a>";
					break;
				case '':
 
				// 如果以默认模式显示父分类, 即不显示父分类
				default:
					$thelist .= '<a href="' . get_category_link( $category->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $category->name ) . '" ' . $rel . '>' . $category->name.'</a>';
			}
 
			// 计数器自增
			++$i;
		}
	}
 
	return apply_filters( 'the_category', $thelist, $separator, $parents );
}

在主题中加入文章导航

1. 不包含父级分类的文章导航
这里用到 the_category() 方法的默认模式, 会调用 get_the_category_list() 生成最后一层的子分类 (分类可能不只一个) 组成的 HTML 字符串并打印到页面上. 代码如下:

<a title="Go to homepage" href="<?php echo get_settings('home'); ?>/">Home</a> <!-- 首页链接 -->
 &gt; <?php the_category(', '); ?> <!-- 每个分类以逗号分隔 -->
 &gt; <?php the_title(); ?> <!-- 文章链接 -->

2. 包含父级分类的文章导航
我们要用的是 the_category() 方法的 multiple 模式, 而他会调用 get_the_category_list()get_category_parents() 两个方法生成一个包含所有父分类的 HTML 字符串并打印到页面上. 代码如下:

<a title="Go to homepage" href="<?php echo get_settings('home'); ?>/">Home</a> <!-- 首页链接 -->
 &gt; <?php the_category(' &gt; ', 'multiple'); ?> <!-- 每个分类以 > 分隔, 父级分类在前, 子分类在后 -->
 &gt; <?php the_title(); ?> <!-- 文章链接 -->

当然, 只要你愿意, 可以将这段代码取代 iNove 主题里 single.php 文件的 id="postpath" 部分, 我并不准备在以后版本的 iNove 主题中使用这个多级的文章导航.

网友评论
<