This documentation is for AppPresser 2 only. For AppPresser 3 docs, click here.

Adding AppPresser Settings

In this tutorial, we are going to walk through how to add settings to the AppPresser settings page from the comfort of your child theme.

In order to achieve this, you will want to create and save a file named appp-settings.php in your root child theme folder. All of the code in the rest of the tutorial will go inside of it, and we'll provide a complete example at the end.

You will need to create this exact file, appp-settings.php, if you want the options to be visible even when your AppPresser theme is not the currently active theme, but is the selected theme to display for mobile/app/admin users.

Hooking into the apppresser_add_settings hook & our first tab

To start out, we will add our WordPress hook and callback function. The apppresser_add_settings hook allows us to add our custom setting values to the AppPresser settings page, as well as create new tabs for your settings if you want to keep that separated. For the sake of this tutorial, we are going to use a "New Tab" tab. You can see what we have, so far, below.

<?php
add_action( 'apppresser_add_settings', 'appp_add_sample_settings' );
function appp_add_sample_settings( $apppresser ) {
    // Create a new tab for our settings
    $apppresser->add_setting_tab( __( 'New Tab', 'apppresser' ), 'new-tab-slug' );
}

With the add_setting_tab method, you will pass in two different parameters. The first one is for the text to be shown in the tab, that a user will click on. The second one is the tab's slug. This will be a parameter you use later on to add settings to the "New Tab" page area. We suggest that a new tab only be created for extensions that have several options to include. In most cases, separating your content with add_setting_label is sufficient.

Details on the $appppresser->add_setting() method

With all examples provided that use $apppresser->add_setting(), they will take take three parameters.

The first parameter is going to be the string text you use for the settings field in the database. You will want to make sure it is a unique string so that it's not overwritten by some other piece of code.

The second parameter is the label text you want for the input. This will help your users know what the associated input is for.

Lastly, the method accepts an array of key/value pairs. They do not have to be provided in any specific order inside the array, but will need to be set to be used. The available parameters and values are as follows:

  1. 'type', default: 'text'

    Displays a text input type if you don't provide a different input type. * Accepted non-default input types: checkbox, select, radio, license_key, h3

    Note. Providing "h3" for the type simply creates a heading separator. A more suitable method, add_setting_label, exists for this purpose.

  2. 'helptext', default: ''

    Displays a jQuery UI tooltip underneath an anchor tag ( <a>) with a question mark for the anchor text. The text provided in the 'helptext' array index will be used in the tooltip to provide more context to the current option.

  3. 'description', default: ''

    Displays a more concise description below the input field of what is expected. Best kept to a few words. Use the helptext parameter for longer descriptions.

  4. 'options', default: 'array()'

    Provides an array to loop over for setting options that should be used inside of <select> and <input type="radio"> input types. The array index will be the stored option value, and the array value will be the displayed label/text.

    Note: Will only be used when the provided type is select or radio

  5. 'tab', default: AppPresser Settings Tab

    Provides the option to specify which tab the setting should go in, by specifying the slug that the tab was registered with.

  6. 'echo' default: false

    Whether or not to echo the field right away, or return it for later use. Only set to true if using the field outside of the AppPresser settings page, as the tabs require the data to be returned.

Adding a License Key field

Up next we are going to include an input for license keys. With this, you will be able to enable automatic updates if your extension is in the apppresser.com extension marketplace.

<?php
function appp_add_sample_settings( $apppresser ) {
    // Create a new tab for our settings
    $apppresser->add_setting_tab( __( 'New Tab', 'apppresser' ), 'new-tab-slug' );

    // Add a license key setting. This works with 'appp_updater_add' or 'appp_theme_updater_add'
    $apppresser->add_setting( 'my_license_setting_key', __( 'AppPresser Extension License Key', 'apppresser' ), array(
        'tab'      => 'new-tab-slug',
        'type'     => 'license_key',
        'helptext' => __( 'Adding a license key enables automatic updates.', 'apppresser' )
    ) );
}

This example is passing in my_license_setting_key for the settings table key, and "AppPresser Extension License Key" for its label text. Lastly, it's passing in an array that indicates it wants the license key field type and sets the help text to provide some more context to the user.

Let's add a few more setting fields to our output.

<?php
function appp_add_sample_settings( $apppresser ) {
    // Create a new tab for our settings
    $apppresser->add_setting_tab( __( 'New Tab', 'apppresser' ), 'new-tab-slug' );

    // Add a license key setting. This works with 'appp_updater_add' or 'appp_theme_updater_add'
    $apppresser->add_setting( 'my_license_setting_key', __( 'AppPresser Extension License Key', 'apppresser' ), array(
        'tab'      => 'new-tab-slug',
        'type'     => 'license_key',
        'helptext' => __( 'Adding a license key enables automatic updates.', 'apppresser' )
    ) );

    // Text input setting
    $apppresser->add_setting( 'my_text_input', __( 'Write some text', 'appp' ), array(
        'tab'         => 'new-tab-slug', // Add these settings to our new tab
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting. Will use custom sanitization to replace "red" with "green"', 'appp' ),
    ) );

    // Checkbox setting
    $apppresser->add_setting( 'my_checkbox', __( 'Check this box', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'checkbox',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
    ) );

    // Radio setting
    $apppresser->add_setting( 'my_radio', __( 'Select an option', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'radio',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
        'options'     => array(
            'value-1' => __( 'Value 1', 'appp' ),
            'value-2' => __( 'Value 2', 'appp' ),
        ),
    ) );
}

Introducing the add_setting_label() method

Another wrapper option for offering a heading divider and create visual sections is the $apppresser->add_setting_label() method. This method accepts two different parameters. The first one is string text to be used for the heading text. The second is an array of arguments that accepts one parameter of type. Like mentioned a moment ago, this is a wrapper method that passes in the argument into the add_setting() method documented above.

Let's add it to our overall appp-settings.php file.

<?php
function appp_add_sample_settings( $apppresser ) {
    // Create a new tab for our settings
    $apppresser->add_setting_tab( __( 'New Tab', 'apppresser' ), 'new-tab-slug' );

    // Add a license key setting. This works with 'appp_updater_add' or 'appp_theme_updater_add'
    $apppresser->add_setting( 'my_license_setting_key', __( 'AppPresser Extension License Key', 'apppresser' ), array(
        'tab'      => 'new-tab-slug',
        'type'     => 'license_key',
        'helptext' => __( 'Adding a license key enables automatic updates.', 'apppresser' )
    ) );

    // Text input setting
    $apppresser->add_setting( 'my_text_input', __( 'Write some text', 'appp' ), array(
        'tab'         => 'new-tab-slug', // Add these settings to our new tab
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting. Will use custom sanitization to replace "red" with "green"', 'appp' ),
    ) );

    // Checkbox setting
    $apppresser->add_setting( 'my_checkbox', __( 'Check this box', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'checkbox',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
    ) );

    // Radio setting
    $apppresser->add_setting( 'my_radio', __( 'Select an option', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'radio',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
        'options'     => array(
            'value-1' => __( 'Value 1', 'appp' ),
            'value-2' => __( 'Value 2', 'appp' ),
        ),
    ) );

    // Add a section label/title
    $apppresser->add_setting_label( __( 'More Options', 'apppresser' ), array(
        'tab' => 'new-tab-slug',
    ) );
}

Creating and using a custom input field.

In this section, we are going to go into a more advanced part of the AppPresser settings API. I'll provide a quick example of how to use the add_setting() method with a custom input type, and follow up with creating a filter to actually create the input type. In the following snippet, we are specifying a custom type named custom_disabled.

// Custom setting type
$apppresser->add_setting( 'my_custom_setting', __( 'This is a custom type', 'appp' ), array(
    'tab'         => 'new-tab-slug',
    'type'        => 'custom_disabled',
    'description' => __( 'This field is disabled and read only', 'appp' ),
    'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
) );

Inside of the add_setting() method is a variable filter named apppresser_field_markup_{$type}. The custom type parameter that you pass in to the method gets used in the name of that filter. For the example we have the hook we will want to use add_filter() with will be apppresser_field_markup_custom_disabled.

    add_filter( 'apppresser_field_markup_custom_disabled', 'appp_add_custom_type', 10, 4 );
    function appp_add_custom_type( $field, $key, $value, $args ) {
        $field = sprintf( '<input class="regular-text" type="text" disabled="disabled" readonly="readonly" placeholder="Read-only Values" id="apppresser-%1$s" name="appp_settings[%2$s]" value="%3$s" /><p class="description">%4$s</p>'."\n", $key, $key, $value, $args['description'] );

        return $field;
    }

This filter has four parameters passed in for you to utilize. The field variable that holds the actual html markup, the option key and value for the setting we are dealing with, and the settings arguments passed in with the add_setting() method.

With all of these combined, you are able craft your own custom input and input attributes attached. In our example above, we have created a custom text input that we have marked as readonly and disabled so that the user can not edit the values. This type of example would be good to display a value in the input but you do not want the user to edit.

Sanitizing our custom inputs.

As much as we like and trust our users, we can not always trust that the data passing through the code is always going to be safe. To ensure that it is, we need to sanitize it before it gets put into the database. In the next portion of this tutorial we will write a quick function to clean up the values. The value is run through sanitize_text_field before being passed into the filter, but you will be able to do further data manipulation and cleanup as you see fit. If you desire to do your own sanitization and want to bypass the default sanitize_text_field-cleaned value, the 3rd parameter passed to the apppresser_sanitize_setting filter is the non-sanitized value. Our example will sanitize the original value with wp_kses_post, and then replace all instances of the word "red" with "green" before returning.

add_filter( 'apppresser_sanitize_setting', 'appp_sanitize_custom_type', 10, 3 );
function appp_sanitize_custom_type( $sanitized_value, $key, $value ) {

    if ( 'my_text_input' == $key ) {
        $sanitized_value = wp_kses_post( $value );
        $sanitized_value = str_replace( 'red', 'green', $sanitized_value );
    }

    return $sanitized_value;
}

This sanitization hook is not tied to the specific field types, so to target a specific field type, you'll need to verify the passed in $key value.

At this point, our appp-settings.php file should look something like this

<?php
add_action( 'apppresser_add_settings', 'appp_add_sample_settings' );
function appp_add_sample_settings( $apppresser ) {

    // Create a new tab for our settings
    $apppresser->add_setting_tab( __( 'New Tab', 'appp' ), 'new-tab-slug' );

    // Add a license key setting. This works with 'appp_updater_add' or 'appp_theme_updater_add'
    $apppresser->add_setting( 'my_license_setting_key', __( 'AppPresser Extension License Key', 'apppresser' ), array(
        'tab'      => 'new-tab-slug',
        'type'     => 'license_key',
        'helptext' => __( 'Adding a license key enables automatic updates.', 'apppresser' )
    ) );

    // Text input setting
    $apppresser->add_setting( 'my_text_input', __( 'Write some text', 'appp' ), array(
        'tab'         => 'new-tab-slug', // Add these settings to our new tab
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting. Will use custom sanitization to replace "red" with "green"', 'appp' ),
    ) );

    // Checkbox setting
    $apppresser->add_setting( 'my_checkbox', __( 'Check this box', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'checkbox',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
    ) );

    // Radio setting
    $apppresser->add_setting( 'my_radio', __( 'Select an option', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'radio',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
        'options'     => array(
            'value-1' => __( 'Value 1', 'appp' ),
            'value-2' => __( 'Value 2', 'appp' ),
        ),
    ) );

    // Add a section label/title
    $apppresser->add_setting_label( __( 'More Options', 'apppresser' ), array(
        'tab' => 'new-tab-slug',
    ) );

    // Select setting
    $apppresser->add_setting( 'my_select', __( 'Select another option', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'select',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
        'options'     => array(
            'value-1' => __( 'Value 1', 'appp' ),
            'value-2' => __( 'Value 2', 'appp' ),
            'value-3' => __( 'Value 3', 'appp' ),
            '1-more'  => __( 'One More', 'appp' ),
        ),
    ) );

    // Custom setting type
    $apppresser->add_setting( 'my_custom_setting', __( 'This is a custom type', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'custom_disabled',
        'description' => __( 'This field is disabled and read only', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
    ) );

}

add_filter( 'apppresser_field_markup_custom_disabled', 'appp_add_custom_type', 10, 4 );
function appp_add_custom_type( $field, $key, $value, $args ) {

    $field = sprintf( '<input class="regular-text" type="text" disabled="disabled" readonly="readonly" placeholder="Read-only Values" id="apppresser--%1$s" name="appp_settings[%2$s]" value="%3$s" /><p class="description">%4$s</p>'."\n", $key, $key, $value, $args['description'] );

    return $field;
}

add_filter( 'apppresser_sanitize_setting', 'appp_sanitize_custom_type', 10, 3 );
function appp_sanitize_custom_type( $sanitized_value, $key, $value ) {

    if ( 'my_text_input' == $key ) {
        $sanitized_value = wp_kses_post( $value );
        $sanitized_value = str_replace( 'red', 'green', $sanitized_value );
    }

    return $sanitized_value;
}

By now, we have a pretty well rounded set of tools available to us to enhance our settings page and tailor the user experience as well as collect custom information. However, we're going to cover two more hooks that may be of use to you.

Add secondary buttons to the settings page.

The first hook that I'll talk about is one that will let you add secondary buttons and links next to the "Save Settings" button at the bottom. This is another spot that takes a variable hook name with apppresser_tab_buttons_{$tab} where the $tab variable is the slug of the tab that you want to add it to. In the example we are echoing a WordPress admin secondary button that simply links the user to the root url.

add_action( 'apppresser_tab_buttons_new-tab-slug', 'appp_add_sample_button' );
function appp_add_sample_button() {
    echo '<a class="button-secondary" href="'. home_url() .'">'. __( 'Go Home', 'appp' ) .'</a>';
}

Arbitrary text at the beginning or end end of the page.

Two last hooks we have are the apppresser_tab_top_{$tab} and apppresser_tab_bottom_{$tab} variable hooks. These are pretty simple hooks that are run at the beginnign and end of the page. You can utilize them to add some some initial and last moment notes to your user. In our case, we'll add some help text at the bottom for the settings tab and a link to an additional resource. Use the apppresser_tab_top_{$tab} very much the same way.

<?php
add_action( 'apppresser_tab_bottom_new-tab-slug', 'appp_add_some_text' );
/**
 * Add an arbitrary row to an options tab in the AppPresser Settings API.
 */
function appp_add_some_text() {

    $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( 'http://google.com' ), __( 'link to another resource', 'appp' ) );
    ?>
    <tr>
        <td colspan="2">
            <?php printf( __( 'This is a sentence describing the reason for this tab of settings. You can add a %s.', 'appp' ), $link ); ?>
        </td>
    </tr>
    <?php
}

Conclusion

By this point, you should have a solid idea of the tools available for working with the AppPresser settings page and can craft a wonderful experience for your users with an easy to use interface.

Here is the final combined result of all of the examples above.

<?php
add_action( 'apppresser_add_settings', 'appp_add_sample_settings' );
function appp_add_sample_settings( $apppresser ) {

    // Create a new tab for our settings
    $apppresser->add_setting_tab( __( 'New Tab', 'appp' ), 'new-tab-slug' );

    // Add a license key setting. This works with 'appp_updater_add' or 'appp_theme_updater_add'
    $apppresser->add_setting( 'my_license_setting_key', __( 'AppPresser Extension License Key', 'apppresser' ), array(
        'tab'      => 'new-tab-slug',
        'type'     => 'license_key',
        'helptext' => __( 'Adding a license key enables automatic updates.', 'apppresser' )
    ) );

    // Text input setting
    $apppresser->add_setting( 'my_text_input', __( 'Write some text', 'appp' ), array(
        'tab'         => 'new-tab-slug', // Add these settings to our new tab
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting. Will use custom sanitization to replace "red" with "green"', 'appp' ),
    ) );

    // Checkbox setting
    $apppresser->add_setting( 'my_checkbox', __( 'Check this box', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'checkbox',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
    ) );

    // Radio setting
    $apppresser->add_setting( 'my_radio', __( 'Select an option', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'radio',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
        'options'     => array(
            'value-1' => __( 'Value 1', 'appp' ),
            'value-2' => __( 'Value 2', 'appp' ),
        ),
    ) );

    // Add a section label/title
    $apppresser->add_setting_label( __( 'More Options', 'apppresser' ), array(
        'tab' => 'new-tab-slug',
    ) );

    // Select setting
    $apppresser->add_setting( 'my_select', __( 'Select another option', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'select',
        'description' => __( 'Input description (optional)', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
        'options'     => array(
            'value-1' => __( 'Value 1', 'appp' ),
            'value-2' => __( 'Value 2', 'appp' ),
            'value-3' => __( 'Value 3', 'appp' ),
            '1-more'  => __( 'One More', 'appp' ),
        ),
    ) );

    // Custom setting type
    $apppresser->add_setting( 'my_custom_setting', __( 'This is a custom type', 'appp' ), array(
        'tab'         => 'new-tab-slug',
        'type'        => 'custom_disabled',
        'description' => __( 'This field is disabled and read only', 'appp' ),
        'helptext'    => __( 'This is a (optional) help text displayed in a tooltip to explain this setting.', 'appp' ),
    ) );

}

add_filter( 'apppresser_field_markup_custom_disabled', 'appp_add_custom_type', 10, 4 );
function appp_add_custom_type( $field, $key, $value, $args ) {

    $field = sprintf( '<input class="regular-text" type="text" disabled="disabled" readonly="readonly" placeholder="Read-only Values" id="apppresser--%1$s" name="appp_settings[%2$s]" value="%3$s" /><p class="description">%4$s</p>'."\n", $key, $key, $value, $args['description'] );

    return $field;
}

add_filter( 'apppresser_sanitize_setting', 'appp_sanitize_custom_type', 10, 2 );
function appp_sanitize_custom_type( $sanitized_value, $key ) {

    if ( 'my_text_input' == $key ) {
        $sanitized_value = str_ireplace( 'red', 'green', $sanitized_value );
    }

    return $sanitized_value;
}

add_action( 'apppresser_tab_buttons_new-tab-slug', 'appp_add_sample_button' );
function appp_add_sample_button() {
    echo '<a class="button-secondary" href="'. home_url() .'">'. __( 'Go Home', 'appp' ) .'</a>';
}

add_action( 'apppresser_tab_bottom_new-tab-slug', 'appp_add_some_text' );
/**
 * Add an arbitrary row to an options tab in the AppPresser Settings API.
 */
function appp_add_some_text() {

    $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( 'http://google.com' ), __( 'link to another resource', 'appp' ) );
    ?>
    <tr>
        <td colspan="2">
            <?php printf( __( 'This is a sentence describing the reason for this tab of settings. You can add a %s.', 'appp' ), $link ); ?>
        </td>
    </tr>
    <?php
}

Screenshot of our new settings tab in the AppPresser settings panel. Screenshot of our new settings tab in the AppPresser settings panel

If you would like to see the entire php class used for the admin settings, visit /plugins/apppresser/inc/admin-settings.php in your favorite text editor or IDE.