Configuration
How get_option, update_option, and post meta translate to Siren's three-level config system.
Last updated: April 9, 2026
Configuration
WordPress stores settings with get_option / update_option (global settings) and get_post_meta / update_post_meta (per-entity settings). Siren replaces both with a unified config system that uses a three-level hierarchy: type, subtype, and key.
// WordPress: global settings
update_option('my_plugin_api_key', 'abc123');
$key = get_option('my_plugin_api_key');
// WordPress: per-entity settings
update_post_meta($post_id, '_commission_rate', '15');
$rate = get_post_meta($post_id, '_commission_rate', true); // Siren facade: three-level config hierarchy
use Siren\Configs\Core\Facades\Configs;
// Read a config value: type, subtype, key, default
$rate = Configs::getConfigValue('program', '42', 'maxCommission', '0');
// Write a config value: type, subtype, key, value
Configs::getContainedInstance()->setConfig('program', '42', 'maxCommission', '15'); // Siren DI: inject ConfigDatastore
use Siren\Configs\Core\Datastores\Config\Interfaces\ConfigDatastore;
class CommissionService
{
protected ConfigDatastore $config;
public function __construct(ConfigDatastore $config)
{
$this->config = $config;
}
public function getMaxCommission(int $programId): string
{
return $this->config->getConfigValue(
'program',
(string) $programId,
'maxCommission',
'0' // default if not set
);
}
public function setMaxCommission(int $programId, string $value): void
{
$this->config->setConfig(
'program',
(string) $programId,
'maxCommission',
$value
);
}
} How does the three-level hierarchy work?
Every config value is scoped by three coordinates:
typeis the domain area. Examples:'program','collaborator','system'.subtypeis the specific entity or context within that type. For entity-scoped settings, this is typically the entity’s ID as a string (e.g.,'42'). For global settings within a domain, this might be a category name.keyis the individual setting name. Examples:'maxCommission','payoutThreshold','notificationEmail'.
This maps cleanly to both of WordPress’s storage patterns. Global settings (get_option) correspond to a fixed type and subtype with varying keys. Per-entity settings (get_post_meta) correspond to a fixed type and key with varying subtypes (one per entity ID).
// Global setting: same type and subtype, different keys
$this->config->getConfigValue('system', 'general', 'siteName', '');
$this->config->getConfigValue('system', 'general', 'currency', 'USD');
// Per-program setting: same type and key, different subtypes (program IDs)
$this->config->getConfigValue('program', '42', 'maxCommission', '0');
$this->config->getConfigValue('program', '99', 'maxCommission', '0');
Why a single system instead of two?
WordPress’s split between wp_options and wp_postmeta creates a conceptual divide. Global settings live in one place, per-entity settings in another, and the APIs are different. Siren’s config system is one table, one API, one mental model. The scope is determined by the type/subtype/key coordinates, not by which function you call.
This also means config values are queryable the same way regardless of scope. You can fetch all config values for a given type and subtype, or all values with a given key across all subtypes.
Where can I learn more?
For the full ConfigDatastore API (querying, deleting, and batch operations), see the Configs resource reference.
For the full PHPNomad framework documentation on datastores, see Datastores Introduction.