So, I am using heading tags h1-h6 on my site in various places, what I'd like to do is put a div around those tags using a WP function. Right now I am using some jQuery to get the job done, but I'm trying to minimize the amount of jQuery on my site, so I figured it'd be better to use some kind of preg_replace to find any h1-h6 tags and add an outer div.

My current jQuery looks like this: $("h6, h5, h4, h3, h2, h1").wrap('<div class="title"></div>');

I found some code that works for images, but I'm not sure how to tweak it, so I can use it for heading tags:

function outer_img_wrap( $content ) {
    $image = '/(<img([^>]*)>)/i';
    $wrapper = '<span class="featured">$1</span>';
    $content = preg_replace( $image, $wrapper, $content );
    return $content;
add_filter( 'the_content', 'outer_img_wrap' );

Any help is appreciated. The function doesn't have to look like that, just found that for images and thought it was nice and simple.


  • Try a regular expression like: <h.*?<\/h.>. Mar 29, 2019 at 13:27
  • @Nicolai - Thanks for the quick reply, I ran this through a regex validator and it finds everything, the header tags and the content, looking at my example code above this should work if I add it where the $image variable is right? Mar 29, 2019 at 14:04
  • Yes, you have to modify the pattern variable, it should be like: /(<h.*?<\/h.>)/ims. Not sure about your issues, it works in my test. Mar 29, 2019 at 14:27

2 Answers 2


Try this code

function wrap_heading_with_div( $content ) {
    $heading = '/<h\d.*?>(.*?)<\/h\d>/ims';
    $wrapper = '<div class="title">$0</div>';
    $content = preg_replace($heading, $wrapper, $content);
    return $content;
add_filter( 'the_content', 'wrap_heading_with_div' );

Live Demo


The code you’ve posted is a great starting point. All you have to do is to change the expressions inside of it.

It’s a little bit trickier, because you have to replace opening and closing tag. I would go for something like this:

function wrap_headers_with_div( $content ) {
    $content = preg_replace('/<h([1-6])>/', '<div class="title"><h$1>', $content);
    $content = preg_replace('/<\/h([1-6])>/', '</h$1></div>', $content);

    return $content;
add_filter( 'the_content', 'wrap_headers_with_div' );
  • There is no need to execute preg_replace() twice though. Mar 29, 2019 at 13:30
  • @Nicolai but the code gets cleaner and easier to understand this way. And you get rid of all of the problems with multiline strings ;) Mar 29, 2019 at 13:33
  • Let me respectfully disagree, we have the modifier m for that. Mar 29, 2019 at 13:35
  • @Nicolai of course we have. And of course there are millions of ways to write this. Using two replacements is not an error and in my point of view it’s much easier to read, the person who uses it doesn’t need to understand modifiers (so it will be easier to modify for such persons), and it’s more reliable (for example it will still work when the HTML is not perfect). Of course you can also use only one replacement - it’s completely up to you. Mar 29, 2019 at 13:46
  • 1
    This code will modify only the headers inside content. You can’t modify the title with such filter, because titles doesn’t contain header tags - these tags are printed by your theme. So you would have to check how your theme prints these titles and modify its code according to your needs. Mar 29, 2019 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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