Pull to refresh

Comments 72

Сделайте простой примерчик на пальцах.
Зашел в блог Nginx, глядь там топиком ниже кто-то модуль анонсировал, который берет данные из MySQL базы и отдает в виде JSON. В связке с моим модулем этот JSON тут же может превратиться в HTML или в RSS, к примеру.

В общем то просто все. Разрабатываете шаблоны сайта с использованием CT++ синтаксиса. Он довольно простой, верстальщики должны легко освоить. Как у всех, есть переменные, ветвления, циклы. В принцыпе к компилятору этому можно прекрутить и, к примеру, Django подобный синтаксис. Тут нет каких-либо технических ограничений, просто кто-то должен этим занияться. Синтаксис сейчас примерно такой: ctpp.havoc.ru/doc/ru/ (к сожалению дока не отражает нововведения версии ct++ 2.6, с которой работает модуль).

Имея шаблоны, вы компилируете их в эффективный байт-код, происходит это достаточно быстро и просто:
$ ctpp2c 'путь/к/исходнику' 'путь/к/результату'

Собрав nginx с модулем, вы можете указать в nginx.conf в любой из секций, с помощью директивы template путь к вашему скомпилированному шаблону, и включить модуль в работу с помощью директивы ctpp2 on. С этого момента, при обращении по соответвующему локэшену сервер nginx будет ожидать данные для страницы в формате JSON от бэкенда (или просто из файла), подгружать байткод шаблона и запускать виртуальную машину, результат шаблонизации отдавать клиенту.

Более того, вы можете построить целый асинхронный контроллер, компаную данный модуль и SSI, и отдельные части html страницы у вас будут формироваться из разных шаблонов и разных запросов JSON данных из разных мест. Благодаря Nginx все это будет происходить асинхронно и параллельно, если вам нужено получить данные для страницы из двух разных мест, например, из какого-нибудь nosql базы и еще какого-то сервиса стороннего, то эти данные будут запрошены параллельно, а не последовательно, и задержки не будут суммироваться.

Надеюсь выполнил вашу просьбу.
Да, спасибо, теперь понятно, как это готовить :)
Более того, забыл упомянуть еще важный момент. Путь к байткоду шаблона можно задавать не только в nginx.conf, но и передавать от бэкенда вместе с JSON, в специальном HTTP заголовке «X-Template» (название его можно настроить). Причем, если модуль не может определить путь к шаблону (нет в заголовке и не указан в nginx.conf), то шаблонизации происходить не будет, JSON будет отдаваться как есть. Так вы можете легко сделать так, что без дополнительной конфигурации у вас по одному uri будет одаваться или html или json для JavaScript нужд. В первом случае ваш бэкенд будет посылать заголовок с путем до шаблона, а во втором нет.

Но это еще не все. =) Модуль ничего не делает с заголовком Content-Type, как с ним работать — на ваше усмотрение. Так вы можете устанавливать его совершенно свободно на бэкенде, и прибавить к JSON, HTML еще и RSS ленту (ваш бэкенд установит соответсвующий заголовок и путь к соответвующему шаблону формирующему XML).
p.s. Разумеется заголовок с путем до шаблона будет вырезан модулем из ответа конечному пользователю.
а возможно упростить синтаксис шаблонизатора?
и сделать его локоничнее, к примеру:
<_var ИМЯ_ПАРАМЕТРА> - непосредственный вывод параметра.
<_if УСЛОВИЕ> <_elsif УСЛОВИЕ> <_else> </_if> - условное ветвление.
<_loop МОДИФИКАТОР1 МОДИФИКАТОР2 ИМЯ_ПАРАМЕТРА> </_loop> - цикл.
<_foreach ИМЯ_ПАРАМЕТРА as ИМЯ_ИТЕРАТОРА> </_foreach> - цикл с итератором.
<_... >

на скорость это не должно влиять, а вот воспринимать и писать приятней будет
Автор CTPP обещал в следующей версии гибко настраиваемый синтаксис.

Если вам прямо сейчас нужно, то можете править парсер ctpp, это не сложно, достаточно лишь базовых знаний C++ и немного свободного времени.
Зашел в блог Nginx, глядь там топиком ниже кто-то модуль анонсировал, который берет данные из MySQL базы и отдает в виде JSON.

это може быть мой модуль HandlerSocket github.com/akalend/ngx_http_handlersocket_json_module
но я не анонсировал хотя на Хабре есть статья;
если модуль не использует HS, то лучше такой модуль не использовать.

Да, верно заметили: первое очень хорошо дополняет второе

Удачи автору
«если модуль не использует HS, то лучше такой модуль не использовать»
Хм, это любопытно, а вот Drizzle + RDS JSON чем принципиально плохи?
1) использует протокол mysql, а следовательно тянется весь функционал — парсинг запросов, оптимизаций запроса, выделение пула буферов  
2) сам протокол HS в 30 раз компактнее, чем протокол mysql
3) HS — обращение напрямую к индексу, минуя весь функционал обработки запроса (п.1)
4) не знаю как в Drizzle, а в MySQL каждый запрос (подзапрос) обрабатывает отдельный поток. а в HS — один поток обрабатывает несколько сетевых запросов, можно варьировать кол-вом потоков в конфиге.

В тестах производительность HS на слабой машине в 30-100 выше, чем нативный SQL.
кратко см презентациюhttp://www.slideshare.net/akalend/handdler-socket-in-the-addconf
Ok, почитаю, спасибо. Хотя, в целом, меня мало интересует превращение SQL в NoSQL. Выглядит как некий костыль, ибо нативные (CouchDB, MongoDB, RIAK и т. д.) решения уж точно не хуже, а лучше и вкуснее, ИМХО.
по моим тестам MongoDB на объеме 10 М ключей — медленнее
другие нет возможности протестировать
иногда некий костыль — это вытаскивание (дублирование ) целой таблицы в noSQL

UFO just landed and posted this here
Да, разумеется.
SSI — просто как пример того, как сделать это исключительно средствами Nginx.
Разве веб-сервер не должен заниматься отдачей контента и разруливанием запросов? А вы внего уже фреймворки тягаете, как-то не unix-way.
К тому же делать в приложениях прибивание к nginx не шибко и хорошо
Современные сервера уже давно по возможностям конфигурирования — целые фреймфорки, уже из коробки, и занимаются фактически разруливанием запросов. В том же nginx есть даже интепретатор Perl встроенный.
Поясню по разруливание запросов подобнее. У нас есть данные, данные которые кто-то запросил по протоколу http(s). Эти данные мы можем в зависимости от клиента представлять в том или ином виде, и это фактически и есть часть поцесса разруливания запросов. Приложение генерирует данные, а веб-сервер это интерфейс доступа к ним. Тут нет каких-либо «идеологических» противоречий с функций веб-сервера, который уже занимается обработкой запросов.

А на счет привязки к nginx, так единственная «привязка», это к CT++. Вы же можете его и отдельно использовать, и в качестве модуля к Python, Perl, PHP, и просто из любого языка, как вызов функции, или как вызов программы. Когда вы устанавливаете CT++ в систему, у вас помимо компилятора (ctpp2c), есть еще отдельно и интерпретатор (ctpp2i) и виртуальная машина (ctpp2vm).

CT++ отлично существовал и развивался задолго до появления модуля к nginx. =) Другое дело, что его привязка к другим языкам, зачастую не очень эффективна. Тот факт, что nginx написан на Си, позволил мне довольно легко встроить в него ctpp2 (написанный на C++) наиболее эффективным образом.
Используя SSI, мы можем сделать следующее.
Кешировать ответы от бэкенда со встроенными SSI-инструкциями.
При каждом запросе SSI-include, прописанный в закешированной странице, ходит по какому-либо адресу, откуда получает набор SSI-команд установки переменных, и далее эти переменные анализируются SSI-условиями для вывода тех или иных блоков (use case: проверка авторизованности пользователя).
Но проблема здесь в том, что SSI достаточно ограничен (нет циклов и вложенных условий).

Можно ли с помощью вашего модуля сделать такой же финт, но используя гораздо более продвинутый CTPP вместо SSI?

PS: А не появилась ли в CTPP возможность установки переменных в шаблонах? Из-за отсутствия этого функционала я использую Clearsilver.
Один из тестов к модулю называется Matryoshka, он состоит в том, что сервер запрашивает JSON, пропускает через CT++, и на выходе получается страница с директивами SSI-include, которые обрабатываются SSI модулем и делаются несколько подзапросов, каждый из подзапросов также берет JSON, пропускает через CT++ и результат отдает SSI модулю.

Что и где на каком месте кэшировать, в общем-то вы определяете сами. Все обработчики запросов, в том числе кэш работают до модулей фильтров, коими являются мой и SSI модуль. При этом мой стоит перед SSI.

Кажется, ответил на ваш вопрос.

По поводу переменных. Совершенно точно там есть возможность установки переменной значения по умолчанию, т. е. если она не будет задана, то будет использовано это значение. Вы это имели ввиду? Если просто строго присвоить переменной некое значение в шаблоне, то в этом для самого шаблонизатора нет никакого смысла, вы с тем же успехом можете перед компиляцие прогнать шаблон через какой-нибудь скрипт, который заменит определенные вами метки на интересующее вас значение. Или я чего-то недопонял?
… и делаются несколько подзапросов, каждый из подзапросов также берет JSON, пропускает через CT++ и результат отдает SSI модулю.

Представьте ситуацию, что у нас есть выделенный авторизационный сервер для проверки сессий, который отдает данные в формате JSON. Мы кешируем страницу (с помощью proxy_cache) со встроенными CTPP-инструкциями. Далее, при очередном запросе достаем страницу из кеша, делаем подзапрос к авторизационному серверу и начинаем выполнять эти инструкции, данные для шаблонизации при этом берутся из ответа на подзапрос, который содержит информацию о пользователе.
Схематично, это будет выглядеть так:

<TMPL_udf SUBREQUEST('/path/to/auth/backend')>
<TMPL_comment>Функция SUBREQUEST() получает данные
в формате JSON и использует их в качестве данных для шаблонизатора</TMPL_comment>

<TMPL_if User>
  Hello, <TMPL_var User.username>!
  Your friends are:
  <TMPL_loop User.friends>
    <TMPL_var friendname>
  </TMPL_loop>
</TMPL_if>


Или я чего-то недопонял?

Хочется вот этого:

<TMPL_set page_title = 'Index page'>
<TMPL_include "include/page_header.tmpl">

А в шаблоне include/page_header.tmpl

<title><TMPL_var page_title></title>
1) Тут нужно разобраться, зачем вы кэшируете страницу с CT++ инструкциями. В модуле находится исключительно виртуальная машина, которая выполняет байткод. В настоящий момент байткод подгружается из файла и не кэшируется. В будущих версиях байткод можно будет «доставать» откуда угодно подзапросом, а также очень эффективно кэшировать его в разделяемой памяти самого Nginx для заведомо предустановленных шаблонов.

Байткод служит лишь для преобразования JSON во что-нибудь иное текстовое. Т. е. он нужен только там, где на входе идет JSON. Вы можете сделать одним из следующих способов:
а) Отдавать (и кэшировать если вам надо) SSI страницу, в которой будут include с запросами к разным сервисам, отдающим JSON, и каждый ответ будет обрабатываться CT++ и вставлятся в SSI страницу. При этом JSON ответ этих сервисов вы можете опять же закэшировать. А временем работы виртуальной машины CT++ можно практически пренебречь (там типичные величины менее 1мс).
б) Отдавать JSON, в котором будут в том числе и инструкции SSI-include, кэшировать этот JSON, он будет преобразовываться и отдаваться SSI модулю, и далее как в 1-ом пункте.
в) (наиболее некрасивый способ) Выстроить цепочку из пары nginx серверов стоящих друг за другом, один будет кэшировать ответ другого, а другой будет преобразовывать JSON в SSI-страницу.

2) Такого вроде бы нет, не видел. Но, на самом деле, то, что вы хотите можно легко добавить, нужно лишь знание C++ и немного свободного времени. Имеет смысл написать по этому поводу автору CT++, и, быть может, он добавит либо подскажет как это делается иначе. Ну или я, если уж так это востребовано, как-нибудь найду время реализовать и пришлю патч разработчику CT++.
К 1-ому, можно еще и так сделать:
г) SSI страница с include будет формировать из пары JSON подзапросов новый JSON документ, который уже далее будет обработан CT++ шаблоном и вставлен в другую SSI страницу.

И в дополнение к (в) с цепочкой из пары nginx я загнул, можно и один использовать, делать подзапросы через http-proxy самому себе.
В общем то, таким образом можно выстраивать сколь угодно длинные цепочки:
CTPP->SSI->CTPP->SSI… SSI->SSI… CTPP->CTPP
и на каждом этапе у вас может быть настроено кэширование стандартными возможностями Nginx.
А xsl синтаксис (с упрощенным xpath'ом) сделать нельзя?
Затрудняюсь ответить, поскольку с XSL практически не знаком. В CT++ компилятор и парсер отделены от виртуальной машины, а виртуальной машине требуется лишь корректный байткод, и не важно как он получен. Т. е. можно переписать компилятор, еще проще добавить функций, и можно править парсер. Так довольно просто достичь синтаксиса, подобного другому шаблонизатору сопоставимому по функциональности с CT++.

Но вообще в Nginx уже есть XSLT модуль: sysoev.ru/nginx/docs/http/ngx_http_xslt_module.html
Спасибо за информацию. Но там не ясно что и как с кешированием. Видимо его нет.
Там указано, что все файлы xslt и dtd компилируются еще на стадии конфигурации, значит остальное время он их, вероятно, и так держит в памяти.

Исходный xml вы можете кэшировать стандартными средставами, также как кэшируете обычные html страницы от бэкендов. Результат тоже можно закэшировать, если использовать proxy-pass самому себе. Если я не ошибаюсь, так можно делать.
а есть уже модуль xslt
зачем мешать мух и котлет?
Не совсем понял, это подобие хэндлера от Mason или TT2?
CT++ это скорее подобиет TT2, только на порядок быстрее. А модуль встраевает его в Nginx.
Я считаю это мегакруто, загорелся этой идей но столкнулся с проблемой. Я так понял Nginx CT++ позиционируется как языково не зависимый, т.е. бекэнд может быть написан на java.

Решил попробовать, у меня есть два шаблона templates/hellow.ct2 и templates/about.ct2. В идеальном мире шаблон hellow.ct2 предназначен для страницы /hellow.html, а about.ct2 соответственно для /about.html.

Для того что бы правильно распределить запросы мне нужно добавить http-заголовок «x-template=hellow.ct2» в ответ сервера hellow.html и «x-template=about.ct2» для about.html

Я могу модифицировать ответ бекэнда. Но блин мой любимый бекэнд написан на java и крутится совершенно на другой машине и на другом сервере. Это решение никуда не годится.

Я вижу один выход — писать прослойку на php которая делает запрос на бекэнд и прибавляет x-template. Ну это же адово решение, теряем производительность, теряем ясность.

Я бы хотел просто написать в hellow.html:
<ctpp template="hellow.ct2" />

В about.html:
<ctpp tempalte="about.ct2"/>


А уже в самих шаблонах ctpp делать подзапрос на мой бекэнд, как было написано выше:
<TMPL_udf SUBREQUEST('http://my-facking-server.ru/about')>


Или такой вариант:
<ctpp template="hellow.ct2" json-from='http://my-facking-server.ru/about' />


Я допускаю что просто чего-то не знаю (все же 2ч всего в теме). Поэтому старался максимально обрисовать проблему, наверняка есть простое решение?

Сейчас наткнулся HttpHeadersModule, выглядит костылем, т.к. нужно править конфигурацию сервера, т.е. в реалтайме бекенд уже не сменишь, да и верстальщик уже не может просто сменить файл шаблона.
Тогда вам нужно именно SSI-include.
Вы можете пути к about.ct2 и hellow.ct2 указывать в настройках nginx. Для этого есть директива template:
ngx-ctpp.vbart.ru/settings#template

В этом случае заголовок X-Template от бэкенда не требуется.

Также удобно пользоваться в сочетании с директивой templates_root

Если вам нужен именно подзапрос на бэкенд, то используйте SSI-include:
sysoev.ru/nginx/docs/http/ngx_http_ssi_module.html#commands
Я так понял template один в концигурации указывается (я с одним шаблоном так и делал). Или на каждый локейшин можно прописать? Тем неменее это ограничивает верстальщиков в создании новых шаблонов — нужно менять конфигурацию сервера что тоже не есть хорошо (может даже перезапускать его).

Про SSI-include еще вчера хотел почитать, но время позднее было. Спасибо, после работы попоробу, затем отпишус.
Можно прописать, начиная от всей секции http и заканчивая if-ом, и разумеется на отдельный локейшн тоже можно. При этом работает уточняющее правило замещения, от общего к частному, локальный template переопределяет в своей области собой более глобальный (если таковой есть). Т. е. если прописать a.ct2 для секции server, а для одного из location в этой секции прописать b.ct2, то для этого отдельного локэйшена будет работь b.ct2, а для всей остальной секции a.ct2.
*ctrl+enter* (

Результаты тестирования таковы:
url: localhost:8888/
Response headers: x-template: build/html/index.html.ct2

url: localhost:8888/about/
Response headers: x-template: build/html/about/index.html.ct2


Все верно, однако шаблонизатор не запускается — браузеры выводят просто json из файлов index.html и about/index.html
Придумал одну схема только она не работает. Не могу понять по чему. В конфигурации nginx я прописал следующее:

    server {
        listen       8888;
        server_name  localhost;

	ctpp2 on;
	templates_header x-template;
	add_header x-template $request_filename.ct2;

        location / {
            root   html;
        }


Согласно конфигурации nginx на каждый конкретный запрос будет добавлять http заголовок x-template=путь-до-файла-html.ct2. В root папке у меня лежат два файла index.html и about/index.html. Оба файла просто json для ct2 шаблонов.

Результаты тестирования таковы:
url: localhost:8888/
Не работает потому, что headers модуль работает уже после моего. Т. е. он заголовок то добавляет, но уже после того, как моему модулю передали заголовки, он в них ничего не нашел, и отдал дальше.

Вообще, я так подумал, что надо бы мне передвинуть модуль подальше, но не ради headers модуля. Ведь по сути, вы просто пытаетесь сделать грязным хаком то, что я и так обещал в будущих версиях — возможность использовать переменные в директиве «template». А передвинуть его думаю стоит ради addition модуля.

Чтобы ваше конфиг заработал уже сейчас, не дожидаясь новой версии, попробуйте в файле «config», папки с исходниками модуля, заменить строчку:
HTTP_COPY_FILTER_MODULE="ngx_http_ctpp2_filter_module $HTTP_COPY_FILTER_MODULE ngx_http_ctpp2_tmpl_loader"
на
HTTP_COPY_FILTER_MODULE="$HTTP_COPY_FILTER_MODULE ngx_http_ctpp2_tmpl_loader"
а после нее добавить:
HTTP_HEADERS_FILTER_MODULE="ngx_http_ctpp2_filter_module $HTTP_HEADERS_FILTER_MODULE"
после этого надо заново выполнить configure и пересобрать nginx.
Понятно. Идея использовать переменные в директиве template мне нравится, она решает все мои проблемы.

Спасибо за разъяснения и замечательный проект.
Я добавил поддержку переменных в директиву template, можете взять последнюю ревизию из svn и потестировать:
svn co svn://svn.vbart.ru/ngx_ctpp2/trunk
Простите, если я не совсем понял.
Если бэкэнд на яве, наверняка он в ВебКонтейнере где вы можете добраться
до HttpServletResponse и сказать ему .setHeader(«X-Template », "/там-гдето")
Если не В вебконтейнере, то гдето-ответ всеравно собирается.
Бекэнд на то и бекэнд, — он о фронтенде ничего знать не должен и не хотелось бы вставлять уродливые
if (requestFromNginx) {
         .setHeader(«X-Template », "/там-гдето")
}
Ок, тут вы правы. Трудно догадатся о вашей архитектуре просто.
Вопрос не технологический а архитектурный получается.
Да и что бы поменять название шаблона для данной страницы нужно править бекэнд в таком случае.
ждал релиза,
к сожалению руки так и не дошли протестировать бету

и все равно спасибо.
Приятно видеть, что кроме меня есть и другие разработчики, развивающие CT++.

В скором времени CT++ ждет большое обновление: выйдет версия 2.7.
Что, собственно нас ждет в этой версии?

— возможность доступа к элементам хэшей и массивов:
— возможность выбрать синтаксис тегов. То есть, вместо можно будет написать или {foo} или [% foo %] или что угодно на ваш выбор
— дополнительные функции (их много)
— и главное: полный набор документации по движку

озможность выбрать синтаксис тегов.

Андрей, а тебе предлагал эту возможность реализовать еще в первой версии,
мы с тобой по поводу использования CTPP общались года четыре назад
Я считаю это мегакруто, загорелся этой идей но столкнулся с проблемой

я загорелся этой идеей три года назад, когда услышал доклад маилрушников на РИТ. Я написал 50% шаблонизатора на С. А потом я сменил работу и нужно было реализовывать другие проекты. Хорошо, что кто-то это сделал.
Гибкий синтаксис шаблонов
Если вы привыкли к синтаксису Smarty, HTML::Template или Text::Template, вы можете настроить CTPP «понимать» ваши старые шаблоны. Разумеется, некоторые переделки будут, но в ряде случаев проблем при переходе на новый «движок» не возникнет.

Кроме этого упоминания больше нигде не нашёл что-либо на эту тему. Так можно ли уже использовать другой синтаксис, или нет?
Ясно, спасибо. Будем ждать
Спасибо автору! и отдельное спасибо Андрею за превосходный шаблонизатор, с которого так трудно «слезть», сколько не пробовал =)
не хочу разводить холивар
а чем не устраивает googleTemplates?
Вышла версия 2.7.0.

slonik-v-domene.livejournal.com/90471.html

Скачать исходники можно здесь: ctpp.havoc.ru/download/ctpp2-2.7.0.tar.gz

Эта версия предназначается для тестировщиков и разработчиков модулей и интерфейсных библиотек для различных сред и языков программирования.

Возможны баги, вас предупредили :) Багрепорты нужно отсылать на reki@reki.ru или на slonik-v-domene@rambler.ru.

Как я понимаю тема сисек сохранения шаблонов в ОЗУ не раскрыта? Можно конечно полагаться на дисковый кэш ОСи, но хочется быть уверенным, что вот все нужные шаблоны у нас в том же memcached и nginx возьмет их именно оттуда.
Будет раскрыта в следующих версиях, сразу после переменных в путях. А пока, на дисковый кэш вполне можно полагаться. А если уж совсем приспичит, то никто не мешает положить шаблоны в /dev/shm.

p. s. Судя по отсутсвию баг-репортов на >50 скачиваний, похоже у всех всё работает.
И кстати, memcached нелох как разделяемый между машинами кэш для часто меняющихся данных, трудно предположить, что шаблоны будут постоянно меняться. Это довольно специфическая и редкая для проектов ситуация. Зато в nginx это будет дополнительный подзапрос со всеми вытекающими накладными расходами.

Поэтому, даже когда в модуле будет реализован функционал подзапросов для байткода, я бы не рекомендовал им злоупотреблять.
Ну я не имею ввиду обязательно использование memchahed, привел для примера. Наверное неплохо было бы сторить вообще в shared memory (в смысле «искаропки» через опцию настройки). Просто имея ХХ мегабайт шаблонов и зная, сколько они потребуют памяти можно прикинуть в целом сколько нужно ресурсов в контексте того, что бОльшая часть данных будет тянуться не диска.
Добавил базовые возможности для кэширования шаблонов, можете опробовать взяв версию из svn.
svn co svn://svn.vbart.ru/ngx_ctpp2/trunk

Кэш включается добавлением слова cached перед путем в директиве template. Пример:
template: cached /path/to/template.ct2;

Шаблон загружается при старте веб-сервера в разделяемую память вместе с конфигурацией. Соответственно, как побочный эффект, чтобы изменить шаблон, надо перезагрузить nginx. Зато, быстрее кэша уж быть не может, да и то, какой-либо особо заметной прибавки в производительности это не дало по моим тестам. Файловый кэш в linux и так неплохо справляется со своей задачей.
О! Отлично, спасибо. Вернусь из отпуска обязательно поставлю.

А перезагрузить в мысле restart или все же reload? Дисковый кэш оси конечно реализован очень хорошо, но напрямую контролю он не поддается. А с sh я гарантированно получаю нужные данные из ОЗУ + видно статистику по сегменту. Понятно, что sh может быть выгружена на диск, но когда идет постоянное обращение к сегменту, то выгрузки происходить не должно. В итоге я хочу прийти к тому, что все связанные со страницей данные будут тянуться из sh или базы (которые опять же будут откэшированы в sh).
А перезагрузить в мысле restart или все же reload?
Без разницы, и то и другое перезагружает конфигурацию.
Собрал на Linux 2.6.32-5-amd64 с nginx 1.0.6 и ctpp2 2.7.1 все отлично. Только по всей видимости шаблон из template директивы в sh не попадает. По strace видно, что nginx файл шаблона прочел, но в выводе ipcs -m я вижу только сегмент принадлежащий postgre-у. Так и должно быть? Как я понимаю используется для кэша не sh, а что предоставляемое самим nginx-ом?
Да. Nginx читает конфигурацию и байткод шаблонов, а затем форкается на число рабочих процессов. Имеет место быть COW, и потомки разделяют один и тот же сегмент с данными конфигурации и байткодом шаблонов, но ipcs -m этого не покажет.
Вышла Production-ready версия шаьлонизатора CTPP: 2.7.1.

Нововведения:
1. Все операторы теперь умеют удалять вокруг себя пробелы, знаки табуляции и переводы строк.
Для этого достаточно после '<' или перед '>' поставить символ '-': <-TMPL_var foo ->

2. Появился новый оператор TMPL_verbose. Если напрягает постоянно писать <-TMPL_var foo -> <-TMPL_var bar ->, достаточно обернуть часть шаблона в <TMPL_verbose>… </TMPL_verbose> и напрягающие пробелы, табы и переводы строк также исчезнут

3. Параметризованные блоки (сиречь — подпрограммы) <-TMPL_call foo(bar, baz)> / <-TMPL_block foo(bar, baz)>… <-/TMPL_block>

4. Своя собственная реализация gettext, совместимая по формату файлов со стандартной и позволяющая работать без настроек переменных окружения.

5. Исправлены некоторые баги.

6. Готовится документация на английском и русском языках.

О дальнейших планах по развитию CTPP можно прочитать здесь: slonik-v-domene.livejournal.com/94370.html

P.S. было бы неплохо сделать отдельный блог, посвященный CTPP; к сожалению, на это не хватает времени.
4. Т.е. системный gettext не используется?

P.S. А есть ли смысл при наличие официальной документации? В принципе месяца через два, по мере использования ctpp я готов написать пару топиков.
Sign up to leave a comment.

Articles