1

I need to displaying some notifications on a Craft site, and I want to allow users to mark each notification as read. There won't be many users or notifications, so a plugin seems overkill. Instead I've created a Notifications section with a Read by (Users) field called notificationReadBy.

Notifications display on the template inside an entry form, with a hidden multi-select field containing all users who've marked the notification as read (i.e. already submitted the form) plus the current user's id in case they want to mark as read too. That works fine to build a list of users who've already read the notification.

Next step is to hide the notification altogether if the current user has already marked it as read, and is listed in the Read by field. So I thought something like this might work...

{% for entry in craft.entries
    .section('notifications')
    .all() %}
    {% set readBy = entry.notificationReadBy %}
    {% if currentUser.id not in readBy %}
        {# Show the notification #}
    {% endif %}{% endfor %}

Does that make sense? Anyway, it's not working as expected and is displaying the entry regardless of whether the current user is listed in Read by or not. Any ideas? Maybe it's neater to move the query up to the entries tag, using the .search() param, but I can't get that working either?

1
  • I'd start by checking what the field content looks like. You can do this as follows with devMod enabled. {{ dump(entry.notificationReadBy) }}
    – Ben Croker
    Commented Jan 11, 2019 at 10:41

2 Answers 2

2

Thanks to Jason and Ben for the assist. I changed tac a bit and moved the field on to the user (as an Entries field). Now got this working:

{# Display unread notifications for current user #}
{% set notificationsRead = currentUser.userNotificationsRead.ids() %}
{% set notifications = craft.entries
    .id(['not']|merge(notificationsRead))
    .section('notifications')
    .all() %}

{% for entry in notifications %}
    {{ entry.title }}
{% endfor %}
1

If it's a multi-select field, have you tried doing something like:

{% if currentUser.id not in readBy.options %}

It also might be worth scrapping the multi-select and having it as a text field and adding it as a fake array, e.g.

['234','53', '90', '103']

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.