Skip to main content

WordPress Integration

Segment membership​

Create the list in the dashboard and attach it to a Targeting filter. Sync members with a Backend application key. Evaluation uses the published list after the next definitions refresh. Flow · HTTP API

Use the PHP core client from a plugin, cron job, or admin-ajax handler. Do not put a Backend key in public theme JavaScript. See the PHP SDK.

Server only

Requires a Backend application key. Do not call this from a browser, mobile app, or other public client.

use Toggly\FeatureManagement\SegmentMembershipClient;

$segments = new SegmentMembershipClient(
$httpClient,
$requestFactory,
$streamFactory,
getenv('TOGGLY_APP_KEY')
);
$segments->addSegmentMembers('Beta Testers', ['user-123']);

Use toggly/wordpress to choose theme content with a PHP helper or shortcode. It includes the PHP core package. Keep your existing theme content as the disabled branch.

WordPress cheat sheet · Download PDF

Requirements​

Composer and a PHP host are required. The examples use PHP 8 syntax. The package retains a PHP 7.4 declared floor and supports PHP through 8.5. PHP 8.5 is the current tested runtime. The plugin retains WordPress 5.0+ support and is currently validated on WordPress 7.1 with PHP 8.5. Validate your installed combination with composer check-platform-reqs. A declared floor does not by itself prove every earlier host version still runs.

Installation​

From the WordPress root (the directory containing wp-load.php), install:

composer require toggly/wordpress
mkdir -p wp-content/plugins wp-content/mu-plugins
ln -s ../../vendor/toggly/wordpress wp-content/plugins/toggly

Use the symlink only if that destination does not already exist. You may instead deploy the package directory there. WordPress must find the entry point at wp-content/plugins/toggly/toggly.php, and the host must load the root Composer autoloader. Prepare the MU plugin below before activation.

Host bootstrap​

Create wp-content/mu-plugins/toggly-host.php. This file loads before normal plugins and provides the cron intervals before the SDK schedules its events. The path assumes the root Composer layout shown above; adjust it for your actual deployment.

<?php
require_once ABSPATH . 'vendor/autoload.php';

add_filter('cron_schedules', static function (array $schedules): array {
$schedules['toggly_refresh_interval'] = [
'interval' => 300,
'display' => 'Every 5 Minutes',
];
$schedules['toggly_send_interval'] = [
'interval' => 60,
'display' => 'Every Minute',
];
return $schedules;
});

// Select a host configuration with no optional transient snapshot adapter.
add_filter('pre_option_toggly_snapshot_provider', static fn () => 'none');

// The plugin initializes on plugins_loaded; refresh after initialization.
add_action('plugins_loaded', static function (): void {
$options = get_option('toggly_settings', []);
if (!empty($options['app_key'])) {
do_action('toggly_refresh_features');
}
}, 20);

In Plugins, activate Toggly Feature Management, then open Settings → Toggly. Set the App Key, exact Environment name and https://definitions.toggly.io/ as Base URL. Select signed definitions to match your app's configuration, then save. Make a new page request so initialization reads those settings. Do not call TogglyPlugin::init() a second time.

Snapshot choice​

The recipe chooses none, which bypasses optional transient caching and works with PSR Simple Cache 3 dependency resolutions. It does not persist snapshots: each new PHP request must refresh before evaluating, and an API outage leaves a new process without saved definitions. The explicit refresh above implements that choice and adds a network request to startup.

The plugin's default selection is transient, backed by WordPressCacheAdapter. Check compatibility with your installed PSR cache interface before choosing it. Do not assume the no-snapshot recipe provides offline persistence. Core applications can explicitly inject other snapshot providers; this plugin does not expose that constructor injection through its settings page.

First flag in a template​

Create new-header in the configured Toggly app and environment. Set an AlwaysOn rule, then place this in a theme template that runs after plugins_loaded:

<?php if (toggly_is_enabled('new-header')): ?>
<p>New header</p>
<?php else: ?>
<p>Original header</p>
<?php endif; ?>

The page should show New header. Change the rule to AlwaysOff and reload; after the startup refresh it should show Original header. Unknown flags are disabled by default. Keep this fallback useful when definitions are unavailable.

Authenticated request context​

The helper is the global function toggly_is_enabled. The plugin loads it during initialization from a file that declares no namespace. Its signature is (string $featureKey, ?array $context = null): bool. Build identity from the authenticated server-side user before the first targeted check:

<?php
$user = wp_get_current_user();
$context = [
'identity' => $user->exists() ? (string) $user->ID : null,
'groups' => $user->exists() ? array_values($user->roles) : [],
];
$enabled = toggly_is_enabled('premium-content', $context);
?>
<?php if ($enabled): ?>
<p>Premium content</p>
<?php else: ?>
<p>Standard content</p>
<?php endif; ?>

Configure Targeting with the same ID convention. The SDK's ambient WordPressFeatureContextProvider supplies an identifier to telemetry; it does not inject the logged-in user into evaluation. Pass identity, groups, server-derived claims and mapped request data explicitly when rules need them. A top-level email is not a targeting identity. Feature flags do not replace WordPress capability checks for protected data or actions.

Shortcodes and programmatic checks​

Use a shortcode for a flag that does not need authenticated request context:

[toggly_feature name="new-banner"]
<p>Shown when enabled.</p>
[/toggly_feature]

name is required; missing or disabled flags render nothing. Optional context is a JSON object that is passed to evaluation. Static shortcode JSON describes literal context, not the current viewer. Do not treat author-supplied identity or claims as authenticated user data; use the server-side helper above for user-specific decisions.

The plugin object forwards the same explicit evaluation context:

$plugin = \Toggly\WordPress\TogglyPlugin::getInstance();
$enabled = $plugin->isEnabled('premium-content', $context);

PHP does not implement ContextProperty or entity registration. Adding Order properties to the context does not activate an entity rule. See PHP context.

WP-Cron and lifecycle​

The early interval filter in host bootstrap lets the plugin register these recurring events on a fresh installation:

HookScheduleBehavior
toggly_refresh_featurestoggly_refresh_interval, 300 secondsRefresh definitions in this process
toggly_send_statstoggly_send_interval, 60 secondsSend usage statistics and metrics from this process

Verify schedules with wp cron event list and configure normal WordPress cron execution on your host. WP-Cron does not initialize definitions in the current page response, and a separate cron process cannot flush another request's in-memory telemetry. The SDK's usage and metrics shutdown handlers flush the owning request; long-lived hosts must manage their own lifecycle.

After initialization, these are the supported operational actions:

do_action('toggly_refresh_features');
do_action('toggly_send_stats');

Do not use WordPress state-action names as automatic flag-change notifications. Use ordinary evaluations for theme decisions. Core integrations expose state-service subscriptions.