-
-
-
-
-
Wordpress Headline Results This is a list of all of the experiments that are running headline tests.
-
-
-
-
-
-
-
-
Ready to launch! These experiments experiments are ready to launch!
+
+
+
+
+
-
-
Not ready to launch These experiments still need a few more visitors before we can declare a winner
+
+
+
+
+
+
+
+
+
+
+
Please Note: Only experiements created through Wordpress will be displayed here. Experiments created directly in Optimizely will not be displayed here.', 'optimizely' ) ?>
+
+
+
+
+
+
-
- Loading Results.....
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
No results!
-
A headline experiement must be created in Wordpress before any results will be displayed here. Please create a new post with multiple headlines, publish the post, and start the experiment. Once the experiment is created and running it will display the results here. Please Note: Only experiements created through Wordpress will be displayed here. Experiments created directly in Optimizely will not be displayed here.
-
-
+
+
+ true
+ );
+
+ $selected_post_types_str = get_option( 'optimizely_post_types', 'post' );
+ $selected_post_types = ( ! empty( $selected_post_types_str ) ) ? explode( ',', $selected_post_types_str ) : array();
+ $post_types = get_post_types( $args, 'objects' );
+ foreach( $post_types as $post_type ) {
+ if ( 'page' != $post_type->name && 'attachment' != $post_type->name ) {
+ if ( in_array( $post_type->name, $selected_post_types ) ) {
+ echo '
' . esc_attr( $post_type->label ) . '';
+ } else {
+ echo '
' . esc_attr( $post_type->label ) . '';
+ }
+ }
+ }
+ ?>
-
-
-
+
+
+
+
+
diff --git a/edit.js b/edit.js
index 55f3ac6..b1348da 100644
--- a/edit.js
+++ b/edit.js
@@ -1,209 +1,216 @@
-function optimizelyEditPage() {
- var $ = jQuery;
-
- // Initialize data from the input fields
- var projectId = $('#optimizely_project_id').val();
- var optly = new OptimizelyAPI($("#optimizely_token").val());
- if(!!$("#optimizely_experiment_id").val()){
- optly.get('experiments/'+$("#optimizely_experiment_id").val(),function(response){
- optly.experiment = response;
- showExperiment(optly.experiment);
- });
- }else{
- optly.experiment = {
- id: $("#optimizely_experiment_id").val(),
- status: $("#optimizely_experiment_status").val()
- }
- $('#optimizely_not_created').show();
- $('#optimizely_created').hide();
- }
-
- // On click, run the createExperiment function
- $('#optimizely_create').click(function(){
- createExperiment();
- });
-
- // Then, handle starts and pauses on the experiment
- $('#optimizely_toggle_running').click(function(){
- if (optly.experiment.status == "Running") {
- pauseExperiment(optly.experiment);
- } else {
- startExperiment(optly.experiment);
- }
- });
-
- // Render the experiment's state on the page
- function showExperiment(experiment) {
- // ID and links
- $("#optimizely_experiment_id").val(experiment.id);
- $('#optimizely_view').attr('href','https://www.optimizely.com/edit?experiment_id=' + experiment.id);
-
- // Status and buttons
- $("#optimizely_experiment_status").val(experiment.status);
- $('#optimizely_experiment_status_text').text(experiment.status);
- if (experiment.status == "Running") {
- $('#optimizely_toggle_running').text('Pause Experiment');
- } else {
- $('#optimizely_toggle_running').text('Start Experiment');
- }
-
- // Hide create button, show status
-
- $('#optimizely_not_created').hide();
- $('#optimizely_created').show();
-
- // Update Wordpress backend w/ experiment data
- var data = {
- action: "update_experiment_meta",
- post_id: $('#post_ID').val(),
- optimizely_experiment_id: experiment.id,
- optimizely_experiment_status: experiment.status
- };
-
- $('.optimizely_variation').each(function(index, input) {
- data[$(input).attr('name')] = $(input).val();
- });
- $.post(wpAjaxUrl, data);
- }
-
- /*
- This function creates an experiment by providing a description based on the post's title and an edit_url based on the permalink of the Wordpress post. We send these as a POST request and register a callback to run the onExperimentCreated function when it completes.
- */
- function createExperiment() {
- $('#optimizely_create').text('Creating...');
- experiment = {};
- post_id = $('#post_ID').val();
- experiment.description = "Wordpress ["+post_id+"]: " + $('#title').val();
- experiment.edit_url = $('#sample-permalink').text();
- var loc = document.createElement('a');
- loc.href = experiment.edit_url;
- var urlTargetdomain = loc.hostname;
- experiment.url_conditions = [
- {
- "match_type": "substring",
- "value": urlTargetdomain
- }
- ];
- optly.post('projects/' + projectId + '/experiments', experiment, onExperimentCreated);
- }
-
- /*
- The experiment we created has two built-in variations, but now we need to add a third and update the content. Since we're adding a variation, we also need to calculate the traffic weight to use for each one. Once we've done this, we'll call the createVariation function explained below.
-
- Our experiment comes with an Engagement goal, but we'll also add one to measure views to the post.
-
- */
- function onExperimentCreated(experiment) {
- // Pause for 200ms so that the experiment is guarenteed to be created before editing and adding variations
-
- setTimeout(function () {
- optly.experiment = experiment;
- var variations = $('.optimizely_variation').filter(function(){return $(this).val().length > 0})
-
- // Set variation weights
- var numVariations = variations.length + 1;
- var variationWeight = Math.floor(10000 / numVariations);
- var leftoverWeight = 10000 - variationWeight*numVariations;
-
- // Create variations
- variations.each(function(index, input) {
- var weight = variationWeight;
- createVariation(experiment, index + 1, $(input).val(), weight);
- });
-
- // Update original with correct traffic allocation
- var origVariationWeight = {"weight":variationWeight + (leftoverWeight > 0 ? leftoverWeight : 0)};
- optly.patch('variations/' + experiment.variation_ids[0], origVariationWeight, checkExperimentReady);
-
- // Create goal
- createGoal(experiment);
- }, 200);
-
- }
-
- /*
- We create a pageview goal that measures how many times the post is viewed. We add one url, the permalink, and use the substring match type. We also set "addable" to false so that the goal won't clog up the list of goals for other experiments.
-
- Finally, we associate the goal with the experiment we just created by adding the experiment's id to experiment_ids. We POST the goal to the projects/{id}/goals endpoint to create it.
- */
- function createGoal(experiment) {
-
- var goal = {
- goal_type: 3, // pageview goal
- title: "Views to page",
- urls: [$('#sample-permalink').text()],
- url_match_types: [4], // substring
- addable: false, // don't clog up the goal list
- experiment_ids: [experiment.id]
- }
-
- optly.post('projects/' + experiment.project_id + '/goals/', goal, checkExperimentReady);
-
- }
-
- /*
- To create a variation, we first generate the variation code. We use a template based on the Wordpress theme, and then we drop in the values for our variation. The result would be:
-
- $(".post-27 .entry-title a").text("Alternate Title #1");
-
- Once we've generated this variation code, we include it in the js_component parameter of our API request. We also add a variation title and weight.
-
- In this example, we have two alternate headlines plus an original. When we created the experiment, it also came with two variations that were created automatically. We'll leave variation 0 alone as the original, update variation 1 to use the first alternate headline, and create a new variation 2 with the second alternate headline.
- */
-
- function createVariation(experiment, index, newTitle, weight) {
-
- // Generate variation code
- var variationTemplate = $('#optimizely_variation_template').val();
- var postId = $('#post_ID').val();
- var originalTitle = $('#title').val();
- var code = variationTemplate
- .replace(/\$OLD_TITLE/g, originalTitle)
- .replace(/\$NEW_TITLE/g, newTitle)
- .replace(/\$POST_ID/g, postId);
-
- // Request data
- var variation = {
- "description": newTitle,
- "js_component": code,
- "weight": weight,
- }
-
- // Update variation #1, create the others
- if (index == 1) {
- optly.patch('variations/' + experiment.variation_ids[1], variation, checkExperimentReady);
- } else {
- optly.post('experiments/' + experiment.id + '/variations', variation, checkExperimentReady);
- }
-
- }
-
- /*
- Once all the PUT and POST requests have returned, we're done! At this point, we can let the user know that the experiment is created and ready.
- */
- function checkExperimentReady(response) {
- if (optly.outstandingRequests == 0) {
- showExperiment(optly.experiment);
- }
- }
-
- /*
- To start a pause an experiment, we just need to change it's status to running. The patch method GETs the experiment metadata, changes the specified fields, and PUTs the object back to Optimizely.
- */
- function startExperiment(experiment) {
- $('#optimizely_toggle_running').text('Starting...');
- optly.patch('experiments/' + experiment.id, {'status': 'Running'}, function(response) {
- optly.experiment = response;
- showExperiment(optly.experiment);
- });
- }
-
- function pauseExperiment(experiment) {
- $('#optimizely_toggle_running').text('Pausing...');
- optly.patch('experiments/' + experiment.id, {'status': 'Paused'}, function(response) {
- optly.experiment = response;
- showExperiment(optly.experiment);
- });
- }
-
-}
\ No newline at end of file
+(function( $ ) {
+
+ function optimizelyEditPage() {
+ // Initialize data from the input fields
+ var projectId = $( '#optimizely_project_id' ).val();
+ var optly = new OptimizelyAPI( $( '#optimizely_token' ).val() );
+
+ if ( !! $( '#optimizely_experiment_id' ).val() ) {
+ optly.get( 'experiments/' + $( '#optimizely_experiment_id' ).val(), function( response ) {
+ optly.experiment = response;
+ showExperiment( optly.experiment );
+ });
+ } else {
+ optly.experiment = {
+ id: $( '#optimizely_experiment_id' ).val(),
+ status: $( '#optimizely_experiment_status' ).val()
+ }
+ $( '#optimizely_not_created' ).show();
+ $( '#optimizely_created' ).hide();
+ }
+
+ // On click, run the createExperiment function
+ $( '#optimizely_create' ).click(function() {
+ createExperiment();
+ });
+
+ // Then, handle starts and pauses on the experiment
+ $( '#optimizely_toggle_running' ).click(function() {
+ if ( optly.experiment.status == 'Running' ) {
+ pauseExperiment( optly.experiment );
+ } else {
+ startExperiment( optly.experiment );
+ }
+ });
+
+ // Render the experiment's state on the page
+ function showExperiment( experiment ) {
+ // ID and links
+ $( '#optimizely_experiment_id' ).val( experiment.id );
+ $( '#optimizely_view' ).attr( 'href', 'https://www.optimizely.com/edit?experiment_id=' + experiment.id );
+
+ // Status and buttons
+ $( '#optimizely_experiment_status' ).val( experiment.status );
+ $( '#optimizely_experiment_status_text' ).text( experiment.status );
+ if ( experiment.status == 'Running' ) {
+ $( '#optimizely_toggle_running' ).text( 'Pause Experiment' );
+ } else {
+ $( '#optimizely_toggle_running' ).text( 'Start Experiment' );
+ }
+
+ // Hide create button, show status
+ $( '#optimizely_not_created' ).hide();
+ $( '#optimizely_created' ).show();
+
+ // Update Wordpress backend w/ experiment data
+ var data = {
+ action: 'update_experiment_meta',
+ post_id: $( '#post_ID' ).val(),
+ optimizely_experiment_id: experiment.id,
+ optimizely_experiment_status: experiment.status
+ };
+
+ $( '.optimizely_variation' ).each(function( index, input ) {
+ data[ $( input ).attr( 'name' ) ] = $( input ).val();
+ });
+ $.post( wpAjaxUrl, data );
+ }
+
+ // This function creates an experiment by providing a description based on the post's title and an edit_url based on the permalink of the Wordpress post. We send these as a POST request and register a callback to run the onExperimentCreated function when it completes.
+ function createExperiment() {
+ $( '#optimizely_create' ).text( 'Creating...' );
+ experiment = {};
+ post_id = $( '#post_ID' ).val();
+ experiment.description = 'Wordpress [' + post_id + ']: ' + $( '#title' ).val();
+ experiment.edit_url = $( '#sample-permalink' ).text();
+ var loc = document.createElement( 'a' );
+ loc.href = experiment.edit_url;
+ var urlTargetdomain = loc.hostname;
+ experiment.url_conditions = [
+ {
+ 'match_type': 'substring',
+ 'value': urlTargetdomain
+ }
+ ];
+ optly.post( 'projects/' + projectId + '/experiments', experiment, onExperimentCreated );
+ }
+
+ /*
+ The experiment we created has two built-in variations, but now we need to add a third and update the content.
+ Since we're adding a variation, we also need to calculate the traffic weight to use for each one.
+ Once we've done this, we'll call the createVariation function explained below.
+ Our experiment comes with an Engagement goal, but we'll also add one to measure views to the post.
+ */
+ function onExperimentCreated( experiment ) {
+ // Pause for 200ms so that the experiment is guarenteed to be created before editing and adding variations
+ setTimeout(function() {
+ optly.experiment = experiment;
+ var variations = $( '.optimizely_variation' ).filter(function() {
+ return $( this ).val().length > 0
+ });
+
+ // Set variation weights
+ var numVariations = variations.length + 1;
+ var variationWeight = Math.floor( 10000 / numVariations );
+ var leftoverWeight = 10000 - ( variationWeight * numVariations );
+
+ // Create variations
+ variations.each(function( index, input ) {
+ var weight = variationWeight;
+ setTimeout(function() {
+ createVariation( experiment, index + 1, $( input ).val(), weight );
+ }, 200 );
+ });
+
+ // Update original with correct traffic allocation
+ var origVariationWeight = { 'weight': variationWeight + ( leftoverWeight > 0 ? leftoverWeight : 0 ) };
+ optly.patch( 'variations/' + experiment.variation_ids[0], origVariationWeight, checkExperimentReady );
+
+ // Create goal
+ createGoal( experiment );
+ }, 1000 );
+ }
+
+ /*
+ We create a pageview goal that measures how many times the post is viewed.
+ We add one url, the permalink, and use the substring match type.
+ We also set 'addable' to false so that the goal won't clog up the list of goals for other experiments.
+ Finally, we associate the goal with the experiment we just created by adding the experiment's id to experiment_ids.
+ We POST the goal to the projects/{id}/goals endpoint to create it.
+ */
+ function createGoal( experiment ) {
+ var goal = {
+ goal_type: 3, // pageview goal
+ title: 'Views to page',
+ urls: [ $( '#sample-permalink' ).text() ],
+ url_match_types: [4], // substring
+ addable: false, // don't clog up the goal list
+ experiment_ids: [ experiment.id ]
+ }
+
+ optly.post( 'projects/' + experiment.project_id + '/goals/', goal, checkExperimentReady );
+ }
+
+
+ /*
+ To create a variation, we first generate the variation code.
+ We use a template based on the Wordpress theme, and then we drop in the values for our variation. The result would be:
+ $( '.post-27 .entry-title a' ).text( 'Alternate Title #1' );
+ Once we've generated this variation code, we include it in the js_component parameter of our API request.
+ We also add a variation title and weight.
+ In this example, we have two alternate headlines plus an original.
+ When we created the experiment, it also came with two variations that were created automatically.
+ We'll leave variation 0 alone as the original, update variation 1 to use the first alternate headline, and create a new variation 2 with the second alternate headline.
+ */
+ function createVariation( experiment, index, newTitle, weight ) {
+ // Generate variation code
+ var variationTemplate = $( '#optimizely_variation_template' ).val();
+ var postId = $( '#post_ID' ).val();
+ var originalTitle = $( '#title' ).val();
+ var code = variationTemplate
+ .replace( /\$OLD_TITLE/g, originalTitle )
+ .replace( /\$NEW_TITLE/g, newTitle )
+ .replace( /\$POST_ID/g, postId );
+
+ // Request data
+ var variation = {
+ 'description': newTitle,
+ 'js_component': code,
+ 'weight': weight,
+ }
+
+ // Update variation #1, create the others
+ if ( index == 1 ) {
+ optly.patch( 'variations/' + experiment.variation_ids[1], variation, checkExperimentReady );
+ } else {
+ optly.post( 'experiments/' + experiment.id + '/variations', variation, checkExperimentReady );
+ }
+ }
+
+ /*
+ Once all the PUT and POST requests have returned, we're done!
+ At this point, we can let the user know that the experiment is created and ready.
+ */
+ function checkExperimentReady( response ) {
+ if ( 0 == optly.outstandingRequests ) {
+ showExperiment( optly.experiment );
+ }
+ }
+
+ /*
+ To start a pause an experiment, we just need to change it's status to running.
+ The patch method GETs the experiment metadata, changes the specified fields, and PUTs the object back to Optimizely.
+ */
+ function startExperiment( experiment ) {
+ $( '#optimizely_toggle_running' ).text( 'Starting...' );
+ optly.patch( 'experiments/' + experiment.id, { 'status': 'Running' }, function( response ) {
+ optly.experiment = response;
+ showExperiment( optly.experiment );
+ });
+ }
+
+ function pauseExperiment( experiment ) {
+ $( '#optimizely_toggle_running' ).text( 'Pausing...' );
+ optly.patch( 'experiments/' + experiment.id, { 'status': 'Paused' }, function( response ) {
+ optly.experiment = response;
+ showExperiment( optly.experiment );
+ });
+ }
+
+ }
+
+ $( document ).ready(function() {
+ optimizelyEditPage();
+ });
+
+})( jQuery );
diff --git a/edit.php b/edit.php
index 66b94d6..b17a478 100644
--- a/edit.php
+++ b/edit.php
@@ -1,119 +1,165 @@
ID, "post_title$i", true);
- $contents .= "
";
- $contents .= "Variation #$i ";
- $contents .= " ";
- $contents .= "
";
- }
-
- if ( can_create_experiments() ) {
- echo $contents;
-
- ?>
-
-
-
-
-
-
-
= get_option('optimizely_variation_template') ?>
-
-
-
-
Please configure your API credentials in the Optimizely settings page .
+
%s',
+ esc_html__( 'Please configure your API credentials in the', 'optimizely' ),
+ esc_url( menu_page_url( 'optimizely-config', false ) ),
+ esc_html__( 'Optimizely settings page', 'optimizely' )
+ ); ?>.
ID, $meta_key, true );
+ echo '
';
+ echo sprintf(
+ '%s #%u ',
+ esc_attr( $meta_key ),
+ esc_html__( 'Variation', 'optimizely' ),
+ absint( $i )
+ );
+ echo sprintf(
+ ' ',
+ esc_attr( $meta_key ),
+ esc_attr( $meta_key ),
+ esc_html__( 'Title', 'optimizely' ),
+ absint( $i ),
+ esc_attr( $titles[ $i ] )
+ );
+ echo '
';
+ }
+ ?>
+
+
+
+
+
+
: ID, 'optimizely_experiment_status', true ) ) ?>
+
+ :
+
+
+
+
+
+
+ (int)$post_id,
- 'post_title' => $winning_var_title
- );
-
- wp_update_post( $my_post );
+add_action( 'wp_ajax_update_experiment_meta', 'optimizely_update_experiment_meta' );
+
+/**
+ * Update the post title on an AJAX request for the winner of the test.
+ * @param int $post_id
+ */
+function optimizely_update_post_title() {
+ if ( isset( $_REQUEST['post_id'] ) && isset( $_REQUEST['title'] ) ) {
+ $post_id = absint( $_REQUEST['post_id'] );
+ $winning_var_title = sanitize_text_field( $_REQUEST['title'] );
+
+ wp_update_post( array(
+ 'ID' => $post_id,
+ 'post_title' => $winning_var_title
+ ) );
+ }
+
+ exit;
+}
+add_action( 'wp_ajax_update_post_title', 'optimizely_update_post_title' );
+
+/**
+ * Check if this is a post type that uses Optimizely.
+ * @param string $post_type
+ * @return boolean
+ */
+function optimizely_is_post_type_enabled( $post_type ) {
+ $selected_post_types = explode( ',', get_option( 'optimizely_post_types' ) );
+ if ( ! empty( $selected_post_types ) && in_array( $post_type, $selected_post_types ) ) {
+ return true;
+ } else {
+ return false;
+ }
}
+/**
+ * Return the meta key format used for all post title variations.
+ * @param int $i
+ * @return string
+ */
+function optimizely_meta_key( $i ) {
+ return 'post_title' . absint( $i );
+}
?>
\ No newline at end of file
diff --git a/images/optimizely-icon.png b/images/optimizely-icon.png
index 8543778..9868c19 100644
Binary files a/images/optimizely-icon.png and b/images/optimizely-icon.png differ
diff --git a/optimizely.js b/optimizely.js
index 708429a..90f46d2 100644
--- a/optimizely.js
+++ b/optimizely.js
@@ -1,86 +1,83 @@
-/*
-The OptimizelyAPI class provides a connection to the API via Javascript and lets you make authenticated calls without repeating yourself.
-
-We store the API token in each instance of the object, and we can connect to multiple different accounts by creating new instances of the OptimizelyAPI class.
-
-Finally, we keep track of how many requests are outstanding so we can tell when all the calls are complete.
-*/
-
-OptimizelyAPI = function(token) {
- this.outstandingRequests = 0;
- this.token = token;
-}
-
-/*
-To call the API, we use jQuery's `$.ajax` function, which sends an asynchronous request based on a set of `options`.
-
-Our function takes four arguments:
-
-* The request `type`, like GET or POST
-* The `endpoint` to hit, like `projects/27`
-* The `data` to send along with a POST or PUT request
-* A `callback` function to run when the operation is done. The callback should take one argument, the `response`.
-
-We construct the URL by appending the endpoint to the base API link, and we authenticate by adding the token in the headers section.
-
-To send data, we set content type to JSON and encode the array as a JSON string to send over the wire.
-*/
-
-OptimizelyAPI.prototype.call = function(type, endpoint, data, callback) {
-
- var self = this;
-
- var options = {
- url: "https://www.optimizelyapis.com/experiment/v1/" + endpoint,
- type: type,
- headers: {"Token": this.token},
- contentType: 'application/json',
- success: function(response) {
- self.outstandingRequests -= 1;
- callback(response);
- }
- }
-
- if (data) {
- options.data = JSON.stringify(data);
- options.dataType = 'json';
- }
-
- this.outstandingRequests += 1;
- jQuery.ajax(options);
-
-}
-
-/*
-Using our `call` function, we can define convenience functions for GETs, POSTs, PUTs, and DELETEs.
-*/
-
-OptimizelyAPI.prototype.get = function(endpoint, callback) {
- this.call('GET', endpoint, "", callback);
-}
-
-OptimizelyAPI.prototype.delete = function(endpoint, callback) {
- this.call('DELETE', endpoint, "", callback);
-}
-
-OptimizelyAPI.prototype.post = function(endpoint, data, callback) {
- this.call('POST', endpoint, data, callback);
-}
-
-OptimizelyAPI.prototype.put = function(endpoint, data, callback) {
- this.call('PUT', endpoint, data, callback);
-}
-
-/*
-We've also added an extra convenience function, `patch`, that updates a model by changing only the specified fields. The function works by reading in an entity, changing a few keys, and then sending it back to Optimizely.
-*/
-
-OptimizelyAPI.prototype.patch = function(endpoint, data, callback) {
- var self = this;
- self.get(endpoint, function(base) {
- for (var key in data) {
- base[key] = data[key];
- }
- self.put(endpoint, base, callback);
- });
-}
\ No newline at end of file
+(function( $ ) {
+
+ /*
+ The OptimizelyAPI class provides a connection to the API via Javascript
+ and lets you make authenticated calls without repeating yourself.
+ We store the API token in each instance of the object,
+ and we can connect to multiple different accounts by creating new instances of the OptimizelyAPI class.
+ Finally, we keep track of how many requests are outstanding so we can tell when all the calls are complete.
+ */
+ OptimizelyAPI = function(token) {
+ this.outstandingRequests = 0;
+ this.token = token;
+ }
+
+ /*
+ To call the API, we use jQuery's `$.ajax` function, which sends an asynchronous request based on a set of `options`.
+
+ Our function takes four arguments:
+
+ * The request `type`, like GET or POST
+ * The `endpoint` to hit, like `projects/27`
+ * The `data` to send along with a POST or PUT request
+ * A `callback` function to run when the operation is done. The callback should take one argument, the `response`.
+
+ We construct the URL by appending the endpoint to the base API link, and we authenticate by adding the token in the headers section.
+ To send data, we set content type to JSON and encode the array as a JSON string to send over the wire.
+ */
+ OptimizelyAPI.prototype.call = function( type, endpoint, data, callback ) {
+ var self = this;
+
+ var options = {
+ url: 'https://www.optimizelyapis.com/experiment/v1/' + endpoint,
+ type: type,
+ headers: { 'Token': this.token },
+ contentType: 'application/json',
+ success: function( response ) {
+ self.outstandingRequests -= 1;
+ callback( response );
+ }
+ };
+
+ if ( data ) {
+ options.data = JSON.stringify( data );
+ options.dataType = 'json';
+ }
+
+ this.outstandingRequests += 1;
+ $.ajax( options );
+ }
+
+ // Using our `call` function, we can define convenience functions for GETs, POSTs, PUTs, and DELETEs.
+ OptimizelyAPI.prototype.get = function( endpoint, callback ) {
+ this.call( 'GET', endpoint, '', callback );
+ }
+
+ OptimizelyAPI.prototype.delete = function( endpoint, callback ) {
+ this.call( 'DELETE', endpoint, '', callback );
+ }
+
+ OptimizelyAPI.prototype.post = function( endpoint, data, callback ) {
+ this.call( 'POST', endpoint, data, callback );
+ }
+
+ OptimizelyAPI.prototype.put = function( endpoint, data, callback ) {
+ this.call( 'PUT', endpoint, data, callback );
+ }
+
+ /*
+ We've also added an extra convenience function, `patch`, that updates a model by changing only the specified fields.
+ The function works by reading in an entity, changing a few keys, and then sending it back to Optimizely.
+ */
+ OptimizelyAPI.prototype.patch = function( endpoint, data, callback ) {
+ var self = this;
+
+ self.get( endpoint, function( base ) {
+ for ( var key in data ) {
+ base[ key ] = data[ key ];
+ }
+
+ self.put( endpoint, base, callback );
+ });
+ }
+})( jQuery );
diff --git a/optimizely.php b/optimizely.php
index 61c2ce9..30844dc 100644
--- a/optimizely.php
+++ b/optimizely.php
@@ -6,7 +6,7 @@
/*
Plugin Name: Optimizely
Plugin URI: http://wordpress.org/extend/plugins/optimizely/
-Description: Simple, fast, and powerful.
Optimizely is a dramatically easier way for you to improve your website through A/B testing. Create an experiment in minutes with our easy-to-use visual interface with absolutely no coding or engineering required. Convert your website visitors into customers and earn more revenue today! To get started: 1) Click the "Activate" link to the left of this description, 2) Sign up for an
Optimizely account , and 3) Go to the
settings page , and enter your Optimizely project code.
+Description: Simple, fast, and powerful.
Optimizely is a dramatically easier way for you to improve your website through A/B testing. Create an experiment in minutes with our easy-to-use visual interface with absolutely no coding or engineering required. Convert your website visitors into customers and earn more revenue today! To get started: 1 ) Click the "Activate" link to the left of this description, 2 ) Sign up for an
Optimizely account , and 3 ) Go to the
settings page , and enter your Optimizely project code.
Author: Arthur Suermondt, Jon Noronha, Brad Taylor
Version: 3.0.0
Author URI: http://www.optimizely.com/
@@ -28,43 +28,75 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-if ( is_admin() ) {
- require_once dirname( __FILE__ ) . '/admin.php';
- require_once dirname( __FILE__ ) . '/edit.php';
- wp_enqueue_script('jquery');
- wp_enqueue_script('jquery-ui-core');
- wp_enqueue_script('jquery-ui-tabs');
- wp_enqueue_script('jquery-ui-progressbar');
- wp_enqueue_script('jquery-ui-tooltip');
- wp_enqueue_script('optimizely_api', plugins_url('optimizely.js', __FILE__));
- wp_enqueue_script('optimizely_editor', plugins_url('edit.js', __FILE__));
- wp_localize_script('optimizely_editor', 'wpAjaxUrl', admin_url('admin-ajax.php'));
- wp_enqueue_script('optimizely_config', plugins_url('config.js', __FILE__));
- wp_enqueue_script('optimizely_results', plugins_url('results.js', __FILE__));
- wp_enqueue_style('jquery_ui_styles', plugins_url('jquery-ui.css', __FILE__));
- wp_enqueue_style('font_awesome_styles',plugins_url('font-awesome.min.css', __FILE__));
- wp_enqueue_style('optimizely_styles', plugins_url('style.css', __FILE__));
-}
+// Constants for default settings
+define( 'OPTIMIZELY_DEFAULT_VARIATION_TEMPLATE', '$( ".post-$POST_ID .entry-title a" ).text( "$NEW_TITLE" );' );
+define( 'OPTIMIZELY_DEFAULT_VISITOR_COUNT', 10316 );
+define( 'OPTIMIZELY_NUM_VARIATIONS', 2 );
+define( 'OPTIMIZELY_NONCE', 'optimizely-update-code' );
- $DEFAULT_VARIATION_TEMPLATE = '$(".post-$POST_ID .entry-title a").text("$NEW_TITLE");';
- add_option('optimizely_variation_template', $DEFAULT_VARIATION_TEMPLATE);
- $DEFAULT_VISITOR_COUNT = 10316;
- add_option('optimizely_post_types', 'post');
- add_option('optimizely_visitor_count', $DEFAULT_VISITOR_COUNT);
- add_option('num_variations', 2);
+// Include files are only required on the admin dashboard
+if ( is_admin() ) {
+ require_once( dirname( __FILE__ ) . '/admin.php' );
+ require_once( dirname( __FILE__ ) . '/edit.php' );
+}
- add_option('optimizely_launch_auto', false);
+/**
+ * Enqueues Optimizely scripts required by the admin dashboard.
+ */
+function optimizely_enqueue_scripts() {
+ // Core scripts
+ wp_enqueue_script( 'jquery' );
+ wp_enqueue_script( 'underscore' );
+ wp_enqueue_script( 'jquery-ui-core' );
+ wp_enqueue_script( 'jquery-ui-tabs' );
+ wp_enqueue_script( 'jquery-ui-progressbar' );
+ wp_enqueue_script( 'jquery-ui-tooltip' );
+
+ wp_enqueue_script( 'optimizely_api', plugins_url( 'optimizely.js', __FILE__ ), array( 'jquery' ) );
+ wp_enqueue_script( 'optimizely_editor', plugins_url( 'edit.js', __FILE__ ), array( 'jquery' ) );
+ wp_localize_script( 'optimizely_editor', 'wpAjaxUrl', admin_url( 'admin-ajax.php' ) );
+ wp_enqueue_script( 'optimizely_config', plugins_url( 'config.js', __FILE__ ), array( 'jquery' ) );
+ wp_enqueue_script( 'optimizely_results', plugins_url( 'results.js', __FILE__ ), array( 'jquery', 'jquery-ui-core', 'jquery-ui-tabs','jquery-ui-progressbar','jquery-ui-tooltip', 'underscore' ) );
+ wp_localize_script( 'optimizely_editor', 'optimizelySettings', array(
+ 'token' => get_option( 'optimizely_token' ),
+ 'projectId' => get_option( 'optimizely_project_id' ),
+ 'visitorCount' => get_option( 'optimizely_visitor_count', 0 ),
+ ) );
+
+ wp_enqueue_style( 'jquery_ui_styles', plugins_url( 'jquery-ui.css', __FILE__ ) );
+ wp_enqueue_style( 'font_awesome_styles', plugins_url( 'font-awesome.min.css', __FILE__ ) );
+ wp_enqueue_style( 'optimizely_styles', plugins_url( 'style.css', __FILE__ ) );
+}
+add_action( 'admin_enqueue_scripts', 'optimizely_enqueue_scripts' );
- // Force Optimizely to load first in the head tag
- add_action('wp_head', 'add_optimizely_script', -1000);
+/**
+ * Force Optimizely to load first in the head tag.
+ */
+function optimizely_add_script() {
+ $project_code = get_option( 'optimizely_project_code' );
+ if ( ! empty( $project_code ) ) {
+ // This cannot be escaped since optimizely_generate_script returns a script tag.
+ // The output of this script is fully escaped within the function below.
+ echo optimizely_generate_script( $project_code );
+ }
+}
+add_action( 'wp_head', 'optimizely_add_script', -1000 );
- function add_optimizely_script() {
- echo get_option('optimizely_project_code');
- }
+/**
+ * Generates the Optimizely script tag.
+ * @param int $project_code
+ * @return string
+ */
+function optimizely_generate_script( $project_code ) {
+ return '';
+}
- function can_create_experiments() {
- return get_option('optimizely_token');
- }
+/**
+ * Check capabilites for creating experiments.
+ */
+function optimizely_can_create_experiments() {
+ return get_option( 'optimizely_token', false );
+}
?>
\ No newline at end of file
diff --git a/results.js b/results.js
index a5dcead..5e586b4 100644
--- a/results.js
+++ b/results.js
@@ -1,305 +1,341 @@
+( function( $ ) {
-function optimizelyResultsPage(apiToken,projectId,poweredVisitor) {
- var $ = jQuery;
+ function optimizelyResultsPage( apiToken, projectId, poweredVisitor ) {
+ var optly = new OptimizelyAPI( apiToken );
- var optly = new OptimizelyAPI(apiToken);
+ // Fetch only Wordpress experiments from project
+ optly.get( 'projects/' + projectId + '/experiments/', function( response ) {
+ optly.wordpressExps = [];
+ var resultsArray = [];
+
+ for ( i = 0; i < response.length; i++ ) {
+ if ( response[ i ].description.indexOf( 'Wordpress' ) > -1
+ && 'Archived' != response[ i ].status
+ && 'Not started' != response[ i ].status
+ && 'Draft' != response[ i ].status ) {
+ resultsArray.push( response[ i ] );
+ }
+
+ }
+
+ if ( resultsArray.length > 0 ) {
+ for ( i = 0; i < resultsArray.length; i++ ) {
+ getWPExpResults( resultsArray[ i ],function( exp ) {
+ displayResultsList( exp,i,function() {
+ showGoalSelected( exp.id );
+ addSelectChange( exp.id );
+ });
+ });
+ }
+ } else {
+ $( '#noresults' ).show();
+ $( '#loading' ).hide();
+ $( '#ready' ).hide();
+ }
+ });
- //fetch only Wordpress experiments from project
- optly.get('projects/' + projectId + '/experiments/', function(response) {
- optly.wordpressExps = [];
- var resultsArray = [];
- for (i=0; i
-1 && response[i].status != 'Archived' && response[i].status != 'Not started' && response[i].status != 'Draft') {
- resultsArray.push(response[i]);
- }
-
- }
- if(resultsArray.length > 0){
- for (i=0; i b.goal_name)
- return 1;
- return 0;
- }
+ // Simple compare function to sort goals by name
+ function compare( a,b ) {
+ if ( a.goal_name < b.goal_name ) {
+ return -1;
+ }
+
+ if ( a.goal_name > b.goal_name ) {
+ return 1;
+ }
+
+ return 0;
+ }
- // Gets the results for the experiment
- function getWPExpResults(expObj,cb) {
- expObj.results = [];
- optly.get('experiments/' + expObj.id + '/results', function(response) {
- var goalNameArray = [];
- response.sort(compare);
- expObj.results = response;
- expObj.avgVisitorCount = getAverageVisitor(expObj.results);
- cb(expObj);
- });
- }
+ // Gets the results for the experiment
+ function getWPExpResults( expObj,cb ) {
+ expObj.results = [];
+ optly.get( 'experiments/' + expObj.id + '/results', function( response ) {
+ var goalNameArray = [];
+ response.sort( compare );
+ expObj.results = response;
+ expObj.avgVisitorCount = getAverageVisitor( expObj.results );
+ cb( expObj );
+ });
+ }
- // AJAX function that updates the title in Wordpress
- function launchWinner(expID, expTitle, winningVarName){
- // Get the ID of the Wordpress post
- var wpPostID = expTitle.substring(11,expTitle.indexOf(']'));
- var data = {
- action: "update_post_title",
- post_id: wpPostID,
- title: winningVarName
- };
+ // AJAX function that updates the title in Wordpress
+ function launchWinner( expID, expTitle, winningVarName ) {
+ // Get the ID of the Wordpress post
+ var wpPostID = expTitle.substring( 11, expTitle.indexOf( ']' ) );
+ var data = {
+ action: 'update_post_title',
+ post_id: wpPostID,
+ title: winningVarName
+ };
- $.post(wpAjaxUrl, data, function(){
- $('#exp_'+expID).fadeOut(1000,function(){
- $('#successMessage').html('You have succesfully launched the new headline Old Headline: '+expTitle+' New Headline: '+winningVarName);
- $('#successMessage').show();
- // Archive the Experiement
- archiveExperiment(expID);
- });
- });
- }
+ $.post( wpAjaxUrl, data, function() {
+ $( '#exp_' + expID ).fadeOut( 1000, function() {
+ $message = $( '' ).text( 'You have succesfully launched the new headline' );
+ $old = $( ' ' ).text( 'Old Headline: ' + expTitle );
+ $new = $( '
' ).text( 'New Headline: ' + winningVarName );
+
+ $( '#successMessage' )
+ .html( '' )
+ .append( $message )
+ .append( $old )
+ .append( $new )
+ .show();
+
+ // Archive the Experiement
+ archiveExperiment( expID );
+ });
+ });
+ }
- // Pause Experiment
- function pauseExperiment(experimentID) {
- optly.patch('experiments/' + experimentID, {'status': 'Paused'}, function(response) {
- $(".opt_results[data-exp-id="+ experimentID +"]").find(".pause").removeClass("pause").addClass("play");
- $(".opt_results[data-exp-id="+ experimentID +"]").find(".fa-pause").removeClass("fa-pause").addClass("fa-play");
- });
- }
+ // Pause Experiment
+ function pauseExperiment( experimentID ) {
+ optly.patch( 'experiments/' + experimentID, { 'status': 'Paused' }, function( response ) {
+ $( '.opt_results[data-exp-id=' + experimentID + ']' )
+ .find( '.pause' )
+ .removeClass( 'pause' )
+ .addClass( 'play' );
+
+ $( '.opt_results[data-exp-id=' + experimentID + ']' )
+ .find( '.fa-pause' )
+ .removeClass( 'fa-pause' )
+ .addClass( 'fa-play' );
+ });
+ }
- // Start Experiment
- function startExperiment(experimentID) {
- optly.patch('experiments/' + experimentID, {'status': 'Running'}, function(response) {
- $(".opt_results[data-exp-id="+ experimentID +"]").find(".play").removeClass("play").addClass("pause");
- $(".opt_results[data-exp-id="+ experimentID +"]").find(".fa-play").removeClass("fa-play").addClass("fa-pause");
- });
- }
+ // Start Experiment
+ function startExperiment( experimentID ) {
+ optly.patch( 'experiments/' + experimentID, { 'status': 'Running' }, function( response ) {
+ $( '.opt_results[data-exp-id=' + experimentID + ']' )
+ .find( '.play' )
+ .removeClass( 'play' )
+ .addClass( 'pause' );
+
+ $( '.opt_results[data-exp-id=' + experimentID + ']' )
+ .find( '.fa-play' )
+ .removeClass( 'fa-play' )
+ .addClass( 'fa-pause' );
+ });
+ }
- // Archive Experiment
- function archiveExperiment(experimentID) {
- optly.patch('experiments/'+ experimentID, {'status': 'Archived'}, function(response) {
- $(".opt_results[data-exp-id="+ experimentID +"]").hide();
- });
- }
+ // Archive Experiment
+ function archiveExperiment( experimentID ) {
+ optly.patch( 'experiments/'+ experimentID, { 'status': 'Archived' }, function( response ) {
+ $( '.opt_results[data-exp-id=' + experimentID + ']' ).hide();
+ });
+ }
- // Will display the resutls and build the HTML
- function displayResultsList(exp,i,cb) {
- $('.loading').hide();
- var html = buildResultsModuleHTML(exp);
- if(exp.avgVisitorCount > poweredVisitor){
- $('#ready').show();
- $('#ready').append(html);
- }else{
- $('#stillwaiting').show();
- $('#stillwaiting').append(html);
- }
+ // Will display the resutls and build the HTML
+ function displayResultsList( exp, i, cb ) {
+ $( '.loading' ).hide();
+ var data = buildResultsModuleData( exp );
+ var tpl = _.template( $( '#optimizely_results' ).html() );
+
+ if ( exp.avgVisitorCount > poweredVisitor ) {
+ $( '#ready' ).append( tpl( data ) );
+ $( '#ready' ).show();
+ } else {
+ $( '#stillwaiting' ).append( tpl( data ) );
+ $( '#stillwaiting' ).show();
+ }
- animateProgressBar(exp);
- cb();
- }
+ animateProgressBar( exp );
+ cb();
+ }
- // Loops through the variations and gets an average of the visitor count for powered testing
- function getAverageVisitor(results){
- var totalVisitors = 0;
- for(var i=0;i < results.length;i++){
- totalVisitors += results[i].visitors;
- }
+ // Loops through the variations and gets an average of the visitor count for powered testing
+ function getAverageVisitor( results ) {
+ var totalVisitors = 0;
+ for ( var i=0; i < results.length; i++ ) {
+ totalVisitors += results[ i ].visitors;
+ }
- return totalVisitors/results.length;
- }
+ return totalVisitors/results.length;
+ }
- // Uses the average visitor count to create the progress bar
- function animateProgressBar(exp){
- var progressbar = $('#exp_'+exp.id).find('.progressbar'),
- poweredPercentage = Math.round((exp.avgVisitorCount/poweredVisitor)*100);
- progressbar.progressbar({
- value: exp.avgVisitorCount,
- max: poweredVisitor
- });
+ // Uses the average visitor count to create the progress bar
+ function animateProgressBar( exp ) {
+ var progressbar = $( '#exp_' + exp.id ).find( '.progressbar' ),
+ poweredPercentage = Math.round( ( exp.avgVisitorCount/poweredVisitor ) * 100 );
+ progressbar.progressbar({
+ value: exp.avgVisitorCount,
+ max: poweredVisitor
+ });
- var progBarColor;
- switch(true){
- case (poweredPercentage < 25):
- progBarColor = "#FF0000";
- break;
- case (poweredPercentage >= 25 && poweredPercentage < 50):
- progBarColor = "#FB7948";
- break;
- case (poweredPercentage >= 50 && poweredPercentage < 75):
- progBarColor = "#FBA92F";
- break;
- case (poweredPercentage >= 75 && poweredPercentage < 100):
- progBarColor = "#CFF43B";
- break;
- default:
- progBarColor = "#90b71c";
- break;
- }
+ var progBarColor;
+ switch( true ) {
+ case ( poweredPercentage < 25 ):
+ progBarColor = '#FF0000';
+ break;
+ case ( poweredPercentage >= 25 && poweredPercentage < 50 ):
+ progBarColor = '#FB7948';
+ break;
+ case ( poweredPercentage >= 50 && poweredPercentage < 75 ):
+ progBarColor = '#FBA92F';
+ break;
+ case ( poweredPercentage >= 75 && poweredPercentage < 100 ):
+ progBarColor = '#CFF43B';
+ break;
+ default:
+ progBarColor = '#90b71c';
+ break;
+ }
- $(progressbar).find('.ui-progressbar-value').css({'background':progBarColor,'border':'1px solid '+progBarColor});
- $(progressbar).attr('title',Math.round(exp.avgVisitorCount)+' / '+poweredVisitor+' visitors');
- }
+ $( progressbar )
+ .find( '.ui-progressbar-value' )
+ .css({
+ 'background': progBarColor,
+ 'border': '1px solid ' + progBarColor
+ });
+ $( progressbar ).attr( 'title', Math.round( exp.avgVisitorCount ) + ' / ' + poweredVisitor + ' visitors' );
+ }
- // Used to convert the value returned by the results API to a rounded percentage
- function getRoundedPercentage(num){
- return (num*100).toFixed(2)+"%";
- }
+ // Used to convert the value returned by the results API to a rounded percentage
+ function getRoundedPercentage( num ) {
+ return ( num*100 ).toFixed( 2 ) + '%';
+ }
- // Changes the goal results based on what is selcted
- function showGoalSelected(expID){
- $('#exp_'+expID).find('.variationrow').hide();
- var goalClass = $('#goal_'+expID).val();
- $('#exp_'+expID).find('.'+goalClass).show();
+ // Changes the goal results based on what is selcted
+ function showGoalSelected( expID ) {
+ $( '#exp_' + expID ).find( '.variationrow' ).hide();
+ var goalClass = $( '#goal_' + expID ).val();
+ $( '#exp_' + expID ).find( '.'+goalClass ).show();
- }
-
- // Main function that builds the HTNML for each results block
- function buildResultsModuleHTML(exp) {
- // Set the checkbox html
- var statusClass = 'play';
- if(exp.status == "Running"){
- statusClass = 'pause';
- }
- var expTitle = exp.description;
- expTitle = expTitle.substring(expTitle.indexOf(']:')+3);
- if(expTitle.length > 73){
- expTitle = expTitle.substring(0,72)+'...';
- }
- var html = ""+
- '
'+
- ''+
- '
'+
- '
'+
- ''+
- 'VARIATION '+
- 'VISITORS '+
- 'CONVERSIONS '+
- 'CONVERSION RATE '+
- 'IMPROVEMENT '+
- 'CONFIDENCE '+
- 'LAUNCH '+
- ' ';
- var isWinner = false;
- for(i=exp.results.length -1;i >= 0;i--){
- var result = exp.results[i],
- improvement,
- conversion_rate,
- avgVisitors = getAverageVisitor(exp.results),
- confidence;
- if(result.status == "baseline"){
- improvement = 'baseline';
- confidence = '-';
- }else{
- confidence = getRoundedPercentage(result.confidence);
- improvement = getRoundedPercentage(result.improvement);
- }
- html = html+
- ''+
- ''+result.variation_name+' '+
- ''+result.visitors+' '+
- ''+result.conversions+' '+
- ''+getRoundedPercentage(result.conversion_rate)+' '+
- ''+improvement+' '+
- ''+confidence+' '+
- '';
- if(result.status != 'baseline'){
- html += '
';
- }
-
- html +=' '+
- ' ';
- }
- html = html+
- '
'+
- '
'+
- ''+
- '
';
- return html;
+ }
+
+ // Main function that builds the HTNML for each results block
+ function buildResultsModuleData( exp ) {
+ // Set the checkbox html
+ var statusClass = 'play';
+
+ if ( 'Running' == exp.status ) {
+ statusClass = 'pause';
+ }
+
+ var expTitle = exp.description;
+ expTitle = expTitle.substring( expTitle.indexOf( ']:' ) + 3 );
+ if ( expTitle.length > 73 ) {
+ expTitle = expTitle.substring( 0, 72 ) + '...';
+ }
+
+ var goalIdArray = [];
+ var goalOptions = [];
+ for ( var i = 0; i < exp.results.length; i++ ) {
+ var result = exp.results[ i ];
+ var selected = '';
+ if ( goalIdArray.indexOf( result.goal_id ) == -1 ) {
+ if ( result.goal_name == 'Views to page' ) {
+ selected = 'selected';
+ } else {
+ selected = '';
+ }
+
+ goalOptions.push({
+ id: result.goal_id,
+ selected: selected,
+ name: result.goal_name
+ });
+
+ goalIdArray.push( result.goal_id );
+ }
+ }
+
+ var variations = [];
+ var isWinner = false;
+ for ( i = exp.results.length -1; i >= 0; i-- ) {
+ var result = exp.results[ i ],
+ improvement,
+ conversion_rate,
+ avgVisitors = getAverageVisitor( exp.results ),
+ confidence;
+
+ if ( 'baseline' == result.status ) {
+ improvement = 'baseline';
+ confidence = '-';
+ } else {
+ confidence = getRoundedPercentage( result.confidence );
+ improvement = getRoundedPercentage( result.improvement );
+ }
+
+ var conversionRate = getRoundedPercentage( result.conversion_rate );
+
+ variations.push({
+ expID: exp.id,
+ status: result.status,
+ goalId: result.goal_id,
+ variationId: result.variation_id,
+ variationName: result.variation_name,
+ editUrl: exp.edit_url,
+ visitors: result.visitors,
+ conversions: result.conversions,
+ conversionRate: conversionRate,
+ improvement: improvement,
+ confidence: confidence
+ });
+ }
+
+ data = {
+ id: exp.id,
+ description: exp.description,
+ title: expTitle,
+ goalOptions: goalOptions,
+ statusClass: statusClass,
+ variations: variations
+ };
+
+ return data;
+ }
}
-}
\ No newline at end of file
+ $( document ).ready(function() {
+ if ( 'toplevel_page_optimizely-config' == pagenow && '' != optimizelySettings.token && '' != optimizelySettings.projectId ) {
+ optimizelyResultsPage( optimizelySettings.token, optimizelySettings.projectId, optimizelySettings.visitorCount );
+ } else {
+ $( '#loading' ).hide();
+ }
+ });
+})( jQuery );
diff --git a/style.css b/style.css
index 9ef9071..86af55d 100644
--- a/style.css
+++ b/style.css
@@ -8,47 +8,51 @@
width: 100%;
}
-#optimizely-tabs .opt_results{
+#optimizely_created, #optimizely_not_created {
+ display: none;
+}
+
+#optimizely-tabs .opt_results {
border: solid 1px #d5d5d5;
margin-bottom: 30px;
box-shadow: 4px 4px 5px 2px rgba(36,36,0,0.1);
}
-#optimizely-tabs .header .title{
+#optimizely-tabs .header .title {
display: inline-block;
width: 60%;
}
-#optimizely-tabs .header .title i{
- color:green;
- font-size:20px
+#optimizely-tabs .header .title i {
+ color: green;
+ font-size: 20px
}
-#optimizely-tabs .winner{
+#optimizely-tabs .winner {
background-color: #D9FBD6;
}
-#optimizely-tabs #winners, #optimizely-tabs #stillwaiting, #optimizely-tabs #ready{
- display:none;
+#optimizely-tabs #winners, #optimizely-tabs #stillwaiting, #optimizely-tabs #ready {
+ display: none;
}
-#optimizely-tabs .header .results_toolbar{
+#optimizely-tabs .header .results_toolbar {
display: inline-block;
width: 40%;
float: right;
text-align: right;
}
-#optimizely-tabs .variationrow{
- display:none;
+#optimizely-tabs .variationrow {
+ display: none;
border-bottom: 1px solid #000;
}
-#optimizely-tabs #launchWinners{
+#optimizely-tabs #launchWinners {
margin-bottom: 15px;
}
-#optimizely-tabs .header, #optimizely-tabs .footer{
+#optimizely-tabs .header, #optimizely-tabs .footer {
height: 20px;
background: #EAEFF1;
padding: 5px 15px 5px 10px;
@@ -62,119 +66,119 @@
}
-#optimizely-tabs .header .title{
- margin-top:5px;
+#optimizely-tabs .header .title {
+ margin-top: 5px;
}
-#optimizely-tabs .header{
+#optimizely-tabs .header {
border-bottom: solid 2px #999;
}
-#optimizely-tabs .results_toolbar .button{
+#optimizely-tabs .results_toolbar .button {
margin-left: 5px;
}
-#optimizely-tabs td,#optimizely-tabs th{
- padding:10px 30px 10px 10px;
+#optimizely-tabs td,#optimizely-tabs th {
+ padding: 10px 30px 10px 10px;
}
-#optimizely-tabs .variations{
+#optimizely-tabs .variations {
background-color: gray;
}
-#optimizely-tabs tr{
+#optimizely-tabs tr {
background-color: #FFFFFF;
}
-#optimizely-tabs table{
+#optimizely-tabs table {
width: 100%;
text-align: right;
border-spacing: 0pt;
}
-#optimizely-tabs td.first{
+#optimizely-tabs td.first {
width: 20%
}
-#optimizely-tabs td.last{
+#optimizely-tabs td.last {
border-right: none;
text-align: center;
}
-#optimizely-tabs{
+#optimizely-tabs {
background-color: white;
z-index: 1;
}
-#optimizely-tabs .tabs-header{
+#optimizely-tabs .tabs-header {
background-color: white;
border: none;
background: #f7f7f7;
}
-#optimizely-tabs th{
+#optimizely-tabs th {
background-color: #F8F8F8
}
-#optimizely-tabs td.last i{
- color:green;
- font-size:25px;
+#optimizely-tabs td.last i {
+ color: green;
+ font-size: 25px;
}
-#optimizely-tabs td.last{
+#optimizely-tabs td.last {
padding: 0px;
}
-#optimizely-tabs .loading{
+#optimizely-tabs .loading {
width: 100%;
- padding:20px;
- text-align:center;
+ padding: 20px;
+ text-align: center;
}
-#optimizely-tabs .progressbar{
+#optimizely-tabs .progressbar {
border-bottom-right-radius: 15px;
border-top-right-radius: 15px;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
- width:100%;
+ width: 100%;
display: inline-block;
height: 20px;
- margin-top:5px;
- margin-right:50px;
+ margin-top: 5px;
+ margin-right: 50px;
}
-#optimizely-tabs .ready, .not-ready{
+#optimizely-tabs .ready, .not-ready {
display: inline-block;
height: 20px;
width: 140px;
text-align: center;
}
-#optimizely-tabs .ready i{
+#optimizely-tabs .ready i {
color: #1964AF;
}
-#optimizely-tabs .button.winner{
+#optimizely-tabs .button.winner {
background: #1964AF;
- color:#ffffff;
+ color: #ffffff;
}
-#optimizely-tabs .ready.launch{
- background-color:#1964AF;
- color:#ffffff;
+#optimizely-tabs .ready.launch {
+ background-color: #1964AF;
+ color: #ffffff;
}
-#optimizely-tabs #successMessage{
- display:none;
+#optimizely-tabs #successMessage {
+ display: none;
width: 100%;
- padding:10px;
+ padding: 10px;
background-color: #D9FBD6;
}
-#optimizely-tabs #stillwaiting > h2{
+#optimizely-tabs #stillwaiting > h2 {
padding: 0px 0px 10px 10px;
border-left: solid 1px #1964AF;
border-bottom: solid 1px #1964AF;
@@ -182,14 +186,20 @@
}
-#optimizely-tabs #stillwaiting > h2 > span, #optimizely-tabs #tabs-1 > h2 > span{
+#optimizely-tabs #stillwaiting > h2 > span, #optimizely-tabs #tabs-1 > h2 > span {
font-size: 13px;
float: right;
}
+#noresults {
+ display: none;
+}
+#optimizely-tabs #stillwaiting, #optimizely-tabs #ready {
+ margin-top: 30px;
+}
-#noresults{
- display:none;
+input.optimizely_variation {
+ width: 100%;
}