TUTORIAL: Using WordPress’ Ajax API

WordPress has tons of APIs to do tons of things. It really does. One of the cool ones that I’ve been using a lot lately, has been around for a bit. It’s the Ajax API. Sure, you could write your own Ajaxy thing but why do that when WordPress lets you do it all very simply.

This tutorial will show you how to replicate the functionality that is presented in the “Like” button at Facebook. It assumes that you have WordPress set to require users to be logged in to take such actions. It wouldn’t make much sense for someone to not be logged in for such functionality. Obviously, you could do something else with Ajax (polls? Loading new content?) that doesn’t have the same assumption, but in this case… we’re assuming a user is logged in and the $current_user global is set.

Getting Started

Let’s start with the basic PHP class (you do write good object-oriented code, right?)

1
2
3
4
5
6
7
8
class My_Like_Button {

    function __construct()
    {
    }
}

$my_like_button = new My_Like_Button;

This code is just a basic skeleton that provides a constructor (the __construct() method, which I’ll use later. It also instantiates a new My_Like_Button object and assigns it to the $my_like_button variable for use in the global scope. Obviously, you can use whatever strikes your fancy for the class name or the global variable.

Building the HTML for the Like Button

Next, we need the basic HTML structure that will be used in our theme for the Like button. For the sake of simplicity, I’m not providing any CSS, but feel free to do as you wish. We need to add this as a new method in our class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function like_button()
{
    if( !is_user_logged_in() )
        return false;
       
    global $current_user;
       
    $html = '<form action="" method="post">
        <input type="hidden" name="like_post_id" id="like_post_id" value="'
. get_the_ID() .'">
        <input type="hidden" name="like_user_id" id="like_user_id" value="'
. $current_user->ID . '">
        <input type="button" name="like_this_post" id="like_this_post" value="Like" />
    </form>'
;
    return $html;
}

This form provides two hidden form fields using get_the_ID() and the $current_user object. Having done this (and after ensuring there is a logged in user), we can now drop this into our theme in the Loop as a template tag:

1
<?php echo $my_like_button->like_button(); ?>

Sending the Ajax Request with jQuery

This is useless by itself. We need something to handle the Ajax. But before we get there, we need to understand how Ajax works within the WordPress context.

All requests must go to wp-admin/admin-ajax.php. Forget the confusion about why you would send a front-end Ajax request to the back-end. You just do.

On the back-end, you’ll have to define functions that will hook into the Ajax API to let WordPress know how to handle the request. More on that in a minute. Let’s build some jQuery to send this to admin-ajax.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function js()
{
    wp_enqueue_script( 'jquery' );
    wp_print_scripts();
    ?>
    <script>
    jQuery(document).ready(function(){
           
        jQuery('#like_this_post').click(function(){
            var like_post_id = jQuery('#like_post_id').val();
            var like_user_id = jQuery('#like_user_id').val();
           
            jQuery.post(
                '<?php echo get_option('siteurl') . '/wp-admin/admin-ajax.php' ?>',
                {
                    action      : 'register_like',
                    user_id     : like_user_id,
                    post_id     : like_post_id,
                    _wpnonce    : '<?php echo wp_create_nonce('nonce-register_like'); ?>',
                },
                function(response) {   
                    alert(response);
                }
            );
               
        });
    });
    </script>
    <?php
}

This is just a PHP function that we can use to throw some jQuery (using the .post() method for our Ajax call) into the head. Note the nonce. You must include this for security. Additionally, you must have an action set. The action is used by WordPress to route the Ajax request.

Finally, we’re passing two extra pieces of data – user_id which is the WordPress user ID and the post_id which is the WordPress post ID of the current $post object inside the Loop. Both of these are supplied in the hidden form fields we created earlier.

Let’s add a new method for hooks and call it in our constructor, so that hooks are executed when the object is instantiated:

1
2
3
4
5
6
7
8
9
function __construct()
{
    $this->hooks();
}
   
function hooks()
{
    add_action( 'wp_head', array( $this, 'js' ) );
}

Supplying the Ajax Handler

Having hooked the jQuery into WordPress, we now need something on the other end to handle the request and return something back to our page. For this, let’s create a method called handle_like().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function handle_like()
{
    global $wpdb;
    $user_id = (int) $_POST['user_id'];
    $post_id = (int) $_POST['post_id'];
       
    if( !is_user_logged_in() )
        return false;
       
    if( !wp_verify_nonce( $_POST['_wpnonce'], 'nonce-register_like' ) )
        die( 'Go away, asshole!' );
       
    /*
        Here is where we do some sort of database operation to associate
        the Like of the given post with the user who performed the action
       
        Make sure you check for errors. In order to return data, you must
        echo something that the originating page can see. True or false
        only makes sense on this page and not back there.
           
        Typically, you'd output some sort of JSON, XML or plain text.
    */

    $meta_id = add_post_meta( $post_id, 'user_liked', $user_id );
    if( !$meta_id )
        echo "Like not recorded";
    else
        echo "Like recorded";
    exit;
}

In this method, it’s important that all data be sanitized to avoid security problems. I’m performing the most basic of data security here by casting the $_POST variables for the users ID and the post ID to integers.

We’re also checking to make sure the user is logged in. This is why using the built in WordPress Ajax API is actually kind of important. If you build your own Ajax handler, there’s no way to reliable tie in to WordPress to use other APIs like the User API.

Finally, make sure you verify the nonce so you know the request is coming from a legitimate source.

The three security procedures I just listed will largely prevent SQL Injection, ensure authenticated users and eliminate the possibility of Cross Site Request Forgery (CSRF) and generally should be used in all WordPress plugin development.

Simply though, the above method takes the post ID, the user ID and creates a new record in the postmeta table. On success, it will print a success method readable by the original sending page and vica versa on failure.

Note: You must use die() or exit() at the end of the method to make sure the Ajax response exits properly.

Tying the Handler into WordPress

Now that we have a handler method to do our bidding, we need to make sure WordPress knows about it so it routes Ajax requests to the proper place. To do this, we leverage the wp_ajax_{$action} hook.

Remember earlier, while building the jQuery Ajax request, I mentioned that an action POST variable had to be set? WordPress looks to this variable to create a dynamic hook that we can use our new Ajax callback to hook into.

1
add_action( 'wp_ajax_register_like', array( $this, 'handle_like' ) );

Because our action in the js() method was set to register_like, the hook WordPress creates dynamically is wp_ajax_register_like and we can use that to hook our Ajax handler onto.

Wrapping it all Together

Easy right? Use jQuery to send data, wp-admin/admin-ajax.php to receive the Ajax request and pass it on to an appropriate handler function, and send data back to the original page. On the receiving end, you can use normal means to handle the returned data as you wish.

You can download the full code used here at Github.

Skunkworks

Back in October, I announced my departure from WP Engine. At that time, though I didn’t talk about it on this blog, I decided to take some time off, more or less. Since 2006, I’ve been hard at work with very little time alotted to myself. I spent 2 years with b5media and jumped immediately into a failed role at Lijit (who has now been acquired by Federated Media – nice work, guys!). Upon my departure from Lijit, shortly after the market bottom in 2008, and needing money desperately, I went into full time WordPress consulting. I did that until I moved to Austin last year when I went in full time on WP Engine and stayed there for 15 months or so.

So basically, I haven’t had a lot of time to myself. So I took time. In the past few months, I’ve taken some large consulting contracts, but mostly, I’ve spent time travelling to Maryland, Seattle, Chicago – all for pleasure, nothing for work. I’ve spent time trying to weigh my priorities and wants. I’ve tossed around starting up a new company or doing something different.

At the end of the day, now that it’s 2012, I know what I want to do. It’s a bit unusual, but I think it’s important and can really revolutionize a boutique agency. I’m not comfortable doing social media work. I’m too honest and raw in my own online presence and many companies and clients may not be comfortable with my level of authenticity.

I also don’t want to do what is common among agencies – sweatshop site development. Hey, no offense. That’s what it is. Take on 30 new clients, promise them websites that are the brainchilds of the agency marketing “expertise” and ask the developers to crank them out with little to no strategic or creative input.

That might work for some developers, but I’m not a normal developer. I’m a highly established WordPress professional that has commanded 5 figure consulting deals, written a 700+ page book on the subject and have built some of the most complex WordPress solutions I’ve ever seen (Humble brag! Also proprietary, but can provide in person demos). I’m not a good fit for sweatshop site generation.

You know what agencies need that no one is doing because no one has taken the time to think outside the box? A skunkworks division. What agencies need to differentiate themselves from the thousands of other agencies they are competing with is a person or small group of people with autonomy and who are focused soley on creating disruptive technologies that no one else is doing. Try things. Fail at some, succeed at others. Test market demand. Offer exclusive access to stuff that no other agency has. Innovate, innovate, innovate.

That’s what I want to do. And someone sees the sense in that. And someone realizes that that is worth thinking outside the box for. Someone is willing to invest in that competitive advantage. Someone gets it. It’ll take money. It’ll take risk. It’ll take balls of steel. Or you can be normal. Who wants to be normal?

So as we enter 2012, I am open to conversations around this or other creative outlets you might want to explore if you want a competitive advantage. Email me at aaron@technosailor.com.

TUTORIAL: Adding an oEmbed Provider to WordPress

I don’t often write tutorials. I probably should. But normally it’s only when someone asks me something and I think, “Hey, self… you should write up how to do this”. As if a book wasn’t enough.

Last night I was at the Austin Web Holiday party, a gathering of some 15+ technical meetup groups cross-pollinating over beer and socializing. I was introduced to one guy (can’t remember his name!) who had built a video site and enabled it for oEmbed. He couldn’t understand why WordPress wouldn’t just automatically let users use his videos, like it does for YouTube, Vimeo, etc. The full list of default oEmbed providers are listed here.

WordPress doesn’t allow automatic use of oEmbed for security reasons. Otherwise, someone could build a video service stuffed with malicious code that could potentially access your database or create a man in the middle attack or worse. WordPress.com certainly doesn’t allow arbitrary oEmbed sites and the dot-org open source software doesn’t allow arbitrary stuff automatically. But it can be done, on the dot-org side, with a plugin. All it is a hook.

Here’s an example. If you want to register an oEmbed video site that is, say, at (randomly) http:/mysuperawesomevideosite.com and your videos are of the format http://mysuperawesomevideosite.com/video/*, it’s as simple as adding a function in your plugin (or more properly from a PHP perspective, a method in a class – but that’s a personal preference. The method/function should call the  wp_oembed_add_provider() function.

In it’s simplest form, all you have to do is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class My_Plugin {

  var $oembed_endpoint;
  var $oembed_format;

  function __construct()
  {
    $this->oembed_endpoint = 'http://mysuperawesomevideosite.com';
    $this->oembed_format = 'http://mysuperawesomevideosite.com/video/*';

    $this->new_oembed();
  }

  function __destruct() {}

  function new_oembed()
  {
    wp_oembed_add_provider( $this->oembed_format, $this->oembed_endpoint );
  }

}

Then, to make this code work, just instantiate the class somewhere.

1
$my_plugin = new My_Plugin;

Voila!

10 Things You Need to Know About WordPress 3.3

WordPress Downloaded over 12.5M timesWordPress 3.2 has been downloaded a killer 12M+ times. WordPress as a whole continues to grow and is touted to be in the approximate 14% of the web zone. That’s ridiculously huge and it astounds me how big the projects footprint has become in the 7 years I’ve been around the community. Well done to all involved!

With that said, WordPress 3.3 is just around the corner and, as usual, it’s chock full of goodies for everyone. I’d say that the notable changes for developers are the most significant. Improved metadata handling, improved SQL tools, improved cache API and deprecation of several venerable functions are all changes that developers should be aware of.

This article touches mostly on the user experience and features that are new in WordPress 3.3. Developers who want to dive in should reference this running list of “things” that were addressed in WP 3.3.

Admin Bar Overhaul

The Admin Bar that was introduced a few versions ago has become a main-stay of my WordPress experience. At first, I felt like it got in the way, but I soon got used to it. In WordPress 3.3, the Admin Bar gets tweaked and enhanced. For Multisite users, you now have access to the Network Admin from a new “My Sites” menu along with all sites that you have access to 1.

As usual, developers can modify the admin bar using the admin_bar_menu action, and hooking a callback that modifies the $wp_admin_bar global. This object is created by the WP_Admin_Bar class that provides an add_menu() and remove_menu() method for manipulation.

Sample Code:

1
2
3
4
5
6
7
8
9
10
11
12
function ab_add_faq_link()
{
  global $wp_admin_bar;
  $wp_admin_bar->add_menu( array(
    'id' => 'menu_faq',
    'title' => __('FAQs'),
    'href' => 'http://example.com/faqs',
    'meta' => array( 'class' => 'custom_adminbar_menu')
    )
  );
}
add_action( 'wp_admin_bar', 'ab_add_faq_link' );

HTML5 Admin/Responsive Layout

More Admin-side improvements, like a conversion to HTML5 are a little more understated and less pronounced – unless you’re trying to access it from your iPhone or mobile phone. The conversion to HTML5, while meeting the trends of the day, also have the practical effect of providing an adaptive design which conforms to the device or viewport you are using. There’s nothing too crazy here, but with the web world going in the direction of HTML5, this move lays groundwork for new HTML5 features in the future.

Drag and Drop Media Uploader

One of the biggest new features in WordPress 3.3 (and a long time in coming!) is a new and improved media uploader. This is a feature that is discussed every single release cycle but because there’s only so much room in a major release cycle for major features (and this is a huge rewrite), it has continued to get bumped to a future release – until now.

While the new uploader is not the holy grail and I feel like there’s still a lot of room for improvement, it takes a giant leap forward in making the web interface feel more natural and more like a native application.

What am I talking about? Well, three words: Drag and Drop. With the new media uploaded, it’s as simple as dragging files to the “drop zone” in the native way that your OS allows: On Mac, from the Finder or by dragging the title bar icon in the app you’re using (Photoshop? Preview? Skitch?) into drop zone. On Windows, by pulling your file from Explorer into the Drop Zone.

Plus, related to the last feature, this media uploader prefers HTML5. For the geeky, the failover for HTML5 uploading is first Silverlight, then Flash then the old fashioned “Choose File” HTML dialog.

HTML5 Media Uploader
HTML5 Media Uploader

Welcome Screen and Pointers

If you already are using WordPress, you won’t see the welcome screen unless you setup a new WordPress install 2. The Welcome panel gives an overview of WordPress to new users.

More importantly, there is a new jQuery plugin that adds “Pointers” to WordPress whenever a new core, user facing feature is added. In WordPress 3.3, you’ll see one immediately pertaining to the new Admin Bar. However, Plugin and Theme developers who want to highlight new features can also do so. If you know jQuery, the following code is a good head start in the right direction:

Sample Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function ab_pointers()
{
  if( !is_admin() )
    return false;

  // Get Proper CSS involved - probably already included, but we want to be safe.
  wp_enqueue_style( 'wp-pointer' );
  wp_print_styles();

  // Get Proper bundled jQuery plugin involved - probably already included, but just to be safe
  wp_enqueue_script( 'wp-pointer' );
  wp_print_scripts();

  // Define text for the Pointer. Make sure you escape stuff
  $widget_text = '<h3>' . esc_js( __( 'Important!') ) . '</h3>';
  $widget_text .= '<p>' . esc_js( __( "This is where you would put some text that'll help the user understand WTF is up with your new stuff. Use it wisely and make sure it's short (Users won't read it if it's too long and once they dismiss it, it won't be shown again)" ) ). '</p>';
  ?>
  <script type="text/javascript">
  jQuery(document).ready(function(){
    jQuery('#your_dom_element').pointer({
      content    : '<?php echo $widget_text ?>',
      position   : 'left',
      close  : function() {}
    }).pointer('open');
  });
  </script>
  <?php
}
add_action('admin_head','ab_pointers');

I imagine this will get easier to implement in the future.

Improvements to Distraction Free Writing

Distraction Free Writing, which made its debut in WordPress 3.2, offered bloggers vast improvements to how they wrote content by removing the silly things that, well, distract from the job of writing.

In WordPress 3.3, DFW now integrates the content width and other CSS stylings of post content into the editor. This is all based on the active theme CSS and it attempts to aid the blogger in formatting properly for the theme the content will be displayed in.

Admin Menu Flyouts

A minor enhancement, yet important from a UI perspective – especially for those of you who, like me, constantly have wp-admin menus expanded – are menu flyouts. Very simple little thing, but when a user mouses over a menu, the submenu items under it appear in a “flyout” to the right and disappear when the mouse is no longer over the top level menu. Of course, for touch devices and clicky people, the collapse/expand functionality still exists.

Tumblr Importer

Technically, importers are no longer bundled with WordPress core. They are plugins. However, the removed importers are still listed on the Tools > Import console and can be installed from within WordPress.

An importer that has been in demand for some time, due to the popularity of Tumblr but the more popular nature of WordPress, is a Tumblr importer. Now that is available – also as a one-click plugin – to assist Tumblrs in moving to WordPress.

Tumblr Importer
Tumblr Importer

Go forth and enjoy a better blogging experience. And hey, use Press This if you like the Tumble style.

Multisite – Internationalized Domain Name Support

For non-english Multisite installs, it is now possible to designate an international domain name 3 as the site install domain. In Multisite, this means that base installs of WordPress can use IDNs now, which will serve to increase the adoption of these domains in non-English speaking parts of the world.

ワードプレスのイェーイ.jp, FTW!

Multisite – Network Enabled Themes and Theme Updates

Since we’re on the topic of Multisite, WordPress 3.3 brings the Network Activate option that has been available for plugins to themes. The plugin flow and the theme flow is different in WordPress, so this option makes things significantly easier. The plugin workflow only allows Super Admins to install WordPress and gives the Super Admin the ability to turn off the plugin menu for Blog Admins, but if left turned on, any Admin can activate any available plugin for their particular blog. For plugins, Super Admins can designate a plugin as a global plugin by Network activating in the Network Admin.

For Themes, it was an arduous task of making themes available to sub-sites in the past. Now, after installing a theme from the Network Admin, all it takes is a single click on Network Activate to make that theme available to sites in the network.

Deprecating Feeds

Finally, for those of you who rely on your feeds and are stuck in the stone age still, WordPress no longer supports old RSS 0.92 feeds and RDF feeds. For what it’s worth though, the default RSS feed is the still supported RSS 2.0 feed (add /feed to the end of just about any URL in WordPress and that is your RSS 2.0 feed.

Still, I know some of you don’t like to change and may be using the old feeds. There are two things to note:

  1. These now-deprecated feeds will redirect to the proper feed, with 301,
  2. If you use FeedBurner, or similar feed repurposing and syndication service, please make sure you are using the RSS 2.0 feed, not the RSS 0.92 feed. Like I said, a 301 will occur but that is actually additional load on the web server because it generates additional HTTP requests

Wrap Up

Sadly, this was the first WordPress release in some time where I have not contributed any code. There are a lot of reasons for that, none of which are all that important. But the core development team has really done a great job with this release and they should be commended.

If you really like WordPress, thank the team with a donation to the WordPress Foundation. All of the work that has gone into this release has come on the backs of volunteers or dedicated, full time paid employees of other companies who have been “donated” to the project.

Notes:

  1. You will only see sites that you have a Core Role on (Administrator, Editor, Author, Contributor, Subscriber). Super Admins that are not assigned to a blog, even though they have access to it as a Super Admin, will not have that blog listed
  2. You can manually turn the Welcome panel on in the Dashboard Screen Option
  3. IDNs are domain names that contains non-ASCII characters such as are provided by languages like Arabic, Kanji or Hiragana or language styles like Cyrillic

TUTORIAL: Using Sass and Compass for managing CSS in WordPress

I don’t often write tutorials but since the rebuild of the WP Engine website some months ago, I have been turned on to the use of a brilliant combination of tools made for development in a Ruby on Rails environment. That doesn’t mean we can’t make it work for WordPress too.

The tools are Compass combined with Sass (which means Sytactically Awesome Stylesheets or some random crap like that).

Sass is cool because it lets you do a whole bunch of stuff with CSS that you couldn’t normally. It’s a kind of abstraction layer above CSS which means you can write normal CSS if you want, but then why wouldn’t you just write normal CSS instead of using Sass?

I’m getting slightly ahead of myself, but With Sass you can do awesome things like variable/placeholders which is awesome for things like defining core elements of a stylesheet such as a palette of colors.

1
2
3
4
$cloud-blue: #d9e7f3;
$light-blue: #f0f7fc;
$dark-blue: #036;
$green: #7ca60a;

Then using those variables, you can just use these placeholders in your SCSS (Sassy CSS) file:

1
2
a { color: $dark-blue; }
a:hover { color: $light-blue; }

You can also write Mixins. Mixins are essentially reusable blocks of CSS that look a lot like functions you would see in languages like JavaScript, PHP or Ruby:

1
2
3
4
5
6
7
8
$radius:5px;

@mixin border-radius($radius)
{
border-radius:$radius;
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
}

You can use that in your SCSS file as such:

1
form input { @include border-radius(5px); }

But again, I’m getting ahead of myself.

When I talked about using Sass and Compass on Twitter, other WordPress devs made comments that made me want to write this tutorial. One person said that they were tired of Rails developers having all the toys – and it’s true. There are so many awesome things out there for Rails developers that we as PHP and WordPress developers don’t benefit from. This tutorial is non-exhaustive. There are tons of things that you can do with this that I won’t cover. But this should get you going with Mac OS X Lion, developing WordPress locally on your own machine and uploading to a theme file called “test” on a remote server.

Prerequisites

First of all, you need to have a local version of WordPress running. There are a variety of ways to do this, but I use the approach of installing XAMPP. Here’s a tutorial on that. Follow the rabbit trail to configure Apache to look to your Sites directory, as I have, or make that translation in your head to what the default is. There’s plenty of instruction on how to do that on the internet.

For the specifics of this tutorial, it’s very important that you have the latest version of Ruby. The best way to do this is with a tool called rvm, or Ruby Version Manager. Install this with the following Terminal command:

1
bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

Once rvm is installed, use it to install 1.9.3-p0, the only current version compatible with OS X Lion, and refresh your Terminal profile settings. The last command sets 1.9.3-p0 (or whatever future version you choose to use) as your default.

1
2
3
4
rvm install 1.9.3-p0
rvm reload
source ~/.bash_profile
rvm --default use 1.9.3-p0

If you wish to verify that you’ve got the proper version of Ruby active, verify it with the ruby -v command.

My system reported:

1
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]

Now, there are some gems that need to be installed. For developers unfamiliar with Ruby – or Rails – gems, are essentially additional libraries that are installed into the Ruby framework, much like PHP PEAR or PECL modules.

The first is Builder, which is used for building XML structures. The second one is Compass which will give us the ability to leverage Sass for CSS authoring.

1
2
gem install builder
gem install compass

Creating a Sass Project

Once we have everything installed properly, we can start a new project. I keep this out of my web directory (i.e. WordPress structure). Personally, I’ve created a sass directory under my user profile (/Users/aaron/sass) and run my projects out of it with a separate directory for each project.

Now we have to create our compass project. We do that with compass create from our ~/sass directory and then moving into the newly created directory.

1
2
compass create test
cd test

Doing a directory listing should show something along these lines:

1
2
3
4
5
6
7
8
NCC-1701:test aaron$ ls -la
total 8
drwxr-xr-x 6 aaron staff 204 Nov 2 11:36 .
drwxr-xr-x 4 aaron staff 136 Nov 2 11:36 ..
drwxr-xr-x 5 aaron staff 170 Nov 2 11:36 .sass-cache
-rw-r--r-- 1 aaron staff 861 Nov 2 11:36 config.rb
drwxr-xr-x 5 aaron staff 170 Nov 2 11:36 sass
drwxr-xr-x 5 aaron staff 170 Nov 2 11:36 stylesheets

Good. Our project is created but we need to make some changes to make this work with WordPress. To do this, we need to edit the config.rb file which is the project configuration file. You can edit this file in Textmate, vi, or whatever you choose as your preferred text editor.

The default configuration is:

1
2
3
4
5
http_path = "/"
css_dir = "stylesheets"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "javascripts"

My config file looks like this:

1
2
3
4
5
6
7
8
http_path = "../../Sites"
css_dir = "../../Sites/wp-content/themes/test/css"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "js"
project_type = :stand_alone
output_style = :nested
line_comments = false

Important changes here:

  • The http_path is a relative path to my DOCROOT – for some reason, things got whacked when using an absolute path.
  • The css_dir is a relative path to the css directory in my WordPress theme directory. At this time, there is no configuration option to control the name of the CSS files being generated so we will have to use @import inside the required WordPress style.css template file to incorporate Compass generated CSS files.
  • You can change the images_dir and javascripts_dir as needed to reflect your taste. Personally, I prefer shorter names, so that is reflected in the config file.
  • The project_type flag is required because, if omitted, Compass assumes we are working in a Rails environment on a Rails project with Rails conventions… WordPress is none of that.
  • The output_style flag has been set to :nested but could be :expanded, :compact or :compressed depending on your tastes.
  • The line_comments flag has been set to false to remove debug information from the generated CSS

All configuration options can be referenced in the Compass docs.

Having modified the config file, we can take one of two approaches to generating the CSS in our WordPress theme. We can use the compass compile which will generate the files one time. Everytime modifications are made, however, this command would have to be re-run. I prefer, instead, to use compass watch which is a small process that remains running and watches your Sass project for changes and recompiles automatically when changes are made.

Simply run this command from inside the Sass project:

1
2
3
4
5
6
7
8
9
compass watch
>>> Change detected to: ie.scss
create ../../Sites/wp-content/themes/test/ie.css
create ../../Sites/wp-content/themes/test/print.css
create ../../Sites/wp-content/themes/test/screen.css
/Users/aaron/.rvm/gems/ruby-1.9.3-p0/gems/fssm-0.2.7/lib/fssm/support.rb:40: Use RbConfig instead of obsolete and deprecated Config.
FSSM -> An optimized backend is available for this platform!
FSSM -> gem install rb-fsevent
>>> Compass is polling for changes. Press Ctrl-C to Stop.

At this point, if you want to develop locally, all you have to do is have your WordPress style.css import these stylesheets.

1
2
3
4
5
6
7
8
9
10
11
/*
Theme Name: Test Theme
Author: Aaron Brazell
Author URI: http://emmense.com
Description: A test theme demonstrating Sass and Compass
Version: 1.0
*/


@import url('css/screen.css');
@import url('css/print.css');
@import url('css/ie.css');

Uploading to a Remote WordPress Install

Fortunately, with a little Ruby magic and some built in Compass hooks, we can also upload these newly created CSS files to our WordPress theme. In order to do this, you have to make sure the remote server has the theme directory created and if you are uploading to a subdirectory of that theme (e.g. theme_dir/css), that that directory is created as well.

In our case, the theme directory is test/ and I want to upload to a subdirectory test/css/.

Next we have to install two new gems – the Net::SSH and Net::SFTP gems. Installing these is as straightforward as the earlier gems:

1
2
gem install net-ssh
gem install net-sftp

Once this has done, include these in your config.rb file. I did this at the top which is best practice with Ruby.

1
2
require 'net/ssh'
require 'net/sftp'

Below all the previous configurations, add some configuration lines and replace values as needed for your own project:

1
2
3
4
5
6
7
8
# note that this is the directory that CSS files will be written. It can be the theme dir
# or a subdirectory (e.g. theme_dir/css). Whatever this path is MUST exist
remote_theme_dir_absolute = '/home/sites/emmense.com/httpdocs/wp-content/themes/test/css'

# SFTP Connection Details - Does not support alternate ports os SSHKeys, but could with mods
sftp_host = 'hostname.com' # Can be an IP
sftp_user = 'username' # SFTP Username
sftp_pass = 'password' # SFTP Password

Finally, we can leverage Compass’ built-in on_stylesheet_saved hook to upload to the remote server using your SFTP credentials:

1
2
3
4
5
6
7
8
9
# Callback to be used when a file change is written. This will upload to a remote WP install
on_stylesheet_saved do |filename|
  $local_path_to_css_file = css_dir + '/' + File.basename(filename)

  Net::SFTP.start( sftp_host, sftp_user, :password =&gt; sftp_pass ) do |sftp|
    puts sftp.upload! $local_path_to_css_file, remote_theme_dir_absolute + File.basename(filename)
    end
  puts ">>> Compass is polling for changes. Press Ctrl-C to Stop"
end

Restart Compass, save one of your Sass .scss files with a change of some sort (from where CSS will be compiled), and watch your files be saved locally and remotely.

At this point, my full config.rb file looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Require any additional compass plugins here.
require 'net/ssh'
require 'net/sftp'

# Set this to the root of your project when deployed:
http_path = "../../Sites"
css_dir = "../../Sites/wp-content/themes/test/css"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "javascripts"

project_type = :stand_alone
output_style = :nested
line_comments = false

# note that this is the directory that CSS files will be written. It can be the theme dir
# or a subdirectory (e.g. theme_dir/css). Whatever this path is MUST exist
remote_theme_dir_absolute = '/home/sites/emmense.com/httpdocs/wp-content/themes/test/css'

# SFTP Connection Details - Does not support alternate ports os SSHKeys, but could with mods
sftp_host = 'hostname.com' # Can be an IP
sftp_user = 'username' # SFTP Username
sftp_pass = 'password' # SFTP Password

# Callback to be used when a file change is written. This will upload to a remote WP install
on_stylesheet_saved do |filename|
  $local_path_to_css_file = css_dir + '/' + File.basename(filename)

  Net::SFTP.start( sftp_host, sftp_user, :password =&gt; sftp_pass ) do |sftp|
    puts sftp.upload! $local_path_to_css_file, remote_theme_dir_absolute + File.basename(filename)
    end
  puts ">>>> Compass is polling for changes. Press Ctrl-C to Stop"
end

Conclusion

Rails developers have all the fun. It’s true. But with Compass, Sass and a little bit of Ruby, PHP developers (including WordPress theme developers) have a great tool that will make workflows more efficient, CSS more readable and structured and central management more coherent.

Obviously, I did not get too far into the details of using Compass and Sass. That’s a whole tutorial to itself. For information on that, I’d recommend checking out these fine articles written on the topic:

(Protip: I love being able to nest CSS… try it)

Disclaimer: I am a PHP developer, not a Ruby developer. My Ruby code could probably be improved upon by someone who is more in tune with the Ruby language.

Changing Roles at WP Engine

For some time, I’ve felt there was a change coming and today, I’m ready to announce that my role within WP Engine is changing. Starting today, I have transitioned into an advisory and consulting role with the company.

Effective immediately, I will be taking the portion of the business that focused on professional services and consulting to allow the company to focus on premiere WordPress hosting. It’s a good thing and I’m excited about the possibilities. Back in November, we decided to start taking on some professional services work to augment demands from many of our customers. It was awesome to have fast, secure, scaleable, managed hosting but they wanted more!

And we wanted more.

However, as the company has evolved, taken funding, hired more people, addressed growth challenges and built out our hosting option, it seemed clear that the professional services portion of the company was a separate kind of deal than what we wanted to focus on.

So today, I’ll be taking that portion of the company (and all related existing and current relationships, as agreed on), and working on that. Meanwhile, I’ll still be working with the company to guide direction and strategy. So it’s good for everyone.

Effective immediately, I am available for all WordPress consulting roles. However, I am also currently entertaining all possibilities involving full time employment as well, and welcome those conversations.

To contact me, please direct emails to aaron@technosailor.com. As transitions go, the immediate financial impact is something that I need to consider.

How is WordPress Subversion Organized


There’s some confusion about how WordPress organizes it’s Subversion (SVN) repository. Most SVN repositories are organized into three main directories, as is best practice — trunk, tags, branches.

The repository can be found at http://core.svn.wordpress.org/ and a primer on how to use SVN for WordPress development can be found on Mark’s blog and, for Windows, on Westi’s blog.

Though there are varying schools of thought as to how branches and tags work, WordPress follows the following system:

/trunk is where future release development occurs. Right now, WordPress development is focused on an upcoming 3.3 release. All development for this release is going into /trunk.

/branches is where 3.3 will go once it is released (or where future “branches” of the software will be housed down the road. The directory contains a series of directories that are branches from the current release development — for example, /branches/3.0, /branches/3.1, /branches/3.2, etc. What you won’t find in branches are security (or dot) releases.

For instance, when a security vulnerability is discovered, it will be patched in /trunk for the current development branch and may be backported to the previous release branch (currently, 3.2). But until the next security release of WordPress comes out for that branch, it is still considered “development” and not “stable”.

/tags is where stable releases are archived. No development goes into tagged releases. These are final releases. You will find every release here in the form of /tags/3.2.1, /tags/3.2, /tags/3.1.4, etc. If you’re looking for the latest current stable for production, this is the place to look.

When branches achieve the next milestone (i.e. a maintenance or security or “dot” release), this is the place where the code is kept.

Hopefully this makes the WordPress repository (and maybe other projects) clear as mud.

WordPress Release Word Clouds

Yesterday, I published the 12th in an ongoing series of blog posts since December 26, 2005, where I take my own look at major WordPress releases and write a hopefully helpful article about features. It’s the routine, and now expected, “10 Things You Need to Know” posts.

Out of morbid curiosity, I decided to run all of those posts through a word cloud generator and see if there were any trends that could be seen. Of course, it’s my writing so there are obvious tendencies and biases, but it was fun to see anyway.

One thing I did to make the results better… I removed the words WordPress and WP. Also, several of the posts had my name in it so I figured it would be better not to include that either.

WordPress 2.0

WordPress 2.1

WordPress 2.2

WordPress 2.3

WordPress 2.5

WordPress 2.6WordPress 2.7

WordPress 2.8

WordPress 2.9WordPress 3.0WordPress 3.1WordPress 3.2

10 Things You Need To Know About WordPress 3.2

Photo credit Randy Stewart.

WordPress 3.2 will be released soon (at the time of this writing, it is in RC1 which essentially means it is done and being tested). This is an exciting release as it marks the first release that drops PHP 4 dependency. For years, WordPress has opted to play to the lowest common denominator while hosts have taken their sweet time arriving at PHP 5.

Of course, this may mean nothing to you, depending on your technical knowledge of the underlying language. However, it has limited the amount of innovation that could be possible using the more modern version of PHP 5.

The focus for this release was to slim down redundant code that had been added along the way to employ PHP 5 techniques in a PHP 4-compatible fashion. In addition, a focus was placed on slimming down code all along the way to provide a more efficient codebase. Eliminate, eliminate, eliminate! More Red than Green – a reference to the way changes are recorded visually where red is code elimination and green is code addition.

Regardless, the approach to PHP 5 adoption has had a positive effect. Approximately 12% of the web is powered today by WordPress, whether self-hosted “.org” sites or Automattic’s WordPress.com and other hosted WordPress sites.

As I have done eleven other times before, today I bring you the Ten Things that, in my opinion, you should know about WordPress 3.2.

Twenty-Eleven

One of the big things that was discussed internally around the time when WordPress 3.0 was released over a year ago was the need to keep the default theme fresh. To that end, for WordPress 3.0 did away with the old Kubrick theme and replaced it with the fresh and semantic Twenty-Ten theme.

Yes, you can see how naming a theme Twenty-Ten in 2010 setup the opportunity for a Twenty-Eleven theme in 2011. And there is that opportunity for a new theme called Twenty-Twelve in 2012, but let’s not get too far ahead of ourselves.

Twenty-Eleven visually is not a huge departure from Twenty-Ten. It still uses much of the same visual layout that Twenty-Ten did. The new theme, however, is greatly different behind the scenes.

Note: This blog (along with all of my blogs) are running Twenty-Eleven right now.

Users of Twenty-Eleven have the opportunity to select a one-column or two column layout for their blog from inside the WordPress Admin. The two column layouts can use a sidebar left or sidebar right variant.

My photoblog uses a one-column format, as an example.

Additionally, Twenty-Eleven also offers a dark and light color scheme. My photoblog, for instance, uses the dark format while this blog uses the light format.

Finally, as with Twenty-Ten, the theme allows for custom header images (or no header images) and backgrounds. Because of the professional nature of this blog, I’ve opted to use no header on this blog and my personal blog utilizes a custom header image.

And of course, as with all things WordPress, no one says you have to settle for what Twenty-Eleven offers out of the box. In fact, it is encouraged that you use Twenty-Eleven as a parent theme that offers all of the benefits of the default theme while putting your own spin on it with a child theme.

Distraction Free Writing

While I write this post, I am using the successor to the Full-screen mode that has been in WordPress for some time. Full screen mode, in my opinion, never really was well adopted but it has been championed in the past by bloggers who focus on efficient workstyles, or Getting Things Done (“GTD”) approach to work.

The ability to shut out all distractions so as to focus on the task at hand is hugely important. WordPress core developer Mark Jaquith has said for years that his vision for WordPress was that it would become a tool that got out of the way of people and their writing. It’s not about WordPress. It’s about writing and the experience should be such that you should never have to think about what tool you are using to do that.

With Distraction Free Writing, you have just that. By clicking on the Full Screen (in HTML writing mode) or the new icon for DFW in the toolbar of the visual text editor, the blogger finds themself on a plain off-white canvas with minor tools along the top of the screen to assist in basic formatting. If you leave your hands off the mouse, even these fade away allowing you to just write in a pleasant, serene environment.

This feature is probably my favorite in WordPress 3.2 and usability/writer-facing features are rarely my favorite as a developer. I generally prefer new APIs and developer tools. However, this feature wins hands-down.

Minor Overhaul to Administrative UI

It’s been several years since WordPress has undergone a major Admin overhaul. There have been tweaks along the way, but by and large the administrative interface has stayed true to what it evolved into (with much research and usability testing) in WordPress 2.7.

There is not a drastic overhaul in WordPress 3.2, but it is the larger than a few tweaks and color scheme modifications. In WordPress 3.1, the Admin Bar (which I’ll talk about later) came into being and in 3.2, emphasis has been put on placing more commonly accessed functions into it as opposed to the main UI.

As a result, familiar things (which were often used for blogs in Multisite mode) such as the “Favorites Menu” have been removed to the Admin Bar. The Quick Access menu that allowed Multisite Super Admins quick access to the “Network Admin” has been relocated to a less-than-obvious dropdown  in the upper right. Hint: The dropdown menu can be accessed by clicking the “Howdy Aaron” link, where “Aaron” is your username.

Other aspects of the new interface are mainly aesthetic. Menus are where you’d expect them. Features are where they’ve always been. Plugin developers who have built UI for their plugins are still safe as long as, as usual, they are using the WordPress best-practices, i.e. using the same HTML formats and structures used in core.

More Determined Move to the Admin Bar

As mentioned before, the Admin Bar has become the focus of a “Command Center” approach. By default, quick actions like Adding a new post or editing a page or getting quick access to the dashboard of other Multisite sites are loaded into quick menus in the Admin Bar.

This is also where the philosophy of plugin development that provides quick access to features should be. A good example of this is the Purge Cache functionality in W3 Total Cache. Where this has been in the Favorites menu inside WordPress, it now will have to move to the Admin Bar. This seems like a more natural place to me anyway. Other plugin developers should look at their code to ensure that they are compliant with this approach.

John Brook has a most excellent tutorial on creating and adding menus to the Admin Bar.

PHP 5.2.4 and MySQL 5.0

I mentioned the new system requirements at the beginning of this article. This shift to PHP 5 has been a long time in coming and was done deliberately to time with WordPress hosting on PHP 4 dipping below 10%. In other words, it is more than likely your host is already on PHP 5.2.4+. However, you should verify this if you’re not sure.

With the adoption of PHP 5.2.4, there is also a bump in the requirements for MySQL. Now WordPress requires MySQL 5.0, another hurdle that is not very hard to overcome but should be verified if you’re not sure.

Ryan Duff has created a quick and easy plugin that can be installed to ensure compatibility with WordPress 3.2.

For Newbies, a Better Help Menu on Each Page

For some time, WordPress has included a contextual “Help” menu in the upper right of many of the screens in the admin interface. However, with WordPress 3.2, every page has a help menu. Not only does every page have a help menu, newbies can get detailed contextual assistance for each page. Veteran users already know their way around, so this will be less than helpful, but for n00bs, the guidance lowers the barrier to entry.

Upgrade Enhancement – Just the code you need!

Think iOS5 but for WordPress. When Steve Jobs announced at WWDC recently that iOS updates would in the future come in smaller packages applying just new code and differences over the air, WordPress was already working on this (errr, except the over the air part).

Up until WordPress 3.2, upgrades were performed by downloading the entire package and applying it over the existing install. While this was fine, it took a lot more time due to the larger package size. This new version will enable future upgrades of WordPress to be done incrementally making the process much faster and efficient.

Code Efficiency enhancements

A huge emphasis was placed on core efficiency in this release. Many of the updates that have gone into this release have been major refactoring of code as well as the removal of legacy (and now unneeded) PHP4 compatibility code.

When I write these articles, I like to look at a diff file of all code changes between the last major release and the current. I was blown away by the amount of PHP4 compatibility code that has been axed.

Additionally, a lot of effort has been placed on database optimization. Many queries have been made more efficient. These things are less notable for smaller sites, but for large sites and hosting companies (such as my company, WP Engine), these types of optimizations add up in orders of magnitude!

File System API

Another optimization that has been made (getting the clue that this release is all about streamlines?) has been in the code that handles upgrades and automatic installs of plugins. When the original code was written, it was written to find what methods were available to write to the filesystem. This was because WordPress does the best it can to be as compatible as possible with as many server configurations as possible.

Some of the more obsolete (and unnecessary) transports have been done away with in favor of Streams. Though streams existed in PHP 4.3 (WordPress’ former system requirement), the upgraded requirement now allows us to do so much more with file transfer, handling and writing.

But I don’t want to get overly technical right now.

No IE6 Support

Screenshot courtesy of Mashable.

We all knew Internet Explorer was dead. Well, most of us. Believe it or not, there are still folks (mostly in government and enterprise organizations) where IE6 is still in use. While WordPress has always endeavored to be as compatible with as many configurations as possible, just like file handling replaced by Streams and PHP4 going the way of the Dodo Bird, IE6 can die in a fucking fire too. Oops. Sorry, kids. No more IE6 support.

Automatically approve parent comments

Finally, a longtime nuance has been comment approval. Comments have always been a one-to-one relationship with approval. You approve one comment at a time. And while that’s normally fine, what if you have nested comments and you approve a child comment but not a parent comment? Then you have a weird hierarchy that may not make a lot of sense.

In WordPress 3.2, now when you approve a comment that has an unapproved parent comment, the parent comment will also be approved. Many people have asked for that and now it’s here.

BONUS: Credits Screen

But wait… There’s one more thing. Every release, hundreds of people participate in the development process by writing code, contributing patches, discussing ideas in IRC and on Trac. That doesn’t even begin to acknowledge the testers, translators, and documentation writers who contribute their time free of charge.

Now, in the footer of the WordPress Admin, you’ll find a Credits link that shows everyone who has contributed to this release. Good job, guys! (I’m one of the contributors).

The WordPress Bible

The WordPress Bible is the guide you need for all levels of skill and expertise in WordPress. If you’re just beginning, I give you tricks and tips on how to make use of the WordPress administrative interface, how to install and configure plugins, themes and widgets.

If you’re a theme developer, I give you insight into the variety of template tags, theme hooks and best practices for building a theme that will wow your readers.

For plugin developers, the many APIs and classes that WordPress has to offer are at your fingertips.

The most popular open source Content Management System on the internet!

As of late 2014, WordPress powers over 20% of the internet. Put another way, one out of every five websites you visit on the internet is likely built using WordPress in one way or another. As of this update, WordPress 4.1 1 has been downloaded over 14.1 million times.

There’s a reason why this book was written for you. Don’t get left behind.

(And if you catch me out and about and own the book, I’ll gladly sign it for you!)

Purchase it today!

Notes:

  1. The WordPress Bible was last revised for WordPress 3.1, but almost everything in it still applies