WordPress没有等效的body_class()
用于html标记。
下面是一种使用输出缓冲来捕获呈现的HTML文档的最终输出的方法。下面的输出缓冲代码改编自发布的解决方案here 和here. 这允许我们访问HTML文档的最终输出,然后对其进行解析和编辑,无需修改主题的模板文件。
首先,我们开始输出缓冲并连接shutdown
函数,它通过迭代所有打开的缓冲区级别、关闭它们并捕获它们的输出来工作。然后,它会发出wpse_final_output
过滤,回显过滤后的内容
/**
* Start output buffering
*/
add_action( \'wp\', \'wpse_ob_start\' );
function wpse_ob_start() {
// Bail immediately if this is the admin area.
if ( is_admin() ) {
return;
}
// Bail immediately if this is a feed.
if ( is_feed() ) {
return;
}
// Start output buffering.
ob_start();
add_action( \'shutdown\', \'wpse_ob_clean\', 0 );
}
/**
* Ensure the buffer is clean and then trigger the wpse_final_output filter.
* This fires right before WP\'s similar shutdown functionality.
*/
function wpse_ob_clean() {
$final = \'\';
// We\'ll need to get the number of ob levels we\'re in, so that we can
// iterate over each, collecting that buffer\'s output into the final output.
$levels = ob_get_level();
for ( $i = 0; $i < $levels; $i++ ) {
$final .= ob_get_clean();
}
// Apply any filters to the final output
echo apply_filters( \'wpse_final_output\', $final );
}
这里解析HTML并使用自定义过滤器
wpse_additional_html_classes
触发,使我们可以在单独的函数中添加额外的类。这段代码有点冗长,但它涵盖了我在使用
DOMDocument
解析HTML。
add_filter( \'wpse_final_output\', \'wpse_html_tag\', 10, 1 );
/**
* Parse final buffer output. Triggers wpse_additional_html_classes, which
* allows us to add classes to the html element.
*/
function wpse_html_tag( $output ) {
// Filterable list of html classes.
$additional_html_classes = apply_filters( \'wpse_additional_html_classes\', array() );
// Bail if there are no classes to add since we won\'t need to do anything.
if ( ! $additional_html_classes ) {
return $output;
}
// Create an instance of DOMDocument.
$dom = new \\DOMDocument();
// Suppress errors due to malformed HTML.
// See http://stackoverflow.com/a/17559716/3059883
$libxml_previous_state = libxml_use_internal_errors( true );
// Populate $dom with buffer, making sure to handle UTF-8, otherwise
// problems will occur with UTF-8 characters.
// Also, make sure that the doctype and HTML tags are not added to our HTML fragment. http://stackoverflow.com/a/22490902/3059883
$dom->loadHTML( mb_convert_encoding( $output, \'HTML-ENTITIES\', \'UTF-8\' ), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
// Restore previous state of libxml_use_internal_errors() now that we\'re done.
// Again, see http://stackoverflow.com/a/17559716/3059883
libxml_use_internal_errors( $libxml_previous_state );
// Create an instance of DOMXpath.
$xpath = new \\DOMXpath( $dom );
// Get the first html element.
$html = $xpath->query( "/descendant::html[1]" );
// Get existing classes for html element.
$definedClasses = explode( \' \', $dom->documentElement->getAttribute( \'class\' ) );
// Adds our additional classes to the existing classes. Ensure that proper spacing of class names
// is used and that duplicate class names are not added.
foreach ( $html as $html_tag ) {
$spacer = \' \';
// Spacer will be set to an empty string if there are no existing classes.
if ( isset( $definedClasses[0] ) && false == $definedClasses[0] ) {
$spacer = \'\';
}
foreach ( $additional_html_classes as $additional_html_class ) {
if ( ! in_array( $additional_html_class , $definedClasses ) ) {
$html_tag->setAttribute(
\'class\', $html_tag->getAttribute( \'class\' ) . $spacer . $additional_html_class
);
}
$spacer = \' \';
}
}
// Save the updated HTML.
$output = $dom->saveHTML();
return $output;
}
这个
wpse_additional_html_classes
filter允许我们轻松过滤添加了HTML元素的其他类。在下面的示例中,为post id添加了一个特殊类(当然,在许多情况下,没有post id)。还添加了自定义类名数组。自定义用于添加类以满足需要的类/逻辑,然后返回类名数组。
add_filter( \'wpse_additional_html_classes\', \'wpse_add_additional_html_classes\', 10, 1 );
/**
* Filters list of class names to be added to HTML element.
*
* @param array $classes
* @return array
*/
function wpse_add_additional_html_classes( $classes ) {
// Example of adding a post ID class.
if ( is_singular() ) {
$post_id = get_the_ID();
if ( $post_id ) {
$post_id_class = "post-id-{$post_id}";
if ( ! in_array( $post_id_class, $classes ) ) {
$classes[] = $post_id_class;
}
}
}
// Add some more classes.
$additional_classes = [
\'class-1\',
\'class-2\',
\'class-3\',
];
$classes = array_merge( $classes, $additional_classes );
return $classes;
}