1. Core Concepts
WordPress organizes content around a few core ideas that everything else — themes, plugins, the block editor — builds on top of:
- Posts — chronological content (blog entries), but also the underlying storage mechanism for nearly everything else via Custom Post Types (Week 19)
- Pages — non-chronological content (About, Contact) — structurally a post with a different
post_type - Themes — control how content is presented: templates, styles, layout
- Plugins — extend or change behavior without modifying WordPress core or the active theme
- The admin (
/wp-admin) — the back-office UI for managing all of the above
A crucial distinction worth internalizing now: WordPress itself, every theme, and every plugin are all just PHP files following WordPress's conventions — there's no hard boundary at the language level, only a strong convention that themes handle presentation and plugins handle behavior, kept separate so either can be swapped independently.
2. Local Setup
WordPress needs PHP, MySQL and a web server — the same LAMP-style stack from Module 1, just running someone else's (very large) PHP application instead of your own. Local (by WP Engine) is the fastest way to get a working environment without manually configuring each piece:
# Download WordPress core
curl -O https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
cd wordpress
php -S localhost:8000
# Then visit http://localhost:8000 and follow the famous "5-minute install"
Either way, you'll end up with a wp-config.php holding database
credentials (the same pattern as Week 9's Laravel .env, just an older
convention — plain PHP constants instead of an environment file) and a running
MySQL database WordPress manages the schema for automatically.
3. wp-cli
wp-cli is WordPress's official command-line tool — for anything
beyond trivial changes, it's dramatically faster than clicking through
/wp-admin:
# Install (one-time, per machine)
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
# Run from inside a WordPress installation directory
wp core version
wp plugin list
wp theme activate twentytwentyfour
wp post create --post_title="Hello from wp-cli" --post_status=publish
wp user create ada ada@example.com --role=administrator
wp db export backup.sql
wp-cli becomes essential from Week 20 onward — scaffolding plugins,
running database operations during development, and scripting repetitive setup
tasks are all faster and more reliable through it than through the admin UI.
4. The wp_ Database Schema
WordPress creates around a dozen tables by default, all prefixed wp_
(configurable, and changing it from the default is a common security
recommendation covered in Week 24). The core ones:
wp_posts— every post, page, and (viapost_type) every custom post type row, all in one tablewp_postmeta— arbitrary key/value metadata attached to posts (a classic Entity-Attribute-Value pattern — flexible, but not normalized the way Week 6 would design it from scratch)wp_users&wp_usermeta— the same posts/postmeta pattern, for userswp_terms,wp_term_taxonomy,wp_term_relationships— categories, tags & custom taxonomies (Week 19)wp_options— sitewide settings, one row per named option
wp db query "SELECT ID, post_title, post_type, post_status FROM wp_posts LIMIT 10"
wp db query "SELECT meta_key, meta_value FROM wp_postmeta WHERE post_id = 1"
wp_ tables directly in real code
WordPress provides a full API — WP_Query, get_post_meta(), update_option() — for every operation on these tables, and it handles caching, hooks, and edge cases raw SQL wouldn't. Direct queries here are for exploration and understanding only; Weeks 18–21 use the proper API throughout.
5. WordPress vs. Laravel: What Actually Changes
Coming straight from Module 2, a few mental adjustments matter:
- No MVC structure to lean on — WordPress's organization is theme templates + hooks, not controllers and routes
- No Eloquent — data access goes through WordPress's own functions (
WP_Query,get_posts()) over the schema above - No Composer-first culture at the WordPress-core level, though it's increasingly used for custom theme/plugin dependencies (as you'll do starting Week 18)
- Global functions and globals (
$post,$wpdb) are idiomatic here, where Module 2 avoided them deliberately
None of this makes WordPress "worse" than Laravel — it's optimized for a different problem: non-developers managing content through an admin UI, with theme/plugin code providing structure and extension points around that. The next four weeks build fluency in that model specifically.
6. Hands-on Exercise
Set up local WordPress and explore its schema with wp-cli
Get a working install running, then look under the hood at exactly what it stores.
Requirements:
- Install WordPress locally (Local, or the manual
php -Sroute) and complete setup, creating an admin account. - Install wp-cli and confirm
wp core versionworks from inside the install directory. - Use
wp post createto create 5 posts and 2 pages from the command line. - Use
wp db queryto run aSELECTagainstwp_postsconfirming your 7 new rows exist, with the correctpost_typedistinguishing posts from pages. - Add post meta to one post with
wp post meta add <id> my_key "my value", then querywp_postmetadirectly to see how it's stored.
Run wp help post create and wp help post meta to see every available flag — wp-cli's built-in help is thorough and faster to check than searching documentation for most day-to-day tasks.
7. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
Structurally, what's the actual difference between a WordPress "post" and a "page"?
Structurally, what's the actual difference between a WordPress "post" and a "page"?
Almost nothing at the database level — both live in the same wp_posts table, and a "page" is simply a row where post_type = 'page' instead of 'post'. The practical difference is presentational and organizational convention: posts are chronological/categorized content, pages are standalone, but WordPress's underlying storage treats them as the same kind of thing.
Q2
Why is wp_postmeta described as an Entity-Attribute-Value pattern rather than a normalized table the way Week 6 would design one?
Why is wp_postmeta described as an Entity-Attribute-Value pattern rather than a normalized table the way Week 6 would design one?
Instead of dedicated typed columns for each piece of metadata, wp_postmeta stores arbitrary key/value pairs as rows — (post_id, meta_key, meta_value) — letting any post carry any number of arbitrary fields without a schema change. This is far more flexible than fixed columns (any plugin can attach its own metadata to any post without altering the table), at the cost of losing type safety and the kind of query performance a properly normalized, purpose-built schema would offer.
Q3
Why does this lesson warn against querying wp_ tables directly in real plugin or theme code?
Why does this lesson warn against querying wp_ tables directly in real plugin or theme code?
WordPress's built-in APIs (WP_Query, get_post_meta(), and similar) handle caching, fire the hooks other plugins may depend on, and correctly account for schema details and edge cases that change across WordPress versions. Querying the tables directly bypasses all of that — it might work today, but it can silently break with a core update or conflict with how another plugin expects to interact with the same data.
Q4
What's the WordPress-side equivalent of the separation Laravel enforces between "controllers" and "views"?
What's the WordPress-side equivalent of the separation Laravel enforces between "controllers" and "views"?
There isn't a strict equivalent — WordPress has no built-in MVC layer. The nearest analogous separation is convention-based: themes are responsible for presentation (their template files play a role similar to Blade views), while plugins are responsible for behavior and data (closer to a controller's job), coordinated through hooks rather than routes. It's a looser, more convention-driven boundary than Laravel's explicit framework structure.