I'm trying to do something I'm used to in Wordpress, but can't really find a right way, or 'correct' way. What I was used to do in Wordpress; every page had a few options, like center content, background image, etc. In page.php (if you know Wordpses this'll make sense) I called a function pageDetails() (defined in functions.php) which returned me some variables for centering content, if it had a background image, etc.

Now I'm trying to do the same in Craft, so I created a section for the pages, added some custom fields to the pages, and now I'm trying to create a likewise method for defining a function once and use that for different 'entry types' to avoid repeating myself for each entry type template. For this, I keep coming back to creating a macro, that I define in _macros/macro.twig (for example). But, I can't get it to return variables.

In short; is there a way to use 'variables' from entry template, to the macro, and have the macro return vars (or array) to the entry template so I can use them in there? Or should I completely rethink this way of doing it?

2 Answers 2


Assuming that your variables are coming from the entry, you want to look into the Twig {% embed %} docs. I generally do something along these lines:

Your main page template

{% extends "_inc/_layout" %}
{% block content %}

    {% include '_inc/_title' %}
    {% embed "_inc/_body_field" %}
        {% block body_field %}{% endblock %}
    {% endembed %}

{% endblock %}

Your body field

{% import '_inc/_macros' as macros %}

{% block body_content %}

    {% for brick in entry.body %}

        {% if brick.type == "heading" %}

            <{{ brick.headingWeight }} class="wrap">{{ brick.heading }}</{{ brick.headingWeight }}>

        {% elseif brick.type == "wysiwyg" %}

            <div class="wrap">
                {% if brick.cappedWidth %}
                    <div class="capped">{{ brick.copy }}</div>
                {% else %}
                    {{ brick.copy }}
                {% endif %}

        {% elseif brick.type == "inlineImage" %}

            {% set img = brick.image.first() %}
            <div class="wrap img-container">
                {{ macros.img(img, 990, {alt: brick.imageAlt}) }}

        {% endif %}

    {% endfor %}

{% endblock %}

Actually, now that I've stripped that down to some generic stuff, you'd be able to achieve the same with a simple {% include %}.

If you're using structures, you could also take this further and look into having a single file that includes a different file depending on the page type:

{% extends "_inc/_layout" %}

{% block main %}

    {# Call on the entry type file #}
    {% include '_types/_' ~ entry.type %}

{% endblock %}

Macros are intended to output to the page, rather than return data to the caller. If you must return the data, I'd suggest writing a custom plugin (although that's where my knowledge stops!).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.