Mixins are like functions and allow you to reduce repetitive content.
Naming
Mixins names should be written in camelCase. Use UpperCamelCase for exported mixins, more on that in the next chapter.
Parameters
Unlike functions, mixins have unordered parameters that must be set by name. When defining the mixin you may set defaults for parameters that are optional. Required parameters must always have a type, the type of optional parameters will be inferred from the default value.
Corgi may sometimes not be able to infer the type of an optional parameter by it's default expression. Don't worry, should that be the case, the corgi compiler will tell you.
In such cases it may be necessary for you to explicitly define the type, like for the bar parameter below.
mixin myMixin(foo string, bar string = "baz", foobar = "foozbaz", fooz = nil)
p
> #{foo}, #{bar}, #{foobar}
if fooz != nil
> , #{fooz}
div: +myMixin(foo="abc", foobar="def")
<div><p>abc, baz, def</p></div>
You can use any expression to set a parameter including ternary and chain expressions.
When using a chain expression, the parameter will only be set if the chain expression passes its checks. When using a chain expression for a required parameter you must provide a default.
If you have parameters that accept URLs or srcset values, you should set their type to woof.URL or woof.Srcset to leverage corgi's contextual escaping.
Blocks allow you to define placeholders for longer content.
Each block is named. If you only have a single block, it is conventional to call it _.
mixin foo()
p: block _
div
+foo()
block _ This is the content of the block.
<div>
<p>
This is the content of the block.
</p>
</div>
You are not limited to just one block. If you want, you can use multiple of them.
mixin namedBlocks()
div
p: block myFirstBlock
p: block myOtherBlock
div
+namedBlocks()
block myFirstBlock
&.foo
> This text will appear in the first <p>.
block myOtherBlock
> This text will appear in the second <p>.
<div>
<div>
<p
class="foo">
This text will appear in the first <p>.
</p>
<p>
This text will appear in the second <p>.
</p>
</div>
</div>
Block Short Form
If you only want to fill the _ block, then you can use one of the block short forms. All of the below examples are equivalent.
div
+foo()\
> Beam me up, Scotty!
div
+foo() Beam me up, Scotty!
div
+foo():> Beam me up, Scotty!
<div>
<p>Beam me up, Scotty!</p>
</div>
Defaults and Checking If a Block Exists
Just like parameters, you can also define defaults for blocks.
mixin withDefaults()
p
block _
> Nothing to see here.
Unlike parameters, there are no "required" blocks. If you don't define a default for a block, it is assumed that the default is simply nothing.
+withDefaults()
+withDefaults() A lot to see here.
<p>Nothing to see here.</p>
<p>A lot to see here.</p>
You can also use an if block conditional to check if a block exists.
mixin leftRight()
div(style="display: flex; justify-content: space-between;")
div: block left
if block right
div: block right
+leftRight()
block left
p Left only
+leftRight()
// no block left
block right
p Right only
+leftRight()
block left
p Left...
block right
p ...and right
p And then he said: #+beam()
p And then he said: #+beam(verb="Fly")
p And then he said: #+beam()[Chekov]
- sulu := "Sulu"
p And then he said: +beam(){sulu}
<p>And then he said: Beam me up, Scotty!</p>
<p>And then he said: Fly me up, Scotty!</p>
<p>And then he said: Beam me up, Chekov!</p>
<p>And then he said: Beam me up, Sulu!</p>
Mixins As Attribute Values
Mixins that only generate text (and no elements, or attributes) can be used as values for attributes.
The syntax is the same as for interpolated mixins, minus the leading #.