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**.

%%img2%%

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 %}
    <figure>
        <img src="{{ img.url }}" alt="{{ img }}">
        {% if img.caption|length %}
        <figcaption>
            <span{{ img.caption }}</span>
        </figcaption>
        {% endif %}
    </figure>
    {% 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. – Jonathan Schofield Dec 13 '15 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 Dec 16 '15 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. – Jonathan Schofield Dec 16 '15 at 20:57

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 %}
        <figure>
            <img src="{{ img.url }}" alt="{{ img }} {{ n }}">
            {% if img.caption|length %}
            <figcaption>
                <span{{ img.caption }}</span>
            </figcaption>
            {% endif %}
        </figure>
        {% 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 :) – Jonathan Schofield Dec 16 '15 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. – Jonathan Schofield Dec 13 '15 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. – Jonathan Schofield Dec 14 '15 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 Dec 14 '15 at 19:03
  • 1
    I added a image to the answer so you can see this it visually in action. – Natetronn Dec 14 '15 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. – Jonathan Schofield Dec 16 '15 at 20:59

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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