3

I am trying to show an image that is defined on a category - named photos. I have an entry page with a list of all category entries listed at the bottom. I'd like to show this image but I'm still green on Craft categories and I'm getting errors in dev mode. This is what I have so far:

{% set entries = craft.entries.section('sermons').find() %}
{% for category, catEntries in entries | group('series.first().title') %}

 {% if category.photos | length %} {# if a photo exists, show it #}
    {% for image in category.photos.limit(1) %}
    {% set params = { width: 300, height: 200 } %}
        <img  src="{{ image.getUrl(params) }}" height="{{ image.getHeight(params) }}" width="{{ image.getWidth(params) }}" alt="">
    {% endfor %}
  {% else %} {# if no photo exists, show a default image #}
        <img  src="/img/cover-default.jpg" width="300" height="200" alt=""></a>
  {% endif %}


{# output all category entries #}   
    <ul class="sermonadditional">
   {% for entry in catEntries %}
       <li><a href="{{ entry.url }}">{{ entry.title }}</a></li>
   {% endfor %}
   </ul>
{% endfor %} 
2
  • What errors are you getting?
    – Brad Bell
    Commented Apr 1, 2015 at 3:04
  • It looks like it fails right at the {% if category.photo ... line. I get: "Impossible to access an attribute ("photos") on a string variable ("1 Corinthians")"
    – glider
    Commented Apr 1, 2015 at 4:02

2 Answers 2

3

It wasn't really clear to me if you want to list only those categories that are related to the current entry or if you want a list of all categories that are assigned to your sermons.

I dont't think the group filter helps a lot in either case and I'd get the catgories like this.

{% set sermonCategories = entry.series %}

In case you don't want them to be ordered by your manual sort order, you need to get them using a craft.categories ElementCriteriaModel.

{% set sermonCategories = craft.categories.relatedTo(entry).order('title') %}

To get all the categories you'd query for all of your "sermons" entries first.

{% set sermons = craft.entries.section('sermons') %}
{% set sermonCategories = craft.categories.relatedTo(sermons).order('title') %}

The you can start with your loop. I did some small changes, so that only categories with entries related to it will be shown.

{% for category in sermonCategories %}

    {% set relatedEntries = craft.entries.relatedTo(category) %}

    {# Only show category if there are related entries #}
    {% if relatedEntries|length %}

        {% set image = category.photos.first() %}
        {% set params = { width: 300, height: 200 } %}

        {# If a photo exists, show it, otherwise show a placeholder #}
        {% if image %}
            <img  src="{{ image.getUrl(params) }}" height="{{ image.getHeight(params) }}" width="{{ image.getWidth(params) }}" alt="">
        {% else %}
            <img  src="/img/cover-default.jpg" width="300" height="200" alt="">
        {% endif %}

        <ul class="sermonadditional">
            {% for entry in relatedEntries %}
                <li><a href="{{ entry.url }}">{{ entry.title }}</a></li>
            {% endfor %}
        </ul>

    {% endif %}

{% endfor %}
1
  • Excellent. Thank you! I am beginning to understand how to use Craft and categories. So it looks like you set a variable and define its properties then call that variable to output the info.
    – glider
    Commented Apr 1, 2015 at 20:09
2

I am guessing that series is your category field. In that case, you are grouping your entries by the title of their first (and only?) category. In the loop

{% for category, catEntries in entries | group('series.first().title') %}

category will be the title of the category, and catEntries will be the entries whose category has that title.

The title of a category is a string, so it makes sense you can't get category.photos.

What you want is a category, not a string. What I would do is this:

{% for categorySlug, catEntries in entries | group('series.first().slug') %}
  {% set category = craft.category.slug(categorySlug).first %}
  ... rest of your code as before ...
{% endfor %}

I am grouping by category slug instead of title, because that is guaranteed to be unique, and then fetching the actual category based on its slug.

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.