I want to allow HTML into a plugin input field via a user, I am using the Settings API, but it strips everything HTML out. - Code below -any pointers?

function plugin_settings(){
        'plugin_prefix validate_input' 
        'My Settings', 
        'plugin_prefix my_section_callback', 
        'HTML Carat', 
        'plugin_prefix ng_html_callback', 
add_action('admin_init', 'plugin_prefix plugin_settings');

function ng_html_callback() {
$options = get_option( 'my_settings' ); 

if( !isset( $options['ng_html'] ) ) $options['ng_html'] = '';

echo '<label for="ng_html">' . esc_attr_e( 'Insert additional HTML','plugin') . '</label>';
echo '<input type="text" id="ng_html" name="my_settings[ng_html]" value="' . $options['ng_html'] . '" placeholder="Add HTML">';

When you register a setting, you pass the santize callback for that setting:

     // The next parameter is the validation callback

Then, in the validation callback you can allow whatever you want. For example, in the next code snippet, users with unfiltered_html capability will be allowed to insert raw HTML code; other users are allowed to insert the same HTML tags allowed in post content:

function my_setting_validation( $input ) {

    // Check for the field that we want to allow html
    if( $input['ng_menu_html'] ) {

        if ( current_user_can('unfiltered_html') ) {

            $validated_input['ng_menu_html'] =  $input['ng_menu_html'];

        } else {

            $validated_input['ng_menu_html'] = stripslashes( wp_filter_post_kses( wp_slash( $input['ng_menu_html'] ) ) ); // wp_filter_post_kses() expects slashed


     } else {

         // Sanitize here other fields with no HTML or whatever you want


     return $validated_input;


Finally, you need to use esc_attr() when set the value of the field:

function ng_html_callback() {

    $options = get_option( 'my_setting_name' ); 

    if( !isset( $options['ng_html'] ) ) $options['ng_html'] = '';

        echo '<label for="ng_html">' . _e( 'Insert additional HTML', 'plugin') . '</label>';
        echo '<input type="text" id="ng_html" name="my_settings[ng_html]" value="' . esc_attr( $options['ng_html'] ) . '" placeholder="Add HTML">';

| improve this answer | |
  • Thanks cybmeta that works great - for the other input fields which require no HTML what is best to add in the else field. else { // Sanitize here other fields with no HTML or whatever you want } I have tried a few but the settings are not being saved. – neilgee Oct 15 '15 at 23:08

This is what I ended up with for the validation - partly taken from here

function my_setting_validation( $input ) {
       // Create our array for storing the validated options
        $output = array();

        // Loop through each of the incoming options
        foreach( $input as $key => $value ) {

            if( isset( $input['ng_menu_html'] ) ) {

                // Keep HTML in this field
               $output['ng_menu_html'] = wp_kses_post($input['ng_menu_html']);

            } // end if

            // Check to see if the current option has a value. If so, process it.
            if( isset( $input[$key] ) ) {

                // Strip all HTML and PHP tags and properly handle quoted strings
                $output[$key] = strip_tags( stripslashes( $input[ $key ] ) );

            } // end if

        } // end foreach

        // Return the array processing any additional functions filtered by this action
        return apply_filters( 'my_setting_validation' , $output, $input );

And as you pointed out ensure esc_attr is used in the input field.

echo '<input type="text" id="ng_menu_html" name="my_settings[ng_menu_html]" value="' . esc_attr($options['ng_menu_html']) . '" placeholder="Add custom HTML mark up">';
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.