Global-2026-07-15
This commit is contained in:
parent
15ac1f81aa
commit
3d9218df11
@ -643,6 +643,14 @@ function add_carbon() {
|
||||
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. Если пусто — рассчитывается из карточки преподавателя.' ),
|
||||
)),
|
||||
))
|
||||
// ====================================================
|
||||
@ -668,6 +676,10 @@ function add_carbon() {
|
||||
Field::make( 'text', 'pksh_prog_base_price_single', 'Стоимость разового занятия' )
|
||||
->set_width( 50 )
|
||||
->set_default_value( '1 000 ₽' ),
|
||||
Field::make( 'text', 'pksh_prog_base_price_razov', 'Стоимость разового занятия ВНЕ абонемента' )
|
||||
->set_width( 50 )
|
||||
->set_default_value( '1 200 ₽' )
|
||||
->set_help_text( 'Отдельная цена для «Разовое занятие вне абонемента: …». Если пусто — используется price_single.' ),
|
||||
Field::make( 'text', 'pksh_prog_base_urgency', 'Срочность (мест в группе)' )
|
||||
->set_width( 100 )
|
||||
->set_default_value( 'Осталось 2 места в группе' ),
|
||||
@ -688,6 +700,10 @@ function add_carbon() {
|
||||
Field::make( 'text', 'pksh_prog_prem_price_single', 'Стоимость разового занятия' )
|
||||
->set_width( 50 )
|
||||
->set_default_value( '1 500 ₽' ),
|
||||
Field::make( 'text', 'pksh_prog_prem_price_razov', 'Стоимость разового занятия ВНЕ абонемента' )
|
||||
->set_width( 50 )
|
||||
->set_default_value( '2 000 ₽' )
|
||||
->set_help_text( 'Отдельная цена для «Разовое занятие вне абонемента: …». Если пусто — используется price_single.' ),
|
||||
Field::make( 'text', 'pksh_prog_prem_urgency', 'Срочность (мест в группе)' )
|
||||
->set_width( 100 )
|
||||
->set_default_value( 'Осталось 3 места в группе' ),
|
||||
|
||||
@ -320,36 +320,38 @@ wp_cache_set( $cache_key, $this->branch['social'], 'dekart_branch', DAY_IN_SECON
|
||||
|
||||
/**
|
||||
* Данные базовой программы
|
||||
* @return array{name: string, subname: string, schedule: string, price_sub: string, price_single: string, urgency: string}
|
||||
* @return array{name: string, subname: string, schedule: string, price_sub: string, price_single: string, price_razov: string, urgency: string}
|
||||
*/
|
||||
public function get_base_program(): array {
|
||||
if ( ! array_key_exists( 'base', $this->programs ) ) {
|
||||
$this->programs['base'] = array(
|
||||
'name' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_name' ) ?: 'Уверенный старт',
|
||||
'subname' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_subname' ) ?: '2 раза в неделю — комфортный темп без перегрузки',
|
||||
'schedule' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_schedule' ) ?: 'вт, чт — 18:00–19:30',
|
||||
'price_sub' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_sub' ) ?: '7 500 ₽',
|
||||
'price_single' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_single' ) ?: '1 000 ₽',
|
||||
'urgency' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_urgency' ) ?: 'Осталось 2 места в группе',
|
||||
);
|
||||
$this->programs['base'] = array(
|
||||
'name' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_name' ) ?: 'Уверенный старт',
|
||||
'subname' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_subname' ) ?: '2 раза в неделю — комфортный темп без перегрузки',
|
||||
'schedule' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_schedule' ) ?: 'вт, чт — 18:00–19:30',
|
||||
'price_sub' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_sub' ) ?: '7 500 ₽',
|
||||
'price_single' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_single' ) ?: '1 000 ₽',
|
||||
'price_razov' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_price_razov' ) ?: '',
|
||||
'urgency' => carbon_get_post_meta( $this->post_id, 'pksh_prog_base_urgency' ) ?: 'Осталось 2 места в группе',
|
||||
);
|
||||
}
|
||||
return $this->programs['base'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Данные премиум-программы
|
||||
* @return array{name: string, subname: string, schedule: string, price_sub: string, price_single: string, urgency: string}
|
||||
* @return array{name: string, subname: string, schedule: string, price_sub: string, price_single: string, price_razov: string, urgency: string}
|
||||
*/
|
||||
public function get_premium_program(): array {
|
||||
if ( ! array_key_exists( 'prem', $this->programs ) ) {
|
||||
$this->programs['prem'] = array(
|
||||
'name' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_name' ) ?: 'Результат за 3 месяца',
|
||||
'subname' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_subname' ) ?: '3 раза в неделю — быстрый прогресс',
|
||||
'schedule' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_schedule' ) ?: 'пн, ср, пт — 16:30–18:00',
|
||||
'price_sub' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_sub' ) ?: '10 500 ₽',
|
||||
'price_single' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_single' ) ?: '1 500 ₽',
|
||||
'urgency' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_urgency' ) ?: 'Осталось 3 места в группе',
|
||||
);
|
||||
$this->programs['prem'] = array(
|
||||
'name' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_name' ) ?: 'Результат за 3 месяца',
|
||||
'subname' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_subname' ) ?: '3 раза в неделю — быстрый прогресс',
|
||||
'schedule' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_schedule' ) ?: 'пн, ср, пт — 16:30–18:00',
|
||||
'price_sub' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_sub' ) ?: '10 500 ₽',
|
||||
'price_single' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_single' ) ?: '1 500 ₽',
|
||||
'price_razov' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_price_razov' ) ?: '',
|
||||
'urgency' => carbon_get_post_meta( $this->post_id, 'pksh_prog_prem_urgency' ) ?: 'Осталось 3 места в группе',
|
||||
);
|
||||
}
|
||||
return $this->programs['prem'];
|
||||
}
|
||||
|
||||
@ -155,13 +155,7 @@ function dekart_schema_output(): void {
|
||||
$graph[] = $faq;
|
||||
}
|
||||
|
||||
// 11b. QAPage — ключевые вопросы для AI citation readiness
|
||||
$qa = dekart_schema_qapage();
|
||||
if ( $qa ) {
|
||||
$graph[] = $qa;
|
||||
}
|
||||
|
||||
// 11c. Event — бесплатное пробное занятие
|
||||
// 11b. Event — бесплатное пробное занятие
|
||||
$event = dekart_schema_trial_event();
|
||||
if ( $event ) {
|
||||
$graph[] = $event;
|
||||
@ -1415,57 +1409,6 @@ function dekart_schema_trial_event(): ?array {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* QAPage — ключевые вопросы для AI citation readiness.
|
||||
* Google retired FAQ rich results May 2026, но QAPage важен для AI Overviews/ChatGPT/Perplexity.
|
||||
*
|
||||
* @see https://schema.org/QAPage
|
||||
*/
|
||||
function dekart_schema_qapage(): ?array {
|
||||
if ( ! is_page( 2 ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$page_url = dekart_schema_page_url();
|
||||
$faq_items = carbon_get_post_meta( get_the_ID(), 'pksh_faq_items' );
|
||||
|
||||
if ( empty( $faq_items ) || ! is_array( $faq_items ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Берём только 3-5 ключевых вопросов (самые частые)
|
||||
$key_questions = array_slice( $faq_items, 0, 5 );
|
||||
|
||||
$main_entity = array();
|
||||
foreach ( $key_questions as $item ) {
|
||||
$question = isset( $item['faq_question'] ) ? trim( $item['faq_question'] ) : '';
|
||||
$answer = isset( $item['faq_answer'] ) ? trim( $item['faq_answer'] ) : '';
|
||||
|
||||
if ( empty( $question ) || empty( $answer ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$main_entity[] = array(
|
||||
'@type' => 'Question',
|
||||
'name' => wp_strip_all_tags( $question ),
|
||||
'acceptedAnswer' => array(
|
||||
'@type' => 'Answer',
|
||||
'text' => wp_strip_all_tags( $answer ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if ( empty( $main_entity ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return array(
|
||||
'@type' => 'QAPage',
|
||||
'@id' => $page_url . '#qapage',
|
||||
'mainEntity' => $main_entity,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offer / AggregateOffer с UnitPriceSpecification.
|
||||
* Добавляет priceSpecification с unitCode: 'MON' для цен за месяц.
|
||||
|
||||
@ -45,7 +45,7 @@ $prem = $data->get_premium_program();
|
||||
<div class="prog-card__pricing">
|
||||
<div class="prog-card__price prog-card__price--premium"><?php echo esc_html( $prem['price_sub'] ); ?> <span class="prog-card__price-period">стоимость абонемента за 4 недели</span></div>
|
||||
<div class="prog-card__price-sub"><?php echo esc_html( $prem['price_single'] ); ?> за занятие — дешевле репетитора</div>
|
||||
<div class="prog-card__price-single">Разовое занятие вне абонемента: <?php echo esc_html( $prem['price_single'] ); ?></div>
|
||||
<div class="prog-card__price-single">Разовое занятие вне абонемента: <?php echo esc_html( $prem['price_razov'] ?: $prem['price_single'] ); ?></div>
|
||||
<div class="prog-card__urgency"><?php echo esc_html( $prem['urgency'] ); ?></div>
|
||||
</div>
|
||||
|
||||
@ -124,7 +124,7 @@ $prem = $data->get_premium_program();
|
||||
<div class="prog-card__pricing">
|
||||
<div class="prog-card__price"><?php echo esc_html( $base['price_sub'] ); ?> <span class="prog-card__price-period">стоимость абонемента за 4 недели</span></div>
|
||||
<div class="prog-card__price-sub"><?php echo esc_html( $base['price_single'] ); ?> за занятие — дешевле репетитора</div>
|
||||
<div class="prog-card__price-single">Разовое занятие вне абонемента: <?php echo esc_html( $base['price_single'] ); ?></div>
|
||||
<div class="prog-card__price-single">Разовое занятие вне абонемента: <?php echo esc_html( $base['price_razov'] ?: $base['price_single'] ); ?></div>
|
||||
<div class="prog-card__urgency"><?php echo esc_html( $base['urgency'] ); ?></div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -32,6 +32,8 @@ $teachers = $data->get_teachers();
|
||||
$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 : '—';
|
||||
@ -51,6 +53,18 @@ $teachers = $data->get_teachers();
|
||||
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">
|
||||
@ -71,26 +85,15 @@ $teachers = $data->get_teachers();
|
||||
<?php if ( $t_subj ) : ?>
|
||||
<p class="pksh-teachers__subj"><?php echo esc_html( $t_subj ); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if ( $t_post ) :
|
||||
$t_desc = get_post_meta( $t_id, '_teacher_description', true );
|
||||
if ( ! empty( $t_desc ) ) : ?>
|
||||
<p class="pksh-teachers__desc"><?php echo esc_html( wp_strip_all_tags( $t_desc ) ); ?></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">
|
||||
<span class="pksh-teachers__meta-badge">👶 Работает с дошкольниками</span>
|
||||
<?php if ( $t_post ) :
|
||||
$exp_years = '';
|
||||
$start_year = get_post_meta( $t_id, '_teacher_start_year', true );
|
||||
if ( $start_year && is_numeric( $start_year ) ) {
|
||||
$exp = (int) date( 'Y' ) - (int) $start_year;
|
||||
if ( $exp > 0 ) {
|
||||
$exp_years = $exp . ' лет';
|
||||
}
|
||||
}
|
||||
if ( $exp_years ) : ?>
|
||||
<span class="pksh-teachers__meta-exp">📅 Стаж: <?php echo esc_html( $exp_years ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?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">📅 Стаж: <?php echo esc_html( $t_exp ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<button class="pksh-teachers__btn open-bitrix-form">Записаться к этому педагогу</button>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user