xmlet / htmlflow Goto Github PK
View Code? Open in Web Editor NEWHtmlFlow Java DSL to write typesafe HTML
Home Page: https://htmlflow.org/
License: MIT License
HtmlFlow Java DSL to write typesafe HTML
Home Page: https://htmlflow.org/
License: MIT License
It seems that even when I use the Dynamic View:
.dynamic(el -> el.text(model.title))
The output is not safe for viewing?
My example is that a user has entered some XSS in the title, such as: <script>alert('1')</script>
.
Am I using the library wrong?
If you are an HtmlFlow user then you should be interested about the release 2.0 news. HtmlFlow version 2.0 has full support for all existing HTML5 elements and attributes. Moreover all attributes are strongly typed with enumerated types which restrict accepted values. Now HtmlFlow API is constructed with the support of an automated framework xmlet based on an XSD definition of the HTML5 syntax and rules (soon HtmlFlow will be transferred to xmlet organization).
Thus we remove the package htmlflow.attributes
and htmlflow.elements
, which have been replaced by the types defined in org.xmlet.htmlapi
library. This new approach forces HtmlFlow API to keep consistency along all methods use. You may check the HtmlFlow development branch to verify the main changes to the API (the Readme.md examples and unit tests have been updated according to the new API). Please let me know about your issues if you do not agree with some change.
So version 2.0 introduces the following core changes:
All fluent methods have no parameters. For example, formerly when we were specifying the text node of a paragraph or heading (such as, .p("my text")
or .h2("my title")
), now we have to chain an invocation to the text()
method (such as, .p().text("my text")
or .h2().text("my title")
).
All fluent methods now return the created element. Whenever we need to proceed with the parent element we may chain an invocation to .º()
. For example, formerly when we wrote .div().br().p()
now we have to write .div().br().º().p()
. Moreover the statement .div().br().p()
not even compiles, because HTML does not allow a paragraph inside a break line element, so we will get a
compilation error.
Except for .text()
which does not create an element but a text node instead, the rest of fluent methods return the created element. For .text()
it returns the element containing the text node (the this
).
The new method º()
returns the parent of an element. This method is strongly typed so it returns exactly an instance of T
where T
is the concrete class which extends Element
. This is an important issue to respect the HTML structure and rules.
Indentation. Now every element or text node is printed in a new line. Formerly there were some exceptions, namely for text nodes which were printed in the same line of the beginning tag.
These exceptions were removed.
If you do not like the HtmlFlow print approach you are free to implement your own org.xmlet.htmlapi.ElementVisitor
. See the htmlflow.HtmlVisitor
implementation as a guideline.
Removed default implementation of method write()
in interface HtmlWriter<T>
.
To all HtmlFlow users @andych008 @dgautier @bignsyd @kenji-getpowered @eorahil @tommywu23
@srekapalli @sndp2510 @vbrknu @alacui @mavarazy @ItisSoham @tenebrius @ohtejera @CapDuan @DNagorny @maksimu @extremely-idle @christhompson121 @luisf11 @AlburIvan @mertserezli @YuriiChukhrai @beatngu13 @prinal10 @xpbtmusic @devaaron @lcduarte
I'm trying to migrate a use made using thymleaf to a view using html flow.
In a table of user I discovered that we can't nest dynamic bloc.
.tbody()
.dynamic(body -> {
users.stream().forEach((user) -> {
body
.tr()
.td()
// should switch on presence of user.getImage() == null
// .img().attrClass("ui image avatar").attrSrc(String.format("data:image/png;base64,%s", user.getImageAsBase64())).__()
.__()
.__();
});
})
The error message is really clear
You are already in a dynamic block! Do not use dynamic() chained inside another dynamic!
Thanks for that.
I assume that there is a technical reason for this limitation. I don't question them, rather I'd like some guidance on how this kind of stuff should be address by a user of htmlflow.
Regards
Wrong use of DynamicView! You should provide a model parameter or use a static view instead! method render(T mode), How to define T mode???
Support other kinds of outputs and make setPrintStream optional, whit a default output.
Today HtmlWriterComposite and HtmlSingleElement are compromised with the setPrintStream.
Also, evaluate support to javax.swing.text.html.HTMLDocument.
use case:
taskView.body()
.div()
.classAttr(divClass)
.idAttr(divId)
.addAttr("toto", "tutu").form("/action.do");
taskView.body()
.div()
.idAttr("id2")
.addAttr("toto", "tutu").form("/action2.do");
Proposition
public class HtmlView<T> extends HtmlWriterComposite<T, HtmlView<T>>{
public HtmlHead<T> head(){return addChild(new HtmlHead<T>());}
private HtmlBody body = null;
public HtmlBody<T> body() {
if (body == null) {
body = addChild(new HtmlBody<T>());
}
return body;
}
HtmlTemplate
instances can be processed before-hand with a mock model object (through a dynamic proxy) that intercepts all calls.
Thus, all static parts can be processed and stored on call to view()
. Any, call to the model out of a dynamic scope it is intercepted by the mock object and throws an exception alerting for the illegal use.
This would avoid control of the first visit in HtmlVisitorCache
.
HtmlFormInputSubmit should be a single element instead of HtmlWriterComposite
Hi,
I think i am missing something but can you please help me understand how can i create nested table.
Something like below? I tried adding table to HtmlTd but that didn't work.
<table cellpadding="0" cellspacing="0">
<tr class="top">
<td colspan="2">
<table>
<tr>
<td class="title">
<img src="logo.png" style="width:100%; max-width:300px;" />
</td>
<td>
Invoice #: 123<br />
Created: January 1, 2015<br />
Due: February 1, 2015
</td>
</tr>
</table>
</td>
</tr>
</table>
Hi @fmcarvalho,
I really like your library for easily creating html docs. In my case I use it for a mail parsing component. Now the problem with version 1.1 (but not 1.0):
My mail parsing component is a maven dependency like yours. I have an application "main" which only uses my mail parsing component as dependency. I checked the resulting "main.war" and there was my mail parser jar as well as your htmlflow jar.
When I try to create a new Instance of my mail parser, which also invokes to create a instance of HtmlView<?>, an UncheckedIOException is thrown that it couldn't find HtmlView-Header.txt. Just for clarification the structure how everything is deployed within main.war:
--META-INF
--static
--WEB-INF
----classes
----lib
------mailParser1.0.jar
------htmlflow1.1.jar
I am still trying to debug it but for the moment I can tell that ClassLoader.getSystemResource("templates/HtmlView-Header.txt")
(related to #16) is not looking at the right point to find the "HtmlView-Header.txt" because of the setup of your project being within another dependency.
Note:
The tests within the mail parser dependency can successfully create a mail parser instance.
Add other static methods to create alternative partial views rather than html
.
Add repository with usage examples
Several errors. Should use try-with-resources. Remove the Task model from the first example.
Use a write method without the int indentation parameter.
Discuss the possibility of using the elements defined in org.w3c.dom.html Java package.
To avoid limitations on fluent API use the root
field of HtmlView
should be of type Html<Element>
public Head<Html<Element>> head(){
return root.head();
}
public Body<Html<Element>> body(){
return root.body();
}
This project really rocks!!!
well done
Hi fmcarvalho,
very nice framework !!
I have one issue could you please help. i am unable to add span element inside the body how can i achieve the following :
`
<title>welcome</title> `My goal is to produce a table with the layout kinda like this:
The code used for producing this output is:
public static void saveWeek(String weekNum, ArrayList<SkemaLektion> man, ArrayList<SkemaLektion> tir) {
HtmlView<Iterable<SkemaLektion>> taskView = new HtmlView<Iterable<SkemaLektion>>();
taskView
.head()
.title(weekNum)
HtmlTable<Iterable<SkemaLektion>> table = taskView
.body().classAttr()
.heading(1, weekNum)
.div()
.table().classAttr(table);
HtmlTr<Iterable<SkemaLektion>> headerRow = table.tr();
headerRow.th().addAttr("rowspan", "9999").text("MANDAG");
headerRow.th().text("Tid");
headerRow.th().text("Enhed");
headerRow.th().text("Fag");
headerRow.th().text("Lek Nr");
headerRow.th().text("Aktivitet");
headerRow.th().text("Leder");
headerRow.th().text("Påklædning");
headerRow.th().text("Sted");
table.trFromIterable(
skemaLektion -> skemaLektion.getLektid().getText(),
skemaLektion -> skemaLektion.getEnhed().getSelectionModel().getSelectedItem(),
skemaLektion -> skemaLektion.getFag().getSelectionModel().getSelectedItem().toString(),
skemaLektion -> skemaLektion.getLekNummer().getSelectionModel().getSelectedItem().toString(),
skemaLektion -> skemaLektion.getAktivitet().getText(),
skemaLektion -> skemaLektion.getAnsvar().getText(),
skemaLektion -> skemaLektion.getPaaklaedning().getText(),
(SkemaLektion skemaLektion2) -> skemaLektion2.getLokation().getText());
try (PrintStream out = new PrintStream(new FileOutputStream(weekNum + ".html"))) {
taskView.setPrintStream(out).write(man);
taskView.setPrintStream(out).write(tir);
Desktop.getDesktop().browse(URI.create(weekNum + ".html"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
My question is how do so that only the table content is added again and not the whole document and the second "Mandag" is changed to "Tirsdag"? (Monday and tuesday.
Kind regards
Create a maven artifact
Upgrade to Java 1.8 and update all examples.
can you please help how I can display a content on message box, once user clicks on data in a cell of table using your framework.
I'm generating an HTML file with <pre>
elements. The first line of the content is incorrectly indented. Is there an option to prevent that?
hi
what is the license?
gpl, lgpl, bsd?
thank you
Does this project plan to produce inline js or inline css.
Using thymleaf it happens from time to time that I need to produce in my inline js base on some variable extracted from the model.
Use new version 2.0 binder support to test attributes binding.
I am using HTML Flow in our project at Zinfinity, can you please tell me if we can use If Else block in HTML ?
The upcoming paper about HtmlFlow includes a couple of use cases comparing dialects between Thymeleaf and HtmlFlow, which should be included here in documentation.
Add a write method without indentation parameter.
Fix HtmlView to HTML5 requirements
I'm trying to figure out the correct way to use this htmlflow as a replacement for thymleaf.
The partial idea is already adressed here, but it seams to me that the partial are upside down.
Maybe that's just my perception that is out of wack at least in the documentation.
The way I intend to use partial is much closer to what was done with SelectField
in the petClinic.
But there it's in a folder called fragment.
What is the distinction you are doing between fragment and partial ? Would be welcome a PR on the documentation of partial ?
In order to setup an HtmlFlow template it would be useful to have a translator tool – Flowifier – that is able to convert an HTML document into the equivalent template definition with HtmlFlow.
This RFP aims to discuss implementation approaches and requirements for Flowifier.
Some of the topics under discussion (not limited):
Add a Maven pom and maybe remove support to Ant.
Some unit-tests are not passing.
Support some how load an existing HTML source and then proceed with HtmlFlow on a given element.
@kenji-getpowered I just notice right now that getElementName is a "basic empty name method.". Shouldn't it be abstract, instead of empty?
Regarding the sample spring application https://github.com/xmlet/spring-petclinic already integrated with HtmlFlow, enhance it with a ViewResolver. This resolver must obey with the strongly typed approach of HtmlFlow and avoid String to map views.
Hi
A great possibility would be to have the possibility to set a Css class property and th Css ad property on elements.
A possible solution would be
The HtmlWriterComposite could have a get/setCssId and get/setCssClass
So all elements could add them at doWriteBefore for instance
@OverRide
public void doWriteBefore(PrintStream out, int depth) {
out.println("<div" + this.getCssId + " "+this.getCssClass()" >");
tabs(depth+1);
}
Well I did not think it thouroughly but, in my opinion, it would be really useful
Hi following error i am getting while doing
mvn clean install
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /Users/mohsin/Documents/dev/springdev/workspace/HtmlFlow/src/test/java/htmlflow/test/views/HtmlTables.java:[98,21] cannot find symbol
symbol: method div()
location: interface org.xmlet.htmlapifaster.Element
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.226 s
[INFO] Finished at: 2019-03-16T14:55:58+05:30
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project htmlflow: Compilation failure
[ERROR] /Users/mohsin/Documents/dev/springdev/workspace/HtmlFlow/src/test/java/htmlflow/test/views/HtmlTables.java:[98,21] cannot find symbol
[ERROR] symbol: method div()
[ERROR] location: interface org.xmlet.htmlapifaster.Element
[ERROR]
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
Release 3.0 will introduce deep changes on end use API and also significantly improvement on performance. Check major major changes on this branch: https://github.com/xmlet/HtmlFlow/tree/readme-for-release-3
Improved performance. HtmlFlow is on this date the most performant template engine and Java DSL for HTML.
Replaced the method º()
by __()
.
New static factory methods view()
of the new classes DynamicHtml
and StaticHtml
Removed the static factory methods html()
, head()
and div()
from HtmlView
.
Html code is emitted on the fly when the methods of HtmlApi
(e.g. html()
, div()
, h1()
, etc)
are called.
Now HtmlView
is just a container of a template function and an ElementVisitor
, which establishes
the HTML output format.
All emitted HTML is cached.
Data binding requires the use of new method dynamic()
to avoid caching. Otherwise, the context objects are ignored on further renders.
New method of()
to enable the use of other methods in the fluent chain.
New addPartial()
to enable the reuse of same HTML template function with different HTML fragments.
Removed the method binder()
. The role of this method is replaced by the concept of template function which receives the context object U
that is captured and used whenever is needed, such as in dynamic()
.
@andych008
@dgautier
@bignsyd
@kenji-getpowered
@tommywu23
@srekapalli
@sndp2510
@vbrknu
@alacui
@mavarazy
@tenebrius
@ohtejera
@CapDuan
@DNagorny
@maksimu
@ross-moug
@christhompson121
@luisf11
@AlburIvan
@mertserezli
@YuriiChukhrai
@beatngu13
@prinal10
@Buchx
@thadumi
@davidalexsoares
@jedcua
@navneet-kumar
@lcduarte
Add writeAsync(AsynchronousSocketChannel)
to HtmlView
API
HtmlSingleElement must not extend HtmlWriterComposite. We should create a base class and include the code from HtmlWriterComposite that is required by the HtmlSingleElement.
Hi @fmcarvalho
thank you for you template engine. Very interesting approach.
Can you provide a standard example Petclinic implemented with "login-registration" (spring security) ? PETCLINIC
The developer need to know how to implement the standard functionality with HtmlFlow.
Read more about petclinic or pet store app:
Regards
So I had everything working using render(), when I ran into issues and decided to change to output into a file when I realized just adding the printStream and calling write at the end didn't work.
Debugging the code I realized all the builder code is executing everything eagerly building some StringBuilder as you add html tags, and all the buffer gets discarded as soon as I call setPrintStream.
So the only solution I found was to set the printStream right before I start building the Html:
var view = (HtmlView<?>) StaticHtml.view().setPrintStream(ps); var html = view.html();
But not sure the method returns a less specific type, thats why I had to add the cast, but in the end it works.
Is this how it is supposed to work? because from the documentation I assumed you could decide how to render it at the end, and so I assumed everything would run lazily like Java streams.
I am creating a dynamic html with dynamic content to send it by email.
I am using spring boot with Java 8 and I would like to add localize text from message.properties depending the language of the customer.
Is there a way to achieve that when I render dynamically the html?
Hey! I'd love to use your library, but I'm not sure how to do some things.
What's the procedure for adding a table?
I noticed that none of your test cases are in the repo. If you've written them, maybe they'd make a good reference for those who want to use it?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.