PHPackages                             altis/ab-tests - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. altis/ab-tests

Abandoned → [altis/experiments](/?search=altis%2Fexperiments)Wordpress-plugin[Framework](/categories/framework)

altis/ab-tests
==============

Web Experimentation framework for Altis

2.4.4(5y ago)1121[7 issues](https://github.com/humanmade/experiments/issues)GPL-2.0-or-laterJavaScript

Since Jul 26Pushed 4y ago16 watchersCompare

[ Source](https://github.com/humanmade/experiments)[ Packagist](https://packagist.org/packages/altis/ab-tests)[ RSS](/packages/altis-ab-tests/feed)WikiDiscussions master Synced 3d ago

READMEChangelogDependencies (2)Versions (39)Used By (0)

Altis Experiments
=================

[](#altis-experiments)

Web Experimentation framework for Altis.

Features
--------

[](#features)

The plugin currently provides the following built in features:

### Post Title A/B Tests

[](#post-title-ab-tests)

With this feature enabled it's simple to create A/B Tests for your post titles directly from the post edit screen.

It is enabled by default but can be disabled using the following filter:

```
add_filter( 'altis.experiments.features.titles', '__return_false' );
```

Posts and pages are supported by default however you can add support for custom post types using the following code in a plugin or your theme's `functions.php`:

```
add_post_type_support( 'events', 'altis.experiments.titles' );
```

Usage
-----

[](#usage)

The plugin provides a programmatic API to register custom A/B Tests for post data:

**`register_post_ab_test( string $test_id, array $options )`**

Sets up the test.

- `$test_id`: A unique ID for the test.
- `$options`: Configuration options for the test.
    - `label `: A human readable label for the test.
    - `rest_api_variants_field `: The field name to make variants available at.
    - `rest_api_variants_type `: The data type of the variants.
    - `goal `: The conversion goal event name, eg "click" or "click:.selector a".
    - `goal_filter `: Elasticsearch bool query to filter goal results. If a callable is passed it receives the test ID and post ID as arguments.
    - `query_filter `: Elasticsearch bool query to filter total events being queried. If a callable is passed it receives the test ID and post ID as arguments.
    - `variant_callback `: An optional callback used to render variants based. Arguments:
        - `$value `: The variant value.
        - `$post_id `: The post ID.
        - `$args `: Optional args passed to `output_ab_test_html_for_post()`.
    - `winner_callback `: An optional callback used to perform updates to the post when a winner is found. Defaults to no-op. Arguments:
        - `$post_id `: The post ID
        - `$value `: The winning variant value.
    - `post_types `: An array of supported post types for the test.

**`output_ab_test_html_for_post( string $test_id, int $post_id, string $default_content, array $args = [] )`**

Returns the A/B Test markup for client side processing.

- `$test_id`: A unique ID for the test.
- `$post_id`: The post ID for the test.
- `$default_content`: The default content for users not in the test.
- `$args`: An optional array of data to pass through to `variant_callback`.

```
namespace Altis\Experiments;

// Register the test.
register_post_ab_test( 'featured_images', [
	'rest_api_variants_type' => 'integer',
	'goal' => 'click',
	'variant_callback' => function ( $attachment_id, $post_id, $args ) {
		return wp_get_attachment_image(
			$attachment_id,
			$args['size'],
			false,
			$args['attr']
		);
	}
] );

// Apply the test by filtering some standard output.
add_filter( 'post_thumbnail_html', function ( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
	return output_ab_test_html_for_post( 'featured_images', $post_id, $html, [
		'size' => $size,
		'attr' => $attr,
	] );
}, 10, 5 );
```

### Goal Tracking

[](#goal-tracking)

Conversion goals are how it is determined whether a variant has been successful or not. This is calculated as the `number of conversions / number of impressions`.

The `click` goal handler is provided out of the box and adds a click event handler to the nearest `` tag.

#### Scoped Event Handling

[](#scoped-event-handling)

For tests where more complex alternative HTML is being rendered you can define the event target with a CSS selector passed to `element.querySelectorAll()`.

For example setting the goal to `click:.my-target` will track a conversion when the element in the variant HTML matching `.my-target` is clicked. This applies for all registered goal handlers.

#### Custom Goal Handlers

[](#custom-goal-handlers)

You can define your own goal handlers in JavaScript:

**`Altis.Analytics.Experiments.registerGoal( name , callback , closest  )`**

This function adds a goal handler where `name` corresponds to the value of `$options['goal']` when registering an A/B Test.

The callback receives the following parameters:

- `element `: Target node for the event.
- `record `: Receives the target element and a callback to log the conversion. The function accepts two optional arguments:
    - `attributes `: Custom atttributes to record with the event.
    - `metrics `: Custom metrics to record with the event.

The `closest` parameter allows you to ensure the element passed to your callback is of a certain type, achieved by stepping up through the DOM tree, for example to return only anchor tags you would pass `[ 'a' ]`.

```
Altis.Analytics.Experiments.registerGoal( 'scrollIntoView', function ( element, record ) {
	var listener = function () {
		// Check element has come into view or not.
		if ( element.getBoundingClientRect().top > window.innerHeight ) {
			return;
		}

		// Remove event listener immediately.
		window.removeEventListener( 'scroll', listener );

		// Record event.
		record();
	};

	// Start listening to scroll events.
	window.addEventListener( 'scroll', listener );
} );
```

**Note:** This JavaScript should be enqueued in the `` via the `wp_enqueue_scripts` action.

Creating your own tests
-----------------------

[](#creating-your-own-tests)

How you manage the variant data is up to you, for example you could use Fieldmanager or Advanced Custom Fields to create metaboxes to save the variant data.

Note you should use the following functions to get and update the variants:

**`get_ab_test_variants_for_post( string $test_id, int $post_id ) : array`**

**`update_ab_test_variants_for_post( string $test_id, int $post_id, array $variants )`**

Roadmap
-------

[](#roadmap)

- Multivariate testing capability
- Features
    - Featured image tests

---

Made with ❤️ by [Human Made](https://humanmade.com/)

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance7

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 91.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~37 days

Recently: every ~27 days

Total

17

Last Release

1885d ago

Major Versions

1.1.0 → 2.0.02019-08-14

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/21655?v=4)[Ryan McCue](/maintainers/rmccue)[@rmccue](https://github.com/rmccue)

![](https://www.gravatar.com/avatar/77dbeefb7745010589603f2ffc6ff310d8f700b58e08d52af190744c43342526?d=identicon)[roborourke](/maintainers/roborourke)

![](https://www.gravatar.com/avatar/f1d0ffccdc5d339ff98a91e1b224a0d92f93dc8c2f772124473a76655b83129c?d=identicon)[joehoyle](/maintainers/joehoyle)

---

Top Contributors

[![roborourke](https://avatars.githubusercontent.com/u/23417?v=4)](https://github.com/roborourke "roborourke (197 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (11 commits)")[![rmccue](https://avatars.githubusercontent.com/u/21655?v=4)](https://github.com/rmccue "rmccue (4 commits)")[![joehoyle](https://avatars.githubusercontent.com/u/161683?v=4)](https://github.com/joehoyle "joehoyle (3 commits)")[![jazzsequence](https://avatars.githubusercontent.com/u/991511?v=4)](https://github.com/jazzsequence "jazzsequence (1 commits)")

### Embed Badge

![Health badge](/badges/altis-ab-tests/health.svg)

```
[![Health](https://phpackages.com/badges/altis-ab-tests/health.svg)](https://phpackages.com/packages/altis-ab-tests)
```

###  Alternatives

[laravel/telescope

An elegant debug assistant for the Laravel framework.

5.2k67.8M192](/packages/laravel-telescope)[spiral/roadrunner

RoadRunner: High-performance PHP application server and process manager written in Go and powered with plugins

8.4k12.2M84](/packages/spiral-roadrunner)[nolimits4web/swiper

Most modern mobile touch slider and framework with hardware accelerated transitions

41.8k177.2k1](/packages/nolimits4web-swiper)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)[laravel/prompts

Add beautiful and user-friendly forms to your command-line applications.

708181.8M596](/packages/laravel-prompts)[cakephp/chronos

A simple API extension for DateTime.

1.4k47.7M121](/packages/cakephp-chronos)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
