Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Demystifying the Black Box of WordPress Core
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
Azure Serverless 2026:Production-ready な AI エージェント基盤 / Azure Serverless 2026: Production-Ready AI Agent Platform
miyake
2
570
Vibe Coding で作ったプロダクトをどう安全に動かすか / How to Safely Run Products Built with Vibe Coding
glidenote
0
540
AIエージェントを最高のパートナーに育てる方法|評価と判断軸を育てる5つのステップ
koichiaoki
1
160
beyond jj: config & tools ecosystem
indirect
0
5.9k
リアーキテクチャ後の障害ゼロを目指したShadow Testingの取り組み
nihonbuson
PRO
1
180
10Xに技術的負債をもたらした「2つの境界の歪み」その構造と解消への営み
10xinc
0
2.4k
サーバーレスをどこまで使う? WebRTC対戦ゲームで選んだVPSとの共存設計
kaidouji85
0
390
地方移住と都心キャリアの両立は「金・時間・人」のリソースをフル活用すれば実現できる!〜Snowflake女子会 vol.8
snowwmn0824
0
110
アクセスキーこわい やめかたと漏らさない工夫
sassssan68
1
700
GoのInterface内部構造から学ぶ!最高パフォーマンスを出すコード設計
yappli_developers
1
270
Genieを崇めよ
kameitomohiro
0
170
人にやさしく、AIにやさしく、書き手を選ばないIaCのガードレール再考 / Rethinking IaC Guardrails for Humans and AI Alike
kohbis
2
430
Featured
See All Featured
Navigating Weather and Climate Data
rabernat
0
530
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
390
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
550
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
410
Claude Code のすすめ
schroneko
67
230k
Designing for humans not robots
tammielis
254
26k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
580
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Side Projects
sachag
456
43k
Are puppies a ranking factor?
jonoalderson
2
3.9k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
510
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