Presentation: Welcome to the Family (WordCamp Toronto 2012)

Welcome to the Family

Becoming an healthy, active member of the WordPress community

WordCamp Orlando (photo from WordCamp Central)

Mohammad (Mo) Jangda

  • Code Wrangler with Automattic ( VIP)
  • batmoo
  • Twitter: @mjangda

If you use WordPress, you’re part of a family.

A very, very big one.

56,000,000 sites

17% of the web

Millions of users

Of the three most important people in WordPress,
the most important one is…


The very fabric of the WordPress community relies on community participation

Families only function if everyone pitches in. Otherwise…

WordPress is FreeAsInSpeech (not FreeAsInBeer)

The Great Uncle Ben once said, “With great power…”


Lots of ways to be a healthy, active member of the community.

Doesn’t matter if you’re a developer, blogger, business, superhero, designer, site owner, photographer, enterprise, artist, freelancer, writer, …

The most important thing is that you do something.
And you do it with the interests of the community in mind.
And don’t do stupid things like cause infighting.

How to give back?

Use WordPress

Even though it’s not the NBT (“Next Big Thing”).

Not just core, but everything else (plugins, themes, tools, APIs etc.)

Give feedback, criticism, or even just a “thanks”.


Share WordPress

Help the family grow. Tell everyone about it.

friends, family, strangers, everyone!

I got SWAG

Share Yourself

Docs: Codex or Tutorials

Help someone




(Meetup Group, WordCamps, conferences, library, etc.)

Share your code

Do the Open Source thing

Help Break WordPress

Beta test (3.5 Beta 1), Report bugs

Help Make WordPress


Patches, plugins, themes, tools, unit tests, etc.


Patches, themes, UI designs, UX testing, etc.



Someone else?

Test patches, copy editing, help text, etc.


For the feel-good feeling

To Learn

Example: free code review


Not just in the spiritual sense

Social, Financial Karma

Most importantly…

it’s necessary for the the continuity of the WordPress Project


You can’t spell WurdPress without a U.

Thanks. | @mjangda

Review: Peter Nimble and His Fantastic Eyes

Peter Nimble and His Fantastic Eyes
Peter Nimble and His Fantastic Eyes by Jonathan Auxier
My rating: 3 of 5 stars

This was a fun read but I had a hard time getting into it. The narration was a bit inconsistent, the dialog and characters seemed a bit forced. And I had a hard time getting over the fact that what seems obviously like a children’s book has so much blood.

Also, “I seen this movie before”. It’s called Star Wars ;)

View all my reviews

Managing Your Editorial Workflow (WordCamp Toronto 2011)

The video of presentation at WordCamp Toronto 2011 on “Managing your Editorial Workflow” where I talk mostly about Edit Flow.

Looks like the video was cut off, which is probably a good thing since it wasn’t really my best performance (being my first WordCamp presentation and all). I also flail my arms alot.

Mo Jangda: Managing Your Editorial Workflow |

WordPress Debugging (WordCamp NYC 2012 Talk)

Here’s my presentation slides from WordCamp NYC 2012. Click on the slide below to go full-screen and arrow keys to navigate.


The end goal of debugging is to find the causes to cute (and not-so-cute) bugs so we can squish them.

Who am I?

  • Mohammad (Mo) Jangda
  • Toronto, ON
  • Code Wrangler, VIP at Automattic
  • Ice Cream fan
  • batmoo (.org)
  • @mjangda

When you debug, you work similar to a doctor or an investigator.

On a really high-level

  • Determine the problem
  • Gather information
  • Analyze the symptoms
  • Rule out improbable causes
  • Make educated or exact guesses about the root cause(s)
  • …and then fix the problem

Knowledge of the domain is important

If you don’t have a good understanding of WordPress (or javascript, or servers, or etc.), your ability to analyze the demonstrated symptoms is limited.

A good understanding of the problem is important

  • The more information we have the better suited we are to fix the problem.
  • If we don’t have enough information, we should gather more.

Collecting the right information

  • “I did, I saw, I expected.”
  • Reproduction steps, screenshots, environment data
  • Common patterns between the symptoms

Collect more than you need, then filter out the garbage.

It’s important to check all your bases and avoid letting assumptions trap you (“oh, it can’t be because of this, because of that…”)

5 Whys

Asking “Why?” is one of your most powerful tools!

The Problem: The YouTube video in my post isn’t showing up.

  • Why? It’s not being rendered on the page.
  • Why? The shortcode callback isn’t outputting anything.
  • Why? The attribute check is failing.
  • Why? The ID has a hyphen in it.
  • Why? YouTube changed its IDs.

(Not limited to 5!)

Always go to the source!

Start at the point of origin for the symptoms and work backwards until you pinpoint the cause of the bug.

Fatal error: Call to undefined function give_me_some_seos() in /Users/moo/Sites/wp/wp-content/themes/twentyeleven/functions.php on line 76

Point of origin

We need to determine where the problem is occurring and eventually originating:

  • server-level
  • database-level
  • application-level (server or client-side)
  • user-level

This will drive our investigation.


WordPress makes debugging easy.

Many built-in tools. More pluggable ones.

defined( ‘CONSTANTS’ );

define( 'WP_DEBUG', true );

Enables error reporting.

If your development environment does not have this set to true, you’re _doing_it_wrong().

defined( ‘CONSTANTS’ );

define( 'WP_DEBUG_DISPLAY', true ); // display_errors
define( 'WP_DEBUG_LOG', '/tmp/php_errors.log' ); // write errors to file

defined( ‘CONSTANTS’ );

Debugging SQL:

define( 'SAVEQUERIES', true );

Debugging CSS and JS:

define( 'SCRIPT_DEBUG', true );
define( 'CONCATENATE_SCRIPTS', false );
define( 'COMPRESS_SCRIPTS', false );
define( 'COMPRESS_CSS', false );
define( 'ENFORCE_GZIP', false );

Debug Bar

Firebug for your WordPress

If your development environment does not have this set to installed and activated, you’re _doing_it_wrong().

Debug Bar Extender

Variable trace, performance profiling, and more.

Debug Bar Extender

if ( class_exists( 'Debug_Bar_Extender' ) ) {
        add_action( 'wp_head', 'my_debug_trace_id' );
        add_action( 'comments_template', 'my_debug_trace_id' );
        add_action( 'wp_footer', 'my_debug_trace_id' );
        function my_debug_trace_id() {
                $post_id = get_the_ID();
                Debug_Bar_Extender::instance()->trace_var( $post_id, 'post_id via get_the_ID()' );

Debug Bar Extender

Profiler example.

Debug Bar: Roll Your Own

// Tracks remote requests made using the WordPress HTTP API and displays their results

class WPCOM_Debug_Bar_Remote_Requests extends Debug_Bar_Panel {
	var $ignore_urls = array(
	var $requests = array();
	var $status_counts = array();
	var $current_request = array();

	function init() {
		$this->title( __('Remote Requests', 'debug-bar') );

		add_filter( 'http_request_args', array( $this, 'log_http_requests' ), 99, 2 ); // after all args have been set up
		add_action( 'http_api_debug', array( $this, 'log_http_request_result' ), 0, 5 ); // as soon as it's complete

		$this->status_counts = array(
			'Informational (1xx)' => 0,
			'Success (2xx)' => 0,
			'Multiple Choices (3xx)' => 0,
			'Client Error (4xx)' => 0,
			'Server Error (5xx)' => 0,
			'Unknown' => 0,
	function render() {
		global $wp;
		<div id='debug-bar-remote-requests'>

				<span>Total Time</span>
				<?php echo number_format( $this->total_time, 2 ) . 's'; ?>
// ...

Other Developer Plugins

  • Debug bar Transients
  • Log Deprecated Notices
  • Monster Widget
  • Rewrite Rule Inspector


  • Hardcoded checkpoints (var_dump) (don’t discount this; it’s ghetto but powerful)
  • error_log (tail + xmpp on
  • debug_backtrace
  • alert / console.log (for javascript)
  • Roll your own…


Index: capabilities.php
--- capabilities.php	(revision 20851)
+++ capabilities.php	(working copy)
@@ -1314,6 +1314,10 @@
 	if ( ! isset( $wp_roles ) )
 		$wp_roles = new WP_Roles();
+	// Debug
+	echo 'Adding role:<br/>';
+	var_dump( $role, $display_name, $capabilities );
 	return $wp_roles->add_role( $role, $display_name, $capabilities );


Index: capabilities.php
--- capabilities.php	(revision 20851)
+++ capabilities.php	(working copy)
@@ -1314,6 +1314,10 @@
 	if ( ! isset( $wp_roles ) )
 		$wp_roles = new WP_Roles();
+	// Debug
+	error_log( 'Adding role: ' . var_export( array( $role, $display_name, $capabilities ), true ) );
 	return $wp_roles->add_role( $role, $display_name, $capabilities );

Homegrown: sekret “all” filter

add_action( 'all', function() {
    var_dump( current_filter() );
} );

Homegrown: dump all callbacks for a hook

function debug_get_functions_for_hook( $hook ) {
	global $wp_filter;

	if( ! isset( $wp_filter[$hook] ) )

	$functions = array();
	foreach( (array) $wp_filter[$hook] as $key => $actions ) {
		$functions['priority_' . $key] = array_keys( $actions );
	ksort( $functions );
	return $functions;
Mfields::dump_hook( 'the_content' );

Non-WordPress Tools

  • Web Inspector / Firebug
  • curl / Charles
  • Xdebug and integrated debugging for IDEs


Let’s work through some examples!

Problem: The Fatal Whitescreen

Problem: The Fatal Whitescreen

With define( 'WP_DEBUG', true );:

(in production, look at your error log)

Problem: The Fatal Whitescreen

Is the function defined anywhere?

$ ack "give_me_magic_and_seos"

Problem: Filters gone bad

Content showing for some posts but not others.

Problem: Filters gone bad

Content showing for some posts but not others.

Problem: Filters gone bad

Step 0. Verify the post content!

Problem: Filters gone bad

Step 1. Where and how is the content being output?

Goto our theme, content.php:

<div class="entry-content">
    <?php the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?>
    <?php wp_link_pages( array( 'before' => '<div class="page-link"><span>' . __( 'Pages:', 'twentyeleven' ) . '</span>', 'after' => '</div>' ) ); ?>
</div><!-- .entry-content -->

Problem: Filters gone bad

Step 2. What does the_content() do?

Goto core:

$content = get_the_content($more_link_text, $stripteaser);
$content = apply_filters('the_content', $content);

Problem: Filters gone bad

Step 3. What is manipulating the_content()?

var_dump( debug_get_functions_for_hook( 'the_content' ) );

Here's what we get:
array(4) {
    ["priority_1"] =>
        array(1) { [0]=> string(14) "polldaddy_link" }
    ["priority_10"] =>
        array(7) { [0]=> string(11) "wptexturize" [1]=> string(15) "convert_smilies" [2]=> string(13) "convert_chars" [3]=> string(7) "wpautop" [4]=> string(17) "shortcode_unautop" [5]=> string(18) "prepend_attachment" [6]=> string(25) "my_content_with_thumbnail" }
    ["priority_11"] =>
        array(2) { [0]=> string(16) "capital_P_dangit" [1]=> string(12) "do_shortcode" }
    ["priority_8"] =>
        array(2) { [0]=> string(45) "0000000072f50cfc0000000022e7a2b6run_shortcode" [1]=> string(41) "0000000072f50cfc0000000022e7a2b6autoembed" } }

Problem: Filters gone bad

Step 4. Investigate all callbacks.

add_filter( 'the_content', 'my_content_with_thumbnail' );

function my_content_with_thumbnail( $content ) {
        if ( has_post_thumbnail() ) {
                return get_the_post_thumbnail() . $content;

Problem: Comments disappearing!

Comments for a post (in fact, many posts) are “disappearing” when submitted.

Questions to ask:

* Did they actually disappear?
* Are they in the database?
* Are they flagged as spam?
* Are they being fetched correctly?
* Are they being fetched at all?
* Are they attached to the correct post?

Not all problems are obvious or visible

For example: cron event fails… but only sometimes.

How do we investigate these? Get Creative :)

(Remote logging; hacks, hacks, hacks)

Debugging is an art

  • Many right ways to do it. Many wrong (but the only) ways to do it.
  • Investigate, distill, hypothesize, test, conclude, solve.
  • Understand your domain and continually learn.
  • Understand and use your tools.

Posted from New York, New York, United States.

Review: Tintin in America

Tintin in America
Tintin in America by Hergé
My rating: 3 of 5 stars

I’ve started reading through the whole Tintin series again (partially in preparation for the movie) and the experience is very similar to re-watching your old childhood TV shows. You get that warm, nostalgic feeling which slowly dissolves into doubt and and leaves you wondering how you could possibly enjoyed something so bad. This particular book has a lot of racist overtones and the dialogue is pretty poorly written (which I guess is really the norm for any comic book written in the early 20th Century).

Overall, though, the book is still a fun read and I can’t wait to re-read the rest.

View all my reviews

On $wpdb->prepare

If you do the following, you’re a terrible person:

$query = "SELECT ID from {$wpdb->posts} WHERE ID = %d";
$query = $wpdb->prepare( $query, $value );

There is absolutely no reason for prepare to be on a separate line.

Here’s how you do it the right way:

$query = $wpdb->prepare( "SELECT ID from {$wpdb->posts} WHERE ID = %d", $value );

One line. Simple, easy to read, and not confusing.

A letter to Canadians from the Honourable Jack Layton

And finally, to all Canadians: Canada is a great country, one of the hopes of the world. We can be a better one – a country of greater equality, justice, and opportunity. We can build a prosperous economy and a society that shares its benefits more fairly. We can look after our seniors. We can offer better futures for our children. We can do our part to save the world’s environment. We can restore our good name in the world. We can do all of these things because we finally have a party system at the national level where there are real choices; where your vote matters; where working for change can actually bring about change. In the months and years to come, New Democrats will put a compelling new alternative to you. My colleagues in our party are an impressive, committed team. Give them a careful hearing; consider the alternatives; and consider that we can be a better, fairer, more equal country by working together. Don’t let them tell you it can’t be done.

My friends, love is better than anger. Hope is better than fear. Optimism is better than despair. So let us be loving, hopeful and optimistic. And we’ll change the world.

Even at his weakest, Jack could still inspire us to be our strongest. Sir, you will be missed.

Read the full letter | See Jack at his best best: happy | Six ways Jack Layton helped build Toronto

WordPress Distraction-Free Skin: Terminal/Matrix

Just Write! Like you're in the Matrix!

Because all the cool kids want to feel like they’re writing posts in the Matrix. (Inspired by Zen)


View on Github