Message Boards

String replace before / after html output

Marcin Klinski, modified 3 Years ago.

String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
Hello !
I need to remove or replace some string from output html - what is the best option for that ?
For example - the front page is fully loaded and we have one line html code that include string "text/javascript" - i want to remove that string everywhere on all pages and also change other string - <h3> to <h2> <div> to <p> etc.
In php I use ob_start("callback") with str_replace but i cant find any similar solution for Liferay.
thumbnail
Olaf Kock, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 6396 Join Date: 9/23/08 Recent Posts
Marcin Klinski:

I need to remove or replace some string from output html - what is the best option for that ?
For example - the front page is fully loaded and we have one line html code that include string "text/javascript" - i want to remove that string everywhere on all pages and also change other string - <h3> to <h2> <div> to <p> etc.
In php I use ob_start("callback") with str_replace but i cant find any similar solution for Liferay.
Your example sounds like this problem. With some more information on the underlying problem, we might be able to point you to a better solution.
In general, you have (for example) PortletFilters at your disposal. Or, of course, plain old Javascript on the rendered DOM. But before going into detail: There's a high probability that this is the wrong (or just a hard-to-maintain) solution for the underlying problem.
Marcin Klinski, modified 3 Years ago.

RE: String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
Dear Olaf,
Your answer did not help me. I need to put WCAG 2.1 changes to multiple pages with single LifeRay and i want to simple replace some output html code. Modyfication after DOM is not good solution. Also I need to make a valid W3C HTML code. The simplest way to do this is replace HTML code generated by LifeRay.
thumbnail
Olaf Kock, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 6396 Join Date: 9/23/08 Recent Posts
Marcin Klinski:

Your answer did not help me. I need to put WCAG 2.1 changes to multiple pages with single LifeRay and i want to simple replace some output html code. Modyfication after DOM is not good solution. Also I need to make a valid W3C HTML code. The simplest way to do this is replace HTML code generated by LifeRay.
I've assumed that it won't be too helpful, as I don't necessarily agree with HTML modification to be "the simplest way".
It all will depend on the concrete changes that you'll need to do, and the purpose. "unnamed changes to multiple pages" isn't quite enough detail:
You might be able to change the JSPs that generate the output that you don't like
You might be able to update the tags
You might be able to filter/rewrite the content
You should let Liferay know what WCAG you need: If there's something that needs to be implemented, it'd be good to have it in the product.
But it all depends on what exactly you need.
Marcin Klinski, modified 3 Years ago.

RE: String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
In templates/portal_normal.vm in <head> section I have code:
$theme.include($top_head_include)
This will output header html with scripts, styles etc. I want to remove all string 'type="text/javascript"' from generated html.
There are some other includes for example $theme.include($content_include), $theme.include($body_bottom_include), etc.
Is there opportunity to change the code for all $theme.include at once ?
thumbnail
Christoph Rabel, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 1554 Join Date: 9/24/09 Recent Posts
Um, why don't you just hook (I am assuming Liferay 6.x here, since you use Velocity templates) top_head.jsp and do whatever is necessary there? Solving it that way looks a lot more sane to me.
Marcin Klinski, modified 3 Years ago.

RE: String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
Christoph, thanks but thats already done. There are still some text/java string in code. Someone can just answer to my question please ?
thumbnail
Christoph Rabel, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 1554 Join Date: 9/24/09 Recent Posts
Well, I guess, people are
a) reluctant because your solution (for whatever problem you have) looks "wrong"
b) Velocity knowledge has become rare
I still don't understand which problem you try to solve here, the "solution" you have found looks like a hack to me. That said:
You could maybe implement a filter, eg. like the StripFilter of Liferay:
https://docs.liferay.com/portal/6.2/javadocs-all/com/liferay/portal/servlet/filters/strip/StripFilter.html
http://www.liferaysavvy.com/2016/02/liferay-servlet-filter-hooks.html
Another idea: In Freemarker it would be possible to write the included content  into a variable, maybe that's possible in vm too. Then you could use search/replace.
Since you say you have already hooked the jsp and for some reason still can't get rid of the javascript tags you don't like: How about encapsulating and writing the whole jsp content into a string buffer instead of letting it write to the response output and replace it there?
Marcin Klinski, modified 3 Years ago.

RE: String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
Ok i will try with that Filter, thanks for reply.
Its sad that in PHP i just wrote 10 lines of code and that work but not in LifeRay of course.
In Joomla I have just put that code in index.php:

<?php
function callback($buffer1)
{
  $org='text/javascript';
  $rep='';
  $buffer1=str_replace($org,$rep,$buffer1);
  return $buffer1; 
}
ob_start("callback");
?>

And all occurences of 'text/javascript' on page just gone ! Fast and simple.
thumbnail
Olaf Kock, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 6396 Join Date: 9/23/08 Recent Posts
Marcin Klinski:

Ok i will try with that Filter, thanks for reply.
Its sad that in PHP i just wrote 10 lines of code and that work but not in LifeRay of course.
In Joomla I have just put that code in index.php:
...

You'd have a similar option in Liferay, however, I'm not aware of any problem that this is a good solution for. Not in Liferay, not in Joomla, and not in any other environment. You have the opportunity to fix the root cause, rather than applying some bandaid.
But if you insist on getting instructions for such a solution, and refuse to give us insight into your underlying problem, do you expect us to hand you the razor blades to hurt you (and the bandaid)? Or would you rather like a hint on how to solve it in a way that doesn't bite you in the next upgrade when you'll have to lift the bandaid?
Even if you'd be happy with bandaid, currently we're resisting public documentation of how to hurt yourself. Even though your solution seems so simple. I've learned the hard way that it's way more important to create maintainable code rather than quickfix bandaid.
Marcin Klinski, modified 3 Years ago.

RE: String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
Christoph Rabel:

How about encapsulating and writing the whole jsp content into a string buffer instead of letting it write to the response output and replace it there?

Exactly - I have that on my mind from the beggining but i dont know where to start emoticon

We have multiple $theme.include() in portal_normal.vm:

$theme.include($top_head_include)
$theme.include($body_top_include)
$theme.include($content_include)
$theme.include($body_bottom_include)
$theme.include($bottom_include)

I think that is clue to solve the problem - in what way we can buffer that output ?
Maybe there are some way to save that include to string, replace string and output string ?

We have some explanaition about includes here https://liferay.dev/forums/-/message_boards/message/10915987 .
In my opinion the best moment to replace strings is just before output single HTML line of code to browser.
thumbnail
Christoph Rabel, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 1554 Join Date: 9/24/09 Recent Posts
You said, you have already hooked/overridden top_head.jsp. You can do that there. Note: The code is from 7.0, so it is quite possible that you have to adapt the code to fit to the Liferay version you use.
This loads the original jsp into a buffer:
CharArrayWriterResponse customResponse  = new CharArrayWriterResponse(response);
request.getRequestDispatcher("/common/themes/top_head.jsp").forward(request, customResponse);
content = customResponse.getOutput();
// Do something, e.g. replace content, then write it to the output
out.write(content);

Or you could simply do something like this, assuming you have depoyed your own jsp:
$theme.include("${dir_include}/common/themes/my_top_head.jsp")
And in my_top_head.jsp you place something like the above code.
Marcin Klinski, modified 3 Years ago.

RE: String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
And thats the answer ! However I made the changes in portal.jsp and the code should look like this:

&lt;%@ taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %&gt;

<liferay-util:buffer var="html">
&nbsp;&nbsp; 
&nbsp;&nbsp; <liferay-util:include         page="/html/common/themes/portal_buffer.jsp" useCustomPage="<%= false %>" servletContext="<%= application %>"    />

</liferay-util:buffer>

&lt;% html = html.replaceAll("change_me", ""); %&gt;
&lt;%= html %&gt;

With this approach I dont have to edit all the include files.

More info about using liferay-util :buffer https://help.liferay.com/hc/en-us/articles/360018165611-JSP-Overrides-Using-OSGi-Fragments-#provide-the-overridden-jsp
thumbnail
David H Nebinger, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 14914 Join Date: 9/2/06 Recent Posts
Oh, Marcin, you're in for a world of hurt...

Sure this code snippet will work, but it means you need to render all of the HTML and cache it in order to do the replace before return. It is going to be a significant hit on your application server capacity and performance.


And sure, you can use this to strip all JS includes on the page, but this is going to make the page fail overall. Liferay uses Senna JS on a page to support loading page fragments rather than having to fully render complete pages before return. So your little edit will work to block loading JS, but it will also block loading content.

The part that stumps me? Even though I know I am not 100% current on WCAG 2.1 compliance, I'm pretty sure there is nothing in there that says JS cannot be used at all. It looks to me (although obviously I don't know for certain) like you want to strip JS includes in order to pass a compliance test or something without worrying what (if any) content was rendered on the page...
Marcin Klinski, modified 3 Years ago.

RE: String replace before / after html output

New Member Posts: 12 Join Date: 1/3/20 Recent Posts
I dont want to remove JS / CSS I just want to modify output code ...

&lt;% html = html.replaceAll(" type=\"text/javascript\"", ""); %&gt;
&lt;% html = html.replaceAll(" type=\"text/css\"", ""); %&gt;
&lt;% html = html.replaceAll("cellpadding=\"0\"", ""); %&gt;
&lt;% html = html.replaceAll("cellspacing=\"0\"", ""); %&gt;
&lt;% html = html.replaceAll("border=\"0\"", ""); %&gt;

... etc. to rid any errors in W3C / WCAG 2.1
thumbnail
David H Nebinger, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 14914 Join Date: 9/2/06 Recent Posts
There are no errors in WCAG in using any of these attributes when used correctly, but removing them would only provide a false negative when scanned using an automated tool. You likely would end up with an incorrect or poorly rendered DOM in a regular browser.
thumbnail
Christoph Rabel, modified 3 Years ago.

RE: String replace before / after html output

Liferay Legend Posts: 1554 Join Date: 9/24/09 Recent Posts
To add to what David said:
I still don't understand why you need to do this.  Are you sure that all the effort you put into it is worth it? Did you do tests with handicapped/blind people and they complained about issues? One of our clients actually did tests with Liferay 6.2 and they also had an expert there and none of this was ever mentioned.
We had to fix quite a few things like the hidden <h1>Navigation</h1>, change the markup generated by CKEditor and a lot of other things, but nobody cared about script types or table styles.
text/javascript and text/css are still valid, they are just the defaults and therefore it isn't necessary anymore. So,  they should only produce warnings, nothing more. And while cellspacing, cellpadding, ... are obsolete/deprecated and shouldn't be used anymore, they still are supported by all browsers (and probably will be for the foreseeable future).