I have a Matrix block with a text field and an Assets field. The text field has a Markdown filter applied to it.

I'd like the content owner to be able to enter a placeholder reference to one of the images uploaded to the sibling Assets field.

For example, when the template processes…

This is a **paragraph**.


This is some more text.

…then %%img2%% (or some such syntax that won't conflict with Markdown) gets replaced with the HTML generated for the second image by the relevant Assets query running in the template.

I've done things like this before with MXjumper and ExpressionEngine but am pretty new to Craft and not sure how to go about it.

I figure I need to:

  1. Set a dynamically named variable (because I don't know in advance how many images are in the image field)
  2. Use replace on the text field, but the replace statement should incorporate dynamically named search strings and the replacements would be the variables named at step 1 not strings.

Really not sure how to execute either of these 2 steps in Twig.

Would something like the following work for step1?

{% for img in sectionImages %}
    {% set n %}{{ loop.index }}{% endset %}
    {% set img ~ n %}
        <img src="{{ img.url }}" alt="{{ img }}">
        {% if img.caption|length %}
            <span{{ img.caption }}</span>
        {% endif %}
    {% endset %}
{% endfor %}

And what then for step 2…

{{ block.sectionText|markdown|replace('%%img' ~ n ~ '%%': img ~ n) }}

My step 1 code feels like it's close but I suspect it's not right. And in any case I feel sure my step 2 code is further off from what's needed.

I think maybe I need to be storing img as key|value pairs in an array and working with that somehow.

Any pointers much appreciated.

  • I sense I need to be using attribute for dynamically named variables, but the lack of examples in Twig documentation has me stumped. Commented Dec 13, 2015 at 19:52
  • Is this tiny images you need to insert inline? Otherwise, why not do like everyone else and make the author end the block, add image block and then continue with another text block? You could even make this work for inline images, just remove the surrounding </p> and <p> with Twig.
    – carlcs
    Commented Dec 16, 2015 at 7:57
  • Thanks carlcs. Yes, that's an option I've considered and done elsewhere. Pros and cons to do with content coherence in the CMS I'm weighing up. Commented Dec 16, 2015 at 20:57

3 Answers 3


Well this feels like an awful kludge but at least I have it working with a finite number of image variables in the code below.

There has to be a more elegant and flexible way to do this. And Natetronn, if your proposal does just that, perhaps you could help me see how. Otherwise, other cleverer folks, do let me know.

{% for subsection in entry.subsections %}

    {# Set variables for up to 4 images per subsection #}
    {% set n  = 0 %}
    {% set imageN = '' %}
    {% set image1 = '' %}
    {% set image2 = '' %}
    {% set image3 = '' %}
    {% set image4 = '' %}

    {% set sectionImgs = subsection.sectionImages %}

    {% for img in sectionImgs %}
        {% set n = loop.index %}

        {% set imageN %}
            <img src="{{ img.url }}" alt="{{ img }} {{ n }}">
            {% if img.caption|length %}
                <span{{ img.caption }}</span>
            {% endif %}
        {% endset %}

        {# assign imageN to a specific variable #}
        {% switch n %}
            {% case 1 %} {% set image1 = imageN %}
            {% case 2 %} {% set image2 = imageN %}
            {% case 3 %} {% set image3 = imageN %}
            {% case 4 %} {% set image4 = imageN %}
        {% endswitch %}
    {% endfor %}

    {{ subsection.sectionText|markdown|replace({
        '%%image1%%': image1, 
        '%%image2%%': image2, 
        '%%image3%%': image3, 
        '%%image4%%': image4
    })|raw }}

{% endfor %}{# /subsection #}

I'd suggest a better approach as detailed here: https://experiencehq.net/blog/craft-with-markdown-and-matrix Once you go down the "structured content" route you'll never look back, I promise you :)

  • Awesome, erwinheiser. Thanks, that is just what I wish I'd thought of :) Commented Dec 16, 2015 at 21:04

This is partially side stepping your question but, it could be a solid option just the same:

You might consider checking out Selvin's Doxter Markdown plugin. It has support for Entries, Assets, Users, Tags, Globals and Categories.

Craft Doxter markdown icons

This all via reference codes which can be copied and pasted into the Markdown as needed.

reference code

Doxter walkthrough

  • Cheers Natetronn. I'll take a look. Commented Dec 13, 2015 at 21:17
  • Thanks for the suggestion. The documentation for reference tags is devoid of any examples, but if I read between the lines correctly one has to know the ID of an element in advance in order to be able to refer to it in a reference tag -- so I don’t think that helps what I’m hoping to do. Commented Dec 14, 2015 at 9:10
  • Did you try the plugin? It allows you to pick an Asset and then presents you the proper reference tag so you can copy and paste it where you want in the Markdown. In other words, there is nothing to know in advance. It literally pops up the Assets window with all the images so the client can select the one they want to use and then, once selected, it offers the proper reference tag, ID included, all set and ready to go.
    – Natetronn
    Commented Dec 14, 2015 at 19:03
  • 1
    I added a image to the answer so you can see this it visually in action.
    – Natetronn
    Commented Dec 14, 2015 at 19:11
  • Thanks for the GIF, Natetronn, that helps. I'll definitely try the plugin and have a proper look. Didn't have time last Sunday for what is a side project. Thanks so much for the suggestion. Commented Dec 16, 2015 at 20:59

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.