Article

Using Tonesque & Sass to generate color schemes

Last month, I posted about Umbra being released on WordPress.org. I’m excited about the release of this one, since I think what we did with colors is really cool.

Click through to see the demo, and be sure to click around on some posts to see the different colors.

The theme defaults to a purple, grey, and gold color scheme, but you can customize this in the customizer. By default, on single pages, it’ll also grab the color from the featured image (or first image in the post).

How did we do it? It’s easier than you might think. By pulling in some libraries from Jetpack, most of the hard work is already done. If you use the theme without Jetpack, you’ll just have the purple/gold theme in the screenshot.

Get a base color from Tonesque

Tonesque isn’t really documented in any user-accessible way, so your best bet is to go right to the source. If you check out theme-tools.php, you’ll see that to load Tonesque, Jetpack looks for theme support. This is a pretty cool feature of core, that you can add support for arbitrary theme features.

So if we want to use tonesque, all we need to do is confirm we support it.

// Support tonesque from Jetpack
add_theme_support( 'tonesque' );

Now we can use Tonesque’s methods. We’ll first create a new Tonesque object, which takes an image URL (you can check out Umbra’s source for how I get the image URL). Once we have that, we can get the sampled color from the image. (If you want to rabbit-hole like I did, you can investigate grab_color & grab_points, to see how the color is picked from the image)

$image = new Tonesque( $image_src );
$color = $image->color();

Create the scheme with Sass

A single color doesn’t really make for an entire color scheme. Luckily Jetpack has more awesome to help us out. To support using CSS preprocessors in the custom css module, it includes libraries for parsing Sass & LESS into plain CSS. Again, check out the source for all the details.

To start, I pulled all my color definitions into a single Sass (.scss) file, along with rules to generate a lot of other colors from a single “base color”. The file I ended up with is a bit of a mess - so if you’re planning on doing this, think about your colors from the start.

Note
Since we’re uploading this to WordPress.org, we can’t use the PHP filesystem methods to read from a sass file. That’s why base-scss.php is a PHP file.

After walking through how Jetpack saves and renders CSS (see get_css), I figured out that I can use the minify method, which will also conveniently minify the generated CSS. Now we can combine the global variable from our Sass PHP file with the real base color. The $sass variable now contains a valid string of Sass, and can be processed to give us our CSS. From here, we’ll inject this CSS into the header on the wp_head hook.

$sass = '$base-color: #' . $color . '; ' . $umbra_base_scss;
$css = Jetpack_Custom_CSS::minify( $sass, 'sass' );

The last step is to wrap all this in caching. We don’t want to run all this processing on every page load every time, it should only run once per color. You can check out how I handled this in generate_css.


Thanks for reading! I hope I gave you some fun ideas for how to work with dynamic colors in your themes. Feel free to ask any questions in the comments :)

Other people doing similar cool things:

  • Color Posts plugin– Jeremy also has a writeup on customizing the plugin’s CSS for your theme.
  • Ryu theme– colors image posts based on the first image.
Article

CSS rotation in IE

Gravity Switch, the company I work for, launched their new website today. I was really pushing as much HTML5/CSS3 as possible in the new site[1]. I even used CSS3 rotation, but as it turned out, IE8 is our biggest browser, and my boss needed these images rotated there. I knew that IE had basic rotation, which does 90°, 180°, & 270° - but I needed 2° & 3°.

Enter the Matrix Filter!

Documentation here, with an example of 60° rotation here. Says it works from IE5.5+, & IE9 supports the CSS3 -ms-transform property. IE10 should just use transform. [source] Read more

Article

Using Chosen + Custom Meta Boxes

Lately I’ve been using Custom Meta Boxes for use with custom post types. CMB makes programmatically adding specific custom fields to your posts very simple - as simple as filling out an array. The following example adds a WYSIWYG ‘sidebar’ field to posts, pages, and events (a custom post type):

You do need to include the CMB code, though -but that’s also easy. Just change the path to the correct location.

These snippets above came from a theme’s functions.php, though CMB can also be used in plugins (as my next example). Perhaps the above would be better if it were moved into a must-use plugin - maybe that’ll be my next improvement. In any case, as awesome as the above is, it gets better: see how in the sidebar field I say 'type' => 'wysiwyg'? There are plenty of field types to choose from, but you can also very easily create your own.

Getting to the point: creating a taxonomy field using Chosen

Read more

Article

Switching from apache to nginx

A note from Jan 2014: This post was written in Sept 2011, and is not kept up-to-date. I’m sure the content is still fine anecdotally, but I’d double check any config settings or files listed here to see if they’re still relevant to current versions.


A few weekends ago, with threat of a hurricane looming, I did the most logical thing: brought all my sites down as I fumbled through switching around my directory structure and installing nginx.

Some background: This site (and presentation.js, valley summit, and others) are all hosted on one 256MB slice at Slicehost running Ubuntu 10.04. I followed the assorted articles to get myself started, but mostly just left default configuration in place, including the directory structure they use (which I grew to dislike). That also meant I installed apache. This was by choice, I wanted something fast & easy to set up, and that I was already vaguely familiar with. So, there we go - I had a server! I shared my success, went to bed, and the next day it had almost completely seized up.

apache vs nginx

I never did grab exactly how much memory the average apache process took, but this article asserts that it’s about 25-50MB in size. The reason for this is that each process is bundled with PHP, so it doesn’t need to talk to anything external to process your PHP pages. This would be great if all the files you’re serving are PHP, but for most sites, the majority of content delivered is images, stylesheets, javascript files, and for each of these, the apache process still has PHP embedded.

Nginx, by contrast, doesn’t include PHP - in fact, to get PHP working, you need to use an external process (FastCGI) to handle the communication between nginx and PHP.

Why? Apache is a memory hog. This is well known, and discussed in an article I failed to read (configuring the apache MPM). The issue was that I was allowing more processes to be created than I had available memory for. After a lot of tweaking I ended up with (in my opinion) ridiculously low numbers. I was only allowing, I think, 5 simultaneous connections? That is, across three+ sites, two of which are fairly well-trafficked. So, needless to say (if you were here before, you know) my server was pretty freaking slow.

What now? At this point I had a decision to make - upgrade to more memory, so apache wouldn’t choke my system, move hosts & start over (this was made more appealing by the fact that I’d misunderstood what Slicehost’s move to Rackspace meant), or keep banging on it till it worked. Obviously the last option wasn’t working so well, and I really couldn’t justify spending more money on my site right now, so I opted for (b), minus the host-move. I spent a little while researching server software, and decided on nginx (my other option was lighttpd, and I don’t really have a clear reason why one won over the other).

And now, the work starts.

Installing nginx was actually really simple. I stopped apache, then (remember, I’m on Ubuntu 10.04):

apt-get install nginx

and I was in business… kind of. Since I was running multiple sites, I had virtual hosts set up. The next thing I needed to do was configure that. (In reality, the next thing I did was move a half-dozen directories, create new users & groups, and set up some ACLs that are still not what I want — but for the sake of this post, I’m going to go straight to the logical next step, not the step that keeps everything not-working for 24hrs).

Re-creating your virtual hosts

In apache, you have a sites-enabled folder with files that probably look like this:

<VirtualHost *:80>
  # Admin email, Server Name (domain name) and any aliases
  ServerAdmin you@site.net
  ServerName  www.site.net
  ServerAlias site.net
  # Index file and Document Root (where the public files are located)
  DirectoryIndex index.php index.html
  DocumentRoot /path/to/site/files
</VirtualHost>

What this is doing is saying when someone accesses site.net (or www.site.net), it will display the files in /path/to/site/files. The equivalent for nginx would be:

server {
  listen          80;
  server_name     site.net *.site.net;
  index           index.html;
  root            /path/to/site/files;
  location / {
    try_files       $uri $uri/;
  }
}

The server { ... } block is basically the equivalent of the <VirtualHost *:80> </VirtualHost> block. You tell nginx to watch for site.net (or any subdomain of site.net) and when it’s found, to serve up the file found in /path/to/site/files. The try_files line is pretty neat - if nginx can’t find the initially requested file, it then tries the next file - so in this case if you type a directory but forget the ending slash, it will still find it.

The location of these configuration files is different per-system, in my case they are in /etc/nginx. nginx.conf is where the main configurations are stored, I ended up leaving these as is. The last line is important, though:

    include /etc/nginx/conf.d/*;

This includes all files in the conf.d directory, so you can use it like sites-enabled in apache. I created new files for each site, and will go over them more in detail after the next step.

But I need PHP. So there’s still another step to come. In my aside on Apache vs Nginx, I mentioned that nginx doesn’t come embedded with PHP like Apache — so we need to install FastCGI. I followed the relevant bits of this post, which lead me through installing FastCGI & creating a startup script, which creates a few FastCGI processes. Since that post doesn’t exist anymore, you should be able to follow this & grab the content for php-fastcgi from this gist.

apt-get install php5-cgi
nano /etc/init.d/php-fastcgi
    (grab the content for this file from the other post)
chmod +x /etc/init.d/php-fastcgi

I did change a few things from their script, as I was having some issues and had read that it could be solved using a UNIX socket rather than a TCP connection, so the top 5 lines of my script look like:

#!/bin/bash
BIND=/tmp/php.socket
USER=www-data
PHP_FCGI_CHILDREN=5
PHP_FCGI_MAX_REQUESTS=50

I also changed the children & requests, because I want to reduce as much memory use as possible. And I’ve been running this for about 3 weeks with no issues.

So, once you’ve grabbed that script, you need to run it to start the processes.

/etc/init.d/php-fastcgi start

To make this script run on startup, use the following command.

update-rc.d php-fastcgi defaults

Now I’ve got PHP, and I’ve got nginx, but they’re not working together. So I’ve got to go back to the nginx configuration, and tell it to send anything php to FastCGI. I went through each file in /etc/nginx/conf.d/, and replaced all my previous configurations with includes to restrictions.conf and wordpress.conf, grabbed from this codex post. Now the file for redradar looks like:

server {
    server_name redradar.net me.redradar.net;
    root /path/to/files;
    include /etc/nginx/global/restrictions.conf;
    include /etc/nginx/global/wordpress.conf;
}

Finally, in wordpress.conf, is the directive to send php to FastCGI. I used the example script almost exactly, only removing some of the extra comments & caching rules (as I don’t currently have caching enabled - that’s a project for another weekend).

And I’m done. I’d be lying, though, if I didn’t mention that all this took place over a few days, with my sites all being intermittently down while I ran through tutorial after tutorial, googleing the various errors I was getting when images failed to load, php wouldn’t work… Apparently the WordPress Codex was the place to look all along, but I didn’t understand where everything went until I’d been mucking around for a while.

I hope this helps anyone else who decides to make this switch - it’s really not that hard, if you actually do your research first.

7/1/12 I’ve since upgraded to a 512MB slice, and turned on caching with APC & Batcache, which was stupidly simple (since APC was already installed).