0

I like to know how can I add clickable links to help text?

el(
    ToggleControl,
    {
        label: 'Toogle',
        help: '<a href="https://.." >This will be escaped, I do not want that</a>',
        checked: props.attributes.toggle,
        onChange: ( value ) => {
            props.setAttributes( { toggle: value } );
        },
    }
)

Basically every GB UI element has help but its escaping all HTML, how can I stop it from escaping it?

I have code like below that is used in other places, the current answer is not really a solution I like. I basically only need plain text and links in some rare cases. I do not know how to create a text element with a link element inside it in Gutenberg. I am looking for a solution to maybe use regex or something to transform my HTML as its defined in PHP into something that I can use in the GB help text as well. Like maybe turning links to markdown or something and then creating save elements from that in GB. Something clever? Or am I overthinking it? I could just additionally define it in php for GB specifically. But how would I define it so it can be used to create a element with links in it.

<?php
...
            'description' => sprintf(
                // Translators: %1$s Providers
                __( 'Post the URL of the video here. For %1$s and any <a href="%2$s">unlisted</a> video hosts paste their iframe embed codes.', 'advanced-responsive-video-embedder' ),
                esc_html( $embed_code_only ),
                esc_url( 'https://nextgenthemes.com/arve-pro/#video-host-support' )
            ),
2

I know this is not going to make you happy, but — unless you copy the relevant UI component and edit it (so that it would allow a HTML string), and then use it instead — you can't stop the HTML from being escaped. And I'm pretty sure you know why would/should it be escaped.. :-)

But if you just want a clickable link to be the "help" text, or for it to have some HTML, then you can pass a WPElement as the help value:

const el = wp.element.createElement;

el( ToggleControl, {
    label: 'Toggle',
    help: el( 'a', { href: 'https://example.com' }, 'This should work..' ),
    ...
} );

And if you really must pass a HTML string, then that's possible using the dangerouslySetInnerHTML attribute/property. But as the name implies, it's dangerous, so make sure your HTML is as secure as possible.

So here's an example:

const el = wp.element.createElement;
const html = ( html ) => { return { __html: html } };

el( ToggleControl, {
    label: 'Toggle',

    // This outputs: <span><a href="#">Foo</a> Bar</span>
    help: el( 'span', {
        dangerouslySetInnerHTML: html( '<a href="#">Foo</a> Bar' )
    } ),

    ...
} );

Or in Gutenberg, you can use wp.element.RawHTML() (which puts the generated element in a div):

const el = wp.element.createElement;
const htmlToElem = ( html ) => wp.element.RawHTML( { children: html } );

el( ToggleControl, {
    label: 'Toggle',

    // This outputs: <div><a href="#">Foo</a> Bar</div>
    help: htmlToElem( '<a href="#">Foo</a> Bar' ),

    ...
} );

Either way, it would be up to you how to pass the HTML from PHP to the above your JS/GB script. But basically, you can use wp_localize_script() to define the HTML list for use in your script.

10
  • Can I use a <span> with html content? I already have HTML with links defined in PHP I just want to pass it to GB so this solution is not very convenient. Nov 6 '19 at 11:21
  • If you really must, you can try the solution here - use the dangerouslySetInnerHTML attribute or wp.element.RawHTML() (but RawHTML() wraps the element in a div).
    – Sally CJ
    Nov 6 '19 at 11:36
  • Opening up my users to CrossSiteScripting does not sound very nice either. I have though of using _.unescape() from underscore on the html elements after they render but that is probably also unsave. Apart from that these elements are not there on dom load and there seem to be no classes or id to select my specific block. Nov 6 '19 at 11:53
  • It surely is not nice. It's merely an option if you wish to pass a HTML string. And regardless you use the native innerHTML method or React's way of creating elements from raw HTML, there's a possibility of security issues there. That's why using the createElement() without passing a HTML string is a better option.
    – Sally CJ
    Nov 6 '19 at 12:10
  • 1
    Unfortunately the RawHTML solution doesn't work well, because the help property is creating a <p> element, then RawHTML is creating a <div> nested in the <p> which react doesn't like and complains about, generating an error. Mar 7 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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