WordPress Cookieless Domains

First off, cookieless domains are your friends for content distribution. Why? Because every time a web browser talks to a server it sends a copy of all its cookies for that domain. As you can imagine this is quite ridiculous if your client is requesting an image, CSS, JS or other static resource which can never use that cookie information. These wasted upload bits are totally unnecessary so lets get rid of them with the help of a cookieless domain.

Sub or New Domain?

You might think there is a magical ‘no cookies’ option on your server but there isn’t. A cookieless domain is simply one that has never set a cookie. This means two options; create a sub domain (like s.forstmist.org) or create a new domain name.

At first glance a sub domain seems nice and simple but there is a caveat. If you redirect your visitors from a sub domain (www.forestmist.org) to your root domain (forestmist.org) you’ll end up with cookies on your root domain. These root cookies are automatically sent along with any requests to all sub domains. That’s right, having cookies on your root domain taints all your sub domains from becoming cookieless domains. This is not a concern if you channel all your visitors to a www sub domain since any cookies there will not be available to the root domain and therefore won’t taint other sub domains.

For short domain name lovers, registering a new domain for serving static content is a no brainer. I definitely fall into this category so I registered forestmisty.org which I shall use as an example in the rest of this guide.

.htaccess Redirect

With the new misty domain setup and pointing to my web server everything was working great. Requests to static images weren’t passing cookie information but what if someone went to the root of forestmisty.org? What if a broken link sent them to a 404? WordPress would handle the request and that means potential cookies from it or Google Analytics. Yikes!

What would be nice is if we can allow any requests for forestmisty.org/wp-content/ but redirect anything else back to forestmist.org. We can do exactly that with the following .htaccess commands.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^forestmisty.org$ [NC]
RewriteCond %{REQUEST_URI} !^/wp-content/?(.*)$ [NC]
RewriteRule ^(.*)?$ http://forestmist.org/$1 [R=301,L]

The first line enables the Apache rewrite engine.
The second line says anytime a request comes in for ‘forestmisty.org’ continue to the next line.
The third line says if the request is NOT for ‘/wp-content/…’ continue to the next line.
The forth line says if we made it this far redirect the original request to forestmist.org including any extra query information like /favicon.ico, /creative-resume, etc…

By the way…
^ means the start of a string.
$ means the end of a string.
? means the preceding character or collection in parenthesis is optional.
. means any one character.
* means the preceding character can occur 0 or more times.
$1 means insert whatever was inside the first set of parenthesis to the left.
[NC] means not case sensitive.
[R=301] means do a 301 redirect.
[L] means the last rule so don’t bother processing the rest of the .htaccess file.

Now we can rest assured that requests to our new cookieless domain will stay cookie free by only servering up what are almost always static file requests from the /wp-content folder.

Configure WordPress

Our new domain is setup and protected pretty well thanks to our .htaccess file so now it’s time for WordPress to join the fray. Specially, WordPress needs to have any /wp-content  links rewritten to point to the same location on our cookie free domain.

  • Download, install and activate the excellent CDN Linker by W-Mark Kubacki.
  • Login to WordPress
    • Settings » CDN Linker
      • Enter your new cookieless domain for CDN URL.
      • Change your ‘Include Dirs’ line to read ‘wp-content’ if you setup your .htaccess file like mine.
      • Save Changes

Load your home page and view source. You should see your new cookieless domain being referenced quite often. Yay!

Success

With a little bit of effort our server is less stressed, our clients are loading faster and hopefully you’ve got a silly grin on your face.


PHP 5 – Sort by Folder

Recently, I needed to display a list of files with PHP. My only caveat was that I wanted to do so using newer methods of PHP 5 where possible.

I was delighted to find scandir. Problem was, scandir returns files mixed with folders and that would upset my flock of easily frightened Windows users.

So a quick… er medium… ok fine,  an exasperating search on Google and only outdated, complex and inefficient samples were to be found. PUFF!

So, here is the version I came up with.

Demo

Downloads

How it works

The most crucial part of all the code you will see inside the demo is the PHP getObjects() function. Without this everything else would be moot so lets go over it in a bit more detail.

function getObjects($path) {
    $path .= '/';
    $array = scandir($path); // returns an array of files and folders sorted alphabetically
    $array = array_diff($array, array('.', '..', '.DS_Store', 'Thumbs.db')); // filter out things we don't want

    $return_array = array();

    foreach($array as $item) {
        if(is_dir($path . $item)) {
            $return_array[$item] = getObjects($path . '/' . $item);
        }
    }

    $count = 0;
    foreach($array as $item) {
        if(!is_dir($path . $item)) {
            $return_array[$item] = $item;
            $count++;
        }
    }
    if($count == 0) {
        $return_array[''] = '';
    }

    return $return_array;
}

Line 3
Scandir returns an array of mixed folders and files for the path requested. This does not include sub directories.

Line 4
Filter out any undesirables. That means the current ‘.’ and parent directory ‘..’ although we don’t want any Mac ‘.DS_Store’ or WIndows ‘Thumbs.db’ files either.

Line 6
We create a new array called $return_array which will be built up with all the folders and files in the order we want them. Folders first, then files. Both alphabetically.

Line 8-12
Here we loop through each item in our filtered results from scandir. If the item is a directory we set the results of $return_array[$item] to a recursive call of the very same function we are already in. Traveling deeper each recursive call, that means we can handle seemingly infinite directory structures. Neat.

This first loop through only cares about directories which is exactly what puts them first in our $return_array. Files will come next.

Line 14
We set a variable $count to 0 to keep track of how many files we find in the next foreach loop.

Line 15-19
In this second loop we check to make sure the items are not directories and if so return those items while incrementing the $count variable.

Line 21-23
Now that we are finished looping for files we can check our $count variable. If 0 then set $return_array to ”. This can useful later in case we want to do something special for directories without files.

Line 25
Finally, we return whatever we have found. In most cases this means returning an $array to another instance of the function although ultimately the original one will return a completed array to the PHP call outside our function that started it all.

In the demo we can now loop through this nicely ordered array and write out some HTML and CSS, add a sprinkle of JavaScript and we have a real working web app.

Epilogue

Once you get your head around recursive loops things become much simpler. Plus you get to worry more about optimizing your code since each loop can be run so many times. It’s a good problem to have, really.

Anyway, I certainly hope this helps you in your next endeavor. I know I certainly would be lost without all the wonderful code and tutorials shared by others.

Cheers!


ForestMist Regeneration

I’ve been making some big changes in my personal life so I felt my website needed to reflect that. Something new, clean and more optimized. It’s no Muramasa but it’s definitely a stepping stone towards something even more fantastical. Plans within plans my friend.

I think it came out pretty nice. Works perfect in nice browsers like Chrome, FireFox, Safari, Opera and even works well in IE 6, 7 and 8. The nicer browsers will have subtle shadows, rounded corners, bit cleaner lines between items but really that could be considered progressive enhancement. The site is perfectly readable in old busted browsers too. Good job if I do say so myself.

I learned a lot on this project, more so than I had imagined but then again… good projects always prepare you for the next challenge. I’m proud to have stuck with it over the course of many days it took.

xoxo

-Daniel