Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Demystifying the Black Box of WordPress Core
Search
Evan Solomon
October 13, 2012
Technology
3.5k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Demystifying the Black Box of WordPress Core
Evan Solomon
October 13, 2012
More Decks by Evan Solomon
See All by Evan Solomon
JavaScript Beyond jQuery
evansolomon
1
530
WordCamp Las Vegas -- Make stuff that people want
evansolomon
2
2.9k
You Have No Idea What Your Users Want
evansolomon
1
530
You Don't Know People
evansolomon
2
860
Other Decks in Technology
See All in Technology
カートの信頼性を担保するWireMockを使ったe2eテスト
ykagano
0
270
『三匹の子ぶた』から学ぶネットワークセキュリティの昔と今 / Network Security: Then and Now Through the Lens of The Three Little Pigs
nttcom
1
4.1k
その“隠したつもり”が命取り ── 自前と平文をやめて「正解」に委ねる
kuroneko13
0
120
Agent 時代の Kaggle 展望 / kaggle-in-the-agentic-era
upura
1
720
LLM・AIエージェントシステムベストプラクティス
shibuiwilliam
6
1.2k
TypeScript入門 2026
recruitengineers
PRO
3
580
FPGAが実現する遠方宇宙の高空間分解能天体撮影 -大型地上望遠鏡の視力を補正する「補償光学」とは?-
komei_mt
0
240
Software Supply Chain Attackからクラウド環境を守るためにできること
lhazy
2
260
AIペネトレーションテスト・ セキュリティ検証「AgenticSec」紹介資料
laysakura
2
9k
Bill One 開発エンジニア 紹介資料
sansan33
PRO
7
19k
20分でわかるセキュアAPI
nwiizo
2
270
関東Kaggler会発表資料
takoi
1
230
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
470
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Marketing to machines
jonoalderson
1
5.7k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
ラッコキーワード サービス紹介資料
rakko
1
4.3M
Raft: Consensus for Rubyists
vanstee
141
7.6k
A better future with KSS
kneath
240
18k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
BBQ
matthewcrist
89
10k
We Are The Robots
honzajavorek
0
300
Transcript
Behind the scenes Demystifying The black box of WordPress Core
Evan Solomon Growth Engineer @ Automattic
“Core” n. The hard or fibrous central part of certain
fruits, such as the apple or pear, containing the seeds.
“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.
Don’t hack core != Don’t read core
Reading Core != Here Be Dragons
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
1. Startup
2. Files
3. Tools
4. Hooks
5. Use it
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 */
index.php Everything starts here
index.php Everything starts here wp-blog-header.php Load WP environment
index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress
bootstrap
index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress
bootstrap wp-settings.php Load /wp-includes
index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress
bootstrap wp-settings.php Load /wp-includes <?php wp(); ?> Parse the request
index.php Everything starts here wp-blog-header.php Load WP environment wp-load.php WordPress
bootstrap wp-settings.php Load /wp-includes <?php wp(); ?> Parse the request template-loader.php Load theme template
It’s impossible to know what WordPress is really doing without
understanding this
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}'
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}'
/wp-admin Mostly page/file relationships that make the wp-admin UI /wp-includes
Mostly discrete functionality not meant to be accessed directly
$ 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
Help! We need tools
GUI & CLI Tools
Debug Bar And friends
Debug Bar Console
Debug Bar Extender
Debug Bar Cron
die(); var_dump(); error_log();
something(); // Make sure this code actually runs die(); thing_i_care_about();
$ ack betterthangrep.com
I had to invent integral and differential calculus to figure
it out. ISSAC NEWTON, ON ELLIPTICAL ORBITS
$ fx $ action $ filter gist.github.com/3568555
$ fx get_user_by Magically opens the function definition wp-inclues/pluggable.php:135
A quick review of actions & filters
action An alert that something just happened or is about
to happen filter A similar alert, with the added responsibility to manipulate data
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()
// 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()
None
function add_action( /* arguments */ ) { return add_filter( /*
same arguments */ ); } wp-includes/plugin.php
Use it!
Links are boring
I like oEmbed, I wish it worked in my comments,
too. ME, SOME TIME IN AUGUST
Maybe comments get filtered. $ ack apply_filters wp-includes/ | ack
comment
Maybe comments get filtered. $ ack apply_filters wp-includes/ | ack
comment TOO. Many. Results. 140!
How does TwentyEleven use comments? <div class="comment-content"> <p>Comment!</p> </div>
Where does that come from? $ ack comment-content wp-content/ themes/twentyeleven
--php wp-content/themes/twentyeleven/functions.php 562: <div class="comment-content"><?php comment_text(); ?></div>
Where does that come from? $ ack comment-content wp-content/ themes/twentyeleven
--php wp-content/themes/twentyeleven/functions.php 562: <div class="comment-content"><?php comment_text(); ?></div>
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 ); }
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 ); }
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' );
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!
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' );
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...', )
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' );
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!
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 );
Test the simplest usage first add_filter( 'comment_text', array( $wp_embed, 'autoembed'
) );
Test the simplest usage first add_filter( 'comment_text', array( $wp_embed, 'autoembed'
) ); Nope, just a link
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 );
Try going earlier add_filter( 'comment_text', array( $wp_embed, 'autoembed' ), 8
); It works!
Videos are cool
Finished Plugin wordpress.org/extend/plugins/ oembed-in-comments/ github.com/evansolomon/ wp-oembed-in-comments &
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