Quick LinksCTRLS | DEVQuick StartThe StructureThe FactoryThe ModulesThe CompilerThe DefaultsThe CSSUsing WP-CLIDevelopment Mode

Note: This is only temporarily created documentation intended for Beta testers.


Controls (CTRLS|DEV) is a WordPress plugin & framework that helps developers to customize and extend any WordPress theme.

The Framework by itself gives you some additional structure, standards, and workflow to follow when working with the Wordpress Customize API.

The primary benefit is to give your theme numerous theme options and variations while writing less code in a structured way.

Quick Start

If you have WP-CLI installed and functional you can run either one of the following two commands inside your wp-content/plugins/ctrlsdev directory to create a start-up theme with the CTRLS Framework.

While the first command will create a child theme extending the Twenty Nineteen theme.

$ wp eval-file start.php twentynineteen -child

The second one will create a new theme.

$ wp eval-file start.php foobar

Inside your new theme folder, under the wp-content/themes, you will find the CTRLS|DEV Framework under ctrls, and all the basic files (index.php, function.php and style.css) required for your theme to be functional.

index.php <-- created only for new themes

You can also download the zipped start-up file and extract it inside wp-content/themes. This will give you a newly created foobar theme as shown above.

The Structure

Inside the wp-content/themes/theme_folder_name/ctrls you will find a couple of folders where you create your modules (with controls) and styles (using SASS).

  • scss/ -- store all your SASS or SCSS** files;
  • modules/ -- create and store all your controls; organize them by panel/section/type/target element, etc. under a module.
  • defaults.json -- store all default values for your controls.
  • load.php -- this is where you include all your modules and finally, you should include this file inside theme fucntions.php

*** Note: There is a standard structure you need to follow when you work with these files (more details in the section below).

*** Note: Keep the same section-slug name for both module & SCSS files, if they are linked (not required but a good practice).*

Framework Structure

An example structure for your ctrls framework.



], true);
// Alternative way where you load up and compile all modules and SCSS files.
$factory->mod('all', true);


include_once 'ctrls/load.php';

The Factory

The factory handles the addition of panels, sections and control types.

Panels and Sections

Creating and adding panels and sections is pretty straightforward. By using the add_pane() function you can add either a panel or a section.

Notice that by default the function will add a panel, if you want to add a section you need to pass false or 0 as a second argument and then if you want to attach this section to a specific panel use the panel attribute with the UUID for the panel.

'uuid' => 'grid',
'context' => ['title' => 'Grid', 'desc' => 'Theme panel for grid section.'],
'uuid' => 'box',
'panel' => 'grid',
'context' => ['title' => 'Box', 'desc' => 'Box section.'],
], false);


There are six custom control types.

Each control type and purpose is explained in more detail in the section below.

  • painter
  • selector
  • slider
  • switcher
  • toggler
  • manual

To create a new control you use the set() function and pass an array with your attributes.

$factory->{control_type}->set(array attributes);

Accepted attributes are:

  • section -- link to UUID for the section where you are going to add the control
  • target -- HTML element, it is best to be as specific as possible e.g. section.box instead of .box
  • uuid -- unique identifier or UUID for the control
  • context -- title (label) and description for our control (array)
    • title -- Optional title for your control
    • desc -- Optional description for your control
  • prop -- a valid CSS property you want to customize (naming is important use dashes as in CSS e.g background-color)
  • value -- used for the Selector, Switcher and Toggler controls (array)
  • input -- input attributes used for the Slider and Toggler controls (array)
  • units -- used for the Slider control (specify any valid CSS unit type, for example, px, em, rem, %, etc)
  • order -- this is generated automatically but you can overwrite it if you specify it (the start order priority value is 1000)

The example below will add a Slider control under the Homepage Settings section to manipulate the padding for the div.box element.

'section' => 'static_front_page',
'target' => 'div.box',
'uuid' => 'box_padding',
'context' => ['title' => 'Box padding', 'desc' => 'Modify your box padding.'],
'prop' => 'padding',
'input' => ['min' => 0, 'max' => 10, 'step' => 1],
'units' => 'rem',

In this second example we use the Switcher control where we may switch between classes with different CSS properties.

'section' => 'static_front_page',
'target' => 'div.container',
'uuid' => 'container_size_class',
'context' => ['title' => 'Box size', 'desc' => 'Modify your box size.'],
'values' => ['' => 'Auto (default)', 'container--lg' => 'Large', 'container--md' => 'Medium', 'container--sm' => 'Small'],

If you wonder how will you apply this control type mod on the front-end, here is an example:

<div class="container <?php echo get_theme_mod('container_size_class', false);?>">...</div>

Note: This is the generic way to do it, I will either create a function or figure a better approach.

Group Controls

Besides, there are group controls where you can create/specify more than 1 control of the same type with a single line of code.

Note: Currently only the Painter has a group control called paintergroup but I also plan to have Slider and Manual control groups.

The following will add 3 controls from the same type that will handle text, background and border color customization for our div.box.

'section' => 'static_front_page',
'target' => 'div.box',
'context' => ['title' => 'Box colors<hr />', 'desc' => 'Text, background & border color.'],
'group' => [
['uuid' => 'box_text_color', 'prop' => 'color'],
['uuid' => 'box_background_color', 'prop' => 'background-color'],
['uuid' => 'box_border_color', 'prop' => 'border-color']


Besides, you can specify globals for section and target.

These will be applied to all the controls that don't have them defined implicitly.

In the example below all the controls that don't have a section or target will be added to the section box and applied to the HTML element article.box.

use CTRLS\Factory as Factory;
Factory::$section = 'box';
Factory::$target = 'article.box';
'section' => 'static_front_page',
'target' => 'body',
'uuid' => 'body_padding',
'context' => ['title' => 'Body padding', 'desc' => 'Modify your body padding.'],
'prop' => 'padding',
'input' => ['min' => 0, 'max' => 10, 'step' => 1],
'units' => 'rem',
'uuid' => 'box_text_color',
'context' => ['title' => 'Box text color', 'desc' => 'Modify your boxes text color.'],
'prop' => 'color',
'uuid' => 'box_background_color',
'context' => ['title' => 'Box background color', 'desc' => 'Modify your boxes background color.'],
'prop' => 'background-color',

Painter Control

Use when you want to manipulate the color scheme of your theme.

For example, properties text-color, background-color, border-color, etc.

Selector Control

Use when you have more than 2 choices for a CSS property.

For example, property text-align has values left, right, center, and justify.

Slider Control

Used when you want to manipulate CSS properties with integers and units.

For example, width, height, padding, etc.

Switcher Control

Use when you want to switch between 2 states of property.

For example, target the element visibility, use attribute display and properties block or none.

Toggler Control

Used when you want to manipulate target element classes.

For example, have a box grid with a couple of different layouts; grid--one-col, grid--two-col or grid--three-col.

Manual Control

Used for adding and applying manual CSS style. (development mode)

For example, border: 1px solid rgba(0, 0, 0, .3);

The Modules

Breaking your theme customization options into modules is another way to add a structure, standards and improve your project workflow.

All the modules must be created inside the theme_folder_name/ctrls/modules directory with extension .mod.php.

And then included, loaded and compiled within the theme_folder_name/ctrls/load.php file.

Every theme that uses our Framework must have a top-level ctrls folder (as described in The Structure section).

The example below is for the theme_folder_name/ctrls/load.php file.

We load up the controls and then execute the module using the mod function y passing only the name of without the .mod.php extension.


Note: The second line compiles the SCSS associated with our module (this is explained in more detail in the next section).

Shortcut for the above code where we load and compile the module with a single command.

$factory->mod('box', true);

Also, you can load up and compile multiple modules. To do this just pass them as an array as shown below.


And again a shortcut to the code above would be:

$factory->mod(['grid','box'], true);

The Compiler

As I already mentioned the plugin comes up with a built-in SASS library SCSSPHP, which gives you a whole lot more power over your styling and customization within WordPress and specifically linked to the Customize API.

This way you can create and update your main CSS stylesheet on the fly.

Once you click the Publish button the CSS will be regenerated and all-new customization will be applied.

  1. Make your Customizer modification;
  2. Publish;
  3. Rebuild CSS and see the change on the front-end;


When you add/create your SCSS within a PHP file there is a certain approach but nothing out of the ordinary if you follow the process.

There are 2 rules to keep in mind:

  1. Use the following code to encapsulate your SCSS $scss = <<<EOD .... EOD
    • closing EOD; must be on a new line, otherwise, you will get an error.
  2. Use {$mod[uuid]} format to link your controls values and to visualize your change on the front-end.
    • where uuid is the unique ID you have used to build your control

Anything else is a fair play you can use @mixins, @functions, @if ... @else structures, lightness and darkness functions, etc.

$scss = <<<EOD
body {
padding: {$mod['body_padding']};
margin: 0 auto;
background-color: {$mod['body_background_color']};
display: {$mod['body_visibility']};
border: {$mod['body_border']};
text-align: {$mod['body_text_align']};
&.body--lg {
width: 1200px;
&.body--md {
width: 992px;
&.body--sm {
width: 768px;
.container {
max-width: 1200px;
margin: 0 auto;

Compile SCSS

As you remember from the previous section after you load up your control module you need to link it up with an SCSS.

The SCSS structure is pretty much the same as modules, but all SCSS files must be placed under theme_folder_name/ctrls/scss wtih extension .scss.php

Just as a reference I will add the different ways to load and compile your controls with SCSS.

$factory->mod('box', true); // shortcut to the above 2 lines
$factory->mod(['grid','box'], true); // shortcut to the above 2 lines

Lastly, it is important to know that if you don't specify a SCSS file or maybe the SCSS doesn't have an associated module and you forget, it won't be loaded at all.

For example, you have all your SASS global vars inside a variables.scss.php and you want to load up normalize.scss.php. In these two cases, you don't need to have a module.

To load up all the SCSS files you must pass the all keyword.

The example below will load up all .mod.scss under your theme_folder_name/ctrls/scss folder including files without associated modules.


Sample file structure:


The Defaults

Lastly, we need to discuss how we handle default values for our controls.

All defaults are stored as JSON files inside theme_folder_name/ctrls/defaults.json.

Here is how a sample JSON default file would look like; the format you should use is "UUID": "default_value"; where UUDI is the unique ID you have used to create your control.

"body_background_color": "#eeeeee",
"body_visibility": "block",
"body_text_align": "left",
"body_border": "1px solid transparent",
"body_container_size_class": "",
"body_padding": "0",
"grid_link_text_color": "#ff44cc",
"grid_text_color": "#333333",
"box_text_color": "#000000",
"box_background_color": "#ffffff",
"box_border_color": "#ffffff"


The generated CSS file is found under wp-content/uploads and is loaded just before the closing </head> tag.

This will assure you can overwrite any existing CSS rules if you try to extend and customize an existing theme.

Note: Set permissions for the uploads to 0755. This shouldn't be an issue for most setups.

Most of the time some magic CSS is required when working with an existing theme and there are cases where you need to use !imporant to overwrite some rules.

Sidenote: I love themes that come up with SCSS files (e.g. Twenty Nineteen), then you can create a child theme by using the existing SCSS files and avoid a lot of headaches.

Using WP-CLI

Another cool feature mentioned in the Quick Start is that you can use the WP-CLI with start.php to generate a skeleton for your theme including the CTRLS framework (of course you must have WP-CLI installed and functional).

For an existing theme, you can run the following command inside the wp-content/plugins/ctrlsdev, which create a child theme with all the basic files included.

$ wp eval-file start.php twentynineteen -child

And here is what will be generated for you.

All the files have some default content that can guide you and give you a head start to understand the framework.

| You are all set. |
| Your base theme including CTRLS framework structure was created successfully. |
[dir] ctrls
|-- [dir] scss
| |-- start.scss.php <-- add your SCSS stylesheets here
|-- [dir] modules
| |-- start.mod.php <-- add you customizer modules with controls here
|-- defaults.json
|-- load.php <-- load and compile your modules here

If you want to apply the same for a new theme all you need do is the same command without -child.

$ wp eval-file start.php foobar

Note: Currently there is no way to remove a created framework/theme; you need to remove all files and folders manually then run the command again to start fresh.

Development Mode

You can use the reset() function inside your functions.php which will delete your current theme mods and also delete the generated .css file form the wp-content/uploads.


Besides, by defining the ENV as prod inside your functions.php file your generated CSS will be compressed and minified. (by default this variable is set to 'dev').

define('ENV', 'prod');