Q: What’s the main WordPress folder structure?
A: wp-admin, wp-content, wp-includes, plus root files like wp-config.php.
The main WordPress folder structure is organized into three primary directories and several root files, each with specific roles:
wp-admin: Contains all files for the admin dashboard, including admin-ajax.php (AJAX handling), admin.php (core admin logic), and subfolders like css, js, and images for admin styling and scripts.
wp-content: Houses user-customizable content, with subfolders:
- themes (stores theme files like twentytwentythree),
- plugins (holds plugin files like hello-dolly),
- uploads (media files, organized by year/month, e.g., 2025/02),
- and optional mu-plugins (must-use plugins).
wp-includes: Includes core WordPress PHP files and libraries, such as class-wp-query.php (query handling), functions.php (general functions), and subfolders like js and css for front-end assets.
Root Files: Key files in the WordPress root include wp-config.php (database settings, salts), index.php (entry point loading core), wp-blog-header.php (initializes environment), wp-settings.php (sets up WordPress), and wp-load.php (bootstraps for external scripts).
This structure separates core functionality, admin tools, and user content, enabling customization while protecting the system.
Q: What does wp-config.php configure?
A: Database connection, salts, debug settings.
The wp-config.php file configures essential WordPress settings, primarily:
Database Connection: Defines database credentials—DB_NAME (database name), DB_USER (username), DB_PASSWORD (password), DB_HOST (host, e.g., localhost), and DB_CHARSET (character set, e.g., utf8).
Authentication Salts: Sets unique keys and salts (e.g., AUTH_KEY, SECURE_AUTH_SALT) to secure cookies and passwords.
Table Prefix: Specifies the database table prefix via $table_prefix (default wp_) for multiple installations or security.
Debugging: Enables debugging with WP_DEBUG (e.g., define(‘WP_DEBUG’, true)), plus WP_DEBUG_LOG and WP_DEBUG_DISPLAY for logging and display options.
Other Settings: Can override memory limits (WP_MEMORY_LIMIT), disable auto-updates (define(‘AUTOMATIC_UPDATER_DISABLED’, true)), or set site URLs (WP_HOME, WP_SITEURL).
Located in the WordPress root, it’s a critical, editable file that doesn’t ship with defaults—generated during installation or manually created.
Q: What’s the role of index.php in the root?
A: Entry point—loads WordPress core.
The index.php file in the WordPress root serves as the primary entry point for all front-end requests, initiating the WordPress loading process. It contains minimal code—typically just a few lines—that kickstarts the system:
It defines the WP_USE_THEMES constant as true to enable theme usage.
It includes wp-blog-header.php via a require statement (e.g., require __DIR__ . ‘/wp-blog-header.php’;), which then loads the core WordPress environment, including wp-load.php, wp-settings.php, and the template loader.
This triggers the entire WordPress bootstrap: database connection, core functions, plugins, themes, and finally, rendering the requested page (e.g., via The Loop).
As the default file for web servers (e.g., Apache, Nginx), it handles all URL requests (e.g., example.com/ or example.com/about) by routing them through WordPress’s rewrite system.
In essence, index.php acts as the gateway, delegating to other files to process and display content, making it indispensable for WordPress’s operation.
Q: What’s wp-content?
A: Stores themes, plugins, uploads.
The wp-content directory in WordPress is the central hub for all user-generated and customizable content, located in the root folder (e.g., /wp-content). It’s where WordPress stores:
themes: Subdirectory (wp-content/themes) containing theme folders (e.g., twentytwentythree), each with files like style.css, index.php, and functions.php for site appearance and functionality.
plugins: Subdirectory (wp-content/plugins) holding plugin folders (e.g., hello-dolly), each with PHP files (e.g., hello-dolly.php) to extend WordPress features.
uploads: Subdirectory (wp-content/uploads) storing media files (e.g., images, PDFs), organized by year and month (e.g., 2025/02/image.jpg), managed via the Media Library.
mu-plugins: Optional subdirectory (wp-content/mu-plugins) for “must-use” plugins, auto-activated PHP files (e.g., my-mu-plugin.php) that can’t be disabled from the admin.
Other Possible Folders: languages (for translations), cache (added by caching plugins), or custom folders created by plugins/themes.
Unlike wp-includes or wp-admin, wp-content is fully editable by users, preserved during core updates, and critical for site customization—making it the heart of a WordPress site’s unique identity.
Q: What’s wp-includes?
A: Core WordPress functions and libraries.
The wp-includes directory in WordPress, located in the root folder (e.g., /wp-includes), contains the core PHP files and libraries that power WordPress’s functionality, forming the backbone of its system. Key aspects include:
Core Functions: Houses essential files like functions.php (general utilities like wp_die()), class-wp-query.php (query handling), and plugin.php (hook system), defining WordPress’s built-in capabilities.
Classes and Objects: Includes object-oriented files such as class-wp-user.php (user management), class-wp-post.php (post handling), and class-wpdb.php (database access via $wpdb).
Subdirectories: Contains folders like js (JavaScript libraries, e.g., jquery), css (styles for core features), and fonts (default font assets), supporting both front-end and back-end rendering.
Utility Files: Features files like formatting.php (e.g., sanitize_text_field()), shortcodes.php (shortcode API), and media.php (media handling), used across themes and plugins.
Immutable: Unlike wp-content, it’s part of the core installation, overwritten during updates, and not meant for direct user edits—custom code goes elsewhere (e.g., functions.php).
In short, wp-includes is the engine room of WordPress, providing the reusable, foundational code that drives posts, users, queries, and more, ensuring consistent operation across all sites.
Q: What’s wp-admin?
A: Admin dashboard files and functionality.
The wp-admin directory in WordPress, located in the root folder (e.g., /wp-admin), contains all the files and scripts responsible for powering the WordPress admin dashboard, accessible via example.com/wp-admin. Key details include:
Core Admin Files: Includes admin.php (main admin logic), admin-ajax.php (handles AJAX requests), and admin-post.php (processes form submissions), serving as the backbone of admin functionality.
Subdirectories:
- css (stylesheets for admin UI, e.g., dashboard.css),
- js (JavaScript for admin features, e.g., post.js),
- images (admin icons and graphics),
- includes (helper files like update-core.php for updates).
User Interface: Drives pages like Posts (edit.php), Pages (page-new.php), Settings (options-general.php), and Users (users.php), rendered via PHP templates and processed server-side.
Access Control: Protected by authentication (login via wp-login.php), requiring user credentials and permissions (e.g., current_user_can(‘edit_posts’)).
Immutable Core: Part of WordPress core, overwritten during updates—customizations belong in plugins or themes, not here.
In essence, wp-admin is the administrative heart of WordPress, managing content, settings, and site administration, distinct from the public-facing wp-content and core logic in wp-includes.
Q: What’s The Loop?
A: Displays posts using have_posts() and the_post().
The Loop is WordPress’s fundamental mechanism for retrieving and displaying posts or other content from the database within a theme’s templates. It operates as a PHP control structure that iterates over a set of posts, leveraging global post data. Key details include:
Core Functions:
- have_posts(): Returns true if there are posts to display, false if none remain, checking the main query or a custom WP_Query.
- the_post(): Advances the loop, setting up the current post’s data (e.g., ID, title) in the global $post object.
Structure: Typically written as:
if (have_posts()) {
while (have_posts()) {
the_post();
the_title(); // Outputs title
the_content(); // Outputs content
}
} else {
echo ‘No posts found.’;
}
Purpose: Used in templates like index.php, single.php, or archive.php to render dynamic content (posts, pages, CPTs) based on the current query.
Customization: Can be modified with WP_Query for specific content (e.g., new WP_Query([‘post_type’ => ‘portfolio’])), requiring wp_reset_postdata() afterward.
Context: Relies on WordPress’s query system ($wp_query)—outside The Loop, functions like the_title() won’t work without setup.
In short, The Loop is the heartbeat of WordPress’s content display, bridging the database and front-end output, essential for any theme development and a likely interview topic.
Q: What’s the difference between a post and a page?
A: Posts are chronological, pages are static.
In WordPress, posts and pages are distinct content types with different purposes, behaviors, and characteristics:
Posts:
- Purpose: Chronological content, typically for blog articles, news, or updates.
- Behavior: Displayed in a reverse-chronological feed (e.g., homepage, archives), tied to The Loop’s main query.
- Features: Support categories, tags, post dates, and author metadata; appear in RSS feeds and archives.
- Database: Stored in wp_posts with post_type as post.
- Example: “My Latest Blog Entry” on a blog page.
Pages:
- Purpose: Static, standalone content, such as “About Us” or “Contact”.
- Behavior: Not part of the blog feed; manually placed via menus or links, often hierarchical (parent/child pages).
- Features: Lack categories/tags by default, no inherent date/author display, designed for timeless info.
- Database: Stored in wp_posts with post_type as page.
- Example: “Our Team” page in navigation.
Key Difference: Posts are time-based and aggregated; pages are static and independent—interviewers might ask this to test your grasp of content structure in WordPress.
Q: What’s the database table for posts?
A: wp_posts.
The database table for posts in WordPress is wp_posts, though the prefix can vary based on the $table_prefix setting in wp-config.php (default is wp_). Key details:
Purpose: Stores all post-type content, including posts, pages, custom post types (CPTs), attachments, and revisions.
Structure: Key columns include:
- ID (unique identifier),
- post_title (title),
- post_content (main content),
- post_type (e.g., post, page, attachment),
- post_status (e.g., publish, draft),
- post_date (publication date),
- post_author (user ID).
Related Tables: Connected to wp_postmeta (custom fields), wp_terms (categories/tags via wp_term_relationships), and wp_comments (comments).
Usage: Queried by WordPress core (e.g., via WP_Query) to retrieve content for The Loop or custom queries.
In short, wp_posts is the central hub for all post-like data, critical for understanding WordPress’s content management—interviewers might probe this to test database knowledge.
Q: What’s the wp_options table for?
A: Stores site settings (e.g., site title).
The wp_options table in WordPress stores site-wide settings and configuration data, acting as a key-value store for options that control how the site behaves and appears. Key details:
Purpose: Holds persistent, global settings accessible via functions like get_option() and update_option().
Structure: Key columns include:
- option_id (unique identifier),
- option_name (key, e.g., siteurl),
- option_value (value, e.g., https://example.com),
- autoload (yes/no—loads automatically on page load if yes).
Examples:
- siteurl (site URL),
- home (homepage URL),
- blogname (site title),
- posts_per_page (posts per page),
- active_plugins (array of enabled plugins).
Usage: Managed via the Settings API or direct DB access ($wpdb), with autoloaded options cached for performance.
Scope: Applies to the entire site (or network in multisite via wp_sitemeta)—custom options can be added by themes/plugins.
In essence, wp_options is WordPress’s settings repository, vital for site configuration and a likely interview topic for understanding data persistence.
Q: What does get_header() do?
A: Includes header.php from the theme.
The get_header() function in WordPress includes the header.php file from the active theme’s directory, injecting the header section (typically the HTML <head> and top site elements) into a template. Key details:
Purpose: Loads reusable header content (e.g., <html>, <head>, navigation) at the start of a page’s output.
How It Works:
- Searches for header.php in wp-content/themes/your-theme/.
- If not found, falls back to the parent theme (in child theme setups) or skips silently.
Optional Parameter: Accepts a $name (e.g., get_header(‘custom’)) to load header-custom.php for specific contexts.
Usage: Commonly used in templates like index.php, single.php, or page.php to maintain consistent headers.
Example:
// In index.php
<?php get_header(); ?>
<main>Main content here</main>
If header.php has <head><title>My Site</title></head>, this outputs above <main>.
Context: Relies on the theme’s template hierarchy and global WordPress environment.
In short, get_header() streamlines theme development by modularizing the header—interviewers might test this to assess your grasp of WordPress templating.
Q: What’s the default theme directory?
A: wp-content/themes.
The default theme directory in WordPress is wp-content/themes, located within the WordPress root folder. Key details:
Purpose: Stores all theme folders (e.g., twentytwentythree, my-custom-theme), each containing files like style.css, index.php, and functions.php that define the site’s appearance and behavior.
Structure: Each theme folder is a self-contained unit—WordPress scans this directory to list available themes in the admin under Appearance > Themes.
Default Behavior: WordPress ships with default themes (e.g., twentytwentythree) pre-installed here, and activating a theme links it to the site’s front-end rendering.
Path: Full path example: /var/www/wordpress/wp-content/themes.
Customization: Users add or edit themes here, preserved during core updates (unlike wp-includes or wp-admin).
In essence, wp-content/themes is the heart of WordPress theming—interviewers might ask this to test your understanding of file structure and theme management.
Q: What’s the admin URL?
A: /wp-admin (e.g., example.com/wp-admin).
The admin URL in WordPress is example.com/wp-admin/, where example.com is the site’s domain, providing access to the administrative dashboard. Key details:
Purpose: Directs users to the login page (wp-login.php) and, upon authentication, the admin interface for managing content, settings, and more.
Default Path: Appended to the site’s root URL (e.g., http://localhost/mysite/wp-admin/ for local setups).
Components:
- Initial redirect to wp-login.php for login (e.g., example.com/wp-login.php).
- Post-login, lands at wp-admin/index.php (dashboard).
Customization: Can be altered via plugins (e.g., WPS Hide Login) or wp-config.php settings for security, but defaults to /wp-admin/.
Access: Requires user credentials and appropriate permissions (e.g., administrator role).
In short, /wp-admin/ is the gateway to WordPress’s back-end—interviewers might ask this to confirm your familiarity with site administration.
Q: What’s a permalink?
A: A permanent URL for a post or page.
A permalink in WordPress is a permanent, user-friendly URL assigned to an individual post, page, or custom post type, designed to remain consistent even as content is updated. Key details:
Purpose: Provides a stable, readable link for content (e.g., example.com/my-first-post/ instead of example.com/?p=123).
Structure: Configurable via Settings > Permalinks in the admin dashboard, with options like:
- Plain: example.com/?p=123 (default, not SEO-friendly).
- Post Name: example.com/my-first-post/ (common choice).
- Category: example.com/category/my-post/.
Components: Built from the post slug (e.g., my-first-post), stored in wp_posts.post_name, often derived from the title and sanitized (e.g., spaces to hyphens).
Rewrite System: Managed by WordPress’s .htaccess or server rules (e.g., Nginx) to map pretty URLs to internal queries.
Usage: Output via the_permalink() or get_permalink() in templates.
In essence, permalinks enhance SEO and usability—interviewers might ask this to test your grasp of WordPress’s URL handling and content accessibility.
Q: What’s the front-end in WordPress?
A: The public-facing site visitors see.
The front-end in WordPress refers to the public-facing portion of the website that visitors see and interact with, rendered by the active theme and driven by WordPress’s core functionality. Key details:
Purpose: Displays content like posts, pages, and custom post types to users, distinct from the admin back-end.
Components:
- Theme Files: Templates (index.php, single.php) in wp-content/themes dictate layout and style.
- The Loop: Fetches and displays content (e.g., via the_title(), the_content()).
- Assets: CSS (style.css), JS, and media from wp-content/uploads.
Rendering: Processed server-side by PHP, outputting HTML, CSS, and JS (e.g., example.com/ or example.com/about/).
Customization: Controlled by themes, plugins, and hooks (e.g., wp_head, wp_footer)—no admin login required to view.
Example: A blog post at example.com/my-post/ with a header, content, and footer.
In short, the front-end is WordPress’s visitor interface—interviewers might ask this to ensure you understand the user-facing vs. admin distinction.
Q: What’s the back-end in WordPress?
A: The admin dashboard for managing content.
The back-end in WordPress refers to the administrative interface and underlying systems that manage the site’s content, settings, and functionality, accessible only to authenticated users. Key details:
Purpose: Allows administrators, editors, and other roles to create, edit, and configure the site—distinct from the public front-end.
Components:
- Admin Dashboard: Reached via example.com/wp-admin/, powered by files in wp-admin (e.g., admin.php, edit.php).
- Database: Managed via $wpdb, storing content (wp_posts), options (wp_options), etc.
- Core Files: wp-includes provides functions (e.g., update_option()) for back-end logic.
Features: Includes Posts, Pages, Media, Users, Settings, Plugins, and Themes management, rendered server-side with PHP.
Access: Requires login (wp-login.php) and permissions (e.g., current_user_can(‘manage_options’) for admins).
Example: Adding a post at example.com/wp-admin/post-new.php.
In essence, the back-end is WordPress’s control center—interviewers might ask this to test your understanding of site administration vs. the visitor-facing front-end.
Q: What’s functions.php?
A: Theme file for custom code (hooks, functions).
The functions.php file in WordPress is a theme-specific PHP file located in the active theme’s directory (e.g., wp-content/themes/twentytwentythree/functions.php), used to define custom functions, hooks, and settings that enhance or modify the theme’s behavior. Key details:
Purpose: Acts as a plugin-like file for the theme, allowing developers to add functionality without altering core WordPress files.
Common Uses:
- Hooks: Registers actions (add_action(‘wp_footer’, ‘my_func’)) and filters (add_filter(‘the_content’, ‘my_filter’)).
- Custom Functions: Defines reusable code (e.g., function my_custom_output() {}).
- Theme Setup: Configures features like add_theme_support(‘post-thumbnails’) or register_nav_menus().
Execution: Automatically loaded by WordPress on every page load (front-end and back-end) when the theme is active.
Scope: Specific to the active theme—child themes can override parent functions.php by including their own.
Example:
function my_footer_text() {
echo ‘<p>Custom footer!</p>’;
}
add_action(‘wp_footer’, ‘my_footer_text’);
In short, functions.php is the theme’s customization hub—interviewers might ask about it to test your ability to extend WordPress functionality.
Q: What’s the WordPress Codex?
A: Official documentation (now Developer Docs).
The WordPress Codex is the original online manual and documentation repository for WordPress, historically hosted at codex.wordpress.org, providing detailed guides, function references, and tutorials for developers, themers, and users. Key details:
Purpose: Served as the go-to resource for understanding WordPress internals, APIs, and best practices (e.g., how to use WP_Query, create themes).
Content: Included:
- Function Reference: Details on functions like get_the_title() or add_action().
- Guides: Step-by-step instructions (e.g., “Creating a Plugin”).
- Examples: Code snippets for common tasks.
Evolution: Largely replaced by the WordPress Developer Documentation (developer.wordpress.org) after 2018, which modernized and expanded the content—Codex is now semi-archived but still referenced.
Access: Open-source, community-edited (wiki-style), though less maintained today.
Example: Codex page for the_title() explained its usage and parameters.
In essence, the Codex was WordPress’s foundational knowledge base—interviewers might mention it to gauge your familiarity with official resources, though they’ll likely point to developer.wordpress.org now.
Q: What’s wp-blog-header.php?
A: Loads core WordPress environment.
The wp-blog-header.php file in WordPress, located in the root directory (e.g., /wp-blog-header.php), is a core file that serves as the central loader for the WordPress environment on front-end requests, bridging the initial index.php entry point to the full system. Key details:
Purpose: Initializes WordPress by loading essential components needed to process and display a page.
Role:
- Included by index.php via require __DIR__ . ‘/wp-blog-header.php’;.
- Loads wp-load.php (sets up constants, database connection), which then includes wp-settings.php (configures hooks, plugins, themes).
Execution: Triggers the main query ($wp_query), applies rewrite rules, and sets up the template loader to render the page (e.g., via The Loop).
Significance: Acts as the glue between the HTTP request and WordPress’s dynamic output—without it, the front-end wouldn’t function.
Not Editable: Part of the core, overwritten on updates—custom code goes elsewhere (e.g., functions.php).
In short, wp-blog-header.php is the engine starter for WordPress’s front-end—interviewers might ask about it to test your understanding of the bootstrap process.
Q: What does ABSPATH define?
A: Absolute path to WordPress root.
ABSPATH in WordPress is a PHP constant that defines the absolute server file system path to the WordPress root directory, ensuring scripts reference the correct location regardless of server setup. Key details:
Purpose: Provides a reliable base path for including files (e.g., require ABSPATH . ‘wp-settings.php’;) and securing WordPress by restricting direct access.
Definition: Set in wp-load.php (included by wp-blog-header.php) using PHP’s __DIR__ or similar, typically something like /var/www/wordpress/ on a server.
Usage:
- Core files use it to load dependencies (e.g., wp-includes/functions.php).
- Often checked to prevent direct file execution:
if (!defined(‘ABSPATH’)) {
exit; // Block access if not loaded via WordPress
}
Immutable: Automatically defined during WordPress startup—not editable in wp-config.php or elsewhere by users.
Example: On a local setup, ABSPATH might be C:/xampp/htdocs/mysite/.
In essence, ABSPATH anchors WordPress’s file operations—interviewers might ask this to test your grasp of WordPress’s file system and security mechanisms.
Q: What’s the plugins folder?
A: wp-content/plugins—stores plugin files.
The plugins folder in WordPress is a directory located at wp-content/plugins within the root folder, dedicated to storing all plugin files that extend or enhance WordPress functionality. Key details:
Purpose: Houses individual plugin directories (e.g., wp-content/plugins/hello-dolly), each containing PHP files (like hello-dolly.php), assets (CSS, JS), and optional subfolders, enabling features like SEO, forms, or custom tools.
Structure: Each plugin folder typically includes a main PHP file with a header comment (e.g., Plugin Name: Hello Dolly) that WordPress reads to list it in the admin under Plugins.
Management: Plugins are activated/deactivated via the Plugins dashboard (wp-admin/plugins.php), which scans this folder—activation runs the plugin’s code via hooks or custom logic.
Customization: User-added or third-party plugins live here, preserved during core updates, unlike wp-includes or wp-admin.
Example: wp-content/plugins/akismet contains akismet.php for spam protection.
In short, the plugins folder is WordPress’s extensibility hub—interviewers might ask about it to assess your understanding of how plugins integrate with the core system.
Q: What’s the mu-plugins folder?
A: wp-content/mu-plugins—must-use plugins.
The mu-plugins folder in WordPress, short for “must-use plugins,” is an optional directory located at wp-content/mu-plugins, designed to store PHP plugin files that are automatically activated and cannot be disabled from the admin dashboard. Key details:
Purpose: Houses plugins that must run on every page load, typically for critical site-wide functionality (e.g., security, performance tweaks) enforced by developers or site admins.
Behavior:
- Files (e.g., my-mu-plugin.php) are auto-loaded by WordPress during initialization (via wp-settings.php), before regular plugins.
- No activation toggle—unlike wp-content/plugins, they’re always active unless removed from the folder.
Structure: Contains standalone PHP files (e.g., custom-functions.php)—no subdirectories are scanned unless explicitly included by a file within.
Creation: Not present by default; must be manually created under wp-content—WordPress recognizes it if it exists.
Example: A file wp-content/mu-plugins/security.php adding a custom login check.
In short, mu-plugins ensures mandatory plugin execution—interviewers might ask this to test your knowledge of plugin management and WordPress’s loading order.
Q: What does wp-load.php do?
A: Bootstraps WordPress for external scripts.
The wp-load.php file in WordPress, located in the root directory (e.g., /wp-load.php), is a core script that bootstraps the WordPress environment by loading essential configuration and core files, enabling WordPress functionality for both front-end and external scripts. Key details:
Purpose: Sets up the foundation for WordPress to run by defining constants, connecting to the database, and preparing the system for further processing.
Actions:
- Loads wp-config.php (database credentials, salts, settings).
- Defines ABSPATH (absolute path to root).
- Includes wp-settings.php (loads core functions, plugins, themes).
- Establishes the database connection via $wpdb.
Usage:
- Included by wp-blog-header.php for front-end requests (via index.php).
- Used directly in custom scripts (e.g., require ‘/path/to/wp-load.php’;) to access WordPress functions outside templates.
Security: Often guarded with if (!defined(‘ABSPATH’)) exit; to prevent direct access.
Example: A cron script might use require ABSPATH . ‘wp-load.php’; to run wp_mail().
In essence, wp-load.php is the entry point for initializing WordPress—interviewers might ask this to probe your understanding of the startup sequence and custom integrations.
Q: What’s the wp-settings.php file?
A: Initializes WordPress settings and hooks.
The wp-settings.php file in WordPress, located in the root directory (e.g., /wp-settings.php), is a core script that configures and initializes the WordPress environment after basic setup, loading essential components to make the system fully operational. Key details:
Purpose: Sets up WordPress’s runtime by defining constants, loading core files, initializing plugins, themes, and hooks, and preparing the global $wp_query object.
Actions:
- Includes wp-includes files (e.g., functions.php, class-wp.php) for core functionality.
- Loads active plugins from wp-content/plugins and must-use plugins from wp-content/mu-plugins.
- Initializes the active theme (via wp-content/themes).
- Sets up global objects like $wpdb (database), $wp (main instance), and $wp_rewrite (permalinks).
- Fires early hooks like plugins_loaded and init.
Execution: Included by wp-load.php (via wp-blog-header.php from index.php) during every page load, front-end or back-end.
Not Editable: Part of the core, overwritten on updates—custom code belongs in functions.php or plugins.
Example Impact: Without it, no plugins, themes, or queries would run—e.g., add_action(‘init’, ‘my_func’) wouldn’t work.
In short, wp-settings.php is the orchestrator of WordPress’s startup—interviewers might ask this to test your grasp of the initialization process and dependency loading.
My post content
} Contrast: Unlike get_the_content(), which returns the content as a string, the_content() echoes it—use get_the_content() for manipulation. Example: Displays formatted text, images, or embedded media from the post editor. In short, the_content() is the go-to for rendering post bodies—interviewers might ask this to test your understanding of WordPress’s content display mechanics.' . esc_html($excerpt) . '
'; } Contrast: Unlike the_excerpt(), which outputs directly, get_the_excerpt() returns the string—ideal for processing before display. In short, get_the_excerpt() offers flexibility for handling post summaries—interviewers might ask this to test your understanding of WordPress’s content retrieval functions.Thanks for visiting my site!
'; } add_action('wp_footer', 'my_custom_footer_message'); // In a template (e.g., footer.php), WordPress includes: do_action('wp_footer'); // Executes all hooked functions© ' . date('Y') . ' My Site
'; } add_filter('the_content', 'add_copyright'); // In a template (e.g., single.php), WordPress includes: the_content(); // Outputs post content plus copyright Hello, world!© 2025 My Site
Updated on: ' . date('F j, Y') . '
'; return $notice . $content; } add_filter('the_content', 'add_content_notice'); // In a template (e.g., single.php): while (have_posts()) : the_post(); the_content(); // Outputs modified content endwhile;Updated on: February 27, 2025
Hello, world!Parent theme footer
'; } add_action('wp_footer', 'parent_footer_message', 15); // In a child theme’s functions.php: remove_action('wp_footer', 'parent_footer_message', 15); // In footer.php: wp_footer(); // No "Parent theme footer" outputNotice
' . $content; } add_filter('the_content', 'parent_content_notice', 15); // In a child theme’s functions.php: remove_filter('the_content', 'parent_content_notice', 15); // In single.php: the_content(); // Outputs content without the notice Hello, world!Early footer message
'; } add_action('wp_footer', 'early_footer', 5); // Low priority, runs first function late_footer() { echo 'Late footer message
'; } add_action('wp_footer', 'late_footer', 15); // High priority, runs last // In footer.php: wp_footer(); // Outputs both messages in orderEarly footer message
Late footer message
Footer message
'; } add_action('wp_footer', 'custom_footer_message'); // In a template (e.g., footer.php): if (has_action('wp_footer')) { echo 'Footer has actions!
'; wp_footer(); // Runs hooked actions } else { echo 'No footer actions.
'; }Footer has actions!
Footer message
Notice
'; } add_filter('the_content', 'add_content_notice'); // In a template (e.g., single.php): if (has_filter('the_content')) { echo 'Notice
First
'; } add_action('wp_footer', 'first_message', 5); // Early function second_message() { echo 'Second
'; } add_action('wp_footer', 'second_message', 15); // Late // In footer.php: wp_footer(); // Outputs messages in priority orderFirst
Second
This is a: ' . esc_html( $post_type ) . '
'; } } Result: Outputs the post type (e.g., "This is a: post") for each post in The Loop. $post_id = 42; $post_type = get_post_type( $post_id ); if ( $post_type ) { echo 'Post ID ' . $post_id . ' is a: ' . esc_html( $post_type ); } else { echo 'Post not found or invalid ID.'; } Result: Outputs the post type for post ID 42 (e.g., "Post ID 42 is a: page") or an error message.Genres: '; the_terms( get_the_ID(), 'genre', '', ', ', '' ); echo '
';No content found.
'; endif; ?>No content found.
'; endif; ?>This is a page!
This is not a page.
This is a single post!
Welcome to the Blog!
Welcome to the Site!
'primary' ) ); ?>Welcome to Our Homepage!
Explore Our Site!
'primary' ) ); ?>
In this example, get_template_directory_uri() generates a URL like http://yoursite.com/wp-content/themes/my-theme/, which is concatenated with asset paths (e.g., /css/custom.css or /images/logo.png). It ensures assets are loaded correctly from the theme folder. Let me know the next concept for your flashcards!
Custom single post layout from child theme!
Oops! It looks like we can’t find the page you’re looking for.
Try searching below or return to the homepage:
Hello world! Link
?> And here’s an example in a template with a custom field: array(), 'i' => array(), 'a' => array( 'href' => true ), ); echo wp_kses( $custom_field, $allowed_html ); } ?> In this example, wp_kses() filters $unsafe_input, keeping onlyInvalid email format.
'; } } } add_action( 'template_redirect', 'my_email_form_handler' ); ?> And here’s an example with a test string: example.com \n"; $clean_email = sanitize_email( $dirty_email ); echo esc_html( $clean_email ); // Outputs: user@example.com ?> In this example, sanitize_email() takes a messy input (" user@example.com \n") and outputs a clean email ("user@example.com") by removing spaces, tags, and newlines. Pair it with is_email() to confirm it’s a valid email before saving (e.g., to user meta). Use it for input sanitization, not output escaping.Security check failed!
'; } } } add_action( 'template_redirect', 'my_form_handler' ); ?> The output of wp_nonce_field() looks like this in HTML: In this example, wp_nonce_field( 'my_form_action', 'my_nonce_field' ) adds a nonce field named my_nonce_field to the form, tied to the action my_form_action. On submission, wp_verify_nonce() checks the nonce’s validity. If it fails (e.g., due to tampering or timeout), the action is blocked. This enhances security for custom forms.Data saved: ' . esc_html( $clean_data ) . '
Sorry, you don’t have permission to edit posts.
'; } } // Add a shortcode to display the restricted content add_shortcode( 'restricted_content', 'my_restricted_content' ); ?> And here’s an example in a template file:Safe URL: ' . esc_html( $safe_url ) . '
'; // Outputs: Safe URL: http://example.com/ ?> And here’s an example restricting protocols: Link'; // Outputs: Link (invalid protocol removed) ?> In these examples, esc_url() cleans $raw_url or $unsafe_url, stripping "; $clean_string = wp_strip_all_tags( $dirty_string ); echo esc_html( $clean_string ); // Outputs: Hello world! ?> Hello\nWorld"; $clean_no_breaks = wp_strip_all_tags( $dirty_with_breaks, true ); echo esc_html( $clean_no_breaks ); // Outputs: HelloWorld ?> In this example, wp_strip_all_tags() removes all tags (, , And here’s an example with enqueueing and a test string: alert("hacked");'; $safe_string = esc_js( $unsafe_string ); wp_add_inline_script( 'my-script', 'var safeValue = "' . $safe_string . '"; console.log(safeValue);' ); } add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' ); ?> The output in the browser would be: // Console output: He said \"Hello\" \u003Cscript\u003Ealert(\"hacked\")\u003C\/script\u003E In this example, esc_js() ensures $dynamic_value or $unsafe_string is safely embedded in JavaScript. For instance, He said "Hello" "; $safe_text = esc_textarea( $unsafe_text ); ?> In this example, esc_textarea() takes $unsafe_text and escapes it, ensuring "; $cleaned = sanitize_meta( 'my_custom_field', $raw_input, 'post' ); echo esc_html( $cleaned ); // Outputs: Hello World! $code_input = "abc-123!@#"; $cleaned_code = sanitize_meta( 'user_code', $code_input, 'user' ); echo esc_html( $cleaned_code ); // Outputs: ABC-123 ?> In this example: - 'my_custom_field' is registered with sanitize_text_field, so sanitize_meta() strips tags and extra spaces from "Hello ", yielding "Hello World!". - 'user_code' uses a custom callback to allow only uppercase letters, numbers, and dashes, transforming "abc-123!@#" to "ABC-123". - The $object_type (e.g., 'post') ensures the correct registration context. Use sanitize_meta() to apply registered sanitization rules explicitly, though it’s often automatic with update_post_meta() for registered keys.
No custom meta keys found.
'; } ?>
In this example, meta_form() is called within the default postcustom metabox, generating a form with a nonce, key dropdown (populated by get_post_custom_keys()), and value textarea. The save function processes this data when submitted. It’s a legacy tool—use custom metaboxes with add_meta_box() for modern development—but it’s still available for manual meta entry.
' . esc_html( $atts['text'] ) . '
'; } add_shortcode( 'myshortcode', 'my_shortcode_func' ); // In a template (e.g., page.php) get_header(); ?>Custom Text
} ?>Nested
contentGreetings!
. - It works on custom field content, enabling shortcodes where the_content() isn’t applied. - Nested shortcodes (e.g., [wrapper]) require do_shortcode( $content ) in the callback to process inner shortcodes. Use it to render shortcodes in non-standard contexts; it’s not needed in the_content() (already filtered).Plugin Version: ' . esc_html( $version ) . '
'; } } add_action( 'admin_notices', 'my_plugin_check' ); ?> In this example: - register_activation_hook( __FILE__, 'my_plugin_activate' ) ties 'my_plugin_activate' to the plugin’s activation. - On activation, my_plugin_activate(): --Sets an option 'my_plugin_version'. --Creates a table wp_my_plugin_data using dbDelta() for safe schema creation. --Logs the event. - Post-activation, the option is displayed in an admin notice. Use it in the plugin’s main file (not functions.php) for setup tasks; pair with register_deactivation_hook() for cleanup.Plugin is active.
'; } } add_action( 'admin_notices', 'my_plugin_status' ); ?> In this example: - register_deactivation_hook( __FILE__, 'my_plugin_deactivate' ) ties 'my_plugin_deactivate' to the plugin’s deactivation. - On deactivation, my_plugin_deactivate(): --Deletes the 'my_plugin_version' option. --Drops the wp_my_plugin_data table. --Clears any scheduled cron events. --Logs the event. -The activation hook sets up the data, and the status check shows it while active. Use it in the plugin’s main file (not functions.php) for cleanup; it doesn’t run on uninstall (use register_uninstall_hook() for that).This is my custom admin page content.
Settings saved.
This is the main settings page.
Sub settings saved.
WooCommerce is not active.
'; } // Check a custom plugin if ( is_plugin_active( 'my-custom-plugin/my-custom-plugin.php' ) ) { echo 'My Custom Plugin is active!
'; } } add_action( 'wp_footer', 'my_plugin_compatibility_check' ); function my_custom_shop_message() { echo 'Special offer available!
'; } ?> And here’s an example in an admin context:Contact Form 7 is active and compatible with this plugin.
Plugin is active.
'; } } add_action( 'admin_notices', 'my_plugin_status' ); ?> In this example: - register_uninstall_hook( __FILE__, 'my_plugin_uninstall' ) ties 'my_plugin_uninstall' to the plugin’s uninstallation. - On uninstall, my_plugin_uninstall(): --Deletes the 'my_plugin_version' option. --Drops the wp_my_plugin_data table. --Removes all post meta with keys starting with 'my_plugin_'. --Logs the event. - The activation hook sets up initial data, which is cleaned up on uninstall. Use it in the plugin’s main file for complete removal; it runs only on deletion, not deactivation. Note: An alternative is an uninstall.php file in the plugin root, which takes precedence if present.Shortcode "myshortcode" is registered.
'; echo do_shortcode( '[myshortcode]' ); // Safe to run } else { echo 'Shortcode "myshortcode" is not registered.
'; } // Check a non-existent shortcode if ( shortcode_exists( 'nonexistent' ) ) { echo 'Shortcode "nonexistent" exists.
'; } else { echo 'Shortcode "nonexistent" does not exist.
'; } } add_action( 'wp_footer', 'my_shortcode_checker' ); // Example in a template function my_template_shortcode() { $content = '[gallery]'; // Core shortcode if ( shortcode_exists( 'gallery' ) ) { return do_shortcode( $content ); } return 'Gallery shortcode not available.
'; } add_shortcode( 'check_gallery', 'my_template_shortcode' ); ?> In this example: - shortcode_exists( 'myshortcode' ) returns true because [myshortcode] is registered with add_shortcode(). - shortcode_exists( 'nonexistent' ) returns false since no such shortcode exists. - For the core [gallery] shortcode, shortcode_exists( 'gallery' ) checks its availability before execution. Use it to confirm a shortcode’s presence before processing, especially with third-party integrations. It doesn’t check functionality—just registration.Replaced shortcode content!
'; } add_shortcode( 'myshortcode', 'my_new_shortcode_func' ); // Remove a core shortcode (e.g., gallery) remove_shortcode( 'gallery' ); } add_action( 'init', 'my_remove_shortcode', 20 ); // High priority to run after registration // Test in a template or content function my_test_shortcode() { $content = '[myshortcode] and [gallery]'; echo do_shortcode( $content ); // Outputs:Replaced shortcode content!
and [gallery] (unprocessed) } add_action( 'wp_footer', 'my_test_shortcode' ); ?> In this example: - remove_shortcode( 'myshortcode' ) unregisters [myshortcode], preventing the original callback from running. - A new add_shortcode() replaces it with updated functionality. - remove_shortcode( 'gallery' ) disables the core [gallery] shortcode, leaving it as plain text when processed. - The init hook with priority 20 ensures it runs after typical shortcode registrations. Use it to disable unwanted shortcodes; it doesn’t affect content already saved—only future processing.This is my custom admin page.
Extra options go here.
Relative path: ' . esc_html( $relative_path ) . '
'; } add_action( 'admin_notices', 'my_include_file' ); ?> In this example: - plugin_basename( __FILE__ ) returns 'my-custom-plugin/my-custom-plugin.php' from a full path like /var/www/wp-content/plugins/my-custom-plugin/my-custom-plugin.php. - It’s used with is_plugin_active() to confirm activation status. - It works with any file path, like 'my-custom-plugin/includes/helper.php' for a subdirectory file. - It’s logged during activation for debugging. Use it to get a plugin’s standardized relative path for WordPress functions; it’s not a URL or full path.Failed to activate WooCommerce: ' . esc_html( $result->get_error_message() ) . '
WooCommerce activated successfully!
'; } } } add_action( 'admin_init', 'my_activate_dependency' ); // Example in a custom plugin’s activation function my_plugin_activate() { $dependency = 'my-dependency-plugin/my-dependency-plugin.php'; if ( ! is_plugin_active( $dependency ) ) { activate_plugin( $dependency, '', false ); // No redirect, single site if ( ! is_plugin_active( $dependency ) ) { wp_die( 'Please install and activate My Dependency Plugin first.' ); } } // Plugin-specific activation tasks update_option( 'my_plugin_active', 'yes' ); } register_activation_hook( __FILE__, 'my_plugin_activate' ); ?> In this example: - activate_plugin( 'woocommerce/woocommerce.php' ) attempts to activate WooCommerce if it’s not already active. - If it fails (e.g., plugin not found), a WP_Error triggers an admin notice. - In my_plugin_activate(), it ensures a dependency (my-dependency-plugin) is active before proceeding, dying with a message if activation fails. - plugin.php is included for frontend or early execution. Use it to programmatically enable plugins; ensure proper permissions (current_user_can( 'activate_plugins' )) and error handling.Conflicting Plugin deactivated.
Insufficient permissions to deactivate plugin.
Enter your custom settings below:
Plugin version: ' . MY_PLUGIN_VERSION . '
'; } add_shortcode( 'my_version', 'my_shortcode_func' ); ?> In this example: - add_action( 'plugins_loaded', 'my_plugin_setup' ) hooks my_plugin_setup() to plugins_loaded. - my_plugin_setup(): -- Checks for WooCommerce functions (available after plugins load) to add integration. -- Loads translation files for the plugin. -- Defines a constant (MY_PLUGIN_VERSION) used elsewhere. -- Logs the event for debugging. - The shortcode [my_version] uses the defined constant. Use plugins_loaded for tasks needing all plugins initialized (e.g., checking dependencies, loading translations); it’s too early for theme-related hooks like wp_enqueue_scripts.Stripped: ' . esc_html( $stripped ) . '
'; // Outputs: Stripped: This is some text with and more text // Compare with normal processing echo 'Processed: ' . do_shortcode( $content ) . '
'; // Outputs: Processed: This is some text withThis is shortcode output!
and more text [gallery output] } add_action( 'wp_footer', 'my_strip_shortcodes_example' ); // Example: Strip shortcodes from excerpts function my_custom_excerpt( $excerpt ) { return strip_shortcodes( $excerpt ); } add_filter( 'the_excerpt', 'my_custom_excerpt' ); ?> In this example: - strip_shortcodes( $content ) removes [myshortcode] and [gallery] from $content, leaving 'This is some text with and more text '. - The original content with do_shortcode() shows the executed output for comparison. - The the_excerpt filter uses it to ensure excerpts don’t include shortcode output or tags. Use it to clean content of shortcodes without processing them; it doesn’t remove shortcode content—just the tags (enclosed content remains).Meta Value: ' . esc_html( $post_meta ) . '
'; // Example 3: Insert data $data = array( 'user_id' => $user_id, 'action' => 'login', 'time' => current_time( 'mysql' ) ); $wpdb->insert( $wpdb->prefix . 'user_logs', $data ); // Example 4: Update data $wpdb->update( $wpdb->prefix . 'user_logs', array( 'action' => 'logout' ), array( 'user_id' => $user_id ), array( '%s' ), array( '%d' ) ); // Example 5: Custom table creation (activation) function my_plugin_activate() { global $wpdb; $table_name = $wpdb->prefix . 'user_logs'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, action varchar(50) NOT NULL, time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, PRIMARY KEY (id) ) $charset_collate;"; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); dbDelta( $sql ); } register_activation_hook( __FILE__, 'my_plugin_activate' ); ?> Key Features - Properties: $wpdb->posts (e.g., 'wp_posts'), $wpdb->prefix, $wpdb->last_error. - Methods: --get_results(): Returns multiple rows as objects or arrays. --get_var(): Returns a single value. --prepare(): Sanitizes queries with placeholders (e.g., %s, %d). --insert(), update(), delete(): Simplified CRUD operations. - Safety: Use prepare() to prevent SQL injection. Explanation - Select: $wpdb->get_results() fetches published posts. - Prepared Query: $wpdb->prepare() safely queries post meta with placeholders. - Insert/Update: $wpdb->insert() and $wpdb--update() manage a custom wp_user_logs table. - Table Creation: dbDelta() ensures safe schema updates on activation. Use $wpdb for custom database operations; always sanitize inputs with prepare() or helper methods.No posts found.
'; } // Example 2: Safe query with prepare() $user_id = get_current_user_id(); $query = $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key LIKE %s", $user_id, 'my_%' ); $meta = $wpdb->get_results( $query, ARRAY_A ); // ARRAY of ASSOCIATIVE ARRAYS if ( $meta ) { echo '| ' . esc_html( $row['meta_key'] ) . ' | ' . esc_html( $row['meta_value'] ) . ' |
Log #' . $id . ': ' . esc_html( $log->action ) . ' at ' . $log->time . '
'; } } ?> Key Features - Parameters: -- $query: SQL statement (e.g., "SELECT * FROM $wpdb->posts"). --$output_type (optional): OBJECT (default), ARRAY_A (associative array), ARRAY_N (numeric array), OBJECT_K (keyed by first column). - Returns: Array of results (empty array if none or on error); check $wpdb->last_error for issues. - Safety: Use $wpdb->prepare() for queries with user input to prevent SQL injection. Explanation - Default (OBJECT): $posts returns objects (e.g., $post->post_title). - ARRAY_A: $meta returns associative arrays (e.g., $row['meta_value']). - OBJECT_K: $logs keys results by id (e.g., $logs[1]->action). - Queries use $wpdb->posts, $wpdb->usermeta, or custom tables with $wpdb->prefix. Use $wpdb->get_results() for multi-row queries; pair with prepare() for safety.Current table prefix: ' . esc_html( $wpdb->prefix ) . '
'; // In multisite, might output 'wp_' (main site) or 'wp_2_' (subsite) } add_action( 'admin_notices', 'my_check_prefix' ); ?> Key Features - Value: Defined in wp-config.php (e.g., $table_prefix = 'wp_'); modifiable in multisite. - Usage: Prepended to table names (e.g., $wpdb->prefix . 'posts' becomes 'wp_posts'). - Core Tables: Built-in $wpdb properties use it (e.g., $wpdb->posts = $wpdb->prefix . 'posts'). - Custom Tables: Combine with custom suffixes (e.g., $wpdb->prefix . 'my_logs'). Explanation - Query: Uses $wpdb->prefix . 'posts' for portability (e.g., 'wp_posts' or 'customprefix_posts'). - Custom Table: Creates wp_my_logs (or similar) with $wpdb->prefix, ensuring uniqueness. - Insert: Adds data to the prefixed custom table. - Multisite: $wpdb->prefix adapts per blog (e.g., 'wp_2_' for blog ID 2). Use $wpdb->prefix for all table references to maintain compatibility across WordPress setups.Custom Setting: ' . esc_html( $my_setting ) . '
'; } else { echo 'Custom Setting not set, using default.
'; } // Example 3: Add and get a custom option function my_plugin_setup() { // Add option if not exists if ( false === get_option( 'my_plugin_version' ) ) { add_option( 'my_plugin_version', '1.0' ); } // Retrieve it $version = get_option( 'my_plugin_version' ); echo 'Plugin Version: ' . esc_html( $version ) . '
'; } add_action( 'admin_init', 'my_plugin_setup' ); // Example 4: Using with Settings API function my_register_settings() { register_setting( 'my_settings_group', 'my_custom_option', 'sanitize_text_field' ); } add_action( 'admin_init', 'my_register_settings' ); function my_options_page() { ?>Current value: ' . esc_html( get_option( 'my_custom_option' ) ) . '
'; } add_action( 'admin_init', 'my_set_custom_option' ); // Example 2: Update with array and autoload function my_plugin_activate() { $settings = array( 'version' => '1.0', 'enabled' => true ); update_option( 'my_plugin_settings', $settings, 'no' ); // No autoload echo 'Settings saved: ' . esc_html( print_r( get_option( 'my_plugin_settings' ), true ) ) . '
'; } register_activation_hook( __FILE__, 'my_plugin_activate' ); // Example 3: Settings API integration function my_register_settings() { register_setting( 'my_settings_group', 'my_custom_setting', 'sanitize_text_field' ); } add_action( 'admin_init', 'my_register_settings' ); function my_options_page() { if ( isset( $_POST['my_custom_setting'] ) && check_admin_referer( 'my_settings_group-options' ) ) { update_option( 'my_custom_setting', sanitize_text_field( $_POST['my_custom_setting'] ) ); echo 'Setting saved.
Option already exists: ' . esc_html( get_option( 'my_plugin_version' ) ) . '
'; } } add_action( 'admin_init', 'my_plugin_setup' ); // Example 2: Add during plugin activation function my_plugin_activate() { add_option( 'my_plugin_settings', array( 'enabled' => true, 'theme' => 'dark' ), '', 'yes' ); $settings = get_option( 'my_plugin_settings' ); echo 'Settings added: ' . esc_html( print_r( $settings, true ) ) . '
'; } register_activation_hook( __FILE__, 'my_plugin_activate' ); // Example 3: Check before adding function my_add_custom_option() { $key = 'my_custom_flag'; if ( ! get_option( $key ) ) { // Check if it doesn’t exist add_option( $key, 'active' ); echo 'Added ' . esc_html( $key ) . ': ' . esc_html( get_option( $key ) ) . '
'; } // Trying again won’t overwrite add_option( $key, 'inactive' ); // No effect echo 'Still: ' . esc_html( get_option( $key ) ) . '
'; // Still 'active' } add_action( 'wp_footer', 'my_add_custom_option' ); ?> Parameters: -- $key: The option name to add (string). -- $value: The value to store (string, array, etc., serialized if complex). -- $deprecated: Unused (empty string for backward compatibility). -- $autoload: 'yes' (default, autoloads) or 'no' (load on demand). - Returns: true if added, false if the option exists or fails. - Behavior: Skips if $key exists (use update_option() to change values). Explanation - Setup: Adds 'my_plugin_version' only if absent, with $autoload = 'no'. - Activation: Adds 'my_plugin_settings' as an array with autoload enabled. - Conditional Add: Adds 'my_custom_flag' if missing; subsequent calls don’t overwrite 'active' with 'inactive'. Use add_option() for initial setup (e.g., plugin activation); prefer update_option() for updates.Failed to delete "' . esc_html( $key ) . '".
'; } } // Verify deletion echo 'Now: ' . ( get_option( $key, 'Not found' ) === 'Not found' ? 'Deleted' : 'Still exists' ) . '
'; } add_action( 'admin_init', 'my_remove_option' ); // Example 2: Cleanup on deactivation function my_plugin_deactivate() { delete_option( 'my_plugin_settings' ); delete_option( 'my_plugin_version' ); error_log( 'Plugin options deleted on deactivation.' ); } register_deactivation_hook( __FILE__, 'my_plugin_deactivate' ); // Example 3: Add then delete function my_test_option() { $key = 'test_option'; update_option( $key, 'Temporary Value' ); // Add or update echo 'Before: ' . esc_html( get_option( $key ) ) . '
'; delete_option( $key ); // Remove it echo 'After: ' . ( get_option( $key, 'Gone' ) === 'Gone' ? 'Deleted' : 'Still here' ) . '
'; } add_action( 'wp_footer', 'my_test_option' ); ?> -Parameter: -- $key: The option name to delete (string). - Returns: true if deleted successfully, false if the option didn’t exist or deletion failed. - Caching: Updates the options cache to reflect the deletion. - Scope: Only affects the current site (use delete_site_option() for multisite network options). Explanation - Removal: Deletes 'my_custom_option' if it exists, with feedback on success. - Deactivation: Cleans up 'my_plugin_settings' and 'my_plugin_version' when the plugin deactivates. - Test: Adds 'test_option', then deletes it, confirming removal with a default fallback. Use delete_option() to remove settings permanently; check existence with get_option() if needed.Updated ' . $updated . ' posts to draft.
'; } else { echo 'Error: ' . esc_html( $wpdb->last_error ) . '
'; } // Example 2: Insert a row $sql = $wpdb->prepare( "INSERT INTO $wpdb->prefix" . "my_logs (log_message, log_time) VALUES (%s, %s)", 'User logged in', current_time( 'mysql' ) ); $inserted = $wpdb->query( $sql ); if ( $inserted ) { echo 'Inserted log entry, ID: ' . $wpdb->insert_id . '
'; } // Example 3: Delete rows $sql = $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", 'temporary_flag', 'yes' ); $deleted = $wpdb->query( $sql ); echo 'Deleted ' . $deleted . ' temporary meta entries.
'; // Example 4: Create a table (raw query) $sql = "CREATE TABLE IF NOT EXISTS " . $wpdb->prefix . "my_logs ( id mediumint(9) NOT NULL AUTO_INCREMENT, log_message varchar(255) NOT NULL, log_time datetime NOT NULL, PRIMARY KEY (id) ) " . $wpdb->get_charset_collate(); $wpdb->query( $sql ); if ( empty( $wpdb->last_error ) ) { echo 'Table created successfully.
'; } ?> Key Features - Parameter: -- $sql: The SQL query string to execute. - Returns: -- Integer: Number of rows affected (e.g., updated, inserted, deleted). -- false: On query failure (check $wpdb->last_error). - Properties Affected: -- $wpdb->last_result: Populated with results (for SELECT, use get_results() instead). -- $wpdb->insert_id: Last inserted ID after INSERT. - Safety: Must use $wpdb->prepare() with placeholders (e.g., %s, %d) for dynamic values. Explanation - Update: Changes post statuses, returning the count of affected rows. - Insert: Adds a log entry to a custom table, retrieving the new ID. - Delete: Removes specific post meta, reporting rows deleted. - Create: Executes a table creation query, checking $wpdb->last_error for success. Use $wpdb->query() for direct SQL execution; prefer $wpdb->get_results() for SELECT and $wpdb->insert()/update() for safer CRUD. Always sanitize with prepare().Log entry added, ID: ' . $wpdb->insert_id . '
'; } else { echo 'Error: ' . esc_html( $wpdb->last_error ) . '
'; } // Example 2: Insert post meta $data = array( 'post_id' => 123, 'meta_key' => 'my_custom_field', 'meta_value' => 'Custom Value' ); $wpdb->insert( $wpdb->postmeta, $data ); // Default format inferred echo 'Meta added for post 123, ID: ' . $wpdb->insert_id . '
'; // Example 3: Create table and insert function my_setup_table() { global $wpdb; $table = $wpdb->prefix . 'user_logs'; $sql = "CREATE TABLE $table ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, action varchar(50) NOT NULL, log_time datetime NOT NULL, PRIMARY KEY (id) ) " . $wpdb->get_charset_collate(); require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta( $sql ); // Insert initial data $wpdb->insert( $table, array( 'user_id' => 1, 'action' => 'setup', 'log_time' => current_time( 'mysql' ) ) ); } register_activation_hook( __FILE__, 'my_setup_table' ); ?> Key features - Parameters: -- $table: Table name (string, e.g., $wpdb->prefix . 'user_logs'). -- $data: Associative array of column => value pairs. -- $format (optional): Array of placeholders (e.g., %s, %d, %f) matching $data order; defaults to %s if omitted. - Returns: 1 on success (one row inserted), false on failure (check $wpdb->last_error). - Properties: $wpdb->insert_id holds the auto-incremented ID of the new row. - Safety: Automatically escapes values using $wpdb->prepare() internally. Explanation - Custom Table: Inserts a log entry into wp_user_logs with explicit formats, retrieving the new ID. - Post Meta: Adds a meta entry to wp_postmeta without $format (defaults to strings). - Setup: Creates wp_user_logs and inserts an initial row on plugin activation. Use $wpdb->insert() for safe, single-row inserts; it’s simpler and safer than raw $wpdb->query() for INSERT.Updated ' . $updated . ' log entries.
'; } else { echo 'Error: ' . esc_html( $wpdb->last_error ) . '
'; } // Example 2: Update post meta $data = array( 'meta_value' => 'New Value' ); $where = array( 'post_id' => 123, 'meta_key' => 'my_custom_field' ); $wpdb->update( $wpdb->postmeta, $data, $where ); // Defaults to %s echo 'Updated meta for post 123.
'; // Example 3: Create table and update function my_setup_and_update() { global $wpdb; $table = $wpdb->prefix . 'user_logs'; $sql = "CREATE TABLE $table ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, action varchar(50) NOT NULL, log_time datetime NOT NULL, PRIMARY KEY (id) ) " . $wpdb->get_charset_collate(); require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta( $sql ); // Insert then update $wpdb->insert( $table, array( 'user_id' => 1, 'action' => 'start', 'log_time' => current_time( 'mysql' ) ) ); $wpdb->update( $table, array( 'action' => 'complete' ), array( 'id' => $wpdb->insert_id ) ); echo 'Updated log entry #' . $wpdb->insert_id . '.
'; } register_activation_hook( __FILE__, 'my_setup_and_update' ); ?> Key Features - Parameters: -- $table: Table name (string, e.g., $wpdb->prefix . 'user_logs'). -- $data: Associative array of columns and new values. -- $where: Associative array of conditions to match rows. -- $format (optional): Array of placeholders for $data (e.g., %s, %d). -- $where_format (optional): Array of placeholders for $where. - Returns: Number of rows updated (0 if none matched), false on error (check $wpdb->last_error). - Safety: Internally uses $wpdb->prepare() to escape values. Explanation - Custom Table: Updates action and log_time in wp_user_logs for the current user, specifying formats. - Post Meta: Updates 'my_custom_field' for post 123, using default string format. - Setup: Creates wp_user_logs, inserts a row, then updates it based on the new ID. Use $wpdb->update() for safe, targeted updates; it’s more convenient and secure than raw $wpdb->query() for UPDATE.Deleted ' . $deleted . ' login log entries.
'; } else { echo 'Error: ' . esc_html( $wpdb->last_error ) . '
'; } // Example 2: Delete post meta $where = array( 'post_id' => 123, 'meta_key' => 'my_custom_field' ); $wpdb->delete( $wpdb->postmeta, $where ); // Defaults to %s echo 'Deleted meta for post 123.
'; // Example 3: Create, insert, and delete function my_setup_and_cleanup() { global $wpdb; $table = $wpdb->prefix . 'user_logs'; $sql = "CREATE TABLE $table ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, action varchar(50) NOT NULL, log_time datetime NOT NULL, PRIMARY KEY (id) ) " . $wpdb->get_charset_collate(); require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta( $sql ); // Insert a row $wpdb->insert( $table, array( 'user_id' => 1, 'action' => 'test', 'log_time' => current_time( 'mysql' ) ) ); $inserted_id = $wpdb->insert_id; // Delete it $deleted = $wpdb->delete( $table, array( 'id' => $inserted_id ), array( '%d' ) ); echo 'Deleted ' . $deleted . ' test log entry.
'; } register_activation_hook( __FILE__, 'my_setup_and_cleanup' ); ?> Key Features - Parameters: -- $table: Table name (string, e.g., $wpdb->prefix . 'user_logs'). -- $where: Associative array of conditions to match rows for deletion. -- $where_format (optional): Array of placeholders (e.g., %s, %d) for $where values; defaults to %s. - Returns: Number of rows deleted (0 if none matched), false on error (check $wpdb->last_error). - Safety: Automatically escapes $where values using $wpdb->prepare() internally. Explanation - Custom Table: Deletes rows from wp_user_logs where user_id and action match, using specific formats. - Post Meta: Removes 'my_custom_field' for post 123, with default string format. - Setup & Cleanup: Creates wp_user_logs, inserts a row, then deletes it by ID, confirming the deletion count. Use $wpdb->delete() for safe, conditional row removal; it’s more structured and secure than $wpdb->query() for DELETE.Published posts: ' . ( $post_count !== null ? esc_html( $post_count ) : 'None' ) . '
'; // Example 2: Safe query with prepare $user_id = get_current_user_id(); $query = $wpdb->prepare( "SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, 'nickname' ); $nickname = $wpdb->get_var( $query ); echo 'User nickname: ' . esc_html( $nickname ?: 'Not set' ) . '
'; // Example 3: Using offsets $query = "SELECT ID, post_title, post_date FROM $wpdb->posts WHERE post_type = 'post' LIMIT 1"; $title = $wpdb->get_var( $query, 1 ); // Column 1 (post_title) echo 'First post title: ' . esc_html( $title ) . '
'; // Example 4: Custom table query $query = $wpdb->prepare( "SELECT log_time FROM $wpdb->prefix" . "user_logs WHERE user_id = %d ORDER BY log_time DESC LIMIT 1", $user_id ); $last_log = $wpdb->get_var( $query ); echo 'Last log time: ' . esc_html( $last_log ?: 'No logs' ) . '
'; ?> Key Features - Parameters: -- $query: SQL query string (e.g., "SELECT name FROM $wpdb->users"). -- $x (optional): Column offset (0-based, default 0). -- $y (optional): Row offset (0-based, default 0, usually ignored since it’s single-value). - Returns: Single value (string, integer, etc.) or null if no result or error (check $wpdb->last_error). - Safety: Use $wpdb->prepare() for queries with dynamic values to prevent SQL injection. Explanation - Count: Gets the total published posts from wp_posts. - Meta: Retrieves the user’s nickname from wp_usermeta safely with prepare(). - Offset: Fetches the post_title (column 1) from the first post row. - Custom Table: Gets the latest log_time from wp_user_logs for the current user. Use $wpdb->get_var() for single-value queries (e.g., counts, specific fields); it’s simpler than $wpdb->get_results() for one datum.Nickname: ' . esc_html( $nickname ?: 'Not set' ) . '
'; // Example 2: INSERT with multiple values $table = $wpdb->prefix . 'user_logs'; $data = array( 'user_id' => 1, 'action' => 'login', 'time' => current_time( 'mysql' ) ); $query = $wpdb->prepare( "INSERT INTO $table (user_id, action, log_time) VALUES (%d, %s, %s)", $data['user_id'], $data['action'], $data['time'] ); $wpdb->query( $query ); echo 'Inserted log entry, ID: ' . $wpdb->insert_id . '
'; // Example 3: UPDATE with array args $query = $wpdb->prepare( "UPDATE $wpdb->posts SET post_status = %s WHERE ID = %d", array( 'draft', 123 ) ); $updated = $wpdb->query( $query ); echo 'Updated ' . $updated . ' posts.
'; // Example 4: DELETE with prepare $post_id = 456; $meta_key = 'temporary_flag'; $query = $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", $post_id, $meta_key ); $deleted = $wpdb->query( $query ); echo 'Deleted ' . $deleted . ' meta entries.
'; ?> Key Features - Parameters: -- $query: SQL string with placeholders (e.g., "SELECT * FROM $wpdb->posts WHERE ID = %d"). -- $args: Values to replace placeholders (variadic arguments or single array). - Placeholders: -- %s: String (escaped with esc_sql()). -- %d: Integer (cast to int). -- %f: Float (cast to float). - Returns: Sanitized SQL query string (e.g., "SELECT * FROM wp_posts WHERE ID = 123"). - Safety: Escapes and quotes values to prevent injection; required for dynamic data. Explanation - SELECT: Prepares a query to fetch a user’s nickname, safely inserting $user_id and 'nickname'. - INSERT: Builds an INSERT query with multiple values from an array, avoiding raw concatenation. - UPDATE: Updates post status for ID 123 using an array of arguments. - DELETE: Deletes meta for a specific post and key, securely embedding variables. Use $wpdb->prepare() before any $wpdb query with user input or variables; never concatenate raw values into $query.Published Post IDs: ' . esc_html( implode( ', ', $post_ids ) ) . '
'; } else { echo 'No published posts found.
'; } // Example 2: Safe query with prepare $user_id = get_current_user_id(); $query = $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE user_id = %d", $user_id ); $meta_keys = $wpdb->get_col( $query ); echo 'User Meta Keys: ' . esc_html( implode( ', ', $meta_keys ) ) . '
'; // Example 3: Using column offset $query = "SELECT ID, post_title, post_date FROM $wpdb->posts WHERE post_type = 'post' LIMIT 5"; $post_titles = $wpdb->get_col( $query, 1 ); // Column 1 (post_title) if ( $post_titles ) { echo 'Login Messages: ' . esc_html( implode( '; ', $log_messages ) ) . '
'; ?> Key Features - Parameters: -- $query: SQL query string (e.g., "SELECT name FROM $wpdb->users"). -- $x (optional): Column offset (0-based, default 0). - Returns: Numeric array of values from the specified column (e.g., [1, 2, 3]), or empty array ([]) if no results or error (check $wpdb->last_error). - Safety: Use $wpdb->prepare() for queries with dynamic values to prevent SQL injection. Explanation - Post IDs: Retrieves all ID values from wp_posts where status is 'publish'. - Meta Keys: Safely gets meta_key values for the current user with prepare(). - Offset: Fetches post_title (column 1) from a multi-column query. - Custom Table: Lists log_message values from wp_user_logs for login actions. Use $wpdb->get_col() for single-column lists (e.g., IDs, names); it’s more efficient than $wpdb->get_results() for this purpose.Published posts: ' . esc_html( $post_count ) . '
'; // Example 3: Loop through tables foreach ( $wpdb->tables as $table_key => $table_name ) { $row_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" ); echo '' . esc_html( $table_key ) . ' rows: ' . esc_html( $row_count ) . '
'; } // Example 4: Multisite check if ( is_multisite() ) { $blog_id = get_current_blog_id(); switch_to_blog( 2 ); // Switch to blog ID 2 echo 'Posts table for blog 2: ' . esc_html( $wpdb->posts ) . '
'; // e.g., wp_2_posts restore_current_blog(); } else { echo 'Posts table: ' . esc_html( $wpdb->posts ) . '
'; // e.g., wp_posts } ?> Key Features - Structure: Associative array with keys (e.g., 'posts', 'users') mapping to prefixed table names (e.g., 'wp_posts', 'wp_users'). - Dynamic: Updated based on $wpdb->prefix (set in wp-config.php) and blog ID in multisite. - Core Tables: Includes standard WordPress tables; excludes custom tables. - Access: Available as properties (e.g., $wpdb->posts) or via $wpdb->tables['posts']. Explanation - List: Displays all core table names (e.g., 'wp_posts', 'wp_usermeta'). - Query: Uses $wpdb->posts directly for a count of published posts. - Loop: Iterates $wpdb->tables to count rows in each core table. - Multisite: Shows how $wpdb->posts changes to 'wp_2_posts' for blog ID 2. Use $wpdb->tables or its properties (e.g., $wpdb->posts) for portable table references in queries; combine with $wpdb->prefix for custom tables.Error: ' . esc_html( $wpdb->last_error ) . '
'; // Outputs: Error: Table 'wp_non_existent_table' doesn’t exist } else { echo 'Query succeeded.
'; } // Example 2: Safe query with error check $user_id = get_current_user_id(); $query = $wpdb->prepare( "SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, 'nonexistent_key' ); $value = $wpdb->get_var( $query ); if ( $value === null && $wpdb->last_error ) { echo 'Query failed: ' . esc_html( $wpdb->last_error ) . '
'; } else { echo 'Value: ' . esc_html( $value ?: 'Not found' ) . '
'; } // Example 3: Insert with error handling $inserted = $wpdb->insert( $wpdb->prefix . 'user_logs', array( 'user_id' => 'invalid', 'action' => 'test' ) // Invalid type for user_id ); if ( $inserted === false ) { echo 'Insert failed: ' . esc_html( $wpdb->last_error ) . '
'; // Outputs: Error: Column 'user_id' cannot be null or type mismatch } else { echo 'Inserted row ID: ' . $wpdb->insert_id . '
'; } // Example 4: Deliberate syntax error $wpdb->query( "SELCT * FROM $wpdb->posts" ); // Typo in SELECT if ( $wpdb->last_error ) { echo 'Syntax error: ' . esc_html( $wpdb->last_error ) . '
'; // Outputs: Error: You have an error in your SQL syntax... } ?> Key Features - Type: String (empty '' if no error). - Set By: Any $wpdb method that interacts with the database (e.g., query(), insert(), update()). - Usage: Check after a method returns false or null to diagnose failures. - Scope: Reflects the last query executed in the current request; reset on new queries. Explanation - Invalid Table: $wpdb->get_results() fails on a nonexistent table, and $wpdb->last_error reveals the issue. - Safe Query: $wpdb->get_var() might return null (no result), but $wpdb->last_error distinguishes between no data and an error. - Insert Failure: An invalid user_id type triggers an error, logged via $wpdb->last_error. - Syntax Error: A typo in SELECT causes $wpdb->query() to fail, with the error message stored. Use $wpdb->last_error for debugging failed database operations; always escape output with esc_html() for display.Site Config: ' . esc_html( print_r( get_option( 'my_site_config' ), true ) ) . '
'; // Example 2: Add option with autoload 'no' add_option( 'my_rarely_used_data', 'Large dataset', '', 'no' ); // No autoload $rare_data = get_option( 'my_rarely_used_data' ); // Loads on demand echo 'Rare Data: ' . esc_html( $rare_data ) . '
'; // Example 3: Update option with autoload change update_option( 'my_plugin_settings', array( 'version' => '1.0' ), 'no' ); // Change to no autoload echo 'Plugin Settings: ' . esc_html( print_r( get_option( 'my_plugin_settings' ), true ) ) . '
'; // Example 4: Check autoload status (manual query) global $wpdb; $autoload_status = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", 'my_site_config' ) ); echo 'Autoload for my_site_config: ' . esc_html( $autoload_status ) . '
'; // 'yes' // Example 5: Plugin activation with autoload control function my_plugin_activate() { add_option( 'my_plugin_version', '1.0', '', 'yes' ); // Autoload for frequent use add_option( 'my_plugin_logs', array(), '', 'no' ); // No autoload for large data } register_activation_hook( __FILE__, 'my_plugin_activate' ); ?> Key Features - Values: 'yes' (autoloaded, default) or 'no' (loaded on demand). - Set By: -- add_option( $key, $value, $deprecated, $autoload ): Sets initial autoload. -- update_option( $key, $value, $autoload ): Updates value and autoload (defaults to existing if $autoload is null). - Performance: 'yes' reduces database queries but increases memory; 'no' saves memory but requires queries. - Storage: Saved in wp_options table’s autoload column. Explanation - Autoload Yes: 'my_site_config' is preloaded for quick access on every page. - Autoload No: 'my_rarely_used_data' loads only when called, saving memory. - Update: Changes 'my_plugin_settings' to 'no' autoload, altering its behavior. - Query: Checks 'my_site_config' autoload status directly from the database. - Plugin: Sets 'my_plugin_version' to autoload (small, frequent use) and 'my_plugin_logs' to no autoload (large, rare use). Use autoload 'yes' for small, often-used options (e.g., site settings); use 'no' for large or rarely accessed data (e.g., logs).Network Setting: ' . esc_html( $custom_setting ) . '
'; // Example 3: Add and retrieve network option function my_network_setup() { if ( is_multisite() && is_network_admin() ) { if ( false === get_site_option( 'my_network_version' ) ) { add_site_option( 'my_network_version', '1.0' ); } $version = get_site_option( 'my_network_version' ); echo 'Network Version: ' . esc_html( $version ) . '
'; } else { echo 'Not in multisite network admin.
'; } } add_action( 'network_admin_notices', 'my_network_setup' ); // Example 4: Compare with per-site option function my_option_comparison() { if ( is_multisite() ) { $site_option = get_option( 'blogname' ); // Per-site $network_option = get_site_option( 'site_name' ); // Network-wide echo 'Site Name: ' . esc_html( $site_option ) . '
'; echo 'Network Name: ' . esc_html( $network_option ) . '
'; } } add_action( 'admin_notices', 'my_option_comparison' ); ?> Key Features - Parameter: -- $key: The network option name (string). -- $default (optional): Returned if the option doesn’t exist (default false). - Returns: The option value (string, array, etc.) or $default if not found. - Scope: Multisite only; stored in wp_sitemeta (not wp_options), accessible network-wide. - Caching: Cached in the network options cache for performance. Explanation - Network Option: Retrieves 'site_name' set in Network Admin > Settings. - Custom with Default: Gets 'my_network_setting', falling back to 'default_value' if unset. - Setup: Adds 'my_network_version' in network admin if missing, then retrieves it. - Comparison: Shows 'blogname' (site-specific, from wp_options) vs. 'site_name' (network-wide, from wp_sitemeta). Use get_site_option() for network-wide settings in multisite (e.g., global configs); use get_option() for site-specific settings. Escape output for safety.Current value: ' . esc_html( get_site_option( 'my_network_setting' ) ) . '
'; } } add_action( 'network_admin_notices', 'my_update_network_setting' ); // Example 2: Update with array function my_network_activate() { if ( is_multisite() ) { $settings = array( 'version' => '1.0', 'enabled' => true ); update_site_option( 'my_network_config', $settings ); $config = get_site_option( 'my_network_config' ); echo 'Network Config: ' . esc_html( print_r( $config, true ) ) . '
'; } } register_activation_hook( __FILE__, 'my_network_activate' ); // Example 3: Network admin form function my_network_options_page() { if ( ! is_network_admin() ) return; if ( isset( $_POST['my_network_option'] ) && check_admin_referer( 'my_network_save' ) ) { update_site_option( 'my_network_option', sanitize_text_field( $_POST['my_network_option'] ) ); echo 'Network option saved.
Failed to delete "' . esc_html( $key ) . '".
'; } } // Verify deletion echo 'Now: ' . ( get_site_option( $key, 'Not found' ) === 'Not found' ? 'Deleted' : 'Still exists' ) . '
'; } } add_action( 'network_admin_notices', 'my_remove_network_option' ); // Example 2: Cleanup on plugin deactivation function my_network_deactivate() { if ( is_multisite() ) { delete_site_option( 'my_network_config' ); delete_site_option( 'my_network_version' ); error_log( 'Network options deleted on deactivation.'); } } register_deactivation_hook( __FILE__, 'my_network_deactivate' ); // Example 3: Add then delete function my_test_network_option() { if ( is_multisite() ) { $key = 'test_network_option'; update_site_option( $key, 'Temporary Value' ); // Add or update echo 'Before: ' . esc_html( get_site_option( $key ) ) . '
'; delete_site_option( $key ); // Remove it echo 'After: ' . ( get_site_option( $key, 'Gone' ) === 'Gone' ? 'Deleted' : 'Still here' ) . '
'; } } add_action( 'wp_footer', 'my_test_network_option' ); ?> Key Features - Parameter: -- $key: The network option name to delete (string). - Returns: true if deleted successfully, false if the option didn’t exist or deletion failed. - Scope: Multisite only; affects wp_sitemeta, network-wide. - Caching: Updates the network options cache to reflect the deletion. Explanation - Removal: Deletes 'my_network_setting' if it exists, with feedback on success. - Deactivation: Removes 'my_network_config' and 'my_network_version' during plugin deactivation. - Test: Adds 'test_network_option', then deletes it, confirming removal with a fallback. Use delete_site_option() to remove network-wide settings in multisite; check existence with get_site_option() if needed.Escaped (old): ' . esc_html( $escaped ) . '
'; // Outputs: O\'Reilly // Example 2: Modern replacement with prepare() $safe_query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_title = %s", $unsafe_string ); $results = $wpdb->get_results( $safe_query ); echo 'Safe query executed.
'; // Example 3: Why escape() is unsafe $malicious = "'; DROP TABLE $wpdb->users; --"; $escaped = $wpdb->escape( $malicious ); // O\'Reilly; DROP TABLE wp_users; -- $query = "SELECT * FROM $wpdb->posts WHERE post_title = '$escaped'"; echo 'Unsafe query: ' . esc_html( $query ) . '
'; // Shows vulnerability // Example 4: Correct modern approach $safe_query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_title = %s", $malicious ); echo 'Safe query: ' . esc_html( $safe_query ) . '
'; // Properly escaped ?> Key Features - Parameter: -- $string: The string to escape (e.g., "O'Reilly"). - Returns: Escaped string (e.g., "O\'Reilly") with backslashes added before quotes, slashes, etc. - Status: Deprecated since WordPress 3.6; replaced by $wpdb->prepare(). - Safety: Limited; doesn’t fully prevent injection with complex inputs (e.g., semicolons). Explanation - Deprecated Use: $wpdb->escape() adds backslashes (e.g., "O'Reilly" to "O\'Reilly"), but isn’t safe for all cases. - Modern Alternative: $wpdb->prepare() uses placeholders (e.g., %s) for robust sanitization. - Vulnerability: $wpdb->escape() fails with malicious input like '; DROP TABLE wp_users; --, allowing injection, while prepare() prevents it. - Output: Shows how prepare() generates a secure query string. Avoid $wpdb->escape() in new code; use $wpdb->prepare() for all dynamic queries to ensure security. This method is a relic of older WordPress versions.Last Query: ' . esc_html( $wpdb->last_query ) . '
'; // Outputs: Last Query: SELECT * FROM wp_posts WHERE post_status = 'publish' LIMIT 2 // Example 2: With prepare() $user_id = get_current_user_id(); $query = $wpdb->prepare( "SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, 'nickname' ); $wpdb->get_var( $query ); echo 'Last Query: ' . esc_html( $wpdb->last_query ) . '
'; // Outputs: Last Query: SELECT meta_value FROM wp_usermeta WHERE user_id = 1 AND meta_key = 'nickname' // Example 3: Debug a failing query $wpdb->query( "SELCT * FROM $wpdb->posts" ); // Typo in SELECT if ( $wpdb->last_error ) { echo 'Error: ' . esc_html( $wpdb->last_error ) . '
'; echo 'Last Query: ' . esc_html( $wpdb->last_query ) . '
'; // Outputs: // Error: You have an error in your SQL syntax... // Last Query: SELCT * FROM wp_posts } // Example 4: Insert and inspect $wpdb->insert( $wpdb->prefix . 'user_logs', array( 'user_id' => 1, 'action' => 'test' ) ); echo 'Last Query: ' . esc_html( $wpdb->last_query ) . '
'; // Outputs: Last Query: INSERT INTO wp_user_logs (user_id, action) VALUES (1, 'test') ?> Key Features - Type: String containing the last executed SQL query. - Set By: Any $wpdb method that runs a query (e.g., query(), get_results(), insert(), update()). - Usage: Debugging tool to see the exact query, especially after errors or unexpected results. - Scope: Updates with each query in the current request; reflects prepared values. Explanation - Simple Query: Shows the full SELECT query run by get_results(). - Prepared Query: Displays the substituted query from prepare() (e.g., with user_id = 1). - Error Debug: Pairs with $wpdb->last_error to reveal a typo (SELCT) causing failure. - Insert: Logs the exact INSERT statement executed. Use $wpdb->last_query for debugging SQL issues; escape with esc_html() for safe output. It’s invaluable for tracing what $wpdb actually ran.Table changes: ' . esc_html( print_r( $result, true ) ) . '
'; } else { echo 'No changes needed.
'; } } register_activation_hook( __FILE__, 'my_create_table' ); // Example 2: Update table structure function my_update_table() { global $wpdb; $table_name = $wpdb->prefix . 'user_logs'; $charset_collate = $wpdb->get_charset_collate(); // Add a new column and index $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, action varchar(50) NOT NULL, log_time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, status varchar(20) DEFAULT 'active', -- New column PRIMARY KEY (id), KEY user_id (user_id), KEY status (status) -- New index ) $charset_collate;"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $result = dbDelta( $sql ); if ( ! empty( $result ) ) { echo 'Updated table: ' . esc_html( print_r( $result, true ) ) . '
'; } } add_action( 'admin_init', 'my_update_table' ); ?> Key Features - Parameter: -- $sql: SQL string with CREATE TABLE or ALTER TABLE statements (multiple allowed, separated by ;). - Returns: Array of changes made (e.g., 'Created table wp_user_logs', 'Added column status'), or empty array if no changes. - Behavior: -- Creates tables if they don’t exist. -- Modifies existing tables (adds columns, updates keys) without dropping data. -- Ignores unchanged definitions. - Requirements: Needs wp-admin/includes/upgrade.php included. Explanation - Create: Defines wp_user_logs with columns and indexes on activation; creates if missing. - Update: Adds status column and index to wp_user_logs if not present, preserving existing data. - Result: $result logs actions (e.g., table creation, column addition) for debugging. Use dbDelta() for safe schema management in plugins/themes; pair with $wpdb->prefix and $wpdb->get_charset_collate() for portability. Avoid raw DROP or destructive changes—it’s additive.Post Title: ' . esc_html( $row->post_title ) . ' (ID: ' . $row->ID . ')
'; } else { echo 'No published posts found.
'; } // Example 2: Safe query with prepare, array output $post_id = 123; $query = $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = %d LIMIT 1", $post_id ); $row = $wpdb->get_row( $query, ARRAY_A ); // Associative array if ( $row ) { echo 'Meta: ' . esc_html( $row['meta_key'] ) . ' = ' . esc_html( $row['meta_value'] ) . '
'; } // Example 3: Numeric array output $query = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'page' LIMIT 1"; $row = $wpdb->get_row( $query, ARRAY_N ); // Numeric array if ( $row ) { echo 'Page: ' . esc_html( $row[1] ) . ' (ID: ' . $row[0] ) . '
'; } // Example 4: Custom table with error check $query = $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "user_logs WHERE user_id = %d LIMIT 1", get_current_user_id() ); $row = $wpdb->get_row( $query ); if ( $row ) { echo 'Last Log: ' . esc_html( $row->action ) . ' at ' . $row->log_time . '
'; } elseif ( $wpdb->last_error ) { echo 'Error: ' . esc_html( $wpdb->last_error ) . '
'; } ?> Key Features - Parameters: -- $query: SQL query string (e.g., "SELECT * FROM $wpdb->posts WHERE ID = 1"). -- $output (optional): OBJECT (default), ARRAY_A (associative array), ARRAY_N (numeric array). -- $y (optional): Row offset (default 0, typically unused as it’s single-row). - Returns: Row as an object (e.g., $row->ID), array (e.g., $row['ID'] or $row[0]), or null if no result or error (check $wpdb->last_error). - Safety: Use $wpdb->prepare() for dynamic values to prevent SQL injection. Explanation - Object: Fetches the first published post as an object (e.g., $row->post_title). - Associative Array: Gets a meta row for a post as an array (e.g., $row['meta_value']). - Numeric Array: Retrieves a page row with numeric keys (e.g., $row[1] for title). - Custom Table: Pulls a user log row, with error checking via $wpdb->last_error. Use $wpdb->get_row() for single-row queries (e.g., one record); it’s more targeted than $wpdb->get_results() for multiple rows.Switched to Blog ID: ' . esc_html( $wpdb->blogid ) . '
'; // 2 echo 'Posts table: ' . esc_html( $wpdb->posts ) . '
'; // wp_2_posts // Query posts from blog 2 $posts = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'publish'" ); echo 'Published posts in Blog 2: ' . esc_html( $posts ) . '
'; restore_current_blog(); echo 'Restored to Blog ID: ' . esc_html( $wpdb->blogid ) . '
'; // Back to 1 } // Example 3: Dynamic table prefix function my_multisite_query() { global $wpdb; $blog_id = $wpdb->blogid; $table = $wpdb->prefix . 'custom_table'; // e.g., wp_custom_table or wp_2_custom_table $count = $wpdb->get_var( "SELECT COUNT(*) FROM $table" ); echo 'Blog ' . esc_html( $blog_id ) . ' custom table rows: ' . esc_html( $count ) . '
'; } add_action( 'wp_footer', 'my_multisite_query' ); // Example 4: Check in single site if ( ! is_multisite() ) { echo 'Single Site Blog ID: ' . esc_html( $wpdb->blogid ) . '
'; // Always 1 } ?> Key Features - Type: Integer representing the current blog’s ID. - Context: -- Single Site: Always 1. -- Multisite: Matches the current blog (changes with switch_to_blog()). - Usage: Influences $wpdb->prefix (e.g., 'wp_' for blog 1, 'wp_2_' for blog 2) and table properties (e.g., $wpdb->posts). - Dynamic: Updates automatically when switching blogs in multisite. Explanation - Display: Shows the current $wpdb->blogid (e.g., 1 or 2 in multisite). - Switch: Demonstrates $wpdb->blogid changing from 1 to 2 with switch_to_blog(2), affecting $wpdb->posts. - Query: Uses $wpdb->blogid to contextually reference a custom table across blogs. - Single Site: Confirms $wpdb->blogid remains 1 in non-multisite setups. Use $wpdb->blogid in multisite to track or adjust queries for the current blog; it’s key for prefix-aware operations.Testing WP_DEBUG
'; } add_action( 'wp_footer', 'my_debug_test' ); // Example: Check WP_DEBUG in code function my_conditional_debug() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { echo 'Debug mode is active!
'; error_log( 'Debug logging is working.' ); // Logs if WP_DEBUG_LOG is true } } add_action( 'wp_footer', 'my_conditional_debug' ); ?> Key Features - Definition: Set in wp-config.php with define( 'WP_DEBUG', true );. - Default: false (no debugging output in production). - Related Constants: -- WP_DEBUG_LOG: true writes errors to wp-content/debug.log; path customizable since WP 5.1. -- WP_DEBUG_DISPLAY: true (default when WP_DEBUG is true) shows errors on-screen; false hides them. - Impact: Enables E_ALL error reporting when true, revealing notices, warnings, and fatal errors. - Scope: Affects all PHP execution in WordPress (core, plugins, themes). Explanation - Basic Setup: WP_DEBUG enabled shows errors like undefined variables or custom notices on-screen. - Logging: With WP_DEBUG_LOG true and WP_DEBUG_DISPLAY false, errors go to debug.log (e.g., Notice: Undefined index: key). - Test: Triggers a notice and custom message, visible or logged based on settings. - Conditional: Checks WP_DEBUG status to run debug-specific code. Use WP_DEBUG during development to catch issues; disable in production (false) and secure with WP_DEBUG_DISPLAY off. Pair with WP_DEBUG_LOG for persistent error tracking.An error occurred while processing your request.
', 'Error Occurred', array( 'response' => 403, 'back_link' => true ) ); } add_action( 'wp_footer', 'my_custom_die' ); // Example 3: AJAX context add_action( 'wp_ajax_my_action', 'my_ajax_handler' ); function my_ajax_handler() { check_ajax_referer( 'my_nonce', 'security' ); if ( ! isset( $_POST['data'] ) ) { wp_die( 'Missing data parameter.', '', array( 'response' => 400 ) ); } wp_send_json_success( 'Data received: ' . sanitize_text_field( $_POST['data'] ) ); } // Example 4: Debug with backtrace function my_debug_die() { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { wp_die( 'Debugging halt!
' . esc_html( print_r( debug_backtrace(), true ) ) . '', 'Debug Stop' ); } } add_action( 'init', 'my_debug_die' ); ?> Key Features - Parameters: -- $msg: Message or HTML to display (string). -- $title (optional): Page title (default 'Error'). -- $args (optional): Array or string (e.g., array('response' => 403, 'back_link' => true )): --- response: HTTP status code (default 200). --- back_link: Adds a “Go back” link (default false). --- exit: Whether to exit (default true). - Returns: None; terminates execution unless exit is false in $args. - Context: Formats output for admin screens or plain text for AJAX/CLI. Explanation - Basic: Stops execution with a permission error, showing a styled message. - Custom: Displays an error with a title and 403 status, including a back link. - AJAX: Sends a 400 error for missing data, halting the AJAX request. - Debug: Shows a backtrace in debug mode, useful for tracing execution. Use wp_die() to halt execution with user feedback (errors, permissions); it’s safer than die() or exit() due to WordPress styling and hooks.
Value: ' . esc_html( $value ) . '
'; } add_action( 'wp_footer', 'my_set_basic_transient' ); // Example 2: Cache an API call function my_fetch_api_data() { $key = 'my_api_data'; $data = get_transient( $key ); if ( false === $data ) { // Simulate API call $data = wp_remote_retrieve_body( wp_remote_get( 'https://api.example.com/data' ) ); set_transient( $key, $data, HOUR_IN_SECONDS ); // Cache for 1 hour error_log( 'API data fetched and cached.' ); } echo 'API Data: ' . esc_html( $data ) . '
'; } add_action( 'wp_footer', 'my_fetch_api_data' ); // Example 3: Cache query results function my_cache_query() { $key = 'my_post_titles'; $titles = get_transient( $key ); if ( false === $titles ) { global $wpdb; $titles = $wpdb->get_col( "SELECT post_title FROM $wpdb->posts WHERE post_status = 'publish' LIMIT 5" ); set_transient( $key, $titles, DAY_IN_SECONDS ); // Cache for 1 day } echo 'Permanent Data: ' . esc_html( get_transient( 'my_permanent_data' ) ) . '
'; ?> Key Features - Parameters: -- $key: Unique transient name (string, max 172 characters). -- $value: Data to store (string, array, object, etc.). -- $expiration: Seconds until expiry (integer; 0 = no expiry, max ~30 days in default setup). - Returns: true if set successfully, false if failed (e.g., database error). - Storage: Saved as an option with _transient_ prefix (e.g., _transient_my_key); leverages object cache if active (e.g., Memcached). - Expiry: Automatically removed after $expiration or via delete_transient(). Explanation - Basic: Sets 'my_transient' for 60 seconds, retrieving it immediately. - API Cache: Caches API data for an hour, fetching only if expired. - Query Cache: Stores post titles for a day, reducing database load. - No Expiry: Sets 'my_permanent_data' without expiration, persisting until manually deleted. Use set_transient() for temporary caching; pair with get_transient() and delete_transient() for full control. Ideal for performance optimization.Transient found: ' . esc_html( $value ) . '
'; } } add_action( 'wp_footer', 'my_get_basic_transient' ); // Example 2: Cache an API call function my_fetch_api_data() { $key = 'my_api_data'; $data = get_transient( $key ); if ( false === $data ) { // Simulate API call $data = wp_remote_retrieve_body( wp_remote_get( 'https://api.example.com/data' ) ); set_transient( $key, $data, HOUR_IN_SECONDS ); // Cache for 1 hour error_log( 'API data fetched and cached.' ); } echo 'API Data: ' . esc_html( $data ) . '
'; } add_action( 'wp_footer', 'my_fetch_api_data' ); // Example 3: Cache query results function my_cache_query() { $key = 'my_post_titles'; $titles = get_transient( $key ); if ( false === $titles ) { global $wpdb; $titles = $wpdb->get_col( "SELECT post_title FROM $wpdb->posts WHERE post_status = 'publish' LIMIT 5" ); set_transient( $key, $titles, DAY_IN_SECONDS ); // Cache for 1 day } echo 'Non-existent: ' . ( $permanent === false ? 'Not found' : esc_html( $permanent ) ) . '
'; ?> Key Features - Parameter: -- $key: The transient name (string, e.g., 'my_transient'). - Returns: -- Stored value (string, array, etc.) if valid and unexpired. -- false if expired, deleted, or never set. - Storage: Retrieved from _transient_$key in wp_options or object cache (e.g., Memcached). - Expiration: Managed by set_transient(); returns false post-expiry. Explanation - Basic: Retrieves 'my_transient', setting it if missing (expires in 60 seconds). - API Cache: Fetches cached API data or re-queries and caches for an hour if expired. - Query Cache: Gets cached post titles or queries and caches for a day if not found. - Non-existent: Returns false for an unset key, allowing conditional logic. Use get_transient() to access cached data; check for false to handle misses or expirations. Pair with set_transient() for caching workflows.Transient deleted.
'; } echo 'After: ' . ( get_transient( $key ) === false ? 'Gone' : esc_html( get_transient( $key ) ) ) . '
'; } add_action( 'wp_footer', 'my_delete_transient' ); // Example 2: Clear API cache function my_clear_api_cache() { $key = 'my_api_data'; if ( get_transient( $key ) !== false ) { delete_transient( $key ); error_log( 'API cache cleared.' ); echo 'API cache cleared.
'; } // Re-fetch on next call my_fetch_api_data(); } add_action( 'admin_init', 'my_clear_api_cache' ); function my_fetch_api_data() { $key = 'my_api_data'; $data = get_transient( $key ); if ( false === $data ) { $data = 'Simulated API Data'; // Simulate API call set_transient( $key, $data, HOUR_IN_SECONDS ); } } // Example 3: Cleanup on deactivation function my_plugin_deactivate() { delete_transient( 'my_post_titles' ); delete_transient( 'my_api_data' ); error_log( 'Transients cleaned up on deactivation.'); } register_deactivation_hook( __FILE__, 'my_plugin_deactivate' ); // Example 4: Non-existent key $deleted = delete_transient( 'non_existent_key' ); echo 'Delete non-existent: ' . ( $deleted ? 'Success (or didn’t exist)' : 'Failed' ) . '
'; ?> Key Features - Parameter: -- $key: The transient name to delete (string, e.g., 'my_transient'). - Returns: -- true: Successfully deleted or didn’t exist. -- false: Deletion failed (e.g., database error). - Storage: Removes _transient_$key from wp_options or clears from object cache (e.g., Memcached). - Scope: Affects only the specified transient; expiration is ignored. Explanation - Basic: Sets 'my_transient', deletes it, and confirms it’s gone. - API Cache: Clears 'my_api_data' if it exists, forcing a refresh on the next fetch. - Cleanup: Deletes 'my_post_titles' and 'my_api_data' during plugin deactivation. - Non-existent: Returns true for a non-existent key, as no action is needed. Use delete_transient() to manually clear cached data; it’s proactive cleanup, unlike waiting for expiration. Pair with set_transient() and get_transient() for full cache control.Event Location: ' . esc_html($event_location) . '
'; ?> ``` **Explanation**: - **`get_field('event_date')`**: Retrieves the value of the `event_date` custom field. - **`get_field('event_location')`**: Retrieves the value of the `event_location` custom field. - **`esc_html()`**: Used to safely output the data to prevent XSS attacks. --- **Summary** - **Creating Custom Fields Programmatically**: You can use `acf_add_local_field_group()` to create custom fields and assign them to post types or taxonomies programmatically. - **Adding Data to Custom Fields**: Use `update_field()` to programmatically set or update the values of the custom fields. - **Displaying Custom Fields**: Use `get_field()` in your templates to retrieve and display the custom field values. This approach allows you to handle custom fields programmatically, giving you full control over custom field creation, value assignment, and display in WordPress.Thank you for reading this post!
'; // Append a custom message } return $content; // Return the modified content } // Hook into 'the_content' filter to modify post content add_filter('the_content', 'modify_post_content'); ``` **Explanation**: - **Filter Hook**: `the_content` is a filter that modifies the content of the post before it is displayed. - **Filter**: The `modify_post_content()` function appends a custom message to the post content if it's a single post. --- **Key Differences:** 1. **Purpose**: - **Action**: Performs an operation (e.g., logging, sending emails, changing settings) without modifying data directly. - **Filter**: Modifies data before it is returned or displayed (e.g., content, text, or other values). 2. **Return Values**: - **Action**: Actions typically do not return a value (they are used to trigger functions at certain times). - **Filter**: Filters always return a modified version of the input data. 3. **Use Cases**: - **Action**: Used for operations that should be performed at specific times, like sending notifications or performing background tasks. - **Filter**: Used for modifying data, like changing the post content, altering form submissions, or adjusting settings. --- **Summary**: - **Action Hooks** (`add_action`): Allow you to execute code at specific points in WordPress’s lifecycle (e.g., sending emails, logging data). - **Filter Hooks** (`add_filter`): Allow you to modify data before it is displayed or saved (e.g., changing post content, modifying strings). Both actions and filters are essential tools in WordPress for extending and customizing the functionality of a site.No options available for this widget.
'; } // Update function for widget options public function update( $new_instance, $old_instance ) { // No options to update, so we return the old instance return $old_instance; } } // Register the custom widget function register_welcome_message_widget() { register_widget( 'Welcome_Message_Widget' ); } // Hook into WordPress to register the widget add_action( 'widgets_init', 'register_welcome_message_widget' ); ?> ``` **Explanation of the Code**: 1. **Class Definition**: - The `Welcome_Message_Widget` class extends the `WP_Widget` class. - The `__construct()` method defines the widget's name, ID, and description. 2. **`widget()` Method**: - This method outputs the widget content on the front-end. In this case, it simply displays the hardcoded message `Welcome to my site!` within an `
```
- Use **Smush** or **Lazy Load by WP Rocket** for better control.
✅ **Reduces initial page load time & improves Core Web Vitals.**
---
**Summary**
✔ **Use a Page Cache plugin (WP Rocket, W3 Total Cache)**
✔ **Enable Object Caching with Redis/Memcached**
✔ **Use Browser Caching via `.htaccess`**
✔ **Enable OPcache for PHP scripts**
✔ **Use Transients API to cache queries**
✔ **Offload static assets with a CDN**
✔ **Lazy load images to reduce initial load**
🚀 **A combination of these caching techniques dramatically improves WordPress performance and reduces server load!**
Hello, this is a custom shortcode!
'; } add_shortcode('custom_hello', 'custom_hello_shortcode'); ``` ✅ **Usage:** ```html [custom_hello] ``` ✅ **Output:** ```htmlHello, this is a custom shortcode!
``` --- **2️⃣ Shortcode with Attributes** Allow users to **pass parameters**: ```php function custom_greeting_shortcode($atts) { $atts = shortcode_atts(array( 'name' => 'Guest' ), $atts, 'custom_greeting'); return 'Hello, ' . esc_html($atts['name']) . '!
'; } add_shortcode('custom_greeting', 'custom_greeting_shortcode'); ``` ✅ **Usage:** ```html [custom_greeting name="John"] ``` ✅ **Output:** ```htmlHello, John!
``` --- **3️⃣ Shortcode with Dynamic Content** Example: Display the current date dynamically. ```php function show_current_date_shortcode() { return 'Today is ' . date('F j, Y') . '.
'; } add_shortcode('current_date', 'show_current_date_shortcode'); ``` ✅ **Usage:** `[current_date]` ✅ **Output:** `"Today is March 2, 2025."` --- **4️⃣ Shortcode Inside PHP Files** Use `do_shortcode()` to render a shortcode inside a theme file: ```php echo do_shortcode('[custom_greeting name="Alice"]'); ``` --- **5️⃣ Removing a Shortcode** To disable a shortcode: ```php remove_shortcode('custom_hello'); ``` --- **Summary** ✔ **Use `add_shortcode()` to register shortcodes** ✔ **Use `shortcode_atts()` to handle attributes** ✔ **Use `do_shortcode()` to render shortcodes in PHP files** ✔ **Always sanitize output (`esc_html()`) for security** 🚀 **Shortcodes make WordPress more flexible by allowing dynamic content anywhere!**Hello from My Plugin!
'; } add_shortcode('custom_hello', 'custom_hello_shortcode'); ``` ✅ **Use `[custom_hello]` anywhere to display the message.** --- **5️⃣ Add a Plugin Settings Page (Optional)** For user configuration, create an admin settings page. ```php function custom_plugin_menu() { add_menu_page('Custom Plugin Settings', 'Custom Plugin', 'manage_options', 'custom-plugin', 'custom_plugin_settings'); } add_action('admin_menu', 'custom_plugin_menu'); function custom_plugin_settings() { echo 'Hello, Gutenberg!
; }, save: () => { returnHello, Gutenberg!
; } }); ``` ✅ **Defines how the block appears in the editor and frontend.** --- **5️⃣ Load JavaScript & CSS Files for Blocks** Register and enqueue block assets in `functions.php`: ```php function enqueue_block_assets() { wp_enqueue_script( 'custom-block-js', get_template_directory_uri() . '/blocks/custom-block/index.js', array('wp-blocks', 'wp-editor', 'wp-element'), filemtime(get_template_directory() . '/blocks/custom-block/index.js') ); wp_enqueue_style( 'custom-block-style', get_template_directory_uri() . '/blocks/custom-block/style.css' ); } add_action('enqueue_block_editor_assets', 'enqueue_block_assets'); ``` ✅ **Ensures the block loads only in the editor.** --- **6️⃣ Styling Gutenberg Blocks (`style.css` & `editor.css`)** Add custom block styles in `style.css` (frontend) and `editor.css` (editor view). ```css .wp-block-custom-block { background: #f3f4f6; padding: 20px; border-radius: 5px; } ``` ✅ **Applies styles to block output.** --- **7️⃣ Use the Block in a Page or Post** After adding the block, it appears in the **Gutenberg editor** under **"Custom Blocks"**. 📌 You can insert it directly via the block inserter. --- **Summary** ✔ **Enable Gutenberg support in `functions.php`.** ✔ **Register a block using `block.json` and `register_block_type()`.** ✔ **Write block logic in JavaScript (`index.js`).** ✔ **Load block assets (`enqueue_block_editor_assets`).** ✔ **Style the block with CSS (`style.css` & `editor.css`).** 🚀 **Custom Gutenberg blocks enhance WordPress themes with modern, dynamic content!**Hello, ' . esc_html($atts['name']) . '!
'; } add_shortcode('greeting', 'custom_greeting_shortcode'); ``` ✅ **Using the Shortcode in a Post/Page** ```html [greeting name="John"] ``` 💡 **Best for:** Dynamic content inside posts, pages, and widgets. --- **Key Differences** - **Widgetized Areas** → **Fixed theme locations** (sidebars, footers). - **Shortcodes** → **Flexible placement inside posts, pages, or widgets**. - **Widgets require user configuration** in the **Widgets menu**, while **shortcodes are inserted directly in content**. 🚀 **Use widgets for structured layouts and shortcodes for inline dynamic content!**Hello, {{ $user->name }}
@endif ``` Blade compiles this into a simple, efficient PHP structure: ```phpHello, name); ?>
``` - **`{{ }}`** is compiled into PHP’s **`echo`** statement. - Blade eliminates unnecessary syntax and reduces the need for repetitive function calls, making the execution faster. This **optimization reduces overhead** and makes template rendering more efficient than a raw PHP implementation with complex conditionals and loops. --- **3️⃣ Blade’s Template Inheritance** Blade’s template inheritance system allows you to define a **base layout** for your views and then extend that layout for individual pages. This reduces the need for repetitive HTML structure, leading to more efficient views and better code reusability. **Example of Blade Template Inheritance:** In a base layout file (`resources/views/layouts/app.blade.php`), you define a common layout structure: ```bladeThis is the content of the home page.
@endsection ``` - **Efficiency**: The base layout is only processed once, and the dynamic content is injected into the appropriate sections. Blade’s inheritance system allows you to avoid repeating the same structure, making your views cleaner and more efficient. - **Code Reusability**: By reusing layouts, you avoid repeating the same code, leading to **better maintainability** and **improved performance** by reducing the size of the templates. --- **4️⃣ Minimizing Template Logic** Blade encourages developers to keep logic out of templates by providing simple control structures, such as loops and conditionals, that are translated into efficient PHP code. **Example: Conditional Rendering in Blade** ```blade @if ($user)Hello, {{ $user->name }}
@elseGuest
@endif ``` - Blade automatically compiles this into efficient PHP that doesn’t involve expensive function calls or multiple checks, ensuring minimal performance impact. Additionally, Blade provides the **`@forelse`** directive for looping with fallback behavior, allowing efficient loop handling in one concise statement. **Example of Looping:** ```blade @forelse ($users as $user){{ $user->name }}
@emptyNo users found.
@endforelse ``` This reduces the need for manual `if` checks and helps avoid redundant conditional checks, improving performance when rendering dynamic lists or content. --- **5️⃣ Blade's `@include` Directive for Partial Views** Blade provides an `@include` directive for including partial views (sub-views), which allows for better **view modularity** and reduced view rendering time. **Example: Including Partial Views** ```blade @include('partials.header') ``` - **Caching**: Partial views are cached by Blade, just like regular views, so including them won’t require recompilation with every request. - **Reduced Redundancy**: Since Blade caches and reuses partial views, it avoids unnecessary repetition of code, improving performance. --- **6️⃣ Blade's Optimized Rendering** Blade uses **inline PHP** for most of its rendering, meaning that simple operations (like echoing variables or checking conditions) are compiled into minimal PHP code, which executes faster than other templating engines that use more complex parsing systems. --- **Summary of Blade's Impact on PHP Performance** - **View Caching**: Blade compiles views into optimized PHP code and caches them, reducing the need for re-compilation on subsequent requests, which improves performance. - **Efficient Template Parsing**: Blade parses the templates once and compiles them into efficient PHP code, eliminating the overhead of interpreting Blade syntax on each request. - **Template Inheritance**: Blade's template inheritance allows for reduced redundancy in view structure, improving maintainability and speeding up rendering. - **Minimized Template Logic**: Blade encourages minimal logic in views, making them faster to render and reducing unnecessary function calls. - **Modularity and Partial Views**: Blade’s `@include` directive helps reuse components efficiently, which can speed up page rendering. --- **In Conclusion** Blade templating improves **PHP performance** in Laravel by caching views, compiling templates into optimized PHP code, and encouraging better practices for modularity, logic separation, and reduced redundancy. Blade’s efficient rendering helps make Laravel applications faster while providing a cleaner, more maintainable way to manage views.{{ $user->email }}
{{ user.email }}
{{ count }}
``` **When to Use**: - This approach works well for simpler, hierarchical components where only a few components need to share state. --- **3. Vuex (Global State Management)** For larger applications, **Vuex** is the most commonly used state management pattern and library for Vue.js. Vuex provides a centralized store to manage the state, making it easier to maintain the state across various components. - **State**: Centralized data that you want to share across components. - **Mutations**: Functions that modify the state. - **Actions**: Functions that can perform asynchronous operations and then commit mutations. - **Getters**: Functions that retrieve computed state from the store. Example of using Vuex: 1. **Store Configuration**: ```javascript // store.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { incrementAsync({ commit }) { setTimeout(() => { commit('increment'); }, 1000); } }, getters: { count(state) { return state.count; } } }); ``` 2. **Using the Store in Components**: ```javascript // Component.vue{{ count }}
{{ state.count }}