I have been trying to figure out how to escape quotes (single and double) from shortcode attributes.
Basically the content is written by the user and therefore can potentially include ” and ‘ quotes. Problem being, with ” quotes it is stopping the shortcode attribute from functioning eg:
attibute=”some text here with “quotes” so it stops the attribute….”
So instead of getting the entire string it is stopping at the second pair of quotes.
Now, I know it could be possible to set it up with single quotes but that leaves the same predicament if a user uses single quotes in the text.
I have looked at a variety of PHP/WP resolutions but I cant seem to get any of them to work, eg esc_html, htmlspecialchars, htmlentities.
Maybe I have set it up wrong or am not actioning the encoding at the right place.
This is currently what I am using (without encoding) as the shortcode (shortened a bit)
function aps_person_schema_shortcode( $atts, $content = null) {
extract( shortcode_atts( array(
'aps_person_description' => ''
), $atts
)
);
$aps_person_return = '<div class="aps_person_container aps_container">';
$aps_person_return .= '<p class="aps_person_description" itemprop="description">' . $aps_person_description . '</p>';
$aps_person_return .= '</div>';
return $aps_person_return;
}
add_shortcode('aps_person', 'aps_person_schema_shortcode');
I’ve tried adding in after the extract array things like
$aps_person_description = esc_html($atts['aps_person_description']);
but as the attribute is already broken (print_r displays that the string after the quote is separated into an array item for each word) escaping the string there doesnt work.
Tried it before the array and it doesn’t work either I get a Notice: Undefined index
So, to clarify, how do you go about sanitizing user input for shortcode attribute data?
It seems you are working on the wrong end.
Try sanitizing the user input, for instance by means of
sanitize_text_field
, not the shortcode output.It turns out WordPress shortcode system uses function
shortcode_parse_atts($text);
to parse a shortcode entry to retrive attributes’ names and values and store them in pairs in the array$atts
, which is then passed to the shortcode function. So in your case adding escaping actions in the shortcode function like this:will not work because
shortcode_parse_atts()
has already retrived attributes’ names and values, and might have wrongly interpreted quotes in attributes’ values.To look closer, function
shortcode_parse_atts()
use this regex pattern:to recognize attributes’ names and values in the formats belows:
So if a user puts quotes in values, it can easily go wrong. For example:
Sanitizing after the parsing is obviously too late, what about sanitizing before the parsing? We will have to sanitize the entire entry since we don’t have any attribute’s values to work on yet. But this also causes problems, for example:
The paradox is: in order to make sure the parsing engine parses correctly, you have to sanitize the attributes values; but to do this you have to run the parsing engine first to get the values.
In conclusion, I think the reasonable way to make sure everything goes fine is to ensure users input attributes in proper formats, once users posted poorly formatted attributes, it will be a big headache. FYI, my experience is to make use of
$content
. In your case, I would putaps_person_description
in the$content
, it may look like this:and quotes will be less a problem.
I faced a similar issue printing out a PHP variable into a shortcode attribute. In my case, this value a taxonomy term name, not user-generated content, so there was no input to sanitize.
Using
htmlentities()
with the flagENT_QUOTES
allows strings including'
and"
to be used as shortcode attributes. However, it also converts other characters to HTML entities, such as&
into&
, which was not ideal for me.To only convert
'
and"
characters into HTML entities, while not converting other characters like&
:htmlspecialchars_decode()
reverses all the HTML entities converted byhtmlentities()
. Using the flagENT_NOQUOTES
prevents'
&"
characters from being converted back.