# 在 WordPress 菜单显示指定时间文章更新数量 类似 bilibili 气泡

- Link: https://yjyj.net/learn/wordpress-learn/4742.html
- Published: 2014-10-07T00:33:50+08:00
- Author: 小 虾

⚡ 生猛大蝦编辑部 · 30 秒核心看点

 * 重写 Walker_Nav_Menu，让菜单项支持自定义描述与气泡展示。
 * 通过指定时间范围统计文章更新数量，把动态数据塞进导航里。
 * 配合 CSS 调整强弱标题与气泡样式，做出更像 bilibili 的视觉效果。

![在 WordPress 菜单显示指定时间文章更新数量 类似 bilibili 气泡 - 配图](https://yjyj.
net/wp-content/uploads/2014/10/2014061710191310.png)

首先需要重新制造一次“菜单”：

    ```decode:true
    class description_walker extends Walker_Nav_Menu
    {
          function start_el(&$output, $item, $depth, $args)
          {
               global $wp_query;
               $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

               $class_names = $value = '';

               $classes = empty( $item->classes ) ? array() : (array) $item->classes;

               $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
               $class_names = ' class="'. esc_attr( $class_names ) . '"';

               $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

               $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
               $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
               $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
               $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

               $prepend = '<strong>';
               $append = '</strong>';
               $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';

               if($depth != 0)
               {
                         $description = $append = $prepend = "";
               }

                $item_output = $args->before;
                $item_output .= '<a'. $attributes .'>';
                $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
                $item_output .= $description.$args->link_after;
                $item_output .= '</a>';
                $item_output .= $args->after;

                $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
                }
    }
    ```

    ```decode:true
    wp_nav_menu( array(
     'container' =>false,
     'menu_class' => 'nav',
     'echo' => true,
     'before' => '',
     'after' => '',
     'link_before' => '',
     'link_after' => '',
     'depth' => 0,
     'walker' => new description_walker())
     );
    ```

    ```decode:true
    .nav{
    height:50px;
    padding-left:13px;
    margin:0;
    padding:0;
    list-style-type:none;
    list-style-position:outside;
    position:relative;
    }

    .nav a{
    display:block;
    float:left;
    line-height:18px;
    outline:medium none;
    padding:2px 10px;
    text-decoration:none;
    width:95px;
    min-height: 35px;
    }

    .nav li a strong {
    display:block;
    font-size:14px;
    font-weight:normal;
    }

    .nav li a span {
    display:block;
    font-size:10px;
    line-height:14px;
    }
    ```

> [Improve your WordPress Navigation Menu Output](https://kriesi.at/archives/improve-your-wordpress-navigation-menu-output)

_以上是大咖的重制办法,下面才是正文:_

**1. 首先，注册一个菜单：**

    ```decode:true
    // 注册菜单
    register_nav_menus( array(
        'primary' => __( '菜单' ),
    ) );
    ```

**2. 而后，给菜单建立一个新的结构：**

    ```decode:true
    // 强化菜单 调用代码 (php) wp_nav_menu( array( 'theme_location' => 'primary', 'walker' => new description_walker ) ); (/php)
    // 强化菜单 结构
    class description_walker extends Walker_Nav_Menu
    {
        function start_el(&$output, $item, $depth, $args)
        {
            global $wp_query;
            $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

            $class_names = $value = '';

            $classes = empty( $item->classes ) ? array() : (array) $item->classes;

            $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
            $class_names = ' class="'. esc_attr( $class_names ) . '"';

            $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

            $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
            $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
            $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
            $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

            $prepend = '<span>';
            $append = '</span>';
            $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';

            if($depth != 0)
            {
                $description = $append = $prepend = "";
            }

            $item_output = $args->before;
            $item_output .= '<a'. $attributes .'>';
            $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
            // seabye++
            if ( $item->description<=0 ) { $item_output .= $description; }
                else { $item_output .= '<span class="day">+'.get_this_week_post_count_by_category($item->description).'</span>'; }
            $item_output .= $args->link_after;
            // seabye++ end
            // $item_output .= $description.$args->link_after;
            $item_output .= '</a>';
            $item_output .= $args->after;

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
    }
    ```

**3. 接着是计时数据的代码：**

    ```decode:true
    // 强化菜单 代表时间
    // 一日 today
    // 一周 1 week ago
    // 一年 1 year ago
    // 千年 1000 year ago
    function get_this_week_post_count_by_category($id) {

        $date_query = array(
            array(
                'after' => 'today'
                )
            );
        $tax_query = array(
            array(
                'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => $id
                )
            );

        $args = array(
            'post_type' => 'post',
            'post_status' => 'publish',
            'tax_query' => $tax_query,
            'date_query' => $date_query,
            'no_found_rows' => true,
            'suppress_filters' => true,
            'fields' => 'ids',
            'posts_per_page' => -1
            );

        $query = new WP_Query( $args );

        return $query->post_count;
    }
    ```

**4. 调用这个菜单的代码：**

    ```decode:true
    <?php wp_nav_menu( array( 'theme_location' => 'primary', 'walker' => new description_walker ) ); ?>
    ```

**5.设置下wordpress的菜单在项目的“图像描述”中填写菜单中该分类的ID**

本文来自:http://meiri.me/9528.html
 感谢作者的辛勤付出!

❓ 延伸问答与排错指南（FAQ）

WordPress 菜单里怎么显示更新数量气泡？

思路是自定义菜单 Walker，在 start_el 里给菜单项追加描述内容，再把统计出来的更新数量
写进 description 或额外字段，最后用 CSS 做成气泡样式。这样导航就能显示动态更新提示，
而不是静态文字。

这种菜单气泡适合放什么信息？

适合放文章更新数、分类更新提示、活动状态或简短说明。重点是信息要短、可一眼扫到，
避免把导航做得太重。本文的做法就是把“指定时间内的更新数量”嵌进菜单项展示。

实现后还需要改哪些样式？

通常要补 CSS：控制菜单高度、链接宽度、标题字号，以及气泡的显示位置和视觉层级。原文
示例里已经给出 nav、a、strong、span 等基础样式，按这个方向微调即可让效果更接近气泡
提示。

📚 【[WordPress 学习](https://yjyj.net/category/learn/wordpress-learn)】专栏延伸
阅读与热门精选（[全站文章归档](https://yjyj.net/archive)）：

 * [WordPress 获取文章中的第一个链接](https://yjyj.net/learn/wordpress-learn/4740.html)
 * [wordpress压缩前端页面的可爱小代码](https://yjyj.net/learn/wordpress-learn/4738.html)
 * [WordPress 图片alt自动使用标题](https://yjyj.net/learn/wordpress-learn/4747.html)
 * [wordpress 为cos-html-cache插件增加页面（Page）、标签（Tag）和分类（Category）的静态化功能](https://yjyj.net/learn/wordpress-learn/4749.html)
 * 热门必读[京东云路由器雅典娜 AX6600 折腾记](https://yjyj.net/learn/7810.html)
 * 热门必读[斐讯R1升级固件，音质终于得以提升了](https://yjyj.net/learn/5984.html)
