前言
默认情况下,一为导航只会展示按发布时间降序的数篇公告,而不会判断 Polylang 所带来的语言。
通过修改原文件实现只展示该语言下的最新公告。
标题中的 适配 并非将主题与插件结合,而是通过一些理念的融合、代码的修改使整站的国际化更彻底。
实现流程
一、修改 templates/bulletin.php
OneNav 主题中公告对应的关键词是 bulletin。
首页的公告模块是 templates/bulletin.php,核心代码在这里:
<div class="carousel-inner" role="listbox">
<?php
$args = array(
'post_type' => 'bulletin',
'posts_per_page' => io_get_option('bulletin_n',5)
);
$i = 0;
$the_query = new WP_Query($args);
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<?php
if(get_post_meta(get_the_ID(),'_goto',true)){
the_title( sprintf( '<div class="carousel-item %s"><a class="overflowClip_1" href="%s" target="_blank" rel="bulletin noreferrer noopener%s">',$i==0?'active':'', esc_url( get_permalink() ),get_post_meta(get_the_ID(),'_nofollow',true)?' external nofollow':'' ), ' ('. get_the_time('m/d').')</a></div>' );
}else{
the_title( sprintf( '<div class="carousel-item %s"><a class="overflowClip_1" href="%s" rel="bulletin">',$i==0?'active':'', esc_url( get_permalink() ) ), ' ('. get_the_time('m/d').')</a></div>' );
}
?>
<?php $i ++; endwhile; ?>
<?php wp_reset_postdata(); ?>
</div>
首先明确下 WP_Query、have_posts() 和 the_post() 在 WordPress 中的作用:
WP_Query:是一个类,用于自定义查询 WordPress 数据库中的帖子。
通过创建 WP_Query 对象,可以根据特定的参数(如分类、标签、作者等)获取特定的帖子集合。<?php $query = new WP_Query(array( 'category_name' => 'news', 'posts_per_page' => 5 ));have_posts():是一个方法,用于检查当前查询是否有更多的帖子可供循环处理,通常与while循环一起使用。the_post():也是一个方法,用于设置当前帖子数据。
每次调用the_post()时,WordPress 会将全局$post对象设置为当前循环中的帖子,并准备好模板标签(如the_title、the_content)以显示该帖子的内容。
现在就好理解了,上述代码是通过 'post_type' => 'bulletin' 和 'posts_per_page' => io_get_option('bulletin_n',5) 这两个参数找文章,然后进行显示。
那我们只需要先拿到当前的语言,然后作为查询参数一起传到后端即可。
而 Polylang 就提供获取当前语言的方法 pll_current_language:
官方文档:pll_current_language
pll_current_language( $value );
参数默认为 slug,参数和返回值如下:
slug:返回当前语言代码,如1。name:返回当前语言名称,如中文。locale:返回当前语言的标识,如zh_CN。
于是修改下核心部分的代码:
<div class="carousel-inner" role="listbox">
<?php
$args = array(
'post_type' => 'bulletin',
'posts_per_page' => io_get_option('bulletin_n',5)
);
# 2024/10/18 Rabbir add start
# 1. 判断是否有多语言插件
if (function_exists('pll_current_language')):
# 2. 通过 pll_current_language() 获取当前语言的表示 locale
$language_locale_for_bulletin_search = pll_current_language("locale");
# 3. 新增检索条件:meta_key = "onenav_bulletin_language_locale" & meta_value = $language_locale_for_bulletin_search
$meta_args = array(
'meta_query' => array(
array(
'key' => 'onenav_bulletin_language_locale',
'value' => $language_locale_for_bulletin_search,
'compare' => '='
)
)
);
# 4. 将 meta_query 添加到 $args 中
$args = array_merge($args, $meta_args);
endif;
# 2024/10/18 Rabbir add end
$i = 0;
$the_query = new WP_Query($args);
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<?php
if(get_post_meta(get_the_ID(),'_goto',true)){
the_title( sprintf( '<div class="carousel-item %s"><a class="overflowClip_1" href="%s" target="_blank" rel="bulletin noreferrer noopener%s">',$i==0?'active':'', esc_url( get_permalink() ),get_post_meta(get_the_ID(),'_nofollow',true)?' external nofollow':'' ), ' ('. get_the_time('m/d').')</a></div>' );
}else{
the_title( sprintf( '<div class="carousel-item %s"><a class="overflowClip_1" href="%s" rel="bulletin">',$i==0?'active':'', esc_url( get_permalink() ) ), ' ('. get_the_time('m/d').')</a></div>' );
}
?>
<?php $i ++; endwhile; ?>
<?php wp_reset_postdata(); ?>
</div>
之后重新打包并更新主题。
二、确认各语言下 locale 的值

| 语言 | slug | name | locale |
|---|---|---|---|
| 英文 | en | English | en_US |
| 中文 | zh | 中文 (中国) | zh_CN |
| 日语 | ja | 日本語 | ja |
三、测试添加公告
1、中文
中文模式下暂时没有公告:

为既有的公告添加一条自定义字段:

回到首页就能看到公告了:


2、英文
英文模式下也暂时没有公告:

发布公告的同时添加下字段:

回到首页就能看到公告了:

在详情页面发生了 404 错误,大概率是 en/ 路径导致的:

将路径从
https://test.steam.cash/en/bulletin/45.html修改为https://test.steam.cash/bulletin/45.html之后,果然页面出现了:
3、日语
日语模式下就不测了,肯定会和英语出现一样的问题。
四、修复非默认语言公告详情 404 的问题
由于非默认语言会在路径中携带 en/ 或 jp/ 等语言标识,因此会导致 OneNav 找不到对应的公告出现 404 错误。
同样的问题也会出现了 网址 详情页中。
这里使用最简单也是最彻底的方式,正则匹配路径并将 ^/en/(.*)/(.*) 和 ^/jp/(.*)/(.*) 路径全部 302 到 /$1/$2 下。
需要使用到 Wordpress 的插件 Redirection:

安装并启用后,在 工具 -> Redirections 中配置重定向规则:

- 原始 URL:
^/en/(.*)/(.*)(在右侧勾上正则表达式) - 匹配:
匹配 URL - 302 重定向到
- 目标 URL:
/$1/$2
其他语言的重定向,参数与英文一样,只是将
en替换为ja等。
之后保存,再去首页检查就可以发现详情页和网站都正常了:

顺便介绍下 301 和 302 重定向的区别:
301重定向:永久重定向,浏览器会缓存。
> 如果是永久重定向那么浏览器客户端就会缓存此次重定向结果,下次如果有请求则直接从缓存读取,譬如我们切换域名,将所有老域名的流量转入新域名,可以使用永久重定向。302重定向:临时重定向,浏览器不缓存。
> 如果只是临时重定向那么浏览器则不会缓存,譬如我们的服务临时升级,会使用临时重定向。
而关于 301 和 302 的区别,Google 的人员是这么说的:
当我们识别到一个重定向并看到它是 302 时,我们首先假定它是一个临时重定向,并假定你想要为初始 URL 编制索引,而不是为了重定向。 […] 然而,当我们意识到它实际上更像是一个永久重定向,302 可能是你不小心设置的,那么我们会将其视为 301。我们不会为此 URL 编制索引, 而将为重定向目标建立索引。这意味着如果你不怎么介意的话,全设置为 302 重定向即可,搜索引擎会自己纠正。
参考资料:
