verbb / wishlist

A Craft CMS plugin for wishlists for your users to save things to
Other
11 stars 12 forks source link

Returning list items for user only #7

Closed putyourlightson closed 5 years ago

putyourlightson commented 5 years ago

When I output items using the code below, all items from all lists are output. Is it possible to output only the items that are in the list(s) that belong to the current user (if logged in) or current session (if logged out)?

{% set items = craft.wishlist.items().all() %}

I see this in the docs but it doesn't seem to be limiting results to the current user only.

We can display items for a given user by doing the following:

  1. Create an item query with craft.wishlist.items().
  2. Set the listId, limit and status parameters on it.
  3. Fetch all items with .all() and output.
  4. Loop through the items using a for tag to output the contents.
anthonyjc commented 5 years ago

I came across the same thing - getting the listId for the current user and passing that as a parameter in the item query seemed to work for me:

{# Get list for current user #}
{% set lists = craft.wishlist.lists()
   .userId(currentUser.id)
   .limit(1)
   .all() %}

{% if lists is empty %}

   <p>You haven't added anything to your wishlist yet.</p>

{% else %}

   {# Get user's list id #}
   {% set listId = lists[0].id %}

   {# Create an items query #}
   {% set itemsQuery = craft.wishlist.items()
      .limit(20)
      .listId(listId) %}

   {# Fetch the Items #}
   {% set items = itemsQuery.all() %}

   {# ... output items #}

{% endif %}

This assumes that the user is logged in, and there's only one "wishlist type" set up

putyourlightson commented 5 years ago

Thanks for this, I've implemented a similar workaround. I've asked @engram-design to look into this and hopefully we'll get an explanation soon :)

engram-design commented 5 years ago

@putyourlightson So to be fair, this functionality is technically correct as-is, but I can see why it might be misleading. The intended behaviour is to first get the list, then get its items.

{# Get the list - note default is optional #}
{% set list = craft.wishlist.lists().default(true).one() %}

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

Or, alternatively:

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

<ul>
    {% for item in craft.wishlist.items().listId(list.id).all() %}
        <li>{{ item.title }}</li>
    {% endfor %}
</ul>

But, I'll make sure the default behaviour is changed, because it makes little sense to query all items across all lists - at least by default.

putyourlightson commented 5 years ago

I think, as you say, the functionality is fine as is. My initial confusion was more about only fetching the current user's items and @anthonyjc's response helped clarify that. Perhaps an example in the docs would be sufficient :)

engram-design commented 5 years ago

Agreed, after reviewing the docs to answer this question, I don't believe there's a good example of this 'standard' behaviour - oops! I'll add it shortly.

echantigny commented 5 years ago

Adding to this in case anyone else stumbles on this thread. You can also specify a list type handle if you want. I'm using wishlist here, the default one that comes with the plugin, but if you create more options, you can display each option separately.

{% set list = craft.wishlist.lists().type('wishlist').one() %}

You can then loop through the items with {% for item in list.items %}

And get the whole targeted element with item.element

engram-design commented 5 years ago

FYI, I've added a new page to the docs to clarify this behaviour - https://verbb.io/craft-plugins/wishlist/docs/template-guides/getting-list-items

putyourlightson commented 5 years ago

Thanks!