我的blog换过很多主题,但是都有一个同样问题,这让我不禁感到奇怪。我们先来看看下面这一串代码

bug
正常的

看出什么问题了吗?正常的代码在同级<div>标签使用的是<ul>标签,而出现问题的代码是在继续沿用<div>标签的前提下向下再套用一个<ul>标签,并且将原本在<ul>标签的元素放到了<div>标签中,这就导致<ul>标签缺少式样,出现布局错误的问题。

往往这种情况就是主题出现的小bug,但是我却换了很多主题都存在同样的问题,而我去访问其他使用相同主题的网站是他们却没有问题,这就说明一个是我的问题。但是所有的主题问题都出现在<header>栏并且都是同样的问题就让我很是奇怪,由于近期我也更换过服务器,wp程序也升级过,所以我也没想到会是哪里的问题,只能一步步排查。

查找问题

本地搭建相同的服务器环境

启动Nginx和PHP7.3

创建一个带有数据库的网站。安装好wp程序后开始测试。

神奇的是,问题依旧。这往往是说明主题的问题,但是因为这个问题也是查了很久基本确定不是主题导致的。我选择先查看主题代码以防万一。

我打开了header.php但是没找到代码,pe端这一段代码被他放到footer.php了,然后我就打开 footer.php 找到这一段代码。

看不懂,因为这个是wp的自定义函数。本来正常的渠道应该是打开官方wiki查看函数使用说明的,但是我本着主题没问题的原则就直奔wp函数的php了。

直接打开wp根目录搜索这个函数名

在这里可以直观的看到wp的wp_nav_menu()函数,这里array()里边的是默认参数,就是当函数调用是没有提供指定的参数时会默认使用对应的函数,可以看到函数的container默认是div这很可能就是外部被套了一个<div>的原因,而下面的menu_class默认"menu"也验证了这一说法,还是要先看看官方文档怎么说

果然这里的container就是指外部是否需要套一个标签,默认套div。但是根据官方wiki如果container填入false即为不套用,我们可以回到之前看主题作者写的

<?php wp_nav_menu( array( 'depth' => 2, 'theme_location' => 'primary', 'container' => false) ); ?>

'container' => false 确实有这个定义,所以说主题设置是没有问题的。那么就是wp的问题,但是其他的博客又没有问题,这就很玄乎。后来我就想到是服务器配置问题,是不是忘记开启php的某个拓展,但是主题wiki也没写清楚依赖哪个拓展。问题很玄乎。

解决问题

这里我暂时想到三个方案

  1. 解决服务器环境带来的问题
  2. 用魔法打败魔法(强制替换错误代码)
  3. 修复主题设置尝试使用另一种方法实现

方案1:简单的试了一下还是放弃了,因为要排查的问题实在是太多了。

方法2:理论上可行,但是由于当时我操作上的失误忽略了 'echo' => false 的问题导致失败。

我在echo处将错误代码用str_replace();替换成了正确的代码:

if ( $args->echo ) {/** 判断echo是否为true **/
		/** echo $nav_menu; **/
		echo str_replace (($nav_menu,"<div class=\"menu\"><ul>","<ul id=\"menu-menu-2\" class=\"menu\">").'<!--0000-->';/** 这个注释是为了方便我排除缓存问题 **/
	} else {
		return str_replace ($nav_menu,"<div class=\"menu\"><ul>","<ul id=\"menu-menu-2\" class=\"menu\">").'<!--0000-->';
	}

最后我使用了方法3:

我将作者原本的写法

<?php wp_nav_menu( array( 'depth' => 2, 'theme_location' => 'primary', 'container' => false) ); ?>

写成了这样

<?php wp_nav_menu( array( 'depth' => 2, 'theme_location' => 'primary', 'container' => 'ul', 'menu_id' => 'menu-menu-2' ) ); ?>

既然使用 false 来禁用外套<div>没有生效,那么我们就定义一个自定义标签就用正确的<ul>来解决, 'menu_id' => 'menu-menu-2' 定义正确的标签。最后问题完美解决。(也许也不完美,因为主题更新回导致它失效,但是总比方法2稳)

总结问题

这个问题其实并非由主题作者引起的,但是最后却通过修改主题来解决了。因为wp没有正确理解他的意思,而我就换了一个写法让wp能够正确理解的方法。