This is an extension of Vaadin 14.X PolymerTemplate
class. It enables server-side access to properties defined in the template file, which is normally not possible. It also attempts to solve a few general issues with templates.
SuperTemplate
is most likely not production ready. Due to complexity of Vaadin Flow it will most likely never be production ready.
Here are the limitations:
- it only works for fields that are annotated in Java with
@Id
and have anid
attribute set in the template file (in Designer terms - components that are linked to the Java companion file); - it only supports passing of attributes present in the HTML markup when there is a corresponding setter that accepts
String
; for example,<my-component attr="value">
will callpublic void setAttr(String s)
- if the method is missing, nothing will happen.
Maven dependency:
<dependency>
<groupId>org.vaadin.miki</groupId>
<artifactId>super-template</artifactId>
<version>0.2.1</version>
</dependency>
Maven repository:
<repository>
<id>vaadin-addons</id>
<url>https://maven.vaadin.com/vaadin-addons</url>
</repository>
Follow instructions: https://github.com/vaadin-miki/super-template/packages
Simply extend your custom template Java class from SuperTemplate
instead of PolymerTemplate
.
This only works with Vaadin Designer version 4.4.2 and above (released 25th of March, 2020).
Locate your .vaadin/designer/project-settings.json
file. Add the following property:
"--design.companion.basetype": "org.vaadin.miki.supertemplate.SuperTemplate<{{ClassName}}.{{ClassName}}Model>"
More information: vaadin/designer#2257
The constructor of SuperTemplate
delegates the magic of initialising the fields to TemplateProcessor
passed as a constructor argument. Unless specified, SimpleTemplateProcessor
will be used.
Please consult the file SuperTemplateTest
and corresponding TestView
and VaadinView
to get a glimpse of how things work.
In general, the processor receives a template object of type PolymerTemplate
. Then:
- it reads the template root - the HTML that corresponds to the template - from the proper
.js
file; - it goes through all fields annotated with
@Id
declared in the template class.
For each field:
- it fetches the value of the field (by using reflection and
setAccessible
to go aroundprivate
) - the constructor ofPolymerTemplate
creates an empty, default object of the correct type; - it locates the corresponding HTML element inside the template root;
- it goes through each attribute of that element;
- it applies any extra configuration (see the next section).
For each attribute:
- it locates a public setter with a matching name (for attribute
foo
it will besetFoo
) and exactly one parameter of typeString
, found in the class of the value (so if the field is of typeTextField
, it will look inTextField.class
) - it calls that setter, passing the
String
found in the attribute.
Unless changed, after setting each field according to its attributes, the object will go through extra configuration. This is defined by TemplateFieldConfigurator
and by default those are available:
- if the value implements
HasText
, itssetText
method will be called with the text found in the element; - if the value is an
Icon
, its server-sideIcon
will be changed to reflect the one specified in the element; - if the value is a
Button
and the element has an icon, the icon will be set on the server side; - if the value is a
Grid
and it is declared in the file asGrid<BeanType>
, the field will be configured as ifnew Grid<>(BeanType.class)
was called; in addition columns can be added (see below).
The default configurators can be skipped by:
- passing a
false
flag to theSuperTemplate
constructor - for that particular template only; - calling
TemplateFieldConfigurators.DEFAULT_CONFIGURATORS.clear()
- for all templates (does not apply retroactively to templates that were created before executing that code).
Under certain conditions columns can be specified in the design. First of all, the Grid
must be typed in Java (so @Id("id-of-grid") private Grid<MyBean> grid
). Then:
- (recommended) columns from
data-columns
attribute onvaadin-grid
, if that attribute is present; the list should be space-separated list of properties, and for each property server-side object will useaddColumn(propertyName)
- (experimental) columns from
vaadin-grid-column
are taken if they have an attributedata-column
; again, server-side object will useaddcolumn(name)
Feel free to file an issue if there are problems with either of the approaches.
Unless changed, TemplateProcessor
will receive all TemplateFieldConfigurator
s present in TemplateFieldConfigurators.DEFAULT_CONFIGURATORS
. That list is modifiable, so whatever gets added or removed will affect all templates created afterwards.
The constructor of SuperTemplate
accepts a varargs parameter of TemplateFieldConfigurator
s. Those will be added in addition to the default ones, but only for that template.
Feel free to create issues or PRs for missing functionality.