Интеграция html шаблонов с MODX

Интеграция html шаблонов с MODX 3 Практика разработки сайтов
MODX - это популярная система управления контентом, которая позволяет создавать сайты любой сложности. Одним из ее преимуществ является возможность интеграции с различными шаблонами, что позволяет создавать уникальный дизайн для вашего сайта. В рамках данного урока расскажу, как правильно интегрировать html шаблоны с MODX.

Перенос готовой верстки (шаблона)

Каждый html шаблон состоит из определенного набора файлов, обычно это html, css, js файлы и изображения. Также могут быть шрифты, scss файлы, php обработчики и т.д.

файлы шаблона Eterna

Скачать шаблон который используется в данном уроке, можно здесь: Шаблоны для MODX.

Для интеграции дизайна нам обычно нужно перенести на хостинг все файлы кроме html и php. В данном случае все, что нам нужно лежит в папке assets:

Содержимое папки assets

Создадим в корне сайта директорию templates и закачаем все файлы из папки assets туда. Сделать это можно при помощи файлового менеджера хостинга или через ftp/sftp. В конечном итоге получаем следующее:

Файлы шаблона залитые на сайт MODX

Примечание! Можно не выносить файлы шаблона в отдельную папку, например можно залить всю папку assets в корень, тогда в дальнейшем не придется менять пути.

Теперь можно отредактировать базовый шаблон, для этого в дереве ресурсов перейдите во вкладку «Элементы» — «Шаблоны» и отредактируем «Начальный шаблон».

Редактирование начального шаблона

Как вы видите в начальном шаблоне присутствует синтаксис MODX: [[*name]] — поля ресурсов и TV, [[++name]] — системные настройки. Мы все это будем изучать его по мере разработки сайта, а сейчас можете удалить весь код шаблона.

Чтобы код MODX шаблонов подсвечивался установите дополнение Ace.

Теперь откройте код главной страницы html шаблона — обычно это файл index.html (делать это лучше при помощи редакторов кода) скопируйте и вставьте его в место стандартного кода начального шаблона.

И так как мы загрузили шаблон в свою папку templates, нам нужно поменять пути к css, js и прочим файлам. Пример: было assets/vendor/animate.css/animate.min.css, стало templates/vendor/animate.css/animate.min.css.

В нашем случае нам нужно везде assets заменить на templates. Если вы устанавливали дополнение Ace, то выделите assets, нажмите CTRL + H, в поле замены напишите templates и напротив заменить нажмите на все.

Быстрая замена в Ace

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

Быстрая замена в Ace v 2

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

Главная страница сайта

Если у вас весь код кривой, значит вы что-то не закачали, либо поправили не все пути до файлов.

Интеграция html верстки с CMS

Интеграция html верстки с CMS — это процесс объединения дизайна и верстки сайта (html, CSS, JavaScript) с системой управления контентом (CMS), в нашем случае с MODX. Это позволяет управлять контентом сайта через интерфейс CMS, без необходимости вручную изменять код сайта.

Иными словами нам нужно превратить статический код в динамический, чтобы значительно упростить процесс управления контентом и обновления сайта, а также при необходимости создавать более сложные и функциональные сайты.

Интеграция верстки в MODX часто начинается с определения того, какие элементы сайта обычно повторяются от страницы к странице. Если открыть все наши html файлы шаблоны и посмотреть на них, то вы увидите что у всех есть повторяющиеся элементы: шапка с навигацией (header), хлебные крошки (на  всех страницах кроме главной), футер.

Сквозные элементы в шаблоне

Это все так сказать сквозные элементы, их можно вынести в отдельные чанки.

Использование чанков

Чанки способ предложить управления повторяющимся контентом в одном месте. В приведенном выше примере шаблона есть статическая навигация в верхнем и нижнем колонтитулах, это может стать проблемой, если возникла необходимость изменить текст для одной из этих ссылок. Вместо изменения текста в каждом шаблоне и десинхронизации риска было бы предпочтительно обновить его один раз, и это изменение отразится на всех шаблонах. Мы можем сделать это, используя чанки.

Сделаем хитрую систему чанков: создаем чанк tpl и переносим в него весь код из начального шаблона, вместо него выводим созданный чанк.

Выносим код шаблона в чанк

Далее открываем чанк tpl.1, находим в нем разметку карусели: Hero Section (которая выводится только на главной странице). Вырезаем ее и помещаем в новый чанк с именем: hero_section.

Выносим карусель в отдельный чанк

и соответственно вызываем его: [[$hero_section]]. Далее вырезаем из чанка tpl весь контент (не сквозные элементы, которые находятся в main) и помещаем их в чанк tpl.1 и вызываем его. На выходе должно получится следующее:

Разбили шаблон на чанки

Если сейчас открыть главную страницу, она не должна поменяться (должна остаться точно такой же как до использования чанков).

Главная страница сайта

Использование стандартных полей ресурса

Открываем чанк со сквозными элементами и прописываем поля ресурсов. Например меняем:

  <title>Eterna Bootstrap Template - Index</title>
  <meta content="" name="description">

на

  <title>[[*longtitle]]</title>
  <meta content="[[*description]]" name="description">

Ну и вызовем где ни будь в tpl.1 поле [[*content]].

Недостаточно стандартных полей, можете создать свои TV.

Использование системных настроек

Вызовем самые ходовые системные настройки:

[[++site_url]] — базовый урл (см. настройка чпу)

[[++modx_charset]] — кодировка сайта

[[++site_name]] — название сайта

[[++cultureKey]] — язык сайта

Наше начало шаблона станет таким:

<!DOCTYPE html>
<html lang="[[++cultureKey]]">
<head>
  <base href="[[++site_url]]">
  <meta charset="[[++modx_charset]]">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">
  <title>[[*longtitle]] | [[++site_name]]</title>

Так же мы можем создать свои системные настройки, сделать это проще всего при помощи дополнения ClientConfig, установите его и создайте там настройки: телефон, email, адрес, соц. сети и т.д.

Затем выведите их в нужных частях шаблона.

Использование фильтров и модификаторов

Усложним логику вывода чанков и стандартных полей, системных настроек при помощи фильтров и модификаторов.

Немного усложним вывод title, сделаем его таким:

title

Добавим meta robots:

<meta name="robots" content="[[*searchable:is=`1`:then=`index, follow`:else=`noindex, nofollow`]]">

Модифицируем вызов чанков hero_section и tpl.1.

[[*id:is=`1`:then=`[[$hero_section]]`]]

Здесь мы выводим данный чанк только у ресурса с id = 1 (главной страницы).

[[$tpl.[[*template]]]]

А в данном случае мы в зависимости от шаблона подключаем tpl.id-шаблона — зачем узнаете далее.

В конечном итоге код нашего чанка (tpl) со сквозными элементами должен принять примерно такой код:

<!DOCTYPE html>
<html lang="[[++cultureKey]]">
<head>
  <base href="[[++site_url]]">
  <meta charset="[[++modx_charset]]">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">
  <title>[[*longtitle]] | [[++site_name]]</title>
  <meta content="[[*description]]" name="description">
  <meta content="" name="keywords">
  <!-- Favicons -->
  <link href="templates/img/favicon.png" rel="icon">
  <link href="templates/img/apple-touch-icon.png" rel="apple-touch-icon">
  <!-- Google Fonts -->
  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Raleway:300,300i,400,400i,500,500i,600,600i,700,700i|Poppins:300,300i,400,400i,500,500i,600,600i,700,700i" rel="stylesheet">
  <!-- Vendor CSS Files -->
  <link href="templates/vendor/animate.css/animate.min.css" rel="stylesheet">
  <link href="templates/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
  <link href="templates/vendor/bootstrap-icons/bootstrap-icons.css" rel="stylesheet">
  <link href="templates/vendor/boxicons/css/boxicons.min.css" rel="stylesheet">
  <link href="templates/vendor/glightbox/css/glightbox.min.css" rel="stylesheet">
  <link href="templates/vendor/swiper/swiper-bundle.min.css" rel="stylesheet">
  <!-- Template Main CSS File -->
  <link href="templates/css/style.css" rel="stylesheet">
</head>
<body>
  <!-- ======= Top Bar ======= -->
  <section id="topbar" class="d-flex align-items-center">
    <div class="container d-flex justify-content-center justify-content-md-between">
      <div class="contact-info d-flex align-items-center">
        <i class="bi bi-envelope d-flex align-items-center"><a href="mailto:[[++email]]">[[++email]]</a></i>
        <i class="bi bi-phone d-flex align-items-center ms-4"><span>[[++phone]]</span></i>
      </div>
      <div class="social-links d-none d-md-flex align-items-center">
        [[++twitter:!empty=`<a href="[[++twitter]]" class="twitter"><i class="bi bi-twitter"></i></a>`]]
        [[++facebook:!empty=`<a href="[[++facebook]]" class="facebook"><i class="bi bi-facebook"></i></a>`]]
        [[++instagram:!empty=`<a href="[[++instagram]]" class="instagram"><i class="bi bi-instagram"></i></a>`]]
        [[++linkedin:!empty=`<a href="[[++linkedin]]" class="linkedin"><i class="bi bi-linkedin"></i></i></a>`]]
      </div>
    </div>
  </section>
  <!-- ======= Header ======= -->
  <header id="header" class="d-flex align-items-center">
    <div class="container d-flex justify-content-between align-items-center">
      <div class="logo">
        <h1><a href="/">[[++site_name]]</a></h1>
      </div>
      <nav id="navbar" class="navbar">
        <ul>
          <li><a class="active" href="index.html">Home</a></li>
          <li><a href="about.html">About</a></li>
          <li><a href="services.html">Services</a></li>
          <li><a href="portfolio.html">Portfolio</a></li>
          <li><a href="team.html">Team</a></li>
          <li><a href="pricing.html">Pricing</a></li>
          <li><a href="blog.html">Blog</a></li>
          <li class="dropdown"><a href="#"><span>Drop Down</span> <i class="bi bi-chevron-down"></i></a>
            <ul>
              <li><a href="#">Drop Down 1</a></li>
              <li class="dropdown"><a href="#"><span>Deep Drop Down</span> <i class="bi bi-chevron-right"></i></a>
                <ul>
                  <li><a href="#">Deep Drop Down 1</a></li>
                  <li><a href="#">Deep Drop Down 2</a></li>
                  <li><a href="#">Deep Drop Down 3</a></li>
                  <li><a href="#">Deep Drop Down 4</a></li>
                  <li><a href="#">Deep Drop Down 5</a></li>
                </ul>
              </li>
              <li><a href="#">Drop Down 2</a></li>
              <li><a href="#">Drop Down 3</a></li>
              <li><a href="#">Drop Down 4</a></li>
            </ul>
          </li>
          <li><a href="contact.html">Contact</a></li>
        </ul>
        <i class="bi bi-list mobile-nav-toggle"></i>
      </nav><!-- .navbar -->
    </div>
  </header><!-- End Header -->
  [[*id:is=`1`:then=`[[$hero_section]]`]]
  <main id="main">
    [[$tpl.[[*template]]]]
  </main><!-- End #main -->
  <!-- ======= Footer ======= -->
  <footer id="footer">
    <div class="footer-newsletter">
      <div class="container">
        <div class="row">
          <div class="col-lg-6">
            <h4>Новостная рассылка</h4>
            <p>Никакого спама, только полезный контент!</p>
          </div>
          <div class="col-lg-6">
            <form action="" method="post">
              <input type="email" name="email"><input type="submit" value="Подписаться">
            </form>
          </div>
        </div>
      </div>
    </div>
    <div class="footer-top">
      <div class="container">
        <div class="row">
          <div class="col-lg-3 col-md-6 footer-links">
            <h4>Полезные ссылки</h4>
            <ul>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Home</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">About us</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Services</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Terms of service</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Privacy policy</a></li>
            </ul>
          </div>
          <div class="col-lg-3 col-md-6 footer-links">
            <h4>Наши услуги</h4>
            <ul>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Web Design</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Web Development</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Product Management</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Marketing</a></li>
              <li><i class="bx bx-chevron-right"></i> <a href="#">Graphic Design</a></li>
            </ul>
          </div>
          <div class="col-lg-3 col-md-6 footer-contact">
            <h4>Контактная информация</h4>
            <p>
              A108 Adam Street <br>
              New York, NY 535022<br>
              United States <br><br>
              <strong>Телефон:</strong> +1 5589 55488 55<br>
              <strong>Email:</strong> info@example.com<br>
            </p>
          </div>
          <div class="col-lg-3 col-md-6 footer-info">
            <h3>About Eterna</h3>
            <p>Cras fermentum odio eu feugiat lide par naso tierra. Justo eget nada terra videa magna derita valies darta donna mare fermentum iaculis eu non diam phasellus.</p>
            <div class="social-links mt-3">
                [[++twitter:!empty=`<a class="twitter" href="[[++twitter]]"><i class="bx bxl-twitter"></i></a>`]]
                [[++facebook:!empty=`<a class="facebook" href="[[++facebook]]"><i class="bx bxl-facebook"></i></a>`]]
                [[++instagram:!empty=`<a class="instagram" href="[[++instagram]]"><i class="bx bxl-instagram"></i></a>`]]
                [[++skype:!empty=`<a class="google-plus" href="[[++skype]]"><i class="bx bxl-skype"></i></a>`]]
                [[++linkedin:!empty=`<a class="linkedin" href="[[++linkedin]]"><i class="bx bxl-linkedin"></i></i></a>`]]
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="container">
      <div class="copyright">
        &copy; Copyright <strong><span>[[++site_name]]</span></strong>. Все права защищены
      </div>
    </div>
  </footer><!-- End Footer -->
  <a href="#" class="back-to-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>
  <!-- Vendor JS Files -->
  <script src="templates/vendor/purecounter/purecounter_vanilla.js"></script>
  <script src="templates/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
  <script src="templates/vendor/glightbox/js/glightbox.min.js"></script>
  <script src="templates/vendor/isotope-layout/isotope.pkgd.min.js"></script>
  <script src="templates/vendor/swiper/swiper-bundle.min.js"></script>
  <script src="templates/vendor/waypoints/noframework.waypoints.js"></script>
  <script src="templates/vendor/php-email-form/validate.js"></script>
  <!-- Template Main JS File -->
  <script src="templates/js/main.js"></script>
</body>
</html>

Создаем дополнительные шаблоны

Пока создадим только 1 шаблон, для обычных статических страниц: о компании, политика конфиденциальности, контакты и т.п.. За основу возьмем к примеру файл team.html.

Создайте новый шаблон с именем Статика и вызовите в нем чанк tpl (в котором хранятся сквозные элементы) и сохраните его.

Создаем новый шаблон

Теперь создаем чанк с именем tpl.2 (где 2 — это id только, что созданного шаблона) и помещаем в него код который находится между в блоке main.

Создаем новый чанк

Теперь модернизируем секцию breadcrumbs, она примет вид:

    <!-- ======= Breadcrumbs ======= -->
    <section id="breadcrumbs" class="breadcrumbs">
      <div class="container">
        <ol>
          <li><a href="/">Главная</a></li>
          <li>[[*pagetitle]]</li>
        </ol>
        <h2>[[*pagetitle]]</h2>
      </div>
    </section><!-- End Breadcrumbs -->

Ее в принципе можно отправить в отдельный чанк: breadcrumbs. И вызвать чанке со сквозными элементами (tpl), вот такой конструкцией: [[*id:is=`1`:else=`[[$breadcrumbs]]`]] — выводим чанк на всех страницах кроме главной.

Выводим чанк на всех страницах, кроме главной

Теперь выкинем все лишнее (в данном случае блоки с командой) из следующей секции с контентом и выведем поле контента, в конечном итоге получим следующий код чанка (tpl.2):

<section id="team" class="team">
    <div class="container">
        [[*content]]
    </div>
</section>

Использование Сниппетов

MODX предлагает много динамики из коробки, и Сниппеты способ расширить эту динамику. Мы можем их писать сами, даже если вы не знаете PHP, можно воспользоваться к примеру чатом gpt (есть бесплатные боты в телеге, вот пример запроса и что он выдал):

Просим бота написать код для сниппета

Может не идеально, но с виду рабочий. Давайте попробуем его вывести, создаем сниппет с именем year и выше приведенным кодом:

<?php
// Получаем текущий год
$currentYear = date("Y");

// Указываем год, с которого начинается копирайтинг
$startYear = 2010;

// Если текущий год совпадает с начальным годом, выводим только один год
if ($currentYear == $startYear) {
    echo $currentYear;
} else {
    // Иначе выводим года в формате "2010 - 2021"
    echo $startYear . " - " . $currentYear;
}
?>

И вызовем его в копирайтинге:

Вызываем сниппет в копирайтинге

Переходим на сайт и проверяем:

Работает

Все работает, единственное мне не особо нравится, то что год создания (фирмы или сайта) нужно менять непосредственно в коде сниппета, модифицируем его, чтобы можно было задавать данный параметр при вызове сниппета:

<?php
$currentYear = date("Y");
if($currentYear == $startYear) {
	return $currentYear;
} else {
return ''.$startYear.' – '.$currentYear.'';
}

Теперь его можно вызывать так: [[year? &startYear=`2022`]].

Исчерпали весь базовый функционал, что дальше?

На самом деле исчерпали не все, и рассмотрели лишь базовые принципы интеграции. При помощи сниппетов или плагинов можно напрограммировать на PHP кучу всего. Но мы пойдем по пути готовых решений — будем устанавливать дополнения (многие из которых включают в себя готовые сниппеты) и сажать остатки кода на них.

Сажать сложные элементы будем на MIGX: слайдеры, однотипные блоки состоящие из многих полей, в общем все то что у главной страницы в несквозных элементах.

А вот для многого остального, нужно создать ресурсы, из них будет строится меню, собираться некоторые блоки (например вывод услуг или статей на главной) и так далее. В общем создайте пока пустые статические страницы сайта (о компании, услуги, портфолио, контакты и т.п.) с новым шаблоном Статика.

Создаем новый ресурс

И переходите к следующему уроку: создание контактных форм при помощи связки компонентов Formit + FetchIt.

Оцените статью
( Пока оценок нет )
MODX 3
Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

  1. Владимир.

    Большое спасибо за ресурс!
    Здесь не совсем понятно откуда взялось tpl.1

    Ответить
    1. Alex87 автор

      Вот эта конструкция [[$tpl.[[*template]]]] подхватывает чанки tpl.1, tpl.2, tpl.3 и т.д. Вот еще статью прочитайте https://web-revenue.ru/modx-revo/chanki — в ней описана такая же логика разбивки (возможно в ней более понятно объяснено).

      Ответить