Global 2026-07-23

This commit is contained in:
Dekart Deploy Bot 2026-07-23 17:47:31 +00:00
parent 2d0cb49a7d
commit 34845fcdab
7 changed files with 748 additions and 132 deletions

View File

@ -86,6 +86,13 @@
--card-radius: 20px;
--card-shadow: 0 2px 16px rgba(0,0,0,0.06);
--card-shadow-hover: 0 8px 32px rgba(0,0,0,0.1);
/* PKSH — shared with teachers-cards component (used on front-page too) */
--pksh-radius-card: var(--radius-lg, 24px);
--pksh-text-warm: #475569;
--pksh-gradient-btn-bright: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
--pksh-gradient-btn-bright-hover: linear-gradient(135deg, var(--color-primary-dark) 0%, var(--color-primary-hover) 100%);
--pksh-btn-shadow-bright: 0 4px 20px color-mix(in oklab, var(--color-primary), transparent 60%);
--pksh-btn-shadow-bright-hover: 0 8px 32px color-mix(in oklab, var(--color-primary), transparent 50%);
/* ════════════════════════════════════════════ */
/* PAGE-SPECIFIC COLOR TOKENS */
@ -11225,3 +11232,425 @@ main > .pksh-section:first-child {
border-top: 1px solid var(--slate-200, #E2E8F0);
}
}
/* ── 19. Contacts ── */
.contacts {
padding: var(--space-6) 0;
background: transparent;
}
/* Override legacy .contacts .container !important */
.contacts > .container {
max-width: 1240px !important;
padding: 0 1.5rem !important;
}
.contacts__header {
margin-bottom: var(--space-5);
}
.contacts__title {
font-family: var(--font-display);
font-weight: 700;
font-size: clamp(1.5rem, 4vw, 2.5rem);
line-height: 1.15;
letter-spacing: -0.02em;
color: var(--color-text);
margin: 0 0 var(--space-3);
}
.contacts__description {
font-size: var(--text-body);
line-height: 1.6;
color: var(--color-text-muted);
margin: 0;
}
.contacts__wrapper {
display: flex;
gap: var(--space-5);
align-items: stretch;
}
.contacts__info {
width: 35%;
display: flex;
flex-direction: column;
gap: var(--space-2);
padding: var(--space-3) 0;
}
.contacts__item {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.contacts__item + .contacts__item {
margin-top: var(--space-2);
}
.contacts__subtitle {
font-size: var(--text-body-sm);
font-weight: 700;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.contacts__value {
font-size: clamp(1rem, 2vw, var(--text-h4));
font-weight: 600;
color: var(--color-primary);
text-decoration: none;
transition: color var(--transition-fast);
}
.contacts__value:hover {
color: var(--color-primary-dark);
text-decoration: underline;
}
.contacts__logistics {
display: flex;
flex-wrap: wrap;
gap: var(--space-2);
margin-top: var(--space-3);
padding: var(--space-3);
background: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
}
.contacts__logistics-item {
display: inline-flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-body-sm);
color: var(--color-text-muted);
width: 100%;
}
.contacts__logistics-icon {
flex-shrink: 0;
width: 18px;
height: 18px;
color: var(--color-primary);
}
.contacts__logistics-text {
flex: 1;
}
.contacts__social {
display: flex;
flex-wrap: wrap;
gap: var(--space-3);
}
.contacts__social-link {
display: inline-flex;
align-items: center;
font-size: clamp(0.875rem, 1.8vw, 1rem);
font-weight: 600;
color: var(--color-primary);
text-decoration: none;
transition: color var(--transition-fast);
}
.contacts__social-link:hover {
color: var(--color-primary-hover);
}
.contacts__social-link + .contacts__social-link::before {
content: '\00B7';
margin-right: var(--space-3);
color: var(--color-text-muted);
font-weight: 400;
}
.contacts__map {
flex: 1;
border-radius: var(--radius-sm);
overflow: hidden;
min-height: 400px;
box-shadow: var(--shadow-md);
}
@media (max-width: 768px) {
.contacts__wrapper {
flex-direction: column-reverse;
}
.contacts__info {
width: 100%;
}
.contacts__map {
min-height: 280px;
margin: 0 calc(-1 * var(--container-padding, 1.5rem));
border-radius: 0;
box-shadow: none;
}
}
/* ── 20. Teachers Cards (shared) ── */
.teachers-cards__wrapper {
display: flex;
flex-wrap: wrap;
gap: clamp(16px, 2vw, 24px);
justify-content: center;
}
.teachers-cards__item {
width: calc(33.33% - 18px);
min-width: 280px;
}
.teachers-cards__card {
background: var(--color-bg);
border-radius: var(--pksh-radius-card, 24px);
overflow: hidden;
box-shadow: var(--shadow-sm);
transition: transform 0.25s ease, box-shadow 0.25s ease;
display: flex;
flex-direction: column;
height: 100%;
}
.teachers-cards__card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-md);
}
.teachers-cards__card-top {
background: linear-gradient(135deg, color-mix(in oklab, var(--color-primary), transparent 95%), color-mix(in oklab, var(--color-secondary), transparent 92%));
display: flex;
justify-content: center;
padding: clamp(24px, 3vw, 32px) clamp(16px, 2vw, 24px) clamp(16px, 2vw, 20px);
}
.teachers-cards__photo {
width: clamp(120px, 12vw, 140px);
height: clamp(120px, 12vw, 140px);
border-radius: 50%;
object-fit: cover;
border: 4px solid var(--color-bg);
box-shadow: 0 4px 16px color-mix(in oklab, var(--color-text), transparent 90%);
}
.teachers-cards__card-body {
padding: clamp(14px, 1.8vw, 18px) clamp(18px, 2.5vw, 24px) clamp(20px, 2.5vw, 24px);
display: flex;
flex-direction: column;
gap: 6px;
flex: 1;
}
.teachers-cards__name {
font-size: clamp(1rem, 1.2vw, 1.125rem);
font-weight: 700;
line-height: 1.3;
color: var(--color-text);
text-align: center;
margin: 0;
}
.teachers-cards__subj {
font-size: clamp(0.8125rem, 0.9vw, 0.875rem);
line-height: 1.4;
color: var(--color-primary);
text-align: center;
font-weight: 600;
margin: 0 0 2px;
}
.teachers-cards__desc {
font-size: 0.825rem;
line-height: 1.5;
color: var(--color-text-muted);
text-align: center;
margin: 0 0 4px;
}
.teachers-cards__meta {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 6px;
margin: 4px 0 12px;
}
.teachers-cards__meta-badge {
display: inline-flex;
padding: 3px 10px;
font-size: 0.72rem;
font-weight: 600;
color: var(--color-primary-dark);
background: var(--color-primary-light, #EFF6FF);
border-radius: var(--radius-pill, 100px);
white-space: nowrap;
}
.teachers-cards__meta-exp {
display: inline-flex;
padding: 3px 10px;
font-size: 0.72rem;
font-weight: 600;
color: var(--pksh-text-warm);
background: color-mix(in oklab, var(--color-bg-alt), var(--color-warning) 12%);
border-radius: var(--radius-pill, 100px);
white-space: nowrap;
}
.teachers-cards__btn {
display: block;
width: 100%;
padding: 12px;
border: none;
border-radius: var(--radius-sm, 12px);
font-family: inherit;
font-size: 0.9rem;
font-weight: 700;
color: var(--color-text-on-dark);
cursor: pointer;
background: var(--pksh-gradient-btn-bright);
text-align: center;
text-decoration: none;
transition: transform var(--transition-fast), box-shadow var(--transition-fast);
box-shadow: var(--pksh-btn-shadow-bright);
margin-top: auto;
}
.teachers-cards__btn:hover {
transform: translateY(-2px);
box-shadow: var(--pksh-btn-shadow-bright-hover);
}
.teachers-cards__btn:focus-visible {
outline: 3px solid var(--color-primary);
outline-offset: 3px;
}
@media (max-width: 768px) {
.teachers-cards__item {
width: calc(50% - 12px);
min-width: 0;
}
.teachers-cards__wrapper { gap: 16px; }
}
@media (max-width: 639px) {
.teachers-cards__scroll-x {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x mandatory;
padding-bottom: 20px;
}
.teachers-cards__wrapper {
flex-wrap: nowrap;
gap: 16px;
justify-content: flex-start;
padding-bottom: 4px;
}
.teachers-cards__item {
flex-shrink: 0;
width: calc(100vw - 64px);
max-width: 340px;
scroll-snap-align: start;
min-width: 0;
}
}
/* ── 21. PKSH Swipe Hint (shared via teachers-cards) ── */
.pksh-swipe-hint {
display: none;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 6px 8px;
margin: 16px 0 4px;
font-size: 0.875rem;
color: var(--color-primary);
font-weight: 600;
}
.pksh-swipe-hint__arrow {
display: inline-block;
font-size: 1.125rem;
}
.pksh-swipe-hint__text {
text-align: center;
}
@media (max-width: 639px) {
.pksh-swipe-hint {
display: flex;
}
}
/* ── 22. Base bento typography (global, from pksh design system) ── */
.bento-h2 {
font-family: var(--font-display);
font-size: clamp(1.5rem, 2.5vw, 2.25rem);
font-weight: 700;
line-height: 1.2;
color: var(--color-text);
margin: 0 0 12px;
text-wrap: balance;
}
.bento-p {
font-size: clamp(1rem, 1.2vw, 1.0625rem);
line-height: 1.7;
color: var(--color-text-muted);
margin: 0 0 20px;
max-width: 70ch;
text-wrap: pretty;
}
.section-header--left {
text-align: left;
}
.section-header--left .bento-h2,
.section-header--left .bento-p {
max-width: none;
margin-left: 0;
margin-right: auto;
}
.section-header--left .bento-p {
max-width: 65ch;
}
.bento-label {
display: inline-block;
font-size: 0.8125rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-primary);
margin-bottom: var(--space-2, 8px);
}
/* ── 23. Section Header Centered (global) ── */
.section-header--centered {
text-align: center;
}
.section-header--centered .bento-h2,
.section-header--centered .bento-p {
max-width: none;
margin-left: auto;
margin-right: auto;
}
.section-header--centered .bento-p {
max-width: 70ch;
}
/* ── 24. Reviews Link CTA (front-page) ── */
.reviews-link {
background: var(--color-bg-alt);
border-radius: var(--radius-lg);
margin: 40px auto;
padding: 48px 24px;
}
.reviews-link .bento__full {
width: 100%;
max-width: 700px;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.reviews-link .bento-p {
max-width: 65ch;
margin-left: auto;
margin-right: auto;
}
.reviews-link .reviews-link__btn {
margin-top: 8px;
}
.reviews-link__btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 14px 32px;
border: none;
border-radius: var(--radius-sm, 12px);
font-family: inherit;
font-size: 0.95rem;
font-weight: 700;
color: var(--color-text-on-dark);
cursor: pointer;
background: var(--pksh-gradient-btn-bright);
text-decoration: none;
transition: transform var(--transition-fast), box-shadow var(--transition-fast);
box-shadow: var(--pksh-btn-shadow-bright);
white-space: nowrap;
}
.reviews-link__btn:hover {
transform: translateY(-2px);
box-shadow: var(--pksh-btn-shadow-bright-hover);
}
.reviews-link__btn:focus-visible {
outline: 3px solid var(--color-primary);
outline-offset: 3px;
}

View File

@ -110,17 +110,34 @@ $branch_addr = get_option( 'branch_address' ) ?: carbon_get_theme_option( '
</div>
</section>
<!-- ССЫЛКА НА СТРАНИЦУ ОТЗЫВОВ ДЛЯ УСИЛЕНИЯ ПЕРЕЛИНКОВКИ -->
<section class="reviews-link-block">
<div class="container">
<div class="reviews-link-wrapper">
<p>Узнайте, что говорят о нас родители и ученики </p>
<a href="/otzyvy/" class="btn-outline btn-page">Читать все отзывы</a>
<!-- ── Отзывы (CTA / internal linking) ── -->
<section class="bento reviews-link">
<div class="bento__full">
<div class="section-header--centered">
<span class="bento-label">Отзывы</span>
<h2 class="bento-h2">Узнайте, что говорят о нас родители и ученики</h2>
</div>
<a href="/otzyvy/" class="reviews-link__btn">Читать все отзывы</a>
</div>
</section>
<?php get_template_part('template-parts/teachers'); ?>
<?php
// ── Преподаватели (из CF) ──
$front_teachers_raw = carbon_get_post_meta( $post_id, 'front_teachers' );
$front_teacher_ids = array();
if ( is_array( $front_teachers_raw ) ) {
foreach ( $front_teachers_raw as $item ) {
if ( ! empty( $item['teacher_id'] ) ) {
$front_teacher_ids[] = (int) $item['teacher_id'];
}
}
}
$front_teachers_text = carbon_get_post_meta( $post_id, 'front_teachers_text' );
get_template_part( 'template-parts/teachers-cards', null, array(
'teacher_ids' => $front_teacher_ids,
'description' => $front_teachers_text ?: '',
) );
?>
<?php
@ -276,6 +293,6 @@ $branch_addr = get_option( 'branch_address' ) ?: carbon_get_theme_option( '
<?php get_template_part('template-parts/map'); ?>
<?php get_template_part('template-parts/contacts'); ?>
<?php get_footer(); ?>

View File

@ -468,6 +468,22 @@ function add_carbon() {
->help_text( 'Размер изображения (желательно) 390px на 550px' )->set_width( 30 ),
Field::make( 'text', 'main_banner_link', 'УРЛ баннера:' )
->set_default_value('#')->set_width( 40 ),
))
->add_tab('👨‍🏫 Преподаватели', array(
Field::make( 'html', 'front_teachers_tab_desc', '' )
->set_html( '<p style="color: #64748b; font-size: 13px; margin: 0 0 12px;">Секция преподавателей на главной странице. Выберите преподавателей и отредактируйте текст под заголовком.</p>' ),
Field::make( 'textarea', 'front_teachers_text', 'Текст под заголовком' )
->set_default_value( 'Каждый педагог имеет опыт работы с дошкольниками от 5 лет. Все — действующие учителя начальных классов с высшим образованием.' )
->set_help_text( 'Текст описания перед карточками преподавателей.' ),
Field::make( 'complex', 'front_teachers', 'Преподаватели на странице' )
->set_layout( 'tabbed-horizontal' )
->set_help_text( 'Добавьте преподавателей для главной страницы. Если не добавить ни одного — покажутся все.' )
->add_fields( array(
Field::make( 'select', 'teacher_id', 'Выберите преподавателя' )
->set_options( array( 0 => '— Выберите преподавателя —' ) + dekart_get_teacher_options() )
->set_width( 100 )
->set_help_text( 'ФИО и фото подтянутся из карточки преподавателя.' ),
)),
));
// ====================================================
@ -593,6 +609,9 @@ function add_carbon() {
->where( 'post_type', '=', 'teacher' )
->add_fields( array(
Field::make( 'text', 'teacher_direction', 'Направление преподавателя (текст в под фото):' ),
Field::make( 'text', 'teacher_badge', 'Бейдж на карточке (например: 👶 Работает с дошкольниками)' )
->set_width( 30 )
->set_help_text( 'Текст бейджа на карточке преподавателя. Если пусто — бейдж скрыт.' ),
Field::make( 'image', 'teacher_avatar', 'Аватар:' )
->set_width( 15 ),
Field::make( 'text', 'teacher_start_year', 'Год начала работы (только год, например: 1987)' )
@ -757,6 +776,9 @@ function add_carbon() {
->add_tab('👨‍🏫 Преподаватели', array(
Field::make( 'html', 'pksh_teachers_tab_desc', '' )
->set_html( '<p style="color: #64748b; font-size: 13px; margin: 0 0 12px;">Секция: <strong>#teachers</strong>. Выберите преподавателей из добавленных в разделе <strong>Преподаватели</strong> главного меню админки. ФИО и фото берутся из карточки преподавателя.</p>' ),
Field::make( 'textarea', 'pksh_teachers_text', 'Текст под заголовком' )
->set_default_value( 'Каждый педагог имеет опыт работы с дошкольниками от 5 лет. Все — действующие учителя начальных классов с высшим образованием.' )
->set_help_text( 'Текст описания перед карточками преподавателей.' ),
Field::make( 'complex', 'pksh_teachers', 'Преподаватели на странице' )
->set_layout( 'tabbed-horizontal' )
->set_help_text( 'Добавьте преподавателей для этой страницы. Выберите из списка существующих.' )
@ -765,20 +787,6 @@ function add_carbon() {
->set_options( array( 0 => '— Выберите преподавателя —' ) + dekart_get_teacher_options() )
->set_width( 100 )
->set_help_text( 'ФИО и фото подтянутся из карточки преподавателя. Если нужного нет — добавьте в разделе Преподаватели.' ),
Field::make( 'text', 'teacher_subject', 'Предмет / должность (на этой странице)' )
->set_width( 100 )
->set_help_text( 'Если оставить пустым — используется значение из карточки преподавателя.' ),
Field::make( 'textarea', 'teacher_about', 'О педагоге (на этой странице)' )
->set_width( 100 )
->set_help_text( 'Краткое описание для этой страницы. Если оставить пустым — используется значение из карточки преподавателя.' ),
Field::make( 'text', 'teacher_badge', 'Бейдж (на этой странице)' )
->set_width( 50 )
->set_default_value( '👶 Работает с дошкольниками' )
->set_help_text( 'Если оставить пустым — скрывается.' ),
Field::make( 'text', 'teacher_exp', 'Опыт (на этой странице)' )
->set_width( 50 )
->set_default_value( '39 лет' )
->set_help_text( 'Только число: «39» или строка: «39 лет». На странице выведется как 📅 Стаж: X. Если пусто — рассчитывается из карточки преподавателя.' ),
)),
))
// ====================================================

View File

@ -35,7 +35,21 @@ get_header();
get_template_part( 'template-parts/block-price' );
get_template_part( 'template-parts/pksh/teachers' );
// ── Преподаватели (из CF) ──
$pksh_teachers_raw = carbon_get_post_meta( get_the_ID(), 'pksh_teachers' );
$pksh_teacher_ids = array();
if ( is_array( $pksh_teachers_raw ) ) {
foreach ( $pksh_teachers_raw as $item ) {
if ( ! empty( $item['teacher_id'] ) ) {
$pksh_teacher_ids[] = (int) $item['teacher_id'];
}
}
}
$pksh_teachers_text = carbon_get_post_meta( get_the_ID(), 'pksh_teachers_text' );
get_template_part( 'template-parts/teachers-cards', null, array(
'teacher_ids' => $pksh_teacher_ids,
'description' => $pksh_teachers_text ?: '',
) );
get_template_part( 'template-parts/pksh/gallery' );
get_template_part( 'template-parts/pksh/guarantee-standalone' );
get_template_part( 'template-parts/pksh/faq' );
@ -43,7 +57,7 @@ get_header();
get_template_part( 'template-parts/pksh/trust-authority' );
get_template_part( 'template-parts/pksh/external-reviews' );
get_template_part( 'template-parts/pksh/final-cta' );
get_template_part( 'template-parts/pksh/contacts' );
get_template_part( 'template-parts/contacts' );
get_template_part( 'template-parts/author-eaat' );
get_template_part( 'template-parts/pksh/sticky-cta' );
?>

View File

@ -0,0 +1,112 @@
<?php
/**
* Шаблон: Контакты + Яндекс.Карта
* Переиспользуемый не зависит от Pksh_Data.
* Данные: get_option('branch_*') с fallback на carbon_get_theme_option('site_*')
*
* @package Dekart
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$opt_phone = get_option( 'branch_phone' ) ?: carbon_get_theme_option( 'site_phone' ) ?: '';
$opt_email = get_option( 'branch_email' ) ?: carbon_get_theme_option( 'site_mail' ) ?: '';
$opt_address = get_option( 'branch_address' ) ?: carbon_get_theme_option( 'site_address' ) ?: '';
$opt_name = get_option( 'branch_name' ) ?: carbon_get_theme_option( 'site_name' ) ?: 'Декарт';
$opt_coords = get_option( 'branch_coords' ) ?: carbon_get_theme_option( 'site_location' ) ?: '';
$opt_logistics_walk = get_option( 'branch_logistics_walk', '' );
$opt_logistics_parking = get_option( 'branch_logistics_parking', '' );
$opt_logistics_nearby = get_option( 'branch_logistics_schools', '' );
$opt_social = get_option( 'branch_social' );
if ( empty( $opt_social ) || ! is_array( $opt_social ) ) {
$opt_social = carbon_get_theme_option( 'site_social' );
}
?>
<section class="contacts" id="contacts" aria-label="Контакты">
<div class="container">
<div class="contacts__header">
<span class="bento-label">Контакты</span>
<h2 class="bento-h2">Наш адрес</h2>
<p class="bento-p">Ждём вас в гости удобно добираться из любого района города</p>
</div>
<div class="contacts__wrapper">
<div class="contacts__info">
<?php if ( ! empty( $opt_phone ) ) : ?>
<div class="contacts__item">
<div class="contacts__subtitle">Телефон:</div>
<a class="contacts__value" href="tel:+<?php echo preg_replace( '/[^0-9]/', '', $opt_phone ); ?>"><?php echo esc_html( $opt_phone ); ?></a>
</div>
<?php endif; ?>
<?php if ( ! empty( $opt_email ) ) : ?>
<div class="contacts__item">
<div class="contacts__subtitle">Почта:</div>
<a class="contacts__value" href="mailto:<?php echo esc_attr( $opt_email ); ?>"><?php echo esc_html( $opt_email ); ?></a>
</div>
<?php endif; ?>
<?php if ( ! empty( $opt_address ) ) : ?>
<div class="contacts__item">
<div class="contacts__subtitle">Адрес:</div>
<div class="contacts__value"><?php echo esc_html( $opt_address ); ?></div>
</div>
<?php endif; ?>
<?php if ( $opt_logistics_walk || $opt_logistics_parking || $opt_logistics_nearby ) : ?>
<div class="contacts__logistics">
<?php if ( ! empty( $opt_logistics_walk ) ) : ?>
<span class="contacts__logistics-item">
<svg class="contacts__logistics-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"/><path d="M12 20c0-1.1.9-2 2-2h2a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-2Z"/><path d="M10 20H5a2 2 0 0 0-2 2v2"/><path d="M14 22h5a2 2 0 0 0 2-2v-2"/></svg>
<span class="contacts__logistics-text"><?php echo esc_html( $opt_logistics_walk ); ?></span>
</span>
<?php endif; ?>
<?php if ( ! empty( $opt_logistics_parking ) ) : ?>
<span class="contacts__logistics-item">
<svg class="contacts__logistics-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 17V7h4a3 3 0 0 1 0 6H9"/></svg>
<span class="contacts__logistics-text"><?php echo esc_html( $opt_logistics_parking ); ?></span>
</span>
<?php endif; ?>
<?php if ( ! empty( $opt_logistics_nearby ) ) : ?>
<span class="contacts__logistics-item">
<svg class="contacts__logistics-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9.5 12 3l9 6.5"/><path d="M5 12v7a1 1 0 0 0 1 1h5v-5h2v5h5a1 1 0 0 0 1-1v-7"/><path d="M9 10h6v2H9z"/></svg>
<span class="contacts__logistics-text"><?php echo esc_html( $opt_logistics_nearby ); ?></span>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ( ! empty( $opt_social ) && is_array( $opt_social ) ) : ?>
<div class="contacts__item">
<div class="contacts__subtitle">Наши соцсети:</div>
<div class="contacts__social">
<?php foreach ( $opt_social as $item ) :
$link = '';
$name = '';
if ( is_array( $item ) ) {
$link = $item['url'] ?? $item['link'] ?? '';
$name = $item['name'] ?? $item['title'] ?? '';
} elseif ( is_string( $item ) ) {
$link = $item;
}
if ( $link ) : ?>
<a class="contacts__social-link" href="<?php echo esc_url( $link ); ?>" target="_blank" rel="noopener noreferrer" title="<?php echo esc_attr( $name ); ?>">
<?php echo esc_html( $name ?: $link ); ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
<div class="contacts__map">
<div id="ya-map" style="width: 100%; height: 100%; min-height: 400px;"
data-coords="<?php echo esc_attr( $opt_coords ?: '55.7558,37.6173' ); ?>"
data-label="<?php echo esc_attr( $opt_name ?: 'Детский центр «Декарт»' ); ?>"></div>
</div>
</div>
</div>
</section>

View File

@ -1,108 +0,0 @@
<?php
/**
* Преподаватели (горизонтальный скролл)
* .bento .pksh-section .pksh-section--teachers #teachers
*
* @package Dekart
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$data = Pksh_Data::instance();
$teachers = $data->get_teachers();
?>
<section class="bento pksh-section pksh-section--teachers" id="teachers" aria-label="Преподаватели">
<div class="bento__full section-header--left">
<span class="bento-label">Преподаватели</span>
<h2 class="bento-h2">Наши преподаватели практикующие педагоги</h2>
<p class="bento-p">Каждый педагог имеет опыт работы с дошкольниками от 5 лет. Все действующие учителя начальных классов с высшим образованием.</p>
<div class="pksh-swipe-hint" aria-hidden="true">
<span class="pksh-swipe-hint__arrow">👇</span>
<span class="pksh-swipe-hint__text">Листайте, чтобы познакомиться с преподавателями</span>
</div>
</div>
<div class="bento__full">
<div class="pksh-teachers__scroll-x">
<div class="pksh-teachers__wrapper">
<?php if ( is_array( $teachers ) && ! empty( $teachers ) ) : ?>
<?php foreach ( $teachers as $item ) :
$t_id = $item['teacher_id'] ?? 0;
$t_subj = $item['teacher_subject'] ?? '';
$t_about = $item['teacher_about'] ?? '';
$t_badge = $item['teacher_badge'] ?? '';
$t_exp = $item['teacher_exp'] ?? '';
$t_post = $t_id ? get_post( $t_id ) : null;
$t_name = $t_post ? $t_post->post_title : '—';
$t_photo = 0;
if ( $t_post ) {
$t_photo = get_post_meta( $t_id, '_teacher_avatar', true );
if ( ! $t_photo ) {
$t_photo = get_post_meta( $t_id, '_thumbnail_id', true );
}
}
if ( empty( $t_subj ) && $t_post ) {
$t_subj = get_post_meta( $t_id, '_teacher_direction', true );
}
if ( empty( $t_about ) && $t_post ) {
$t_about = get_post_meta( $t_id, '_teacher_about', true );
}
if ( empty( $t_exp ) && $t_post ) {
$start_year = get_post_meta( $t_id, '_teacher_start_year', true );
if ( $start_year && is_numeric( $start_year ) ) {
$e = (int) date( 'Y' ) - (int) $start_year;
if ( $e > 0 ) {
$t_exp = $e . ' лет';
}
}
} elseif ( ! empty( $t_exp ) && ctype_digit( trim( $t_exp ) ) ) {
$t_exp = trim( $t_exp ) . ' лет';
}
?>
<div class="pksh-teachers__item">
<div class="pksh-teachers__card">
<div class="pksh-teachers__card-top">
<?php if ( $t_photo ) : ?>
<?php $photo_url = wp_get_attachment_image_url( $t_photo, array( 280, 280 ) ); ?>
<img class="pksh-teachers__photo" loading="lazy" width="140" height="140"
src="<?php echo esc_url( $photo_url ?: get_template_directory_uri() . '/assets/images/no-photo.png' ); ?>"
alt="<?php echo esc_attr( $t_name ); ?>">
<?php else : ?>
<img class="pksh-teachers__photo" loading="lazy" width="140" height="140"
src="<?php echo get_template_directory_uri(); ?>/assets/images/no-photo.png"
alt="<?php echo esc_attr( $t_name ); ?>">
<?php endif; ?>
</div>
<div class="pksh-teachers__card-body">
<h3 class="pksh-teachers__name"><?php echo esc_html( $t_name ); ?></h3>
<?php if ( $t_subj ) : ?>
<p class="pksh-teachers__subj"><?php echo esc_html( $t_subj ); ?></p>
<?php endif; ?>
<?php if ( $t_about ) : ?>
<p class="pksh-teachers__desc"><?php echo esc_html( wp_strip_all_tags( $t_about ) ); ?></p>
<?php endif; ?>
<div class="pksh-teachers__meta">
<?php if ( $t_badge ) : ?>
<span class="pksh-teachers__meta-badge"><?php echo esc_html( $t_badge ); ?></span>
<?php endif; ?>
<?php if ( $t_exp ) : ?>
<span class="pksh-teachers__meta-exp"><svg aria-hidden="true" width="14" height="14" style="vertical-align:-2px;margin-right:4px"><use href="#icon-calendar"/></svg> Стаж: <?php echo esc_html( $t_exp ); ?></span>
<?php endif; ?>
</div>
<button class="pksh-teachers__btn open-bitrix-form">Записаться к этому педагогу</button>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,144 @@
<?php
/**
* Преподаватели (горизонтальный скролл, CPT)
*
* Reads teacher data directly from the 'teacher' custom post type.
*
* Поддерживает $args:
* - teacher_ids (int[]) выбрать конкретных преподавателей.
* Если пусто/не передан показываются все.
* - description (string) текст описания под заголовком.
* Если пусто/не передан жёсткий текст по умолчанию.
* - hide_label (bool) скрыть бейдж «Преподаватели» над заголовком.
*
* Fields used:
* - Post title teacher name
* - _teacher_direction subject
* - _teacher_avatar photo (attachment ID)
* - _teacher_badge badge text
* - _teacher_start_year experience calculation
* - _teacher_about description
*
* @package Dekart
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// ── Parse args ─────────────────────────────────────────────
$teacher_ids = $args['teacher_ids'] ?? array();
$description = isset( $args['description'] ) ? $args['description'] : 'Каждый педагог имеет опыт работы с дошкольниками от 5 лет. Все — действующие учителя начальных классов с высшим образованием.';
$hide_label = ! empty( $args['hide_label'] );
// ── Query ──────────────────────────────────────────────────
$query_args = array(
'post_type' => 'teacher',
'posts_per_page' => -1,
'post_status' => 'publish',
);
if ( ! empty( $teacher_ids ) ) {
$query_args['post__in'] = $teacher_ids;
$query_args['orderby'] = 'post__in';
} else {
$query_args['orderby'] = 'date';
$query_args['order'] = 'DESC';
}
$teachers_query = new WP_Query( $query_args );
?>
<section class="bento teachers-cards" id="teachers" aria-label="Преподаватели">
<div class="bento__full section-header--left">
<?php if ( ! $hide_label ) : ?>
<span class="bento-label">Преподаватели</span>
<?php endif; ?>
<h2 class="bento-h2">Наши преподаватели практикующие педагоги</h2>
<p class="bento-p"><?php echo esc_html( $description ); ?></p>
<div class="pksh-swipe-hint" aria-hidden="true">
<span class="pksh-swipe-hint__arrow">👇</span>
<span class="pksh-swipe-hint__text">Листайте, чтобы познакомиться с преподавателями</span>
</div>
</div>
<div class="bento__full">
<div class="teachers-cards__scroll-x">
<div class="teachers-cards__wrapper">
<?php if ( $teachers_query->have_posts() ) : ?>
<?php while ( $teachers_query->have_posts() ) :
$teachers_query->the_post();
$t_id = get_the_ID();
$t_name = get_the_title();
$t_subj = get_post_meta( $t_id, '_teacher_direction', true );
$t_about = get_post_meta( $t_id, '_teacher_about', true );
$t_badge = get_post_meta( $t_id, '_teacher_badge', true );
$t_photo = get_post_meta( $t_id, '_teacher_avatar', true );
$start_year = get_post_meta( $t_id, '_teacher_start_year', true );
// Experience calculation.
$t_exp = '';
if ( $start_year && is_numeric( $start_year ) ) {
$e = (int) date( 'Y' ) - (int) $start_year;
if ( $e > 0 ) {
$t_exp = $e . ' лет';
}
}
// Name splitting: first part on first line, rest on second.
$name_parts = explode( ' ', $t_name, 2 );
$name_first = $name_parts[0] ?? $t_name;
$name_rest = $name_parts[1] ?? '';
// Description truncation.
$t_about_clean = $t_about ? wp_strip_all_tags( $t_about ) : '';
if ( mb_strlen( $t_about_clean ) > 200 ) {
$t_about_clean = mb_substr( $t_about_clean, 0, 200 ) . '…';
}
?>
<div class="teachers-cards__item">
<div class="teachers-cards__card">
<div class="teachers-cards__card-top">
<?php if ( $t_photo ) : ?>
<?php $photo_url = wp_get_attachment_image_url( $t_photo, array( 280, 280 ) ); ?>
<img class="teachers-cards__photo" loading="lazy" width="140" height="140"
src="<?php echo esc_url( $photo_url ?: get_template_directory_uri() . '/assets/images/no-photo.png' ); ?>"
alt="<?php echo esc_attr( $t_name ); ?>">
<?php else : ?>
<img class="teachers-cards__photo" loading="lazy" width="140" height="140"
src="<?php echo esc_url( get_template_directory_uri() . '/assets/images/no-photo.png' ); ?>"
alt="<?php echo esc_attr( $t_name ); ?>">
<?php endif; ?>
</div>
<div class="teachers-cards__card-body">
<h3 class="teachers-cards__name">
<?php echo esc_html( $name_first ); ?>
<?php if ( $name_rest ) : ?>
<br><?php echo esc_html( $name_rest ); ?>
<?php endif; ?>
</h3>
<?php if ( $t_subj ) : ?>
<p class="teachers-cards__subj"><?php echo esc_html( $t_subj ); ?></p>
<?php endif; ?>
<?php if ( $t_about_clean ) : ?>
<p class="teachers-cards__desc"><?php echo esc_html( $t_about_clean ); ?></p>
<?php endif; ?>
<div class="teachers-cards__meta">
<?php if ( $t_badge ) : ?>
<span class="teachers-cards__meta-badge"><?php echo esc_html( $t_badge ); ?></span>
<?php endif; ?>
<?php if ( $t_exp ) : ?>
<span class="teachers-cards__meta-exp"><svg aria-hidden="true" width="14" height="14" style="vertical-align:-2px;margin-right:4px"><use href="#icon-calendar"/></svg> Стаж: <?php echo esc_html( $t_exp ); ?></span>
<?php endif; ?>
</div>
<button class="teachers-cards__btn open-bitrix-form">Записаться к этому педагогу</button>
</div>
</div>
</div>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
</div>
</div>
</div>
</section>