Появилось желание делать сайты на Clojure. Разработка веб-приложений на этом языке отличается тем, что здесь нет унифицированной инфраструктуры, как, например, в J2EE или Ruby on Rails. Каждый волен сам выбирать себе сервер, движок шаблонов, способ доступа к БД и т.д. И если с сервером в основном понятно (это, как правило, ring-based Compojure или Mustache), то с движком шаблонов ситуация не очень. Наиболее известные и используемые в Clojure-комьюнити: hiccup, enlive и fleet. Из всех троих больше всего мне пришелся по душе enlive, но он довольно сложен в освоении и использовании. Особенно портит ситуацию почти полное отсутствие вменяемой документации. Поэтому я решил использовать библиотеку StringTemplate.
Подключить и освоить ее оказалось делом очень простым.
1. Качаем с сайта stringtemplate.org последнюю версию stringtemplate, а с antlr.org -- последнюю версию antlr.
2. Создаем проект leiningen: lein new st-test.
3. В project.clj добавляем зависимости.
[stringtemplate/stringtemplate "4.0"]
[antlr/antlr "3.3"]
4. Если сделать сейчас lein deps, то, естественно,библиотеки эти не найдутся. Зато leiningen предложит их добавить в локальный репозиторий (смотри полный вывод команды). Например, в моем случае добавление выглядело так:
mvn install:install-file -DgroupId=antlr -DartifactId=antlr -Dversion=3.3 -Dpackaging=jar -Dfile=/path/to/file
Аналогично и для stringtemplate.
5. Теперь можно выполнить lein deps.
6. Подключим библиотеку:
(ns st-test.core
(import [org.antlr.stringtemplate StringTemplate]))
(defn template [^String txt ^java.util.Map context]
(let [t (StringTemplate. txt)]
(.setAttributes t context)
(.toString t)))
7. Сгенерим шаблон:
(template
"Hello, $name$!
This is a $if(really_true)$really true $else$ falsy $endif$ test!
And here is a list: $mylist:{n| <li>$n$</li> }$"
{"name" "World", "really_true" true, "mylist" ["first" "second"]})
В примере демонстрируется использование как простой замены (name), так и условной (if (really_true)), a также использование foreach для переменной mylist.
Выход функции:
"Hello, World! This is a really true test! And here is a list: <li>first</li> <li>second</li>"
По-моему, очень удобно.
Подключить и освоить ее оказалось делом очень простым.
1. Качаем с сайта stringtemplate.org последнюю версию stringtemplate, а с antlr.org -- последнюю версию antlr.
2. Создаем проект leiningen: lein new st-test.
3. В project.clj добавляем зависимости.
[stringtemplate/stringtemplate "4.0"]
[antlr/antlr "3.3"]
4. Если сделать сейчас lein deps, то, естественно,библиотеки эти не найдутся. Зато leiningen предложит их добавить в локальный репозиторий (смотри полный вывод команды). Например, в моем случае добавление выглядело так:
mvn install:install-file -DgroupId=antlr -DartifactId=antlr -Dversion=3.3 -Dpackaging=jar -Dfile=/path/to/file
Аналогично и для stringtemplate.
5. Теперь можно выполнить lein deps.
6. Подключим библиотеку:
(ns st-test.core
(import [org.antlr.stringtemplate StringTemplate]))
(defn template [^String txt ^java.util.Map context]
(let [t (StringTemplate. txt)]
(.setAttributes t context)
(.toString t)))
7. Сгенерим шаблон:
(template
"Hello, $name$!
This is a $if(really_true)$really true $else$ falsy $endif$ test!
And here is a list: $mylist:{n| <li>$n$</li> }$"
{"name" "World", "really_true" true, "mylist" ["first" "second"]})
В примере демонстрируется использование как простой замены (name), так и условной (if (really_true)), a также использование foreach для переменной mylist.
Выход функции:
"Hello, World! This is a really true test! And here is a list: <li>first</li> <li>second</li>"
По-моему, очень удобно.
А Closure Templates от Google не нравятся?
ОтветитьУдалитьПосмотрел Closure Templates. По-моему, примерно то же самое.
ОтветитьУдалитьЕсть мнение что возможностей StringTemplate недостаточно для серьезного проекта на Clojure http://steve.vinoski.net/pdf/IC-Clojure_Templating_Libraries_Fleet_and_Enlive.pdf
ОтветитьУдалитьС одной стороны -- да, возможностей у библиотеки не так уж и много. Но вот переходить из-за этого на Enlive или Fleet (с обеими я уже успел наиграться), пожалуй не стану. У Enlive проблема -- ее сложно изучить и использовать. У Fleet: он, вроде, уже не развивается; а кроме того он добавляет слишком много логики в представление.
ОтветитьУдалитьИнтерес, пожалуй, представляет Google Closure Templates (узнал о ней с подачи archimag'а). Скорее всего, попробую что-нибудь на ней.
И еще о StringTemplate. Стюарт Сиерра, автор "Practical Clojure" использовал ее для разработки сайта AltLaw.org (на сегодняшний момент сайт уже закрыт). Пруфлинк: https://github.com/stuartsierra/altlaw-template. В последующих обсуждениях движков шаблонов Стюарт неоднократно поддерживал использование StringTemplate для генерации html; Рич Хикки тоже ставил ее в пример всем движкам шаблонов. Пруфлинк: http://groups.google.com/group/clojure/browse_thread/thread/ab7a6a7a14575a96/55565925939312b3.
Одним словом, думаю, что достаточно хорошая библиотека.