42 replies [Last post]
zhangty's picture
Offline
Joined: 01/27/2010
Juice: 41

I have the latest Drupal 6 and the latest Ubercart 2.2 on our site.

I have tried using the Boost Module (Stable and Dev); however, it seems I cannot get the shopping cart block to work correctly for anonymous users. The Shopping Block cart is cached so it does not display the actual contents for anonymous users.

I have searched quite a few threads, but found no solutions.

The following posts I reviewed are here for reference:

http://drupal.org/node/628988
http://drupal.org/node/586210

Can anyone tell me what needs to be done to get Boost working with Ubercart?

Thanks in advance.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Boost Module and Shopping Cart Block

Have you tried UC Ajax Cart? http://drupal.org/project/uc_ajax_cart

--
Help directly fund development: Donate via PayPal!

zhangty's picture
Offline
Joined: 01/27/2010
Juice: 41
Shopping cart ghost products for anonymous users.

Thank you for your reply.

I tried UC Ajax Cart but I had the same results as when I was using the standard UC Cart.

After reading this post http://drupal.org/node/377798#comment-1484506, I now understand that what I am experiencing is referred to as "Ghost carts for anonymous users".

Before trying the Boost Module, I always had Drupal Core Page and Block caching enabled. On my site, with both UC Ajax and UC default cart, this resulted in anonymous users always seeing the trimmed down shopping cart block that just uses static HTML. I understand this is by design after reading the following:
http://www.ubercart.org/docs/user/9168/cart_block_now_safe_page_caching

Therefore, no cart contents were listed inside the shopping cart block for anonymous users.

When I enabled the Boost Module, Drupal Core caching became disabled and the dynamic shopping cart block began displaying cart contents for anonymous users. However, I also began experiencing the "Ghost carts for anonymous users" problem.

Any suggestions on what I should try next?

mikeytown2's picture
Offline
Joined: 03/19/2010
Juice: 6
Boost

This looks promising.
http://drupal.org/node/679422

zhangty's picture
Offline
Joined: 01/27/2010
Juice: 41
mikeytown2 wrote: This looks
mikeytown2 wrote:

This looks promising.
http://drupal.org/node/679422

Thanks for the link mikeytown2...

When I originally started searching for solutions to the problem, I looked at that thread and even applied the patches recommended by torgosPizza. The UC Cart patch is listed in post #6 and the additional JS file from post #4.

The patches did not seem to solve Cart Ghosting problem though with the Boost Module enabled.

After reading post #26 by torgosPizza in that thread, as far as I can tell, the patches given in #4 and #6 of that thread are not meant the solve the Cart Ghosting issue. In the opening post he writes "The problem: Anonymous users can't add things to cart (on first try, anyway)". I was not having that problem.

For the time being, I am able to use the devel version of the Boost Module with our site. I disabled the Ubercart Shopping cart block and created another block with a plain link to the shopping cart. That does away with any Cart Ghosting issues. Hopefully I will find a solution later and can have a fully dynamic shopping cart block.

moby's picture
Offline
Joined: 10/05/2008
Juice: 156
benefits?

whats the benefit from using the Devel version?

I have just switched to usng boost, and a plain cart link for anon users.

does the boost module detect the Cart cookie? if it does, that should mean that the boost module isnt used once someone has something in their cart..

zhangty's picture
Offline
Joined: 01/27/2010
Juice: 41
Thanks for the post Moby... I

Thanks for the post Moby...

I installed the 6.x-1.x-dev (2010-Feb-21) version because there was a fix for "Prevent caching of Ubercart shopping cart pages." in that release. (More information is here http://drupal.org/cvs?commit=331428 )

Please correct me if I am wrong, but I would think using the Recommended Release and just specifying that cart and cart/ pages not be cached in the boost settings would achieve the same results as that commit.

For my site, I am having a problem with the Feb 21 Dev version. I receive error messages in my log when I enable the Boost Crawler. I briefly scanned the issue queue and did not see others with the same problem so it may be that I have configured something incorrectly in my boost settings.

I don't know if boost detects the cart cookie or not. Would the session cookie and cart cookie be the same thing?

The 2 threads I list in my opening post discuss the session cookie. There is a patch listed in a posting from the second thread here: http://drupal.org/node/586210#comment-2596954

Please let me know your experiences with boost and Ubercart.

moby's picture
Offline
Joined: 10/05/2008
Juice: 156
Re: Thanks for the post Moby... I

so boost has been in for a few weeks.

what I like:
speed! googles webmaster tools graph is showing that now my average load times for pages are 2seconds.
previously i had spikes up to 15! (the joys of shared hosting i guesS)

what i dont.
not sure .. haha

that i still havent found a way to track cart abandonment.. when they get to the checkout page, but not proceed to the review page..

persianninja's picture
Offline
Joined: 06/10/2011
Juice: 38
boost + uc_ajax_cart steps

I got it working i think. Here are my steps:
################

First installed uc_ajax_cart module (used recomended drupal 6 version)
Then somewhere in the ubercart Store Configuration is a link to the UC Ajax Cart settings:
as recommended on project page, I:

1. Enable 'Ajax Support for anonymous users'
2. Disable 'Ajaxify cart page'
3. Select 'Ajaxify only products that have the specified CSS class' in 'Apply Ajax Cart functionality to specified products', and use a nonexistent CSS class like i just used: nonExistantCssClass

I would follow that exactly or the ajaxy stuff can do some goofy things as I found out. The last 2 options I didn't follow intially as i thought those options would be cool to have. Seem like need to do it so the POST to drupal handles everything vs an ajax function which may not know how to handle everything is what I'm thinking?

################
(Think I installed Global Redirect cause Boost recommends it as it will result in less duplicate content for Search Engines to find and Pathauto to create nice SEO names automatically... These are the filenames you'll find in your cached directory like content/_about_us.html instead of stuff like node/_12.html )
Then installed Boost module (used recomended drupal 6 version) for caching. PS I left my drupal caching set to Normal as well, and js/css caching enabled (not sure if Boost overrides all that anyway).
Boost settings are in Performance in another tab there...
Turn on caching in Boost settings tab:
'Boost - Static page cache:': Enabled,

and
'Cache every page except the listed pages.:' and these pages in textarea on each line:

uc_ajax_cart
uc_ajax_cart/*
cart
cart/*
checkout
checkout/*

I copied over .htaccess Boost rules in that other tab to my .htacess file.

################
Go into Blocks area and remove standard ubercart Cart from sidebar and put in the uc_ajax_cart one (called something like Ajax Cart) in that sidebar.
################
Go into Boost settings and click that clear button at bottom just to start from scratch in case accidentally cached stuff earlier (as i did from testing so much). There is another set of buttons to clear cached stuff in the middle. might not hurt to clear those. (Note sometimes it doesn't clear out every single file and 1 or 2 etc are left)
################
Go in a different browser and don't log in and start surfing your site...
/home/your-username/your-drupal-site.com/cache/yoursitename.com/normal/content or node etc should start filling up with cached content
################
(Maybe turn on the option in Boost settings for cron to prefetch and cache all your pages.)
################

OR if above too complicated take simple approach:
Just create a Block that always has a link listed to your cart (whether its empty or not, and never shows items in your cart in the sidebar... seems ghetto)
or keep the ubercart 2.0 cart and don't turn on the option to 'hide' it in the Block settings (it should do same thing and always show a direct link to your cart for anonymous users (logged in users like when your logged in as Admin will see item's in the cart since cache isn't used )). Basically both of these do the same thing for anonymous users, but isnt really good solution since most people buying stuff are anonymous and would be cool to show them cart items in the sidebar.

Dzah's picture
Offline
Joined: 03/22/2010
Juice: 44
zhangty, I am having the

zhangty,

I am having the same (or very similar) problem with Boost 6.x-1.18:
the cart block (present on every page) gets cached and shows content that anonymous users didn't put there.
The cart page itself shows that the cart is empty. This is probably because the caching of cart pages is disabled in Boost settings.
Going back to catalog pages shows some content again.

Did you find any solution for that other then removing cart block from every page?
Thank you in advance, I'd highly appreciate any help!

mitrpaka's picture
Offline
Joined: 05/30/2010
Juice: 3
Hi, Would also appreciate

Hi,

Would also appreciate solution for this if someone has been able to figure out how to exclude shopping cart from caching.

Would like to present cart block in every page and use Boost Eye-wink

hermes_costell's picture
Offline
Joined: 01/18/2010
Juice: 7
Re: Boost Module and Shopping Cart Block

In admin/settings/performance/boost

In the "Statically cache specific pages: " section

I checked "Cache every page except the listed pages."

And then entered these two in the textarea underneath it:
cart
cart/*

It seems to be working for me at the moment.

joethejoe's picture
Offline
Joined: 10/12/2009
Juice: 77
Boost Bust in Mini-Cart Block

Using boost-6.x-1.18 cuurent ubercart 2.4 and the anonymous mini cart is showing 0.00 when items added. The regular /cart works.
as per hermes_costell:
In admin/settings/performance/boost
In the "Statically cache specific pages: " section
I checked "Cache every page except the listed pages."
And then entered these two in the textarea underneath it:
cart
cart/*

--- also block caching is disabled

So mini-cart does not work for me with boost. It's a big deal from ui standpoint. Customers need to see what's in the cart.
Anything I should try?

916Designs's picture
Offline
Joined: 10/31/2008
Juice: 22
Boost for the win?

After researching this problem for days... I think I've finally found an acceptable solution.

Ubercart: 6.x-2.x-dev, probably works fine with 6.x-2.4
Ubercart Ajax Cart: No! Isn't it kind of funky anyway?
Boost: 6.x-1.18

So basically Boost gives us the option to not cache certain pages. While you may want the Shopping Cart block on every page, it probably isn't necessary. I set the standard shopping cart block to hide when empty, and to only show on my "main" pages, and not on deeply nested/hidden pages like blog posts that anonymous first time customers are not likely to look at after adding a product. But then again, I'm not working on a standard online store so I don't know. More later.

So then you set boost to not cache these same pages (pages that your shopping cart block will appear on.)

Results:
-Even pages that have Boost page caching disabled (cart block pages) are incredibly fast. 4x faster for my slower localhost setup
-Anonymous shopping cart blocks show up as expected- hidden when empty, correct quantities with items added to the cart
-Tested with 2 anonymous users "at the same time", no overlap in items, cart ghosting, or failure to update quantities (as expected)

So I'm pretty jazzed on this and hopefully everything will hold up after further testing. Need the cart block on every page? Write a snippet to detect if the cart block is present under Boost's "Statically cache specific pages:" setting or try "Cache only the listed pages." and put nothing in the box (technically no page caching). I'm figuring that Boost's other performance gains will offset the fact that caching of pages with the Cart Block is disabled. Just theory of course. I suppose Ajax Cart is the other option, though I did not like it.

Hoping the issue will come to a close with D7. This issue is critical to usability and affects my ability to recommend Drupal+Ubercart as a viable solution to online shopping.

@joethejoe try what I'm suggesting and let me know!

joethejoe's picture
Offline
Joined: 10/12/2009
Juice: 77
Re: Boost for the win?

Once a customer adds to the cart it is necessary, from my perspective, for the cart to always be visible if it is shown on one page block and it must always be absolutely correct. So I'm abandoning the idea of boost AND the cart showing in page blocks. I loves my boost so I am unwilling to let it go.
My approach now is to use the uc_ajax_cart in growler mode. This way the user receives positive feedback when adding to the cart. I should note that I do not send the user to the cart page everytime they add to the cart. This would be another option of course but I find it tiresome for the user.
916Designs, This is all about usability and it changes from site to site. So I am aware that what makes sense for the site I'm working on does not apply universally.

However I am having an issue with uc_ajax_cart that I am posting on a separate thread

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Boost for the win?

Issues to UC Ajax Cart should be placed in that project's Issue Queue on drupal.org, since it's not part of Drupal core. http://drupal.org/project/uc_ajax_cart.

Since Boost caches things statically, and in doing so bypasses the database, an Ajax region is the only true viable option. This would also be true if you were using Authcache to cache authenticated user content.

--
Help directly fund development: Donate via PayPal!

lindenlion's picture
Offline
Joined: 11/12/2008
Juice: 39
How about a cart counter, instead of a cart content block?

I spent some thought on this issue recently, and maybe the idea that I came up with sounds interesting to you?
My thoughts are: Cached pages are static. Cart contents are not.
The number of items in your cart is also not static, but it is at least small enough to store in a cookie.

So, what if static pages were able to incorporate a single number from a cookie in the pages they serve? You'd have a cart counter! This is at least more user-friendly than a static cart block which doesn't give the user any dynamic information...

Tell me your thoughts:

http://www.ubercart.org/forum/bounties/20605/anonymous_cart_counter_comp...

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: How about a cart counter, instead of a cart content block?

Yep, this is what we're doing on http://www.rifftrax.com. The "Cart" link at the top gets updated via jQuery. We have it setup so that when the page is done loading, jQuery fires off a custom callback I wrote that just returns the number of items in a user's cart. Using jQuery we then update the text "Cart" to include the item count. Would be a cool addition to the cart module itself, as it's only a few lines of code, and could be part of Drupal.behaviors wherever there is a "cart" link. (Maybe a setting for this would be good, too.)

--
Help directly fund development: Donate via PayPal!

lindenlion's picture
Offline
Joined: 11/12/2008
Juice: 39
javascript

Hey torgosPizza, thank you for the reply.
My concern is that not everyone is using javascript, and that javascript calls are just additional (small) page requests, which I am trying to avoid if possible. Would it be possible to achieve the same by caching the cart count in a cookie and just updating this cookie using regular php calls when changing the cart contents? What are your thoughts, can it be done?

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: javascript

No, it can't be done. You answered the question yourself by saying "Updating the cookie using regular php calls when changing the cart contents." Once you've used PHP, that means you're no longer using Boost - unless your solution is to use a javascript callback that's called asynchronously. That's the only way, with current web technologies, to do it that I'm aware of.

Otherwise you might as well not be using Boost.

--
Help directly fund development: Donate via PayPal!

lindenlion's picture
Offline
Joined: 11/12/2008
Juice: 39
I'm not convinced though...

On requests that change the cart content, I want regular dynamic page calls, so I don't think it'd be too much of a problem getting the cookie updated server side. A whole heap of stuff needs to checked anyway, like how many items are still in stock, and whether the resulting cart content would be available.

But when the cart content is not changing I want a cached page with a number stored in a cookie displayed on the page. It would probably be very easy to use javascript to print the contents of a cookie into a page, right? That's even an acceptable solution... people without javascript could always just login to get their cart contents displayed properly, it's more of minority issue.

But why wouldn't having a single line like

<?php
print $_COOKIE['cart_counter'];
?>

in the cached page not work with boost?
What about regular page caching?

Making unnecessary ajax requests slows your site down, that's my main issue.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
lindenlion wrote: On requests
lindenlion wrote:

On requests that change the cart content, I want regular dynamic page calls, so I don't think it'd be too much of a problem getting the cookie updated server side. A whole heap of stuff needs to checked anyway, like how many items are still in stock, and whether the resulting cart content would be available.

But when the cart content is not changing I want a cached page with a number stored in a cookie displayed on the page. It would probably be very easy to use javascript to print the contents of a cookie into a page, right? That's even an acceptable solution... people without javascript could always just login to get their cart contents displayed properly, it's more of minority issue.

But why wouldn't having a single line like

<?php
print $_COOKIE['cart_counter'];
?>

in the cached page not work with boost?
What about regular page caching?

Regular page caching would be fine, because you're still serving PHP scripts. Boost saves your dynamic pages as static html, and serves them via apache. Since these are static html pages, you cannot use statements like <?php print $_COOKIE['cart_counter']; ?>.

Quote:

Making unnecessary ajax requests slows your site down, that's my main issue.

No they don't; thats why they exist. The point of an ajax request is that it happens asynchronously. When done correctly (on document.ready() or as a Drupal.behavior) the ajax request only fires once the page is done loading. This alleviates page load and speeds up the time it takes for your page to render. And since it's javascript/jQuery it can degrade gracefully; for instance on rifftrax.com, the cart counter shows up if you have javascript enabled. With javascript disabled, it just says "Cart".

However keep in mind that, even when using Boost, as soon as you add an item to your cart, a session cookie is created and you're no longer receiving truly cached pages. Well, that's not entirely true; you could still have cached product pages, but the cart page will need to stay un-Boosted in order for the cookie with your cart/session info to be updated. This is for the same reasons I've mentioned above.

Does this makes sense? If this is still confusing, let me know.

EDIT: I just re-read this part of your comment:

Quote:

But when the cart content is not changing I want a cached page with a number stored in a cookie displayed on the page. It would probably be very easy to use javascript to print the contents of a cookie into a page, right? That's even an acceptable solution... people without javascript could always just login to get their cart contents displayed properly, it's more of minority issue.

This is exactly what I've been saying is the only way you can do it. It's how we're doing it on rifftrax.com. As an anonymous user, you can browse the site, and you'll continue to see Boost content (static html pages) and as you add items to your cart, the counter (at the very top) will be updated - but that's triggered via a jQuery AJAX request.

Sorry if I've caused any confusion. Smiling Hope this helps in some way.

--
Help directly fund development: Donate via PayPal!

lindenlion's picture
Offline
Joined: 11/12/2008
Juice: 39
well that sounds good.

It does sound like an easy fix to make a javascript ajax call to retrieve the cart count.

I'm wondering though how much strain that would put on the server?! I get what you're saying about the document.ready, but that's on client-side and not what I am referring to here.

You know, in Ubercart I've noticed the tax module makes ajax calls on checkout pages.In my performance log details I found that a dynamic page takes about 40-60Mb to load, whereas a cached page only 3Mb, but a simple tax call is like 25Mb! Another module that I have, the out of stock module, makes ajax calls to get the current stock status of products, and that is about 25Mb each call as well. So I am a bit wary on making ajax calls now, if you know what I mean. Two of those calls and you might as well just serve a dynamic page in the first place...

So what about this custom ajax call that you wrote, how much Mb does the server use to process that request? If it's any more than 4Mb I think I'd still prefer to cache the cart count in a cookie and grab it from there. I'd just need to find a few hooks in the cart module that allow me to set and update the cookie cache, and if I understand you right, using javascript to print the cookie content in the page would even work with Boost.

What do you think? Am I on the right track?

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
lindenlion wrote: It does
lindenlion wrote:

It does sound like an easy fix to make a javascript ajax call to retrieve the cart count.

I'm wondering though how much strain that would put on the server?! I get what you're saying about the document.ready, but that's on client-side and not what I am referring to here.

You know, in Ubercart I've noticed the tax module makes ajax calls on checkout pages.In my performance log details I found that a dynamic page takes about 40-60Mb to load, whereas a cached page only 3Mb, but a simple tax call is like 25Mb! Another module that I have, the out of stock module, makes ajax calls to get the current stock status of products, and that is about 25Mb each call as well. So I am a bit wary on making ajax calls now, if you know what I mean. Two of those calls and you might as well just serve a dynamic page in the first place...

So what about this custom ajax call that you wrote, how much Mb does the server use to process that request? If it's any more than 4Mb I think I'd still prefer to cache the cart count in a cookie and grab it from there. I'd just need to find a few hooks in the cart module that allow me to set and update the cookie cache, and if I understand you right, using javascript to print the cookie content in the page would even work with Boost.

What do you think? Am I on the right track?

The code that I wrote returns nothing more than the integer of how many items are in the cart. According to Firebug this request is only 21B. That's "bytes". What "simple tax call" are you requesting that takes 25 megabits to load? (That's just about 8 megabytes!). Where is this measurement coming from? That is surely not correct, unless for some reason your ajax requests are loading up an entire page? Or are these server stats you're talking about? In that case, that is probably an Apache or RAM footprint or something.

Ajax calls do not normally request that much data, so I'm really curious as to what it's returning that is 25Mb, or how it is exactly that you're measuring it. Is there a link we can see?

Are you not caching/aggregating your CSS and JS? That is a first step to lowering the amount of bytes a page contains. You should also look into making CSS sprites for your images and serving them from a CDN. That's usually the largest culprit to page load, and is easily fixed. A quick and easy way to get spites is at http://spriteme.org.

Hope this helps!

EDIT: By the way, I just checked the Firebug stats in my Checkout page, and to calculate the tax and shipping (via ajax request) only takes 284B.

--
Help directly fund development: Donate via PayPal!

lindenlion's picture
Offline
Joined: 11/12/2008
Juice: 39
Hey mate,

I'm talking about the PHP Memory footprint of requests. It might be only a few bytes of data that is being transferred, but still use alot of memory on the server.
It's what I can see when I use the Devel module's performance details log.
Does this make sense? and do I even need to worrie about it? I guess I am talking about server-side performance and you are about client-side performance.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
lindenlion wrote: I'm talking
lindenlion wrote:

I'm talking about the PHP Memory footprint of requests. It might be only a few bytes of data that is being transferred, but still use alot of memory on the server.
It's what I can see when I use the Devel module's performance details log.
Does this make sense? and do I even need to worrie about it? I guess I am talking about server-side performance and you are about client-side performance.

You don't need to worry about this at all, at least, not in the way that you're currently worrying about it. The php memory footprint is going to be there no matter what type of request you make, whether it be a simple ajax request or serving up an entire page. The only time you need to worry about your apache/php memory size is when you're setting up your server. Memory is directly related to how many connections your server can have open at any given moment, all at once. But apache requests, in general, are only open for as long as it takes to serve the request, and then they die - meaning that memory is only used for a very short amount of time.

The amount of memory each request makes will be about the same, but this is a result of several things - mainly what php modules your server is using, what other applications or servers are running on top of it (such as opcode etc). It's less an issue of serving data to your visitor and more an issue of apache processes that can be spawned in memory before you start swapping into disk memory, which is slow and can cause servers to hang.

If you're worried about your server memory, you should consider load testing your site and seeing what these memory settings should be, and if your apache footprint is low enough to accommodate what your settings are now. I'd recommend a good hosting company that can help you with these things, or a third party consultation from a Drupal-centric firm - there are many listed on drupal.org that provide this kind of service.

--
Help directly fund development: Donate via PayPal!

Summit_drupal's picture
Offline
Joined: 12/11/2010
Juice: 137
Hi, I am using uc_microcart,

Hi,
I am using uc_microcart, and also having problems with caching. Anyone simple solution to get the cart block working with caching. It seems to work on every page except homepage in my situation.
Subscribing, to this thread.
greetings, Martijn

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Hi, I am using uc_microcart,

Martijn, please see my solution below and see if it works for you. (You'll need to add a link in a menu somewhere that just says "Cart" and links to the cart page.)

--
Help directly fund development: Donate via PayPal!

James Peck's picture
Offline
Joined: 10/20/2010
Juice: 51
Boost / Cart

Hi - I've recently installed Boost to aid my creaking site and ran into the same problem as every-one else - that it doesn't work nicely with shopping carts!

Your jQuery solution seems to be the only method that makes sense to me and you've clearly designed your process/site well around this "limitation."

Is your solution something that you can share or sell?

i.e. can your code be picked up from one site and elegantly plonked onto another? Or is it very specific to RiffTrax?

Cheers - James

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Hey James, It's not specific

Hey James,

It's not specific at all. It's actually quite simple, however it's a two-part process.

1) I have a custom module that I wrote where I have a simple menu callback that calls a function for counting the # of items in a cart.

So in my example.module file, there's this:

<?php
function example_menu() {
 
$items['ajax/cart/count'] = array(
   
'title' => 'Add to cart ajax callback',
   
'access arguments' => array('access content'),
   
'page callback' => 'example_ajax_cart_count',
   
'type' => MENU_CALLBACK,
  );
  return
$items;
}

// Callback
function example_ajax_cart_count() {
  print
uc_cart_get_total_qty();
}
?>

2). Create a Javascript file (I call it example.js) and add it to your theme's .info file so it's added on every page load. All you need is to wrap your jQuery function in a document.ready (or in Drupal.behaviors) like so:

$(document).ready(function(){
    $.get('/ajax/cart/count', function(data) {
      $('#header-topnav').find("a[@href*='/cart']").text('Cart ('+data+')');
    });
});

(this part could also be done in Drupal.behaviors)

That's it! Clear your cache, and put a Menu Link somewhere that is just "Cart" and points to your shopping cart. (I like a navigation strip like on rifftrax.com where it's easily accessible, but less intrusive than a full Cart Block would be). The jQuery function will find it and automatically populate it with the data returned from your callback, which is the count of the number of items in the current cart.

Hope this helps! (And perhaps I'll make it into a tiny module someday.)

EDIT: Had to make the URLs match so they weren't specific to my custom rifftrax module. Good luck!

--
Help directly fund development: Donate via PayPal!

James Peck's picture
Offline
Joined: 10/20/2010
Juice: 51
Hi, me again... Firstly,

Hi, me again...

Firstly, thank you for your super fast response yesterday, unfortunately I'm taking a bit longer! I've tried the above and it is not quite working yet.

I've added the module - I even enabled it - eventually!

I've added the Javascript file and referenced it in the theme's .info - I can see that it is being called so assume that this part is working. I replaced '#header-topnav' with '#primary-menu-inner' to reflect where I've placed 'Cart' on my site, which is to the right of the primary menu. (I'll move it once it's working!)

I've cleared all caches repeatedly.

I'm not sure if I should be changing anything to make it specific to my site? For example, I can see that 'ajax/cart/count' is universal, but not sure if I should be personalizing 'example_ajax_cart_count' or 'example_menu'?

Am I missing something obvious?!

My site - http://www.pharmacys.com.au/

Thanks again for your help - James

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Hi, me again... Firstly,

Okay, I got it. Looks like you're using jQuery 1.3.2, which apparently doesn't like the find syntax I was using.

This works:

$.get('/ajax/cart/count', function(data) {
  $('#primary-menu-inner').find('a[href$="/cart"]').text('Cart ('+data+')');
});

You could also do:

$.get('/ajax/cart/count', function(data) {
  $('a[href$="/cart"]').text('Cart ('+data+')');
});

... but that would affect *every* link to the cart. The first one just alters the one in your menu bar.

--
Help directly fund development: Donate via PayPal!

James Peck's picture
Offline
Joined: 10/20/2010
Juice: 51
Re: Re: Hi, me again... Firstly,

Mr Pizza Sir you are a legend.

Slab of cold 'uns on its way via PayPal.

Cheers
James

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Re: Hi, me again... Firstly,

Well, thank you kindly. I'm just glad to help!

Site looks great - nice work! Smiling

--
Help directly fund development: Donate via PayPal!

tr3online's picture
Offline
Joined: 03/23/2011
Juice: 26
Re: Re: Re: Re: Hi, me again... Firstly,

This is a great snippit of code. If I could get it working right, it would be even better Eye-wink This is exactly something I need.

My problem is I'm not on a domain yet, so I am @ a http://IP/~username/.

I played around a bit, and removed the / from $items['/ajax/cart/count'] = array( to get $items['ajax/cart/count'] = array(

I'm also using :

$.get('/~username/ajax/cart/count', function(data) {
$('#cartRight').find('a[href$="/cart"]').text('Cart ('+data+')');
});

I'm sure I'm doing something wrong in terms of pointing to the server (I'm not good with ajax or javascript).

What's happening is if I add an item to cart, I get my ajax cart popup saying I added it, but the number does not change.
If I reload the page or re-run the :
$.get('/~username/ajax/cart/count', function(data) {
$('#cartRight').find('a[href$="/cart"]').text('Cart ('+data+')');
});

via firebug, the number updates. What can I do to fix this?

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Re: Re: Re: Hi, me again... Firstly,

I'd have to see your site. Can you post a link?

My first guess is that it has something to do with your href tag. Did you try the 2nd option I mentioned after seeing that the other poster was using jQuery 1.3.2?

--
Help directly fund development: Donate via PayPal!

tr3online's picture
Offline
Joined: 03/23/2011
Juice: 26
Re: Re: Re: Re: Re: Re: Hi, me again... Firstly,

Shot ya an email with the link to my site.
$('#cartRight').find('a[href$="/cart"]').text('Cart ('+data+')'); works just fine for the replacement string. I just cant get the Cart () to auto update :|

James Peck's picture
Offline
Joined: 10/20/2010
Juice: 51
Re: Re: Re: Re: Re: Re: Re: Hi, me again... Firstly,

Hi - not sure if this will help - I did some tinkering in the boost settings.

I excluded these pages -

ajax/cart/count
cart
cart/*
checkout
checkout/*

Best Wishes
James

com_net's picture
Offline
Joined: 11/29/2010
Juice: 22
strange behavior...

... can You help with strange problem?
site: www.legrand1.ru
After module update (can't say exectly - which module)
1)cached catalog pages became very slow (7-20seconds delay before content transfer begins even for unregistered users)
2) ajax cart shows correct content only after manual bypass cache (ctrl+F5). Otherwise shows random "cached" cart content.
You can see 3 different results: after adding or removing item from cart, afyrt pressing F5 and after pressing ctrl+F5..
Before "upgrade" typical page load time was 0.8-1.2s.
Now sometimes I see 30s delay to add product to cart.
(some strange actions like reinstall modules, clear cache, change various tuning options etc., results nothing)
___
site uses boost+CacheRouter+APC+object cache, patched (filters) advanced catalog.
Now apache solr facet filters "live" requests about three time faster, then cached ubercart advanced catalog pages...
___
dedicaded server, almost no load, almost all modules are latest development versions.
___
without boost it takes about 3s to load any catalog page, but ALL pages begins with empty string (before <!DOCTYPE...)

com_net's picture
Offline
Joined: 11/29/2010
Juice: 22
boost+ajax cart

I had to disable boost module on a running site, but I assembled a special test site http://stock.satmania.com/ with a minimal set of modules, illustrating the non-functional of boost+ajax cart combination.
The proposal does not cache the page, if there are cookies - not a solution because uncached catalog pages are unacceptably slow.
...
I do not really understand how uncached catalog pages can work quickly, since the formation of the catalog page is accompanied by the executing of about 5500 sql queries. About 1ms each.

Slim Grin's picture
Offline
Joined: 04/24/2011
Juice: 5
stuck

Hi,

I followed your advice in #28 and also the first option in #30.. I added a 'cart' menu item to my Primary links but it doesn't show the (#).

My site is at:
http://uvulittle.com

Thanks

eliasb's picture
Offline
Joined: 05/14/2011
Juice: 12
It seems there is a little error in your module

Hello, Mr. Pizza. It seems there is a little error in your module.

Instead of:

<?php
'access arguments' => array('access content'),
?>

You should have:

<?php
'access callback' => array('access content'),
?>

You also didn't create a hook perm to allow access to this menu. Besides, there is no need to add hook perm since this module should run for every unauthenticated user. Therefore, you should write:

<?php
'access callback' => TRUE,
?>

And to make things more compact and simpler, you should add the JavaScript file into your module folder and load it through a drupal_add_js() call using a hook init like so:

<?php
function example_init(){
 
 
$path = drupal_get_path('module', 'example');
 
drupal_add_js($path . '/example.js', 'module', 'header', TRUE);
}
?>

You should name your JavaScript file as "example.js" and it should be placed in the example module folder.

The whole module code should look like this:

<?php
/**
* @desc
* Implementation of hook_menu()
*/
function example_menu() {
 
$items['ajax/cart/count'] = array(
   
'title' => 'Add to cart ajax callback',
   
'access callback' => TRUE,
   
'page callback' => 'example_ajax_cart_count',
   
'type' => MENU_CALLBACK,
  );
  return
$items;
}

/**
* @desc
* example menu callback for 'ajax/cart/count'
*/
function example_ajax_cart_count() {
  print
uc_cart_get_total_qty();
}

/**
* @desc
* Implementation of hook_init()
*/
function example_init(){
 
 
$path = drupal_get_path('module', 'example');
 
drupal_add_js($path . '/example.js', 'module', 'header', TRUE);
}
?>

By the way, this little module you posted here literally saved my day! Thank you so much, Mr. Pizza.

eliasb's picture
Offline
Joined: 05/14/2011
Juice: 12
IMPORTANT

Very IMPORTANT to mention!

Once the module is installed, enabled, and working you will have to go back to the Boost settings page (admin/settings/performance/boost) and do the following:

  • Go down to where it says "Statically cache specific pages" and make sure that the option "Cache every page except the listed pages" is selected.
  • Add the line ajax/cart/* to the text area titled "Pages:"

If you don't do this, Boost will keep caching the callback results and the Ajax module will always return the same value to the unauthenticated user.

By the way, just in case you are not sure what HTML to place in your page for the module to work, write the following to the place where you want the number of items to appear:

<div id="primary-menu-inner">
  <a title="" href="/cart"> Cart (0)</a>
</div>

There is one last thing that I wanted to mention.
If you want your callback function to return more than just plain text like, for example, html formatted data, you will have to use a JQuery function that is a little different than the one Mr. Pizza suggested.

The following JQuery code will return any html rich content that is sent back by the callback function. Create a JavaScript file in your example module folder and name it "example.js". Then, copy and paste the following function into this "example.js" file.

$(document).ready(function(){
  $.get('/ajax/cart/count', function(data) {
    $('#primary-menu-inner').find('a[href$="/cart"]').html('Cart ('+data+')');
  });
});