9

Is there another way of detecting if a page is an 'entry' or a 'category' than the following? Maybe some global variable that I do not know of?

{% if entry is defined %}
  <!-- Code here -->
{% endif %}
{% if category is defined %}
  <!-- Code here -->
{% endif %}

I have a html code block that is included in both entry pages and category pages hence the need for this.

Thanks in advance!

2 Answers 2

10

It'd be nice to see an example of your HTML block. From your comments it sounds like you may be using the same HTML block for Entry and Category pages but need to know which variable to use in the code.

Assuming you know that your code is running on the Entry or Category pages, and that the fields across both your Entries and Categories for this part of the page are the same, you can place your common HTML in an include and pass both the entry and category variable to that include with the same variable name. In the example below, we're handing off the entry and category variables and using the variable name object in the include template:

_entry.html

{% include '_partials/shared-template' with { object : entry } %}

_category.html

{% include '_partials/shared-template' with { object : category } %}

_partials/shared-template

<div>
    {{ object.fieldName }}

    {% for item in object.someOtherFieldName %}
      {{ item }}
    {% endfor %}
</div>

If some of the field names are different, you may need to use some conditional logic or reconsider what variables are being passed to the included template. You could pass dissimilar variables under the same variable names to a common template in the following way:

index.html

{% if entry is defined %}
    {% include '_partials/shared-template' with { 
        title : entry.title,
        someOtherVariable: entry.fancyFieldOne
    } %}
{% endif %}

{% if category is defined %}
    {% include '_partials/shared-template' with { 
        title : category.title,
        someOtherVariable: category.fancyFieldTwo
    } %}
{% endif %}

_partials/shared-template

<div>
    {{ title }}

    {% for item in someOtherVariable %}
      {{ item }}
    {% endfor %}
</div>
6

Testing for the pre-populated variables is probably the only way to do this. But as you're asking for a single (global) var to test against, I believe you're looking for a way to have clean, dry code in your shared code block without using your posted snippet again and again.

How about doing something like this:

{% set entry = entry is defined ? entry : null %}
{% set category = category is defined ? category : null %}

Then your two variables entry and category will always be defined, which allows you to have very short ternary syntax in your print expressions.

<div class="myDefaultClass{{ entry ? ' myEntryClass' }}"></div>

Another thing you could do is to set a new var model, which holds either the Entry Model or the Category Model.

{% set model = entry is defined ? entry : category is defined ? category : null %}
{% set entry = entry is defined ? entry : null %}
{% set category = category is defined ? category : null %}

<h1>{{ model.title }}</h1>
4
  • 1
    Nice answer @carlcs. I think you need to use the full ternary instead of the twig shorthand though, otherwise it will return a boolean. entry is defined ? entry : null
    – Fyrebase
    Commented Nov 12, 2015 at 14:36
  • In my testings entry is defined ? entry : null and entry is defined ?: null did the same. I was surprised when I first noticed this, maybe it's a bug?!
    – carlcs
    Commented Nov 12, 2015 at 15:14
  • Things may have changed. I had to go with the full ternary to get it to work.
    – Fyrebase
    Commented Nov 13, 2015 at 0:05
  • Corrected the answer. Thanks for testing and reporting the issue, @Fyrebase!
    – carlcs
    Commented Nov 13, 2015 at 0:08

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.