قوالب FreeMarker

Apache FreeMarker هو محرك قوالب: مكتبة Java لتوليد إخراج النص (صفحات HTML ، xml ، ملفات التكوين ، رمز المصدر ، إلخ.) يتم إرسال قالب إلى الإدخال ، على سبيل المثال ، html الذي توجد فيه تعبيرات خاصة ، يتم إعداد البيانات المقابلة لهذا التعبير ، ويدرج Freemarker هذه البيانات ديناميكيًا وتحصل على مستند يتم ملؤه ديناميكيًا.

الصورة

في مقالة FreeMarker
التمهيد الربيع
وحدات الماكرو
REST API

على سبيل المثال التعبير البسيط على freemarker هو على سبيل المثال $ {name} ، العمليات الحسابية ، عمليات المقارنة ، الشروط ، الحلقات ، القوائم ، الدوال المضمنة ، وحدات الماكرو وغيرها الكثير مدعومة في التعبير. مثال html مع التعبير $ {name} (template test.ftl):

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>${name}!</title> </head> <body> <h2>Hello ${name}!</h2> </body> </html> 

إذا قمت الآن بإنشاء نموذج بيانات في جافا:

 import freemarker.template.Configuration; import freemarker.template.Template; ... //  Configuration cfg = new Configuration(Configuration.VERSION_2_3_27); //   Map<String, Object> root = new HashMap<>(); root.put("name", "Freemarker"); //  Template temp = cfg.getTemplate("test.ftl"); //      Writer out = new OutputStreamWriter(System.out); //    temp.process(root, out); 

ثم نحصل على مستند html بالاسم المعبأ.

إذا كنت بحاجة إلى معالجة القائمة ، يتم استخدام بناء #list ، على سبيل المثال لقائمة html:

 <ul> <#list father as item> <li>${item}</li> </#list> </ul> 

في جافا ، يمكنك إدراج نموذج البيانات على النحو التالي

 Map<String, Object> root = new HashMap<>(); .... root.put("father", Arrays.asList("Alexander", "Petrov", 47)); 

دعنا ننتقل إلى الربيع


التمهيد الربيعي لديه دعم Freemarker. على موقع SPRING INITIALIZR يمكنك الحصول على ملف مشروع pom.

ملف بوم
 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demoFreeMarker</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demoFreeMarker</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 


فئة DemoFreeMarkerApplication
 @SpringBootApplication public class DemoFreeMarkerApplication { public static void main(String[] args) { SpringApplication.run(DemoFreeMarkerApplication.class, args); } } 


يحتوي الربيع على مكون تكوين تم تكوينه مسبقًا لـ freemarker. بالنسبة لتطبيق مثال لوحدة التحكم ، سأخذ واجهة الربيع لمعالجة سطر الأوامر (CommandLineRunner) وأعد نموذج البيانات لقالب ftl التالي (hello_test.ftl):

قالب Hello_test.ftl
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello ${name}!</title> </head> <body> <input type="text" placeholder="${name}"> <table> <#list persons as row> <tr> <#list row as field> <td>${field}</td> </#list> </tr> </#list> </table> </body> </html> 


كود جافا لنموذج بيانات قالب hello_test.ftl:

فئة CommandLine ونموذج البيانات
 @Component public class CommandLine implements CommandLineRunner { @Autowired private Configuration configuration; public void run(String... args) { Map<String, Object> root = new HashMap<>(); //  ${name} root.put("name", "Fremarker"); //  <#list persons List<List> persons = new ArrayList<>(); persons.add(Arrays.asList("Alexander", "Petrov", 47)); persons.add(Arrays.asList("Slava", "Petrov", 13)); root.put("persons", persons); try { Template template = configuration.getTemplate("hello_test.ftl"); Writer out = new OutputStreamWriter(System.out); try { template.process(root, out); } catch (TemplateException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } } 


بعد المعالجة نحصل على مستند html:

إخراج HTML
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Fremarker!</title> </head> <body> <input type="text" placeholder="Fremarker"> <table> <tr> <td>Alexander</td> <td>Petrov</td> <td>47</td> </tr> <tr> <td>Slava</td> <td>Petrov</td> <td>13</td> </tr> </table> </body> 


وحدات الماكرو


Freemarker لديه دعم ماكرو ، وهو مريح وقوي للغاية ، ومن الضروري للغاية استخدامه.

مثال بسيط:

 <#macro textInput id value=""> <input type="text" id="${id}" value="${value}"> </#macro> 

هذا ماكرو له اسم textInput ومعلمات المعلمات (مطلوب) والقيمة (غير مطلوبة ، لأنه يحتوي على قيمة افتراضية). التالي هو جسده واستخدام معلمات الإدخال. في القالب ، يتم توصيل ملف الماكرو على النحو التالي:

 <#import "ui.ftl" as ui/> 

من القالب ، يسمى الماكرو على النحو التالي:

 <@ui.textInput id="name" value="${name}"/> 

حيث ui هو الاسم المستعار الذي تم تحديده عند الاتصال ، يكون $ {name} متغيرًا في النموذج ، ثم من خلال الاسم المستعار نشير إلى اسم الماكرو textInput وتحديد معلماته ، على الأقل إلزامية. سأقوم بإعداد وحدات ماكرو بسيطة لإدخال HTML والجدول:

ملف الماكرو ui.ftl
 <#-- textInput macro for html input --> <#macro textInput id placeholder="" value=""> <input type="text" id="${id}" placeholder="${placeholder}" value="${value}"> </#macro> <#-- table macro for html table --> <#macro table id rows> <table id="${id}"> <#list rows as row> <tr> <td>${row?index + 1}</td> <#list row as field> <td>${field}</td> </#list> </tr> </#list> </table> </#macro> 


$ {row؟ index + 1} هو دعم الفهرس المدمج لعنصر القائمة ، وهناك العديد من الوظائف المضمنة المماثلة. إذا قمنا الآن بتغيير القالب الرئيسي السابق واستبدلنا المدخل والجدول فيه بوحدات الماكرو ، نحصل على الوثيقة التالية:

قالب Hello.ftl
 <#import "ui.ftl" as ui/> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello ${name}!</title> </head> <body> <@ui.textInput id="name" placeholder="Enter name" value="${name}"/> <@ui.table id="table1" rows=persons/> </body> </html> 


راحة


بالطبع ، هذا النموذج مناسب للاستخدام في تطبيق الويب. أقوم بتوصيل التبعية في بوم:

  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 

إضافة وحدة تحكم REST:

DemoController.java
 @Controller public class DemoController { @Autowired private RepositoryService repositoryService; @GetMapping("/") public String index() { return "persons"; } @RequestMapping(value = "/search", method = RequestMethod.POST) public String hello(Model model, @RequestParam(defaultValue = "") String searchName) { List<List<String>> persons = repositoryService.getRepository(); List<List<String>> filterList = persons.stream() .filter(p -> p.get(0).contains(searchName)) .collect(Collectors.toList()); model.addAttribute("persons", filterList); model.addAttribute("lastSearch", searchName); return "persons"; } @RequestMapping(value = "/save", method = RequestMethod.POST) public String save(Model model, @ModelAttribute("person") Person person) { List<List<String>> persons = repositoryService.addPerson(person); model.addAttribute("persons", persons); return "persons"; } } 


مستودع الخدمة للأفراد:

RepositoryService.java
 @Service public class RepositoryService { private static List<List<String>> repository = new ArrayList<>(); public List<List<String>> getRepository() { return repository; } public List<List<String>> addPerson(Person person) { repository.add(Arrays.asList(person.getFirstName(), person.getAge().toString())); return repository; } } 


فئة الوجه:

Person.java
 public class Person { public Person(String firstName, Integer age) { this.firstName = firstName; this.age = age; } private String firstName; private Integer age; public String getFirstName() { return firstName; } public Integer getAge() { return age; } } 


قالب الماكرو:

ui.ftl
 <#macro formInput id name label type="text" value=""> <label for="${id}">${label}</label> <input type="${type}" id="${id}" name="${name}" value="${value}"> </#macro> <#macro table id rows> <table id="${id}" border="1px" cellspacing="2" border="1" cellpadding="5"> <#list rows as row> <tr> <td>${row?index + 1}</td> <#list row as field> <td>${field}</td> </#list> </tr> </#list> </table> </#macro> 


القالب الرئيسي:

الأشخاص. ftl
 <#import "ui.ftl" as ui/> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Person</title> <link href="style/my.css" rel="stylesheet"> </head> <body> <div> <fieldset> <legend> </legend> <form name="person" action="save" method="POST"> <@ui.formInput id="t1" name="firstName" label=""/> <br/> <@ui.formInput id="t2" name="age" label=""/> <br/> <input type="submit" value="Save" /> </form> </fieldset> </div> <div> <fieldset> <legend></legend> <form name="searchForm" action="search" method="POST"> <@ui.formInput id="t3" name="searchName" label=""/> <br/> <input type="submit" value="Search" /> </form> </fieldset> </div> <p><#if lastSearch??> : ${lastSearch}<#else></#if></p> <@ui.table id="table1" rows=persons![]/> </body> </html> 


هيكل المشروع:

الصورة

سيقوم التطبيق بمعالجة أمرين "حفظ" و "بحث" للوجه (انظر وحدة التحكم). يتم تنفيذ جميع الأعمال المتعلقة بمعالجة (تعيين) معلمات الإدخال بواسطة Spring.

بعض التفسيرات للقالب.

 <#if lastSearch??> : ${lastSearch}<#else></#if> 

يتحقق إذا تم تعيين المعلمة ، ثم عرض العبارة "بحث عن: .." ، وإلا فلا شيء:

 <@ui.table id="table1" rows=persons![]/> 

هنا أيضا ، تم التحقق من وجود قائمة الأشخاص ، وإلا فهي فارغة. هذه الفحوصات مهمة عند فتح الصفحة لأول مرة ، وإلا سيكون عليك تهيئتها في الفهرس () ، وحدة التحكم.

عمل التطبيق

الصورة

المواد:

دليل أباتشي FreeMarker

Source: https://habr.com/ru/post/ar420549/


All Articles