HTML entities are not being decoded when using WordPress REST API for Gutenberg blocks
Asked Answered
H

2

9

I am building a custom Gutenberg block that makes a request to the WordPress REST API to get some Posts. I'm using axios to make the request to the REST endpoint.

When the result comes back, there is an array of Post objects, and I can see the titles of the Posts, but they are all contained in the JSON object as title.rendered and contain HTML entities eg.

title: {
    rendered: "This has a hyphen – oh dear"
}`

I'm trying to populate a <SelectControl> with the resulting data, so there's no way to use the React dangerouslySetInnerHTML method which would solve the entities problem. So how can I get rid of these entities when populating the options?

Here is the code I'm using to populate the options from the REST response:

const options = response.data.map((post) => {
    return {
        label: post.title.rendered,
        value: post.id,
    };
});
Handcuff answered 7/9, 2018 at 20:16 Comment(0)
H
7

It's not immediately obvious, but there is in fact a method made available in the Blocks API to do this.

At the top of your block code, type:

const { decodeEntities } = wp.htmlEntities;

Then you can use it like this:

const options = response.data.map((post) => {
    return {
        label: decodeEntities(post.title.rendered),
        value: post.id,
    };
});

Bazoozaa! HTML entities are gone.

Handcuff answered 7/9, 2018 at 20:16 Comment(2)
in my case, I added this line: import {decodeEntities} from "@wordpress/html-entities"; after run npm install @wordpress/html-entities --saveThearchy
Yep - that works perfectly if you're using the @wordpress imports (I'm using that too) - I'll add that into the answerHandcuff
M
5

And why not using rest_prepare_<post_type> filter ?

$post_type = "post";
add_filter( "rest_prepare_{$post_type}", 'prefix_title_entity_decode' );
function prefix_title_entity_decode( $response ) {
    $data = $response->get_data();
    $data['title']['rendered'] = html_entity_decode( $data['title']['rendered'] );
    $response->set_data( $data );
    return $response;
}
Must answered 8/11, 2019 at 13:22 Comment(1)
You should also pass new title value through wp_kses_post(), because it may contain unescaped tags that might lead to XSS vulnerabilities: $data['title']['rendered'] = wp_kses_post( html_entity_decode( $data['title']['rendered'] ) );Step

© 2022 - 2024 — McMap. All rights reserved.