Last active
November 17, 2020 02:47
-
-
Save mjangda/d5b8082ca902493318478f45daf207da to your computer and use it in GitHub Desktop.
Client-side, randomized, percentage-based segmentation using the WordPress Cache Segmentation API. Only supports 1 experiment and 1 control group.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once( WPMU_PLUGIN_DIR . '/cache/class-vary-cache.php' ); | |
use Automattic\VIP\Cache\Vary_Cache; | |
Vary_Cache::register_group( 'beta' ); | |
add_action( 'wp_head', function() { | |
// TODO: if possible, load this directly very early in the header.php (instead of wp_head) | |
// TODO: Could possibly even skip loading this if `Vary_Cache::is_user_in_group( 'beta' )` | |
include_once( __DIR__ . '/inline-script.php' ); | |
}, -1000 ); | |
add_action( 'wp_footer', function() { | |
$in_beta = Vary_Cache::is_user_in_group_segment( 'beta', 'yes' ); | |
if ( ! $in_beta ) { | |
return; | |
} | |
?> | |
<style> | |
body { | |
background: yellow; | |
} | |
</style> | |
<?php | |
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Automattic\VIP\Cache\Vary_Cache; | |
// Percentage of users to put in the experiment | |
$experiment_threshold = 10; | |
$cookie_name = Vary_Cache::COOKIE_SEGMENT; | |
$cookie_expires = time() + MONTH_IN_SECONDS; | |
$cookie_expires_formatted = gmdate( 'r', $cookie_expires ); | |
$cookie_domain = COOKIE_DOMAIN; | |
$cookie_path = COOKIEPATH; | |
// Make sure we use the same server-side formatting for the cookie value. | |
// This is to allow us to use the Vary_Cache helper functions | |
// TODO: Vary_Cache should probably make stringify_groups a public method. Or just have this client-side stuff built-in :) | |
// TODO: Notably, this will not work if you have other cache segmentation happening server-side. | |
$cookie_value_control_group = 'vc-v1__beta_--_no'; | |
$cookie_value_experiment_group = 'vc-v1__beta_--_yes'; | |
?> | |
<script> | |
( function() { | |
// What percentage of users should land in the new group? | |
const threshold = <?php echo absint( $experiment_threshold ); ?>; | |
// TODO: skip if the browser or user doesn't support cookies | |
// If we have the cookie already, don't bother segmenting again | |
const hasCookie = -1 !== document.cookie.indexOf( '<?php echo esc_js( sprintf( '%s=', $cookie_name ) ); ?>' ); | |
if ( hasCookie ) { | |
console.log( 'Have cookie; skipping segmentation' ); | |
return; | |
} | |
// TODO: if bot user, don't segment | |
let inExperiment = false; | |
let cookieValue = '<?php echo esc_js( $cookie_value_control_group ); ?>'; | |
const randomNumber = Math.floor( Math.random() * Math.floor( 100 ) ); | |
if ( randomNumber < threshold ) { | |
console.log( 'Adding to experiment group' ); | |
inExperiment = true; | |
cookieValue = '<?php echo esc_js( $cookie_value_experiment_group ); ?>'; | |
} else { | |
console.log( 'Adding to control group' ); | |
} | |
// Set the cache segementation cookie. | |
// Note: we set the cookie for both control and experiment groups. | |
// Otherwise we run the risk of control group users get re-assigned into the experiment. | |
// This does create an extra cache bucket for control users though which is unfortunate. | |
document.cookie = '<?php echo sprintf( | |
"%s=' + cookieValue + '; expires=%s; path=%s; domain=%s;", | |
// TODO: Consider better escaping for the values below, something that is cookie-friendly | |
esc_js( $cookie_name ), | |
esc_js( $cookie_expires_formatted ), | |
esc_js( $cookie_path ), | |
esc_js( $cookie_domain ) | |
); ?>'; | |
// Reload the page for users in experiment to make sure they get the correct | |
if ( inExperiment ) { | |
console.log( 'Reloading from experiment group' ); | |
window.location.reload(); | |
} | |
} )(); | |
</script> | |
<?php |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment