Search code examples
javascripttemplatespug

Using Pugjs, what's the proper way to include a mixin within a links href attribute?


tl;dr: What's the proper way to insert a mixin within a links href attribute?


I'm starting to use Pug but I ran into an issue when I tried to use a mixin to generate an attributes value. Within my template I need to use a shortcode from a third-party website to include the phone number (and other settings) dynamically; which I've created a simple mixin to generate:

//- mixins.pug

mixin setting(value)
    | [setting:#{value}]

Within my header.pug template I am trying to code a default link for the phone number, which I'm inserting within the right-widget block; using a three-column header. The shortcode that the mixin generates, when processed by the third party server, grabs the phone number from their database.

//- header.pug

block right-widget
    h3.title
        | Call:
        a(href='tel:' +setting('Company Phone'))
            +setting('Company Phone')
    +button_reserve

When I try and include the setting mixin so it creates the shortcode for the phone number, it ends up being inserted as a string. Here is an example of the generated HTML:

<h3 class="title">
    Call: <a href="tel:" settings('Company="settings('Company" Phone')="Phone')">companyPhone</a>
</h3>

Instead of the desired result:

<h3 class="title">
    Call: <a href="tel:[setting:Company Phone]">[setting:Company Phone]</a>
</h3>

A solution I tried was using unbuffered code to include the mixin like so:

//- header.pug

block right-widget
    - var phone = +setting('Company Phone')
    h3.title
        | Call:
        a(href='tel:' + phone)
            phone
    +button_reserve

But when I do this, I get an error saying that setting (the mixin) is not a function. I also tried it without var as well, just to see what would happen. When searching, I see nothing discussing this. The solutions I tried were from this stackoverflow post. Both of the single line & multi line solutions must be outdated, because they did not work for me.

What's the best way to go about setting this up?


Solution

  • Mixins are meant to be used at the tag level. A simple mixin for your a tag could be:

    mixin setting(value)
      a(href= 'tel:[setting:' + value + ']')= '[setting:' + value + ']'
    

    You can also use javascript functions to do things like string manipulation:

    - let settingString = (value) => { return '[setting:' + value + ']'}
    

    Combining them can be powerful, and is likely what you're looking for:

    // function
    - let settingString = (value) => { return '[setting:' + value + ']'}
    
    // mixin (that uses the function)
    mixin settingLink(value)
      a(href= 'tel:' + settingString(value))= settingString(value)
    
    // mixin call
    h3.title
      | Call: 
      +settingLink('Company Phone')
    

    This renders:

    <h3 class="title">
      Call: <a href="tel:[setting:Company Phone]">[setting:Company Phone]</a>
    </h3>