Тег <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> и нет явного во включаемых шаблонах, то будет использоваться неявный в самом шаблоне, который расположен в конце самого шаблона.