<p>So in this case with <code>ctaUrl</code>, the issue is that you are checking <code>if ctaUrl is defined</code>. </p>

<p>As long as a field exists, <code>is defined</code> will return <code>true</code> as in reality, the variable <code>block.ctaUrl</code> exists, it's just empty. To check for content in your case, you should test for <code>NULL</code>. So <code>if ctaUrl is not NULL</code> show your link.</p>

<p>In terms of organisation of your code, it's up to you. Like Roi said, you don't need the <code>with</code>. Your <code>matrixBlocks</code> will be available within the component. </p>

<p>Whether you set stuff up in the main template is up to you. Personally, I would do my logic in the component rather than the main templates. </p>

<p>You will need to be consistant with your naming but the component is where you need this logic so if it's is in there, you don't need to dig around to understand what is going on. If you remove a component, the logic goes with it as suppose to have a bloated main template and also, you don't do a lot of stuff before you need to. No need in checking if you have a <code>ctaUrl</code> if your <code>_components/imageRight</code> isn't requested... </p>

<p>One reason for doing the logic in the main template would be that you would have less duplication (maybe) but from experience, I'm not sure it's worth it. So In your case:</p>

<pre class="lang-twig prettyprint-override"><code>{% set matrixBlocks = entry.fullContentMatrix.all() %}

{% for block in matrixBlocks %}
    {% if block.type == 'imageRight' %}
        {% include '_components/imageRight' %}
    {% elseif block.type == 'imageLeft' %}
        {% include '_components/imageLeft' %}
    {% elseif block.type == 'someOtherBlock' %}
        ....
    {% endif %}
{% endfor %}
</code></pre>

<p>Then do your work in your components:</p>

<pre class="lang-twig prettyprint-override"><code>&lt;h2&gt;{{ block.heading }}&lt;/h2&gt;
{{ block.bodyContent }}
{% if ctaUrl is not NULL %}
  &lt;a class="primary link" href="{{ block.ctaUrl }}"&gt;Click&lt;/a&gt;
{% endif %}
</code></pre>

<p>Doing this, you will have a lean and clear main template and the component level logic will live in the component where it belongs. My opinion only though... Plenty of ways to do this :)</p>

<p>So to your question:</p>

<blockquote>
  <p>What is the best way to write this so that variables are only passed to the include if they are defined?</p>
</blockquote>

<p>In your case, don't worry about that, check if they are defined when you need to use them, at component level.</p>

CC BY-SA 4.0
2019-02-25T01:38:56.083Z
Thank you Olivier. You're right, I was using `is defined` wrong. I ended up using `{% if ctaUrl is defined and ctaUrl %}` to check both.

Also thanks for the advice on how to construct the templates.
Lee
CC BY-SA 4.0
2019-02-24T19:25:01.393Z
2019-02-24T21:36:13.910Z
2019-02-24T21:36:13.910Z
Oli
<p>Craft noob here. I have an include file which I'm calling a "component" so I can reuse it across the site.</p>

<p>The component is set up like this.</p>

<pre><code>&lt;h2&gt;{{ heading }}&lt;/h2&gt;
{{ bodyContent }}
{% if ctaUrl is defined %}
  &lt;a class="primary link" href="{{ ctaUrl }}"&gt;Click&lt;/a&gt;
{% endif %}
</code></pre>

<p>Then on the template, I include it and pass some variables. In this case, the variables are from a Matrix field.</p>

<pre><code>{% set matrixBlocks = entry.fullContentMatrix.all() %}

{% for block in matrixBlocks %}
    {% if block.type == 'imageRight' %}

        {% include '_components/imageRight' with {
            heading: block.heading,
            bodyContent: block.bodyContent,
            ctaUrl: block.ctaUrl
        } %}

...etc
</code></pre>

<p>This all works great. Until I have fields that are optional and have no value, in this case, the <code>ctaUrl</code>. </p>

<p>What is the best way to write this so that variables are only passed to the include if they are defined?</p>

CC BY-SA 4.0
2019-02-23T00:05:54.607Z
Simple approach would be to have two includes and use your conditional to decide which to execute,\
Roi Agneta
CC BY-SA 4.0
2019-02-23T11:34:06.860Z
That would work but in the case when I have a Matrix field with a lot of optional fields this doesn't feel very scalable.
Lee
CC BY-SA 4.0
2019-02-23T18:27:31.237Z
What do you want to know exactly? How to check for those variables if they are defined in your included template or how to not pass the value in your parent template?
Robin Schambach
CC BY-SA 4.0
2019-02-24T17:23:40.790Z
Keep in mind that you do not have to pass variables to an include - you can just declare them in the main template, setting them to null if they do not exist, and then reference those variables in the "component"
Roi Agneta
<craft3><matrix><variable><include>
Passing optional variable values into an include template
# Passing optional variable values into an include template

(Asked by: username_0 on 2019-02-22)

Craft noob here. I have an include file which I'm calling a "component" so I can reuse it across the site.
The component is set up like this.
{{ heading }}
{{ bodyContent }}
{% if ctaUrl is defined %}
  Click
{% endif %}

Then on the template, I include it and pass some variables. In this case, the variables are from a Matrix field.
{% set matrixBlocks = entry.fullContentMatrix.all() %}

{% for block in matrixBlocks %}
    {% if block.type == 'imageRight' %}

        {% include '_components/imageRight' with {
            heading: block.heading,
            bodyContent: block.bodyContent,
            ctaUrl: block.ctaUrl
        } %}

...etc

This all works great. Until I have fields that are optional and have no value, in this case, the ctaUrl. 
What is the best way to write this so that variables are only passed to the include if they are defined?

**Tags:** craft3, matrix, variable, include

> **Comments:**
> **username_1**: Simple approach would be to have two includes and use your conditional to decide which to execute,\  
> **username_0**: That would work but in the case when I have a Matrix field with a lot of optional fields this doesn't feel very scalable.  
> **username_2**: What do you want to know exactly? How to check for those variables if they are defined in your included template or how to not pass the value in your parent template?  
> **username_1**: Keep in mind that you do not have to pass variables to an include - you can just declare them in the main template, setting them to null if they do not exist, and then reference those variables in the "component"  

---

## 1 answers

### Answer by username_3 on 2019-02-24. Score: 2 | Accepted answer

So in this case with ctaUrl, the issue is that you are checking if ctaUrl is defined. 
As long as a field exists, is defined will return true as in reality, the variable block.ctaUrl exists, it's just empty. To check for content in your case, you should test for NULL. So if ctaUrl is not NULL show your link.
In terms of organisation of your code, it's up to you. Like Roi said, you don't need the with. Your matrixBlocks will be available within the component. 
Whether you set stuff up in the main template is up to you. Personally, I would do my logic in the component rather than the main templates. 
You will need to be consistant with your naming but the component is where you need this logic so if it's is in there, you don't need to dig around to understand what is going on. If you remove a component, the logic goes with it as suppose to have a bloated main template and also, you don't do a lot of stuff before you need to. No need in checking if you have a ctaUrl if your _components/imageRight isn't requested... 
One reason for doing the logic in the main template would be that you would have less duplication (maybe) but from experience, I'm not sure it's worth it. So In your case:
{% set matrixBlocks = entry.fullContentMatrix.all() %}

{% for block in matrixBlocks %}
    {% if block.type == 'imageRight' %}
        {% include '_components/imageRight' %}
    {% elseif block.type == 'imageLeft' %}
        {% include '_components/imageLeft' %}
    {% elseif block.type == 'someOtherBlock' %}
        ....
    {% endif %}
{% endfor %}

Then do your work in your components:
{{ block.heading }}
{{ block.bodyContent }}
{% if ctaUrl is not NULL %}
  Click
{% endif %}

Doing this, you will have a lean and clear main template and the component level logic will live in the component where it belongs. My opinion only though... Plenty of ways to do this :)
So to your question:

What is the best way to write this so that variables are only passed to the include if they are defined?

In your case, don't worry about that, check if they are defined when you need to use them, at component level.

> **Comments:**
> **username_0**: Thank you username_3vier. You're right, I was using `is defined` wrong. I ended up using `{% if ctaUrl is defined and ctaUrl %}` to check both.  Also thanks for the advice on how to construct the templates.  

---

