Wishlist 3

Verbb Team Verbb Team May 2024 3 min read

Wishlist 3 is available now for Craft 5 and includes a revamp and make the developer experience a little better.

For those who remember the "old days", Wishlist was based on the Shortlist (opens new window) plugin for Craft 2, which was itself ported from Expression Engine (opens new window). As such, we kept the API very similar to allow for easy migration between Shortlist and Wishlist for those who were used to it.

However, since 2018 when Wishlist was released, a lot has changed in Craft, and the Shortlist plugin never made the jump to Craft 3 and above. We wanted to improve the developer experience and simplify things.

Getting the list#

There's now a clearer method of getting the list for the current user.

{# Wishlist v2 #}
{% set list = craft.wishlist.lists().default(true).one() %}

{% if list %}
    <ul>
        {% for item in list.items.all() %}
            <li>{{ item.title }}</li>
        {% endfor %}
    </ul>
{% endif %}

{# Wishlist v3 #}
{% set list = craft.wishlist.getUserList() %}

<ul>
    {% for item in list.getItems() %}
        <li>{{ item.title }}</li>
    {% endfor %}
</ul>

The craft.wishlist.getUserList() will always return a ListElement element even if the user hasn't created a list yet. It's a quick shortcut function that can cut down some code.

Managing items#

We've decided to deprecate the craft.wishlist.item() call required when performing anything on a list item. This has always felt a little clunky, and is actually quite un-performant.

{# Wishlist v2 #}
{% set item = craft.wishlist.item(entry.id) %}

{% if item %}
    <a href="{{ item.addUrl() }}">Add to List</a>
    <a href="{{ item.toggleUrl() }}">Toggle in List</a>
    <a href="{{ item.removeUrl() }}">Remove from List</a>
{% endif %}

{# Wishlist v3 #}
<a href="{{ craft.wishlist.addItemUrl(entry) }}">Add to List</a>
<a href="{{ craft.wishlist.toggleItemUrl(entry) }}">Toggle in List</a>
<a href="{{ craft.wishlist.removeItemUrl(entry) }}">Remove from List</a>

Rather than get a Wishlist Item by its element ID (entry.id here), then render the URLs for add/toggle/remove, you can now do that globally with just the element (entry). This makes for a much simpler bit of code.

You could also do the same thing based on the list.

{% set list = craft.wishlist.getUserList() %}

<a href="{{ list.addItemUrl(entry) }}">Add to List</a>
<a href="{{ list.toggleItemUrl(entry) }}">Toggle in List</a>
<a href="{{ list.removeItemUrl(entry) }}">Remove from List</a>

Checking if in a list#

Similar to the above, previously you needed to get the List Item first to determine if it was in the list or not. You can now use list.getItem(entry) to determine if the give element (entry) exists in the list as a List Item.

{# Wishlist v2 #}
{% for entry in craft.entries.section('news').all() %}
    {% set item = craft.wishlist.item(entry.id) %}

    {% if item.getInList() %}
        <a href="{{ item.removeUrl() }}">Remove from List</a>
    {% else %}
        <a href="{{ item.addUrl() }}">Add to List</a>
    {% endif %}
{% endfor %}

{# Wishlist v3 #}
{% set list = craft.wishlist.getUserList() %}

{% for entry in craft.entries.section('news').all() %}
    {% if list.getItem(entry) %}
        <a href="{{ list.removeItemUrl(entry) }}">Remove from List</a>
    {% else %}
        <a href="{{ list.addItemUrl(entry) }}">Add to List</a>
    {% endif %}
{% endfor %}

Bits & Pieces#

There's also some extra goodies in the release.

  • Create a list when adding or toggling an item in one request.
  • Update multiple items at once.
  • Bulk list actions for add/remove/toggle/update, to perform tasks on multiple lists at once.
  • Change the owner user for a list in the control panel.
  • Duplicate a list from the front-end.
  • Attach a PDF to the share email.

These new features are available right now for Wishlist for Craft 5 (opens new window). Be sure to check out the Upgrading from v2 guide.