wp使用tidy扩展美化HTML 输出,格式化html源代码

记录一下,美化 WordPress HTML 输出,无需任何插件

在WordPress中使用输出缓冲(Output Buffering)和Tidy库来美化HTML输出是一个很好的实践,尤其是在开发或调试阶段。

  1. 确保Tidy库可用:首先,确保你的服务器安装了Tidy库,并且PHP的Tidy扩展已经启用。这通常不是所有服务器都默认安装的。
  2. WordPress主题和插件的兼容性
    在WordPress中使用shutdown钩子进行输出处理可能会影响某些插件或主题的功能,尤其是那些也使用输出缓冲的插件。
  3. 性能考虑
    使用tidy来解析和清理HTML可能会对服务器性能产生影响,特别是当网站流量大或HTML内容复杂时。
  4. 输出时机
    虽然shutdown钩子是在请求结束时执行,但通常用于日志记录或清理工作,而不是修改最终发送给客户端的响应。确保这是你想要的行为。

下面是一个代码示例,增加了错误处理和确保tidy对象被正确使用:

function beautify_html_output() {  
    if (ob_get_level() > 0) {  
        $html = ob_get_clean();  
  
        if (class_exists('\tidy')) {  
            $tidy = new \tidy;  
            $tidy->parseString($html, [  
                'indent' => true,  
                'output-xhtml' => true,  
                'wrap' => 0
            ], 'utf8');  
            $tidy->cleanRepair();  
  
            if ($tidy->errorBuffer) {  
                // 处理tidy的错误  
                error_log('Tidy Error: ' . $tidy->errorBuffer);  
            } else {  
                echo $tidy;  
            }  
        } else {  
            // 如果tidy类不存在,则回退到原始HTML  
            echo $html;  
        }  
    }  
}  
  
add_action('shutdown', 'beautify_html_output', 0);  
  
// 启动输出缓冲  
ob_start();

换行符处理:这可能会影响HTML的可读性(在源代码中),但不会影响浏览器渲染的页面。如果您希望保留一些可读性,可以考虑只去除不必要的换行符或空格。这里$buffe只是合并css的时候去除多余空格,注意,如果文章中有pre代码,会被压缩处理

function format_html_output($buffer) {  
    // 早期返回:对于登录用户或XML内容  
    if (is_user_logged_in() || strpos(strtolower($buffer), '<?xml') === 0) {  
        return $buffer;  
    }  
  
    // 去除换行符  
    $buffer = str_replace(["\r\n", "\r", "\n"], '', $buffer);  
  
    // 尝试使用HTML Tidy进行格式化(如果可用)  
    if (function_exists('tidy_parse_string')) {  
        // 内联配置选项  
        $tidy = tidy_parse_string($buffer, [  
            'indent' => 2, // 启用缩进  
            'wrap' => 0,   // 禁自动换行            
            'char-encoding' => 'UTF8' // 设置字符编码  
        ], 'UTF8');  
  
        // 直接获取并返回Tidy的输出  
        if ($tidy) {  
            $buffer = tidy_get_output($tidy);  
        }  
    }  
  
    return $buffer;  
}  
  
// 添加输出缓冲  
ob_start('format_html_output');

如果文章中有pre代码格式,需要做特殊处理,否则其中代码会被压缩

为了修改format_html_output函数以在美化HTML时不删除<pre>标签内的换行符,我们需要在去除全局换行符之前先处理<pre>标签内的内容,以确保其内部的换行符得到保留。由于直接在字符串操作中区分<pre>标签的内容较为复杂,我们可以采用正则表达式配合回调函数的方式来处理。

但是,由于HTML的复杂性(如嵌套<pre>标签或包含<pre>标签的JavaScript字符串等),直接通过正则表达式来完美处理所有情况可能会很复杂且容易出错。不过,对于简单的用途,我们可以尝试以下方案:

  1. 使用正则表达式找到所有的<pre>标签及其内容。
  2. 对这些内容进行特殊处理,比如暂时替换为占位符。
  3. 去除剩余的换行符。
  4. 格式化HTML(如果可能)。
  5. <pre>标签的内容恢复回原位置。

但是,考虑到性能和实现的复杂性,这里给出一个简化的方案,它依赖于HTML结构相对简单且<pre>标签不包含嵌套的HTML元素(如<div><span>等)的假设。

下面是一个简化的示例,它使用preg_replace_callback来保留<pre>标签内的换行符:

function format_html_output($buffer) {  
    // 早期返回:对于登录用户或XML内容  
    if (is_user_logged_in() || strpos(strtolower($buffer), '<?xml') === 0) {  
        return $buffer;  
    }  
  
    // 使用正则表达式找到所有的<pre>标签并保留其内部换行符  
    $buffer = preg_replace_callback('/<pre[^>]*>(.*?)<\/pre>/is', function ($matches) {  
        // 替换换行符为特殊占位符(确保它不会出现在正常文本中)  
        $preservedContent = str_replace(["\r\n", "\r", "\n"], '__PRE_NEWLINE__', $matches[1]);  
        return "<pre>" . $preservedContent . "</pre>";  
    }, $buffer);  
  
    // 去除剩余的换行符  
    $buffer = str_replace(["\r\n", "\r", "\n"], '', $buffer);  
  
    // 尝试使用HTML Tidy进行格式化(如果可用)  
    if (function_exists('tidy_parse_string')) {  
        $tidy = tidy_parse_string($buffer, [  
            'indent' => 2,  
            'wrap' => 0,  
            'char-encoding' => 'UTF8'  
        ], 'UTF8');  
  
        if ($tidy) {  
            $buffer = tidy_get_output($tidy);  
  
            // 将特殊占位符替换回换行符  
            $buffer = str_replace('__PRE_NEWLINE__', "\n", $buffer);  
        }  
    }  
  
    // 如果Tidy不可用,则直接替换回换行符  
    if (!function_exists('tidy_parse_string')) {  
        $buffer = str_replace('__PRE_NEWLINE__', "\n", $buffer);  
    }  
  
    return $buffer;  
}  
  
// 添加输出缓冲  
ob_start('format_html_output');

注意

  • 这个解决方案假设<pre>标签不包含嵌套的HTML元素,或者即使包含,它们也不会干扰到换行符的替换。
  • 如果HTML内容非常复杂,或者<pre>标签内的内容可能包含对换行符有特殊要求的元素(如<textarea>),则可能需要更复杂的处理逻辑。
  • 在实际应用中,考虑到性能和可维护性,通常建议只在必要时才进行此类处理,并且可能需要更健壮的HTML解析和修改库来确保准确性和可靠性。
声明:本站资源绿色无后门无广告,可放心下载。如无特殊说明或标注,均为本站原创发布,转载请注明出处!