Кастомні Макети і Шаблони в Magento

В попередніх статтях ми розібрали основи Magento: файли шаблону та файли макету, а в цій статті приділимо більше уваги самій логіці створення кастомних файлів блоків та макетів. Зокрема, ми розглянемо як працюють файли розмітки і блоків в Magento, і подивимось на рендеринг файлів макету.

 

Що таке файл Макету?

Файли макету (розмітки) впливають на рендеринг сторінок в інтерфейсі Magento. Ці XML-файли знаходяться за адресою app > design > frontend > [пакет тем] > [ваша тема] > layout. В цій папці можуть знаходитись файли макету для будь-якого існуючого модуля. Наприклад, модуль, що відноситься до всіх операцій з клієнтами, має власний файл макета — customer.xml, модуль каталогу — catalog.xml і т.д. Універсальний файл макету – це local.xml в папці активної теми, в якому, в основному, змінюють налаштування для будь-яких системних модулів.

 

Відкрийте для прикладу файл макету customer.xml в системній папці за адресою app > design > frontend > base > default > layout. У цьому файлі ви побачите, що всі блоки огорнуті основним тегом <layout>. Також в ньому є кілька різних тегів <{tag}>, що містять різні блоки.

 

  <!--  New customer registration (Реєстрація нового користувача)  -->   <customer_account_create translate="label">     <label>Customer Account Registration Form</label>     <!-- Mage_Customer -->     <remove name="right"/>     <remove name="left"/>       <reference name="root">      <action method="setTemplate"><template>page/1column.phtml</template></action>     </reference>     <reference name="content">      <block type="customer/form_register" name="customer_form_register" template="customer/form/register.phtml">       <block type="page/html_wrapper" name="customer.form.register.fields.before" as="form_fields_before" translate="label">        <label>Form Fields Before</label>       </block>      </block>     </reference>   </customer_account_create>          

 



Розглянемо основні моменти в цьому файлі.

Handle (“Зачіпка”)

“Зачіпка” – це основна сутність, за допомогою якої Magento ідентифікує, який блок завантажувати, коли викликається певний модуль. <customer_account_create> — це “зачіпка” конкретного модуля (Mage_Customer). А дана “зачіпка” спрацьовує, коли хтось відкриває сторінку реєстрації клієнта.

Кожна зачіпка обробляє специфічний блок. Деякі з файлів макетів містять <default> “зачіпки”. Специфічні “зачіпки” модуля рендерять вкладені блоки лише тоді, коли цей модуль рендериться браузером, в той час як “зачіпки” за замовчуванням вантажаться на більшості сторінок. Специфічні “зачіпки” створюються в налаштуваннях модуля (у файлі config.xml), а також в контролері модуля.

 

<block>

Всередині “зачіпок” є різні блоки, які вказують на файл шаблону, що має бути завантажений, коли цей блок викликається. Блоки бувають двох типів:

  1. Структуровані Блоки
  2. Блоки Контенту

 

В прикладі вище наведено два структуровані блоки: “root” і “content”, а блоки контенту – це те, що міститься всередині цих блоків.

 

Блоки контенту містять такі атрибути як, наприклад:

  • type — визначає класи блоків, в яких ми можемо задіювати різні функціональні можливості. Це URI Згрупованованого Імені Класу. В даному прикладі type customer/form_register – це посилання на клас Mage_Customer_Block_Form_Register, що розташований за адресою app/code/core/Mage/Customer/Block/Form/Register.php За типом блоку достатньо легко віднайти потрібний клас.
  • name визначає унікальне ім’я конкретного блоку для того, щоб інші блоки могли робити посилання на існуючий блок за його ім’ям і розширювати його
  • before/after — за допомогою цих атрибутів ми можемо встановити позицію нашого блоку відносно інших всередині структурованого блоку.
  • template визначає фактичне ім’я phtml файлу і шлях до нього відносно папки template активної теми (в даному прикладі app/design/frontend/[назва пакету тем]/ [назва теми]/template/customer/form/register.phtml)
  • action дозволяє нам запускати будь-яку дію (наприклад, завантажувати JavaScript, призначати шаблон і т.п.)
  • as – цей атрибут, в основному, використовується для структурованих блоків

 

<reference>

Тег <reference> використовується для розширення блоків, що вже існують. В цьому випадку, ми розширили блок основного контенту сторінки (<reference name="content">) і вставили в нього потрібний блок.

 

<remove>

Тег <remove> використовується для видалення конкретного блоку. В прикладі-коді цей тег використовується, щоб видалити праву і ліву колонки (тобто, блоки з name="left" і name="right"). Щоб видалити потрібний блок використовуйте наступний синтаксис <remove name="ім'я блоку для видалення"/>.

 

Дочірній <block>

Коли ви вкладаєте один блок в інший, цей обгорнутий блок називається дочірнім. Всякий раз, коли батьківський блок викликається за допомогою модуля, автоматично викликається і дочірній блок.

 

  <block type="core/template" name="parent" template="parent.phtml">   <block type="core/template" name="child" template="child.phtml"/>  </block>    

 

Ви також можете окремо викликати дочірній блок з наведеним нижче синтаксисом у файлі-шаблоні

echo $this->getChildHtml('дочірній-блок');

 

кореневий (root) <block>

Відкрийте файл макету page.xml, і ви знайдете <root> блок, що виглядає як в прикладі нижче

 

  <block type="page/html" name="root" output="toHtml" template="page/3columns.phtml">    

 

Magento починає рендеринг сторінки з кореневого root блоку. Всі інші блоки є дочірніми блоками відносно кореневого блоку. Кореневий блок визначає структуру сторінки. Так, в даному прикладі, по дефолту виставлений шаблон 3columns.phtml, але це можна змінити, наприклад, на шаблон з однією колонкою (1column.phtml) за допомогою файлу розмітки теми local.xml.

 

Додавання CSS і JavaScript через XML Макет

Для будь-якої конкретної сторінки ви можете додати будь-які CSS і/або JavaScript файли через теги макету, як показано нижче:

 

  <customer_account_create>   <reference name="head">    <action method="addCss"><stylesheet>css/styles.css</stylesheet></action>    <action method="addJs"><script>varien/js.js</script></action>   </reference>  </customer_account_create>    

 

З цього прикладу видно, що ми додали файл CSS і JavaScript-файл всередині секції <head> на сторінку створення акаунту клієнта.

 

Ще раз повторимо про Класи Блоків

Класи Блоків використовуються для визначення функцій, які є специфічними для конкретного блоку. Файли класу блоку знаходяться в папці app > code > local/community/core > [простір імен модуля]  > [назва модуля] > Block. Ці файли містять функції, які ми можемо використовувати безпосередньо з ключовим словом $this в блоці конкретного файлу шаблону. Давайте розглянемо один приклад, щоб зрозуміти класи блоків.

Перейдіть до файлу review.xml, що розташований в папці app > design > frontend > base > default > layout та знайдіть представлений нижче код:

 

  <!--  Customer account home dashboard layout (Макет домашньої сторінки акаунту клієнта )  -->     <customer_account_index>     <!-- Mage_Review -->   <reference name="customer_account_dashboard">     <block type="review/customer_recent" name="customer_account_dashboard_info1" as="info1" template="review/customer/recent.phtml"/>   </reference>     </customer_account_index>    

 

Тут ви можете побачити блок review/customer_recent із шаблоном recent.phtml. Перейдіть до app > design > frontend > base > default > template > review > customer і відкрийте файл recent.phtml.

На початку цього файлу ви можете побачити дві функції, що викликаються за допомогою ключового слова $this. Це $this->getCollection() та $this->count(). Ці функції визначені в файлі Recent.php свого класу блока, що знаходиться в папці app > code > core > Mage > Review > Block > Customer.

Так, блок type="review/customer_recent" відноситься до класу блоку Mage_Review_Block_Customer_Recent, що визначений у файлі Recent.php. Незалежно від функцій, які ви визначаєте в цьому класі, ви можете безпосередньо використовувати їх у відповідному файлі шаблону із ключовим $this.

 

Створення файлів Макету і Блоків користувацького модуля

І, нарешті, нам залишилося розібратися із налаштуванням кастомного Макету і блоків для модуля.  Отже, для початку створіть тестовий модуль “Hello World” в локальному середовищі розробки.

Розгорніть наступну структуру модуля:

  • app/code/local/Test/Helloworld/Block
  • app/code/local/Test/Helloworld/controllers
  • app/code/local/Test/Helloworld/etc

 

Для створення файлу макета, необхідно спочатку створити файл класу блока. Перед тим, як додати файл класу, ми повинні оголосити в нашому модулі, що ми включаємо файли блоку. Тож перейдіть до app > code > local > Test > Helloworld > etc, створіть файл налаштувань модуля config.xml і додайте в нього наступні рядки коду:

 

  <?xml version="1.0"?>  <config>    <modules>     <Test_Helloworld>      <version>0.1.0</version> <!-- Версія модуля -->     </Test_Helloworld>    </modules>    <frontend>     <routers> <!-- Додаємо контролер, щоб перевірити роботу модуля -->      <helloworld>       <use>standard</use>       <args>        <module>Test_Helloworld</module>        <frontName>helloworld</frontName>       </args>      </helloworld>     </routers>    <layout>     <updates>      <helloworld>       <file>helloworld.xml</file> <!-- Назва нашого файлу макету -->      </helloworld>     </updates>    </layout>    </frontend>    <global>     <blocks>      <helloworld>       <class>Test_Helloworld_Block</class>      </helloworld>     </blocks>    </global>  </config>      

 

Створюємо файл Класу Блока

Тепер перейдіть до app > code > local > Test > Helloworld > Block і створіть файл Helloworld.php, що містить такі рядки коду

 

  <?php  class Test_Helloworld_Block_Helloworld extends Mage_Core_Block_Template  {   public function myTestFunction()    {     echo "Привіт, світ!";    }  }    

 

Тут ми оголосили клас Test_Helloworld_Block_Helloworld, що містить функцію myTestFunction, яку ми можемо викликати прямо з нашого файлу шаблона.

 

Не забудьте включити створений модуль:

додайте файл Test_Helloworld.xml з наведеним нижче контентом у папку app/etc/modules/

  <config>   <modules>    <Test_Helloworld>     <active>true</active>     <codePool>local</codePool>    </Test_Helloworld>   </modules>  </config>    

 

Створюємо XML файл Макету

Перейдіть до app > design > frontend > [назва пакету тем] > [назва вашої теми] > layout і створіть файл helloworld.xml, який містить такі рядки коду

 

  <?xml version="1.0" encoding="UTF-8"?>  <layout version="0.1.0">   <helloworld_index_index>    <reference name="content">     <block type="helloworld/helloworld" name="helloworld_block" template="helloworld/helloworld-shablon.phtml" />    </reference>   </helloworld_index_index>  </layout>    

 

<helloworld_index_index> – це «зачіпка»; спрацьовує для контролера IndexController при відкритті в браузері посилання {домен}/helloworld/index/. Назва «зачіпки» (частина лінка) вказується в налаштуваннях модуля в секції <routers><frontName>helloworld</frontName></routers>

 

Створюємо файл Шаблону

Створіть папку для шаблона в app > design > frontend > [назва пакету тем] > [назва вашої теми] > template > helloworld і створіть в ній файл-шаблон helloworld-shablon.phtml. У цьому файлі ми будемо викликати функцію myTestFunction, яку ми оголосили в нашому класі блоку.

 

  <?php   echo $this->myTestFunction();  ?>    

 

Тепер додамо контролер для перевірки роботи модуля

Створіть файл IndexController.php в папці app > code > local > Test > Helloworld > controllers

із наступним змістом:

  <?php    class Test_Helloworld_IndexController extends Mage_Core_Controller_Front_Action {    public function indexAction() {     $this->loadLayout();     $this->renderLayout();   }     }    

 

Якщо у вас включений кеш, то оновіть його. Тепер для перевірки відкрийте сторінку http://{ваш-домен}/helloworld/index/ (або ж просто http://{ваш-домен}/helloworld/). Якщо ми все зробили правильно, то ви побачите в результаті показ контенту із шаблона helloworld-shablon.phtml.

 

 

Ось як працюють макети в Magento. Структура макетів Magento спочатку видається трохи дивною та незрозумілою, але як тільки ви починаєте розбиратися з макетами, ви легко зрозумієте ідею, що стоїть за нею.

Не соромтеся коментувати і ставити будь-які питання, що відносяться до цього конкретного посту.

 

 

Стаття адаптована, на основі перекладу спеціально для сайту Tuts+