Option to proivde remove links

Created on 18 October 2024, 2 months ago

Problem/Motivation

It'd be great to be able to provide remove links as well. Especially for wishlists this would be useful, since this is a very common pattern to be able to add and remove products from an overview using links.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Feature request
Status

Active

Version

2.0

Component

Code

Created by

🇨🇭Switzerland Lukas von Blarer

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Lukas von Blarer
  • 🇨🇭Switzerland Lukas von Blarer

    luksak changed the visibility of the branch 3481746-option-to-proivde to hidden.

  • 🇯🇴Jordan Anas_maw

    Thanks for this great feature, I was just looking for it, one issue only, cache should be prevented in this case 'max-age' => 0

  • 🇯🇴Jordan Anas_maw

    Here is a patch with the fix until you add it to the MR, many thanks

  • 🇨🇭Switzerland Lukas von Blarer

    @anas_maw Thank you for your feedback!

    Yeah, I found the caching issue as well. But your approach simply disables caching altogether. I think we could do better.

    I tried to use the wishlist cache context. This improves the situation, but doesn't solve it completely. The cache somehow doesn't vary when a product is added to the wishlist. Any ideas how to solve that? Do we need a different context?

    Additionally we might want to use a lazy builder to improve performance.

  • 🇨🇭Switzerland Lukas von Blarer

    Ok, I guess this is why the cache context isn't working:

    https://git.drupalcode.org/project/commerce_wishlist/-/blob/8.x-3.x/src/...

    public function getContext() {
      return implode(':', $this->wishlistProvider->getWishlistIds($this->account));
    }
    

    I guess that we'd need a new context that takes into all wishlist items into account. WishlistCacheContext only takes wishlist entites into account.

  • 🇨🇭Switzerland Lukas von Blarer

    Ok, now a remove link is being displayed if any (not the default) product variation is in the wishlist.

  • 🇨🇭Switzerland Lukas von Blarer

    I implemented a new cache context. I don't have a lot of experience with caching, so probably this could be solved in a better performing way. My approach potentially creates a lot of cache data. I'd happy to get a review on this.

    I'm trying to look into the lazy builder, since that'd probably improve performance a lot.

  • 🇨🇭Switzerland Lukas von Blarer

    Ok, the last commit adds a lazy builder. This improved performance a lot.

  • 🇦🇹Austria agoradesign

    regarding the wishlist items cache context:

    I maybe the wrong person to answer this, as I keep struggling for years to find a way to find the right cache metadata for cart links in the page header, that show the number of items in the cart. Everytime I thought, I solved that, it happened again, that the counter kept staying at 0.

    This is little bit different of course. Because every single link depends on the actual items in the wishlist. We may have to think about caching here in general

  • First commit to issue fork.
  • 🇨🇭Switzerland berdir Switzerland

    Opened 🐛 Wishlist link adds #attached to lazy builder, throws AssertionError Active but realized the issue is introduced by this issue.

    Pushed a quickfix but I think the cache contexts aren't necessary and should be moved into the lazy builder, as it is now they might bubble up and cover the whole page. But I'll need to do more testing on that.

    @agoradesign:

    > I maybe the wrong person to answer this, as I keep struggling for years to find a way to find the right cache metadata for cart links in the page header, that show the number of items in the cart. Everytime I thought, I solved that, it happened again, that the counter kept staying at 0.

    What we do in custom block in a project is the combination of cart cache context + cache tags from the cart(s):

    
      /**
       * {@inheritdoc}
       */
      public function getCacheContexts() {
        return Cache::mergeContexts(parent::getCacheContexts(), ['cart']);
      }
    
      /**
       * {@inheritdoc}
       */
      public function getCacheTags() {
        $cache_tags = parent::getCacheTags();
        $cart_cache_tags = [];
    
        /** @var \Drupal\commerce_order\Entity\OrderInterface[] $carts */
        $carts = $this->cartProvider->getCarts();
        foreach ($carts as $cart) {
          // Add tags for all carts regardless items or cart flag.
          $cart_cache_tags = Cache::mergeTags($cart_cache_tags, $cart->getCacheTags());
        }
        return Cache::mergeTags($cache_tags, $cart_cache_tags);
      }
    

    So you vary by cart and invalidate if the cart changes. This has been working well for us.

  • 🇦🇹Austria agoradesign

    @berdir thanks for your input!

    That's basically the same code, we also use always. but idk, I have seen some caching issues anyway, after I thought, that the problems were gone. Anyway, I just tried on two of our projects, and I could not reproduce it though. afaik when it happened, it was always the problem, when an anonymous user without a cart/session added the first item to cart

    So I honestly don't know, if our current solutions works 100%. At least it does not happen too often, so that I do not get complaints by our clients :D

Production build 0.71.5 2024