1

I use AuthCache and Drupal Commerce in my Drupal 7 site. I am currently building a new Foundation subtheme for the site with the Foundation topbar activated for mobile only.

Now, to show the number of items in the cart I simply replace the default cart block content with this in my template.php:

function mynewtheme_block_view_alter(&$data, $block) {
  global $user;
  if ($block->module == 'commerce_cart') {
    if ($order = commerce_cart_order_load($user->uid)) {
      // Count the number of product line items on the order.
      $wrapper = entity_metadata_wrapper('commerce_order', $order);
      $quantity = commerce_line_items_quantity($wrapper->commerce_line_items, commerce_product_line_item_types());

      if($quantity){
        $data['content'] = ('<a class="varukorg" href="/cart"><i class="fi-shopping-cart"></i>('.$quantity.')</a>');
      }else{
        $data['content'] = ('<span class="varukorg cart-empty-block"><i class="fi-shopping-cart"></i> (0)</span>');
      }
    }else{
      $data['content'] = ('<span class="varukorg cart-empty-block"><i class="fi-shopping-cart"></i> (0)</span>');
    }
  }
}

The above shows a basket with the number of items in the cart.

Then, to show the number of items also in the Foundation topbar on mobile devices or narrow windows I use this code in a preprocess_page hook in template.php:

  $cartblock = block_render('commerce_cart', 'cart');
  $vars['varukorgen'] = $cartblock;

Followed by this line in page.tpl.php:

<?php print render($varukorgen); ?>

Now to my problem... the number of items shown by the variable $varukorgen in page.tpl.php is incorrect on smaller window sizes when the topbar is toggled. It think that is shows a cached version of the number.

In the AuthCache settings in the block in question i have set "Never" for the Cache lifetime, Per user and I also enabled Ajax.

So why is the number not showing correctly when it is rendered by means of a custom variable in page.tpl.php?

EDITED: the solution was as suggested below to create a new region in the .info file, place the cart block in that region in the UI and then render that region inside the topbar region in page.tpl.php like this:

    <?php if ($page['topplist']): ?>
      <div id="topplist" class="basket">
        <?php print render($page['topplist']); ?>
      </div> <!-- /#topplist -->
    <?php endif; ?>

Now the the number of items in the cart is updated as it should on every page by the means of Ajax (enabled in the cart block).

1 Answer 1

2

You don't want to put this code directly into your tpl, as it will indeed cache. What you want to do is create a region in your template and then add your cart block to that region in the UI. You will also have to set that block to load via ajax or ESI so that it works properly with Authcache. You will see those settings if you go to configure the block.

Ideally you don't ever want to include any code that "does stuff" in your tpl files, as it can get cached. This is more obvious in Drupal 8 thanks to twig making this harder, but it is very easy to do incorrectly in Drupal 7.

You can be even more efficient if you change your code to save the cart quantity as a session variable or cookie and only calculate it when the cart changes, thus saving you from performance heavy order loads on every page. This is outside of the scope of your initial question though, but I thought I would mention it.

3
  • Yes, this is what I began to suspect. That is also how I do it for screens bigger than 768 px. Below that I use the Foundation topbar on mobile devices. I will try to add the cart block to the topbar for narrow screens without using page.tpl.php. Thanks!
    – TBJ
    Commented Dec 12, 2017 at 7:02
  • 1
    Yah, when cached, nothing in your tpl gets "run" again, so things like loading up the cart doesn't happen. Your whole tpl is frozen in time.
    – smccabe
    Commented Dec 12, 2017 at 18:22
  • Still I had to render the new 'cart region' in page.tpl though. Thanks again, I have updated my question with the solution above.
    – TBJ
    Commented Dec 13, 2017 at 7:16

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.