最后更新时间: 2024年2月26日
上一节我们把静态网站的首页已经集成到 wordpress 中去了,但是导航部分是固定写死的(如下代码截图),不能动态添加,这一节我们就来实现导航部分动态渲染

首先我们在 function.php 中添加如下代码,表示在 wordpress 的后台启用菜单功能,添加后刷新 wordpress后台
function filterbag_widget_areas(){
register_sidebar(
array(
'before_title' => '',
'after_title' => '',
'before_widget' => '',
'after_widget' => '',
),
array(
'name' => 'Siderbar Area',
'id' => 'siderbar-1',
'description' => 'Siderbar Widget Area'
)
);
}
add_action( 'widgets_init', 'filterbag_widget_areas');
可以看到如下所示,这里可以添加任意形式的链接,比如页面,文章,自定义链接及分类目录等

这里我们为了演示,进行以下操作
1. 建立页面 About Us
2. 建立页面 Contact
3. 新建分类 Production Line(新建立四篇 posts)
4. 新建分类 Solutions(配合分类调试)
这里选择相应链接,然后点击添加到菜单项,按照我们的静态页面展示的,把菜单栏调整成如下图这样

这样操作后我们的 wordpress 菜单项就建立好了,现在只需要调用 wordpess 的相关 api 函数取出菜单栏,并渲染到 header.php中去即可
我们使用 wp_get_nav_menus()和 wp_get_nav_menu_items 来实现自渲染菜单功能项,代码如下
<?php
//get all menus
$menus = wp_get_nav_menus();
//定义导航字符串变量
$menuHtml = '';
if($menus) {
foreach ($menus as $menu) {
if($menu->name === 'Header Menu') {
$menu_itmes = wp_get_nav_menu_items($menu->term_id);
// get header menu items
if($menu_itmes) {
foreach($menu_itmes as $menu_item) {
$menuHtml.= '<li><a href="'. $menu_item->url .'">'.$menu_item->title.'</a></li>';
}
}
break;
}
}
}
//echo $menuHtml;
?>
我们这里结合静态网站的菜单 html结构,渲染出来列表项li,并指定描文本链接,然后把这个$menuHtml 输出到静态页面导航中相应的位置即可渲染出导航了,如下图

如下图展示为正确渲染的动态导航部分了

但这里还有几个小问题
问题一: 是我们静态页面,比如在 About Us 页面的时候,导航栏中 About Us 高亮表示选中状态,如下图,解决方案:我们可以判断当前是哪个页面,一般是判断 slug,即页面的 url,然后给菜单添加一个 active 的 class 即可,当然这里要情况讨论,wordpress 一般有以下以种类型的页面类型
1. 首页 is_front_page()
2. 单页面 is_page()
3. 分类页 is_category()
4. post 页 is_single()

最终代码如下
<?php
//get all menus
$menus = wp_get_nav_menus();
//获取当前url
$current_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
//echo $current_url;
//var_dump(get_permalink());
//定义导航字符串变量
$menuHtml = '';
if($menus) {
foreach ($menus as $menu) {
if($menu->name === 'Header Menu') {
$menu_itmes = wp_get_nav_menu_items($menu->term_id);
//var_dump($menu_itmes);
// get header menu items
if($menu_itmes) {
foreach($menu_itmes as $menu_item) {
$active_class='';
//echo 'menu url'. $menu_item->url;
if((is_front_page() && $menu_item->url == $current_url) || (is_page() && $menu_item->object_id == get_the_ID()) || (is_category() && $menu_item->url == $current_url)) {
$active_class='active';
}
//针对单页面处理
elseif (is_single() && has_category('', get_the_ID())) {
$categories = get_the_category(get_the_ID());
foreach($categories as $category){
//todo: 比较字符串, 因此分类名不能为子集 ,如 production-line和product匹配时会有bug
if(stripos($menu_item->url, $category->slug) !== false) {
$active_class='active';
break;
}
}
}
$menuHtml.= '<li class="'. $active_class .'"><a href="'. $menu_item->url .'">'.$menu_item->title.'</a></li>';
}
}
break;
}
}
}
//echo $menuHtml;
?>
这样我们打开首页时首页这个 menu item 高亮, 打开about 这个页面时 About Us 这个menu item 高亮,打开 Production Line 这个列表页时 Production Line 高亮,当然这里 post 页面,即属于某个分类下的 post页面当然也是高亮它所属于的分类,打开 contact 时对应的 Contact这个 menu item高亮。


问题二:我们新建的目录 Production Line 的链接是 http://127.0.0.2/category/production-line,中间多了一个 catetory,而我们想要到效果是 http://127.0.0.2/production-line, 方法有很多,最简单的是使用插件 No Category Base (WPML),安装插件后激活即可。
下边首页部分还有一段需要动态获取的,这里是引入 Production Line 分类下的最新的四篇文章显示在这里, 现在这里是写死的

对应的代码截图如下:

首先在后台新建如下的 Posts

下边看看我们如何在首页引入这几篇 posts,我们使用 wordpress 提供的 WP_Query 函数创建一个自定义的查询循环,代码如下:
<div class="row">
<?php
// 设置查询参数
$args = array(
'category_name' => 'production-line', // 使用分类的别名(slug)
'posts_per_page' => 4, // 获取最新的四篇文章
'order' => 'DESC', // 最新的文章首先显示
'orderby' => 'date' // 根据日期排序
);
// 创建一个新的 WP_Query 实例
$the_query = new WP_Query($args);
// 检查是否有文章满足查询条件
if ($the_query->have_posts()) {
// 循环遍历所有文章
while ($the_query->have_posts()) {
$the_query->the_post();
// 输出文章图片, 标题和链接
echo '<div class="col-xs-12 col-sm-4 col-md-3">
<div class="recent-work-wrap">
<img class="img-responsive" src="'.get_the_post_thumbnail_url(get_the_ID(), 'full').'" alt="">
<div class="overlay">
<div class="recent-work-inner">
<h3><a href="'.get_permalink().'">'. get_the_title(). '</a></h3>
<a href="'.get_permalink().'">View Details</a>
</div>
</div>
</div>
</div>';
}
// 重置全局的 $post 对象,以确保后续代码的正常运行
wp_reset_postdata();
} else {
// 如果没有找到文章,可以输出一条消息或进行其他处理
echo 'No posts found.';
}
?>
</div><!--/.row-->
现在再打开首页可以看到四篇最新的文章已经加载出来了,包括图片和标题及链接部分都可以正确使用了,如下图

有些复杂的主题,可能尾部导航也要新建 Footer Menu,然后动态渲染,这里就不演示了,原理和 Header Menu 一样,到此,首页已经完善了。下一节我们讨论如何完善wordpress的page页面,如 About Us 和 Contact 页面。