Is it possible to create aliases for pug mixins? I have a library of generic mixins for a project, but then have another mixin that when I call it I want to modify the behavior of some of the generic mixins within the body of the complex mixin. So, in code that I know doesn't work, I'd like to do something like:
//- Generic mixins
mixin input(inputObj)
//- does some things
//- Complex mixin
mixin complex
mixin _input = input
mixin input
//- does some slightly different things from the base input mixin.
//- and then calls the base input mixin via it's newly defined alias
_input
//- Invoked like so:
//- Invokes the base input
+input({name:'some name'})
//- invoke the complex section
+complex
//- Invoke the input defined in the complex section instead of the base mixin
+input({name:'name for complex mixin'})
Is it possible to create aliases for pug mixins? I have a library of generic mixins for a project, but then have another mixin that when I call it I want to modify the behavior of some of the generic mixins within the body of the complex mixin. So, in code that I know doesn't work, I'd like to do something like:
//- Generic mixins
mixin input(inputObj)
//- does some things
//- Complex mixin
mixin complex
mixin _input = input
mixin input
//- does some slightly different things from the base input mixin.
//- and then calls the base input mixin via it's newly defined alias
_input
//- Invoked like so:
//- Invokes the base input
+input({name:'some name'})
//- invoke the complex section
+complex
//- Invoke the input defined in the complex section instead of the base mixin
+input({name:'name for complex mixin'})
Share
Improve this question
asked Mar 28 at 5:30
Scott CaseyScott Casey
931 silver badge12 bronze badges
2
- Can you provide a concrete minimal example of the kind of thing you want both mixins to do? It'll be easier for folks to give you helpful answers. – Sean Commented Mar 28 at 21:25
- Found the answer while debugging some other code. – Scott Casey Commented yesterday
2 Answers
Reset to default 1It's hard to answer without more concrete details about the things you envision both mixins doing, but it sounds like a viable approach would be to have a single mixin with an additional boolean argument with a default value that you could use as a flag to do the optional things.
A contrived example: A mixin for a link that has two "variants"—
The simple, default behavior just wraps the provided text in an anchor with a class
The "complex" version does some "slightly different things" (in this case it changes the text to all caps, adds an additional class, and adds an icon)
mixin link(href, complex = false)
if complex
- text = text.toUpperCase()
a.link(href= href, class= complex ? 'additional-class' : '')
if complex
img(src='icon.svg')
if block
block
+link('/') simple link
+link('/', true) complex link
This renders—
<a class="link" href="/">simple link</a>
<a class="link additional-class" href="/"><img src="icon.svg"/>COMPLEX LINK</a>
Alternatively, you can call one mixin from within another—
mixin simple(href)
a.link(href= href)&attributes(attributes)
if block
block
mixin complex(href, text)
- text = text.toUpperCase()
+simple(href).additional-class
img(src='icon.svg')
| #{text}
+simple('/') simple link
+complex('/', 'complex link')
This renders HTML identical to the previous example—
<a class="link" href="/">simple link</a>
<a class="link additional-class" href="/"><img src="icon.svg"/>COMPLEX LINK</a>
Found the answer on how to do this. As a basic example of what I'm trying to do:
//- A basic mixin that just does some registering of the inputs that have been created using it.
mixin input(inputObj)
- inputObj.type = inputObj.type || 'text';
- registeredInputs.push(inputObj.name);
input&attributes(inputObj)
//- A mixin that defines a unique section where we want to log each form element that is created and adds a span before the created form element
mixin override
- pug_mixins._input = pug_mixins.input;
mixin overInput(inputObj)
- console.log('override input',inputObj);
span
|#{inputObj.name}
+_input(inputObj)&attributes(attributes)
- pug_mixins.input = pug_mixins.overInput;
block
-pug_mixins.input = pug_mixins._input;
//- Use the various forms of the mixins
+input({name:'before_override',type:'text'})
+override
+input({name:'in_override',type:'number'})
+input({name:'after_override',type:'hidden'})
The pug_mixins
object is created by the pug parser as part of parsing the pug language and we can use that to manipulate what mixin is actually called by a given mixin call.
Along with console logging the inputObj for the input created within the override, it creates the following html (prettified for easier demonstration):
<input name="attr_before_override" type="text" title="@{before_override}"/>
<span>in override</span>
<input name="attr_in_override" type="number" title="@{in_override}"/>
<input name="attr_after_override" type="hidden" title="@{after_override}"/>
Using this method, I can now create shadow versions of generic mixins in the project to add additional functionality when within certain other mixins. This will be useful for logging certain data and registering created data.