Re: AMP pages with Tapestry

Carlos Montero Canabal <[email protected]>
Newsgroups gmane.comp.java.tapestry.user
Message-ID <[email protected]>
Thank you for the response.

AMP validation is very restrictive, so I need write <html amp> only, not <html amp=“amp”> or <html amp=“true”>.

So, I go for other fast solution which I use in other project to generate emails.

I will show the extended solution in my  tapestry5.dev-util.com <http://tapestry5.dev-util.com/> webapp, but as a short summary:

AmpPage.java

@Inject
private Block head, body;

...

AmpPage.tml

!doctype html>
<html
	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
	xmlns:p="tapestry:parameter">

<t:block t:id="head">
<head>
 ...
</head>
</t:block>

<t:block t:id="body">
<body>
 ...
</body> 
</t:block>
</html>

<t:delegate to="block:head"/>
<t:delegate to="block:body"/>

</html>

So AmpPage is the “real" page but it has invalid AMP attributes. So I created a AmpExporterPage:

public class AmpExporterPage {

	@Inject
	private PartialTemplateRenderer partialTemplateRenderer;

	@Inject
	private ComponentSource componentSource;

	@Inject
	private Request request;

	@Inject
	private Environment environment;

	public Object onActivate(final EventContext ec) {

		return new StreamResponse() {

			@Override
			public void prepareResponse(final Response response) {

			}

			@Override
			public InputStream getStream() throws IOException {

				final AmpPage ampPage = (AmpPage) componentSource.getPage(AmpPage.class);
				ampPage.onActivate(ec);
				ampPage.setupRender();
				final Block head = ampPage.getHead();
				final Block body = ampPage.getBody();
				
				environment.push(Heartbeat.class, new HeartbeatImpl());

				String markupHead = partialTemplateRenderer.render(head);
				String markupBody = partialTemplateRenderer.render(body);
				
				markupHead = markupHead.replace(" xmlns=\"http://www.w3.org/1999/xhtml\"", "");
				markupHead = markupHead.replaceAll("amp-boilerplate=\"amp-boilerplate\"", "amp-boilerplate");

				markupBody = markupBody.replace(" xmlns=\"http://www.w3.org/1999/xhtml\"", "");
				
				final StringBuilder sb = new StringBuilder();
				sb.append("<!doctype html><html amp>").append(markupHead).append(markupBody).append("</html>");
				final InputStream is = new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
				
				return is;
			}

			@Override
			public String getContentType() {
				return "text/html";
			}
		};
	}

}

I do a speed test and it takes around 40 milliseconds in generate de response, so it’s ok for me.

Regards

Carlos Montero


> El 30/11/2016, a las 14:06, Thiago H. de Paula Figueiredo <[email protected]> escribió:
> 
> On Tue, Nov 29, 2016 at 6:36 PM, Carlos Montero Canabal <
> [email protected]> wrote:
> 
>> Hello Tapestry users,
>> 
> 
> Hi!
> 
> 
>> 
>> I would like to create an amp version of my pages into a tapestry5.4
>> webapp. According to https://www.ampproject.org/
>> docs/reference/spec#required-markup <https://www.ampproject.org/
>> docs/reference/spec#required-markup> the root html only would be:
>> 
>> <html amp>
>> 
>> Tapestry5 make a xhtml compilation for the .tml, so I ask you if there is
>> any method to:
>> 
> 
> That's not correct. Tapestry 5 uses an XML parser for template files, and
> attributes without values aren't valid XML. You can try <html amp="amp">.
> 
> 
>> 1. Exclude de xhtml compilation for this pages
>> 2. Intercept the result and modify it to eliminate additional tags added
>> by Tapestry.
>> 3. Create a MarkupModel for AMPHtml?
>> 
> 
> Number 3 above is probably the best idea. You'll need to override the
> MarkupWriterFactory so you can use your AmpMarkupModel.
> 
> --
> Thiago
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.