Thesis Options API Array Format

The heart of the Thesis Options API is a simple PHP array format that Thesis can use to output forms and create options.

An Options API array is basically just a list of options, and you can think of each option in terms of its associated <form> element:

  • text inputs <input type="text" />
  • textareas <textarea>
  • checkboxes <input type="checkbox" />
  • radio buttons <input type="radio" />
  • dropdown select menus <select>

The Options API also supports specialized inputs like color pickers, WordPress media gallery selections, and even custom inputs that you define.

In addition, the Options API supports more complex constructions like option groups, option objects, and object sets.

Introduction: Sample Thesis Options API Arrays

Here’s a sample Thesis Options API array for a text input:

array(
	'option_id' => array(
		'type' => 'text',
		'label' => __('Option Label', 'my_namespace'),
		'tooltip' => __('Option tooltip', 'my_namespace')));

In the above code, option_id represents the name of this particular option. This name appears both in the <form> where options are collected and also in your code, when you need to reference the value of an option.

When you build a Thesis extension (be it a Box, Skin, or something else), be sure to give each option a unique option_id.

Next, we have the type parameter, which determines the type of field that will appear in the options <form>. In this case, the option is a text <input>.

In most cases, you’ll want to use the label parameter to provide a label for your option in the output <form>. Also, be sure to include the label value within a translation function as shown above, along with your specific namespace. This will enable your Thesis add-on to be translated into any language under the sun.

Finally, we have the tooltip parameter. If your option requires additional instructions or explanation, providing a tooltip is a great way to convey this information to the user. As with the label above, be sure to place your tooltip within a translation function.

Now let’s look at a sample Thesis Options API array for a checkbox input:

array(
	'another_id' => array(
		'type' => 'checkbox',
		'label' => __('Three Checkbox Options', 'my_namespace'),
		'options' => array(
			'one' => __('Label for option 1', 'my_namespace'),
			'two' => __('Label for option 2', 'my_namespace'),
			'three' => __('Label for option 3', 'my_namespace')),
		'default' => array(
			'two' => true)));

In the code above, the sample option has a name of another_id.

Next, you’ll notice that the type parameter has a value of checkbox, making this option a checkbox within your options form.

Unlike the text option in the first example, the checkbox option requires an array of options to represent each of your checkboxes. The sample checkbox option above actually contains 3 checkboxes, and each checkbox is represented by a ('name' => __('checkbox label text', 'my_namespace')) key-value pair.

Sometimes, you may want your checkboxes to be checked by default, and you can achieve this by providing a default array. In this example, checkbox two has been set to true and will be checked by default.

Now that you’ve seen how Thesis Options API arrays work, let’s look at the basic option types and the various parameters available to each.

Text Inputs

When you need to gather text data from the user, a text <input> is your option of choice (unless you need to collect a lot of text, in which case a <textarea> is more appropriate). The Thesis Options API supports the following parameters and associated values for text inputs:

  • type — text
  • width — tiny (50px), short (120px), medium (200px), long (400px), or full (100%)
  • code — set to true if the user should input code
  • label — translation function
  • tooltip — translation function
  • default — default value for this text box
  • counter — translation function
  • description — translation function
  • placeholder — string or translation function, depending on expected input

Only the type parameter is required for a valid text input, but we strongly recommend you include a label and, if necessary, a tooltip to explain your option.

The counter and description fields are directionally exclusive—the presence of a counter will preclude the presence of a description. Both parameters accept translation functions as their values, and you can treat both of these like input descriptions or prompts for the user.

Also, the placeholder parameter represents an HTML5 placeholder attribute, which can be helpful as a prompt for the user.

Translation functions: Some option explanations reference the use of a translation function. Whenever you include a string, you should wrap it in a translation function like this:

__('My Text', 'my_namespace')

Textareas

If you need to gather a long string of text from the user, then you’ll want to use a <textarea> instead of a standard text <input>.

  • type — textarea
  • rows — integer value for the number of visible rows in the textarea
  • code — set to true if the user should input code
  • label — translation function
  • tooltip — translation function
  • default — default value for this textarea
  • counter — translation function
  • description — translation function

Once again, only the type parameter is required for a valid <textarea>, but you’ll probably want to include a label and tooltip, too.

Use the rows parameter to determine the number of rows of text the <textarea> displays. For example, if you know you need approximately two lines of input from the user, then you’d want to set your rows to 2.

Checkboxes

For options that can only exist in an on/off state, checkboxes are a perfect choice for simplicity and reliability.

  • type — checkbox
  • label — label above this group of checkboxes (translation function)
  • tooltip — translation function, requires a label
  • options — array of options with 'name' => __('checkbox label text', 'my_namespace') pairs
  • default — array of checkbox option defaults, set 'name' => true for any options that should be set to true

Both the type and options parameters are required for a valid checkbox <input>.

If your boxes should be un-checked by default, you should omit the default parameter entirely.

Note: Checkbox options and default parameters should be given as array values.

Referencing Checkbox Option Values in Your Code

Unlike most option values, which are stored in basic scalar format, checkbox values are stored in an array.

Because of this, you must use a slightly different syntax when referencing checkbox options. For example, if your checkbox option looks like this:

'eggs' => array(
	'type' => 'checkbox',
	'label' => __('How do you like your eggs?', 'my_namespace'),
	'options' => array(
		'easy' => __('over easy', 'my_namespace'),
		'sunny' => __('sunny side up', 'my_namespace'),
		'poached' => __('poached', 'my_namespace')));

…then your option value references will look something like this:

if (!empty($options['eggs']['easy']))
	echo "You like your eggs over easy.";
if (!empty($options['eggs']['sunny']))
	echo "You like your eggs sunny side up.";
if (!empty($options['eggs']['poached']))
	echo "You like your eggs poached.";

Here, the eggs checkbox structure actually consists of 3 checkboxes: easy, sunny, and poached.

Because of this hierarchical organization, checkbox options require array references instead of scalar ones.

Radio Buttons

When the user must select a single value from a small list of options (5 or less), you should use a radio button. For selections from larger groups of options, consider using a <select> element instead.

  • type — radio
  • label — label above radio options (translation function)
  • tooltip — translation function, requires a label
  • options — array of options with 'value' => __('radio button text', 'my_namespace') pairs
  • default — default value from the options list

Both the type and options parameters are required for a valid radio button <input>.

In all likelihood, you’ll probably also want to include label and tooltip parameters to further refine your radio button.

Note: The options parameter for a radio button is an array, but the default parameter is just a single value.

Select Elements

If the user needs to make a selection from a large list of options, you should employ a <select> element to simplify their experience. Here’s how it’s done with the Thesis Options API:

  • type — select
  • label — translation function
  • tooltip — translation function
  • options — array of options with 'value' => __('select option text', 'my_namespace') pairs
  • default — default value from the options list

A valid <select> element only requires type and options parameters, but just like the radio button, you’ll probably also want to include a label and tooltip to indicate what is being selected.

Note: The options parameter for a <select> element is an array, but the default parameter is just a single value.

Multiple select? At this time, multiple <select> elements are not supported.

Option Dependencies

To simplify your forms, sometimes you might want to show or hide an element depending on the value of a different input.

To accommodate this scenario, the Thesis Options API contains a simple parent-child dependency system that you can add to any checkbox, radio button, or <select> element.

In the following example, a checkbox determines the display of an associated text input. If the box is checked, then the text input will show. If the box is un-checked, then the text input will be hidden.

array(
	'parent_checkbox' => array(
		'type' => 'checkbox',
		'label' => __('Text Input Controller', 'my_namespace'),
		'options' => array(
			'on' => __('Show the text input', 'my_namespace')),
		'dependents' => array('on')),
	'child_text' => array(
		'type' => 'text',
		'label' => __('Dependent Text Input', 'my_namespace'),
		'parent' => array(
			'parent_checkbox' => 'on')));

To make an option a parent, you must declare which of its options have dependents. In the example above, the parent_checkbox has declared that its on option has dependents.

To make an option a child, or dependent, of another option, you must declare its parent(s). This is done through a parent array, as shown in the child_text option above.

Here, the parent is the on option from parent_checkbox.

Required Options

Some applications may not work without specific data from the user, and in cases like this, it’s nice to be able to mark certain form fields as required.

Accomplishing this with the Thesis Options API is simple, as you only need to add the req parameter to any option, like so:

array(
	'option_id' => array(
		'type' => 'text',
		'label' => __('Option Label', 'my_namespace'),
		'req' => '*',
		'tooltip' => __('Option tooltip', 'my_namespace')));

Notice that the req parameter has a value—* in this example. The value you specify here will appear alongside your option label to indicate that this field is required.

As a convention, Thesis uses an asterisk to mark a required field, but you can use any character you like instead. You can even use a string, but don’t forget to serve it inside a translation function.

Note: You cannot mark a field as required unless you also supply a label.

Option Groups

In some cases, you may wish to group certain options together to organize an interface or make distinctions between sets of options.

This is where option groups come in handy. Check out the following example, which contains two groups of options:

array(
	'group1_id' => array(
		'type' => 'group',
		'label' => __('Group 1', 'my_namespace'),
		'fields' => array(
			'option1_id' => array(
				'type' => 'text',
				'label' => __('Group 1, Option 1', 'my_namespace')),
			'option2_id' => array(
				'type' => 'checkbox',
				'options' => array(
					'yes' => __('Vote Yes on group 1, option 2', 'my_namespace'))))),
	'group2_id' => array(
		'type' => 'group',
		'label' => __('Group 2', 'my_namespace'),
		'fields' => array(
			'option3_id' => array(
				'type' => 'text',
				'label' => __('Group 2, Option 1', 'my_namespace')),
			'option4_id' => array(
				'type' => 'checkbox',
				'options' => array(
					'yes' => __('Vote Yes on group 2, option 2', 'my_namespace'))))));

Grouping options in this manner can be handy for organizing an interface without adding complexity to your option references. Grouped options are still referenced in the same manner as other options, so they are intuitive to work with.

For example, if you’d like to know the value of Group 2, Option 1 (option1_id) from above, you’d use a reference similar to this in your code:

$options['option1_id'];

Ultimately, option groups are a basic, classical way of organizing options within an interface, but they aren’t the only way to achieve better interface organization.

For that, you need option objects, which we’ll look at now.

Option Objects

Similar to option groups, option objects are structures consisting of individual options that are related in some way.

Their purpose is not only to refine and organize an interface, but also to organize options data itself in a meaningful way.

To function properly, an object must have the following 3 parameters:

  • type — object
  • label — translation function
  • fields — array of options in Options API array format

Let’s look at some sample code for an option object, and we’ll see how objects differ from option groups:

array(
	'coffee' => array(
		'type' => 'object',
		'label' => __('My Coffee', 'my_namespace'),
		'fields' => array(
			'beans' => array(
				'type' => 'text',
				'label' => __('Preferred Coffee Beans', 'my_namespace')),
			'condiments' => array(
				'type' => 'checkbox',
				'label' => __('Cream and/or Sugar?', 'my_namespace'),
				'options' => array(
					'cream' => __('cream', 'my_namespace'),
					'sugar' => __('sugar', 'my_namespace'))))));

Though the object syntax is similar to the group syntax, there are two important differences.

First, all option objects store their data in an array. Given the example shown above, you’d use code similar to the following to reference your object option values:

$option['coffee']['beans'];
$option['coffee']['condiments']['cream'];
$option['coffee']['condiments']['sugar'];

Note: Options contained in the fields parameter of an object cannot be referenced directly—they must be referenced through the containing object, as shown above.

Second, options grouped together in an object will always be presented together in the Thesis interface. At this time, there is only one supported way to include option objects in your code, and that’s via the use of an object set, which we’ll look at now.

Adding Objects to the Thesis Interface with Object Sets

Option objects are designed to dramatically reduce the on-screen real estate needed to present options that are related in some way.

When presented by themselves in an interface, option objects aren’t particularly useful because context is usually necessary to understand what certain options do.

To address this issue of context, the Thesis Options API contains object sets. Object sets are groups of objects tied together into a single, robust interface.

Here are the option parameters for an object set:

  • type — object_set
  • label — (optional) translation function, label above <select> element
  • select — (optional) translation function, <select> element default text
  • objects — array of option objects

And here is some sample code for an object set:

array(
	'beverages' => array(
		'type' => 'object_set',
		'label' => __('Drink Preferences', 'my_namespace'),
		'select' => __('Select your beverage type:', 'my_namespace'),
		'objects' => array(
			'coffee' => array(
				'type' => 'object',
				'label' => __('Coffee', 'my_namespace'),
				'fields' => array(
					'beans' => array(
						'type' => 'text',
						'label' => __('Preferred Coffee Beans', 'my_namespace')),
					'condiments' => array(
						'type' => 'checkbox',
						'label' => __('Cream and/or Sugar?', 'my_namespace'),
						'options' => array(
							'cream' => __('cream', 'my_namespace'),
							'sugar' => __('sugar', 'my_namespace'))))),
			'tea' => array(
				'type' => 'object',
				'label' => __('Tea', 'my_namespace'),
				'fields' => array(
					'leaves' => array(
						'type' => 'text',
						'label' => __('Preferred Tea Leaves', 'my_namespace')),
					'condiments' => array(
						'type' => 'checkbox',
						'label' => __('Milk and/or Honey?', 'my_namespace'),
						'options' => array(
							'milk' => __('milk', 'my_namespace'),
							'honey' => __('honey', 'my_namespace')))))));

To see how this structure is advantageous, let’s look at the Classic Responsive Skin design options, which include an object set interface to handle things like layout, fonts, sizes, and colors:

Thesis object set interface

First, object sets are concise—active objects (those with currently-set values) appear as buttons, and inactive objects appear within a <select> element.

Second, object sets are smart—they know which objects are active (currently contain values) and which are inactive (no values currently set). This provides for some pretty cool interface behaviors, like showing which options are set within a particular object:

Thesis object option preview

Third, each object in an object set is isolated from the rest of the interface. This reduces visual noise, makes relationships between options clearer, and improves the overall feedback for the user:

Thesis option object popup

In summary, object sets are a new way to present deep customization options to users without overwhelming them with too many options at any given time.

Options Module Syntax

Certain options structures in Thesis require a module wrapper around a typical options array. Two examples of this are Box post meta and Box template options, both of which have interfaces that lend themselves to the module syntax.

For example, in the edit post interface, post meta modules look like this:

WordPress post meta box

And here’s what a template options module looks like in the Thesis template editor:

Thesis template options

In cases like these where the options module syntax applies, you must specify both a module title and a list of options that appear inside the module. Here’s what that looks like:

array(
	'title' => __('Your Module Title', 'your_namespace'),
	'fields' => array()); /* normal options array */

In addition to the title and fields parameters shown above, some options structures may allow for other parameters in the options module.

For example, template options accommodate an exclude parameter that you can use to prevent options from appearing on certain templates. The WP Loop Box uses this parameter to prevent the “Number of Posts Per Page” option from appearing on Single and Page templates (and their descendants).