PHPackages                             mvo/contao-content-variants - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. mvo/contao-content-variants

ActiveContao-bundle[Utility &amp; Helpers](/categories/utility)

mvo/contao-content-variants
===========================

Use a single integer field to store variant configurations of content elements.

089PHP

Since Jan 19Pushed 4y ago1 watchersCompare

[ Source](https://github.com/m-vo/contao-content-variants)[ Packagist](https://packagist.org/packages/mvo/contao-content-variants)[ RSS](/packages/mvo-contao-content-variants/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

Contao Content Variants
=======================

[](#contao-content-variants)

This DX package eases working with binary variant options for content elements. The selected variants will be stored as bit flags in a **single integer column** in `tl_content`. The available values can be defined within each content element controller itself.

A typical usage scenario are predefined options like different layouts/designs/colors/… that an editor should be able to choose from via a select menu.

Usage
-----

[](#usage)

1. Add a `variantSelect` field for each variant group to your `tl_content`field section. Do not include SQL definitions:

    ```
     $GLOBALS['TL_DCA']['tl_content']['fields']['effect'] = [
             'inputType' => 'variantSelect',
             'eval' => [
                 'tl_class' => 'w50',
             ],
     ];

     $GLOBALS['TL_DCA']['tl_content']['fields']['layout'] = [
             'inputType' => 'variantSelect',
             'eval' => [
                 'tl_class' => 'w50',
             ],
     ];
    ```

    Then add the fields to your palettes like usual. The `variantSelect` is basically a select menu - we're automatically populating it with the respective options once you access the DCA in the back end.
2. Define labels in your language files. By default, an `_` will be appended to the field name for the options reference:

    ```
    $GLOBALS['TL_LANG']['tl_content']['effect'] = ['Effect', 'Visual variant'];
    $GLOBALS['TL_LANG']['tl_content']['effect_']['default'] = ['Default'];
    $GLOBALS['TL_LANG']['tl_content']['effect_']['popup'] = ['Popup'];
    $GLOBALS['TL_LANG']['tl_content']['effect_']['highlight'] = ['Highlight'];

    // …
    ```
3. Implement the `VariantsInterface` and use the `VariantsTrait` in your fragment controller. You can then define the variant groups and their values as bit flags like so:

    ```
    /**
     * @ContentElement(category="texts")
     */
    class MyTextFragment extends AbstractContentElementController implements VariantsInterface
    {
        use VariantsTrait;

        public function getVariants(): array
        {
            return [
                'effect' => [
                    'default'     => (1 (1 (1 [
                    'default'     => (1 (1 (1 (1 $model->text,
                'variants' => $this->getVariantsMap($model),
            ];

            return $this->render('@Contao/my_text.html.twig', $context);
        }
    }
    ```

    You have control over the bit flags. If you want to get rid of an option at one point, simply delete the line and keep the other fields untouched.
4. Handle variants in your template:

    ```

        {% if variants.effect.highlight %}
            Wow!
        {% endif %}

        […]

    ```

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity28

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5305677?v=4)[M. Vondano](/maintainers/m-vo)[@m-vo](https://github.com/m-vo)

---

Top Contributors

[![m-vo](https://avatars.githubusercontent.com/u/5305677?v=4)](https://github.com/m-vo "m-vo (2 commits)")

### Embed Badge

![Health badge](/badges/mvo-contao-content-variants/health.svg)

```
[![Health](https://phpackages.com/badges/mvo-contao-content-variants/health.svg)](https://phpackages.com/packages/mvo-contao-content-variants)
```

###  Alternatives

[florianv/swap

PHP currency conversion library for retrieving exchange rates from 30+ providers, with caching and fallback.

1.3k6.8M23](/packages/florianv-swap)[drupal/core-composer-scaffold

A flexible Composer project scaffold builder.

5445.2M563](/packages/drupal-core-composer-scaffold)[junohamburg/kirby-reload-on-save

Kirby Reload On Save

293.6k](/packages/junohamburg-kirby-reload-on-save)

PHPackages © 2026

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