Тег <b:content>
определяет точку вставки контента, если для него явно не задана точка вставки. Имеется ввиду контент, который находится внутри <b:include>
и не обрамлен специальными тегами вроде <b:append>
, <b:replace>
и т.д.
- Принцип работы
- Механика
- Неявное определение <b:content>
- Контент по умолчанию
- Взаимодействие с операциями трансформации декларации
- Наследование и крайние случаи
Исходный шаблон:
<button class="button">
{caption}
<b:content/>
</button>
Модифицирующий шаблон:
<b:include src="./button.tmpl">
My content
</b:include>
Результат:
<button class="button">
{caption}
<b:content>
My content
</b:content>
</button>
Здесь и далее в результате указывается
<b:content>
, хотя в реальной разметке (та что будет отдана браузеру) такого элемента нет. Это делается для того, чтобы показать где будет в результат определена точка вставки.
Весь контент внутри <b:include>
не обрамленный в специальные теги вставляется на место <b:content>
. Пример:
<button class="button">
{caption}
<b:content/>
</button>
<b:include src="./button.tmpl">
foo
<b:replace ref="caption">
replaced
</b:replace>
bar
</b:include>
Результат:
<button class="button">
replaced
<b:content>
foo
bar
</b:content>
</button>
В случае отсутствия <b:content>
в подключаемом шаблоне, считается, что <b:content>
указан в конце описания шаблона. Это повторяет поведение шаблонов до введения <b:content>
. Например:
<button class="button">
{caption}
</button>
Будет эквивалентно:
<button class="button">
{caption}
</button>
<b:content/>
Такое определение является неявным и имеет меньший приоритет по отношению к явному определению <b:content>
. (см. Наследование и крайние случаи)
Внутри <b:content>
можно указывать любую разметку. Это содержимое будет оставаться до тех пор, пока содержимое шаблона не будет подключено через <b:include>
, внутри которого есть не обрамленный в специальные теги (теги с префиксом b:
) контент.
Пример шаблона кнопки:
<button class="button">
<b:content>
{caption}
</b:content>
</button>
В таком случае, чтобы заменить содержимое новым, не нужно использовать <b:replace>
или <b:remove>
. Достаточно просто указать необходимое содержимое внутри <b:include>
не обрамляя в специальные теги:
<b:include src="./button.tmpl">
<img … /> My content
</b:include>
В результате получим:
<button class="button">
<b:content>
<img … /> My content
</b:content>
</button>
Как видно, явный <b:content>
сохранил свое местоположение, но его содержимое было заменено на новое.
Содержимое <b:content>
(дочерние токены) является такой же частью декларации как и все остальное. То есть оно доступно для любых операций с использованием ссылок.
Операции <b:replace>
, <b:remove>
, <b:prepend>
, <b:append>
и все операции связанные с атрибутами работают без изменений.
Операции <b:before>
и <b:after>
для токенов внутри <b:content>
работают так, как будто <b:content>
обычный элемент. То есть, если маркер-ссылка находится внутри <b:content>
, то новый контент вставляется внутрь <b:content>
, а не перед ним.
<button class="button">
<b:content>
{caption}
</b:content>
</button>
<b:include src="./button.tmpl">
<b:before ref="caption">
My content
</b:before>
</b:include>
Результат:
<button class="button">
<b:content>
My content{caption}
</b:content>
</button>
Для <b:content>
используется специальная ссылка - :content
(то что имя начинается с двоеточия делает невозможным задать такую ссылку другим способом, то есть используя маркеры или атрибут b:ref
).
<button class="button">
<!-- <b:before ref=":content"/> -->
<b:content>
<!-- <b:prepend ref=":content"/> -->
My content{caption}
<!-- <b:append ref=":content"/> -->
</b:content>
<!-- <b:after ref=":content"/> -->
</button>
Стоить помнить, что если во включаемом шаблоне нет <b:content>
, то операции трансформации будут производиться с неявным <b:content>
, расположенным в конце декларации.
Операции по работе с атрибутами игнорируются (с варнингом), так как это виртуальный элемент не имеющий атрибутов. Инструкции <b:add-ref>
и <b:remove-ref>
не имееют силы и выбрасывают предупреждение.
Если есть несколько определений <b:include>
, то выигрывает последнее определение по натуральному обходу дерева. Остальные определения игнорируются, то есть из декларации удаляется определение <b:content>
, но его содержимое сохраняется.
Простой случай:
<div>
<b:content> <!-- проигравший, тег будет удален, содержимое останется -->
one
</b:content>
<b:content> <!-- победитель, будет использоваться -->
two
</b:content>
</div>
Эквивалентно:
<div>
one
<b:content>
two
</b:content>
</div>
По той же логике, <b:content>
вложенный в <b:content>
так же выигрывает.
<div>
<b:content>
one
<b:content> <!-- победитель -->
two
</b:content>
</b:content>
</div>
Результат:
<div>
one
<b:content>
two
</b:content>
</div>
Если есть хотя бы одно явное определение <b:content>
, то игнорируются все неявные. При этом учитываются <b:content>
не только в описании самого шаблона, но и в описании включаемых шаблонов.
Если включается несколько шаблонов, и нужно определить явно в какой из них должно попадать содержимое при наследовании, необходимо вставить <b:content>
в нужный шаблон.
Например, шаблон источник:
<div class="section">
<b:content/>
</div>
Шаблон включающий несколько шаблонов, с явным указанием куда помещать содержимое:
<div class="layout">
<b:include src="./section.tmpl">
some content
<b:content/>
</b:include>
<b:include src="./section.tmpl">
some content
</b:include>
</div>
В данном примере, если не указать явно <b:content>
в первом <b:include>
, то контент будет вставляться во второе включение.
Если в шаблоне нет явного <b:content>
и нет явного во включаемых шаблонах, то будет использоваться неявный в самом шаблоне, который расположен в конце самого шаблона.