PHPackages                             jeffreyvanrossum/wp-settings - 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. jeffreyvanrossum/wp-settings

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

jeffreyvanrossum/wp-settings
============================

Handy wrapper to make creating WordPress settings pages a breeze.

1.2.2(2y ago)902.8k↓87.8%81MITPHPPHP ^7.4|^8.0

Since Aug 13Pushed 2y ago5 watchersCompare

[ Source](https://github.com/jeffreyvr/wp-settings)[ Packagist](https://packagist.org/packages/jeffreyvanrossum/wp-settings)[ Fund](https://vanrossum.dev/donate)[ GitHub Sponsors](https://github.com/jeffreyvr)[ RSS](/packages/jeffreyvanrossum-wp-settings/feed)WikiDiscussions master Synced yesterday

READMEChangelog (8)Dependencies (4)Versions (9)Used By (1)

[![vanrossum.dev Logo](https://raw.githubusercontent.com/jeffreyvr/vanrossum.dev-art/main/logo.svg)](https://vanrossum.dev)

[![Total Downloads](https://camo.githubusercontent.com/b97ca4ddb438727f6e9ddfa4b8cad0a6f03d0467480faff8025e12b38a7504a7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6a65666672657976616e726f7373756d2f77702d73657474696e6773)](https://packagist.org/packages/jeffreyvanrossum/wp-settings)[![Latest Stable Version](https://camo.githubusercontent.com/0e9c72f743cc6f35c8ef29769bb85f2b0b1ca1118aab5fccc37383f8e66fab94/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a65666672657976616e726f7373756d2f77702d73657474696e6773)](https://packagist.org/packages/jeffreyvanrossum/wp-settings)[![License](https://camo.githubusercontent.com/d61708a0bac5a6a0c38da7ee1c102b1aba8978eba14a89af453b153d2e2b256c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6a65666672657976616e726f7373756d2f77702d73657474696e6773)](https://packagist.org/packages/jeffreyvanrossum/wp-settings)

WP Settings
===========

[](#wp-settings)

This package aims to make it easier to create settings pages for WordPress plugins. Typically, you would use the [Settings API](https://developer.wordpress.org/plugins/settings/settings-api/) or write something custom. While the Settings API works, there is still quite a lot to set up. You still need to write the HTML for your options for example. And it gets quite complicated if you want to add tabs and tab-sections. See this [comparison](https://www.youtube.com/watch?v=WoBRuLgacDo).

[![Code Snippet](/art/snippet.png)](/art/snippet.png)

Installation
------------

[](#installation)

```
composer require jeffreyvanrossum/wp-settings
```

Usage
-----

[](#usage)

### Basic example

[](#basic-example)

```
use Jeffreyvr\WPSettings\WPSettings;

$settings = new WPSettings(__('My Plugin Settings'));

$tab = $settings->add_tab(__( 'General', 'textdomain'));

$section = $tab->add_section('MailChimp');

$section->add_option('text', [
    'name' => 'mailchimp_api_key',
    'label' => __('API Key', 'textdomain')
]);

$settings->make();
```

### Creating the settings instance

[](#creating-the-settings-instance)

```
$settings = new WPSettings(__('My Plugin Settings'));
```

By default, the page slug is created by sanitizing the title. You may pass a specific slug as the second parameter of the constructor.

Other methods for this class:

```
$settings->set_capability('manage_options');
$settings->set_option_name('my_plugin_options');
$settings->set_menu_icon('dashicons-admin-generic');
$settings->set_menu_position(5);
$settings->set_menu_parent_slug('options-general.php');
```

### Tabs

[](#tabs)

Tabs are only displayed when there is more then one.

```
$settings->add_tab(__( 'General', 'textdomain'));
```

### Sections

[](#sections)

You can call the `add_section` method from an instance of `Tab`. You can also call it from the `WPSettings` instance. It will then be added to the last created `Tab`.

```
$tab->add_section('Section 1');
```

If you want sections to be displayed as submenu-items, you can do:

```
$tab->add_section('Section 1', ['as_link' => true]);
```

Note that this only has an effect when you have more then one `as_link` section.

### Options

[](#options)

To add an option, you either call the `add_option` method from an instance of `Section`. You may also call `add_option` from the `WPSettings` instance. The option will then be added to the last created section.

#### Text

[](#text)

```
$section->add_option('text', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
]);
```

In addition to `name` and `label`, you can also pass `type`. This makes it possible to set the input type to, for example, password or number.

#### Textarea

[](#textarea)

```
$section->add_option('textarea', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain'),
]);
```

You may also set the `cols` and `rows` attributes.

#### Checkbox

[](#checkbox)

```
$section->add_option('checkbox', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
]);
```

#### Select

[](#select)

```
$section->add_option('select', [
    'name' => 'option_1',
    'label' => __( 'Option 1', 'textdomain' ),
    'options' => [
        'value_1' => 'Label 1',
        'value_2' => 'Label 2'
    ]
]);
```

#### Select Multiple

[](#select-multiple)

```
$section->add_option('select-multiple', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain'),
    'options' => [
        'value_1' => 'Label 1',
        'value_2' => 'Label 2'
    ]
] );
```

#### WP Editor

[](#wp-editor)

```
$section->add_option('wp-editor', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
] );
```

#### Code Editor

[](#code-editor)

```
$section->add_option('code-editor', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
] );
```

#### Color

[](#color)

```
$section->add_option('color', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
] );
```

#### Media

[](#media)

```
$section->add_option('media', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
] );
```

For an image specific, you can use:

```
$section->add_option('image', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
] );
```

For video specific, you can use:

```
$section->add_option('video', [
    'name' => 'option_1',
    'label' => __('Option 1', 'textdomain')
] );
```

### Validation

[](#validation)

You are able to validate an option. You may pass a callback and a feedback message. You can pass multiple validation rules.

```
$section->add_option('text', [
    'name' => 'mailchimp_api_key',
    'label' => __('API Key', 'textdomain'),
    'validate' => [
        [
            'feedback' => __('Your API key is too short.', 'textdomain'),
            'callback' => function($value) {
                return strlen($value) > 35;
            }
        ]
    ]
]);
```

### Sanitization

[](#sanitization)

You may pass a sanitization callback.

```
$section->add_option('text', [
    'name' => 'mailchimp_api_key',
    'label' => __('API Key', 'textdomain'),
    'santitize' => function($value) {
        return sanitize_key($value);
    }
]);
```

### Options array structure

[](#options-array-structure)

By default, the options are stored as a one level array:

```
[
    'option_1' => 'value 1',
    'option_2' => 'value 2',
]

```

However, you can add tab and/or section levels in this structure.

```
$tab = $settings->add_tab(__( 'General', 'textdomain'))
    ->option_level();

$section = $tab->add_section('Example', ['as_link' => true])
    ->option_level();
```

Which would result in:

```
[
    'general' => [
        'example' => [
            'option_1' => 'value 1',
            'option_2' => 'value 2',
        ]
    ]
]

```

### Adding a custom option type

[](#adding-a-custom-option-type)

To add an custom option type, you can use the `wp_settings_option_type_map` filter.

```
add_filter('wp_settings_option_type_map', function($options){
    $options['custom'] = YourCustomOption::class;
    return $options;
});
```

You will need to create a class for your custom option type.

```
use Jeffreyvr\WPSettings\Options\OptionAbstract;

class YourCustomOption extends OptionAbstract
{
    public $view = 'custom-option';

    public function render()
    {
        echo 'Your custom option HTML';
    }
}
```

Once registered, you can then use your option type like so:

```
$settings->add_option('custom-option', [
    'name' => 'your_option_name',
    'label' => __('Your label')
]);
```

Contributors
------------

[](#contributors)

- [Jeffrey van Rossum](https://github.com/jeffreyvr)
- [All contributors](https://github.com/jeffreyvr/wp-settings/graphs/contributors)

License
-------

[](#license)

MIT. Please see the [License File](/LICENSE) for more information.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity35

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 95.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 ~114 days

Recently: every ~66 days

Total

8

Last Release

987d ago

PHP version history (2 changes)1.0.0PHP ^7.2|^8.0

1.1.0PHP ^7.4|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/66ca71465f93459010e10f39821b541f1c00c61233c48bcda0cea8a8d6fb6988?d=identicon)[jeffreyvr](/maintainers/jeffreyvr)

---

Top Contributors

[![jeffreyvr](https://avatars.githubusercontent.com/u/9550079?v=4)](https://github.com/jeffreyvr "jeffreyvr (60 commits)")[![alessandroalessio](https://avatars.githubusercontent.com/u/2146326?v=4)](https://github.com/alessandroalessio "alessandroalessio (1 commits)")[![MahdiAkrami01](https://avatars.githubusercontent.com/u/54323929?v=4)](https://github.com/MahdiAkrami01 "MahdiAkrami01 (1 commits)")[![qriouslad](https://avatars.githubusercontent.com/u/4230816?v=4)](https://github.com/qriouslad "qriouslad (1 commits)")

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/jeffreyvanrossum-wp-settings/health.svg)

```
[![Health](https://phpackages.com/badges/jeffreyvanrossum-wp-settings/health.svg)](https://phpackages.com/packages/jeffreyvanrossum-wp-settings)
```

###  Alternatives

[cognesy/instructor-php

The complete AI toolkit for PHP: unified LLM API, structured outputs, agents, and coding agent control

318123.0k1](/packages/cognesy-instructor-php)[crwlr/crawler

Web crawling and scraping library.

36917.4k2](/packages/crwlr-crawler)[lingaro/magento2-codegen

Magento 2 Code Generator

966.5k](/packages/lingaro-magento2-codegen)[dotink/jin

Jsonified Ini Notation

1410.6k3](/packages/dotink-jin)

PHPackages © 2026

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