1

I have setup chevrons to links to the previous and next posts. It seems to work for all but a handful of posts. Those posts generate the following template error:

Impossible to access an attribute ("url") on a null variable

        <p class="post-meta">
            {% set prev = entry.getPrev( 'posts' ) %}
            {% set next = entry.getNext( 'posts' ) %}

        <!-- previous post -->
        <span><a href="{{ prev.url }}"><i class="fa fa-chevron-left" aria-hidden="true"></i></a></span>
        <!--date of post -->
        <span>{{ entry.postDate | date('F d, Y') }} </span> 
        <!-- next post -->
        <span><a href="{{ next.url }}"><i class="fa fa-chevron-right" aria-hidden="true"></i></a></span>
    </p>

The specific line the template error references is

<span><a href="{{ prev.url }}"><i class="fa fa-chevron-left" aria-hidden="true"></i></a></span>

There are previous entries to access.

Thanks

2

First – you're passing a string value ('posts') to the getNext() and getPrev() methods, which will produce unreliable results.

The getNext() and getPrev() methods actually expect either an ElementCriteriaModel instance, or an object representing an ElementCriteriaModel's attributes (i.e. a query like { section: 'posts' } – not a string, number or any other, non-iterable value.

I'm guessing 'posts' is a section handle, but Craft won't know that and it will just ignore the string and return any element matching the current element's type - so if you call entry.getNext('posts'), you're probably going to get an entry back, but it won't reliably be an entry from the 'posts' section; it could be an entry from any section in your system.

So here's how your code probably should look:

{% set criteria = { section: 'posts' } %}
{% set prev = entry.getPrev(criteria) %}
{% set next = entry.getNext(criteria) %}
...

If this code is in an entry template, you could even do something like this:

{% set criteria = { section: entry.section } %}
{% set prev = entry.getPrev(criteria) %}
...

An additional tidbit: The only instance where it's ok to call getNext() and getPrev() without passing an ECM (or pass an invalid value, like a string), is whenever your entry variable is already part of an element result set – for instance, whenever you're looping on the result of a craft.entries query:

{% for entry in craft.entries.section('posts') %}
    ...
    {% set next = entry.getNext() %}
    {% if next %}
        <a href="{{ next.url }}">{{ next.title }}</a>
    {% endif %}
{% endfor %}

As for the error message you're seeing:

The getNext() and getPrev() methods should always be wrapped in a conditional, because they won't realibly, always return an element (i.e., there might not be a "next" or "previous" entry in your current context):

{% set prev = entry.getNext(criteria) %}
{% set next = entry.getPrev(criteria) %}

{% if prev %}
    <a href="{{ prev.url }}">{{ prev.title }}</a>
{% endif %}

{% if next %}
    <a href="{{ next.url }}">{{ next.title }}</a>
{% endif %}

The error message you're getting, is simply stating that there is no url attribute for one of your next or prev variables – meaning that those variables don't actually refer to valid elements, because the getNext() and/or getPrev() methods returned a NULL value. Simply wrap your code in conditionals, and the error will go away.

If you want to make sure that you're always displaying both a "next" and a "previous" link, you can make the links "loop" by having them point to the first and last entries respectively, whenever there isn't a next or previous entry in the set:

{% set criteria = craft.entries.section('posts') %}
...
{% set next = entry.getNext(criteria) ?? criteria.first() %}
{% set prev = entry.getPrev(criteria) ?? criteria.last() %} 
...
{% if next %}
    <a href="{{ next.url )}">{{ next.title }}</a>
{% endif %}
| improve this answer | |
1

Take a look at this: https://craftcms.com/docs/templating/paginate This is the standard craft reference what I use all the time. If you use this it will work!

| improve this answer | |
  • This is for a single entry, not a page of entries. – Hellyar Dec 8 '16 at 22:25
  • And it also did not work – Hellyar Dec 8 '16 at 22:38

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.