I have been unable to figure out how I can properly sanitize (in the customizer) and escape (in the theme, while allowing the user to use "<" and ">" to insert a '< br >' and add a line break wherever they want.

I have an area in my theme's customizer that allows the user to put text in a text box, and it outputs to a main headline area of the site. It works fine, but it does not appear to really be outputting HTML even with the use of esc_html().

I have looked through the WordPress core sanitize functions for something I can use for the input in the customizer like:

  • sanitize_email
  • sanitize_html_class
  • sanitize_key

And I have dug through the codex for ways to sanitize the output in the theme like:

  • esc_html
  • esc_attr

When using any of these I end up with the "< br >" being printed on the page, instead of it actually inserting a line break. The only way I have been able to make it behave like I want is to not sanitize it at all. If I don't use a sanitize callback in the customizer, and I don't escape the output at all, the user is able to put "< br >" in the text box and the browser will insert a line break instead of printing the "< br >".

I thought maybe I could make a custom function. I went to wp-includes/formatting.php thinking I could copy and edit the sanitize_html_class function and found this:

function esc_html( $text ) {
$safe_text = wp_check_invalid_utf8( $text );
$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
 * Filter a string cleaned and escaped for output in HTML.
 * Text passed to esc_html() is stripped of invalid or special characters
 * before output.
 * @since 2.8.0
 * @param string $safe_text The text after it has been escaped.
 * @param string $text      The text prior to being escaped.
return apply_filters( 'esc_html', $safe_text, $text );}

I also found this:

function sanitize_html_class( $class, $fallback = '' ) {
//Strip out any % encoded octets
$sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $class );

//Limit to A-Z,a-z,0-9,_,-
$sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $sanitized );

if ( '' == $sanitized )
    $sanitized = $fallback;

 * Filter a sanitized HTML class string.
 * @since 2.8.0
 * @param string $sanitized The sanitized HTML class.
 * @param string $class     HTML class before sanitization.
 * @param string $fallback  The fallback string.
return apply_filters( 'sanitize_html_class', $sanitized, $class, $fallback );}

 * Converts lone & characters into `&#038;` (a.k.a. `&amp;`)
 * @since 0.71
 * @param string $content    String of characters to be converted.
 * @param string $deprecated Not used.
 * @return string Converted string.
function convert_chars( $content, $deprecated = '' ) {
if ( ! empty( $deprecated ) ) {
    _deprecated_argument( __FUNCTION__, '0.71' );

if ( strpos( $content, '&' ) !== false ) {
    $content = preg_replace( '/&([^#])(?![a-z1-4]{1,8};)/i', '&#038;$1', $content );

return $content;}

Is there a way I can rename and edit these to make a custom function that will allow me to use "<" and ">" like I can in HTML?

Should I be using wp_kses in the theme file instead of escaping?

1 Answer 1


You should use the helping site of validation - https://codex.wordpress.org/Data_Validation

I think in your context is wp_kses the right function. You can allow HTML tags. The function have a lot of possibilities to use it with custom requirements.

A small example to fast usage:

$allowed_html = array(
    'a' => array(
        'href' => array(),
        'title' => array()
    'br' => array(),
$my_filtered_string = wp_kses( $string, $allowed_html, $allowed_protocols = array() );

Small words on the end about performance. The function is hungry, you should use it carefully. More about this include values from benchmarks can you find in this post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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