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.

| improve this answer | |
  • 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. – NextGenThemes 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. – NextGenThemes 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
  • I edited my question based on your valuable but still very unsatisfying answer ;) Still not sure what to do now because its just just a link its text with links already possibly translated from php. – NextGenThemes Nov 6 '19 at 12:46

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.