'WordPress Security Standards want me to escape my html, but how to do it correctly?

I'm trying to build a custom Elementor Widget (https://developers.elementor.com/creating-a-new-widget/). In the render() function, I can put the HTML thats being rendered in the frontend.

Now I have a project set up that uses codesniffer to force wordpress coding standards.

I have the following code for the render() function:

/**
 * Render widget output on the frontend
 */
protected function render() {
    $i_am                 = __( 'I am', 'hello-elementor-child' );
    $and_i_am_looking_for = __( 'and I am looking for', 'hello-elementor-child' );

    $output = <<<HTML
        <form>
            <div>
                <label>$i_am</label>
                <input type="text" name="i_am" value="" />
            </div>
            <div>
                <label>$and_i_am_looking_for</label>
                <input type="text" name="and_i_am_looking_for" value="" />
            </div>
        </form>
    HTML;

    echo $output;
}

CodeSniffer now complains about the $output, since I'm not escaping it:

All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found '$output'.

PHPCS(WordPress.Security.EscapeOutput.OutputNotEscaped)

Now looking up the WP Dev Handbook, it tells me about several methods to escape the output, and esc_html for excamples does exactly what it should, but of course, Then I have the frontend display html code to the user instead of rendering actual html thats rendered by the browser...

So in this szenario, how do I please the codesniffer but also output what I need?



Solution 1:[1]

if you want to echo html code inside php. Better make them into String. Please change your code a litle like this:

$output = "<HTML>
    <form>
        <div>
            <label>$i_am</label>
            <input type='text' name='i_am' value='' />
        </div>
        <div>
            <label>$and_i_am_looking_for</label>
            <input type='text' name='and_i_am_looking_for' value='' />
        </div>
    </form>
</HTML>";

Solution 2:[2]

You can use wp_kses.

echo wp_kses(
    $output,
    array(
        'form'  => array(),
        'div'   => array(),
        'label' => array(),
        'input' => array(
            'type',
            'name',
            'value',
        ),
    )
);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 th?ng nguy?n
Solution 2 Marcos Nakamine