Adding pageviews to WordPress stats on galleries

Jetpack is awesome. Among many features, by default, it runs WordPress stats. While they are not Google Analytics by any means, they do give you a nice view on how your site is doing, with a very small footprint. The event code is just added to your site’s footer and voila! it just works!

The problem is your site’s footer doesn’t know anything. Slideshows, galleries, compilations and one-page apps are good examples of cases where the content of the page changes via Javascript with a click, or perhaps a time-based approach. As far as I know, wp stats doesn’t have a solution for this issue. I, however, have a hack ready to go, that works wonders.

NOTE: This code will not work on your site as is! but it will hopefully give you the general idea on how to do it.

Let’s make 2 assumptions: one, you have jQuery available (not necessary), and two, the page we have is a picture gallery and fires an event “pageChange” every time NEXT or PREV are clicked.

The part that does the pageview of course is:

This code was added on July 24th. Notice the traffic increase after July 25th.

One of the sites I handle has a lot of ajax type slideshows. Traffic itself didn’t increase, it just wasn’t being recorded on wpstats (see chart above)!

Boom! easy! The same concept applies to one-page applications. Make sure to pass the right urls and post ids to WordPress Stats.

Run javascript that depends on multiple remote assets

Async JS is the way of the present (and future). We MUST load all of our scripts async. They are getting heavy and slow, and the browser needs help, specially on mobile devices. Why wouldn’t you want your page to load faster (see this post).

As web pages grow more and more complex, the idea of a single script that does everything is Jurassic. But what if we want to run code that depends on multiple scripts at the same time? If your app/site is complex you should look into requireJS. If you need something less daunting … I got you (with jQuery):

Neat right? … Let’s kick it up a notch. Say we need the script AND some external data file:

And now the cherry on top … we want to load myData.json or yourData.json or just nothing conditionally:

 

I’m sure you can do something similar on vanilla JS … but if you need something like this, chances are you are running jQuery.

How to make SYNC javascript assets work ASYNC

Speed is everything. It always is … there is no such thing as “the page loaded too fast”. To make matters worse, today we have Google Pagespeed Insights to make our lives miserable (a whole different topic). They usually recommend loading your JS asynchronous (async) or on the footer.

Why?

Javascript is render blocking, which means the browser can’t work on displaying the page while the script is running. So, consider this:

If myscript.js takes 1 minute to load, the whole page will be delayed 1 minute, no matter how simple it is. Not cool. To fix this, we just add async to the script tag. This makes the browser start the load of the asset (myscript.js) but continue parsing html. The problem now is that because the asset is still loading, and will arrive in 1 minute, the function changeText() is not available by the time the browser gets to it. Your code will not run, but the page has loaded, which is good news.

 

How?

You can implement a queue or a callback*. Both ways work just as nicely, but they have different use cases. (* you can use Promises but that’s kind of a callback, just real fancy)

Queues work better if you need to do many calls to the same script in different parts of the page but all depend on the previous call one way or another. Here you go (Notice the change on the js file):

Tiny change … works like a charm … once myscript.js loads 1 minute later, it’ll execute all the functions pushed to the queue.

Potential pitfall 
Lets say instead of the script loading slow, it loads super fast. If you are working on the DOM, make sure the elements you want, are in place by the time the queue executes. In the example this is mitigated by adding to the queue after the dom element ( <div> ).

Implementing a callback is a bit easier, but works better if you only need to run code once. Notice, no changes are needed on myscript.js from the original version.

You can make a hybrid of these 2 approaches where the callback is the code to process the queue … but it feels a bit ghetto to me. I’m sure there is some good use case where this would be desirable. The same pitfall as above applies, but as long as you load the script after the dom element you’ll be ok.

As always there is a jQuery way to do this. And it is in fact quite nice, what I don’t like about it is having to load jQuery synchronous. That being said, you can probably turn all your jquery into a queue and now “we all happy“.

 

When caching is not enough: “Double Buffered” Remote Calls

One of the challenges of running WordPress at scale is dealing with API calls to (insert_external_service_here). Using wp_remote_get (or curl) is probably your go-to method for API calling and this is a fine function for a low traffic site. On a site that gets millions of pageviews, it is just not going to cut it. You will inevitably run into race conditions.

In case you don’t know, a race condition is when person1 is waiting on the server to finish the api call, then person2 makes another call, then person3 … then person X, but person1 is still waiting. If the API server is being slow, there could be a queue of thousands waiting, at that point, your server has crashed for sure. wikipedia

Another reason for not using wp_remote_get on every request is API limiting. Some services do not allow more than X calls per second/minute/day. If you make a call for every visit, you will surely reach that limit extremely fast!

Simple Solution: Caching.

By caching your call the “traditional” way, you’ve now gone way ahead from where you started. The API will only happen every 5 minutes, and people will not have to wait for the results as you have them stored already! This is just perfect for medium traffic sites and fast response APIs.

The problem with this approach is that at the 5 minute mark you still need to wait for the API to respond. If the response is slow you could run into a race condition again, because cache is invalidated, and it goes like so: person1 triggers cache invalidation (past 5 minutes) and calls API, person2 calls API too because cache is not valid, person3 same ….. person100 same, person1’s call is done and cache is set again for the next 5 minutes, person101 gets a cached result everyone is happy from here on, in the meantime, persons2-100 are still waiting on the response slowly. We have somewhat mitigated the problem, but not completely solved it. If the traffic is really high and the API is really slow, your server could crash.

If you have that kind of traffic, you are playing with the big boys. Lazy caching is not going to be enough.

Complex Solution: Double Caching

Instead of just caching the result, you can double cache it. To do so, we are doing the same thing as above, but twice. And we’ll do it in a way where cache1 lives for 5 minutes and cache2 lives for 10 minutes. When cache1 invalidates, that person makes the api call and sets a switch so everyone else uses cache2. Now only person1 is slow.

This is pretty great as is, but we can do better. Let’s say the API starts to malfunction for whatever reason. In that scenario, you’ll have good data for 5 minutes until the next time you do the call … not so awesome. Add a data consistency check (which you SHOULD have), and now we are in business:

The only caveat with that approach is if your backup cache invalidates. A neat alternative, save the backup in an option:

“Double Buffer”

Boom! Now even if the API fails or nobody accesses the page and cache dies, your site still has content, all you have to do now is find a way to alert you of the problem.

Overkill? yes … Works? … Really well!

Note: wordpress options have limited size, if the data you are storing is too big, you may want to consider WP Large Options.

To $(document).ready() or not to $(document).ready() ? that is the question.

TLDR;

If you place your JS/jQuery below the elements, you don’t have to use $(document).ready.

 

Wrapping all your Javascript in a $(document).ready. All the cool kids are doing it, and it is safe to do so. However, this doesn’t come without drawbacks. Also, there multiple considerations when it comes to loading jQuery itself, but that’s a different conversation.

jQuery SHOULD be loaded on the footer of your <html>. At this point, wrapping or not doesn’t really matter. The magic lies in the fact the by the time your JS runs, the elements are already on the page (aka above the script you are running ).

 

But let’s say you are forced to load jQuery in the <head> AND you are also forced (or want) to place your JS on <head> as well … now you HAVE to use $(document).ready( function() {} ); because by the time the JS runs, the elements to be selected haven’t been seen by the browser yet.

 

From https://learn.jquery.com/using-jquery-core/document-ready/

Code included inside $( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute. Code included inside $( window ).load(function() { ... }) will run once the entire page (images or iframes), not just the DOM, is ready.

Here’s where the issue lies. When you use $(document).ready() you need to wait for the entire page to load! So, if you want to have your JS do some kind of effect, like a sticky sidebar, or transitions, or anything at all, they will not happen instantly. Sometimes, this isn’t an issue, but the more images and external script your page has, the longer it takes for your js to run. This can be unacceptable, as most of the times, this causes your effect to start working at weird times, making the site … well … act weird.

The solution: instead of wrapping in .ready(), place the <script> just below the elements you want it to work on. Again, by the time your script runs, the elements have already been “seen” by the browser, and the effects will kick in even though the page hasn’t completely loaded yet. No need to wait.

 

Foundation 6 + Block Grid + WordPress Gallery

If you are using foundation i’m sure you love block grids, but wordpress galleries do their own HTML. No worries, throw this snippet in your functions.php (or wherever it belongs in your theme’s structure) and the markup will change to a blockgrid instead. This works with Foundation 6 … for Foundation 5 you’ll need to change the output to UL and LIs instead of row/column DIVs.

Easy. You are welcome!

 

Killer steak sauce (pseudo chimichurri)

Every steak can use this killer recipe! which in turn, it is not a true recipe, but more of a combination of flavors that you can adjust to your own taste. It goes especially well with flank steak or skirt steak. Chicken, pork, and fish also love this sauce.

  • Parsley or Cilantro (aka Coriander) or both. Lots of it!
  • Garlic. 2 or 3 cloves.
  • Cumin powder (or seeds). About half a teaspoon.
  • Red Pepper flakes.
  • Olive oil. A lot (think pesto)
  • Salt and Pepper
  • Optional: white vinegar

Warm up your olive oil and put the pepper flakes and cumin. Just warm up, so the oil gets infused with the spiciness and flavor of the ingredients. DO NOT FRY THEM … just warm it up. Once happy with the flavor, just leave it to cool down on the side. ( Experiment: put garlic on the oil as well, until soft. Cooked garlic tastes sweet )

In the meantime, chop the parsley/cilantro and garlic real small. Mash them together. Add salt and pepper to taste. When the oil is cool (you don’t want to cook the parsley/cilantro) mix it all together. Whisk it. Eat it! It is going to be AWESOME! I promise!

 

Static classes on WordPress plugins

If you have a wordpress plugin, more than likely you are using add_action and/or add_filter. No problem, until you get this error:

One of the annoyances of wordpress is that tracking bugs when in actions or filters can be a bit of a hassle, but you don’t know where the error actually originated, but with a bit of grep-ing of searching you can find the issue. With the error above however, what’s going on is not so evident. Consider the following plugin that does nothing:

Nothing seems wrong here, however, it throws the warning above. The right way of doing this is:

The key being __CLASS__ instead of self on the add_action line. When using static classes add_action and add_filter don’t like self however, if your class is not static, therefore, instantiated you can use add_action( $this, 'function' )  no problem. Seems odd, but that’s how it is.

Layers on Canvas

TLDR;

Can’t be done natively, use this instead: layeredCanvas

 

HTML5 Canvas doesn’t implement a layers mechanism. In order to implement this you can do it in 2 different ways:

Multiple canvas elements approach

Think of a layer as an individual canvas and then absolute position one on top of the other. Then to lay it out just wrap on a div with position relative:

What’s crappy about this is if you want to save the image you have to do a screenshot and then cut it, or you can only save one canvas element at a time.

Single canvas element approach

Natively, there is no way of doing this, but with a little bit of abstraction, it isn’t a problem. Think of a layer as a function, now you call the functions in order and you are mostly layered:

This is still a bit crappy … lets make it slight more layer-like. We can make an array of functions and run them in sequence. This is much better because now we can remove (or change the index) an element from the array effectively replicating a layer feel:

DONE! Not too bad … using this principle I created a more elegant approach that allows you a couple more neat little things like show/hide … try it, fork it, use it: layeredCanvas