-
19 Feb 2013 3:33 AM #1
Problem with XTemplate and html entities
Problem with XTemplate and html entities
Hi all, I have a problem that is driving me crazy.
I have the method redditivita() in a i18 Constants class that returns the String "Redditività":
As you can see inside this string there is the html entity "à"Code:... /** * Translated "Redditività". * * @return translated "Redditività" */ @DefaultStringValue("Redditività") @Key("redditivita") String redditivita(); ...
When i try to use it in a XTemplate the result is as follow:
shot.png
while I expect the text of the label is RedditivitÃ
This is my code:
and this is my template file:Code:... interface DetailRenderer extends XTemplates { @XTemplate(source = "SectionDetail.html") public SafeHtml renderItem(SectionItem section); } ... final DetailRenderer r = GWT.create(DetailRenderer.class); IsideCommonCssBundle.INSTANCE.listViewStyle().ensureInjected(); ListViewStyle style = IsideCommonCssBundle.INSTANCE.listViewStyle(); ListViewCustomAppearance<SectionItem> appearance = new ListViewCustomAppearance<SectionItem>("." + style.thumbWrap()) { @Override public void render(SafeHtmlBuilder builder) { builder.appendHtmlConstant("<div class='" + ListView.getStandardResources().css().view() + "' id='list-view'></div>"); } @Override public void renderEnd(SafeHtmlBuilder builder) { String markup = new StringBuilder("<div class=\"").append(CommonStyles.get().clear()).append("\"></div>").toString(); builder.appendHtmlConstant(markup); } @Override public void renderItem(SafeHtmlBuilder builder, SafeHtml content) { builder.append(content); } }; listView = new ListView<SectionItem, SectionItem>(listStore, new IdentityValueProvider<SectionItem>() { @Override public void setValue(SectionItem object, SectionItem value) { } }, appearance); listView.setCell(new SimpleSafeHtmlCell<SectionItem>(new AbstractSafeHtmlRenderer<SectionItem>() { public SafeHtml render(SectionItem object) { SafeHtml h = r.renderItem(object); return h; } }));
section.name is the field containing the result of redditivita() method from i18n Constants class.HTML Code:<div class="thumb-wrap"> <div class="thumb"><img src="{section.iconUrl}" title="{section.name}"></div> <span class="x-editable">{section.name}</span></div>
Where is the problem?
-
28 Feb 2013 10:58 AM #2
If you know that your browser can handle that entity character, then it appears when XTemplates encounters a method that returns a String it appears to escape the entities so that they are not rendered correctly. Since the SectionItem.getName() needs to be treated without being escaped, you are probably going to want to pass SectionItem.getName in as a SafeHtml.
I believe this would prevent XTemplates from doing anything to the String. I think you can use SafeHtmlUtils.fromTrustedString(String), or SafeHtmlUtils.htmlEscapeAllowEntities(String) to get the right value.
This would change your XTemplate method to:
whereCode:renderItem(SectionItem section, SafeHtml sectionName)
Here's the link to the javadocs for SafeHtmlUtils.Code:SafeHtml sectionName = SafeHtmlUtils.fromTrustedString(String); // or .htmlEscapeAllowEntities(...)
Give that a go and see if that fixes your issue.
-
28 Feb 2013 11:03 AM #3
I could be mistaken, but I think that the Constants subclass is allowed to return SafeHtml instead of String. Doing so would let you skip the fromTrustedString call.
-
1 Mar 2013 12:44 AM #4
I have modified my code like this:
it seems that I'm not allowed to use SafeHtml in the render method, this is the error:Code:interface DetailRenderer extends XTemplates { @XTemplate(source = "SectionDetail.html") public SafeHtml renderItem(SectionItem section, SafeHtml sectionName); } .... listView.setCell(new SimpleSafeHtmlCell<SectionItem>(new AbstractSafeHtmlRenderer<SectionItem>() { public SafeHtml render(SectionItem object) { SafeHtml sectionName = SafeHtmlUtils.fromTrustedString(object.getName()); SafeHtml h = r.renderItem(object,sectionName); return h; } }));
SafeHtml used in a non-text context. Did you mean to use java.lang.String or SafeStyles instead?
I've tried also other solution with SafeHtmlUtils.htmlEscapeAllowEntities(object.getName()); but this not change anything...
I think the problem is with the class AbstractSafeHtmlRenderer that i use in
listView.setCell(new SimpleSafeHtmlCell<SectionItem>(new AbstractSafeHtmlRenderer<SectionItem>() {....
looking the source of this class I've found this method:
Is it possible that method toSafeHtml is called and the red part is the trouble?Code:protected SafeHtml toSafeHtml(Object obj) { return obj == null ? EMPTY_STRING : SafeHtmlUtils.fromString(String.valueOf(obj)); }
-
1 Mar 2013 1:26 AM #5
-
1 Mar 2013 2:03 AM #6
Now, after further analysis, I'm pretty sure that the problem si with XTemplates core implementation class, as you ca see in the image below,debugging my application the result of the renderItem method contain the mistake...
PrintScreen.jpg
There is no development group member who can help me?
-
1 Mar 2013 2:33 AM #7
This is my trick to solve the problem...
Not a good practice...Code:public SafeHtml render(SectionItem object) { SafeHtml h = r.renderItem(object,SafeHtmlUtils.htmlEscapeAllowEntities(object.getName())); return SafeHtmlUtils.fromSafeConstant(h.asString().replaceAll("&", "&")); }
-
1 Mar 2013 9:12 AM #8
I think you missed our point. Here's a working example of what I meant (by the way, did you try changing your Constants class to return a SafeHtml per Colin's suggestion?):
Code:public class XTemplateEntityTest implements EntryPoint { private final XTemplateEntity template = GWT.create(XTemplateEntity.class); @Override public void onModuleLoad() { ContentPanel cp = new ContentPanel(); cp.setPixelSize(400, 400); String textWithEntity = "This has an entity character: à"; SafeHtml safeHtmlWithEntity = SafeHtmlUtils.fromTrustedString(textWithEntity); SafeHtml result = template.renderEntity(safeHtmlWithEntity); cp.setWidget(new HTML(result)); RootPanel.get().add(cp); } interface XTemplateEntity extends XTemplates { @XTemplate("<span>{safeHtml}</span>") public SafeHtml renderEntity(SafeHtml safeHtml); } }Last edited by icfantv; 6 Mar 2013 at 8:35 AM. Reason: removed extra blank lines
-
4 Mar 2013 1:07 AM #9
Thank you so much. I can't return a SafeHtml from Constants class but your solution work.
I've previously tried this and it didn't work due to a wrong template like this.
It's not possible to render a SafeHtml in a attribute, so I've removed title="{sectionName}" and all things worked well.HTML Code:<div class="thumb-wrap"> <div class="thumb"><img src="{section.iconUrl}" title="{sectionName}"></div> <span class="x-editable">{sectionName}</span></div>
-
6 Mar 2013 8:34 AM #10
You're welcome. Please mark this question as answered if you feel it's done so. Thanks.


Reply With Quote