Позиционирование блоков контента в Orchard CMS

Введение

При работе с Orchard CMS у многих возникает вопрос: как отобразить один список справа, другой слева, если весь контент выводится в @Zone(Modеl.Content)?

Эта статья является ответом на этот вопрос. Для ясности я сделал демосайт, который можно скачать себе, запустить и посмотреть, как всё работает (логин: admin, пароль: admin123) .


Иерархия шаблонов

В Orchard CMS существует следующая иерархия шаблонов.

  1. Document.cshtml — корневой шаблон.
  2. Layout.cshtml — отвечает за размещение виджетов.
  3. Content.cshtml — отвечает за размещение блоков контента.
  4. Шаблоны Shape'ов, но в данной статье мы их касаться не будем.

Document.cshtml

Самый верхний уровень — это шаблон Document.cshtml. По-умолчанию именно им рендерятся теги HTML, BODY и HEAD. Исходный Document.cshtml можно взять из папки: \src\Orchard.Web\Core\Shapes\Views\Document.cshtml.

Layout.cshtml

Layout.cshtml служит для рендеринга зоны с виджетами и самого Content Item'а. Порядок вывода виджетов в зоне задаётся в панели управления.

В качестве примера создадим Layout с двумя зонами.

Для этого нужно добавить название новых зон в файл Theme.txt:

Zones: Left, Right

Добавим виджеты в панели управления в соответствующие зоны. На изображении ниже видно, что я добавил в зоны Left и Right по одному виджету (LeftBlock и RightBlock).

Зоны Left и Right с виджетами LeftBlock и RightBlock
Зоны Left и Right с виджетами LeftBlock и RightBlock

Теперь добавляем в Layout.cshtml код для вывода зон. Например, такой, как показан ниже.

<div class="mp-left box">
	@Zone(Model.Left)
</div>
<div class="mp-center box">
	@Zone(Model.Content)
</div>
<div class="mp-right box">
	@Zone(Model.Right) 	
</div>

В итоге получаем страницу следующего вида:

Главная страница с двумя виджетами
Главная страница с двумя виджетами

Если включить модуль Url Alternates, то можно задавать специальные Layout'ы для страниц. Например, если нужен отдельный Layout для главной страницы, то он будет называться Layout-url-homepage.cshtml.

Content.cshtml и Placement.info

Следующий уровень — это Content.cshtml. Его задача разместить блоки документа, которые описаны в файле Placement.info. Имеет смысл создавать специфичный Content.cshtml для каждого Content Type. Например, для типа Page, шаблон будет называться Content-Page.cshtml.

Layout.info позволяет определять, в каких блоках и в каком прорядке будут выводиться Shape'ы. Например, в следующем коде мы определим два блока: Left и Center.

<Match ContentType="Page">
  <Place Parts_Title="Left:1"/>
  <Place Parts_Common_Body="Center:1"/>		
</Match>

В блоке Left будет выведен заголовок документа (Shape с названием Parts_Title), а в блоке Center будет выведен BodyPart, чей Shape имеет имя Parts_Common_Body. Цифры после названия блока задают порядок отображения Shape'ов внутри блока.

Затем мы просто рендерим блоки контента в Content.cshtml:

<div class="p-container">
  <div class="p-left box">
  	@Display(Model.Left)
  </div>
  <div class="p-center box">
  	@Display(Model.Center)
  </div>
</div>

На выходе мы получаем вот такую страницу:

Страница с двумя блоками контента
Страница с двумя блоками контента

Заключение

В данной статье были рассмотрены способы размещения частей контента на уровне виджетов и на уровне блоков контента в Content.cshtml. Сложным моментом может являться комбинирование этих двух приёмов в случае сложной вёрстки. Например, если нам нужно получить доступ к полям документа из Layout.cshtml, то придётся врукопашную получать ContentItem по URL.

Стоит помнить, что Widget'ы сложно редактировать контент-редактору: в них сложнее ориентироваться, чем в документах. Потому часто стоит отказываться от виджетов в пользу блоков с контентом на уровне Content.cshtml. Хорошим примером является главная страница сайта, где много различных списков и блоков. Здесь проще создать специальный Content Type для главной страницы и использовать его единожды.