在 WordPress 开发中,我们经常需要根据不同的页面类型(如首页、分类页、标签页、搜索页等)设置不同的每页显示文章数量。这种灵活的设置可以优化用户体验,让不同内容的展示更加合理。
一、为什么要分页面设置文章数量?
- 首页:通常需要展示最新、最重要的内容,数量适中
- 分类页/标签页:特定主题内容,可能需要更多文章展示深度
- 搜索页:搜索结果可能需要更精确的控制
- 自定义页面:根据业务需求特殊设置
二、核心方法:使用 pre_get_posts钩子
WordPress 提供了 pre_get_posts钩子,让我们可以在主查询执行前修改查询参数。
基础实现
/**
* 根据页面类型设置每页文章数量
*/
function custom_posts_per_page($query) {
// 确保只在主查询中修改
if (!is_admin() && $query->is_main_query()) {
// 首页
if ($query->is_home()) {
$query->set('posts_per_page', 6);
}
// 分类页
elseif ($query->is_category()) {
$query->set('posts_per_page', 12);
}
// 标签页
elseif ($query->is_tag()) {
$query->set('posts_per_page', 10);
}
// 搜索页
elseif ($query->is_search()) {
$query->set('posts_per_page', 8);
}
// 作者页
elseif ($query->is_author()) {
$query->set('posts_per_page', 15);
}
// 存档页(按日期)
elseif ($query->is_date()) {
$query->set('posts_per_page', 20);
}
}
}
add_action('pre_get_posts', 'custom_posts_per_page');
三、进阶实现:更精细的控制
1. 根据特定分类设置
function custom_posts_per_page_by_category($query) {
if (!is_admin() && $query->is_main_query()) {
// 针对特定分类
if ($query->is_category('news')) {
$query->set('posts_per_page', 8);
}
// 针对多个分类
elseif ($query->is_category(array('technology', 'web-design'))) {
$query->set('posts_per_page', 10);
}
// 获取当前分类对象
elseif ($query->is_category()) {
$category = get_queried_object();
// 通过分类自定义字段控制
$posts_per_page = get_term_meta($category->term_id, 'posts_per_page', true);
if ($posts_per_page) {
$query->set('posts_per_page', intval($posts_per_page));
} else {
$query->set('posts_per_page', 12); // 默认值
}
}
}
}
add_action('pre_get_posts', 'custom_posts_per_page_by_category');
2. 根据自定义文章类型设置
function custom_posts_per_page_by_post_type($query) {
if (!is_admin() && $query->is_main_query()) {
// 获取当前查询的文章类型
$post_type = $query->get('post_type');
// 如果是数组,取第一个
if (is_array($post_type)) {
$post_type = $post_type[0];
}
switch ($post_type) {
case 'product':
$query->set('posts_per_page', 16);
break;
case 'portfolio':
$query->set('posts_per_page', 9);
break;
case 'event':
$query->set('posts_per_page', 20);
break;
default:
// 使用默认设置
break;
}
}
}
add_action('pre_get_posts', 'custom_posts_per_page_by_post_type');
3. 结合页面模板设置
function custom_posts_per_page_by_template($query) {
if (!is_admin() && $query->is_main_query()) {
// 如果是特定页面模板
if (is_page_template('template-blog-grid.php')) {
$query->set('posts_per_page', 9);
}
elseif (is_page_template('template-blog-masonry.php')) {
$query->set('posts_per_page', 12);
}
elseif (is_page_template('template-blog-list.php')) {
$query->set('posts_per_page', 6);
}
}
}
add_action('pre_get_posts', 'custom_posts_per_page_by_template');
四、主题选项集成
在主题中添加设置选项
/**
* 在主题定制器中添加设置选项
*/
function custom_theme_customizer_settings($wp_customize) {
// 文章数量设置部分
$wp_customize->add_section('posts_per_page_section', array(
'title' => __('每页文章数量', 'text-domain'),
'priority' => 30,
));
// 首页文章数量
$wp_customize->add_setting('posts_per_page_home', array(
'default' => 6,
'sanitize_callback' => 'absint',
));
$wp_customize->add_control('posts_per_page_home', array(
'label' => __('首页文章数量', 'text-domain'),
'section' => 'posts_per_page_section',
'type' => 'number',
'input_attrs' => array(
'min' => 1,
'max' => 50,
'step' => 1,
),
));
// 分类页文章数量
$wp_customize->add_setting('posts_per_page_category', array(
'default' => 12,
'sanitize_callback' => 'absint',
));
$wp_customize->add_control('posts_per_page_category', array(
'label' => __('分类页文章数量', 'text-domain'),
'section' => 'posts_per_page_section',
'type' => 'number',
));
// 标签页文章数量
$wp_customize->add_setting('posts_per_page_tag', array(
'default' => 10,
'sanitize_callback' => 'absint',
));
$wp_customize->add_control('posts_per_page_tag', array(
'label' => __('标签页文章数量', 'text-domain'),
'section' => 'posts_per_page_section',
'type' => 'number',
));
}
add_action('customize_register', 'custom_theme_customizer_settings');
/**
* 应用主题设置
*/
function apply_custom_posts_per_page($query) {
if (!is_admin() && $query->is_main_query()) {
if ($query->is_home()) {
$posts_per_page = get_theme_mod('posts_per_page_home', 6);
$query->set('posts_per_page', $posts_per_page);
}
elseif ($query->is_category()) {
$posts_per_page = get_theme_mod('posts_per_page_category', 12);
$query->set('posts_per_page', $posts_per_page);
}
elseif ($query->is_tag()) {
$posts_per_page = get_theme_mod('posts_per_page_tag', 10);
$query->set('posts_per_page', $posts_per_page);
}
}
}
add_action('pre_get_posts', 'apply_custom_posts_per_page');
五、完整示例代码
/**
* 根据页面类型设置每页文章数量 - 完整实现
*/
class Custom_Posts_Per_Page {
private $default_settings = array(
'home' => 6,
'category' => 12,
'tag' => 10,
'search' => 8,
'author' => 15,
'date' => 20,
);
public function __construct() {
add_action('pre_get_posts', array($this, 'set_posts_per_page'));
add_action('customize_register', array($this, 'add_customizer_settings'));
}
/**
* 设置每页文章数量
*/
public function set_posts_per_page($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
// 从主题设置获取或使用默认值
$posts_per_page = null;
if ($query->is_home()) {
$posts_per_page = get_theme_mod('posts_per_page_home', $this->default_settings['home']);
}
elseif ($query->is_category()) {
$posts_per_page = get_theme_mod('posts_per_page_category', $this->default_settings['category']);
}
elseif ($query->is_tag()) {
$posts_per_page = get_theme_mod('posts_per_page_tag', $this->default_settings['tag']);
}
elseif ($query->is_search()) {
$posts_per_page = get_theme_mod('posts_per_page_search', $this->default_settings['search']);
}
elseif ($query->is_author()) {
$posts_per_page = get_theme_mod('posts_per_page_author', $this->default_settings['author']);
}
elseif ($query->is_date()) {
$posts_per_page = get_theme_mod('posts_per_page_date', $this->default_settings['date']);
}
// 如果有设置,应用到查询
if ($posts_per_page) {
$query->set('posts_per_page', intval($posts_per_page));
}
}
/**
* 添加主题定制器设置
*/
public function add_customizer_settings($wp_customize) {
$wp_customize->add_section('posts_per_page_settings', array(
'title' => __('分页设置', 'text-domain'),
'priority' => 120,
));
$settings = array(
'home' => __('首页', 'text-domain'),
'category' => __('分类页', 'text-domain'),
'tag' => __('标签页', 'text-domain'),
'search' => __('搜索页', 'text-domain'),
'author' => __('作者页', 'text-domain'),
'date' => __('日期存档页', 'text-domain'),
);
foreach ($settings as $key => $label) {
$setting_name = "posts_per_page_{$key}";
$wp_customize->add_setting($setting_name, array(
'default' => $this->default_settings[$key],
'sanitize_callback' => 'absint',
));
$wp_customize->add_control($setting_name, array(
'label' => sprintf(__('%s文章数量', 'text-domain'), $label),
'section' => 'posts_per_page_settings',
'type' => 'number',
'input_attrs' => array(
'min' => 1,
'max' => 100,
'step' => 1,
),
));
}
}
}
// 初始化
new Custom_Posts_Per_Page();
六、最佳实践建议
- 性能考虑:
- 不要设置过大,一般建议不超过20-30篇
- 考虑使用分页加载(Ajax)优化体验
- 响应式设计:
- 可以根据屏幕尺寸动态调整
- 移动端建议显示更少的文章
- 缓存优化:
- 如果使用缓存插件,确保分页设置被正确缓存
- 考虑不同的分页参数可能需要不同的缓存
- SEO优化:
- 保持合理的分页深度
- 确保分页链接可以被搜索引擎抓取
七、常见问题解决
1. 分页链接错误
如果修改了文章数量后分页出现问题,可以重置重写规则:
flush_rewrite_rules();
2. 与插件冲突
某些插件(如WooCommerce、bbPress)可能有自己的分页设置,需要检查插件文档。
3. 自定义查询
对于自定义的WP_Query查询,需要在查询参数中直接设置:
$custom_query = new WP_Query(array(
'post_type' => 'post',
'posts_per_page' => 6,
'category_name' => 'news',
));
总结
通过灵活设置不同页面类型的每页文章数量,可以极大地提升 WordPress 网站的用户体验。建议从实际需求出发,结合网站内容和设计风格,设置最合适的数值。记住,不是越多越好,而是要让用户在有限的内容中获得最佳的浏览体验。


湘公网安备43020002000238