7

It's my first website using Craft. I'm trying to figure out how to loop Matrix. I have created a field called bannerMatrix with a block type called banner that has 3 fields:

  1. Image (assets)
  2. Heading (plain text)
  3. Subheading (plain text)

This is what I have so far:

{% for block in entry.bannerMatrix %}
    {% if block.type == "banner" %}
        <div>
            <img src="{{ block.image }}" alt="{{ image.title }}">
            <div class="hero_msg">
                <h3>{{ block.heading }}</h3>
                <h4>{{ block.subheading }}</h4>
            </div>
        </div>
    {% endif %}
{% endfor %}

Anything will be helpful. Thanks!


UPDATE

@JamieWade, thanks a lot for the super fast answer! Unfortunately, the code above still doesnt work for me :(

{% for block in entry.bannerMatrix %}
    <div>
        <img src="{{ block.image.first().title }}" alt="">
        <div class="hero_msg">
            <h3>{{ block.heading }}</h3>
            <h4>{{ block.subheading }}</h4>
        </div>
    </div>
{% endfor %}

I also tried this :

{% set image = block.image.first() %}
{% if image %}
    <img src="{{ image.getUrl('image') }}">
{% endif %}

And I dont get anything as well :(

I wonder if my structure is correct. So I attached a screenshot. enter image description here

@Alec, yes there is content in the entry(I attached a screenshot). Now I'm even more curious, what's missing here. I also added the path to subfolder in the Field Setting.

enter image description here

enter image description here enter image description here

  • The update looks pretty sound to me, unless i'm missing something too, It might seem obvious but are you sure there is content in the matrix block of the entry you are viewing? – Alec Ritson Aug 18 '15 at 10:37
  • 1
    If you put an {% else %} just before the closing {% endfor %} and put some text between, do you see the text? – Alec Ritson Aug 18 '15 at 16:42
  • Yes, I see the text! So looks like the code doesnt work for this case. – Sylvia Prabudy Aug 19 '15 at 4:09
  • Silly I know but are you sure the "entry" variable is populated? Can you try a {{ dump(entry) }} above your code if you have devMode enabled? – Jérôme Coupé Aug 19 '15 at 7:05
  • Jerome, I got Variable "entry" does not exist error :/ Not sure which part I didnt do it right. I have Matrix field called bannerMatrix, has 1 block with 3 fields (image, heading, subheading). A section (home-page-banner) that linked to the matrix field. And I put those entries there in home-page-banner. – Sylvia Prabudy Aug 20 '15 at 5:35
3

From your last update it looks like you simply need to get the entry that contains that matrix block, the error Variable "entry" doesn't exist simply means nothing is assigned to entry in your templates. There are a couple of ways you can solve this:

Option 1 - Tell Craft which template to load for this entry

If you go into your section settings, there will be a field called Entry template which if, for example, you put about in this craft would look for either about.html or about/index.html in your craft/templates folder and would automatically assign a variable entry to your template when you visit the /about url.

There is also an option This is for the homepage in the settings which, if checked, will assign the entry to index.html in your templates (but i don't think this will show if there is already a section checked elsewhere)

You can see more about this in the craft docs: http://buildwithcraft.com/docs/templating-overview

Option 2 - Fetch the entry in your template using twig tags

There are numerous ways to do this, but given you are using a single you should just be able to use this:

{% set entry = craft.entries.section('homePageBanner').first() %}

You might need to adjust the homePageBanner part if that isn't the handle of your section, but this will then give you an entry variable to work with in your template and hopefully you'll find you will get the matrix content back :)

If you need some more details on how craft.entries works then the docs are a great place to find out more: http://buildwithcraft.com/docs/templating/craft.entries

| improve this answer | |
  • I used the 1st option, and it works! Thanks a lot Alec, you rock! :) First obstacle is solved. Cant wait to dig deeper. – Sylvia Prabudy Aug 20 '15 at 22:40
2

Hi Sylvia and welcome to Craft. You are almost there with your markup, there are only 2 little things I can spot straight away:

Line 4 you are calling {{ image.title }} however the image variable doesn't exist anywhere from what I can see in your code. In Line 1 you are looping through your Matrix field with a block variable: {% for block in ... %}, so this means each time you reference a field you will need to start it with {{ block. }}

If you change Line 4 to {{ block.image.first().title }} then you will get what you are trying to achieve.

Also if your Matrix field only has one block type, there is no need to check that block type when looping through it. You can remove {% if block.type == "banner" %} and everything will still work like before.

| improve this answer | |
2

I would try this:

{% for block in entry.bannerMatrix %}
  <div>
    {% set blockImage = block.image.first %}
    {% if blockImage %}
      <img src="{{ blockImage.getUrl() }}" alt="{{ blockImage.filename }}">
    {% endif %}
    <div class="hero_msg">
      <h3>{{ block.heading }}</h3>
      <h4>{{ block.subheading }}</h4>
    </div>
  </div>
{% endfor %}
  • You loop over all the blocks :{% for block in entry.bannerMatrix %}.
  • block.image will be an ElementCriteriaModel, which is not an asset, but a way to get an asset.
  • Set blockImage to the first (and only) asset if it exists, and otherwise null: {% set blockImage = block.image.first %}.
  • Only try to use the image if it exists: {% if blockImage %}.
  • Assets don't have a title, so {{ blockImage.title }} won't work. You can use {{ blockImage.filename }}, or you could assign another field in the asset's Field Layout, and then use that: {{ blockImage.altText }} for example.
| improve this answer | |
  • Marion, thanks for the answer. However, this blockImage dont show my entries either :( If you have any suggestions to change my matrix structures, I am open :) – Sylvia Prabudy Aug 19 '15 at 4:23
  • Your matrix structures look fine. I would turn on devMode (in config/general.php), and add {{ dump(blockImage) }} to see what it is set to (right before the if line) – Marion Newlevant Aug 19 '15 at 16:45
  • Hi Marion, when I turned on the devMode, it tells me that Variable "entry" does not exist (attached screenshots of the errors and the sections). Which part I didnt do it correctly? – Sylvia Prabudy Aug 20 '15 at 5:22
  • Hi Sylvia, I think Alec has you covered here. Think about why you would expect entry to be set: either this is the entry template for some section, or you set it explicitly. – Marion Newlevant Aug 20 '15 at 18:50
2

thanks a lot for all the answers!

I finally got my entries to show up! What I did was move that entry to Homepage section(like what Alec Ritson suggested) together with other entry I already have in Homepage and wrapped the block code with {% for entry in craft.entries.section('homepage') %}

So the full code is:

{% for entry in craft.entries.section('homepage') %}
    {% for block in entry.bannerMatrix %}
        <div>
            {% set blockImage = block.image.first() %}

            {% if blockImage %}
                <img src="{{ blockImage.getUrl() }}" alt="{{ block.heading }}" title="{{ block.heading }}">
            {% endif %}

            <div class="hero_msg">
                <div class="caption_top"></div>
                <div class="caption">
                    <h3>{{ block.heading }}</h3>

                    <h4>
                        <span class="rsep"></span>
                        {{ block.subheading }}
                        <span class="lsep"></span>
                    </h4>

                </div>
                <div class="caption_bot"></div>
            </div>
        </div>
    {% endfor %}
{% endfor %}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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