Search code examples
jsonpugmixinsjavascript-objects

Accessing JSON attributes within Jade Mixins


Motivation

I have some ugly working code embedded in my Jade template and I want to move it to a mixin so it is more readable, maintainable, etc.

The code

A simplified equivalent version of the mixing would be:

mixin mixinName(param1, param2, paramObject)
    .tile(class="#{param1 >= paramObject['atr1'] && param1 < paramObject['atr1'] + paramObject['atr2'])?'additionalClass':''"}) &nbsp;

Why do I think this should work?

If instead of &nbsp; I put paramObject I get the object contents in the HTML like {atr1: 2, atr2: 2}, so they are there. If I instead put paramObject['atr1'] or paramObject.atr1, etc. I only get a blank space. My guess is I am not accessing the attributes properly.

The jade code context

I think it is not needed but here it is.

...
template(repeat="{{col in columns | enumerate}}")
    .col
        template(repeat="{{tile in col.value | enumerate}}")
            +mixinName("{{col.index}}", "{{tile.index}}", "{{cursor}}")
...

Ugly workaround solution

I think this is ugly because I really have many more params, and many more attributes/fields I need to compare within the paramObject, so it just clutters the rest of the Jade template.

mixin mixinName(param1, param2, paramObjectAtr1, paramObjectAtr2)
    .tile(class="#{param1 >= paramObjectAtr1 && param1 < paramObjectAtr1 + paramObjectAtr2)?'additionalClass':''"}) &nbsp;

The jade code context

Basically the same as before, but sending each object parameter as a different parameter.

...
template(repeat="{{col in columns | enumerate}}")
    .col
        template(repeat="{{tile in col.value | enumerate}}")
            +mixinName("{{col.index}}", "{{tile.index}}", "{{cursor['atr1']}}", "{{cursor['atr2']}}")
...

Solution

  • It's strange that paramObject works in place of &nbsp. Jade syntax should be:

    .tile(...)= paramObject
    

    or

    .tile(...) #{paramObject}
    

    If you just use space after the tag or class name, Jade thinks you mean plain text, not JS code.

    As for your mixin, you can go:

    mixin mixinName(param1, param2, paramObject)
      - var moarClasses = [];
      - if (param1 >= paramObject.atr1 &&
      -     param1 < paramObject.atr1 + paramObject.atr2)
      -   moarClasses.push('additionalClass');
    
      .tile(class=moarClasses)= paramObject.atr3