Pretty Code Editor in WordPress

I’m one of those people that has the visual editor disabled in WordPress. I write everything in Markdown and I want the editor to make very few decisions about what HTML to generate. The downside of this is that the code editor is set in Consolas — not exactly great for writing long posts. To fix that, I made a new file in mu-plugins called pretty-code-editor.php. It’s just two CSS rules, but now writing in the code editor is much easier.

\#wp_mce_fullscreen, .wp-editor-area {
font-family: "Baskerville", Georgia, Serif !important;
font-size: 16px;

<?php }

Follow along with the Gist on Github because I’ve got some ideas that would make this even better.

WordPress Powers Politics

The VIP team compiled WordPress usage data around the current election season. It’s good to see how many politicians are using free, open-source software. Check out the awesome infographic!

WordPress and LEMP

In the past I’ve written about running WordPress more efficiently [on Apache]( Part of that was using Nginx to serve static files and only relying on Apache to interact with PHP. But we don’t need Apache for that. We can achieve a similar result with PHP-FPM and never have to install Apache.

Recently I rebuilt my server on a the [Rackspace Cloud]( Here I’ll detail the steps involved in setting up the server from the start.

Note: I’m using Ubuntu 12.04.

#1. Initial Setup
When your server first starts up, the only user you can access is root. Rackspace will send you an email with the root password. The first thing you need to do is change that. This should be something that you have to open 1Password for every time, and definitely not “123456”.


Then I like to add a non-root user for myself. You can add this user to the admin group, which automatically gives you sudoers access, but I’d recommend against it.[^sudosecurity] Anything that needs root privilege can be done with the root user. In fact, you probably want to stay logged in as root while we finish installing the services.

useradd -d /home/myuser -m myuser
passwd myuser

If you want to add your user to the admin group.

groupadd admin
usermod myuser -G admin

Next, you probably want to install any updates that are available.

apt-get update && apt-get upgrade

As a final step in the setup, I like to grab [my dotfiles]( from Github so my shell is useable.

#2. Uncomplicated Firewall
Also in the name of security, a software firewall. Realistically, you probably only need to allow the outside world to talk to your server on port 22 (for ssh), port 80 (for http), and *maybe* port 443 (for ssl).

ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow www
ufw allow 443
ufw enable

#3. Nginx, PHP-FPM, and MySQL
Let’s install a web server on this web server. I found [a great article]( that walks through setting up Nginx on Ubuntu 12.04. Honestly, after you do it a couple times, this becomes really easy. Nginx config files are generally pretty easy to read.

apt-get install mysql-server mysql-client
apt-get install nginx
service nginx start
apt-get install php5-fpm

I’m going to set up a default virtual host as a wild card to grab any request that isn’t to my domain and redirect it.

vim /etc/nginx/sites-available/default

server {
server_name _;
rewrite ^ $scheme://$request_uri redirect;

location = /50x.html {
root /usr/share/nginx/www;

Then we can set up the virtual host for our specific domain. The article I linked to does this a little differently. I’m going to do some WordPress specific things right away, but you could set it up generically and then come back to this if you wanted to. The idea here is to put the rules specific to this site in a this virtual host and then have some generic files we include incase we want to set up another WordPress site on this server. Honestly, you could simplify this into one file if you’re only ever going to set up one site.

First open `/etc/nginx/sites-available/` with vim and paste the following, editing the relevent bits.

server {
listen 80; ## listen for ipv4; this line is default and implied
listen [::]:80 default ipv6only=on; ## listen for ipv6

root /var/www/;
index index.php index.html index.htm;

# Make site accessible from

include global/restrictions.conf;

# More rules here

include global/wordpress.conf;

Next up is `/etc/nginx/global/restrictions.conf`.

# Global restrictions configuration file.
# Designed to be included in any server {} block.</p>
location = /favicon.ico {
log_not_found off;
access_log off;

location = /robots.txt {
allow all;
log_not_found off;
access_log off;

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /. {
deny all;

# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*.php$ {
deny all;

And finally, `/etc/nginx/global/wordpress.conf`.

# WordPress single blog rules
# Designed to be included in any server {} block.

# This order might seem weird – this is attempted to match last if rules below fail.
location / {
try_files $uri $uri/ /index.php?$args;

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# Directives to send expires headers and turn off 404 error logging.
location ~* .(?:js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;

# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ .php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;

Now we need to configure PHP-FPM to be compatible with the Nginx configuration. Comment out the `listen` directive and add a new one like the one below or just replace the localhost address with `/tmp/php5-fpm.sock`. Open `/etc/php5/fpm/pool.d/www.conf` and looks for something like like `listen =` and replace it with the following.

;listen =
listen = /tmp/php5-fpm.sock

Then restart PHP-FPM with `service php5-fpm reload`. Time to run the WordPress install!

#4. Postfix
WordPress needs to be able to send email for certain things. We’ll use Postfix for this.

apt-get install postfix

I was having a problem because the hostname of my server is, but this isn’t actually a mail server. In `/etc/postfix/`, there’s a line: `mydestination`. It was automatically set to “,, localhost” causing postfix to intercept messages to before they ever left the server. I just removed “” from that list and restarted postfix to fix the problem.

#5. Alternative PHP Cache
APC is a PHP opcode cache — it makes PHP faster. But it also has a key-value store that can be used for the [WordPress Object Cache]( Mark Jaquith has [a nice plugin]( for this.

apt-get install php-apc

#6. iStat
You might know iStat for the Mac dashboard widget or the [iPhone app]( There’s also a version of [iStat server for Linux]( The setup is a bit outside the scope of this article, but there are pretty good instructions in the readme on Github. Once it’s setup, you can access information about your server like CPU load, free memory, and disk utilization all from you iPhone.

#7. cdn
So, I have a love/hate relationship with Rackspace’s Cloud Files. This is the only part that I haven’t actually finished yet because I can’t decide if I want to use Cloud Files or Amazon’s CloudFront — or just skip the CDN aspect all together for now.

Origin pull would be really nice — if a file doesn’t exist on one of the edges, it just gets pulled from your server. Both Rackspace and Amazon claim to have origin pull. Amazon’s origin pull works exactly the way it’s supposed to. You have to think a little differently to understand Rackspace’s approach though.

First, you have to consider Cloud Files not as a CDN[^notacdn], but just a place to store your files — a file server if you like. You can then tell Cloud Files to turn on the CDN, which hooks it into Akamai’s CDN. From the store on Cloud Files, there is indeed origin pull, but Cloud Files has no way of asking your Cloud Server for a file if it doesn’t exist.

I used this as an opportunity to rebuild my virtual environment as well. I’ve written a couple of posts about virtualizing your local development environment in the past. Turns out, VirtualBox does some weird stuff to shared files sometimes.

The new server was killing some of my javascript and adding null bytes to the end. I found [an article on serverfault]( that addressed this issue. If you turn sendfile off in nginx, it fixes the problem. Apparently it can happen with Apache too, but this is the first time I’ve seen it.

#Further Reading
* [Set up VirtualBox for Web Development]( – An article I wrote about virtualizing your development environment in VirtualBox.
* [Virtualized Development, Part 2]( – A follow up article I wrote about sharing files between a VirtualBox host and client. With a similar setup, I can edit all my files in OSX, but use Ubuntu to serve them on a local domain.
* []( – The codex entry on has some good stuff.

[^sudosecurity]: My recommendations about security and what you actually do in practice might not be the same. Be aware of the risks though — especially if your account has a password that might be easily cracked.

[^notacdn]: Because Cloud Files isn’t a CDN. It’s a file server that happens to have the ability to hook into Akamai’s CDN if you want it to.

HTML Examples Plugin Demo

I worked on a plugin this weekend for storing HTML demos in WordPress. This is still a work in progress, but I think it’s pretty cool so I wanted to post a video showing what I’ve got so far.

When you write a new demo, you get fields for HTML, CSS, and Javascript. There’s also an option to select from a few libraries that are already including in WordPress to load on the page. On the post page, the HTML, CSS, and Javascript are inserted where the_content() is called.

The syntax highlighter used here is CodeMirror. You can find the code for HTML Examples on Github.

Tweet Posts

I deleted all my old Twitter archives the other day, which meant I was hardly using any of Twitter Tools1. Then, I launched the new version of and I can do all kinds of fun stuff with post formats, but Twitter Tools still says “New blog post:” when I publish anything. So I threw together something that does exactly what I want and nothing that I don’t.

It’s not super customizable. There’s some logic to tweet a bit differently depending on what the post format is, but it’s all hard-coded. For a new quote, for example, it will say something like “New quote:”.

One goal I have is to rewrite the Twitter OAuth API helper to use more of the WordPress HTTP functions instead of relying on cURL directly. I’m always happy to accept pull requests on GitHub. The plugin is also available in the repository.

  1. I would normally link to the plugin, but I see that it hasn’t been updated in over two years and you get a nice big yellow warning when you visit the page. 


Version 11.1

I realize that I was just writing about v10 four-and-a-half months ago. I liked it, but I haven’t done a ton of front-end work lately and I was itching to work on something. I started working on this probably six or seven weeks ago. It made its first public appearance on Dribble on July 14th. There’s a ton going on here, so I’m going to try and break it down a bit here.


When I finally had something I wanted to build, I started with the main navigation. My first thought was to do it in CSS. The only sticking point is the darker yellow shadow on the bottom. It’s not even that hard to do, just a bunch of dropshadows. The way I did it looks pretty horrible in Safari, though, and not much better in Chrome. I’m going to look into this again when I get a minute because it would be awsome for customization. I’d love to be able to put an option in the customizer that lets you pick the nav color.


So, I used Compass for this. Compass is the best reason for using SASS right now, in my opinion. Instead of maintaining your own list of mixins, which is likely to become out of date quickly, you can use Compass. It’s open source and used by tons of people.

And with SASS 3.2, there are some really cool things you can do with @media queries. For me, the following mixins made this theme easier to code and should make it much easier to maintain.

@mixin breakpoint($point) {
    @if $point == mid {
        @media (min-width: 800px) { @content; }
    @else if $point == large {
        @media (min-width: 1170px) { @content; }

@mixin retina() {
    only screen and (-webkit-min-device-pixel-ratio: 2),
    only screen and (   min--moz-device-pixel-ratio: 2),
    only screen and (     -o-min-device-pixel-ratio: 2/1),
    only screen and (        min-device-pixel-ratio: 2),
    only screen and (                min-resolution: 192dpi),
    only screen and (                min-resolution: 2dppx) { @content; }

Post Formats

This theme supports Standard, Link, Image, Video, Audio, Quote, and Status formats. Links still link to some external site or article. Image, Video, and Audio posts display extra content above the post title. Quote and Status posts are pretty straight forward, but it’s worth noting that they don’t have titles.

I’m still managing these with the Crowd Favorite Post Formats plugin.


There are a couple of built in widgets. The biography widget, currently at the top of the sidebar, is available. It asks for an email address and will automatically pull your gravatar and profile information. The social icons are another widget that are part of this theme. Currently there are icons for Twitter, Dribbble, Forrst, Github, Google+, Facebook, LinkedIn, LastFM, Skype, Flickr, Vimeo, and WordPress. Theme Directory

I’m going to submit this to the Theme Directory. The only thing I haven’t quite figured out yet is how to handle the navigation on mobile. The problem is that you can’t reliably set more than one level of sub-menus right now. Since they expand out to the right, eventually stuff is being drawn outside the page. I have some ideas for this, so hopefully I can get that figured out in the next week and get this thing up for review.

Since there’s no good way of distributing themes with specific TypeKit typefaces, I added some Google Fonts fallbacks that can be enabled in the customizer.

Theme Customizer

There are a few things you can specify in the customizer. The copyright notice starts you with a format of “© {yyyy}”. I replace the “{yyyy}” pattern with the current year. Hopefully it’s not super confusing, but I’m not replacing any other pattern so “{yy}” isn’t going to get you the last two digits of the current year or anything.

Google Fonts can be enabled, as I mentioned previously.

The background image or color can also be specified. The default is what I have set here, but you can upload your own image or pick your own color too.


  • I stole the awesome ❮ and ❯ arrows from Chexee.
  • The Wisconsin glyph in the footer is from StateFace.
  • Retina, baby. The entire thing has been written to take advantage of a retina screen. And it’s nice.
  • There’s a bunch of stuff from _s in here. Take a look. That’s the place to start.
  • The current breakpoints are at 650px, 800px and 1170px.

  1. Honestly, I don’t even remember how I came up with this number. It seems unreasonable. But I’m pretty sure I counted at some point. 

P2 Hovercards

A couple weeks ago I worked on a project that we called P2 Hovercards. We released the code on Github last week for anyone else that might find them useful. The idea is that you can see additional information about certain links without clicking on them, therefore keeping you on the P2 and not diverting your attention unnecessarily.