将唯一类添加到HTML标记/元素

时间:2017-05-27 作者:Garconis

我知道WordPress有一个body\\u类函数。但是有没有一种(或一种方法)可以将类添加到HTML元素中呢?

我的目标是能够向页面的HTML元素添加唯一的类(或ID)。目前,我的主题是将页面id XXXX类添加到body元素,但我需要一种在实际HTML元素上具有唯一类或id的方法。将页面id XXXX也添加到HTML元素中可能会更好,尽管我更希望能够在每个页面中添加一个自定义字段,在这里我可以键入类/id,然后将其添加到HTML元素中。

至少,是否有一个函数可以用于向HTML元素添加类或ID,类似于body\\u class函数的工作方式?

5 个回复
最合适的回答,由SO网友:Garconis 整理而成

感谢的帮助this 回答:我发现此解决方案可以用于添加id. 虽然我不确定是否要添加到class 属性

function add_id_to_html_element( $output ) {
    global $post;
    $output .= \' id="custom-id-\' . $post->ID . \'"\';
    return $output;
}
add_filter( \'language_attributes\', \'add_id_to_html_element\' );

SO网友:Robert Went

为什么不直接将类添加到标记中?

<html <?php language_attributes(); ?> class="page-id-<?php the_ID(); ?>">

SO网友:Dave Romsey

WordPress没有等效的body_class() 用于html标记。

下面是一种使用输出缓冲来捕获呈现的HTML文档的最终输出的方法。下面的输出缓冲代码改编自发布的解决方案herehere. 这允许我们访问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;
    }

SO网友:James0r

这对我来说似乎很管用

add_filter( \'language_attributes\', \'add_no_js_class_to_html_tag\', 10, 2 );

function add_no_js_class_to_html_tag( $output, $doctype ) {
    if ( \'html\' !== $doctype ) {
        return $output;
    }

    $output .= \' class="no-js"\';

    return $output;
}
我在抄本上找不到它的任何内容。贷记至https://gist.github.com/nickdavis/73d91d674b843b77a1cd0a21f9c0353a

SO网友:Jared Cobb

由于您处于循环之外,最干净的解决方案就是像这样简单地创建自己的函数

function wpse_268339_get_post_class() {
    global $post;
    if ( ! empty( $post->ID ) ) {
        return \'post-\' . $post->ID;
    }
}
然后,在你的header.php 模板只调用函数作为主体类中的转义输出。本例假设您在<html> 标签

<html <?php language_attributes(); ?> class="no-js no-svg <?php echo esc_attr( wpse_268339_get_post_class() ); ?>">
仅当您在帖子/页面上时,才会输出类名。

或者,如果所有的正常身体类别都没有伤害任何东西,你可以使用body_class()<html> 标记。该功能可在任何位置工作。

<html <?php body_class(); ?>>

结束