How to tranform Headlines into linkable permalinks?

My WordPress site has fairly long entries and includes many data visualisations. I want to make it easier for visitors to refer to a specific part of a page and therefore would like to make it easy to link to a specific headline.

I would like to make it possible for the visitors to link to the ‘id’ of a headline. I think the perfect solution is the one at GitHub. For example a link like this: https://example.com/foo/bar#anchor-name. When you hover over any headline a small symbol signals that you can link to this position in the document.

Read More

The closest thing I’ve found is this plugin, which only works for Posts.

Edit:

Thanks for the very helpful comments! In the end I managed to do it with the help of the mentioned add-ids-to-header-tags-plugin. I changed it so that it also works for pages by using

if ( ! is_singular() ) {

instead of

if ( ! is_single() ) {

.
If someone is interested in what the result looks like, here is the page I’m using it for: http://www.explainingprogress.com/data/population-growth-vital-statistics/child-mortality/

Related posts

3 comments

  1. Analysed situation

    When you take a look at your (original) example “GitHub” and it’s source code, you see the following:

    <a name="updating-submodules" class="anchor" href="#updating-submodules">
        <span class="octicon octicon-link"></span>
    </a>
    

    Prerequisites

    Basically this is possible (even pretty easy), but you’ll have to have theme templates that properly use WordPress Templates Tags. The functions that are needed are the_permalink() or the underlying get_the_permalink() and an action/callback on that filter.

    Styles/Icons

    First off, WordPress registers dashicons per default, so they are ready for enqueuing. So we simply need:

    add_action( 'wp_enqueue_scripts', 'wpseDashiconsFrontEnd' );
    function wpseDashiconsFrontEnd()
    {
        wp_enqueue_style( 'dashicons' );
    }
    

    To use them, we pass its CSS class dashicons-[name] to any element where we are going to use it on. Take a look at the Dashicons site, click icon and look at the name for it on top.

    Add the anchor link:

    Now when WordPress calls the permalink to a post, it normally looks close to the following:

    the_title(
        sprintf(
            '<h2><a href="%s" title="%s">',
            get_the_permalink(),
            get_the_title()
        ),
        '</a></h2>',
    );
    

    Then we want to transform it to something like the following:

    the_title(
        sprintf(
            '<h3><a href="#%1$s" name="%1$s" class="anchor"><span class="anochor-icon dashicons-admin-links"></span>',
            get_the_title()
        ),
        '</a></h3>',
    );
    

    Obviously you want to have .anchor span with display: none; per default in your main stylesheet and only show it on h3:hover .anchor .anchor-icon with display: inline-block;.

    Additional info

    If this is not about a list of headlines for posts, pages or any other custom post type, then you’ll need an action on the content filter that makes a DOMDocument::XPath search to add the needed MarkUp.

    You could as well just write a 10 line custom plugin that hooks into get_the_title() and adds the needed output.

  2. I agree with Mayeenul, but the problem is normalizing the creation of bookmarks from within the WordPress theme. This would be easy enough to accomplish with the post title, but the sub-headings are generated manually when writing the post. There is no way to get the content of the sub-headings of the post without JavaScript. Try this:

     <script type="text/javascript" src="http://www.google.com/jsapi"></script>         
     <script type="text/javascript">
            google.load("jquery", "1.3.2");
    
            google.setOnLoadCallback(function() {
                // initalize variable
                var $menu = '';
                // select all the page headings, assuming that h1 is only used once (for the main page title)
                $("h2, h3, h4, h5, h6").each(function () {
                    // Dirify heading text to create the anchor
                    $anchor = dirify($(this).text());
                    };
                    // Append anchor to heading
                    $(this).append('<a title="Link to this section" class="anchor" href="#' + $anchor + '"> ¶</a>').attr('id', $anchor);
                });
            });
        </script>
    

    This won’t work without also including the dirify() function from here:

    http://www.beausmith.com/mt/2009/07/dirify-function-in-javascript.php

    Here’s the working fiddle:

    http://jsfiddle.net/7Tj2v/

  3. Linking to a subheading is called Bookmarking. It can be done using a simple anchor tag, but no actual http link inside it.

    <a href="#my-sub-heading">My Sub Heading</a>
    

    So with this, the complete link will be:

    http://example.com/main-heading#my-sub-heading
    

    Hope it answers you.

    If the plugin do the thing manually, you can modify it to work for pages and custom post types also. Just you have to deal with 'post_type' = 'page' or 'your-custom-post-type'.

Comments are closed.