processHTML only works with textarea?

It looks like processHTML does not work with html retrieved from input field HtmlArea, we have to use a TextArea, or else it just shows the string, without rendering it as html.

Is this by design, or do we have some kind of error? We are rendering with data-th-utext, but the problem is with the input type. TextArea works fine, but I would like to use it with the HtmlArea as well.

Hi Tore.

Can you elaborate a bit on the context? Are you using our JavaScript framework, or are you processing via the GraphQL API?

Using processHTML on TextArea makes no sense?

I’ll elaborate:

I can’t use the built-in macro, because that does not support anything else than a pure iframe element. But we have elements with additional divs, that provides inline styling (from Plandisc). So, I created a part, with a HtmlArea, for the user to paste the entire iframe+div combo inside. I retrieve it in the model, use processHtml on it, and then show it with th-utext. That didn’t work, until I changed the input field from HtmlArea to TextArea. Then it worked. Seems like the editor for HtmlArea ads a p-tag, but removing that in the source for the input field didn’t work either, so I changed it to TextArea, which did the trick.

But I would also like to create a custom macro for allowing the user to paste the iframe-div combo in a body text type anywhere, i.e not having to use a designated part for it. But then I run into the same problem, it doesn’t work when coming from a HtmlArea, and in this case I can’t change it to TextArea.

Hope that made sense :slight_smile:

Here’s an example on a iframe+div combo. Without the div’s inline styling, it does not render well.

<div style="max-width:1000px;width:100%;"><div style="position: relative;padding-bottom: 117%;padding-top: 35px;height: 0;overflow: hidden;"><iframe src="https://create.plandisc.com/wheel/embed/QB4GDZj" scrolling="no" frameborder="0" title="Financial Governance" style="position:absolute;top:0;left:0;width:100%;height:100%;"></iframe></div></div><a style="font-size:10px;" href="https://create.plandisc.com/QB4GDZj ">Can't see the plandisc? Click here</a>

Tore.
Can you share your macro definition here as well
Also would be nice with a screenshot of what it looks like when you try to use the macro inside htmlarea in Content Studio.

Yes. Probably something simple I’m missing here, but:

xml:

<macro>
    <display-name>Plandisc - utvidet iframe</display-name>
    <description>Iframe element med tillegg</description>
    <form>
        <input name="body" type="HtmlArea">
            <label>Iframe - element</label>
        </input>
    </form>
</macro>

es6:

const libs = {
  portal: require("/lib/xp/portal")
};

exports.macro = (context) => {
  const body = context.body;
  const iframeData = libs.portal.processHtml({ value: body });
  return {
    body: iframeData
  };
};

Should be simple enough? But what it renders is:

-or, if I just paste some simple html, it looks like this:

image

But if I just return like this, then it renders:

const libs = {
  portal: require("/lib/xp/portal")
};

exports.macro = (context) => {
  const body = context.body;
  const iframeData = libs.portal.processHtml({ value: body });

  log.info(JSON.stringify(iframeData, null, 4));
  return {
    body: "<h1>Dette er en h1</h1>"
  };
};

So possibly processHtml does not do what I expected it to do…and I need to do something else entirely.

HtmlArea contains HTML. When its contents come to the macro controller it’s html-escaped, so you need to html-unescape it before feeding to processHtml().

Add this to the dependencies section of your build.gradle:

dependencies {
    ...
    include "com.enonic.lib:lib-text-encoding:2.1.1"
}

Then in your macro controller:

const libs = {
  portal: require("/lib/xp/portal"),
  encoding: require("/lib/text-encoding")
};

exports.macro = (context) => {
  const body = libs.encoding.htmlUnescape(context.body);
  const iframeData = libs.portal.processHtml({ value: body });

  return {
      body: iframeData
  };
};

Here are my comments:

  1. You should not run processHtml within the macro controller itself - it is only supposed to be applied for the whole editor value.
  2. Macros were made so users should not paste html into the editor (which is basically a massive security hole, and wrong in many many ways). Simply. move the markup you want to produce into the macro code, and you will be fine.

Interesting, that partially solved the problem, but only partially: On my test page I have now inserted two iframes, and with this method (htmlUnescape), one of them is now showing. The other one, there is space allocated to it, but it does not show, it’s just blank space. This is interesting, because if I insert the part I also made, the one that uses a TextArea istead of a HtmlArea, and insert the exact same iframe+div combo, then that is showing. That’s weird, isn’t it?

Here, just blank space

Here, the other iframe+div, which is showing:

And here, the same iframe+div as where there is now blank space, but inserted with my part, and it is showing fine:

So that’s a bit weird, what could be the cause of that?

Check what’s returned in the case when nothing is shown. Use log.info to output first the raw contents of the field, then contents fed through processHtml.

But conceptually I agree with @tsi in that you shouldn’t use HTML/RichText inside a macro - you’ll end up with HTML inside HTML which may produce unexpected results (as you have seen).

Yes, I understand the security issue (however, if that happens and someone from within inserts malevolent code, then we have a huge problem already).

I can move the div inside, but since that information varies (the two iframe-div combos in my screenshots above are different for instance), then it will be too inflexible.

This is why you can define a form for the macro.
Here you can provide configuration parameters that can be used to output the desired markup in the end.

In theory, but in practise perhaps not so feasible… I mean, one content-provider supplies the iframe inside a div, with a lot of accompanying stiles, while another one supplies their’s inside TWO divs, both with separate styling. It’s not unprobable down the line that still others have their own sets, which has to be adhered to if you want everything to display correctly. It’s not easy to cover all the bases here, but okey, I think a part or js listening for messages from the iframe is the way to go here.

I don’ know how many providers we’re talking a out here. But ideally, make one macro per provider.