Блог типа

Шаблонизатор

Вернулся к обдумыванию применения LOMO и LEAF в качестве языка для описания объектов и процесса их построения, проще говоря, в качестве шаблонизатора.

Основная идея такая. Определяется некий контекст. Пока неважно какой, главное, в нем возможно создание объектов и их сохранение после завершения работы условного шаблонизатора.

Объекты представляют собой суть ссылку на класс и любое пользовательское содержимое, выраженное в форме составных типов MAP, LIST и, возможно, SET. Это даёт возможность описывать всевозможные отношения объектов и их свойства.

Важным свойством шаблонизатора будет возможность обращения к данным, которые размещены в контексте.

А еще более важным свойством будет являться возможность описывать императивный и декларативный код (на LEAF и LOMO, соответственно) непосредственно в теле шаблона, и такой код будет полностью легально создавать куски шаблона, менять свойства объектов и обращаться к данным в контексте.

Долго пришлось подумать над базовой концепцией шаблонизатора, которая позволила бы реализовать подобные возможности. Эта концепция, в общем, проста. Шаблон будет компилируемым. А вариация синтаксиса для описания объектов будет представлять собой то, что могло бы получиться у авторов XML, если бы они знали про Оберон.

core.template(my-perfect-page):
    core.import! context html;
    html.body(root):
    	br: enhanced;
    	br
    	br:
    		type: page;
    		fp = 344H;
    	;
    	`ffe`
    	para(see-my-text):
    		`first i was like`
    		bold: `smth`;
    		`, but then i `
    		italic: `lol'd`;
    	;
    	table:
    		len = context.len;
    		do!
    		var i integer
    		begin
    			while i < context.len do
    				this:
  					tr: hidden;
                      text = @see-my-text;
    				;
    				parent:
					   count = i + 1;

    				;
    			end
    		end;
    	;
    ;
  ;

Вполне вероятно, это будет выглядеть вот так. Капс скорее всего тоже будет применён (хотя кто знает).

Итак, что мы видим: шаблон представляет собой вариацию на тему модуля Оберона. Базовые правила описания объектов: класс (существующий, импортированный, стандартный или вновь созданный) (core.template, core.import, html.body, br и т.д.), затем опциональный идентификатор конкретного объекта (для модуля обязательный), потом модификатор доступа к содержимому: : - обычное содержимое, ! - специальное (мета)содержимое, = - уникальное (в рамках родительского объекта) содержимое. Возможно также описывать объекты заданного класса без содержимого. Особенностью будет необязательная квалификация классов внутри объекта с классом, импортированным из других шаблонов. Для html-шаблонов это будет немаловажным фактом.

Внутреннее содержимое объекта определяется как перечисление идентификаторов классов объектов и управление содержимым этих объектов. Кроме этого, содержимым объектов может быть любая константа текстового, числового или любого другого допустимого в LEAF/LOMO простого типа. Возможно имеет смысл непосредственно представлять любой объект как аналог модуля LOMO, но непонятно, как быть с императивными вставками. Отдельно рассматривается возможность использования в качестве содержимого ссылок на объекты по идентификатору.

Данный пример технической части является лишь наброском и возможно будет изменен, но базовая концепция постепенно формируется в прототип. Так, исполнение кода внутри шаблона будет доступно при его генерации. В принципе, этот код будет ничем не ограничен, но в нем будут доступны объекты, внутри которых он был вызван таким образом внутри кода будет возможность создания объектов контекста.

В примере был выбран шаблон html как наиболее шаблонизируемого языка, так как создание html из шаблонов это довольно важная часть работы шаблонизаторов вообще. Результатом работы шаблонизатора над примером будет дерево объектов, которое может быть легко оттранслировано в html, провалидировано по требуемым правилам и так далее.