AEM - Make the rendered html prettier/more readable | Community
Skip to main content
VictorToledo_
Level 3
April 16, 2020
Solved

AEM - Make the rendered html prettier/more readable

  • April 16, 2020
  • 3 replies
  • 10172 views

 

Hello everyone,

does anyone know if there is a way to make the rendered html more readable?. I mean, properly tabulated and ordered.
I'm using sigthly and the markup of each component is well tabulated on the app code.
But I understand that the rendering engine is modifying that indentation and rendering an html that is not ordered and indenting.

an example

<html> <head></head> <body> <div><span> </span></div> </body> <footer> <div> </div> </footer> </html>

instead of something like this

 

<html> <head></head> <body> <div> <span></span> </div> </body> <footer> <div></div> </footer> </html>

 

Is that posible without add an extra html processor or something similar to that?

Thanks in advance

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by VictorToledo_

Well finally i have a possible approach.

Thanks @joerghoh and @briankasingli for all your help!!
here is the filter that i created and seems to be working. And i would like to share the solution and know your opinions. 

import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Service; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; @Component(immediate = true) @Service(Filter.class) @Properties({ @Property(name = "sling.filter.scope", value = "REQUEST"), @Property(name = "sling.filter.pattern", value = ".*\\.html"), @Property(name = "service.ranking", value = "700") }) public class HTMLFormatterFilter extends SlingAllMethodsServlet implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // create a response wrapper to capture the original response CharResponseWrapper wrappedResponse = new CharResponseWrapper( (HttpServletResponse)response); chain.doFilter(request, wrappedResponse); // modify the response with the formatted html byte[] bytes = wrappedResponse.getByteArray(); if (wrappedResponse.getContentType().contains("text/html")) { String out = new String(bytes); Document doc = Jsoup.parse(out); response.getOutputStream().write(doc.toString().getBytes()); } else { response.getOutputStream().write(bytes); } } @Override public void destroy() { // Do nothing } private static class ByteArrayServletStream extends ServletOutputStream { ByteArrayOutputStream baos; ByteArrayServletStream(ByteArrayOutputStream baos) { this.baos = baos; } public void write(int param) throws IOException { baos.write(param); } } private static class ByteArrayPrintWriter { private ByteArrayOutputStream baos = new ByteArrayOutputStream(); private PrintWriter pw = new PrintWriter(baos); private ServletOutputStream sos = new ByteArrayServletStream(baos); public PrintWriter getWriter() { return pw; } public ServletOutputStream getStream() { return sos; } byte[] toByteArray() { return baos.toByteArray(); } } private static class CharResponseWrapper extends HttpServletResponseWrapper { private ByteArrayPrintWriter output; private boolean usingWriter; public CharResponseWrapper(HttpServletResponse response) { super(response); usingWriter = false; output = new ByteArrayPrintWriter(); } public byte[] getByteArray() { return output.toByteArray(); } @Override public ServletOutputStream getOutputStream() throws IOException { // will error out, if in use if (usingWriter) { super.getOutputStream(); } usingWriter = true; return output.getStream(); } @Override public PrintWriter getWriter() throws IOException { // will error out, if in use if (usingWriter) { super.getWriter(); } usingWriter = true; return output.getWriter(); } public String toString() { return output.toString(); } } }

 

3 replies

joerghoh
Adobe Employee
Adobe Employee
April 17, 2020

Technically it's possible, but as the indentation is only relevant for a human (for better readability when debugging) and not for a machine/browser, why don't you reformat the HTML when you need it?

VictorToledo_
Level 3
April 22, 2020
Hi @joerghoh, yes i know, this is a client requirement, they want to have a "better" html for debugging propose and compare with their Front End code. I just trying to test some posible solution and see if it makes sense or we will have a performance decrease
BrianKasingli
Community Advisor and Adobe Champion
Community Advisor and Adobe Champion
April 18, 2020

If you wish to pretty print CSS, JS, HTML you can utilise the JavaScript library, js-beautify. Although this solution requires customisation to your JavaScript logic.

Example Code:

let formattedHTML = window.jsbeautifier.beautify('your HTML,CSS,JS string');

Documentation can be found here for js-beautify https://www.npmjs.com/package/js-beautify

 

VictorToledo_
Level 3
April 21, 2020
Hi @briankasingli, thanks for your response. But i would like to it on the render process and not add an extra process on the client side.
VictorToledo_
VictorToledo_AuthorAccepted solution
Level 3
April 24, 2020

Well finally i have a possible approach.

Thanks @joerghoh and @briankasingli for all your help!!
here is the filter that i created and seems to be working. And i would like to share the solution and know your opinions. 

import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Service; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; @Component(immediate = true) @Service(Filter.class) @Properties({ @Property(name = "sling.filter.scope", value = "REQUEST"), @Property(name = "sling.filter.pattern", value = ".*\\.html"), @Property(name = "service.ranking", value = "700") }) public class HTMLFormatterFilter extends SlingAllMethodsServlet implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // create a response wrapper to capture the original response CharResponseWrapper wrappedResponse = new CharResponseWrapper( (HttpServletResponse)response); chain.doFilter(request, wrappedResponse); // modify the response with the formatted html byte[] bytes = wrappedResponse.getByteArray(); if (wrappedResponse.getContentType().contains("text/html")) { String out = new String(bytes); Document doc = Jsoup.parse(out); response.getOutputStream().write(doc.toString().getBytes()); } else { response.getOutputStream().write(bytes); } } @Override public void destroy() { // Do nothing } private static class ByteArrayServletStream extends ServletOutputStream { ByteArrayOutputStream baos; ByteArrayServletStream(ByteArrayOutputStream baos) { this.baos = baos; } public void write(int param) throws IOException { baos.write(param); } } private static class ByteArrayPrintWriter { private ByteArrayOutputStream baos = new ByteArrayOutputStream(); private PrintWriter pw = new PrintWriter(baos); private ServletOutputStream sos = new ByteArrayServletStream(baos); public PrintWriter getWriter() { return pw; } public ServletOutputStream getStream() { return sos; } byte[] toByteArray() { return baos.toByteArray(); } } private static class CharResponseWrapper extends HttpServletResponseWrapper { private ByteArrayPrintWriter output; private boolean usingWriter; public CharResponseWrapper(HttpServletResponse response) { super(response); usingWriter = false; output = new ByteArrayPrintWriter(); } public byte[] getByteArray() { return output.toByteArray(); } @Override public ServletOutputStream getOutputStream() throws IOException { // will error out, if in use if (usingWriter) { super.getOutputStream(); } usingWriter = true; return output.getStream(); } @Override public PrintWriter getWriter() throws IOException { // will error out, if in use if (usingWriter) { super.getWriter(); } usingWriter = true; return output.getWriter(); } public String toString() { return output.toString(); } } }