2026-08-30 Правки секции hero

This commit is contained in:
Dekart Deploy Bot 2026-08-30 15:07:57 +00:00
parent 37d9611978
commit e2a010af97
13 changed files with 1627 additions and 2 deletions

View File

@ -0,0 +1,603 @@
/* ============================================================
Страница КЛАССА начальной школы (page-class.php)
Наследует дизайн-токены main.css + базовые стили front-page/school.
Акцент: --color-primary #2563EB. Кнопки: .btn-write.btn-primary.
============================================================ */
/* ── Hero (тёмная тема, как ds-hero) ─────────────────────── */
.class-hero {
background:
radial-gradient(1200px 600px at 85% -10%, rgba(37, 99, 235, 0.35), transparent 60%),
radial-gradient(900px 500px at -10% 110%, rgba(37, 99, 235, 0.18), transparent 60%),
#0f172a;
color: #fff;
padding: 72px 0 88px;
overflow: hidden;
}
.class-hero__inner {
display: grid;
grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
gap: 56px;
align-items: center;
}
.class-hero__badge {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 14px;
border-radius: 999px;
background: rgba(37, 99, 235, 0.16);
border: 1px solid rgba(37, 99, 235, 0.45);
color: #bfdbfe;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.02em;
margin-bottom: 20px;
}
.class-hero__h1 {
font-family: var(--font-display);
font-size: clamp(2rem, 3.4vw, 3rem);
font-weight: 700;
line-height: 1.15;
margin: 0 0 18px;
text-wrap: balance;
color: #fff;
}
.class-hero__subtitle {
font-size: clamp(1rem, 1.2vw, 1.125rem);
line-height: 1.7;
color: #cbd5e1;
max-width: 56ch;
margin: 0 0 22px;
text-wrap: pretty;
}
.class-hero__social-proof {
display: flex;
align-items: center;
gap: 8px;
color: #94a3b8;
font-size: 14px;
margin-bottom: 28px;
}
.class-hero__social-proof svg {
color: #fbbf24;
flex-shrink: 0;
}
.class-hero__actions {
display: flex;
align-items: center;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 36px;
}
.class-hero__cta {
min-width: 260px;
}
.class-hero__phone {
color: #e2e8f0;
font-size: 18px;
font-weight: 600;
text-decoration: none;
border-bottom: 1px solid rgba(148, 163, 184, 0.4);
transition: color 0.2s, border-color 0.2s;
}
.class-hero__phone:hover {
color: #fff;
border-color: #fff;
}
.class-hero__stats {
list-style: none;
margin: 0;
padding: 0;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
max-width: 480px;
}
.class-hero__stat {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 14px;
padding: 14px 16px;
display: flex;
flex-direction: column;
gap: 4px;
}
.class-hero__stat-number {
font-family: var(--font-display);
font-size: 22px;
font-weight: 700;
color: #fff;
white-space: nowrap;
}
.class-hero__stat-label {
font-size: 13px;
color: #94a3b8;
}
.class-hero__visual {
position: relative;
}
.class-hero__visual-glow {
position: absolute;
inset: -10%;
background: radial-gradient(closest-side, rgba(37, 99, 235, 0.35), transparent 70%);
z-index: 0;
pointer-events: none;
}
.class-hero__photo {
position: relative;
z-index: 1;
width: 100%;
height: auto;
aspect-ratio: 3 / 2;
object-fit: cover;
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.6);
}
/* ── Программа ───────────────────────────────────────────── */
.class-program,
.class-schedule,
.class-testimonials,
.class-faq {
padding: 72px 0;
background: #fff;
}
.class-program[data-bg="class-program"],
.class-testimonials[data-bg="class-testimonials"] {
background: #f8fafc;
}
.class-program__text {
max-width: 72ch;
}
.class-program__grid {
list-style: none;
margin: 32px 0 0;
padding: 0;
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 20px;
}
.class-program__card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 18px;
padding: 26px 22px;
transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.class-program__card:hover {
transform: translateY(-4px);
border-color: rgba(37, 99, 235, 0.35);
box-shadow: 0 16px 40px -16px rgba(15, 23, 42, 0.16);
}
.class-program__icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 52px;
height: 52px;
border-radius: 14px;
background: var(--color-primary-light);
margin-bottom: 16px;
}
.class-program__icon img {
filter: saturate(1);
}
.class-program__card-title {
font-family: var(--font-display);
font-size: 17px;
font-weight: 700;
margin: 0 0 8px;
color: var(--color-text);
}
.class-program__card-text {
font-size: 14px;
line-height: 1.6;
color: var(--color-text-muted);
margin: 0;
}
.class-program__gallery {
margin-top: 40px;
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 16px;
}
.class-program__gallery-item {
margin: 0;
}
.class-program__gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 4 / 3;
border-radius: 16px;
display: block;
}
.class-program__gallery-item--wide {
grid-column: span 2;
grid-row: span 2;
}
.class-program__gallery-item--wide img {
aspect-ratio: auto;
}
/* ── Расписание и стоимость ──────────────────────────────── */
.class-schedule__layout {
display: grid;
grid-template-columns: minmax(0, 1.5fr) minmax(0, 0.5fr);
gap: 28px;
align-items: start;
margin-top: 32px;
}
.class-schedule__table-wrap {
overflow-x: auto;
border: 1px solid #e2e8f0;
border-radius: 18px;
}
.class-schedule__table {
width: 100%;
border-collapse: collapse;
font-size: 15px;
}
.class-schedule__table th {
text-align: left;
padding: 14px 18px;
background: #f1f5f9;
color: var(--color-text);
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
border-bottom: 1px solid #e2e8f0;
}
.class-schedule__table td {
padding: 12px 18px;
border-bottom: 1px solid #f1f5f9;
color: var(--color-text);
}
.class-schedule__table tbody tr:last-child td {
border-bottom: none;
}
.class-schedule__table tbody tr {
transition: background 0.15s;
}
.class-schedule__table tbody tr:hover {
background: #f8fafc;
}
.class-price {
background:
radial-gradient(500px 300px at 100% 0%, rgba(37, 99, 235, 0.14), transparent 60%),
#0f172a;
color: #fff;
border-radius: 18px;
padding: 30px 26px;
display: flex;
flex-direction: column;
gap: 10px;
position: sticky;
top: 24px;
}
.class-price__label {
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #94a3b8;
}
.class-price__amount {
font-family: var(--font-display);
font-size: 28px;
font-weight: 700;
line-height: 1.2;
color: #fff;
}
.class-price__note {
font-size: 14px;
color: #cbd5e1;
margin: 0 0 12px;
}
.class-price__cta {
width: 100%;
}
/* ── Отзывы ──────────────────────────────────────────────── */
.class-testimonials__grid {
margin-top: 32px;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 20px;
}
.class-testimonials__card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 18px;
padding: 28px 24px;
display: flex;
flex-direction: column;
gap: 14px;
}
.class-testimonials__stars {
display: flex;
gap: 3px;
color: #fbbf24;
}
.class-testimonials__text {
margin: 0;
font-size: 15px;
line-height: 1.7;
color: var(--color-text);
}
.class-testimonials__author {
display: flex;
align-items: center;
gap: 12px;
margin-top: auto;
padding-top: 14px;
border-top: 1px solid #f1f5f9;
}
.class-testimonials__avatar {
width: 44px;
height: 44px;
border-radius: 50%;
object-fit: cover;
}
.class-testimonials__name {
font-style: normal;
font-weight: 600;
font-size: 15px;
color: var(--color-text);
}
/* ── FAQ ──────────────────────────────────────────────────── */
.class-faq__list {
margin-top: 28px;
max-width: 820px;
}
.class-faq__item {
border: 1px solid #e2e8f0;
border-radius: 14px;
margin-bottom: 12px;
background: #fff;
overflow: hidden;
}
.class-faq__question {
cursor: pointer;
list-style: none;
padding: 18px 22px;
font-family: var(--font-display);
font-size: 16px;
font-weight: 600;
color: var(--color-text);
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
transition: background 0.15s;
}
.class-faq__question::-webkit-details-marker {
display: none;
}
.class-faq__question::after {
content: "+";
font-size: 22px;
font-weight: 400;
color: var(--color-primary);
flex-shrink: 0;
transition: transform 0.2s ease;
}
.class-faq__item[open] .class-faq__question {
background: #f8fafc;
}
.class-faq__item[open] .class-faq__question::after {
transform: rotate(45deg);
}
.class-faq__answer {
padding: 0 22px 18px;
font-size: 15px;
line-height: 1.7;
color: var(--color-text-muted);
}
/* ── Финальный CTA ───────────────────────────────────────── */
.class-cta {
padding: 72px 0;
background:
radial-gradient(900px 400px at 50% -20%, rgba(37, 99, 235, 0.3), transparent 60%),
#0f172a;
color: #fff;
text-align: center;
}
.class-cta__inner {
max-width: 720px;
margin: 0 auto;
}
.class-cta__title {
font-family: var(--font-display);
font-size: clamp(1.5rem, 2.5vw, 2.25rem);
font-weight: 700;
line-height: 1.2;
margin: 0 0 14px;
text-wrap: balance;
color: #fff;
}
.class-cta__text {
font-size: 1.0625rem;
line-height: 1.7;
color: #cbd5e1;
margin: 0 0 28px;
text-wrap: pretty;
}
.class-cta__actions {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 22px;
}
.class-cta__phone {
color: #e2e8f0;
font-size: 18px;
font-weight: 600;
text-decoration: none;
border-bottom: 1px solid rgba(148, 163, 184, 0.4);
transition: color 0.2s, border-color 0.2s;
}
.class-cta__phone:hover {
color: #fff;
border-color: #fff;
}
.class-cta__msgs {
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
flex-wrap: wrap;
}
.class-cta__msgs-label {
font-size: 14px;
color: #94a3b8;
}
.class-cta__msg {
padding: 8px 16px;
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e2e8f0;
font-size: 14px;
font-weight: 600;
text-decoration: none;
transition: background 0.2s, color 0.2s;
}
.class-cta__msg:hover {
background: rgba(255, 255, 255, 0.1);
color: #fff;
}
/* ── Адаптив ─────────────────────────────────────────────── */
@media (max-width: 1024px) {
.class-hero__inner {
grid-template-columns: 1fr;
gap: 40px;
}
.class-program__grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.class-schedule__layout {
grid-template-columns: 1fr;
}
.class-price {
position: static;
}
}
@media (max-width: 768px) {
.class-hero,
.class-program,
.class-schedule,
.class-testimonials,
.class-faq,
.class-cta {
padding: 48px 0 56px;
}
.class-hero__stats {
grid-template-columns: 1fr 1fr;
}
.class-program__grid,
.class-testimonials__grid {
grid-template-columns: 1fr;
}
.class-program__gallery {
grid-template-columns: 1fr 1fr;
}
.class-program__gallery-item--wide {
grid-column: span 2;
grid-row: auto;
}
.class-program__gallery-item--wide img {
aspect-ratio: 4 / 3;
}
.class-schedule__table th {
display: none;
}
.class-schedule__table td {
display: block;
padding: 8px 16px;
border-bottom: none;
}
.class-schedule__table td::before {
content: attr(data-label);
display: block;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
color: #64748b;
margin-bottom: 2px;
}
.class-schedule__table tbody tr {
display: block;
padding: 8px 0;
border-bottom: 1px solid #f1f5f9;
}
}

View File

@ -775,9 +775,37 @@
/* ── Mobile hero: CTA выше, secondary info ниже ── */
@media (max-width: 768px) {
.ds-hero {
padding-top: 24px;
}
.ds-hero__inner {
align-items: stretch;
}
.ds-hero__h1 {
display: inline-block;
width: fit-content;
font-size: clamp(28px, 7.5vw, 32px);
letter-spacing: -0.01em;
text-wrap: balance;
padding: 8px 16px;
background: linear-gradient(90deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.04) 100%);
border-left: 4px solid var(--color-primary);
border-radius: 12px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
}
.ds-hero__h1::after {
width: 80px;
height: 4px;
margin-top: 12px;
box-shadow: 0 0 12px var(--color-primary);
}
.ds-hero__content {
display: flex;
flex-direction: column;
width: 100%;
max-width: 100%;
}
.ds-hero__content .ds-hero__cta-btn {
order: 1;
@ -792,6 +820,41 @@
.ds-hero__content .ds-hero__messengers {
order: 2;
}
.ds-hero__h1,
.ds-hero__subtitle,
.ds-hero__rating-text,
.ds-hero__social-proof,
.ds-hero__seats,
.ds-hero__phone,
.ds-hero__assurance-item,
.ds-hero__msg,
.ds-hero__mobile-usp {
overflow-wrap: break-word;
word-break: break-word;
hyphens: auto;
}
.ds-hero__address {
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 8px;
width: fit-content;
max-width: 100%;
padding: 6px 16px;
background: rgba(255, 255, 255, 0.12);
border-radius: 100px;
margin-bottom: 24px;
}
.ds-hero__hours-badge {
padding: 0;
background: transparent;
border-radius: 0;
max-width: 100%;
}
.ds-hero__seats {
white-space: normal;
max-width: 100%;
}
.ds-hero__assurance {
flex-direction: column;
gap: 4px;
@ -1530,7 +1593,11 @@
@media (max-width: 860px) {
.sticky-cta-mobile { display: block; }
body { padding-bottom: 76px; }
body.home { padding-top: 76px; padding-bottom: 76px; }
.main-page { padding-top: 0; }
}
@media (min-width: 861px) {
.main-page { padding-top: 0; }
}
@media (max-width: 380px) {
.sticky-cta-mobile__text { font-size: 0.8125rem; }

View File

@ -0,0 +1,26 @@
/**
* Страница КЛАССА начальной школы (page-class.php)
* Лёгкие улучшения: плавная прокрутка к якорю формы записи.
* Reveal-анимации (IntersectionObserver) глобальные в add.js.
*
* @package Dekart
*/
(function () {
'use strict';
// Плавная прокрутка к якорю #form / #class-cta
document.querySelectorAll('a[href^="#"]').forEach(function (anchor) {
anchor.addEventListener('click', function (event) {
var id = this.getAttribute('href');
if (!id || id === '#') {
return;
}
var target = document.querySelector(id);
if (!target) {
return;
}
event.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
});
})();

View File

@ -64,6 +64,53 @@ add_filter('pre_option_blogname', function ($default) {
add_filter('wpseo_json_ld_output', '__return_false');
/* --- Удаляем мета из YOASTSEO END --- */
// ────────────────────────────────────────────────────
// SEO: страница КЛАССА (page-class.php) — переопределение
// Yoast-мета из вкладки «📊 SEO» (Настройки Страницы Класса)
// ────────────────────────────────────────────────────
add_filter('wpseo_title', function ($title) {
if (! is_page_template('page-class.php')) {
return $title;
}
$seo_title = carbon_get_post_meta(get_the_ID(), 'class_seo_title');
return $seo_title ?: $title;
}, 20);
add_filter('wpseo_metadesc', function ($desc) {
if (! is_page_template('page-class.php')) {
return $desc;
}
$seo_desc = carbon_get_post_meta(get_the_ID(), 'class_seo_description');
return $seo_desc ?: $desc;
}, 20);
add_filter('wpseo_opengraph_image', 'dekart_class_og_image', 20);
add_filter('wpseo_twitter_image', 'dekart_class_og_image', 20);
function dekart_class_og_image($img)
{
if (! is_page_template('page-class.php')) {
return $img;
}
$og_id = carbon_get_post_meta(get_the_ID(), 'class_seo_og_image');
if ($og_id) {
$src = wp_get_attachment_image_url((int) $og_id, 'full');
if ($src) {
return $src;
}
}
return $img;
}
add_filter('wpseo_robots', function ($robots) {
if (! is_page_template('page-class.php')) {
return $robots;
}
if (carbon_get_post_meta(get_the_ID(), 'class_seo_noindex')) {
$robots['index'] = 'noindex';
}
return $robots;
}, 20);
// ────────────────────────────────────────────────────
// Hero-изображение как OG/Twitter image для главной
// ────────────────────────────────────────────────────
@ -1142,6 +1189,167 @@ function add_carbon()
Field::make('textarea', 'block_text_3', 'Текст для блока «Семейные классы в Щёлково» (зарезервировано)'),
));
// ====================================================
// Страница КЛАССА начальной школы (page-class.php)
// ====================================================
Container::make('post_meta', '🏫 Настройки Страницы Класса')
->where('post_template', '=', 'page-class.php')
->add_tab('🖼️ HERO', array(
Field::make('html', 'class_hero_tab_desc', '')
->set_html('<p style="color:#64748b;font-size:13px;margin:0 0 12px;">Главный экран страницы класса. Заголовок H1 — под поисковый запрос «частная школа [N] класс [город]». Фото — горизонтальное 1200×800px, WebP/JPEG, до 2 МБ.</p>'),
Field::make('text', 'class_hero_title', 'Заголовок H1')
->set_width(60)
->set_default_value('Частная школа 1 класс в Щёлково')
->set_help_text('Главный заголовок. Пример: «Частная школа 2 класс в Щёлково: набор 2026/27».'),
Field::make('image', 'class_hero_image', 'Фото героя')
->set_width(40)
->set_help_text('Горизонтальное фото 1200×800px. Показывается в правой части героя.'),
Field::make('textarea', 'class_hero_subtitle', 'Подзаголовок')
->set_default_value('Мини-класс до 15 учеников, учитель начальных классов и английский каждый день. Официальное прикрепление к московской школе — аттестат государственного образца.')
->set_help_text('Короткий текст под заголовком (23 предложения). Можно выделять важное <strong>жирным</strong>.'),
Field::make('html', 'class_hero_btn_sep', '')
->set_html('<hr style="margin:16px 0;border:none;border-top:1px solid #e2e8f0;"><h3 style="margin:0 0 8px;font-size:13px;color:#475569;">🔘 Кнопка записи</h3><p style="color:#94a3b8;font-size:12px;margin:0 0 8px;">Единая CTA на странице. Ведите на форму записи или мессенджер.</p>'),
Field::make('text', 'class_hero_btn_text', 'Текст кнопки')
->set_width(50)
->set_default_value('Записаться на пробный урок')
->set_help_text('Конверсионный интент: «Записаться на пробный урок» / «Записаться на экскурсию».'),
Field::make('text', 'class_hero_btn_url', 'Ссылка кнопки')
->set_width(50)
->set_default_value('#form')
->set_help_text('URL формы записи, страницы контактов или мессенджера. Начинается с /.'),
Field::make('html', 'class_hero_stats_sep', '')
->set_html('<hr style="margin:16px 0;border:none;border-top:1px solid #e2e8f0;"><h3 style="margin:0 0 8px;font-size:13px;color:#475569;">📊 Показатели статистики</h3><p style="color:#94a3b8;font-size:12px;margin:0 0 8px;">3 карточки с цифрами под заголовком.</p>'),
Field::make('complex', 'class_hero_stats', 'Показатели')
->set_layout('tabbed-horizontal')
->add_fields(array(
Field::make('text', 'stat_number', 'Число')
->set_width(30)
->set_help_text('Например: до 15, 5, 8:30.'),
Field::make('text', 'stat_label', 'Подпись')
->set_width(70)
->set_help_text('Например: человек в классе, дней в неделю, старт занятий.'),
)),
))
->add_tab('📚 Программа', array(
Field::make('html', 'class_program_tab_desc', '')
->set_html('<p style="color:#64748b;font-size:13px;margin:0 0 12px;">Программа обучения класса: описание + список предметов (68 карточек) + галерея фото класса. Рекомендуемый объём текста 200300 символов.</p>'),
Field::make('text', 'class_program_title', 'Заголовок блока')
->set_default_value('Программа обучения'),
Field::make('rich_text', 'class_program_text', 'Описание программы')
->set_help_text('23 абзаца об учебном плане класса. Укажите ключевые предметы и особенности.'),
Field::make('complex', 'class_program_items', 'Предметы')
->set_layout('tabbed-horizontal')
->set_help_text('Рекомендуется 68 карточек. Иконка — название из набора (book, math, pen, globe, music, art, sport, science, computer, shield).')
->add_fields(array(
Field::make('text', 'item_icon', 'Иконка')
->set_width(20)
->set_help_text('book, math, pen, globe, music, art, sport, science, computer, shield.'),
Field::make('text', 'item_title', 'Название предмета')
->set_width(40),
Field::make('textarea', 'item_text', 'Краткое описание')
->set_width(40)
->set_help_text('12 предложения. Что изучают, результат.'),
)),
Field::make('html', 'class_gallery_sep', '')
->set_html('<hr style="margin:16px 0;border:none;border-top:1px solid #e2e8f0;"><h3 style="margin:0 0 8px;font-size:13px;color:#475569;">📸 Фото класса</h3><p style="color:#94a3b8;font-size:12px;margin:0 0 8px;">34 фото 800×600px, WebP/JPEG. Выводятся галереей.</p>'),
Field::make('complex', 'class_program_gallery', 'Галерея')
->set_layout('tabbed-horizontal')
->add_fields(array(
Field::make('image', 'gallery_image', 'Фото')
->set_help_text('Рекомендуемый размер 800×600px.'),
)),
))
->add_tab('👨‍🏫 Преподаватели', array(
Field::make('html', 'class_teachers_tab_desc', '')
->set_html('<p style="color:#64748b;font-size:13px;margin:0 0 12px;">Учителя класса. Выберите преподавателей из картотеки «Преподаватели». Если ничего не выбрано — покажутся все преподаватели школы.</p>'),
Field::make('text', 'class_teachers_title', 'Заголовок блока')
->set_default_value('Преподаватели класса'),
Field::make('text', 'class_teachers_subtitle', 'Подзаголовок')
->set_default_value('Учитель начальных классов и педагоги-предметники, которые ведут уроки в этом классе')
->set_help_text('Короткий текст под заголовком.'),
Field::make('association', 'class_teachers', 'Преподаватели')
->set_types(array(
array('type' => 'post', 'post_type' => 'teacher'),
))
->set_max(12)
->set_help_text('Выберите учителей для этого класса. Пусто = показать всех преподавателей школы.'),
))
->add_tab('🗓 Расписание и стоимость', array(
Field::make('html', 'class_schedule_tab_desc', '')
->set_html('<p style="color:#64748b;font-size:13px;margin:0 0 12px;">Расписание занятий класса и стоимость обучения. Если стоимость не заполнена — подтянется глобальная цена из настроек филиала.</p>'),
Field::make('text', 'class_schedule_title', 'Заголовок блока')
->set_default_value('Расписание и стоимость'),
Field::make('complex', 'class_schedule', 'Расписание')
->set_layout('tabbed-horizontal')
->set_help_text('510 строк: день недели, время, предмет.')
->add_fields(array(
Field::make('select', 'schedule_day', 'День')
->set_width(25)
->add_options(array(
'Понедельник' => 'Понедельник',
'Вторник' => 'Вторник',
'Среда' => 'Среда',
'Четверг' => 'Четверг',
'Пятница' => 'Пятница',
)),
Field::make('text', 'schedule_time', 'Время')
->set_width(25)
->set_help_text('Например: 9:009:45.'),
Field::make('text', 'schedule_subject', 'Предмет')
->set_width(50)
->set_help_text('Например: Математика.'),
)),
Field::make('html', 'class_price_sep', '')
->set_html('<hr style="margin:16px 0;border:none;border-top:1px solid #e2e8f0;"><h3 style="margin:0 0 8px;font-size:13px;color:#475569;">💰 Стоимость</h3><p style="color:#94a3b8;font-size:12px;margin:0 0 8px;">Оставьте пустым, чтобы взять глобальную цену из настроек филиала.</p>'),
Field::make('text', 'class_price_text', 'Стоимость обучения')
->set_width(60)
->set_help_text('Например: 45 000 ₽ / месяц. Пусто = глобальная цена филиала.'),
Field::make('text', 'class_price_note', 'Примечание к цене')
->set_width(40)
->set_help_text('Например: «включая питание и продлёнку».'),
))
->add_tab('💬 Отзывы', array(
Field::make('html', 'class_reviews_tab_desc', '')
->set_html('<p style="color:#64748b;font-size:13px;margin:0 0 12px;">Отзывы родителей о школе. Выберите из картотеки «Отзывы». Если ничего не выбрано — покажутся последние отзывы школы.</p>'),
Field::make('text', 'class_reviews_title', 'Заголовок блока')
->set_default_value('Отзывы родителей'),
Field::make('association', 'class_reviews', 'Отзывы')
->set_types(array(
array('type' => 'post', 'post_type' => 'reviews'),
))
->set_max(6)
->set_help_text('Выберите 36 отзывов. Пусто = последние отзывы из картотеки.'),
))
->add_tab('❓ FAQ', array(
Field::make('html', 'class_faq_tab_desc', '')
->set_html('<p style="color:#64748b;font-size:13px;margin:0 0 12px;">Вопросы-ответы о классе. Выводятся на странице и в микроразметке FAQPage (для поисковой выдачи). Рекомендуется 46 пар.</p>'),
Field::make('text', 'class_faq_title', 'Заголовок блока')
->set_default_value('Часто задаваемые вопросы'),
Field::make('complex', 'class_faq_items', 'Вопросы')
->set_layout('tabbed-horizontal')
->add_fields(array(
Field::make('textarea', 'faq_question', 'Вопрос')
->set_width(50),
Field::make('textarea', 'faq_answer', 'Ответ')
->set_width(50)
->set_help_text('Развёрнутый ответ 13 предложения.'),
)),
))
->add_tab('📊 SEO', array(
Field::make('html', 'class_seo_tab_desc', '')
->set_html('<p style="color:#64748b;font-size:13px;margin:0 0 12px;">SEO-поля страницы класса. Основные title/description задаёт Yoast SEO (блок ниже редактора). Эти поля переопределяют их и используются в Schema.org разметке. Заполнять по желанию — при пустых значениях берутся Yoast/стандартные.</p>'),
Field::make('text', 'class_seo_title', 'SEO-заголовок (title)')
->set_width(60)
->set_help_text('Пример: «Частная школа 3 класс в Щёлково — набор 2026/27». 5060 символов.'),
Field::make('textarea', 'class_seo_description', 'SEO-описание (meta description)')
->set_width(40)
->set_help_text('140160 символов, с ключевым запросом и призывом.'),
Field::make('image', 'class_seo_og_image', 'Open Graph картинка')
->set_help_text('1200×630px, JPEG/PNG. Для соцсетей.'),
Field::make('checkbox', 'class_seo_noindex', 'Не индексировать (noindex)')
->set_help_text('Включите, если страница-черновик или дубль.'),
));
// ====================================================
// Доп поля для страницы "ВСЕ КУРСЫ"
// ====================================================
@ -2479,6 +2687,42 @@ function enqueue_template_specific_styles()
true
);
}
// Страница КЛАССА начальной школы — наследует стили школы + свои
if (is_page_template('page-class.php')) {
wp_enqueue_style(
'front-page-style',
get_template_directory_uri() . '/assets/css/front-page.css',
array(),
filemtime(get_template_directory() . '/assets/css/front-page.css')
);
wp_enqueue_style(
'school-style',
get_template_directory_uri() . '/assets/css/school.css',
array(),
filemtime(get_template_directory() . '/assets/css/school.css')
);
wp_enqueue_style(
'class-style',
get_template_directory_uri() . '/assets/css/class.css',
array(),
filemtime(get_template_directory() . '/assets/css/class.css')
);
wp_enqueue_script(
'class-script',
get_template_directory_uri() . '/assets/js/class.js',
array(),
filemtime(get_template_directory() . '/assets/js/class.js'),
true
);
wp_enqueue_script(
'sticky-cta',
get_template_directory_uri() . '/assets/js/sticky-cta.js',
array(),
filemtime(get_template_directory() . '/assets/js/sticky-cta.js'),
true
);
}
}
/**

View File

@ -0,0 +1,142 @@
<?php
/**
* Template Name: Класс начальной школы
*
* Универсальный шаблон лендинга для классов начальной школы (14).
* Все данные страницы управляются через Carbon Fields (вкладки «Настройки Страницы Класса»):
* 🖼️ HERO, 📚 Программа, 👨‍🏫 Преподаватели, 🗓 Расписание и стоимость,
* 💬 Отзывы, FAQ, 📊 SEO.
* Глобальные секции (контакты) и данные филиала (телефон, адрес, цена)
* из настроек филиала (branch_*).
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
get_header();
$post_id = (int) get_the_ID();
$class_page_url = get_permalink($post_id) ?: home_url('/');
$class_hero_title = crb_get_post_meta($post_id, 'class_hero_title', '');
$yoast_title = get_post_meta($post_id, '_yoast_wpseo_title', true);
$schema_title = crb_get_post_meta($post_id, 'class_seo_title', '') ?: ($yoast_title ?: wp_get_document_title());
$schema_desc = crb_get_post_meta($post_id, 'class_seo_description', '')
?: get_post_meta($post_id, '_yoast_wpseo_metadesc', true)
?: crb_get_post_meta($post_id, 'class_hero_subtitle', '');
$class_published = get_the_date('c', $post_id);
$class_modified = get_the_modified_time('c', $post_id);
?>
<main class="page-class">
<?php get_template_part('template-parts/class/hero'); ?>
<?php get_template_part('template-parts/class/program'); ?>
<?php get_template_part('template-parts/class/teachers'); ?>
<?php get_template_part('template-parts/class/schedule'); ?>
<?php get_template_part('template-parts/class/testimonials'); ?>
<?php get_template_part('template-parts/class/faq'); ?>
<?php get_template_part('template-parts/class/cta'); ?>
<?php get_template_part('template-parts/contacts'); ?>
</main>
<?php
// ─── Schema.org @graph ───
$graph = array();
$graph[] = array(
'@type' => 'WebPage',
'@id' => $class_page_url . '#webpage',
'url' => $class_page_url,
'name' => wp_strip_all_tags($schema_title),
'description' => wp_strip_all_tags($schema_desc),
'inLanguage' => str_replace('_', '-', determine_locale() ?: 'ru'),
'isPartOf' => array('@id' => home_url('/') . '#website'),
'breadcrumb' => array('@id' => $class_page_url . '#breadcrumb'),
'speakable' => array(
'@type' => 'SpeakableSpecification',
'cssSelector' => array('h1.class-hero__h1', '.class-hero__subtitle'),
),
'datePublished' => $class_published,
'dateModified' => $class_modified,
);
$graph[] = array(
'@type' => 'BreadcrumbList',
'@id' => $class_page_url . '#breadcrumb',
'itemListElement' => array(
array(
'@type' => 'ListItem',
'position' => 1,
'name' => 'Главная страница',
'item' => home_url('/'),
),
array(
'@type' => 'ListItem',
'position' => 2,
'name' => 'Начальная школа',
'item' => home_url('/nachalnaya-shkola/'),
),
array(
'@type' => 'ListItem',
'position' => 3,
'name' => wp_strip_all_tags($schema_title),
),
),
);
if (function_exists('dekart_schema_organization')) {
$organization = dekart_schema_organization();
if (is_array($organization) && ! empty($organization)) {
$graph[] = $organization;
}
}
// FAQPage — из CF-полей класса
$class_faq_items = crb_get_post_meta($post_id, 'class_faq_items');
if (is_array($class_faq_items) && ! empty($class_faq_items)) {
$faq_main = array();
foreach ($class_faq_items as $item) {
$q = isset($item['faq_question']) ? trim($item['faq_question']) : '';
$a = isset($item['faq_answer']) ? trim($item['faq_answer']) : '';
if ('' === $q || '' === $a) {
continue;
}
$faq_main[] = array(
'@type' => 'Question',
'name' => wp_strip_all_tags($q),
'acceptedAnswer' => array(
'@type' => 'Answer',
'text' => wp_strip_all_tags($a),
),
);
}
if (! empty($faq_main)) {
$graph[] = array(
'@type' => 'FAQPage',
'@id' => $class_page_url . '#faq',
'name' => 'Часто задаваемые вопросы о ' . mb_strtolower(wp_strip_all_tags($schema_title)),
'mainEntity' => $faq_main,
);
}
}
if (! empty($graph)) : ?>
<script type="application/ld+json">
<?php echo wp_json_encode(array('@context' => 'https://schema.org', '@graph' => $graph), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>
</script>
<?php endif; ?>
<?php
get_footer();

View File

@ -0,0 +1,66 @@
<?php
/**
* Финальная CTA-секция страницы класса начальной школы.
* Кнопка записи + телефон + мессенджеры филиала.
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
$post_id = (int) get_the_ID();
$cta_title = crb_get_post_meta($post_id, 'class_hero_title', 'Частная школа 1 класс в Щёлково');
$cta_text = crb_get_post_meta($post_id, 'class_hero_subtitle', 'Запишитесь на пробный урок — познакомьтесь с учителем и посмотрите классы.');
$hero_btn_text = crb_get_post_meta($post_id, 'class_hero_btn_text', 'Записаться на пробный урок');
$hero_btn_url = crb_get_post_meta($post_id, 'class_hero_btn_url', '#form');
$branch_phone = get_option('branch_phone') ?: crb_get_theme_option('site_phone');
$phone_clean = $branch_phone ? preg_replace('/[\s\-\\(\)]/', '', $branch_phone) : '';
$branch_msgs = array();
$msg_wa_url = get_option('branch_messenger_whatsapp', '');
$msg_tg_url = get_option('branch_messenger_telegram', '');
$msg_wa_on = (bool) get_option('branch_messenger_whatsapp_on', 1);
$msg_tg_on = (bool) get_option('branch_messenger_telegram_on', 1);
if ($msg_wa_on && $msg_wa_url) {
$branch_msgs[] = array('name' => 'WhatsApp', 'url' => $msg_wa_url);
}
if ($msg_tg_on && $msg_tg_url) {
$branch_msgs[] = array('name' => 'Telegram', 'url' => $msg_tg_url);
}
?>
<section class="class-cta section-bg" data-bg="class-cta" id="class-cta" aria-labelledby="class-cta-title">
<div class="container">
<div class="class-cta__inner">
<h2 id="class-cta-title" class="class-cta__title">Запишитесь на пробный урок в «<?php echo esc_html(trim(str_replace('Частная школа', '', $cta_title))); ?>»</h2>
<p class="class-cta__text"><?php echo esc_html(wp_trim_words($cta_text, 18, '…')); ?></p>
<div class="class-cta__actions">
<?php if ($hero_btn_url && '#' !== $hero_btn_url) : ?>
<a class="btn-write btn-primary class-cta__btn" href="<?php echo esc_url($hero_btn_url); ?>"><?php echo esc_html($hero_btn_text); ?></a>
<?php else : ?>
<button class="btn-write btn-primary class-cta__btn open-bitrix-form" type="button"><?php echo esc_html($hero_btn_text); ?></button>
<?php endif; ?>
<?php if ($branch_phone && $phone_clean) : ?>
<a class="class-cta__phone" href="tel:<?php echo esc_attr($phone_clean); ?>"><?php echo esc_html($branch_phone); ?></a>
<?php endif; ?>
</div>
<?php if (! empty($branch_msgs)) : ?>
<div class="class-cta__msgs">
<span class="class-cta__msgs-label">Или напишите нам:</span>
<?php foreach ($branch_msgs as $m) : ?>
<a class="class-cta__msg" href="<?php echo esc_url($m['url']); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html($m['name']); ?></a>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
</section>

View File

@ -0,0 +1,46 @@
<?php
/**
* Секция «FAQ» страницы класса начальной школы.
* Вкладка «❓ FAQ»: аккордеон на <details>. Микроразметка FAQPage в page-class.php.
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
$post_id = (int) get_the_ID();
$faq_title = crb_get_post_meta($post_id, 'class_faq_title', 'Часто задаваемые вопросы');
$faq_items = crb_get_post_meta($post_id, 'class_faq_items');
if (empty($faq_items) || ! is_array($faq_items)) {
return;
}
?>
<section class="class-faq section-bg" data-bg="class-faq" id="class-faq" aria-labelledby="class-faq-title">
<div class="container">
<div class="section-header--left">
<h2 id="class-faq-title" class="bento-h2"><?php echo esc_html($faq_title); ?></h2>
</div>
<div class="class-faq__list">
<?php foreach ($faq_items as $item) :
$q = isset($item['faq_question']) ? trim($item['faq_question']) : '';
$a = isset($item['faq_answer']) ? trim($item['faq_answer']) : '';
if ('' === $q || '' === $a) {
continue;
}
?>
<details class="class-faq__item">
<summary class="class-faq__question"><?php echo esc_html($q); ?></summary>
<div class="class-faq__answer"><?php echo esc_html($a); ?></div>
</details>
<?php endforeach; ?>
</div>
</div>
</section>

View File

@ -0,0 +1,111 @@
<?php
/**
* Секция «Герой» страницы класса начальной школы.
* Управляется вкладкой «🖼️ HERO» (Настройки Страницы Класса).
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
$post_id = (int) get_the_ID();
$hero_title = crb_get_post_meta($post_id, 'class_hero_title', 'Частная школа 1 класс в Щёлково');
$hero_subtitle = crb_get_post_meta($post_id, 'class_hero_subtitle', 'Мини-класс до 15 учеников, учитель начальных классов и английский каждый день. Официальное прикрепление к московской школе — аттестат государственного образца.');
$hero_image = crb_get_post_meta($post_id, 'class_hero_image');
$hero_btn_text = crb_get_post_meta($post_id, 'class_hero_btn_text', 'Записаться на пробный урок');
$hero_btn_url = crb_get_post_meta($post_id, 'class_hero_btn_url', '#form');
$hero_stats = crb_get_post_meta($post_id, 'class_hero_stats');
if (empty($hero_stats) || ! is_array($hero_stats)) {
$hero_stats = array(
array('stat_number' => 'до 15', 'stat_label' => 'человек в классе'),
array('stat_number' => '5', 'stat_label' => 'дней в неделю'),
array('stat_number' => '8:30', 'stat_label' => 'старт занятий'),
);
}
// ─── Данные филиала ───
$branch_city = get_option('branch_city') ?: crb_get_theme_option('site_city', 'Щёлково');
$branch_phone = get_option('branch_phone') ?: crb_get_theme_option('site_phone');
$phone_clean = $branch_phone ? preg_replace('/[\s\-\\(\)]/', '', $branch_phone) : '';
$rating_ya = get_option('branch_rating_yandex', '');
$rating_2gis = get_option('branch_rating_2gis', '');
// ─── Фото героя ───
$hero_src = '';
$hero_alt = wp_strip_all_tags($hero_title);
if ($hero_image) {
$hero_img = wp_get_attachment_image_src((int) $hero_image, 'large');
if (is_array($hero_img)) {
$hero_src = $hero_img[0];
}
$hero_alt = get_post_meta((int) $hero_image, '_wp_attachment_image_alt', true) ?: $hero_alt;
}
if (! $hero_src) {
$hero_src = get_template_directory_uri() . '/assets/images/logo-svg.svg';
}
?>
<section class="class-hero section-bg" data-bg="class-hero" id="class-hero" aria-labelledby="class-hero-title">
<div class="ds-container">
<div class="class-hero__inner">
<div class="class-hero__content">
<span class="class-hero__badge">Набор 2026/27 учебный год</span>
<h1 id="class-hero-title" class="class-hero__h1"><?php echo esc_html($hero_title); ?></h1>
<p class="class-hero__subtitle"><?php echo wp_kses_post($hero_subtitle); ?></p>
<?php if ($rating_ya || $rating_2gis) : ?>
<div class="class-hero__social-proof">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<span>Лучшая частная школа <?php echo esc_html($branch_city); ?> по версии Яндекс.Карт (<?php echo esc_html($rating_ya ?: '5.0'); ?>) <span class="ds-hero__rating-nowrap">и 2GIS (<?php echo esc_html($rating_2gis ?: '4.7'); ?>)</span></span>
</div>
<?php endif; ?>
<div class="class-hero__actions">
<?php if ($hero_btn_url && '#' !== $hero_btn_url) : ?>
<a class="btn-write btn-primary class-hero__cta" href="<?php echo esc_url($hero_btn_url); ?>"><?php echo esc_html($hero_btn_text); ?></a>
<?php else : ?>
<button class="btn-write btn-primary class-hero__cta open-bitrix-form" type="button"><?php echo esc_html($hero_btn_text); ?></button>
<?php endif; ?>
<?php if ($branch_phone && $phone_clean) : ?>
<a class="class-hero__phone" href="tel:<?php echo esc_attr($phone_clean); ?>"><?php echo esc_html($branch_phone); ?></a>
<?php endif; ?>
</div>
<?php if (! empty($hero_stats)) : ?>
<ul class="class-hero__stats">
<?php foreach ($hero_stats as $stat) :
$num = isset($stat['stat_number']) ? trim($stat['stat_number']) : '';
$label = isset($stat['stat_label']) ? trim($stat['stat_label']) : '';
if ('' === $num) {
continue;
}
?>
<li class="class-hero__stat">
<span class="class-hero__stat-number"><?php echo esc_html($num); ?></span>
<span class="class-hero__stat-label"><?php echo esc_html($label); ?></span>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<div class="class-hero__visual">
<div class="class-hero__visual-glow" aria-hidden="true"></div>
<img class="class-hero__photo"
src="<?php echo esc_url($hero_src); ?>"
alt="<?php echo esc_attr($hero_alt); ?>"
loading="eager" fetchpriority="high" decoding="async"
width="1200" height="800">
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,90 @@
<?php
/**
* Секция «Программа» страницы класса начальной школы.
* Вкладка «📚 Программа»: описание + карточки предметов + галерея фото.
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
$post_id = (int) get_the_ID();
$program_title = crb_get_post_meta($post_id, 'class_program_title', 'Программа обучения');
$program_text = crb_get_post_meta($post_id, 'class_program_text', '');
$program_items = crb_get_post_meta($post_id, 'class_program_items');
$gallery = crb_get_post_meta($post_id, 'class_program_gallery');
if (empty($program_items) || ! is_array($program_items)) {
$program_items = array(
array('item_icon' => 'chart-bar', 'item_title' => 'Математика', 'item_text' => 'Счёт, логика и решение задач. Учим думать, а не запоминать.'),
array('item_icon' => 'book', 'item_title' => 'Русский язык', 'item_text' => 'Грамотное письмо и речь. Чистописание и разбор правил.'),
array('item_icon' => 'book-2', 'item_title' => 'Литературное чтение', 'item_text' => 'Скорочтение и понимание текста. Классика и современная детская литература.'),
array('item_icon' => 'star', 'item_title' => 'Английский язык', 'item_text' => 'Ежедневные уроки: говорение, чтение и лексика в игровой форме.'),
array('item_icon' => 'school', 'item_title' => 'Окружающий мир', 'item_text' => 'Природа, общество и безопасность. Проекты и наблюдения.'),
array('item_icon' => 'heart', 'item_title' => 'Физкультура и здоровье', 'item_text' => 'Подвижные игры, осанка и режим. Спортивные секции после уроков.'),
array('item_icon' => 'bulb', 'item_title' => 'Творчество', 'item_text' => 'Музыка, изобразительное искусство и театральная студия.'),
array('item_icon' => 'medal-2', 'item_title' => 'Логика и шахматы', 'item_text' => 'Развитие мышления, памяти и внимания через интеллектуальные игры.'),
);
}
$icons_dir = get_template_directory_uri() . '/assets/images/icons/';
?>
<section class="class-program section-bg" data-bg="class-program" id="class-program" aria-labelledby="class-program-title">
<div class="container">
<div class="section-header--left">
<h2 id="class-program-title" class="bento-h2"><?php echo esc_html($program_title); ?></h2>
<?php if ($program_text) : ?>
<div class="bento-p class-program__text"><?php echo wp_kses_post($program_text); ?></div>
<?php endif; ?>
</div>
<ul class="class-program__grid">
<?php foreach ($program_items as $item) :
$icon = isset($item['item_icon']) ? sanitize_title($item['item_icon']) : 'book';
$title = isset($item['item_title']) ? trim($item['item_title']) : '';
$text = isset($item['item_text']) ? trim($item['item_text']) : '';
if ('' === $title) {
continue;
}
?>
<li class="class-program__card">
<span class="class-program__icon" aria-hidden="true">
<img src="<?php echo esc_url($icons_dir . $icon . '.svg'); ?>"
alt="" loading="lazy" width="28" height="28"
onerror="this.src='<?php echo esc_url($icons_dir . 'book.svg'); ?>'">
</span>
<h3 class="class-program__card-title"><?php echo esc_html($title); ?></h3>
<?php if ($text) : ?>
<p class="class-program__card-text"><?php echo esc_html($text); ?></p>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php if (is_array($gallery) && ! empty($gallery)) : ?>
<div class="class-program__gallery">
<?php foreach ($gallery as $i => $item) :
$img_id = isset($item['gallery_image']) ? (int) $item['gallery_image'] : 0;
if ($img_id < 1) {
continue;
}
$src = wp_get_attachment_image_url($img_id, 'medium_large');
$alt = get_post_meta($img_id, '_wp_attachment_image_alt', true) ?: $program_title;
if (! $src) {
continue;
}
?>
<figure class="class-program__gallery-item<?php echo 0 === $i ? ' class-program__gallery-item--wide' : ''; ?>">
<img src="<?php echo esc_url($src); ?>" alt="<?php echo esc_attr($alt); ?>" loading="lazy" decoding="async">
</figure>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</section>

View File

@ -0,0 +1,84 @@
<?php
/**
* Секция «Расписание и стоимость» страницы класса начальной школы.
* Вкладка «🗓 Расписание и стоимость».
* Цена: class_price_text ?: глобальная branch_price_school.
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
$post_id = (int) get_the_ID();
$schedule_title = crb_get_post_meta($post_id, 'class_schedule_title', 'Расписание и стоимость');
$schedule_rows = crb_get_post_meta($post_id, 'class_schedule');
$price_text = crb_get_post_meta($post_id, 'class_price_text', '');
if ('' === $price_text) {
$price_text = get_option('branch_price_school') ?: '45 000 ₽ / месяц';
}
$price_note = crb_get_post_meta($post_id, 'class_price_note', 'включая питание и продлёнку до 19:00');
$hero_btn_text = crb_get_post_meta($post_id, 'class_hero_btn_text', 'Записаться на пробный урок');
$hero_btn_url = crb_get_post_meta($post_id, 'class_hero_btn_url', '#form');
?>
<section class="class-schedule section-bg" data-bg="class-schedule" id="class-schedule" aria-labelledby="class-schedule-title">
<div class="container">
<div class="section-header--left">
<h2 id="class-schedule-title" class="bento-h2"><?php echo esc_html($schedule_title); ?></h2>
</div>
<div class="class-schedule__layout">
<?php if (is_array($schedule_rows) && ! empty($schedule_rows)) : ?>
<div class="class-schedule__table-wrap">
<table class="class-schedule__table">
<thead>
<tr>
<th scope="col">День</th>
<th scope="col">Время</th>
<th scope="col">Предмет</th>
</tr>
</thead>
<tbody>
<?php foreach ($schedule_rows as $row) :
$day = isset($row['schedule_day']) ? trim($row['schedule_day']) : '';
$time = isset($row['schedule_time']) ? trim($row['schedule_time']) : '';
$subject = isset($row['schedule_subject']) ? trim($row['schedule_subject']) : '';
if ('' === $subject && '' === $time) {
continue;
}
?>
<tr>
<td data-label="День"><?php echo esc_html($day); ?></td>
<td data-label="Время"><?php echo esc_html($time); ?></td>
<td data-label="Предмет"><?php echo esc_html($subject); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<aside class="class-price">
<span class="class-price__label">Стоимость обучения</span>
<span class="class-price__amount"><?php echo esc_html($price_text); ?></span>
<?php if ($price_note) : ?>
<p class="class-price__note"><?php echo esc_html($price_note); ?></p>
<?php endif; ?>
<?php if ($hero_btn_url && '#' !== $hero_btn_url) : ?>
<a class="btn-write btn-primary class-price__cta" href="<?php echo esc_url($hero_btn_url); ?>"><?php echo esc_html($hero_btn_text); ?></a>
<?php else : ?>
<button class="btn-write btn-primary class-price__cta open-bitrix-form" type="button"><?php echo esc_html($hero_btn_text); ?></button>
<?php endif; ?>
</aside>
</div>
</div>
</section>

View File

@ -0,0 +1,38 @@
<?php
/**
* Секция «Преподаватели» страницы класса начальной школы.
* Вкладка «👨‍🏫 Преподаватели»: выбор из CPT teacher (association).
* Пусто показываются все преподаватели школы (глобальный партиал teachers-cards).
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
$post_id = (int) get_the_ID();
$teachers_title = crb_get_post_meta($post_id, 'class_teachers_title', 'Преподаватели класса');
$teachers_subtitle = crb_get_post_meta($post_id, 'class_teachers_subtitle', 'Учитель начальных классов и педагоги-предметники, которые ведут уроки в этом классе');
$teachers = crb_get_post_meta($post_id, 'class_teachers');
$teacher_ids = array();
if (is_array($teachers) && ! empty($teachers)) {
foreach ($teachers as $t_id) {
$t_id = (int) $t_id;
if ($t_id > 0) {
$teacher_ids[] = $t_id;
}
}
}
get_template_part(
'template-parts/teachers-cards',
null,
array(
'teacher_ids' => $teacher_ids,
'description' => $teachers_subtitle,
'title' => $teachers_title,
)
);

View File

@ -0,0 +1,106 @@
<?php
/**
* Секция «Отзывы» страницы класса начальной школы.
* Вкладка «💬 Отзывы»: выбор из CPT reviews (association).
* Пусто последние отзывы школы (тип school/primary).
*
* @package Dekart
*/
if (! defined('ABSPATH')) {
exit;
}
$post_id = (int) get_the_ID();
$reviews_title = crb_get_post_meta($post_id, 'class_reviews_title', 'Отзывы родителей');
$reviews_sel = crb_get_post_meta($post_id, 'class_reviews');
$review_ids = array();
if (is_array($reviews_sel) && ! empty($reviews_sel)) {
foreach ($reviews_sel as $r_id) {
$r_id = (int) $r_id;
if ($r_id > 0) {
$review_ids[] = $r_id;
}
}
}
$args = array(
'post_type' => 'reviews',
'post_status' => 'publish',
'posts_per_page' => 3,
'orderby' => 'date',
'order' => 'DESC',
'no_found_rows' => true,
);
if (! empty($review_ids)) {
$args['post__in'] = $review_ids;
$args['orderby'] = 'post__in';
$args['posts_per_page'] = count($review_ids);
} else {
$args['meta_query'] = array(
array(
'key' => 'review_type',
'value' => array('school', 'primary'),