paint-brush
How to Insert Jump Anchors on Headings with PugJSby@spekulatius
129 reads

How to Insert Jump Anchors on Headings with PugJS

by PeterDecember 12th, 2019
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

PugJS is a JavaScript template engine that turns Pug-lang into HTML. You can have conditional content without client-side JavaScript. Use variables to set content and attributes across your site or application. Declare Mixins to define HTML tags, attributes, and more. Freely componentize your project files using inheritance and includes. Add dynamic anchors to headings using Pug-Mixins to allow you to jump directly to a certain part of the document. Use a mixin-example for daily coding.

Company Mentioned

Mention Thumbnail
featured image - How to Insert Jump Anchors on Headings with PugJS
Peter HackerNoon profile picture

I'm definitely a fan of cats 😺️ in real life, but when it comes to
code this reverses and I've got a preference for Pug 🐶️ For those who
aren't coders: PugJS is a JavaScript template engine. It converts
Pug-lang into HTML. I know there is more power in PugJS, besides the
simple turning the Pug-lang into HTML. At the moment I'm not using the
potential of the language - I use PugJS mostly to hold my content. Let's
look at some ways to get more out of Pug I've learned about recently.

If you are using Pug on your static-site you can:

  • Use variables to set content and attributes across your site or application.
  • Declare Mixins to define HTML tags, attributes, and more. More about this later.
  • Freely componentize your project files using inheritance and includes. This
    allows you to build up a project structure you like. I like to keep the
    same structure as the related SCSS files - just avoiding unneeded
    complexity in the project.
  • You can have conditional content without client-side JavaScript. A simple example could be:
  • - var promo_is_live = false;
    
    if promo_is_live
        h2 Special deal!
        p Get our super special promotional offer!
        p.price Only $9.99
    else
        p.price Only $19.99

This content will be dynamically-included on each compile of the HTML output, depending on the variable

promo_is_live
. If you switch the flag to false, any related content won't be included in the output at all.

This keeps your site clean and tidy, avoids exposure of time-sensitive information (such as the annual Christmas promotion) and at the same
time avoids the need to manually add and remove code for promotions and temporary content every time. Avoiding hidden content can be useful if you’re aiming to optimize your site for search engines as well.

Pug is a powerful template engine and a read over the language reference is good for some "Ahhh, neat"-moments! Below, you will find a useful mixin-example applicable for daily coding.

An example: Adding dynamic anchors to headings using Pug-Mixins

Often you might want an

id
to allow you to jump directly to a certain part of the document. For me, these are usually headings. The heading above "An example: Adding dynamic anchors to headings using Pug", one could write:

h2(id="an-example-adding-dynamic-anchors-to-headings-using-Pug").
    An example: Adding dynamic anchors to headings using Pug

This triggers me, as it's error-prone, overhead to read as developer and overhead to maintain. Wouldn't it be nicer if you could avoid the double content and could instead generate the slug out of the heading on the fly? With Pug mixins you can:

mixin h2(headline)
  - let id = headline.toLowerCase().replaceAll(' ', '-').replace(/[!\"#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, '');
  h2(id= id)
    = headline

With this little helper Pug-mixin you can just write

+h2('An example: Adding dynamic anchors to headings using Pug')

and it will be processed to

<h2 id="an-example-adding-dynamic-anchors-to-headings-using-Pug">
  An example: Adding dynamic anchors to headings using Pug
</h2>

Isn't this a much better developer-experience? :)

Taking it one step further

You can also make the heading level a parameter handed over to the mixin:

mixin h(level, headline)
  - let id = headline.toLowerCase().replace(' ', '-').replace(/[!\"#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, '');
  section(id= id)
    #{'h' + level}= headline
    if block
      block

This allows you to write the following Pug-code:

+h(2, 'Section A')

+h(2, 'Section B')
  p Lorem ipsum dolor amit

+h(2, 'Section C')
  p Lorem ipsum dolor amit
  +h(3, 'Section C, Subsection A')
    p Lorem ipsum dolor amit

and this will be compiled to the HTML shown below:

<section id="section-a">
  <h2>Section A</h2>
</section>

<section id="section-b">
  <h2>Section B</h2>
  <p>Lorem ipsum dolor amit</p>
</section>

<section id="section-c">
  <h2>Section C</h2>
  <p>Lorem ipsum dolor amit</p>
  <section id="section-c-subsection-a">
    <h3>Section C, Subsection A</h3>
    <p>Lorem ipsum dolor amit</p>
  </section>
</section>

This allows you to define any level of heading dynamically, on the fly.

Summary and Source

As mentioned above, the language can do more. Mixins are only one powerful side of PugJS. Have a look at the language reference for more
information. By the way, if you are a fan of Netlify too I have good
news for you. Of course, you can use Pug with your Netlify-hosted website.

Praise where praise is due: Thanks to the Pug maintainers for their great
work. I have to say "Thank you" to Sean who pointed me to the
possibilities answering my question on Stackoverflow as well.

Previously published at https://peterthaleikis.com/posts/how-to-insert-jump-anchors-on-headings-with-pugjs/.