What the Queries

I’ve never been a fan of IDEs, complex debugging tools with breakpoints, variable watch lists and all that fancy stuff. var_dump() and print_r() have always been my best friends.

Recently I was playing around with the caching arguments in WP_Query, trying to combine that with update_meta_cache() while sticking wp_suspend_cache_addition() somewhere there in the middle, and it quickly became a mess, so I wanted to know what queries am I actually running under the hood.

I came up with this little piece, which I think I’ll use more often from now on:

// Assuming SAVEQUERIES in set to true.
$GLOBALS['wpdb']->queries = array();

// All the magic goes here

var_dump( $GLOBALS['wpdb']->queries );

This gives you a nice list of SQL queries that were triggered only by that magic code in between. Works great when you need a quick sanity check on all those caching arguments, priming meta or term caches, splitting queries and whatnot.

Obviously it empties the initial set of queries, so anything in Debug Bar, Query Monitor, etc. will no longer be accurate.

What’s your favorite way to keep track of queries?

WordCamp Russia 2015 Recap

We did it.

WordCamp Russia 2015

WordCamp Russia 2015 was held last weekend in the amazing Digital October Center in Moscow. Attendance didn’t change much from last year — we saw about 200 people in person, but a lot of them (~ 60%) were folks who never attended a WordCamp before.

The attendees survey showed great results, pretty much in line with last year and with what we expected overall. The pizza was good, the lounge music was praised, the presentations were terrific.

One thing that stood out was a gentleman, who for some reason decided that it was okay to jump up on stage during a presentation, and point out some (supposedly) mistakes that the speaker had made in their code. Awkward. I guess we’re going to have to hire a bouncer next year.

Here are some other things we learned this year:

  • Some communities don’t care about Wapuu and friends, they’d rather have a t-shirt with a W logo instead
  • If you’re playing music in the hallway during breaks and lunch, make sure you normalize all the tracks
  • Lights, shooting video and a projector don’t go well together, luckily inverting some slides helps
  • With two tracks available perhaps it’s a better idea to split presentations by popularity, rather than just user/dev
  • Launching a screen recording on the presenter’s laptop during their talk is a great idea, video production goes much faster

Big thanks to the organizing team, all the volunteers, speakers and sponsors who made WordCamp Russia a success!

Capture the Flag / OTA 2015

This past weekend I participated in my first Capture the Flag challenge which was hosted by Matt Hamilton (Eriner) and other folks of the OTA Team. It was an epic 72 hours. We teamed up with my brother and took 5th place.

During those 72 hours I learned a lot more than I knew about steganography, cryptography, filesystem superblocks, and even got to sharpen my math skills. I must admit I knew nothing (or maybe forgot everything) about calculus.

My favorite challenge was cracking an Enigma-encoded message. It turns out that the military version of this 1920s machine has over 158 quintillion (!) different ways to setup the initial key. My first blind attempt at bruteforcing it yielded only one million combinations in about 10 minutes. Yeah, good luck with that.

The Enigma Machine

Luckily there are much more effective algorithms to crack the message in fewer steps (yes, faster than the Turing Bombe), by relying on quadgram statistics, given that we know the language of the original message.

Thanks to the OTA Team for hosting this online event! If you’re looking to join such an event in the future, check out ctftime.org.

Color Options vs. Decisions in WordPress Themes

One feature I was particularly excited about in Twenty Fourteen is the “accent color” which lets you personalize your theme by changing the default green to whatever you like. Unfortunately the feature was removed in #26220, mainly due to the fact that it allowed users to make bad choices, like using a color with a bad contrast, rendering their website ugly and unusable1.

I’ve been thinking about this a lot after that commit, and even more lately. Many themes come with color options these days and the vast majority suffer from the very same problem — poor user choices.

Take Weaver for instance. The options panel will let you adjust the color of probably any single element on your site:

weaver-color-options

I can’t say I love Weaver’s default look and feel — it’s okay. But it’ll only take a few minutes for an average WordPress user to completely ruin it without even knowing it. Then again, Weaver is a pretty popular theme on WordPress.org and if I had to guess why — it’s the amount of freedom it gives its users via theme options.

But that freedom comes with a price. And I’m not talking about the theme’s pro version, no. I’m talking about the risk users take unknowingly. The risk that could result in poor usability, ugliness and insanely high bounce rates, even if the site looks “just perfect” to the owner.

So how can we protect our users from poor decisions, while still giving them their beloved color options? Providing a predefined set of color schemes is one way of doing it, but this post is about something different.

Contrast Correction with Sass or LESS

You’re probably already familiar with CSS preprocessors, so here’s an interesting piece on accessibility and contrast with Sass and LESS. You can use brightness() or lightness() to help you choose better contrasting colors. You can use darken() and lighten() to alter your colors for better contrast. You can take it a step further and calculate the color luminance and contrast ratios.

But building your WordPress theme stylesheet with Sass or LESS is one thing. Providing users with an option that could somehow magically change and recompile your CSS is another. One way is to bundle a Sass or LESS PHP-based compiler inside your theme, though I’m not sure if the folks over at the Theme Review Team would be very happy about that.

A better way would be to offload CSS compilation into a plugin, ideally one that’s already active on millions of websites, like Jetpack :)

Jetpack Custom CSS

One of the lesser known features in Jetpack’s Custom CSS module is the availability of both LESS and Sass preprocessors, which means that Jetpack already bundles the necessary PHP libraries, and exposes them via functions, such as jetpack_sass_css_preprocess():

$accent_color = get_theme_mod( 'accent_color', '#00ff00' );
$sass = sprintf( '$accent-color: %s;', $accent_color );
$sass .= get_the_rest_of_the_sass_code();
$css = jetpack_sass_css_preprocess( $sass ); // boom!

So in the rest of the Sass code you can use the $accent-color variable which is defined by the user:

.element {
    background: $accent-color;
    color: if( lightness( $accent-color ) > 50, 'black', 'white' );
    &:hover {
        background: darken( $accent-color, 5% );
    }
}

Where you get the rest of the Sass code is entirely up to you. You can store it as a string in a PHP file, you can query the file system for the actual Sass file (note that Theme Check won’t let you use file_get_contents()) or you can even wp_remote_get() it, perhaps as a fallback if nothing else works.

Sass and LESS compilation can take a while, especially when you start using math functions like pow() or nthroot() (you’ll need these for luminance), so make sure you’re not compiling your stylesheets on the fly on every single request.

Instead, you can grab a hash of the color choices, and perhaps the stylesheet version, and cache the compiled CSS forever in a theme mod, and if the colors are changed, you’ll simply overwrite the cached entry.

Example

Semicolon is a magazine theme I released earlier this year. It was built with Sass already, so I simply extracted all the color definitions from the main stylesheet into a new colors.scss file, and then used some basic regex to inject user color values and recompile the stylesheet with Jetpack.

I also added automatic contrast correction which is on by default. So if the user picks bad contrasting colors, Semicolon will lighten or darken them until a contrast ratio threshold is reached. This guarantees a certain level of readability, even if it means drastically changing the user colors, like yellow to almost brown.

So this:

semicolon-color-options

Becomes this:

semicolon-contrasted

Obviously this is purely experimental for now, and there are probably some edge cases where users would want to turn Auto Contrast off. For example, in Semicolon you can’t set that sidebar widget fill color to the same color you’ve chosen for your page background. In fact, here’s what happens when you set all three values to white:

semicolon-white

Which I don’t think is bad, but it will certainly surprise many users. I guess a little tooltip message about why they’re not seeing the colors they’ve picked could help them understand what we did there.

You can grab the theme from WordPress.org or browse the theme code on GitHub. The Sass magic lives inside css/colors.scss and the compilation and caching code is in functions.php (custom_colors() method).

It’s not meant to be perfect, but I think it’s a good start. Give it a spin and let me know what you think. You’ll need Jetpack’s Custom CSS module active. If you’re working locally, you’ll want Jetpack’s development mode.

I appreciate your thoughts and comments!

1. There’s a neat plugin for the default Twenty Fourteen theme called Fourteen Colors, which also adjusts contrasts using PHP.

An Alternative to @import in WordPress Child Themes

Using Child Themes in WordPress is a great way to modify an existing theme, however the CSS @import directive is slower than it has to be, so you should try and avoid it. Here’s why.

If it takes 200ms to load the child theme’s stylesheet, and 200ms to load the parent theme’s CSS, a modern web browser should take approximately 200ms to load both of them, because modern browsers load assets in parallel.

Unfortunately this is not true for CSS @import. Let me quote Google:

The browser must download, parse, and execute first.css before it is able to discover that it needs to download second.css.

Which means that instead of 200ms, with @import it’ll take the web browser approximately 400ms to load both stylesheets. Here’s a typical child theme’s CSS:

/**
 * Theme Name: My Child Theme
 * Template: parent-theme
 */
@import url(../parent-theme/style.css);

/* My Child Theme CSS */

We can drop the @import statement, and make good use of functions.php and the wp_enqueue_style() function:

// Faster than @import
add_action( 'wp_enqueue_scripts', 'my_child_theme_scripts' );
function my_child_theme_scripts() {
    wp_enqueue_style( 'parent-theme-css', get_template_directory_uri() . '/style.css' );
}

And we don’t need to re-declare dependencies because the child theme’s functions.php is loaded before the parent theme’s. Unless, of course, the parent theme uses a different action priority, in which case we should just match it.

That’s +1 to our PageSpeed score :)

MegaFon Moscow: Privacy & Advertising

Funny thing happened today. My car insurance expired, so I called my insurance company (RESO) from my cellphone. Nobody answered my call, it was Friday evening after all, so I hung up and decided to call them on Monday.

A few hours later, I received a text-message:

megafon-moscow-advertising

For those of you who can’t read Russian, it’s an advert from INHELP, a different insurance company offering its services. The message came from PROMO — the official MegaFon advertising channel.

At first I thought it was a coincidence, so I asked my wife to dial the same number and moments later she gets the exact same text advert!

I wouldn’t consider this a big deal if I had registered on some website online and given them my phone number. I would actually expect them to sell the number to third-party advertisers, but this is different.

Here’s what I think: MegaFon Moscow, one of the three largest network operators in Russia, is not only selling my phone number to advertisers, but also the fact that a phone call was made to a certain number. At this point I wouldn’t be surprised if a recording of the phone call was also handed over.

Talk about privacy.

WordCamp Russia 2014

The second WordCamp in Russia was a success, with almost 200 attendees and a great lineup of 14 speakers from all over Russia and abroad, including Ukraine and even Germany.

WordCamp Russia 2014

I’m not going to go into much planning details like I did last year. Everything was mostly the same, with the exception of having almost twice as many speakers, two tracks, pizza for lunch, a new logo (which everybody thought was a splash), as well as little irritating things that made planning more stressful — like the absence of parking spots close to the venue, problems with shipping anything from the US to Russia, and the fact that we bought about 10x more coffee than we ended up serving.

In any case, the post-WordCamp survey showed a 96% satisfaction rate, which definitely works for me. Now back to reading those new 4.0 commits, and still struggling for inbox zero, even though it’s been over a week now.

Photos from WordCamp Russia 2014 are on Facebook. Slides from my talk about scaling WordPress can be found here, the videos from all the sessions should appear on WordPress.tv in a few weeks.