Skip to content

Conversation

roborourke
Copy link
Contributor

This PR adds support for escaping html in attributes so that HTML no longer breaks the view rendering.

It should also go some way to paving the way forward for #236

It does a few things:

  1. Adds a default attribute for field types called 'escape'
  2. If 'escape' is true the value is passed through encodeURIComponent() and decodeURIComponent() where appropriate
  3. Shortcodes with fields that are marked to be escaped have a filter added to run rawurldecode() automatically on the values provided the shortcode author uses the shortcode_atts() function and provides the 3rd parameter stating the shortcode tag name

Example:

<?php

add_shortcode( 'html_textarea_field', function ( $attr = '', $content = false ) {

    $attr = shortcode_atts( array(
       'html_content'   => '',
    ), $attr, 'html_textarea_field' ); // 3rd param here enables the automatic rawurldecode() filter

    $output = apply_filters( 'the_content', $attr['html_content'] );

    return $output;
} );

if ( function_exists( 'shortcode_ui_register_for_shortcode' ) ) {

    shortcode_ui_register_for_shortcode( 'html_textarea_field', array(
        'label'         => __( 'HTML Textarea' ),
        'listItemImage' => 'dashicons-align-left',
        'attrs'         => array(
            array(
                 'label' => __( 'HTML' ),
                 'attr'  => 'html_content',
                 'type'  => 'textarea',
            )
        )
     );

}

@danielbachhuber
Copy link
Contributor

I'm 👎 on storing escaped data in attributes. It seems like a technical hack around conceptual contradiction — shortcodes are macros to produce HTML markup.

@goldenapples
Copy link
Contributor

I think escaping the data in some way is unavoidable. Its a common use case for shortcode attributes to hold names, strings for display, or other data which can't reasonably be expected to be free of all special characters. There's no other way, short of a core change, to get shortcode_parse_atts to handle quotes or some other special characters in attribute text.

The idea of the filter on "shortcode_atts_{$shortcode}" seems like a good way to handle this transparently for those attributes that desire it, while still preserving existing default behavior. Yes, this isn't what urlencoding is really for, but it works, and has the advantage of being available in a similar form in PHP and javascript.

@goldenapples
Copy link
Contributor

But, if we're looking for alternative approaches, replacing the attribute parser regex in core with something like an XML attribute reader would be a good start. My initial confusion at this issue came because intuitively I expected shortcode attributes to behave like HTML attributes and was surprised that attr="value with \"quotes\"" didn't work. We already have tools to deal with escaping attribute values; if shortcode attributes worked like XML/HTML attributes, then the problem here would be simpler and we could use a more appropriate escaping method.

@roborourke
Copy link
Contributor Author

I think the main problem I was getting around was that it breaks the view if an attribute has html in, when you have a textarea field that gets stored in an attribute this can happen with no clear way to recover easily.

URL escaping was the only common way to handle this between JS and PHP besides atob() / btoa() which aren't supported before IE10, guess that depends on the browser support offered by wp admin which afaik is still IE8.

I agree it's totally hacky but can't see how else would #236 be feasible?

@roborourke
Copy link
Contributor Author

A slightly less hacky approach may be to embed the data inside inner_content somehow. Eg. <div style="display:none" data-shortcode-attr="attribute-name">some <strong>HTML</strong> content</div> then read the values out from there

@roborourke
Copy link
Contributor Author

@mattheu any thoughts on this?

@danielbachhuber
Copy link
Contributor

It would be nice to have an official core opinion on this.

@danielbachhuber
Copy link
Contributor

We chatted about this some today. It seems like encoding behind the scenes is the only way we can go for now.

Could we make registration happen on the field-level, and automatically unencode so no modification to an existing shortcode is necessary?

@danielbachhuber
Copy link
Contributor

@sanchothefat One nit before this lands — could we call the argument encode instead of escape? Technically we're doing the former.

@danielbachhuber danielbachhuber added this to the v0.4.0 milestone Jun 1, 2015
@danielbachhuber danielbachhuber changed the title Allow HTML in textarea fields Allow HTML in attributes Jun 1, 2015
@danielbachhuber danielbachhuber removed this from the v0.4.0 milestone Jun 2, 2015
@danielbachhuber
Copy link
Contributor

Actually, now that #179 has landed, let's bump this out of v0.4.0 and come back to it if we need.

@danielbachhuber
Copy link
Contributor

Closing in favor of #496

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants