FreeMarker je šablonovací systém pro Javu. Je navržen s ohledem na čistotu návrhu podle vzoru MVC. Používá se především pro pohled (view) v prostředí Java Servlets, ale může být použit pro generování textů v libovolném prostředí – např. generování statických webových stránek, konfiguračních souborů, e-mailů…

FreeMarker
Logo
VývojářJonathan Revusky, Attila Szegedi, Dániel Dékány, a další
Aktuální verze2.3.32 (12. ledna 2023)
Operační systémmultiplatformní (Java)
Vyvíjeno vJava
Typ softwarušablonovací systém
LicenceBSD-like licence
Webfreemarker.org
Některá data mohou pocházet z datové položky.

FreeMarker na rozdíl od JavaServer Pages neumožňuje přímé vkládání Java kódu do šablon a šablony jsou interpretovány až za běhu (nejsou předkompilovány do Java bajtkódu). FreeMarker umožňuje automatický výběr šablony podle zvoleného jazyka – např. při požadavku na stránku index.ftl pro jazyk cs_CZ se postupně hledají šablony index_cs_CZ.ftl, index_cs.ftl a index.ftl. FreeMarker rovněž umožňuje používat jakýsi systém dědičnosti šablon. Např. v následující struktuře souborů se při vložení (include) obsahu souboru */menu.ftl do souborů /index.ftl a /aktuality.index.ftl vloží soubor /menu.ftl, do souboru /e-shop/index.ftl se ale vloží /e-shop/menu.ftl:

/index.ftl
/menu.ftl
/aktuality/index.ftl
/aktuality/menu.ftl
/e-shop/index.ftl
/e-shop/menu.ftl

Ve FreeMarkeru lze vytvářet knihovny šablon, které je následně možné naimportovat do jiné šablony. Při importu je určen jmenný prostor knihovny, takže při importu více knihoven s prvky se shodnými názvy nedochází ke konfliktu jmen.

Příklad

editovat

Šablona ve FreeMarkeru:

<html>
<body>
<h1>Ahoj světe!</h1>
<p>Tito ${lide?size} lidé zdraví svět:</p>
<ul>
[#list lide as osoba]
 <li>${osoba.jmeno} ${osoba.prijmeni} (${osoba.vek} let) z obce ${osoba.obec}</li>
[/#list]
</ul>
</body>
</html>

Model – Java objekty:

public class Osoba {
 public Osoba(String jmeno, String prijmeni, int vek, String obec)
 public String getJmeno() {  }
 public String getPrijmeni() {  }
 public int getVek() {  }
 public String getObec() {  }
}

List<Osoba> osoby = new LinkedList<osoba>();
osoby.add(new Osoba("Marie", "Černá", 32, "Ostrava"));
osoby.add(new Osoba("František", "Novák", 54, "Brno"));
osoby.add(new Osoba("Natálie", "Zajícová", 72, "České Budějovice"));

Map<String, Object> root = new HashMap<String, Object>();
root.put("lide", osoby);
//root je předáno FreeMarkeru jako datový model

Po spojení šablony a datového modelu je vygenerován výstup:

<html>
<body>
<h1>Ahoj světe!</h1>
<p>Tito 3 lidé zdraví svět:</p>
<ul>
 <li>Marie Černá (32 let) z obce Ostrava</li>
 <li>František Novák (54 let) z obce Brno</li>
 <li>Natálie Zajícová (72 let) z obce České Budějovice</li>
</ul>
</body>
</html>

Datový model - Java

editovat

Datový model pro šablonu FreeMarkeru může obsahovat tři typy objektů – skalár (text, číslo, datum a čas, logická hodnota), sekvenci (seřazený seznam objektů) nebo mapu (klíče a odpovídající hodnoty). Skaláry je možné přímo vypisovat do výstupu, případně je formátovat (získat část řetězce, formátovat datum a čas nebo číslo). Sekvenci je možné procházet pomocí příkazu [#list seznam as položka]…[/#list]. Mapy je možné procházet pomocí tečkové notace mapa.klíč. FreeMarker poskytuje mapování ze standardních Javovských objektů (řetězce, čísla, logické hodnoty, datum a čas) na skaláry, kolekce mapuje na sekvence a mapy a JavaBeany mapuje na mapy – názvy vlastností (properties) JavaBeanu jsou mapovány jako klíče mapy. Toto mapování může programátor předefinovat a přidat mapování vlastních objektů – takto je např. ve FreemarkerServletu mapován kontext atributů HTTP požadavku, HTTP session a aplikace (servlet kontextu) mapován na mapu Freemarkeru. Jako datový model šablony se Freemarkeru předává mapa objektů.

Šablony

editovat

Šablony FreeMarkeru umožňují vypisovat a formátovat skalární hodnoty (pomocí konstrukce ${skalár}). Dále mohou obsahovat podmíněné příkazy, příkaz pro procházení sekvence, vytváření maker (opakujících se částí šablony), importovat knihovny maker z jiných souborů a vkládat jiné šablony. Do šablon není možné psát Java kód, příkazy šablon jsou orientovány pouze na prezentační logiku.

Použití v prostředí Java servletů

editovat

Při použití v prostředí Java servletů je možné používat knihovny tagů pro JSP (taglibs). Freemarker také poskytuje rozšiřitelný FreemarkerServlet, který je možné namapovat například na vzor *.ftl. Všechny soubory s koncovkou .ftl jsou pak zpracovány jako FreeMarker šablony, jako datový model je jim předán sloučený kontext HTTP požadavku, session a aplikace – zadané jméno (např. ${osoba}) se postupně hledá jako atribut v HttpServletRequest, HttpSession a ServletContext. Díky tomu je možné použít FreeMarker jako hotovou knihovnu (bez dalšího rozšiřování), v servletu naplnit potřebné hodnoty (model) do atributů požadavku, session nebo aplikace a následně požadavek předat na soubor s koncovkou .ftl.

Příklad

editovat

Šablonu z předchozího příkladu uložíme jako soubor /lide.ftl v kořenovém adresáři webové aplikace. Ve web.xml nakonfigurujeme FreemarkerServlet pro zpracování souborů s příponou .ftl:

<web-app metadata-complete="false" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <servlet>
 <servlet-name>Freemarker</servlet-name>
 <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
 <init-param>
 <param-name>TemplatePath</param-name>
 <param-value>/</param-value>
 </init-param>
 <init-param>
 <param-name>ContentType</param-name>
 <param-value>text/html</param-value>
 </init-param>

 <!-- FreeMarker settings: -->
 <init-param>
 <param-name>auto_import</param-name>
 <param-value>*/freemarker/common.ftl as c</param-value>
 </init-param>
 <init-param>
 <param-name>tag_syntax</param-name>
 <param-value>square_bracket</param-value>
 </init-param>
 <init-param>
 <param-name>template_update_delay</param-name>
 <param-value>0</param-value><!-- 0 is for development only! Use higher value otherwise. -->
 </init-param>
 <init-param>
 <param-name>default_encoding</param-name>
 <param-value>UTF-8</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>Freemarker</servlet-name>
 <url-pattern>*.ftl</url-pattern>
 </servlet-mapping>
</web-app>

Řídící servlet:


public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOexception, ServletException {
 List<Osoba> osoby = new LinkedList<osoba>();
 osoby.add(new Osoba("Marie", "Černá", 32, "Ostrava"));
 osoby.add(new Osoba("František", "Novák", 54, "Brno"));
 osoby.add(new Osoba("Natálie", "Zajícová", 72, "České Budějovice"));

 request.setAttribute("lide", osoby);
 request.getServletContext().getRequestDispatcher("/lide.ftl").forward();
}

Požadavek na tento servlet vygeneruje stejný výstup, jako úvodní příklad.

Související články

editovat

Externí odkazy

editovat