What is WordPress?
WordPress is an open-source Content Management System (CMS) based on PHP and MySQL/MariaDB. Powering over 40% of the web, it has evolved from a simple blogging engine into a highly extensible, enterprise-grade application framework featuring robust plugin/theme ecosystems and modern block-based site building capabilities.
Core Directory Structure
- A standard WordPress installation separates administration, configuration, and user assets:
File Layout
├── wp-admin/ # Admin dashboard backend core files
├── wp-includes/ # Core libraries, helper functions, and classes
├── wp-content/ # User-space directory (safest place to modify)
│ ├── themes/ # Custom and active themes
│ ├── plugins/ # Custom and active plugins
│ └── uploads/ # Media library items (organized by year/month)
├── wp-config.php # Database configuration, salts, and debug settings
├── .htaccess # Apache server configuration (permalink routing rules)
└── index.php # Main entry point that loads the WordPress core
Database Schema
- WordPress uses a simple relational database structure consisting of 12 core tables by default:
Core Table Functions
| Table Name | Purpose | Key Columns / Relations |
|---|---|---|
wp_posts | Stores post types (posts, pages, attachments, menu items, revisions). | ID, post_title, post_content, post_type, post_status |
wp_postmeta | Metadata store (EAV pattern) containing custom fields for posts. | meta_id, post_id (FK), meta_key, meta_value |
wp_options | Site-wide configuration settings and transients. | option_id, option_name, option_value, autoload |
wp_users | Registered users data. | ID, user_login, user_pass (hashed), user_email |
wp_usermeta | Metadata associated with users (capabilities, preferences). | meta_id, user_id (FK), meta_key, meta_value |
wp_terms | Classification descriptors (categories, tags, custom taxonomies). | term_id, name, slug |
wp_term_taxonomy | Groups terms into taxonomies (e.g., term #1 is a ‘category’). | term_taxonomy_id, term_id (FK), taxonomy |
wp_term_relationships | Resolves many-to-many links between posts and terms. | object_id (Post ID), term_taxonomy_id (FK) |
wp_comments | Comment list, approvals, and pingbacks. | comment_ID, comment_post_ID (FK), comment_author |
wp_commentmeta | Metadata associated with comments. | meta_id, comment_id (FK), meta_key, meta_value |
The Hooks System (Actions vs Filters)
- Hooks are the core mechanism of WordPress extensibility, allowing developers to execute code or modify data without modifying core files.
Key Concepts
- Actions: Triggered at specific points in the execution cycle. Used to perform tasks (e.g., sending emails, registering custom sidebars, or enqueuing styles).
- Filters: Triggered to process data before it is rendered, saved to the database, or returned. Always receive data as an argument and must return modified data.
Hooks Execution Cycle
graph TD A[WordPress Bootstraps] --> B(do_action 'init') B --> C(do_action 'wp_enqueue_scripts') C --> D[Run Queries / Load Template] D --> E{apply_filters 'the_content'} E --> F[Render output to Client]
Actions & Filters Syntax
// 1. ACTION EXAMPLE
// Trigger custom script/style loading
function my_theme_assets() {
wp_enqueue_style( 'my-style', get_stylesheet_uri() );
}
add_action( 'wp_enqueue_scripts', 'my_theme_assets', 10 );
// 2. FILTER EXAMPLE
// Append custom text to all post content
function my_custom_content_footer( $content ) {
if ( is_single() ) {
$content .= '<p class="content-sig">Thanks for reading!</p>';
}
return $content; // Filters MUST return the input data
}
add_filter( 'the_content', 'my_custom_content_footer', 15 );Template Hierarchy & The Loop
Hierarchy Flow
- When a page is requested, WordPress traverses a fallback hierarchy to find the appropriate template file:
- Single Post (
post):single-post.php➔single.php➔singular.php➔index.php - Static Page (
page):page-{slug}.php➔page-{id}.php➔page.php➔singular.php➔index.php - Archive (Category):
category-{slug}.php➔category-{id}.php➔category.php➔archive.php➔index.php
The WordPress Loop
- The fundamental logic blocks used to fetch and display posts:
// The standard global loop
if ( have_posts() ) {
while ( have_posts() ) {
the_post(); // Hydrates the global $post object and sets up template tags
echo '<h2>' . get_the_title() . '</h2>';
the_content();
}
} else {
echo '<p>No content found.</p>';
}Custom Query (WP_Query)
- For fetching custom data outside the main global query:
$args = array(
'post_type' => 'product',
'posts_per_page' => 5,
'meta_key' => 'featured',
'meta_value' => 'yes'
);
$custom_query = new WP_Query( $args );
if ( $custom_query->have_posts() ) {
while ( $custom_query->have_posts() ) {
$custom_query->the_post();
the_title( '<h3>', '</h3>' );
}
wp_reset_postdata(); // Restores global $post object to original main query
}Theme Development
- A minimal theme requires only two files:
style.css(metadata declaration) andindex.php(rendering logic).
style.css Header
/*
Theme Name: Developer Reference Theme
Theme URI: https://example.com/ref-theme
Author: Vaibhav Rathod
Description: A minimal, high-performance base theme for developer notes.
Version: 1.0.0
License: GNU General Public License v2 or later
Text Domain: dev-ref-theme
*/functions.php Setup
- Used to configure theme support, menus, and assets:
<?php
function dev_theme_setup() {
// Add support for document title tag (handled by WP)
add_theme_support( 'title-tag' );
// Add support for post thumbnails (featured images)
add_theme_support( 'post-thumbnails' );
// Register navigation menus
register_nav_menus( array(
'primary-menu' => esc_html__( 'Primary Navigation Menu', 'dev-ref-theme' ),
) );
}
add_action( 'after_setup_theme', 'dev_theme_setup' );
// Enqueue styles and scripts correctly
function dev_theme_scripts() {
wp_enqueue_style( 'main-style', get_stylesheet_uri() );
wp_enqueue_script( 'main-js', get_template_directory_uri() . '/js/main.js', array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'dev_theme_scripts' );Plugin Development & Security
Starter Plugin Header
- Place this in a file named
wp-content/plugins/my-plugin/my-plugin.php:
<?php
/*
Plugin Name: Developer Reference Core Plugin
Plugin URI: https://example.com/ref-plugin
Description: Core custom functionalities, custom post types, and security filters.
Version: 1.0.0
Author: Vaibhav Rathod
License: GPL2
Text Domain: dev-ref-plugin
*/
// Prevent direct file access (Crucial Security Check)
if ( ! defined( 'ABSPATH' ) ) {
exit;
}Data Sanitization & Escaping
- Always assume client inputs are untrusted and output targets must be clean to prevent XSS:
// 1. Sanitizing incoming inputs
$username = sanitize_text_field( $_POST['username'] );
$user_email = sanitize_email( $_POST['email'] );
// 2. Escaping output variables
echo '<h3>' . esc_html( $username ) . '</h3>';
echo '<a href="' . esc_url( $profile_url ) . '">View Profile</a>';
echo '<input type="text" name="city" value="' . esc_attr( $city ) . '">';Database Access ($wpdb)
- For database mutations, always use
$wpdb->prepareto prevent SQL Injection:
global $wpdb;
$table_name = $wpdb->prefix . 'custom_table';
$user_status = 'active';
$user_id = 45;
// Prepare ensures SQL is fully parameterized and clean
$query = $wpdb->prepare(
"UPDATE $table_name SET status = %s WHERE id = %d",
$user_status,
$user_id
);
$wpdb->query( $query );Modern Block Development (Gutenberg)
- Modern WordPress uses Block Themes (Full Site Editing) relying on JSON configuration and HTML templates containing block markup rather than raw PHP.
theme.json Structure
- Defines color palettes, typography, and default layout widths:
{
"version": 2,
"settings": {
"color": {
"palette": [
{
"name": "Primary",
"slug": "primary",
"color": "#3858e9"
},
{
"name": "Light",
"slug": "light",
"color": "#f8f9fa"
}
]
},
"layout": {
"contentSize": "800px",
"wideSize": "1200px"
}
}
}Advanced Performance Optimization
The Transients API
- Used to store parsed/complex data in the database with an expiration time, preventing expensive API calls or database calculations:
// Fetch data, caching it for 1 hour
function get_featured_products_count() {
$cache_key = 'featured_products_count';
$count = get_transient( $cache_key );
if ( false === $count ) {
// Transient expired or doesn't exist, calculate value
global $wpdb;
$count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = 'publish'" );
// Save for 1 hour (3600 seconds)
set_transient( $cache_key, $count, HOUR_IN_SECONDS );
}
return $count;
}
// Clear transient on product publish
add_action( 'publish_product', function() {
delete_transient( 'featured_products_count' );
});Caching Types
- Page Cache: Saves the generated HTML output of a webpage. Subsequent visitors receive the static HTML page directly without running PHP or MySQL. Handled via plugins (W3 Total Cache, WP Rocket).
- Object Cache: Caches individual database query results or computation objects in memory (using Redis or Memcached). Prevents repetitive SQL queries during a single session.