<p>Tons of ways to skin this cat; a simple option is to use <a href="https://stackoverflow.com/questions/7704253/how-to-concatenate-strings-in-twig">string concatenation</a>, which could look like the below example. Note that I'm actually creating a new variable for <code>classes</code> at the top of the macro, which IMO helps clean up the markup a little bit and also makes it a bit more clear what's going on – you can continue to do this logic "inline" if you want to, of course.</p>

<p>Also note that the <code>default</code> filter has been omitted from the Twig statement rendering the <code>classes</code> variable; it's redundant now because the <code>classes</code> variable will always be set.</p>

<pre><code>{% macro button(label, link, width, classes, colours, textclasses, alignment) %}
    {% set classes = 'flex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-moreflex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-more' ~ (classes ? ' ' ~ classes) %}
    &lt;a href="{{ link }}" class="btn {{ width|default('w5') }} {{ colours|default('bg-tdgreen white') }} {{ classes }} {{ alignment|default('center') }}"&gt;
        &lt;p class="ttu center mv0 {{ textclasses|default('') }}"&gt;{{ label }}&lt;/p&gt;
    &lt;/a&gt;
{% endmacro %}
</code></pre>

<p>The important bit is the <code>... ~ (classes ? classes)</code> part, which basically appends the <code>classes</code> macro parameter to the default classnames, if the parameter is set.</p>

<p>A variation on the above solution, and – in my opinion – maybe a bit cleaner, is to use an array that is joined (i.e. flattened to a string):</p>

<pre><code>{% macro button(label, link, width, classes, colours, textclasses, alignment) %}{% macro button(label, link, width, classes, colours, textclasses, alignment) %}
    {% set classes = ['flex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-moreflex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-more', classes]|filter|join(' ') %}
    ...
{% endmacro %}
</code></pre>

<p>Basically, in the above the <code>classes</code> <em>variable</em> is an array containing the default classes and whatever was passed in the <code>classes</code> <em>parameter</em>. The array is piped through the <a href="https://docs.craftcms.com/v3/dev/filters.html#filter" rel="nofollow noreferrer"><code>filter</code></a> Twig filter, which removes any null/undefined values (i.e. it removes the <code>classes</code> parameter value if one wasn't set), and finally <a href="https://twig.symfony.com/doc/2.x/filters/join.html" rel="nofollow noreferrer"><code>join(' ')</code></a> which merges the two array values together with a space (which means it's now a string and you can do <code>{{ classes }}</code> to print the whole thing).</p>

CC BY-SA 4.0
2018-07-26T07:50:59.953Z
Ah, this is perfect and exactly what I was looking for. It definitely makes a lot more sense (and is much cleaner) doing it this way. Thanks so much!
fbnntt
CC BY-SA 4.0
2018-07-25T11:36:11.730Z
2018-07-25T11:36:11.730Z
Mats Mikkel Rummelhoff
<p>I'm fairly new to using macros and haven't found anything online regarding this — sorry if this is a possible duplicate post.</p>

<p>I've created a macro with 7 possible parameters but on different templates I want to add to the default classes.</p>

<pre><code>{% macro button(label, link, width , classes, colours, textclasses, alignment) %}
  &lt;a href="{{ link }}" class="btn {{ width|default('w5') }} {{ colours|default('bg-tdgreen white') }} {{ classes|default('flex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-more') }} {{ alignment|default('center') }}"&gt;
    &lt;p class="ttu center mv0 {{ textclasses|default('') }}"&gt;{{ label }}&lt;/p&gt;
  &lt;/a&gt;
{% endmacro %}
</code></pre>

<p>Is there a way of doing this without having to set a variable with all the defaults in it and tacking on new classes? For example:</p>

<pre><code>{% set buttonClasses = "absolute w5-ns l-50 tc pa2 pa3-ns ph3 br2 z-max link white f6 flex mt--18 mt--25-ns underline-hover tracked-more" %}
  {% if buttonPosition == 'above' %}
    {% set buttonClasses = buttonClasses ~ " top-0" %}
  {% endif %}
{{ macros.button(block.ctaText, block.ctaLink.one().url, "", buttonClasses) }}
</code></pre>

<p>Any help would be appreciated!</p>

<p>— Thanks</p>

<templating><craft3><macro>
Adding to default classes in a macro
# Adding to default classes in a macro

(Asked by: username_0 on 2018-07-25)

I'm fairly new to using macros and haven't found anything online regarding this — sorry if this is a possible duplicate post.
I've created a macro with 7 possible parameters but on different templates I want to add to the default classes.
{% macro button(label, link, width , classes, colours, textclasses, alignment) %}
  
    {{ label }}
  
{% endmacro %}

Is there a way of doing this without having to set a variable with all the defaults in it and tacking on new classes? For example:
{% set buttonClasses = "absolute w5-ns l-50 tc pa2 pa3-ns ph3 br2 z-max link white f6 flex mt--18 mt--25-ns underline-hover tracked-more" %}
  {% if buttonPosition == 'above' %}
    {% set buttonClasses = buttonClasses ~ " top-0" %}
  {% endif %}
{{ macros.button(block.ctaText, block.ctaLink.one().url, "", buttonClasses) }}

Any help would be appreciated!
— Thanks

**Tags:** templating, craft3, macro


---

## 1 answers

### Answer by username_1 on 2018-07-25. Score: 2 | Accepted answer

Tons of ways to skin this cat; a simple option is to use string concatenation, which could look like the below example. Note that I'm actually creating a new variable for classes at the top of the macro, which IMO helps clean up the markup a little bit and also makes it a bit more clear what's going on – you can continue to do this logic "inline" if you want to, of course.
Also note that the default filter has been omitted from the Twig statement rendering the classes variable; it's redundant now because the classes variable will always be set.
{% macro button(label, link, width, classes, colours, textclasses, alignment) %}
    {% set classes = 'flex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-moreflex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-more' ~ (classes ? ' ' ~ classes) %}
    
        {{ label }}
    
{% endmacro %}

The important bit is the ... ~ (classes ? classes) part, which basically appends the classes macro parameter to the default classnames, if the parameter is set.
A variation on the above solution, and – in my opinion – maybe a bit cleaner, is to use an array that is joined (i.e. flattened to a string):
{% macro button(label, link, width, classes, colours, textclasses, alignment) %}{% macro button(label, link, width, classes, colours, textclasses, alignment) %}
    {% set classes = ['flex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-moreflex pa2 pa3-ns ph3 tc lh-solid f7 f6-ns link underline-hover z-999 br2 mv3 tracked-more', classes]|filter|join(' ') %}
    ...
{% endmacro %}

Basically, in the above the classes variable is an array containing the default classes and whatever was passed in the classes parameter. The array is piped through the filter Twig filter, which removes any null/undefined values (i.e. it removes the classes parameter value if one wasn't set), and finally join(' ') which merges the two array values together with a space (which means it's now a string and you can do {{ classes }} to print the whole thing).

> **Comments:**
> **username_0**: Ah, this is perfect and exactly what I was looking for. It definitely makes a lot more sense (and is much cleaner) doing it this way. Thanks so much!  

---

