WordPress建站基础二十三:wordpress商业主题开发教程(Part 2 完善首页)

最后更新时间: 2024年2月26日

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

heder-menu-html
网站导航menu部分固定写死

首先我们在 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');

可以看到如下所示,这里可以添加任意形式的链接,比如页面,文章,自定义链接及分类目录等

add-menu-function
add-menu-function

这里我们为了演示,进行以下操作

1. 建立页面 About Us
2. 建立页面 Contact
3. 新建分类 Production Line(新建立四篇 posts)
4. 新建分类 Solutions(配合分类调试)

这里选择相应链接,然后点击添加到菜单项,按照我们的静态页面展示的,把菜单栏调整成如下图这样

wp-menu-structure
wp-menu-structure

这样操作后我们的 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 输出到静态页面导航中相应的位置即可渲染出导航了,如下图

wp-retrive-menu-items-in-html
wp-retrive-menu-items-in-html

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

wp-retrive-menu-items-show
wp-retrive-menu-items-show

但这里还有几个小问题

问题一: 是我们静态页面,比如在 About Us 页面的时候,导航栏中 About Us 高亮表示选中状态,如下图,解决方案:我们可以判断当前是哪个页面,一般是判断 slug,即页面的 url,然后给菜单添加一个 active 的 class 即可,当然这里要情况讨论,wordpress 一般有以下以种类型的页面类型

1. 首页 is_front_page()
2. 单页面 is_page()
3. 分类页 is_category()
4. post 页 is_single()

wp-menu-widget-add
wordpress页面种类

最终代码如下

<?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高亮。

category-menu-highlight
category-menu-highlight
post-menu-highlight
post-menu-highlight

问题二:我们新建的目录 Production Line 的链接是 http://127.0.0.2/category/production-line,中间多了一个 catetory,而我们想要到效果是 http://127.0.0.2/production-line, 方法有很多,最简单的是使用插件 No Category Base (WPML),安装插件后激活即可。

下边首页部分还有一段需要动态获取的,这里是引入 Production Line 分类下的最新的四篇文章显示在这里, 现在这里是写死的

front-page-import-post
首页对应的 Production Line 部分是固定的

对应的代码截图如下:

fontpage-post-html
首页对应的 html 代码块(写死的)

首先在后台新建如下的 Posts

wp-add-demo-posts
后台发布4篇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-->

现在再打开首页可以看到四篇最新的文章已经加载出来了,包括图片和标题及链接部分都可以正确使用了,如下图

wp-frontage-retrive-html
wp-frontage-retrive-html

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

请投票