ZetCode

Java Jinjava

最后修改于 2024 年 1 月 27 日

Java Jinjava 教程展示了如何使用 Jinjava 在 Java 中创建模板。

模板引擎是一个用于将模板与数据相结合以生成文档的库。模板引擎用于生成大量电子邮件、进行源代码预处理或生成动态 HTML 页面。

模板由静态数据和动态区域组成。动态区域稍后会被数据替换。渲染函数随后将模板与数据结合。模板引擎用于将模板与数据模型相结合以生成文档。

Jinjava 库是一个 Java 模板引擎,其灵感来自 Python 的 jinja 模板引擎。

Jinjava 在模板字符串中使用各种分隔符

文档使用 render 方法渲染。该方法接受模板字符串和上下文,其中包含数据。

<dependency>
    <groupId>com.hubspot.jinjava</groupId>
    <artifactId>jinjava</artifactId>
    <version>2.6.0</version>
</dependency>

我们使用 jinjava 依赖项。

Jinjava 简单示例

以下是一个 Jinjava 简单示例。

com/zetcode/Simple.java
package com.zetcode;

import com.google.common.collect.Maps;
import com.hubspot.jinjava.Jinjava;

import java.util.Map;

public class Simple {

    public static void main(String[] args)  {

        var jnj = new Jinjava();

        Map<String, Object> context = Maps.newHashMap();
        context.put("name", "John Doe");

        String res = jnj.render("Hello {{ name }}!", context);
        System.out.println(res);
    }
}

我们打印一条简单的消息。

var jnj = new Jinjava();

创建了一个 Jinjava 对象。

Map<String, Object> context = Maps.newHashMap();
context.put("name", "John Doe");

我们创建一个上下文;它包含传递给模板引擎的数据。

String res = jnj.render("Hello {{ name }}!", context);

我们使用 render 方法渲染最终输出。它接受一个模板字符串和上下文对象。

从文件读取 Jinjava 模板

在下一个示例中,我们从文件中读取模板。

src/main/resources/message.jinja
{{ name }} is a {{ occupation }}.

这是模板文件。

com/zetcode/FromFile.java
package com.zetcode;

import com.google.common.collect.Maps;
import com.hubspot.jinjava.Jinjava;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;

public class FromFile {

    public static void main(String[] args) throws IOException {

        var jnj = new Jinjava();

        Map<String, Object> context = Maps.newHashMap();
        context.put("name", "John Doe");
        context.put("occupation", "gardener");

        String fileName = "src/main/resources/message.jinja";
        String template = Files.readString(Paths.get(fileName));

        String res = jnj.render(template, context);
        System.out.println(res);
    }
}

我们使用 Files.readString 读取模板文件。

Map<String, Object> context = Maps.newHashMap();
context.put("name", "John Doe");
context.put("occupation", "gardener");

我们在上下文对象中传递两个变量。

Jinjava for 指令

for 指令用于迭代模板中的数据集合。

src/main/resources/words.jinja
{% for word in words -%}
    {{ word }}
{% endfor %}

在模板中,我们使用 for 指令来遍历 words 数据结构的元素。- 字符会去除空格字符。

com/zetcode/Words.java
package com.zetcode;

import com.google.common.collect.Maps;
import com.hubspot.jinjava.Jinjava;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

public class Words {

    public static void main(String[] args) throws IOException {

        var jnj = new Jinjava();

        var words = List.of("sky", "rock", "small", "bed", "food", "warm");

        Map<String, Object> context = Maps.newHashMap();
        context.put("words", words);

        String fileName = "src/main/resources/words.jinja";
        String template = Files.readString(Paths.get(fileName));

        String res = jnj.render(template, context);
        System.out.println(res);
    }
}

在该程序中,我们将单词列表传递给模板引擎。我们得到一个单词列表作为输出。

Jinjava 过滤器

可以将过滤器应用于数据以修改它们。过滤器在 | 字符后应用。

src/main/resources/words.jinja
{% for word in words -%}
    {{ word }} has {{ word | length }} characters
{% endfor %}

length 过滤器返回字符串的大小。

com/zetcode/WordsLen.java
package com.zetcode;

import com.google.common.collect.Maps;
import com.hubspot.jinjava.Jinjava;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

public class WordsLen {

    public static void main(String[] args) throws IOException {

        var jnj = new Jinjava();

        var words = List.of("sky", "rock", "small", "bed", "food", "warm");

        Map<String, Object> context = Maps.newHashMap();
        context.put("words", words);

        String fileName = "src/main/resources/words.jinja";
        String template = Files.readString(Paths.get(fileName));

        String res = jnj.render(template, context);
        System.out.println(res);
    }
}

在该程序中,我们将单词列表传递给模板。我们打印每个单词及其大小。

Jinjava if 条件

可以使用 if/endif 指令创建条件。

src/main/resources/tasks.jinja
{%- for task in tasks -%}
    {% if task.done %}
        {{ task.title }}
    {% endif %}
{%- endfor %}

在模板文件中,我们使用 if 指令仅输出已完成的任务。

com/zetcode/Task.java
package com.zetcode;

public class Task {

    private String title;
    private boolean done;

    public Task(String title, boolean done) {
        this.title = title;
        this.done = done;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public boolean isDone() {
        return done;
    }

    public void setDone(boolean done) {
        this.done = done;
    }
}

这是 Task 类。

com/zetcode/Tasks.java
package com.zetcode;

import com.google.common.collect.Maps;
import com.hubspot.jinjava.Jinjava;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

public class Tasks {

    public static void main(String[] args) throws IOException {

        var jnj = new Jinjava();

        var tasks = List.of(new Task("Task 1", true),
                new Task("Task 2", true), new Task("Task 3", false),
                new Task("Task 4", true), new Task("Task 5", false));

        Map<String, Object> context = Maps.newHashMap();
        context.put("tasks", tasks);

        String fileName = "src/main/resources/tasks.jinja";
        String template = Files.readString(Paths.get(fileName));

        String res = jnj.render(template, context);
        System.out.println(res);
    }
}

我们从任务列表中生成一个输出。在输出中,我们仅包含已完成的任务。

来源

Jinjava Github 页面

在本文中,我们介绍了 Jinjava 模板引擎。

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有Java教程