Выносить настройки будем в дополнение ClientConfig. Если вы первый раз слышите о нем, сначала идем в урок с его документацией — здесь мы сосредотачиваемся исключительно на Fenom и практике.
Зачем выносить данные в настройки
В реальном проекте телефон, email, адрес, соцсети и любые повторяющиеся данные не должны храниться в шаблонах и чанках.
Причины:
- удобно редактировать (в одном месте → появляются везде);
- можно менять данные без разработчика;
- меньше дублирования;
- меньше ошибок;
- проще поддерживать проект в долгосрочной перспективе;
- хороший тон для модульных систем.
Создаём настройки
Как создавать группы и настройки есть в уроке по ClientConfig, здесь только важная практическая суть. В общем смотрим код шалона и смотрим, что из него можно вынести. Я вынес следующее:

| Название | Ключ | Тип поля | Значение |
|---|---|---|---|
| Телефон | cc_phone |
Текст | (800) 123-4567 |
| Доп. телефон | cc_dop_phone |
Текст | (800) 123-4567 |
cc_email |
Текст | mail@example.com | |
| Часы работы | сс_opening_hours |
Текст | Mon — Sat 9:00am — 6:00pm / Sunday — CLOSED |
| Адрес | cc_address |
Текст | 123 Street Name, City, England |
| Соцсети | cc_socials_json |
Code или Текстовая область |
[ |
| Логотип | cc_logo |
Изображение | img/demos/seo-2/logo.png |
| Логотип в подвале | cc_logo_footer |
Изображение | img/demos/seo-2/logo-footer.png |
| Текст в футере | cc_about |
Текстовый редактор | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc viverra lorem ipsum erat orci, ac auctor lacus tincidunt ut… |
Все настройки — это просто системные опции MODX с собственным namespace.
Получение значений в Fenom (3 способа)
Прямой вызов config: {'cc_phone' | config};
Через объект MODX: {$_modx.config.cc_phone};
Сохранить в переменную (желательно): {set $phone = 'cc_phone' | config} и соответственно вызывать ее затем так {$cc_phone}
О том почему лучше выносить в системные переменные рассказывал в прошлом уроке.
А вот Json массив выводится интереснее:
{if $json}
{set $items = $json | fromJSON}
<ul class="social-icons custom-social-icons-style-1">
{foreach $items as $item}
{if $item.url}
<li class="social-icons-{$item.name}">
<a href="{$item.url}" target="_blank" title="{$item.title}">
<i class="{$item.icon}"></i>
</a>
</li>
{/if}
{/foreach}
</ul>
{/if}
Подключение и вывод настроек в базовом шаблоне (base.tpl)
Обычно значения системных настроек подключают в верхней части шаблона, чтобы потом использовать везде:
{* Подтягиваем настройки проекта *}
{set $phone = 'cc_phone' | config}
{set $email = 'cc_email' | config}
{set $address = 'cc_address' | config}
...
<!DOCTYPE html>
<html>
<head>
...
$phone, $email, $socials доступны весь шаблон.
В конечном итоге код базового шаблона (base.tpl), должен принять примерно вот такой вид:
{set $site_name = 'site_name' | config}
{set $site_url = 'site_url' | config}
{set $culture = 'cultureKey' | config}
{set $title = ($_modx->resource.longtitle ?: $_modx->resource.pagetitle) | notags}
{set $description = $_modx->resource.description | replace :' "':' «' | replace :'"':'»'}
{set $cc_phone = 'cc_phone' | config}
{set $cc_dop_phone = 'cc_dop_phone' | config}
{set $cc_email = 'cc_email' | config}
{set $cc_opening_hours = 'cc_opening_hours' | config}
{set $cc_address = 'cc_address' | config}
{set $cc_logo = 'cc_logo' | config}
{set $cc_logo_footer = 'cc_logo_footer' | config}
{set $cc_about = 'cc_about' | config}
{set $json = 'cc_socials_json' | config}
<!DOCTYPE html>
<html lang="{$cultureKey}">
<head>
<base href="{$site_url}">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{$title}</title>
<meta name="description" content="{$description}">
<meta name="author" content="fastdevlab.com">
<!-- Favicon -->
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon" />
<link rel="apple-touch-icon" href="img/apple-touch-icon.png">
<!-- Mobile Metas -->
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, shrink-to-fit=no">
<!-- Web Fonts -->
<link id="googleFonts" href="https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700&display=swap" rel="stylesheet" type="text/css">
<!-- Vendor CSS -->
<link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="vendor/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="vendor/animate/animate.compat.css">
<link rel="stylesheet" href="vendor/simple-line-icons/css/simple-line-icons.min.css">
<link rel="stylesheet" href="vendor/owl.carousel/assets/owl.carousel.min.css">
<link rel="stylesheet" href="vendor/owl.carousel/assets/owl.theme.default.min.css">
<link rel="stylesheet" href="vendor/magnific-popup/magnific-popup.min.css">
<!-- Theme CSS -->
<link rel="stylesheet" href="css/theme.css">
<link rel="stylesheet" href="css/theme-elements.css">
<link rel="stylesheet" href="css/theme-blog.css">
<link rel="stylesheet" href="css/theme-shop.css">
<!-- Demo CSS -->
<link rel="stylesheet" href="css/demos/demo-seo-2.css">
<!-- Skin CSS -->
<link id="skinCSS" rel="stylesheet" href="css/skins/skin-seo-2.css">
<!-- Theme Custom CSS -->
<link rel="stylesheet" href="css/custom.css">
</head>
<body>
<div class="body">
<header id="header" class="header-transparent header-effect-shrink" data-plugin-options="{ 'stickyEnabled': true, 'stickyEffect': 'shrink', 'stickyEnableOnBoxed': true, 'stickyEnableOnMobile': false, 'stickyChangeLogo': true, 'stickyStartAt': 70, 'stickyHeaderContainerHeight': 70 }">
<div class="header-body border-top-0 appear-animation" data-appear-animation="fadeIn">
<div class="header-top">
<div class="container">
<div class="header-row">
<div class="header-column justify-content-start">
<div class="header-row">
<nav class="header-nav-top">
<ul class="nav nav-pills">
<li class="nav-item">
<span class="ws-nowrap custom-text-color-grey-1 text-2 ps-0"><i class="icon-envelope icons text-4 top-3 left-1 me-1"></i> <a href="mailto:{$cc_email}" class="text-color-default text-color-hover-primary">{$cc_email}</a></span>
</li>
<li class="nav-item d-none d-md-block">
<span class="ws-nowrap custom-text-color-grey-1 text-2"><i class="icon-clock icons text-4 top-3 left-1 me-1"></i> {$cc_opening_hours}</span>
</li>
</ul>
</nav>
</div>
</div>
<div class="header-column justify-content-end">
<div class="header-row">
{if $json}
{set $items = $json | fromJSON}
<ul class="header-social-icons social-icons social-icons-clean d-none d-lg-block me-3">
{foreach $items as $item}
{if $item.url}
<li class="social-icons-{$item.name}">
<a href="{$item.url}" target="_blank" title="{$item.title}">
<i class="{$item.icon}"></i>
</a>
</li>
{/if}
{/foreach}
</ul>
{/if}
<a href="tel:{$cc_phone | preg_replace : '/[^0-9+]/' : ''}" class="btn btn-tertiary font-weight-semibold text-3 px-4 custom-height-1 rounded-0 align-items-center d-none d-md-flex">
<i class="icon-phone icons text-4 me-2"></i> {$cc_phone}
</a>
</div>
</div>
</div>
</div>
</div>
<div class="header-container container">
<div class="header-row">
<div class="header-column">
<div class="header-row">
<div class="header-logo">
<a href="/">
<img alt="{$site_name}" width="126" height="32" src="{$cc_logo}">
</a>
</div>
</div>
</div>
<div class="header-column justify-content-end">
<div class="header-row">
<div class="header-nav header-nav-links order-2 order-lg-1">
<div class="header-nav-main header-nav-main-square header-nav-main-effect-2 header-nav-main-sub-effect-1">
<nav class="collapse">
<ul class="nav nav-pills" id="mainNav">
<li>
<a class="nav-link active" href="/">
Home
</a>
</li>
<li class="dropdown">
<a class="dropdown-item dropdown-toggle" href="demo-seo-2-services.html">
Services
</a>
<ul class="dropdown-menu">
<li>
<a class="nav-link" href="demo-seo-2-services.html">Overview</a>
</li>
<li>
<a class="nav-link" href="demo-seo-2-services-detail.html">Seo Services</a>
</li>
<li>
<a class="nav-link" href="demo-seo-2-services-detail.html">Email Marketing</a>
</li>
<li>
<a class="nav-link" href="demo-seo-2-services-detail.html">Data Analysis</a>
</li>
<li>
<a class="nav-link" href="demo-seo-2-services-detail.html">Digital Marketing</a>
</li>
<li>
<a class="nav-link" href="demo-seo-2-services-detail.html">Social Media Marketing</a>
</li>
</ul>
</li>
<li>
<a class="nav-link" href="demo-seo-2-blog.html">
Blog
</a>
</li>
<li>
<a class="nav-link" href="demo-seo-2-contact-us.html">
Contact Us
</a>
</li>
</ul>
</nav>
</div>
<button class="btn header-btn-collapse-nav" data-bs-toggle="collapse" data-bs-target=".header-nav-main nav">
<i class="fas fa-bars"></i>
</button>
</div>
<div class="header-nav-features header-nav-features-no-border header-nav-features-lg-show-border order-1 order-lg-2">
<div class="header-nav-feature header-nav-features-search d-inline-flex">
<a href="#" class="header-nav-features-toggle text-decoration-none" data-focus="headerSearch" aria-label="Search"><i class="fas fa-search header-nav-top-icon"></i></a>
<div class="header-nav-features-dropdown" id="headerTopSearchDropdown">
<form role="search" action="page-search-results.html" method="get">
<div class="simple-search input-group">
<input class="form-control text-1" id="headerSearch" name="q" type="search" value="" placeholder="Search...">
<button class="btn" type="submit" aria-label="Search">
<i class="fas fa-search header-nav-top-icon"></i>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<div role="main" class="main">
{block 'content'}
{/block}
</div>
<footer id="footer" class="bg-color-quaternary position-relative mt-0">
<svg class="custom-section-curved-top-7" width="100%" height="400" xmlns="http://www.w3.org/2000/svg">
<path id="svg_2" fill="#171940" stroke="#000" stroke-width="0" d="m-16.68437,95.44889c0,0 5.33335,176.00075 660.00283,93.33373c327.33474,-41.33351 503.33549,15.3334 639.00274,35.66682c135.66725,20.33342 59.66691,9.66671 358.33487,28.33346c298.66795,18.66676 268.66829,-45.00088 382.66831,-112.00048c114.00002,-66.9996 718.31698,-59.48704 1221.66946,95.563c503.35248,155.05004 -221.83202,184.10564 -243.66935,197.60521c-21.83733,13.49958 -3008.67549,-19.83371 -3008.00467,-20.83335c-0.67082,0.99964 -30.00428,-232.33469 -10.00419,-317.66839z" class="svg-fill-color-quaternary"/>
</svg>
<div class="container position-relative mt-0 mb-4">
<div class="row py-5">
<div class="col-lg-3 mb-5 mb-lg-0">
<h4 class="font-weight-bold text-color-light text-5 ls-0 pb-1 mb-2">ABOUT US</h4>
{$cc_about}
<a href="/">
<img src="{$cc_logo_footer}" class="img-fluid" alt="{$site_name}">
</a>
</div>
<div class="col-lg-3 mb-4 mb-lg-0">
<h4 class="font-weight-bold text-color-light text-5 ls-0 pb-1 mb-2">USEFUL LINKS</h4>
<ul class="list list-unstyled">
<li class="mb-1">
<a href="#">Features</a>
</li>
<li class="mb-1">
<a href="#">Pages</a>
</li>
<li class="mb-1">
<a href="#">Portfolio</a>
</li>
<li class="mb-1">
<a href="#">About Us</a>
</li>
<li class="mb-1">
<a href="#">Contact Us</a>
</li>
</ul>
</div>
<div class="col-lg-3 mb-4 mb-lg-0">
<h4 class="font-weight-bold text-color-light text-5 ls-0 pb-1 mb-2">OUR SERVICES</h4>
<ul class="list list-unstyled">
<li class="mb-1">
<a href="demo-seo-2-services-detail.html">Seo Services</a>
</li>
<li class="mb-1">
<a href="demo-seo-2-services-detail.html">Email Marketing</a>
</li>
<li class="mb-1">
<a href="demo-seo-2-services-detail.html">Data Analysis</a>
</li>
<li class="mb-1">
<a href="demo-seo-2-services-detail.html">Digital Marketing</a>
</li>
<li class="mb-1">
<a href="demo-seo-2-services-detail.html">Social Media Marketing</a>
</li>
</ul>
</div>
<div class="col-lg-3">
<h4 class="font-weight-bold text-color-light text-5 ls-0 pb-1 mb-2">CONTACT US</h4>
<ul class="list list-unstyled">
<li class="mb-1">
Address: {$cc_address}
</li>
<li class="mb-1">
Phone: <a href="tel:{$cc_dop_phone | preg_replace : '/[^0-9+]/' : ''}">{$cc_dop_phone}</a>
</li>
<li class="mb-1">
Email: <a href="emailto:{$cc_email}">{$cc_email}</a>
</li>
</ul>
{if $json}
{set $items = $json | fromJSON}
<ul class="social-icons custom-social-icons-style-1">
{foreach $items as $item}
{if $item.url}
<li class="social-icons-{$item.name}">
<a href="{$item.url}" target="_blank" title="{$item.title}">
<i class="{$item.icon}"></i>
</a>
</li>
{/if}
{/foreach}
</ul>
{/if}
</div>
</div>
</div>
<div class="footer-copyright bg-color-quaternary">
<div class="container py-2">
<hr class="bg-color-light opacity-1 mb-0">
<div class="row justify-content-center py-4">
<div class="col-auto">
<p class="text-color-light opacity-5 text-3">Porto SEO © Copyright 2025. All Rights Reserved.</p>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- Vendor -->
<script src="vendor/plugins/js/plugins.min.js"></script>
<!-- Theme Base, Components and Settings -->
<script src="js/theme.js"></script>
<!-- Demo -->
<script src="js/demos/demo-seo-2.js"></script>
<!-- Theme Custom -->
<script src="js/custom.js"></script>
<!-- Theme Initialization Files -->
<script src="js/theme.init.js"></script>
</body>
</html>
В следующем уроке разберем наш шаблон на управляемые блоки. Но перед этим рекомендую создать источник файлов для изображений (чтобы быстрее получать к ним доступ).







