razethestray
razethestray

Reputation: 676

Using pug mixin arguments inside attributes using string interpolation

I'm using angular and pug, and have the following template

mixin row(label, value)
    tr       
        td 
            strong= label
        td 
            span= "{{" + value + "}}"

Which I'm then using like

    +row("Dates", "data.dates")
    +row("Venue", "data.venue")
    +row("Meals", "data.meals")

Which is working fine, generating the following, which angular then binds to and populates the data as expected:

<tr>
    <td>Dates</td>
    <td>{{data.dates}}</td>
</tr>
<tr>
    <td>Venue</td>
    <td>{{data.venue}}</td>
</tr>
<tr>
    <td>Meals</td>
    <td>{{data.meals}}</td>
</tr>

But I'd like to be able to use the value parameter within attributes so I can do stuff like

mixin row(label, value)
    tr(ng-show="{value} && {value} !== ''"       
        td 
            strong= label
        td 
            span= "{{" + value + "}}"

with the intention that this gets compiled to

<tr ng-show="data.dates && data.dates !== ''">
    <td>Dates</td>
    <td>{{data.dates}}</td>
</tr>
<tr ng-show="data.venue && data.venue !== ''">
    <td>Venue</td>
    <td>{{data.venue}}</td>
</tr>
<tr ng-show="data.meals && data.meals !== ''">
    <td>Meals</td>
    <td>{{data.meals}}</td>
</tr>

But I can't get this to work. I've tried a variety of different escaping techniques:

   {value}
   {{value}}
   #{value}
   #{{value}}
   ${value}
   ${{value}}
   \#{value}
   \{value}

But nothing has worked. Can't find anything at all in the docs either.

I've come up with a few workarounds, passing the attributes in like

+row("Dates", "data.dates")(ng-show="data.dates && data.dates !== ''")

which in my final code is really messy

mixin row(label, value)
        tr(ng-show!=attributes.ngShow)        
            td 
                strong= label
            td 
                span(class="preserve-newlines" ng-bind-html!=attributes.ngbindhtml)= "{{" + value + "}}" 

+row("Dates", "data.dates")
+row("Venue", "data.venue")(ngShow="data.venue && data.venue !== ''")
+row("Meals", "data.meals")(ngShow="data.meals && data.meals !== ''")
+row("Accommodation", "data.accommodation")(ngShow="data.accommodation && data.accommodation !== ''")
+row("Check-in", "data.checkin")(ngShow="data.checkin && data.checkin !== ''")
+row("Donation", "data.donation")(ngShow="data.donation && data.donation !== ''")
+row("Registration", "data.registration")(ngShow="data.registration && data.registration !== ''")
+row("Contact", "data.contact")(ngShow="data.contact && data.contact !== ''")
+row("Telephone", "data.telephone")(ngbindhtml="getTrusted(data.telephone)" ngShow="data.telephone && data.telephone !== ''")
+row("Email", "data.email")(ngbindhtml="getTrusted(data.email)" ngShow="data.email && data.email !== ''")

But at this point, its barely a template and I might as well just copy and paste, since I am already writing all the attributes for each row out separately even though they could be vastly simplified if I could just use string interpolation within attributes inside a pug mixin.

So, how do I use string interpolation within attributes inside a pug mixin?

Upvotes: 0

Views: 1672

Answers (1)

razethestray
razethestray

Reputation: 676

I asked over on pugs github, and with some help from somebody over there managed to figure it out.

Essentially, the attribute strings are evaluated as plain JavaScript expressions, so any form of building a string will work. I went for ES6 style string interpolation as it seemed nicest, resulting in

mixin row(label, model, html)
    tr(ng-show=`${model} && ${model} !== ''`)        
        td 
            strong= label
        td
            if html
                span(class="preserve-newlines" ng-bind-html=`getTrusted(${model})`)= "{{" + model + "}}" 
            else
                span(class="preserve-newlines")= "{{" + model + "}}" 

+row("Dates", "data.dates")
+row("Venue", "data.venue")
+row("Meals", "data.meals")
+row("Accommodation", "data.accommodation")
+row("Check-in", "data.checkin")
+row("Donation", "data.donation")
+row("Registration", "data.registration")
+row("Contact", "data.contact")
+row("Telephone", "data.telephone", true)
+row("Email", "data.email", true)

Upvotes: 2

Related Questions