Dynamically add id to heading tags

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.

3 s
3

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=' ) ) {
                continue;
            }
            $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;
}

Leave a Comment