Bat
Bat

Reputation: 255

Jade / Pug: how to use a mixin in a parameter array of another mixin

I'm trying to use atomic design pattern in Jade / Pug to create a simple list with a link in it. My list mixin is as follows and accepts an array of items:

include ../../atoms/listitem/listitem
mixin list(spec)
    - spec = spec || {}
    - spec.__class = spec.__class || ''
    - spec.type = spec.type || 'ul'
    - spec.items = spec.items || {}

    if spec.items.length
        #{spec.type}
            for item in spec.items
                +listitem({content: item})

List item:

mixin listitem(spec)
    - spec = spec || {}
    - spec.__class = spec.__class || ''
    - spec.content = spec.content || ''

    li(class=spec.__class)&attributes(attributes)
        != spec.content

Link:

mixin link(spec)
    - spec = spec || {}
    - spec.__class = spec.__class || ''
    - spec.text = spec.text || 'Default Link'

    a.link(class=spec.__class)&attributes(attributes)
        if block
            block
        else
            != spec.text

And in my template I have the following:

include _modules/atoms/link/link
include _modules/molecules/list/list

block content
    +list({items: [
        'list item 1',
        'list item 2',
        +link({text: "Hi link"})(href="#"),
        'list item 4'
    ]})

I'm getting an error:

link is not a function

But if I use the link outside of that items array it's working just fine. What am I doing wrong?

Upvotes: 0

Views: 3816

Answers (2)

litel
litel

Reputation: 3980

Alas, you cannot pass a mixin in Jade as argument for another mixin. If you want to preserve your format for the most part: in order to get the functionality you'd want, you'll have to use type detection in multiple instances and pass your argument as an array.

mixin listitem(spec)
    - spec = spec || {}
    - spec.__class = spec.__class || ''
    - spec.content = spec.content || ''

    li(class=spec.__class)&attributes(attributes)
       if (typeof spec.content === 'string') 
         != spec.content
       else
         block

mixin link(spec)
    - spec = spec || {}
    - spec.__class = spec.__class || ''
    - spec.text = spec.text || 'Default Link'
    - attributes = spec.attributes || ''


    a.link(class=spec.__class)&attributes(attributes)
        if block
            block
        else
            != spec.text


mixin list(spec)
    - spec = spec || {}
    - spec.__class = spec.__class || ''
    - spec.type = spec.type || 'ul'
    - spec.items = spec.items || {}

    if spec.items.length
        #{spec.type}
            for item in spec.items
               +listitem({content: item})
                 if (item[0])
                   +link(item[0])


block content
    +list({items: [
        'list item 1',
        'list item 2',
        [{text: "Hi link"}],
        'list item 4'
    ]})

Upvotes: 2

Sean
Sean

Reputation: 8032

A mixin can't be an object in an array. Consider reformatting your object and approaching the problem like this (simplified to communicate concept):

-
  var myList = [
    {text: 'list item 1'},
    {text: 'list item 2', link: '#'},
    {text: 'list item 3'}
  ];

mixin list(listObject)
  ul
    for each listItemObject in listObject
      +listItem(listItemObject)

mixin listItem(listItemObject)
  li
    if (listItemObject.link.length > 0)
      a(href= listItemObject.link)= listItemObject.text
    else
      #{listItemObject.text}

Upvotes: 0

Related Questions