diff --git a/documentation/src/main/java/controllers/templates/FragmentController.java b/documentation/src/main/java/controllers/templates/FragmentController.java new file mode 100644 index 000000000..73c7ff121 --- /dev/null +++ b/documentation/src/main/java/controllers/templates/FragmentController.java @@ -0,0 +1,42 @@ +/* + * #%L + * Wisdom-Framework + * %% + * Copyright (C) 2013 - 2014 Wisdom Framework + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +// tag::controller[] +package controllers.templates; + +import org.wisdom.api.DefaultController; +import org.wisdom.api.annotations.Controller; +import org.wisdom.api.annotations.Route; +import org.wisdom.api.annotations.View; +import org.wisdom.api.http.HttpMethod; +import org.wisdom.api.http.Result; +import org.wisdom.api.templates.Template; + +@Controller +public class FragmentController extends DefaultController { + + @View("page") + Template template; + + @Route(method = HttpMethod.GET, uri = "/templates/page") + public Result welcome() { + return ok(render(template, "username", "Clement")); + } +} +// end::controller[] diff --git a/documentation/src/main/java/controllers/templates/WelcomeController.java b/documentation/src/main/java/controllers/templates/WelcomeController.java new file mode 100644 index 000000000..0d27b32b2 --- /dev/null +++ b/documentation/src/main/java/controllers/templates/WelcomeController.java @@ -0,0 +1,42 @@ +/* + * #%L + * Wisdom-Framework + * %% + * Copyright (C) 2013 - 2014 Wisdom Framework + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +// tag::controller[] +package controllers.templates; + +import org.wisdom.api.DefaultController; +import org.wisdom.api.annotations.Controller; +import org.wisdom.api.annotations.Route; +import org.wisdom.api.annotations.View; +import org.wisdom.api.http.HttpMethod; +import org.wisdom.api.http.Result; +import org.wisdom.api.templates.Template; + +@Controller +public class WelcomeController extends DefaultController { + + @View("welcome") // <1> + Template template; // <2> + + @Route(method = HttpMethod.GET, uri = "/templates/welcome") + public Result welcome() { + return ok(render(template, "welcome", "Welcome on the Path to Wisdom")); // <3> + } +} +// end::controller[] diff --git a/documentation/src/main/resources/assets/index.ad b/documentation/src/main/resources/assets/index.ad index 74cb52ecc..f61d183b5 100644 --- a/documentation/src/main/resources/assets/index.ad +++ b/documentation/src/main/resources/assets/index.ad @@ -4,6 +4,7 @@ Version ${project.version} :description: This document is the documentation of the Wisdom Framework. :toc: right :sourcedir: ${project.basedir}/src/main/java +:resourcedir: ${project.basedir}/src/main/resources :assetdir: ${project.basedir}/src/main/assets :assetoutdir: ${project.basedir}/target/wisdom/assets :icons: font @@ -21,6 +22,7 @@ include::build-process.ad[] include::http.ad[] include::routing.ad[] include::response.ad[] +include::template.ad[] include::session-and-scope.ad[] include::json.ad[] include::file-upload.ad[] diff --git a/documentation/src/main/resources/assets/template.ad b/documentation/src/main/resources/assets/template.ad new file mode 100644 index 000000000..9c6e73058 --- /dev/null +++ b/documentation/src/main/resources/assets/template.ad @@ -0,0 +1,197 @@ +== Using Templates + +=== Template as a Service + +Just to makes you understand how the template system works, you should read these small paragraphs. + +Wisdom allows the integration of any template engine. By default, http://www.thymeleaf.org/[Thymeleaf] is provided. + Each template is exposed as a _service_ and can be injected in a controller using the `@View` annotation. This + pattern is used regardless the template engine you use. + +The `View` annotation is looking for a template with the specified name. It is equivalent to a regular `@Requires` +with a filter. + +=== The Thymeleaf Template Engine + +http://www.thymeleaf.org/[Thymeleaf] is an XML / XHTML / HTML5 template engine (extensible to other formats) that +can work both in web and non-web environments. It is really well suited for serving XHTML/HTML5 at the view layer of +web applications, but it can process any XML file even in offline environments. + +The main goal of Thymeleaf is to provide an elegant and well-formed way of creating templates. It allows you to create +powerful natural templates, that can be correctly displayed by browsers and therefore work also as static prototypes. + One of the main interest of Thymeleaf is a smooth collaboration with Web Designer. By using specific attributes on + HTML elements, you never interfere with the work of the web designers. They create the HTML page with whatever + structure, and CSS tricks, and you just identify the parts where you inject the data. + +It looks like this. As you can see, it's a pretty straightforward syntax supporting all the features you expect from a + template engine: variables, internationalization, iterations, layouts, fragments, object navigation, and much more. + +[source,xml,indent=0] +---- + + + + + + + + + + + + + +
NamePrice
Oranges0.99
+---- + +The complete documentation of Thymeleaf is available http://www.thymeleaf.org/doc/html/Using-Thymeleaf.html[here]. + +==== My First Template + +Thymeleaf templates are HTML files with the `.thl.html` extension, for example: `mytemplate.thl.html`. The +"mytemplate" is referred as the template name. Templates can be placed in: + +* `src/main/resources/templates` and are embedded in the application's Jar. +* `src/main/templates` and are in the distribution but not in the application's Jar file. + + +Whether or not your application is intended to be reused in several 'bigger' application determines the place of your + template files. + +Let's look at the following template, named `welcome.thl.html`: + +[source,xml,indent=0] +---- +include::{resourcedir}/templates/welcome.thl.html[] +---- + +The `th:text` attribute instructs the template engine to replace the content of the element by the `welcome` +value. This value is given as parameter to the template engine. + +So now in your controller, use the `@View` annotation to inject the template: + +[source,java,indent=0] +---- +include::{sourcedir}/controllers/templates/WelcomeController.java[tags=controller] +---- +<1> Use the `@View` annotation and indicate the template name +<2> The injected field must use the `Template` type +<3> Use the `render(template, ...)` methods to render the template + +You can render the template using the `render` methods: + +* `render(Template template)` asks the template engine to render the template without input variables +* `render(Template template, Map params)` inserts the given parameters to the template +* `render(Template template, Object... params)` proposes an easier way to pass parameters. However, one parameter +over two must be a string (the parameter name), while the following is the value: + + return ok(render(template, "welcome", "hello", "age", 1, "colors", new String[] {"red", "blue"})); + +The `render` method is wrapped within a `ok` method indicating the type of response. Obviously, you can use any other + type of result. + +Some values are automatically given to the template engine: + +* the parameters of the request +* the values stored in the session +* the value stored in the flash scope + +==== Some Thymeleaf constructions + +Now we have seen how template can be used, let's see some general construction patterns we use in templates: + +**Variable:** + +

this will be replace by the variable

+

this will be replace by the variable (unescape so won't remove the contained HTML elements) +

+ +**Internationalized variable:** + +

this will be replace by the variable using the request locale

+ +WARNING: Internationalized value are directly retrieved from the internationalization service from Wisdom. + +**Iteration:** + +You can iterate on collections, arrays, maps... + + + + Onions + 2.41 + yes + + +**Conditionals:** + + + true or false according to the prod.isStock value + + + display this link comments if not empty + + +TIP: Check the http://www.thymeleaf.org/doc/html/Using-Thymeleaf.html[Thymeleaf documentation] to find more. + +==== Fragments and Layout + +Templates are generally used to create layouts. Thymeleaf allows to create _fragments_, and to include them in the +_main_ template. + +Fragments are identified part of a template. For example, the following snippet defined two fragments: `my-content` +and `sub-content`. + +[source,xml,indent=0] +---- +include::{resourcedir}/templates/content.thl.html[] +---- + +Fragments can be included either using: + +*`th:include`: include the fragment 'under' the element using the directive +*`th:replace`: replace the element using this directive with the fragment content + +The value of theses directive is formed by `name_of_the_template_defining_the_fragments :: fragment_name`. For +example, if the previous fragment are defined in `content.thl.html`, including them would look like: + +[source,xml,indent=0] +---- +include::{resourcedir}/templates/page.thl.html[] +---- + +TIPS: fragments can use any variable given to the template engine. + +==== Using the router from the template + +A template can use a special object named `#routes` to retrieve the url of action methods. In the following snippet, +the `action` attribute is assigned to the url of the `upload` method of the current controller (the controller having + requests the template rendering). + +[source,xml,indent=0] +---- +th:attr="action=${#routes.route('upload')}" +---- + +You can also ask for the url of an action method receiving parameters: + +[source,xml,indent=0] +---- +th:attr="action=${#routes.route('upload', 'param', 'value', 'param2', 'value2')}" +---- + +Finally, you can target method from other controllers with: + +[source,xml,indent=0] +---- +th:attr="action=${#routes + .route(`org.acme.controller.MyOtherController`, 'upload', 'param', 'value')}" +---- + +If the route cannot be found, the template rendering fails. + + + + + + diff --git a/documentation/src/main/resources/templates/content.thl.html b/documentation/src/main/resources/templates/content.thl.html new file mode 100644 index 000000000..23a65236b --- /dev/null +++ b/documentation/src/main/resources/templates/content.thl.html @@ -0,0 +1,18 @@ + + + + + This is a fragment + + + +
+

Hello my name

+
+ +
+

This is the first step to Wisdom, follow us...

+
+ + + \ No newline at end of file diff --git a/documentation/src/main/resources/templates/page.thl.html b/documentation/src/main/resources/templates/page.thl.html new file mode 100644 index 000000000..2386c66e8 --- /dev/null +++ b/documentation/src/main/resources/templates/page.thl.html @@ -0,0 +1,20 @@ + + + + + My Main Page + + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/documentation/src/main/resources/templates/welcome.thl.html b/documentation/src/main/resources/templates/welcome.thl.html new file mode 100644 index 000000000..1e63359b1 --- /dev/null +++ b/documentation/src/main/resources/templates/welcome.thl.html @@ -0,0 +1,13 @@ + + + + + Follow the Wisdom Path + + + +

Hello

+ + + \ No newline at end of file