Settings Screens
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This sub-section’s WordPress bibliography lists the reference material consulted while preparing these pages. |
This page was written against WordPress 7.1.3 (released 2026-10-06; 7.1.4, a security release of 2026-10-28, is the
version to run in production) and WP-CLI 2.12.0, and checked on 2026-10-28. WordPress 7.1 requires PHP 7.4 at minimum,
and PHP 8.3 or newer is recommended. WordPress 7.2 is in beta and planned for
2026-12-08. Every option name, default value and command output below was read from a fresh WordPress 7.1.3 site
(official wordpress:7.1.3-php8.4-apache image, MariaDB 11.8, table prefix lp_), and the robots, permalink and
Connectors behaviour was observed over HTTP on that site.
The Settings menu is where an administrator sets the site-wide defaults of Lumen Press, the fictitious publisher used
throughout this sub-section: its name and time zone, a static home page with the news blog on a separate page, the
comment policy, image sizes, clean URLs and the privacy policy page. Every field on these screens is a row in the
wp_options table (lp_options for Lumen Press, see Database Schema), so
each one can also be read and written with wp option, scripted for staging copies, and checked in code with
get_option().
How the Settings screens work
Five of the eight screens are plain HTML forms that post to wp-admin/options.php. That file holds an allow list
of option names per screen (the $allowed_options array, filtered by allowed_options), checks the nonce and the
manage_options capability, saves only the options in the list for the submitted screen, and redirects back. Plugins
add their own fields to these screens with the Settings API (register_setting(), add_settings_field()), which
appends to the same allow list; that API is covered in
Administration Menus and Settings API.
| Menu item | File | Capability | Saved through |
|---|---|---|---|
General |
|
|
|
Connectors (7.0) |
|
|
REST API ( |
Writing |
|
|
|
Reading |
|
|
|
Discussion |
|
|
|
Media |
|
|
|
Permalinks |
|
|
the screen itself |
Privacy (4.9.6) |
|
|
the screen itself |
The menu order in 7.1 is General, Connectors, Writing, Reading, Discussion, Media, Permalinks, Privacy; plugins usually add their own pages below Privacy. Connectors is a JavaScript application that saves through the REST API, and Permalinks and Privacy process their own form. On a Multisite network, a sub-site’s General screen has no URL fields and no Membership section, because those belong to the network (Multisite Networks).
Part of the same options is exposed by the REST API at /wp/v2/settings to users with manage_options. On the Lumen
Press site, the endpoint returned these keys (plus one per active AI provider, see Connectors (7.0)):
title description url email timezone date_format time_format start_of_week language use_smilies
default_category default_post_format posts_per_page show_on_front page_on_front page_for_posts
default_ping_status default_comment_status site_logo site_icon
Source: REST API Handbook: Settings
The REST names are aliases: title is blogname, description is blogdescription, url is home, email is
admin_email, timezone is timezone_string and language is WPLANG.
General
General holds the identity of the site and how it formats dates.
| Field | Option | Default | Notes |
|---|---|---|---|
Site Title |
|
value entered at install |
Shown by most themes and in the feed title. |
Tagline |
|
empty |
Empty by default; the placeholder text is only a hint. |
Site Icon |
|
|
Attachment ID. On this screen since 6.5 (before that only in the Customizer; block themes also set it in the Site Editor). At least 512 × 512 pixels. |
WordPress Address (URL) |
|
install URL |
Where the core files live. Locked when |
Site Address (URL) |
|
install URL |
The public address. Locked when |
Administration Email Address |
|
install email |
A change is not applied until it is confirmed by email (see below). |
Membership: Anyone can register |
|
|
Opens |
New User Default Role |
|
|
Role given to self-registered users and the preselected role in Users > Add New. |
Site Language |
|
absent (English, |
Downloads the language pack when the file system is writable. A |
Timezone |
|
|
Choose a city, not an offset, so daylight saving time is followed. |
Date Format |
|
|
PHP date characters, used by themes and blocks, not by most admin lists. |
Time Format |
|
|
|
Week Starts On |
|
|
|
The two URL fields are the most dangerous fields in the admin. A typo in either one makes the dashboard unreachable,
because every redirect then points to the wrong host. The recovery is to fix the value outside the admin: with
wp option update home and wp option update siteurl, or by defining WP_HOME and WP_SITEURL in wp-config.php,
which overrides the database and locks the fields. Both URLs differ only when WordPress is
given its own directory.
Changing the domain of an existing site needs a search and replace through the content as well, covered in
Importing, Exporting and Migrating.
The administration email is where WordPress sends update results, fatal-error recovery-mode links, new-user and
comment-moderation notices. Since 4.9, a change made on the screen is stored in new_admin_email, a hash goes into
adminhash, and a confirmation link is mailed to the new address; admin_email changes only when the link is
followed. On a site that cannot send mail, the change never completes. There is no WP_ADMIN_EMAIL constant, which
one older book suggests; the address can only be changed through the screen, the REST API or WP-CLI. Writing the option
directly skips the confirmation:
# Screen-equivalent: stores the pending address and mails a confirmation link
wp eval 'wp_set_current_user( 1 ); update_option( "new_admin_email", "editors@lumenpress.example" );'
wp option get adminhash --format=json # {"hash":"<hash>","newemail":"editors@lumenpress.example"}
# Direct change without confirmation (for scripted setups and lost mailboxes)
wp option update admin_email editors@lumenpress.example
wp option delete adminhash new_admin_email
The time zone is stored in one of two options. Choosing a city stores timezone_string (for example
Europe/Madrid) and leaves gmt_offset alone; choosing a "UTC+1" style entry stores gmt_offset and empties
timezone_string. When timezone_string is set, a filter (wp_timezone_override_offset()) recomputes gmt_offset on
every read: on the Lumen Press site, wp option get gmt_offset printed 1 while the stored row still held 0. Code
should call wp_timezone() or wp_date() instead of reading either option.
Connectors (7.0)
WordPress 7.0 added the AI Client, a provider-neutral PHP API (wp_ai_client_prompt()) that plugins use to send
prompts, and the Connectors API that stores the credentials for it. Settings > Connectors is the screen for those
credentials. Core bundles no AI provider: the screen lists three featured connectors (Anthropic, Google and
OpenAI), and each needs its provider plugin (ai-provider-for-anthropic, ai-provider-for-google,
ai-provider-for-openai) before a key can be entered. The screen also lists Akismet, the one non-AI connector core
registers, which reuses Akismet’s existing wordpress_api_key option. A notice on the screen offers the separate "AI"
plugin, which adds a Settings > AI screen and the editor features (titles, excerpts, alt text, images) that actually
use the connectors.
Each connector is a card with its name, description, a link to the provider’s key page, an Install or Activate button when its plugin is missing, and, once the plugin is active, a key field and the connection status. The screen needs JavaScript; without it, it shows only an error notice.
| Connector | Database option | Environment variable and PHP constant |
|---|---|---|
Anthropic |
|
|
|
|
|
OpenAI |
|
|
Akismet (spam filtering) |
|
constant |
Other AI providers |
|
|
How keys behave, as verified on WordPress 7.1.3:
-
Lookup order. An environment variable wins over a PHP constant, which wins over the database option. When the key comes from the environment or a constant, the screen shows its source and does not store anything.
-
Storage. A key typed into the screen is saved in
wp_optionsin plain text. It is masked in the interface and in REST responses (only the last four characters are shown), but it is not encrypted, so it is in every database dump and backup. A Secrets API for stored credentials is expected in WordPress 7.2; until 7.2 ships, it is upcoming and not something to rely on. -
Registration. The option is registered as a setting only while the provider plugin is active. Without the plugin,
/wp/v2/settingsdoes not accept the key at all. -
Validation. When a key for an AI provider is saved through the REST API, WordPress checks it against the provider. An invalid key is not kept: the option is reset to an empty string and the response returns
"". -
Disabling AI.
define( 'WP_AI_SUPPORT', false );inwp-config.php, or thewp_supports_aifilter returningfalse, removes the three AI connectors; only Akismet remains on the screen.
The recommended way to provide Lumen Press’s key is an environment variable, so the key never reaches the database or a backup. In the Compose file of the site (the full file is in Local Development Environments):
services:
web:
image: wordpress:7.1.3-php8.4-apache
environment:
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} # taken from the host's environment or an .env file, never committed
The checks below were run on the Lumen Press site with the Anthropic provider plugin installed. The placeholder key
is deliberately invalid, and the application password is the placeholder <app-password>:
$ wp plugin install ai-provider-for-anthropic --activate
$ wp eval 'foreach ( wp_get_connectors() as $id => $c ) { echo $id, " ", $c["authentication"]["setting_name"], "\n"; }'
anthropic connectors_ai_anthropic_api_key
google connectors_ai_google_api_key
openai connectors_ai_openai_api_key
akismet wordpress_api_key
$ curl -s -u "lp_admin:<app-password>" -X POST -H "Content-Type: application/json" \
-d '{"connectors_ai_anthropic_api_key":"sk-ant-not-a-real-key-1234"}' \
http://localhost/wp-json/wp/v2/settings | head -c 40
{"connectors_ai_anthropic_api_key":"",
$ wp --exec="define( 'WP_AI_SUPPORT', false );" eval 'echo implode( ",", array_keys( wp_get_connectors() ) );'
akismet
Source: Code Reference: wp_supports_ai()
Only administrators can open the screen (manage_options). The AI Client dev note also recommends that plugins expose
each AI feature through their own REST endpoint with its own permission check, rather than letting lower roles send
arbitrary prompts with the site’s key; the Lumen Press blurb generator follows that pattern in
AI Client and Connectors. Plugins that are not AI providers can add
their own connector cards with the wp_connectors_init action. None of the older books covers this screen: it did not
exist before 7.0.
Writing
| Field | Option | Default | Notes |
|---|---|---|---|
Default Post Category |
|
|
Term ID given to posts saved without a category. That category cannot be deleted while it is the default. |
Default Post Format |
|
|
Only meaningful for themes that support post formats. |
Default Link Category |
|
|
Shown only when the legacy Links Manager is enabled ( |
Post via email: Mail Server, Port, Login Name, Password |
|
|
POP3 only, checked when |
Default Mail Category |
|
|
|
Update Services |
|
XML-RPC "weblogUpdates.ping" targets, one per line. Shown only when the site is public. |
|
Formatting (emoticons, XHTML nesting) |
|
|
Shown only on sites installed before 4.3; new installs never see this section. |
There is no setting on this screen to choose between the block editor and the classic editor. One older book describes
such a setting; it is added by the Classic Editor plugin, not by core, and core’s only per-type switch is the
use_block_editor_for_post_type filter. Post via email is rarely used today: it needs a dedicated, secret POP3 mailbox,
anyone who knows the address can publish, and the password sits unencrypted in the database. Lumen Press disables it
with add_filter( 'enable_post_by_email_configuration', '__return_false' ); in a must-use plugin. Update Services
pings blog directories when a post is published; most of those services no longer exist, and the ping only reveals
new URLs early, so many sites empty the list.
Reading
| Field | Option | Default | Notes |
|---|---|---|---|
Your homepage displays |
|
|
|
Homepage |
|
|
Page ID used as the front page. |
Posts page |
|
|
Page ID whose URL lists the posts. Its own content and template are ignored. |
Number of recent posts shown on archive pages |
|
|
Called "Blog pages show at most" in older versions and books. Applies to every main archive query, not only the blog. |
Number of recent items shown in syndication feeds |
|
|
|
For each post in a feed, include |
|
|
|
Search engine visibility: Discourage search engines from indexing this site |
|
|
The checkbox stores |
Encoding for pages and feeds |
|
|
Shown only when the stored charset is not UTF-8. Removed from new installs in 3.5. |
Block themes ignore part of this screen. The front page shown is still decided by show_on_front and
page_on_front, but the templates (front-page.html, home.html, page.html) decide what is rendered and how many
posts a Query Loop block shows unless it is set to inherit the main query. The template hierarchy is covered in
Template Hierarchy. The screen warns when the Homepage and the Posts page
are the same page, or when either is the Privacy Policy page.
What "Discourage search engines" really does
The checkbox does not hide the site. It sets blog_public to 0, and that value changes five things:
| Output | blog_public = 1 (default) |
blog_public = 0 |
|---|---|---|
Robots meta tag in |
|
|
Virtual |
|
The same two rules, without the |
XML sitemaps at |
Served |
Disabled (404) |
Update Services pings ( |
Sent when a post is published |
Not sent; the field is replaced by a notice on the Writing screen |
Dashboard |
Nothing |
"Search engines discouraged" in the At a Glance widget |
Source: Code Reference: wp_robots()
Until WordPress 5.2, the setting answered /robots.txt with Disallow: /. Version 5.3 replaced that with the
noindex meta tag, because a crawler that is forbidden to fetch a page never sees its noindex, and search engines can
still list a URL they only know from links. Advice that the checkbox "adds Disallow: / to robots.txt" is outdated.
Since 5.7 the meta tag is produced by the Robots API: wp_robots() runs on wp_head, login_head and embed_head,
and the wp_robots filter receives an array of directives. The callbacks wp_robots_noindex(),
wp_robots_noindex_search(), wp_robots_noindex_embeds() and wp_robots_max_image_preview_large() are attached by
default.
Observed on the Lumen Press site with pretty permalinks, first with the default and then after
wp option update blog_public 0:
GET /robots.txt (blog_public = 1)
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Sitemap: http://localhost/wp-sitemap.xml
GET /robots.txt (blog_public = 0)
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Source: Code Reference: do_robots()
Practical consequences:
-
The virtual
robots.txtexists only when WordPress answers the request. A physicalrobots.txtfile in the web root wins, and with plain permalinks (?p=123) there is no rewrite rule for it: on the Lumen Press site,/robots.txtthen redirected to the home page, and the rules were reachable only as/?robots=1. -
The meta tag only appears in HTML that calls
wp_head(). Feeds, REST responses, uploaded PDFs and images carry no directive, so a search engine can still index them. -
The setting is a request, not access control. A staging site that must stay private needs HTTP authentication or an IP allow list at the web server. A copy of production restored on staging also copies
blog_public = 1, which is the usual way staging sites end up in search results.
Lumen Press solves the last point in a must-use plugin that forces the setting off on every non-production
environment (WP_ENVIRONMENT_TYPE), adds an X-Robots-Tag header that also covers feeds, and appends two rules to the
public robots.txt:
<?php
/**
* Plugin Name: Lumen Press visibility guard
* Description: Keeps non-production copies of Lumen Press out of search engines.
*/
// On local, development and staging copies, behave as if "Discourage search engines" were ticked.
if ( 'production' !== wp_get_environment_type() ) {
add_filter( 'pre_option_blog_public', '__return_zero' );
// Also send the directive as an HTTP header, which covers feeds and other non-HTML responses.
add_action(
'send_headers',
static function () {
header( 'X-Robots-Tag: noindex, nofollow', true );
}
);
}
// Keep internal search result pages out of crawlers on every environment. Priority -1 runs
// before core adds its "Sitemap:" line at priority 0, so the rules stay in the "User-agent: *" group.
add_filter(
'robots_txt',
static function ( $output, $is_public ) {
if ( $is_public ) {
$output .= "Disallow: /?s=\n";
$output .= "Disallow: /search/\n";
}
return $output;
},
-1,
2
);
Source: Code Reference: robots_txt hook
Saved as wp-content/mu-plugins/lumen-visibility.php. On the local copy (WP_ENVIRONMENT_TYPE = local) the site
answered with X-Robots-Tag: noindex, nofollow on pages, /robots.txt and /feed/, and with the noindex, nofollow
meta tag, even though the stored blog_public was still 1. On a production configuration, the two Disallow lines
followed Allow: /wp-admin/admin-ajax.php, before the blank line and the Sitemap: line; at the default priority
they would land after the Sitemap: line instead.
The search rules are a crawl-budget choice, not a requirement: core already adds noindex to search result pages
through wp_robots_noindex_search(). Sitemaps, structured data and the SEO plugins that replace parts of this output are
covered in SEO, Analytics and Privacy.
Discussion
The Discussion screen sets the defaults for comments, pingbacks, moderation and avatars. Its fields map to these options; their meaning and the moderation workflow are explained in Categories, Tags and Comments.
| Section | Options | Defaults |
|---|---|---|
Default post settings |
|
|
Other comment settings |
|
|
Email me whenever |
|
|
Before a comment appears |
|
|
Comment Moderation / Disallowed Comment Keys |
|
|
Avatars |
|
|
The "Anyone posts a note" notification (wp_notes_notify) arrived in 6.9 with Notes, the editorial comments of the
block editor. disallowed_keys was called blacklist_keys before 5.5. The two keyword lists are stored with
autoload off, unlike the rest of the screen. The "default" settings apply to new posts only; changing them does not
touch existing posts, whose comment_status and ping_status columns keep their values.
Media
| Field | Option | Default |
|---|---|---|
Thumbnail size, Crop thumbnail to exact dimensions |
|
|
Medium size |
|
|
Large size |
|
|
Organize my uploads into month- and year-based folders |
|
|
Store uploads in this folder, Full URL path to files |
|
empty |
The sizes are maximum dimensions, applied when an image is uploaded; changing them does not resize existing images
(wp media regenerate does). Core also creates a medium_large size (medium_large_size_w = 768) and the sizes
registered by themes and plugins, none of which appears here. The two upload path fields are shown only when they
already hold a non-default value, so they cannot be set from a fresh install’s screen; the supported way to move
uploads is the UPLOADS constant. The image_default_* options in the allow list are remembered from the classic media
dialog, not edited on the screen. An "Embeds" section appears only when a plugin registers fields for it. Image
processing, formats and sizes are covered in Media Library.
Permalinks
Permalinks decide the URL of every post, page and archive. The structure is a string of structure tags stored in
permalink_structure; WordPress turns it into the regular expressions of the Rewrite API, stored in the
rewrite_rules option.
| Choice | Stored permalink_structure |
Example URL |
|---|---|---|
Plain |
empty |
|
Day and name |
|
|
Month and name |
|
|
Numeric |
|
|
Post name |
|
|
Custom Structure |
any combination of tags |
|
The tags offered by the screen are %year%, %monthnum%, %day%, %hour%, %minute%, %second%, %post_id%,
%postname%, %category% (nested categories become nested paths) and %author%. Plugins add more through the
available_permalink_structure_tags filter. The Optional section sets category_base (default category) and
tag_base (default tag). Every structure applies to posts only: pages always use their slug path, and each custom
post type sets its own base when it is registered (the Lumen Press lp_book type uses books, so a book lives at
/books/<slug>/ whatever the post structure), as shown in
Custom Post Types and Taxonomies.
Choosing a structure:
-
/%postname%/is the common choice and the one Lumen Press uses: short, readable and independent of dates. -
Dates in URLs make old content look old and change nothing about performance. The long-standing advice to avoid starting with
%postname%or%category%for performance reasons stopped applying in 3.3. -
A structure that begins with
/index.php/("PATHINFO" permalinks) works without any rewrite module. The screen uses it automatically when it cannot detect URL rewriting. -
Changing the structure of an established site breaks every old link. Core redirects some old post URLs through
wp_old_slug_redirect()and its canonical redirect guesses, but not changed category or tag bases: on the Lumen Press site,/category/uncategorized/returned 404 oncecategory_basewastopics. Plan 301 redirects at the web server before changing a live site.
What "Save Changes" writes
Saving the screen updates the options and calls flush_rewrite_rules(), which rebuilds rewrite_rules and, on
Apache, writes the rewrite block into .htaccess in the site root through save_mod_rewrite_rules(). WordPress only
edits the lines between its own # BEGIN WordPress and # END WordPress markers; rules outside the markers are
kept. When the file or the directory is not writable, the screen prints the rules to paste by hand. With the Lumen Press
settings, the generated block was:
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
The block is the same for every structure: all non-file requests go to index.php, and WordPress matches the URL
against rewrite_rules in PHP. That is why a new structure needs no new .htaccess lines, and why "404 on every
page except the home page" after a migration usually means the block is missing or AllowOverride is off for the
directory. The HTTP_AUTHORIZATION line passes the Authorization header to PHP, which application passwords need.
The same file is managed on IIS as web.config. On nginx, Caddy and FrankenPHP (detected from SERVER_SOFTWARE), the
screen writes nothing and shows no rules; the server configuration needs the equivalent once, for nginx
try_files $uri $uri/ /index.php?$args;, as described in
Web Servers: Apache and nginx. Older books show Apache 2.2
Order allow,deny blocks next to these rules; Apache 2.4 uses Require.
The same settings from WP-CLI. wp rewrite structure stores the structure and flushes the rules, but WP-CLI only writes
.htaccess when called with --hard and told that mod_rewrite is loaded, because it cannot inspect the web
server from the command line:
$ wp rewrite structure '/%postname%/' --category-base=topics --tag-base=subjects
Success: Rewrite structure set.
Success: Rewrite rules flushed.
$ wp rewrite flush --hard
Warning: Regenerating a .htaccess file requires special configuration. See usage docs.
Success: Rewrite rules flushed.
$ printf 'apache_modules:\n - mod_rewrite\n' > wp-cli.yml
$ wp rewrite flush --hard
Success: Rewrite rules flushed.
The Rewrite API behind this screen (custom rules, endpoints, add_rewrite_rule(), when to flush) is covered in
Rewrite API and Permalinks.
Privacy
The Privacy screen (since 4.9.6, with the GDPR tools) does one thing: it chooses the Privacy Policy page, stored as a
page ID in wp_page_for_privacy_policy. The installer already creates a draft page titled "Privacy Policy" with
suggested text (ID 3 on a fresh install) and points the option at it. The screen offers to select an existing page or
to create a new one, and links to the Policy Guide (Settings > Privacy > Policy Guide tab), where core, themes and
plugins add suggested paragraphs through wp_add_privacy_policy_content().
| Effect of the setting | Detail |
|---|---|
|
Return the page’s URL and a link, used by |
Comment form consent and the cookie checkbox |
Themes can link the policy next to the consent field. |
Editing the page |
Requires |
Reading screen warnings |
The page must not also be the Homepage or the Posts page. |
The screen only stores a page ID. The text is the site owner’s legal responsibility, and the draft created at install is a template, not a policy. The personal data export and erasure tools live under Tools, and plugins hook into them as shown in Privacy and Personal Data. Cookie consent and analytics are covered in SEO, Analytics and Privacy.
Lumen Press: all settings as a script
Clicking through eight screens on every new environment is error-prone. Lumen Press keeps its baseline settings in a
shell script run once after wp core install
(Installation):
#!/bin/sh
# Lumen Press: baseline settings, run once after "wp core install".
set -e
# General
wp option update blogname 'Lumen Press'
wp option update blogdescription 'Independent books since 1998'
wp option update timezone_string 'Europe/Madrid'
wp option update date_format 'j F Y'
wp option update time_format 'H:i'
wp option update start_of_week 1
wp option update users_can_register 0
wp option update default_role subscriber
# Writing
wp option update default_post_format 0
# Reading: static front page plus a posts page
home_id=$(wp post create --post_type=page --post_status=publish --post_title='Home' --porcelain)
news_id=$(wp post create --post_type=page --post_status=publish --post_title='News' --porcelain)
wp option update show_on_front page
wp option update page_on_front "$home_id"
wp option update page_for_posts "$news_id"
wp option update posts_per_page 12
wp option update rss_use_excerpt 1
wp option update blog_public 1
# Discussion
wp option update default_pingback_flag 0
wp option update default_ping_status closed
wp option update close_comments_for_old_posts 1
wp option update close_comments_days_old 30
wp option update comment_previously_approved 1
# Media
wp option update large_size_w 1200
wp option update large_size_h 1200
# Permalinks
wp rewrite structure '/%postname%/' --category-base=topics --tag-base=subjects
# Privacy: publish the draft policy page created by the installer
policy_id=$(wp option get wp_page_for_privacy_policy)
wp post update "$policy_id" --post_status=publish
After the script, wp option get returned the values above (the Home and News pages got IDs 5 and 6), and /, /news/, /topics/uncategorized/, /privacy-policy/ and /robots.txt all answered 200. Writing options
directly skips the screen’s side effects: the admin email confirmation, the .htaccess rewrite (unless
wp rewrite flush --hard is configured as shown above), and the sanitizing done by options.php for values typed by hand. The site language is set with
wp language core install es_ES --activate or wp site switch-language, which also download the language files,
rather than by writing WPLANG.
Pitfalls
-
Locked URL fields. Greyed-out WordPress Address and Site Address fields mean
WP_SITEURLandWP_HOMEare defined inwp-config.php. Edit them there. -
Settings that "do not save". A page cache or an unflushed persistent object cache shows old values, or a plugin forces a value with a
pre_option_{option}filter, as the Lumen Press visibility guard does on purpose. -
Static front page with a block theme. A
home.htmltemplate is used for the Posts page, and afront-page.htmltemplate, when present, renders the front page whichever Homepage option is chosen. -
A "discouraged" site still listed. Pages indexed before the box was ticked stay listed until a crawler revisits them and sees
noindex; a hand-writtenDisallow: /in a physicalrobots.txtprevents that revisit.
References
-
Make WordPress Core: Introducing the Connectors API in WordPress 7.0
-
Make WordPress Core: Introducing the AI Client in WordPress 7.0
-
Make WordPress Core: Changes to prevent search engines indexing sites
-
Make WordPress Core: Robots API and max-image-preview directive in WordPress 5.7
-
Advanced Administration Handbook: Giving WordPress Its Own Directory