Variable values don't persist across different snippets, even when they're on the same page or in the same template. In the previous article, we looked at using a
$_SESSION variables to pass data to another snippet. In this one, we'll see how to do it with cookies.
In the previous article, we looked at
$_SESSION variables. Cookies are very much like
$_SESSION variables except that they persist across separate visits and can be accessed and deleted by users.
A cookie is a bit of data sent by code on your site to your browsers. The browser stores the cookie in a file and when the same user visits another page, or comes back to your site later, more code on your site can read the cookie from the PHP
$_COOKIE array and retrieve the data.
There are many sites that do a good job of explaining cookies. Here is one of them. Here is another one that is aimed at marketers. If you Google "Cookies" you'll find plenty more. The PHP manual page for the
setCookie() function is also useful in understanding cookies from the point of view of a developer.
Problems and Limitations
Cookies are problematical for several reasons. One problem is the need to set a cookie before any page output has occurred. If you try to set a cookie later in the process, you'll get a "Headers already sent" error and the cookie won't be set. Fortunately, MODX executes the code of all snippets on a page before the page is ever sent to the browser. Setting a cookie in a snippet should always work unless an earlier snippet on the page successfully flushes the output buffer, which is unlikely.
There are also limits on the total number of cookies that can be set in the browser and the number of cookies that can be set per domain. There are limits on the size of each cookie (usually around 4096 bytes). The limits vary between browsers. The maximum total number or cookies usually quite large (sometimes unlimited). For quite a while, the total number of cookies per domain was set a 20. This is still true for older versions of IE, but most modern browsers will allow at least 50 cookies per domain. IE 7 will allow 50 and Safari will allow up to 600. There's a nice listing of the various browser cookie limits here.
Cookies are also browser-specific. That means if you set cookie when a user visits your site and the user later comes back using a different browser, the cookie value won't be available, though most users have a favorite browser that they use for all sites.
There are alternatives to cookies that we'll see in the next few articles, but they are only useful if users log in to your site. If you need user-specific data to persist across visits for anonymous users, cookies are really your only choice.
No matter how you arrange things, users will be able to see the value of any cookies you set. Never put sensitive data in a cookie!. You can encrypt data before setting a cookie, but since you need a way to decrypt it later, you can't use a one-way hash, which compromises the security of the data.
Setting Cookies in MODX
Setting cookies in MODX is usually done in PHP, using the
You can certainly roll your own cookie setting code with
setCookie(), and get the value later with
$value = $_COOKIE['cookieName'], but for most cases, it's a lot easier to use David Pede's excellent MODX extra CookieJar. The CookieJar documentation is very good and should tell you all you need to know about setting your cookies. CookieJar has two snippets, one to set cookies and another to retrieve them. When retrieving them, you have the option of using the value directly, setting a placeholder for the cookie value, or using a Tpl chunk to display it.
Passing data between snippets with CookieJar is very easy. The two MODX tags below don't need to be on the same page as long as the first one (snippet1, the snippet that returns the cookie value to be set) executes before the second one does:
[[!SetCookie? &name=`my_cookie` &value=`[[!Snippet1]]` ]]
[[!Snippet2? &cookieValue = `[[!GetCookie? &name=`my_cookie`]]` ]]
In Snippet2, the cookie value will be available with:
$value = $modx->getOption('cookieValue', $scriptProperties, 'default value', true);
The default value will be used if the cookie is not set or is empty.
At this writing (with CookieJar 1.0.3), the cookie value will not be available to the second snippet on the page until the page is reloaded. I've suggested a change to David that will fix this, so that may not be the case by the time you read this. If not, here is the fix. Just add this line to the SetCookie snippet right below the call to
$_COOKIE[$name] = $value;
If you roll your own cookie code, using the line above will also work to make the cookie value available without a page reload. Here's an example that will set the cookie with no expiration date for the whole domain and an example of retrieving the cookie in a second snippet:
In snippet one:
$value = 'some data'; setcookie("my_cookie", $value); $_COOKIE["my_cookie"] = $value;
In snippet two:
$value = $_COOKIE['my_cookie']
In the next article, we'll look at passing user-specific data to another snippet using a User Setting, which will persist across different visits to the site.
Looking for high-quality, MODX-friendly hosting? As of May 2016, Bob's Guides is hosted at A2 hosting. (More information in the box below.)