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?


1 Answer 1


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:

    do_action( 'body_start_tag_attributes' ); 

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!

  • this is EXACTLY what I was looking for. unfortunately, nothing from that callback actually ends up in the body tag. Would the theme possibly be stripping it out?
    – Daveh0
    Commented Aug 30, 2020 at 15:37
  • @Daveh0 Unlikely. Debug the problem, print out the meta value you get (maybe it's empty), check upper/lowercase and so on.
    – fuxia
    Commented Aug 30, 2020 at 21:02
  • this is very strange. It seems to be taking that attribute (or whatever I output from the function), creating a <br> element just below <body> and adding the attribute there: `<br style="display:none" data-myattr="my value">. ever seen that before?
    – Daveh0
    Commented Aug 31, 2020 at 12:55
  • @Daveh0 Is that from View Source or from Inspect Element?
    – fuxia
    Commented Aug 31, 2020 at 13:36
  • 1
    YES! that worked. GTM stuff is from this plugin - wordpress.org/plugins/duracelltomi-google-tag-manager... just FYI. Pretty sure I'm good go now - thanks for sticking with.
    – Daveh0
    Commented Sep 1, 2020 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.