Build WordPress plugins from scratch: actions and filters, shortcodes, settings pages, custom post types, meta boxes, AJAX, REST endpoints, custom tables, cron and blocks.
Lessons
The Options API stores site-wide values in the wp_options table under a unique name, and its four functions — add_option(), get_option(), update_option() and delete_option() — are the simplest way for a plugin to remember settings and small pieces of state.
<?php
// Create, only if it does not exist yet.
add_option( 'gdc_books_installed_at', time() );
// Read, with a default for when it is missing.
$settings = get_option( 'gdc_books_settings', array() );
// Create or overwrite.
update_option( 'gdc_books_last_import', current_time( 'mysql' ) );
// Remove.
delete_option( 'gdc_books_last_import' );Options store any PHP value — strings, numbers, arrays, objects. WordPress serialises them automatically, so arrays come back as arrays.
An option saved by an older version of your plugin may be missing keys you added later. Merge with defaults every time you read it:
<?php
function gdc_books_get_settings() {
$defaults = array(
'books_per_page' => 6,
'show_isbn' => 1,
'currency' => 'USD',
);
return wp_parse_args( get_option( 'gdc_books_settings', array() ), $defaults );
}
// Everywhere else in the plugin:
$per_page = gdc_books_get_settings()['books_per_page'];On every request, WordPress loads all autoloaded options in a single query and keeps them in memory. That makes get_option() instant for them — but every autoloaded option costs memory on every page, even pages that never use it.
<?php
// Needed on most requests: autoload (the default).
update_option( 'gdc_books_settings', $settings );
// Large, or only needed on one admin screen: do not autoload.
update_option( 'gdc_books_import_log', $big_log_array, false );Watch out: A plugin that stores a few megabytes in an autoloaded option slows down every page of the site. Check Tools → Site Health → Info for the total autoloaded size; WordPress warns when it gets too large.
| Data | Better home |
|---|---|
| Settings for the whole site | An option |
| Data about one post (ISBN, price) | Post meta — lesson 16 |
| Data about one user (favourites) | User meta: update_user_meta() |
| Temporary cached results | A transient — lesson 21 |
| Thousands of rows you need to query | A custom table — lesson 20 |
Storing every book's data in one giant option is a classic beginner mistake. It cannot be queried, it grows without limit, and two admins saving at once overwrite each other.
gdc_books_get_settings() with defaults and use it everywhere you read settings.wp_options table.In accordance with Section 6 & Section 7 of the DPDP Act 2023, third-party analytics and marketing trackers are strictly gated behind your affirmative consent. You may withdraw consent at any time under Section 6(4).
Essential for session authentication (ci_session), Cross-Site Request Forgery security (csrf_cookie_name), and Cloudflare DDoS/bot prevention. Cannot be disabled.
Gated under DPDP Section 7. Allows Google Analytics 4 (Google Consent Mode v2) to measure aggregate, anonymized tool usage.
Enables browser local storage to preserve your theme selection (dark/light mode) and code editor layout between visits.
Used to display developer sponsorships and native tool partner notices.