How do I add an id attribute dynamically to every heading tag on a wordpress website using php? I wanted to make it so that for every heading tag (h1, h2, h3, h4, h5, h6) I have a unique id attached so that it would be like: <h1 id="this_is_sparta">This Is Sparta</h1>

So I can link to it using <a href="#this_is_sparta">Go to This Is Sparta</a>

I've been looking for a solution to this for hours now, and I can't seem to find anything, so if someone can please help, anything would be appreciated!

If it must be done manually, all is ok, I just need an easier way to do this for a client.

  • Every heading tag? Does that cover template-generated HTML as well as post/page content? Would be easier to do with JS/jQuery IMHO. Apr 5 '13 at 4:24
  • just the post/page content
    – nwong212
    Apr 5 '13 at 4:26

I had this very same dilemma, and I found this plugin: Add IDs to Header Tags, and it works fine for posts. (I'm not affiliated to the plugin in any way).

To make it work for pages too, I had to make a change in the code, which is explained on this support page: Not adding IDs

It seems that the developer is not active, and is not offering any support for the plugin, so if you find some problems, you have to fix them yourself, unfortunately. But the plugin is a fine base to start out from.

In this following code I removed the "is_single()" check, so that the code works on both pages and posts. Futhermore I removed some of the "extra" code to make it fit OP's question.

//Author URI: http://stephanis.info

add_filter( 'the_content', 'add_ids_to_header_tags' );
function add_ids_to_header_tags( $content ) {

    $pattern = '#(?P<full_tag><(?P<tag_name>h\d)(?P<tag_extra>[^>]*)>(?P<tag_contents>[^<]*)</h\d>)#i';
    if ( preg_match_all( $pattern, $content, $matches, PREG_SET_ORDER ) ) {
        $find = array();
        $replace = array();
        foreach( $matches as $match ) {
            if ( strlen( $match['tag_extra'] ) && false !== stripos( $match['tag_extra'], 'id=' ) ) {
            $find[]    = $match['full_tag'];
            $id        = sanitize_title( $match['tag_contents'] );
            $id_attr   = sprintf( ' id="%s"', $id );
            $replace[] = sprintf( '<%1$s%2$s%3$s>%4$s</%1$s>', $match['tag_name'], $match['tag_extra'], $id_attr, $match['tag_contents']);
        $content = str_replace( $find, $replace, $content );
    return $content;
  • 1
    Please state your affiliation. This is compulsory. Oct 8 '14 at 7:46
  • 1
    What do you mean @PieterGoosen? I'm not the developer, and I have no connection to the plugin. I just wanted to help somebody out, and as this is "Wordpress Development" I thought it was ok to link to a plugin that helped me a lot. But, I can paste in the code that worked for me if that's any better?
    – Squazz
    Oct 8 '14 at 7:51
  • I think you understood me wrong :-). Yes, you have to state your affiliation when recommending a plugin. All you need to add is the following "I'm not affiliated to the plugin in any way" if you are just a user or "I'm the author of the plugin" if you are the author. Hope this makes more sense Oct 8 '14 at 8:12
  • 2
    Oh, ok, I'll add that too then :) I hope that the edits is acceptable
    – Squazz
    Oct 8 '14 at 8:14
  • 2
    Great implementation! Just one issue: %5$s in the format string (last line in the foreach) should be removed to avoid a PHP notice. May 11 '15 at 15:00

There's a function in wp-includes/formatting.php called sanitize_title_with_dashes which you can use.

<h1 id="<?php echo sanitize_title_with_dashes( get_the_title() ); ?>"><?php the_title(); ?></h1>

If your title is This Is Sparta the output will be this-is-sparta.

  • What he wants is modify post content not template part, where php wont work... Apr 5 '13 at 7:35
  • Not sure about what OP wants, you normally must have only one <h1> per page, most of the time, it will be in the template.
    – RRikesh
    Apr 5 '13 at 7:39
  • This is a great solution for the title, but I wanted to use them for other <hx> tags so as to work with jump links, Google Jump To, etc.
    – nwong212
    Apr 6 '13 at 5:34

You can use the_content filter, and then find all header tags in content and add ids.

For finding header tags in content you can use either Regex expressions or something like simple_html_dom. Look at this

  • ok, i've decided on the dom method, but how would i implement it so that it will add the id attribute? I'm sorry, I'm new to wordpress and php, etc. :P
    – nwong212
    Apr 6 '13 at 5:53

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.