Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using pug mixin arguments inside attributes using string interpolation #2757

Closed
camelofcode opened this issue Mar 12, 2017 · 3 comments
Closed

Comments

@camelofcode
Copy link

camelofcode commented Mar 12, 2017

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 !== ''")

But at this point, its barely a template and I might as well just copy and paste.

My final stuff looks like this when working around it, which is messier than I'd like when classing the templates, especially the last two which have multiple attributes

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 print passed valuesstring interpolation within attributes inside a pug mixin?

(Also asked http://stackoverflow.com/questions/42749773/using-pug-mixin-arguments-inside-attributes-using-string-interpolation)

@jbsulli
Copy link
Contributor

jbsulli commented Mar 13, 2017

I think you are close. The attribute values are evaluated as plain JavaScript expressions. So any of the following should work:

//- string concatination
tr(ng-show="{" + value + "} && {" + value + "} !== ''")

//- JavaScript template literals
tr(ng-show=`${value} && ${value} !== ''`)

@camelofcode
Copy link
Author

Thanks for the advice - very helpful. I'd completely forgotten about needing backticks when doing ES6 string interpolation!

Implementing properly, I now have the much nicer, and exactly what I wanted:

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

+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)

I've got a whole project of stuff done whilst first learning pug (then jade) and angular that could do with a serious refactor using this stuff!

Many thanks again.

@jbsulli
Copy link
Contributor

jbsulli commented Mar 13, 2017

Awesome! Glad to help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants