PHPackages                             owl-concept/settings-bundle - 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. owl-concept/settings-bundle

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

owl-concept/settings-bundle
===========================

Bundle Symfony pour le paramétrage global de l'application et les préférences utilisateur (thème, langue, etc.) avec interface auto-générée | Symfony bundle for global application settings and per-user preferences with auto-generated UI

00PHP

Since Mar 5Pushed 3mo agoCompare

[ Source](https://github.com/Jaecko/owl-settings-bundle)[ Packagist](https://packagist.org/packages/owl-concept/settings-bundle)[ RSS](/packages/owl-concept-settings-bundle/feed)WikiDiscussions main Synced 2w ago

READMEChangelogDependenciesVersions (1)Used By (0)

OwlSettingsBundle
=================

[](#owlsettingsbundle)

[![PHP](https://camo.githubusercontent.com/88b464e5614cf654f181925115d47b523dc429fcfe41d59565e42e757f306f29/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253345253344382e312d3838393242462e737667)](https://www.php.net/)[![Symfony](https://camo.githubusercontent.com/b4b1393dc9e6ac9410cecb1dbdaed9eff36a00e3886287ddcbde27d1b00d438a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d362e34253230253743253230372e782d3030303030302e737667)](https://symfony.com/)

**\[FR\]** Bundle Symfony pour le paramétrage global de l'application et les préférences utilisateur (thème, langue, etc.) avec interface auto-générée. **\[EN\]** Symfony bundle for global application settings and per-user preferences (theme, language, etc.) with auto-generated UI.

---

Sommaire / Table of Contents
----------------------------

[](#sommaire--table-of-contents)

- [Français](#-fran%C3%A7ais)
    - [Fonctionnalités](#fonctionnalit%C3%A9s)
    - [Installation](#installation)
    - [Configuration](#configuration)
    - [Utilisation](#utilisation)
    - [Types de champs](#types-de-champs)
    - [Héritage des préférences](#h%C3%A9ritage-des-pr%C3%A9f%C3%A9rences)
    - [Fonctions Twig](#fonctions-twig)
- [English](#-english)
    - [Features](#features)
    - [Installation](#installation-1)
    - [Configuration](#configuration-1)
    - [Usage](#usage)
    - [Field types](#field-types)
    - [Preference inheritance](#preference-inheritance)
    - [Twig functions](#twig-functions)

---

🇫🇷 Français
-----------

[](#-français)

### Fonctionnalités

[](#fonctionnalités)

- **Deux niveaux de paramétrage** — paramètres globaux (admin) + préférences utilisateur (profil)
- **Builder pattern fluide** — API chainable inspirée du FormBuilder de Symfony
- **Groupes de paramètres** — organisation en onglets dans l'interface admin
- **Héritage** — une préférence utilisateur peut hériter d'un paramètre global si non définie
- **9 types de champs** — text, email, number, boolean (toggle switch), select, textarea, file, color, password
- **Stockage DBAL** — pas besoin de Doctrine ORM, fonctionne avec DBAL seul
- **Cache Symfony** — les paramètres sont cachés, invalidés automatiquement à la modification
- **Interface auto-générée** — templates Twig prêts à inclure pour l'admin et le profil utilisateur
- **Controller AJAX inclus** — routes de sauvegarde prêtes à l'emploi, zéro config
- **JavaScript vanilla** — onglets, soumission AJAX, preview thème/fichier, auto-save
- **CSS par défaut** — nommage BEM, toggle switch, responsive mobile
- **Fonctions Twig** — `owl_setting()` et `owl_user_pref()` pour lire les valeurs partout

### Installation

[](#installation)

Ajoutez le repository et le package dans votre `composer.json` :

```
{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/Jaecko/owl-settings-bundle"
        }
    ],
    "require": {
        "owl-concept/settings-bundle": "dev-main"
    }
}
```

Puis lancez :

```
composer update
```

Enregistrez le bundle dans `config/bundles.php` :

```
return [
    // ...
    OwlConcept\SettingsBundle\OwlSettingsBundle::class => ['all' => true],
];
```

Importez les routes du bundle dans `config/routes/owl_settings.yaml` :

```
owl_settings:
    resource: '@OwlSettingsBundle/Resources/config/routes.yaml'
```

Installez les assets (CSS &amp; JS) :

```
php bin/console assets:install
```

Créez les tables en base de données :

```
# Prévisualiser le SQL
php bin/console owl:settings:install

# Exécuter
php bin/console owl:settings:install --force
```

Incluez le CSS et le JS dans votre template de base :

```

```

### Configuration

[](#configuration)

Configuration optionnelle dans `config/packages/owl_settings.yaml` :

```
owl_settings:
    css_class_prefix: owl-settings       # Préfixe CSS (défaut: owl-settings)
    cache_pool: cache.app                # Pool de cache Symfony (défaut: cache.app)
    cache_ttl: 3600                      # Durée du cache en secondes (défaut: 3600)
    settings_table: owl_settings         # Nom de la table des paramètres (défaut: owl_settings)
    preferences_table: owl_user_preferences  # Nom de la table des préférences (défaut: owl_user_preferences)
    user_identifier_method: getUserIdentifier  # Méthode sur l'entité User (défaut: getUserIdentifier)
```

### Utilisation

[](#utilisation)

#### 1. Définir les paramètres globaux

[](#1-définir-les-paramètres-globaux)

Créez un service pour déclarer vos paramètres. Appelez-le au boot de l'application (par exemple via un EventSubscriber sur `kernel.request` ou dans un CompilerPass) :

```
use OwlConcept\SettingsBundle\Builder\SettingsBuilder;

class SettingsConfigurator
{
    public function __construct(private SettingsBuilder $builder) {}

    public function configure(): void
    {
        $this->builder->createGroup('general', 'Paramètres généraux')
            ->setDescription('Configuration principale de l\'application')
            ->setIcon('⚙️')
            ->add('app_name', 'Nom de l\'application', 'text', 'Mon CRM')
            ->add('default_language', 'Langue par défaut', 'select', 'fr', [
                'options' => ['fr' => 'Français', 'en' => 'English', 'es' => 'Español']
            ])
            ->add('items_per_page', 'Éléments par page', 'number', 25, [
                'min' => 5, 'max' => 100
            ])
            ->add('maintenance_mode', 'Mode maintenance', 'boolean', false, [
                'help' => 'Active la page de maintenance pour les visiteurs'
            ])
            ->build();

        $this->builder->createGroup('email', 'Configuration email')
            ->setIcon('📧')
            ->setRole('ROLE_ADMIN')
            ->add('from_name', 'Nom d\'expéditeur', 'text', 'Mon CRM')
            ->add('from_email', 'Email d\'expéditeur', 'email', 'noreply@moncrm.com')
            ->add('signature', 'Signature', 'textarea', '')
            ->build();

        $this->builder->createGroup('apparence', 'Apparence')
            ->setIcon('🎨')
            ->add('primary_color', 'Couleur principale', 'color', '#0d6efd')
            ->add('logo', 'Logo', 'file', null, ['accept' => 'image/*'])
            ->build();
    }
}
```

#### 2. Définir les préférences utilisateur

[](#2-définir-les-préférences-utilisateur)

```
$this->builder->createUserPreferences()
    ->add('theme', 'Thème', 'select', 'light', [
        'options' => ['light' => 'Clair', 'dark' => 'Sombre', 'auto' => 'Automatique (système)']
    ])
    ->add('language', 'Langue', 'select', null, [
        'options' => ['fr' => 'Français', 'en' => 'English'],
        'inherit_from' => 'general.default_language',
    ])
    ->add('items_per_page', 'Éléments par page', 'number', null, [
        'min' => 5, 'max' => 100,
        'inherit_from' => 'general.items_per_page',
    ])
    ->add('notifications_email', 'Notifications par email', 'boolean', true)
    ->add('sidebar_collapsed', 'Barre latérale réduite', 'boolean', false)
    ->build();
```

> Quand `inherit_from` est défini et que l'utilisateur n'a pas choisi de valeur, la préférence hérite automatiquement du paramètre global correspondant.

#### 3. Afficher les pages

[](#3-afficher-les-pages)

**Page admin — Paramètres globaux :**

```
{% extends 'admin/base.html.twig' %}

{% block body %}
    Paramètres
    {% include '@OwlSettings/admin.html.twig' %}
{% endblock %}
```

**Page profil — Préférences utilisateur :**

```
{% extends 'base.html.twig' %}

{% block body %}
    Mes préférences
    {% include '@OwlSettings/user_preferences.html.twig' %}
{% endblock %}
```

> Les formulaires sont auto-générés avec les bons types de champs, les valeurs actuelles pré-remplies, et la sauvegarde se fait en AJAX sans rechargement de page.

#### 4. Lire les valeurs dans le code

[](#4-lire-les-valeurs-dans-le-code)

```
use OwlConcept\SettingsBundle\Service\SettingsService;

class MyService
{
    public function __construct(private SettingsService $settings) {}

    public function doSomething(): void
    {
        // Paramètre global
        $appName = $this->settings->get('general.app_name');         // 'Mon CRM'
        $perPage = $this->settings->get('general.items_per_page');   // 25 (int)
        $maintenance = $this->settings->get('general.maintenance_mode'); // false (bool)

        // Préférence utilisateur (utilisateur connecté)
        $theme = $this->settings->getUserPreference('theme');        // 'dark'
        $lang = $this->settings->getUserPreference('language');      // 'fr' (hérité du global si non défini)

        // Préférence d'un utilisateur spécifique
        $theme = $this->settings->getUserPreference('theme', $otherUser);
    }
}
```

#### 5. Lire les valeurs en Twig

[](#5-lire-les-valeurs-en-twig)

```
{# Paramètre global #}
{{ owl_setting('general.app_name') }}

{# Préférence utilisateur #}

{# Conditionnel #}
{% if owl_setting('general.maintenance_mode') %}
    Site en maintenance
{% endif %}
```

#### 6. Modifier les valeurs dans le code

[](#6-modifier-les-valeurs-dans-le-code)

```
// Modifier un paramètre global
$this->settings->set('general.app_name', 'Nouveau nom');

// Modifier une préférence utilisateur
$this->settings->setUserPreference('theme', 'dark');

// Réinitialiser une préférence (retour à l'héritage/défaut)
$this->settings->resetUserPreference('language');
```

#### Options du GroupBuilder

[](#options-du-groupbuilder)

```
$this->builder->createGroup('security', 'Sécurité')
    ->setIcon('🔒')                              // Icône dans l'onglet
    ->setRole('ROLE_SUPER_ADMIN')                 // Restreindre l'accès
    ->setDescription('Paramètres de sécurité')    // Description sous le titre
    ->add(...)
    ->build();
```

### Types de champs

[](#types-de-champs)

TypeRendu HTMLOptions disponibles`text````placeholder`, `maxlength`, `required``email````placeholder`, `maxlength`, `required``number````min`, `max`, `step``boolean`Toggle switch (checkbox)—`select````options` : `['value' => 'Label', ...]``textarea````rows` (défaut: 4)`file``` avec preview image`accept` : `'image/*'``color```—`password````placeholder`, `maxlength`### Héritage des préférences

[](#héritage-des-préférences)

Le système d'héritage fonctionne en 3 niveaux :

```
1. Valeur définie par l'utilisateur    → priorité maximale
2. Paramètre global (inherit_from)     → si l'utilisateur n'a rien défini
3. Valeur par défaut (defaultValue)    → dernier recours

```

Exemple concret :

```
// Paramètre global
->add('items_per_page', '...', 'number', 25)    // défaut: 25

// Préférence utilisateur
->add('items_per_page', '...', 'number', null, [
    'inherit_from' => 'general.items_per_page',  // hérite du global
])
```

CasValeur retournée par `owl_user_pref('items_per_page')`L'utilisateur a choisi 50`50`L'utilisateur n'a rien choisi, admin a mis 30 en global`30` (hérité)L'utilisateur n'a rien choisi, global non modifié`25` (défaut)### Fonctions Twig

[](#fonctions-twig)

FonctionDescriptionExemple`owl_setting(key)`Lit un paramètre global`{{ owl_setting('general.app_name') }}``owl_user_pref(key)`Lit une préférence utilisateur`{{ owl_user_pref('theme') }}``owl_settings_groups()`Liste des groupes (pour templates custom)`{% for g in owl_settings_groups() %}``owl_settings_all()`Map de tous les paramètres globaux`{% set all = owl_settings_all() %}``owl_user_pref_definitions()`Définitions des préférences`{% for d in owl_user_pref_definitions() %}``owl_user_pref_all()`Map de toutes les préférences user`{% set prefs = owl_user_pref_all() %}`### Schéma de base de données

[](#schéma-de-base-de-données)

Le bundle crée 2 tables via la commande `owl:settings:install` :

**`owl_settings`** — Paramètres globaux

ColonneTypeDescription`setting_key`VARCHAR(255) PKClé qualifiée (ex: `general.app_name`)`setting_value`TEXTValeur sérialisée`setting_group`VARCHAR(100)Groupe (ex: `general`)`setting_type`VARCHAR(50)Type de champ`created_at`DATETIMEDate de création`updated_at`DATETIMEDernière modification**`owl_user_preferences`** — Préférences utilisateur

ColonneTypeDescription`user_id`VARCHAR(255) PKIdentifiant utilisateur`pref_key`VARCHAR(255) PKClé de préférence`pref_value`TEXTValeur sérialisée`created_at`DATETIMEDate de création`updated_at`DATETIMEDernière modification---

🇬🇧 English
----------

[](#-english)

### Features

[](#features)

- **Two-level settings** — global application settings (admin) + per-user preferences (profile)
- **Fluent builder pattern** — chainable API inspired by Symfony's FormBuilder
- **Setting groups** — organized as tabs in the admin interface
- **Inheritance** — a user preference can inherit from a global setting if not defined
- **9 field types** — text, email, number, boolean (toggle switch), select, textarea, file, color, password
- **DBAL storage** — no Doctrine ORM needed, works with DBAL alone
- **Symfony Cache** — settings are cached, automatically invalidated on change
- **Auto-generated UI** — ready-to-include Twig templates for admin and user profile pages
- **Built-in AJAX controller** — save routes included, zero config needed
- **Vanilla JavaScript** — tabs, AJAX submission, theme/file preview, auto-save
- **Default CSS** — BEM naming, toggle switch, responsive mobile
- **Twig functions** — `owl_setting()` and `owl_user_pref()` to read values anywhere

### Installation

[](#installation-1)

Add the repository and package to your `composer.json`:

```
{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/Jaecko/owl-settings-bundle"
        }
    ],
    "require": {
        "owl-concept/settings-bundle": "dev-main"
    }
}
```

Then run:

```
composer update
```

Register the bundle in `config/bundles.php`:

```
return [
    // ...
    OwlConcept\SettingsBundle\OwlSettingsBundle::class => ['all' => true],
];
```

Import the bundle routes in `config/routes/owl_settings.yaml`:

```
owl_settings:
    resource: '@OwlSettingsBundle/Resources/config/routes.yaml'
```

Install the assets (CSS &amp; JS):

```
php bin/console assets:install
```

Create the database tables:

```
# Preview the SQL
php bin/console owl:settings:install

# Execute
php bin/console owl:settings:install --force
```

Include the CSS and JS in your base template:

```

```

### Configuration

[](#configuration-1)

Optional configuration in `config/packages/owl_settings.yaml`:

```
owl_settings:
    css_class_prefix: owl-settings       # CSS prefix (default: owl-settings)
    cache_pool: cache.app                # Symfony cache pool (default: cache.app)
    cache_ttl: 3600                      # Cache duration in seconds (default: 3600)
    settings_table: owl_settings         # Settings table name (default: owl_settings)
    preferences_table: owl_user_preferences  # Preferences table name (default: owl_user_preferences)
    user_identifier_method: getUserIdentifier  # Method on User entity (default: getUserIdentifier)
```

### Usage

[](#usage)

#### 1. Define global settings

[](#1-define-global-settings)

Create a service to declare your settings. Call it at application boot (e.g., via an EventSubscriber on `kernel.request` or in a CompilerPass):

```
use OwlConcept\SettingsBundle\Builder\SettingsBuilder;

class SettingsConfigurator
{
    public function __construct(private SettingsBuilder $builder) {}

    public function configure(): void
    {
        $this->builder->createGroup('general', 'General Settings')
            ->setDescription('Main application configuration')
            ->setIcon('⚙️')
            ->add('app_name', 'Application Name', 'text', 'My CRM')
            ->add('default_language', 'Default Language', 'select', 'en', [
                'options' => ['en' => 'English', 'fr' => 'Français', 'es' => 'Español']
            ])
            ->add('items_per_page', 'Items per Page', 'number', 25, [
                'min' => 5, 'max' => 100
            ])
            ->add('maintenance_mode', 'Maintenance Mode', 'boolean', false, [
                'help' => 'Enables the maintenance page for visitors'
            ])
            ->build();

        $this->builder->createGroup('email', 'Email Configuration')
            ->setIcon('📧')
            ->setRole('ROLE_ADMIN')
            ->add('from_name', 'Sender Name', 'text', 'My CRM')
            ->add('from_email', 'Sender Email', 'email', 'noreply@mycrm.com')
            ->add('signature', 'Signature', 'textarea', '')
            ->build();

        $this->builder->createGroup('appearance', 'Appearance')
            ->setIcon('🎨')
            ->add('primary_color', 'Primary Color', 'color', '#0d6efd')
            ->add('logo', 'Logo', 'file', null, ['accept' => 'image/*'])
            ->build();
    }
}
```

#### 2. Define user preferences

[](#2-define-user-preferences)

```
$this->builder->createUserPreferences()
    ->add('theme', 'Theme', 'select', 'light', [
        'options' => ['light' => 'Light', 'dark' => 'Dark', 'auto' => 'Automatic (system)']
    ])
    ->add('language', 'Language', 'select', null, [
        'options' => ['en' => 'English', 'fr' => 'Français'],
        'inherit_from' => 'general.default_language',
    ])
    ->add('items_per_page', 'Items per Page', 'number', null, [
        'min' => 5, 'max' => 100,
        'inherit_from' => 'general.items_per_page',
    ])
    ->add('notifications_email', 'Email Notifications', 'boolean', true)
    ->add('sidebar_collapsed', 'Sidebar Collapsed', 'boolean', false)
    ->build();
```

> When `inherit_from` is set and the user hasn't chosen a value, the preference automatically inherits from the corresponding global setting.

#### 3. Display the pages

[](#3-display-the-pages)

**Admin page — Global settings:**

```
{% extends 'admin/base.html.twig' %}

{% block body %}
    Settings
    {% include '@OwlSettings/admin.html.twig' %}
{% endblock %}
```

**Profile page — User preferences:**

```
{% extends 'base.html.twig' %}

{% block body %}
    My Preferences
    {% include '@OwlSettings/user_preferences.html.twig' %}
{% endblock %}
```

> Forms are auto-generated with the correct field types, pre-filled with current values, and saving is done via AJAX without page reload.

#### 4. Read values in code

[](#4-read-values-in-code)

```
use OwlConcept\SettingsBundle\Service\SettingsService;

class MyService
{
    public function __construct(private SettingsService $settings) {}

    public function doSomething(): void
    {
        // Global setting
        $appName = $this->settings->get('general.app_name');         // 'My CRM'
        $perPage = $this->settings->get('general.items_per_page');   // 25 (int)
        $maintenance = $this->settings->get('general.maintenance_mode'); // false (bool)

        // User preference (current user)
        $theme = $this->settings->getUserPreference('theme');        // 'dark'
        $lang = $this->settings->getUserPreference('language');      // 'en' (inherited from global if not set)

        // Preference of a specific user
        $theme = $this->settings->getUserPreference('theme', $otherUser);
    }
}
```

#### 5. Read values in Twig

[](#5-read-values-in-twig)

```
{# Global setting #}
{{ owl_setting('general.app_name') }}

{# User preference #}

{# Conditional #}
{% if owl_setting('general.maintenance_mode') %}
    Site under maintenance
{% endif %}
```

#### 6. Modify values in code

[](#6-modify-values-in-code)

```
// Modify a global setting
$this->settings->set('general.app_name', 'New Name');

// Modify a user preference
$this->settings->setUserPreference('theme', 'dark');

// Reset a preference (back to inheritance/default)
$this->settings->resetUserPreference('language');
```

#### GroupBuilder options

[](#groupbuilder-options)

```
$this->builder->createGroup('security', 'Security')
    ->setIcon('🔒')                              // Icon in the tab
    ->setRole('ROLE_SUPER_ADMIN')                 // Restrict access
    ->setDescription('Security settings')         // Description under the title
    ->add(...)
    ->build();
```

### Field types

[](#field-types)

TypeHTML RenderAvailable Options`text````placeholder`, `maxlength`, `required``email````placeholder`, `maxlength`, `required``number````min`, `max`, `step``boolean`Toggle switch (checkbox)—`select````options`: `['value' => 'Label', ...]``textarea````rows` (default: 4)`file``` with image preview`accept`: `'image/*'``color```—`password````placeholder`, `maxlength`### Preference inheritance

[](#preference-inheritance)

The inheritance system works in 3 levels:

```
1. User-defined value               → highest priority
2. Global setting (inherit_from)    → if user hasn't set a value
3. Default value (defaultValue)     → last resort

```

Concrete example:

```
// Global setting
->add('items_per_page', '...', 'number', 25)    // default: 25

// User preference
->add('items_per_page', '...', 'number', null, [
    'inherit_from' => 'general.items_per_page',  // inherits from global
])
```

CaseValue returned by `owl_user_pref('items_per_page')`User chose 50`50`User hasn't chosen, admin set 30 globally`30` (inherited)User hasn't chosen, global not modified`25` (default)### Twig functions

[](#twig-functions)

FunctionDescriptionExample`owl_setting(key)`Read a global setting`{{ owl_setting('general.app_name') }}``owl_user_pref(key)`Read a user preference`{{ owl_user_pref('theme') }}``owl_settings_groups()`List of groups (for custom templates)`{% for g in owl_settings_groups() %}``owl_settings_all()`Map of all global settings`{% set all = owl_settings_all() %}``owl_user_pref_definitions()`Preference definitions`{% for d in owl_user_pref_definitions() %}``owl_user_pref_all()`Map of all user preferences`{% set prefs = owl_user_pref_all() %}`### Database schema

[](#database-schema)

The bundle creates 2 tables via the `owl:settings:install` command:

**`owl_settings`** — Global settings

ColumnTypeDescription`setting_key`VARCHAR(255) PKQualified key (e.g., `general.app_name`)`setting_value`TEXTSerialized value`setting_group`VARCHAR(100)Group (e.g., `general`)`setting_type`VARCHAR(50)Field type`created_at`DATETIMECreation date`updated_at`DATETIMELast modification**`owl_user_preferences`** — User preferences

ColumnTypeDescription`user_id`VARCHAR(255) PKUser identifier`pref_key`VARCHAR(255) PKPreference key`pref_value`TEXTSerialized value`created_at`DATETIMECreation date`updated_at`DATETIMELast modification---

License
-------

[](#license)

Proprietary — Owl Concept

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance53

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

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://www.gravatar.com/avatar/d9c48f4a438b587779711c9b1619fc238d635817cadc99091820d553700abcca?d=identicon)[Jaecko](/maintainers/Jaecko)

### Embed Badge

![Health badge](/badges/owl-concept-settings-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/owl-concept-settings-bundle/health.svg)](https://phpackages.com/packages/owl-concept-settings-bundle)
```

###  Alternatives

[otgs/multilingual-tools

Set of tools related to WPML plugin bundle. Created with tendency to ease WPML compatibility testing process.

39167.2k](/packages/otgs-multilingual-tools)[johndwells/craft.minimee

A Craft CMS port of the popular Minimee add-on for ExpressionEngine.

664.5k](/packages/johndwells-craftminimee)[leaphly/price

466.5k](/packages/leaphly-price)

PHPackages © 2026

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