Генерация по шаблонам
В jc
имеется возможность генерировать произвольные наборы файлов по шаблонам gsp
.
Пример:
// сюда будем генерировать
def outDir = wd("temp/gendir1")
// ощищаем каталог, он будет пустым и существующим
ut.cleandir(outDir)
// создаем скрипт генератор по gsp-файлу
GspScript gs = create("my-templates/template1.gsp")
// запускаем генерацию, указывая куда генерировать и с какими аргументами
gs.generate("${outDir}/result1.txt", [a1: 1, a2: 2])
Пример шаблона:
<%@ page import="jandcode.jc.*" %>
<%
// содержимое gsp - это тело метода jandcode.jc.GspScript#onGenerate
// поэтому можно получить типизированную ссылку
GspScript th = this
def s = "Текст1"
%>
Текст
Переменная ${s}
Аргументы ${th.args['a1']}, ${th.args.a2}
<% out("Текст") %>
<% out(s) %>
Аргументы для генерации
Аргументы для генерации передаются в виде Map в методе genеrate
и доступны
в момент генерации через свойство: args
типа IVariantMap
.
Эти аргументы существуют в процессе генерации в единственном экземпляре и разделяются между вложенными шаблонами.
Вложенные шаблоны
Допустим, что у Вас имеется шаблон, который содержит некоторый обощенный вариант генерации. Такой шаблон можно использовать из основного так:
<%@ page import="jandcode.jc.*" %>
<%
GspScript th = this
// создаем экземпляры скриптов
// важно, что бы они были созданы внутри шаблона, откуда будут выводится
GspScript child1 = th.create('lib/child1.gsp')
GspScript child2 = th.create('lib/child2.gsp')
%>
Первый шаблон:
${child1}
Второй шаблон:
<% out(child2) %>
Это простейший способ использования вложенных шаблонов.
Кроме этого существует возможность объявить во вложенном шаблоне функции, которые можно вызывать из родительского. Такие функции будут выводить текст в текущий файл.
В таком случае шаблон с функциями используется как набор функций и не должен использоватся самостоятельно.
Так определяются функции во вложенном шаблоне:
<%@ page import="jandcode.jc.*" %>
<%
GspScript th = this
// функции объявляем как Closure и записываем в vars
th.vars.func1 = { a ->
out("A=${a}")
}
%>
Весь вывод вне функций будет проигнорирован!
<% th.vars.func2 = { b -> %>
B=${b}
<% } %>
Так они используются:
<%@ page import="jandcode.jc.*" %>
<%
GspScript th = this
// создаем экземпляр скрипта, содержащего функции
GspScript lib = th.create('lib/lib1.gsp')
// выполняем функции
lib.vars.func1(1)
lib.vars.func2(2)
%>
Генерация нескольких файлов
При запуске генерации в методе generate
мы указываем в какой файл генерировать.
Каталог с указанным файлом будет рассматриватся как базовый каталог генерации.
В процессе генерации можно изменять текущий файл, в который будет осуществляется
дальнейшая генерация.
Допустим мы запускаем генерацию так:
// создаем скрипт генератор по gsp-файлу
GspScript gs = create("my-templates/template1.gsp")
// запускаем генерацию, указывая файл, куда генерировать
// каталог с этим файлом будет базовым каталогом генерации
gs.generate("temp/gendir/result1.txt", [a1: 1, a2: 2])
Тогда в шаблоне можно делать так:
<%@ page import="jandcode.jc.*" %>
<%
GspScript th = this
// текущий файл для вывода: temp/gendir/result1.txt
def curFile = th.currentFile
// базовый каталог для вывода: temp/gendir
def outDir = th.outDir
// вывод в файл temp/gendir/result1.txt
th.out('1')
// меняем файл на temp/gendir/f2.txt, указывая имя относительно outDir
th.changeFile("f2.txt")
// вывод в файл temp/gendir/f2.txt
th.out('2')
// меняем файл на ранее используемый temp/gendir/result1.txt
// и указывая параметр append=true, открываем его в режиме добавления
th.changeFile("result1.txt", true)
// добавляем данные в файл temp/gendir/result1.txt
th.out('3')
// меняем файл на temp/gendir/f3.txt, предыдущий temp/gendir/result1.txt
// остается открытым
th.pushFile("f3.txt")
// выводим в файл temp/gendir/f3.txt
th.out('4')
// возвращаемся к файлу temp/gendir/result1.txt
th.popFile()
// выводим в файл temp/gendir/result1.txt
th.out('5')
%>
При смене файла методами changeFile
и pushFile
файл физически не создается
и не открывается, пока не было никакого вывода. Поэтому при запуске генерации
можно указать какой либо фиктивный файл (он нужен для определения базового каталога
генерации), а уже в теле шаблона указать смену файла на нужный.
Допустим для вышеуказанного вызова в шаблоне можно написать так:
<%@ page import="jandcode.jc.*" %>
<%
GspScript th = this
// текущий файл для вывода temp/gendir/result1.txt, однако он еще не создан,
// так как вывода еще не было
def curFile = th.currentFile
// выводим в набор файлов
for (i in 1..3) {
th.changeFile("f-${i}.txt")
th.out(i)
}
// будут созданы файлы:
// temp/gendir/f-1.txt
// temp/gendir/f-2.txt
// temp/gendir/f-3.txt
%>
Ресурсы для генерации
Скрипт jandcode.jc.GspScript
является наследником от
jandcode.jc.ProjectScript
и обладает всеми его свойствами.
Например, свойство scriptDir
указывает на каталог, из которого был загружен
скрипт. Это позволяет хранить ресурсы рядом со скриптом и в процессе генерации
копировать их в каталог вывода.
Допустим, мы генерируем html-файл и ему нужны css, js, картинки. Можно сделать так:
<%@ page import="jandcode.jc.*" %>
<%
GspScript th = this
// каталог в котором лежит скрипт
def scrdir = th.scriptDir
// копируем все ресурсы
th.ant.copy(todir: th.outDir) {
fileset(dir: srcdir) {
include(name: '**/*.js')
include(name: '**/*.css')
include(name: '**/*.jpg')
}
}
// генерируем html
%>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
text
</body>
</html>