Adding Anchor Links to every header

Usually, I blog about the Power Platform, Dynamics 365/CDS, and ALM, but in this blog post, I will describe how to add Anchor Links to every header of your blog posts automatically.

A few weeks ago, Jonas Rapp posted a video on how to add Header Anchor Links in WordPress.

My first thought was: “That is really nice and helpful. I want that on my blog as well!”

My second thought was: “There has to be a way that doesn’t require a manual process of adding those links everywhere I would like to have it!”

There is a way of doing it automatically and that is exactly what we are looking at in this blog post.

Problem

The “Problem” I tried to solve is that I would like to have an anchor on every header of my blog posts. It should be possible to press a link to get the URL which leads directly to that anchor. Basically, I would like to resemble the functionality you see on the Microsoft docs (the post has some relation to Microsoft after all πŸ™‚ ).

MS documentation
MS Documentation

If you click this little chain symbol you will get the following link:

https://docs.microsoft.com/en-us/power-platform/alm/overview-alm#what-is-alm

This link will lead directly to the header “What is ALM” and you could share with others.

Since I don’t know which part you might find interesting of my articles and I don’t want to add it to every header manually I would like to add those icons automatically to every header.

Solution

After I searched the web a bit, I found a very interesting article of Jeroen Sormani that describes exactly that. I had to change it a bit to get it working, but the idea is the same.

We will have to

  • install a plugin to be able to use Font Awesome
  • add a function that processes the content and adds some HTML to it
  • add some CSS

Plugin

We would like to use one of the icons of Font Awesome, therefore we will install the official Font Awesome WordPress plugin to our instance.

Function

To add the needed HTML to all of the headers we have to add the following function to the functions.php file of our theme.

function auto_id_headings( $content ) {

  $content = preg_replace_callback( '/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i', function( $matches ) {
    if ( ! stripos( $matches[0], 'id=' ) ) :
      $heading_link = '<a href="#' . sanitize_title( $matches[3] ) . '" class="heading-anchor-link"><i class="fas fa-link"></i></a>';
      $matches[0] = $matches[1] . $matches[2] . ' id="' . sanitize_title( $matches[3] ) . '">' . $heading_link . $matches[3] . $matches[4];
    endif;

    return $matches[0];
  }, $content );

    return $content;

}
add_filter( 'the_content', 'auto_id_headings' );

This function basically does the following steps:

Creating an anchor

It adds an id attribute to the header-tag with the text of the header as the content. Spaces will be replaced with hyphens (“-“) and the text will be lowercase.

Adding the link

It also adds an a-tag that has a CSS class and the id of the header as the href-attribute.

Add icon

Within the a-tag it will add an i-tag that will show the font awesome icon.

Here is an example of an HTML that will be added

<h3 id="steps">
<a herf="#steps" class="heading-anchor-link"><i class="fas fa-link"></i></a>
Steps
</h3>

If you don’t have your own child theme, an update of your current theme will override the changes in both the function.php and the CSS file.

CSS

The last step is to add some CSS to make the icon look a bit nicer and only appear when one is hovering above the header.

The CSS I present here is working for my theme. It might need some changes to look nice for your setup.

First of all, we style the anchor link. We would like to show it beside the header without changing the position of the header. We also would like to hide it as the standard (opacity 0). The last line defines a smooth transition if the opacity is changed.

h2 a.heading-anchor-link,
h3 a.heading-anchor-link,
h4 a.heading-anchor-link,
h5 a.heading-anchor-link,
h6 a.heading-anchor-link{
	opacity:0;
	font-size: 1rem;
        position: absolute;
        left: 10px;
        transition: opacity 0.2s linear;
}

Secondly we would like to show the icon when we hover over the header.

h2:hover a.heading-anchor-link,
h3:hover a.heading-anchor-link,
h4:hover a.heading-anchor-link,
h5:hover a.heading-anchor-link,
h6:hover a.heading-anchor-link{
	opacity:0.7;
}

Last but not least we would like to make the icon a bit more visible when we hover over it itself.

h2:hover a.heading-anchor-link:hover,
h3:hover a.heading-anchor-link:hover,
h4:hover a.heading-anchor-link:hover,
h5:hover a.heading-anchor-link:hover,
h6:hover a.heading-anchor-link:hover{
	opacity:0.9;
}

Here you have the complete CSS

h2 a.heading-anchor-link,
h3 a.heading-anchor-link,
h4 a.heading-anchor-link,
h5 a.heading-anchor-link,
h6 a.heading-anchor-link{
	opacity:0;
	font-size: 1rem;
    position: absolute;
    left: 10px;
    transition: opacity 0.2s linear;
}

h2:hover a.heading-anchor-link,
h3:hover a.heading-anchor-link,
h4:hover a.heading-anchor-link,
h5:hover a.heading-anchor-link,
h6:hover a.heading-anchor-link{
	opacity:0.7;
}

h2:hover a.heading-anchor-link:hover,
h3:hover a.heading-anchor-link:hover,
h4:hover a.heading-anchor-link:hover,
h5:hover a.heading-anchor-link:hover,
h6:hover a.heading-anchor-link:hover{
	opacity:0.9;
}

Conclusion

As you can see it is quite easy to add an anchor to every header in your blog posts. You only need a few lines of code.

I got one step further and created a very simple WordPress Plugin that includes all those changes. You can find it on the WordPress Plugin store and the code on my GitHub. Everything should work if you install the Font Awesome Plugin and mine.

Because of the request of an individual I have added some functionality to the version you can download (Both from GitHub and the Plugin Store). It will now also handle if you add id’s manually or add several headers with the same text.

I hope this article helped you. Feel free to contact me if you have any questions. I am always happy to help.

1+

Add a Comment

Your email address will not be published. Required fields are marked *