Slide 1

Slide 1 text

Behind the scenes Demystifying The black box of WordPress Core

Slide 2

Slide 2 text

Evan Solomon Growth Engineer @ Automattic

Slide 3

Slide 3 text

“Core” n. The hard or fibrous central part of certain fruits, such as the apple or pear, containing the seeds.

Slide 4

Slide 4 text

“Core” n. The hard or fibrous central part of certain fruits, such as the apple or pear, containing the seeds. n. Those files you can download from WordPress.org.

Slide 5

Slide 5 text

Don’t hack core != Don’t read core

Slide 6

Slide 6 text

Reading Core != Here Be Dragons

Slide 7

Slide 7 text

If you are reading this document in earnest, you should be comfortable reading documentation in code. So I won’t bother to copy and paste it here where it has little hope of staying current. ANDY SKELTON, AUTOMATTIC FIELD GUIDE

Slide 8

Slide 8 text

1. Startup

Slide 9

Slide 9 text

2. Files

Slide 10

Slide 10 text

3. Tools

Slide 11

Slide 11 text

4. Hooks

Slide 12

Slide 12 text

5. Use it

Slide 13

Slide 13 text

Startup /** * Front to the WordPress application. * This file doesn't do anything, but loads * wp-blog-header.php which does and * tells WordPress to load the theme. * * @package WordPress */

Slide 14

Slide 14 text

index.php Everything starts here

Slide 15

Slide 15 text

index.php Everything starts here wp-blog-header.php Load WP environment

Slide 16

Slide 16 text

index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress bootstrap

Slide 17

Slide 17 text

index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress bootstrap wp-settings.php Load /wp-includes

Slide 18

Slide 18 text

index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress bootstrap wp-settings.php Load /wp-includes Parse the request

Slide 19

Slide 19 text

index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress bootstrap wp-settings.php Load /wp-includes Parse the request template-loader.php Load theme template

Slide 20

Slide 20 text

It’s impossible to know what WordPress is really doing without understanding this

Slide 21

Slide 21 text

File structure -rw-r--r-- index.php -rw-r--r-- license.txt -rw-r--r-- readme.html -rw-r--r-- wp-activate.php drwxr-xr-x wp-admin -rw-r--r-- wp-app.php -rw-r--r-- wp-blog-header.php -rw-r--r-- wp-comments-post.php -rw-r--r-- wp-config-sample.php drwxr-xr-x wp-content -rw-r--r-- wp-cron.php drwxr-xr-x wp-includes -rw-r--r-- wp-links-opml.php -rw-r--r-- wp-load.php -rw-r--r-- wp-login.php -rw-r--r-- wp-mail.php -rw-r--r-- wp-settings.php -rw-r--r-- wp-signup.php -rw-r--r-- wp-trackback.php -rw-r--r-- xmlrpc.php $ ls -l | awk '{print $1"\t"$9}'

Slide 22

Slide 22 text

File structure -rw-r--r-- index.php -rw-r--r-- license.txt -rw-r--r-- readme.html -rw-r--r-- wp-activate.php drwxr-xr-x wp-admin -rw-r--r-- wp-app.php -rw-r--r-- wp-blog-header.php -rw-r--r-- wp-comments-post.php -rw-r--r-- wp-config-sample.php drwxr-xr-x wp-content -rw-r--r-- wp-cron.php drwxr-xr-x wp-includes -rw-r--r-- wp-links-opml.php -rw-r--r-- wp-load.php -rw-r--r-- wp-login.php -rw-r--r-- wp-mail.php -rw-r--r-- wp-settings.php -rw-r--r-- wp-signup.php -rw-r--r-- wp-trackback.php -rw-r--r-- xmlrpc.php $ ls -l | awk '{print $1"\t"$9}'

Slide 23

Slide 23 text

/wp-admin Mostly page/file relationships that make the wp-admin UI /wp-includes Mostly discrete functionality not meant to be accessed directly

Slide 24

Slide 24 text

$ ls wp-includes SimplePie Text admin-bar.php atomlib.php author-template.php bookmark-template.php bookmark.php cache.php canonical.php capabilities.php category-template.php category.php class-feed.php class-http.php class-IXR.php class-json.php class-oembed.php class-phpass.php class-phpmailer.php class-pop3.php class-simplepie.php class-smtp.php class-snoopy.php class-wp-admin-bar.php class-wp-ajax-response.php class-wp-customize- control.php class-wp-customize-manager.php class-wp-customize-section.php class-wp-customize-setting.php class-wp-editor.php class-wp-embed.php class-wp-error.php class-wp-http-ixr-client.php class-wp-theme.php class-wp-walker.php class-wp-xmlrpc-server.php class-wp.php class.wp-dependencies.php class.wp-scripts.php class.wp-styles.php comment-template.php comment.php compat.php cron.php css default-constants.php default-filters.php default-widgets.php deprecated.php feed-atom-comments.php feed-atom.php feed-rdf.php feed-rss.php feed-rss2-comments.php feed-rss2.php feed.php formatting.php functions.php functions.wp-scripts.php functions.wp-styles.php general-template.php http.php images js kses.php l10n.php link-template.php load.php locale.php media.php meta.php ms-blogs.php ms-default-constants.php ms-default-filters.php ms-deprecated.php ms-files.php ms-functions.php ms-load.php ms-settings.php nav-menu-template.php nav-menu.php option.php pluggable-deprecated.php pluggable.php plugin.php pomo post-template.php post-thumbnail-template.php post.php query.php registration-functions.php registration.php rewrite.php rss-functions.php rss.php script-loader.php shortcodes.php taxonomy.php template-loader.php template.php theme-compat theme.php update.php user.php vars.php version.php widgets.php wlwmanifest.xml wp-db.php wp-diff.php

Slide 25

Slide 25 text

Help! We need tools

Slide 26

Slide 26 text

GUI & CLI Tools

Slide 27

Slide 27 text

Debug Bar And friends

Slide 28

Slide 28 text

Debug Bar Console

Slide 29

Slide 29 text

Debug Bar Extender

Slide 30

Slide 30 text

Debug Bar Cron

Slide 31

Slide 31 text

die(); var_dump(); error_log();

Slide 32

Slide 32 text

something(); // Make sure this code actually runs die(); thing_i_care_about();

Slide 33

Slide 33 text

$ ack betterthangrep.com

Slide 34

Slide 34 text

I had to invent integral and differential calculus to figure it out. ISSAC NEWTON, ON ELLIPTICAL ORBITS

Slide 35

Slide 35 text

$ fx $ action $ filter gist.github.com/3568555

Slide 36

Slide 36 text

$ fx get_user_by Magically opens the function definition wp-inclues/pluggable.php:135

Slide 37

Slide 37 text

A quick review of actions & filters

Slide 38

Slide 38 text

action An alert that something just happened or is about to happen filter A similar alert, with the added responsibility to manipulate data

Slide 39

Slide 39 text

function es_alert_me() { send_the_alert( 'evan' ); } add_action( 'sound_the_alarm', 'es_alert_me' ); /** * Some other code runs... */ do_action( 'sound_the_alarm' ); // es_alert_me() runs add_action()

Slide 40

Slide 40 text

// Always turn sirens to bells function es_set_alert( $alert ) { return ( 'bell' == $alert ) ? 'siren' : $alert; } add_filter( 'alert_type', 'es_set_alert' ); /** * Some other code runs... */ $alert = 'bell'; $alert = apply_filters( 'alert_type', $alert ); // Now $alert is 'siren' add_filter()

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

function add_action( /* arguments */ ) { return add_filter( /* same arguments */ ); } wp-includes/plugin.php

Slide 43

Slide 43 text

Use it!

Slide 44

Slide 44 text

Links are boring

Slide 45

Slide 45 text

I like oEmbed, I wish it worked in my comments, too. ME, SOME TIME IN AUGUST

Slide 46

Slide 46 text

Maybe comments get filtered. $ ack apply_filters wp-includes/ | ack comment

Slide 47

Slide 47 text

Maybe comments get filtered. $ ack apply_filters wp-includes/ | ack comment TOO. Many. Results. 140!

Slide 48

Slide 48 text

How does TwentyEleven use comments?

Comment!

Slide 49

Slide 49 text

Where does that come from? $ ack comment-content wp-content/ themes/twentyeleven --php wp-content/themes/twentyeleven/functions.php 562:

Slide 50

Slide 50 text

Where does that come from? $ ack comment-content wp-content/ themes/twentyeleven --php wp-content/themes/twentyeleven/functions.php 562:

Slide 51

Slide 51 text

This function looks promising $ fx comment_text function comment_text( $comment_ID = 0 ) { $comment = get_comment( $comment_ID ); echo apply_filters( 'comment_text', get_comment_text( $comment_ID ), $comment ); }

Slide 52

Slide 52 text

This function looks promising $ fx comment_text function comment_text( $comment_ID = 0 ) { $comment = get_comment( $comment_ID ); echo apply_filters( 'comment_text', get_comment_text( $comment_ID ), $comment ); }

Slide 53

Slide 53 text

I bet this changes comments function es_comment_text( $comment_text ) { return $comment_text . 'I SHOULD SEE THIS'; } add_filter( 'comment_text', 'es_comment_text' );

Slide 54

Slide 54 text

I bet this changes comments function es_comment_text( $comment_text ) { return $comment_text . 'I SHOULD SEE THIS'; } add_filter( 'comment_text', 'es_comment_text' ); Fatal error!

Slide 55

Slide 55 text

Let’s see why it breaks function es_comment_text( $comment_text ) { error_log( var_export( $comment_text, true ) ); return $comment_text; } add_filter( 'comment_text', 'es_comment_text' );

Slide 56

Slide 56 text

Let’s see why it breaks function es_comment_text( $comment_text ) { error_log( var_export( $comment_text, true ) ); return $comment_text; } add_filter( 'comment_text', 'es_comment_text' ); array ( 0 => 'comment text here...', )

Slide 57

Slide 57 text

Use the array function es_comment_text( $comment_text ) { $comment_text[ 0 ] += " I SHOULD SEE THIS"; return $comment_text; } add_filter( 'comment_text', 'es_comment_text' );

Slide 58

Slide 58 text

Use the array function es_comment_text( $comment_text ) { $comment_text[ 0 ] += " I SHOULD SEE THIS"; return $comment_text; } add_filter( 'comment_text', 'es_comment_text' ); It works!

Slide 59

Slide 59 text

There’s probably an oEmbed filter $ ack add_filter wp-includes/ | ack oembed wp-includes/class-oembed.php:54: add_filter( 'oembed_dataparse', array(&$this, '_strip_newlines'), 10, 3 ); wp-includes/media.php:1058: add_filter( 'the_content', array(&$this, 'autoembed'), 8 );

Slide 60

Slide 60 text

Test the simplest usage first add_filter( 'comment_text', array( $wp_embed, 'autoembed' ) );

Slide 61

Slide 61 text

Test the simplest usage first add_filter( 'comment_text', array( $wp_embed, 'autoembed' ) ); Nope, just a link

Slide 62

Slide 62 text

I know what makes automatic links $ ack add_filter wp-includes/ | ack comment_text | ack make_clickable wp-includes/default-filters.php: 151: add_filter( 'comment_text', 'make_clickable', 9 );

Slide 63

Slide 63 text

Try going earlier add_filter( 'comment_text', array( $wp_embed, 'autoembed' ), 8 ); It works!

Slide 64

Slide 64 text

Videos are cool

Slide 65

Slide 65 text

Finished Plugin wordpress.org/extend/plugins/ oembed-in-comments/ github.com/evansolomon/ wp-oembed-in-comments &

Slide 66

Slide 66 text

class ES_oEmbed_Comments { function __construct() { add_action( 'init', array( $this, 'init' ) ); } function init() { if ( ! is_admin() ) $this->oembed_in_comments(); } function oembed_in_comments() { $clickable = has_filter( 'comment_text', 'make_clickable' ); $priority = ( $clickable ) ? $clickable - 1 : 10; add_filter( 'comment_text', array( $this, 'oembed_filter' ), $priority ); } function oembed_filter( $comment_text ) { global $wp_embed; add_filter( 'embed_oembed_discover', '__return_false', 999 ); $comment_text = $wp_embed->autoembed( $comment_text ); remove_filter( 'embed_oembed_discover', '__return_false', 999 ); return $comment_text; } } new ES_oEmbed_Comments; Finished Plugin