Daniel Dvorkin

My take on WordPress and related geekery

Category: WordPress (Page 1 of 3)



WordPress 3.6 comes with a hidden goody. Well, it’s not really hidden, but I just spotted it a few days ago. It’s called do_accordion_sections and it’s used to render the sections in the new menu manager:


But the cool thing about it is that it’s basically a replacement for do_meta_boxes. So, with just a few lines of code you can make it work, for instance, in your Custom Post Type edit screen. Why? Just because!

Simple and hacky code to make this change for Pages.

add_action( 'edit_form_after_editor', 'testing_accordion_section' );

function testing_accordion_section() {

	$screen = get_current_screen();
	if ( $screen->id != 'page' )

	do_accordion_sections( $screen, 'normal', get_post() );

	global $wp_meta_boxes;
	$wp_meta_boxes[$screen->id]['normal'] = array();

And the ‘normal’ metaboxes in the Page edit screen will render like:


I created a Trac ticket and submitted a patch to allow you select this metaboxes style just using a filter, or implement custom metabox styles. (tabs, etc)

mu-plugins, maybe.

UPDATED: Added also deactivation enforcing

A few days ago, Ryan McCue on twitter asked a question that I’ve asked myself a few times now, and always deferred looking for an answer and moved away to do more pressing things. But this time I really needed a solution for a site we’re doing, and came up with an idea.

I don’t really like moving everything to mu-plugins because:

a) You can’t deactivate on dev for testing things.
b) It’s stupid, but I like having an unified list of plugins. People never check the “must-use” tab when looking for activated plugins.

So, wouldn’t it be neat to have mu-plugins on production that work like standard plugins in dev and staging?

I came up with this mu-plugin:

Plugin Name:	Force Plugin Activation/Deactivation (except if WP_DEBUG is on)
Plugin URI: 	http://danieldvork.in
Description:	Make sure the required plugins are always active.
Version:    	1.0
Author:     	Daniel Dvorkin
Author URI: 	http://danieldvork.in

class Force_Plugin_Activation {

	private $force_active = array(

	private $force_deactive = array(

	function __construct() {
		add_filter( 'option_active_plugins',    array( $this, 'force_plugins'       ), 10, 1 );
		add_filter( 'plugin_action_links',      array( $this, 'plugin_action_links' ), 99, 4 );

	function force_plugins( $plugins ) {

		$plugins = array_merge( (array) $plugins, $this->force_active   );
		$plugins = array_diff ( (array) $plugins, $this->force_deactive );

		$plugins = array_unique( $plugins );

		return $plugins;

	function plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {

		if ( in_array( $plugin_file, $this->force_active ) )
			unset( $actions['deactivate'] );

		if ( in_array( $plugin_file, $this->force_deactive ) )
			unset( $actions['activate'] );

		return $actions;

// We want to enfornce only on production, where WP_DEBUG is off.
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
	new Force_Plugin_Activation();

End result:

What do you think?


The Humble Programmer

To put it quite bluntly: as long as there were no machines, programming was no problem at all; when we had a few weak computers, programming became a mild problem, and now we have gigantic computers, programming had become an equally gigantic problem. In this sense the electronic industry has not solved a single problem, it has only created them, it has created the problem of using its products. To put it in another way: as the power of available machines grew by a factor of more than a thousand, society’s ambition to apply these machines grew in proportion, and it was the poor programmer who found his job in this exploded field of tension between ends and means. The increased power of the hardware, together with the perhaps even more dramatic increase in its reliability, made solutions feasible that the programmer had not dared to dream about a few years before. And now, a few years later, he had to dream about them and, even worse, he had to transform such dreams into reality! Is it a wonder that we found ourselves in a software crisis? No, certainly not, and as you may guess, it was even predicted well in advance; but the trouble with minor prophets, of course, is that it is only five years later that you really know that they had been right.

Grab a coffee and go read this now…

Screen Shot 2013-04-12 at 12.03.22 PM

XHProf vs xDebug running on Apache and OSX

My good friend Peter Chester pointed out to me that I should be trying XHProf. It is a PHP profiler created by Facebook and open sourced a while back. To be honest, the reason I did not do this before is because I’m pretty happy using xDebug as a profiler tool, but let’s give XHProf a test ride and compare the results with a xDebug profile for the same site.

Installing XHProf using homebrew

Dependencies. You probably have most of them already, but in case you’re missing any:

brew install autoconf
brew install freetype
brew install gettext
brew install zlib
brew install jpeg
brew install libpng
brew install pcre

You should also install GraphViz if you want to have a nice Call Graph like the one illustrating this post. You have a link to the full version of that (massive) graph at the end of the post.

brew install graphviz

Check your PHP version doing:

php -v

If you are running PHP 5.3.x run:

brew install php53-xhprof

Or, if you’re on PHP 5.4.x run:

brew install php54-xhprof

On the other hand, if you’re in PHP 5.2, you should not.Stop reading this immediately and go fix that.

When the brew install process finishes, it will show you the path where XHProf got installed. It will look something like /usr/local/Cellar/php53-xhprof/0.9.2. The .so file is in that directory, and we need to place it in our Apache extensions directory, doing:

sudo cp  /usr/local/Cellar/php53-xhprof/0.9.2/xhprof.so /usr/lib/php/extensions/no-debug-non-zts-20090626/

If you’re not sure where is your apache’s extensions directory, edit your /private/etc/php.ini and look for extendion_dir.

Now edit your /private/etc/php.ini, look where all extensions are being loaded and add:


And restart Apache

sudo apachectl restart

Installing XHProf from source

If you’re not using Homebrew, do yourself a favor and install it. In any case, this should do:

pecl download xhprof-0.9.2
tar -xvf xhprof-0.9.2.tar.gz
cd xhprof-0.9.2/extension
make install
sudo cp xhprof.so /usr/lib/php/extensions/no-debug-non-zts-20090626/

Profiling a WordPress install

Install this plugin. You’re done. Really.

You need to have WP_Debug set to true, and of course the plugin activated. You’ll see a link on your footer like this one:

Screen Shot 2013-04-12 at 11.43.02 AM

Click there and you’re ready to roll.

If for some reason you don’t want to use the plugin to have more control or if you just want to profile a smaller part of your application, you need to to manually start and stop the profiler data gathering using the module functions: xhprof_enable and xhprof_disable.

Conclusions after playing with it for 30 minutes

I must confess, I started doing this exercise being quite sure I wouldn’t be moving away from xDebug anytime soon.

Boy I was wrong.

For the data that’s in both places, I couldn’t find any big difference that would make me suspicious something is fishy.

But there are 3 points that totally tip the scales in favor of XHProf.

  1. It’s insanely fast and efficient. I didn’t really notice it was actually saving profile data in each page load until I checked the folder.
  2. Profile log file size is 10x-15x smaller. Really. For the site I’m testing this on, xDebug gives me a 18Mb file, vs a bit less than 1Mb for XHProf. This is great for performance: opening a 20Mb file on any xDebug viewer takes a while.  This is so good to be true, so probably XHProf is missing some info that will come to bite me in the future. Will need to research a bit more about that, because I can’t seem to find anything missing.
  3. Memory profiling. For doing memory diffs on xDebug you need to do Traces, and it’s a completely separated process. In XHProf you see all the information in the same table, you can order by any col, etc.

I would feel really bad if I don’t give xDebug even one point, so here it is: The table view for XHProf is ugly. Big time ugly. xDebug is older and more popular, and have tons of tools to browse the profile data. I use MacCallGrind, which is pretty. But you have KCachegrind which is super powerful, phpStorm has an integrated viewer, there are lots of browser-based viewers. Etc.

Update: xhprof.io Sorry xDebug. You just lost your point.


Here the full version of that image. It shows a homepage load for a WP 3.6 install with only bbPress activated. Click to expand.


And here is the table view.

Screen Shot 2013-04-12 at 12.31.33 PM


It turns out procrastination is not typically a function of laziness, apathy or work ethic as it is often regarded to be. It’s a neurotic self-defense behavior that develops to protect a person’s sense of self-worth.

You see, procrastinators tend to be people who have, for whatever reason, developed to perceive an unusually strong association between their performance and their value as a person. This makes failure or criticism disproportionately painful, which leads naturally to hesitancy when it comes to the prospect of doing anything that reflects their ability — which is pretty much everything.

But in real life, you can’t avoid doing things. We have to earn a living, do our taxes, have difficult conversations sometimes. Human life requires confronting uncertainty and risk, so pressure mounts. Procrastination gives a person a temporary hit of relief from this pressure of “having to do” things, which is a self-rewarding behavior. So it continues and becomes the normal way to respond to these pressures.

–Nice post about procrastination from David Cain


Use current directory as taskwarrior project filter

I use taskwarrior as my project management tool, and when I’m working on a given project, I always have a tmux pane in the project’s root folder that I use for dealing with taskwarrior tasks.

Having to add pro:my_project to each and every command is a pain, so I came up with this function (I’ve added it to my .zshrc, but you can make a stand alone script with it):

function t() {
    project=$(basename `pwd`);
    tp=( $(task _projects | grep $project) );

    if [[ -n $tp ]]; then
        task "$@" project:$project;
        task "$@"

As you can see, this function assumes that your project in taskwarrior is called exactly like your project root folder.

So now, when you use t instead task, if you’re not in one of your projects root folder, it will work as usual:

daniel@malbec ~ » t
[task next]

ID Project       Pri Due A Age Urgency Description                                                     
 3 my_project_1  H          1h       7 re dek headings on new meta                                     
 2 my_project_2             2h       1 Tutorial: How to use an image instead of "open" and "closed"    

2 tasks

but if you are in one of your projects folder:

daniel@malbec Sites/my_project_1 (server/dev %) » t
[task next project:my_project_1]

ID Project       Pri Due A Age Urgency Description                    
 3 my_project_1  H          1h       7 re dek headings on new meta    

1 task

daniel@malbec Sites/my_project_1 (server/dev %) » t add "my test task"
Created task 4.
The project 'my_project_1' has changed.  Project 'my_project_1' is 0% complete (3 of 3 tasks remaining).

daniel@malbec Sites/my_project_1 (server/dev %) » t
[task next project:my_project_1]

ID Project       Pri Due A Age Urgency Description                    
 3 my_project_1 H          1h       7 re dek headings on new meta    
 4 my_project_1            2s       1 my test task                   

2 tasks

daniel@malbec Sites/my_project_1 (server/dev %) » t 4 del
Permanently delete task 4 'my test task'? (yes/no) y
Deleting task 4 'my test task'.
Deleted 1 task.
The project 'my_project_1' has changed.  Project 'my_project_1' is 0% complete (2 of 2 tasks remaining).

daniel@malbec Sites/my_project_1 (server/dev %) » t long
ID Project       Pri Added     Started Due Recur Countdown Age Deps Tags Description                
 3 my_project_1  H   1/21/2013                 -            1h           re dek headings on new meta

1 task

Page 1 of 3

Powered by WordPress & Theme by Anders Norén