How to add data- attribute to <body> tag

I need to add a data- attribute with a user-supplied value (via custom fields) to the tag of each page. I tried editing header.php as such

body ?php astra_schema_body(); ? ?php bene_body_class(); ? data-myAttr=?php get_post_meta(get_the_id(),'my_attr')[0] ?

but when I load the page, the attribute does not show up. I'm guessing something the theme strips out all unknown attributes?

Is there a filter I can use to add it in via functions.php?

Topic page-attributes filters Wordpress

Category Web


There are two ways to solve this. The first one is what you are trying, but you have to print out the value you get. Like this:

print get_post_meta();

I don't recommend this for two reasons:

  1. You should keep your templates as simple as possible. Otherwise they become cluttered with fragments of business code which makes everything harder to maintain.
  2. Printing this value requires a bit more work than you might think. Moving this to a separate place keeps your template clean and your code more readable.

Write your body tag like this instead:

<body 
    <?php 
    do_action( 'body_start_tag_attributes' ); 
    astra_schema_body(); 
    bene_body_class(); 
    ?>
>

Note the do_action() I introduced. This allows you to add any code you need from anywhere. Now let's use that hook in your functions.php:

add_action( 'body_start_tag_attributes', function() {
    
    if ( ! is_singular() ) {
        return; // an archive or a 404
    }
    
    $post = get_post();
    // the last parameter means you get the first entry of the meta array.
    $meta = get_post_meta( $post->ID, 'my_attr', true );
    
    if ( ! $meta ) {
        return; // no meta value
    }
    
    $value = esc_attr( $meta );
    
    print ' data-myAttr="' . $value . '"';
});

As you can see, you need some "guards" before you can print the value: check for the type of the current page (singular), the presence of the attribute, and finally escape the value for security reasons.

And then, and only then, you can print it.

You can even reuse the hook to add other attributes in case you need them later — without any further changes to your template!

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.