Manager
БЫСТРАЯ СВЯЗЬ
Консультация за 5 минут

Виза Visiteur во Франциии

Да. Для этого тебе нужен единый single-legal.php, построенный по стилю шаблона новостей, но с другой логикой данных:

  • вместо страны сверху — название программы

  • h1заголовок правового материала

  • дата — строка вида «Данные актуализированы [дата публикации]»

  • описание — как lead/excerpt в новостях

  • ниже — основной текст из редактора

  • блок «Другие новости» — только новости по той же стране, что и у текущей правовой страницы

Ниже даю готовый шаблон.


Готовый

single-legal.php

<?php
/** Single Legal (CPT: legal) */
get_header();
the_post();

function gi_legal_lead($post_id){
  $lead = get_the_excerpt($post_id);
  if (!$lead){
    $text = wp_strip_all_tags(get_post_field('post_content', $post_id));
    $lead = wp_trim_words($text, 35, '…');
  }
  return $lead;
}

$photo_caption = get_field('legal_photo_caption');
$photo_credit  = get_field('legal_photo_credit');

/**
 * Получаем страну и программу у legal
 */
$legal_country_name = '';
$legal_program_name = '';

if (taxonomy_exists('legal_country')) {
  $country_terms = get_the_terms(get_the_ID(), 'legal_country');
  if ($country_terms && !is_wp_error($country_terms)) {
    $legal_country_name = $country_terms[0]->name;
  }
}

if (taxonomy_exists('legal_program')) {
  $program_terms = get_the_terms(get_the_ID(), 'legal_program');
  if ($program_terms && !is_wp_error($program_terms)) {
    $legal_program_name = $program_terms[0]->name;
  }
}

/**
 * Если нет программы — подстрахуемся заголовком
 */
if (!$legal_program_name) {
  $legal_program_name = get_the_title();
}
?>
<style>
  @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&family=Playfair+Display:wght@600;700;800&display=swap');

  :root{
    --brand-blue:#334257;
    --brand-gold:#CDA578;

    --bg:#f7f9fc;
    --card:#fff;
    --text:#1a2230;
    --muted:#6e7b90;
    --accent:var(--brand-gold);
    --border:#e8edf5;
    --shadow:0 22px 44px rgba(17,26,40,.08);
    --radius:26px;
    --gold:#CDA578;
    --rule:#d9dee7;
  }

  html,body{
    background:var(--bg);
    color:var(--text);
    font:16px/1.68 "Open Sans",system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,"Helvetica Neue",Arial,sans-serif;
  }

  .wrap{
    width: 100%;
    max-width: 1380px;
    margin: 0 auto;
    padding: 24px;
    box-sizing: border-box;
  }

  .breadcrumbs{
    padding-top: 150px;
    margin-bottom: 34px;
  }

  .cnbc-hero{padding:0;margin:0}

  .cnbc-kicker{
    font-weight:800;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:#1A2234;
    font-size:14px;
    margin:0 0 18px;
  }

  .cnbc-title{
    font-weight:900;
    max-width:none;
    font-size:45px;
    line-height:1.02;
    margin:0 0 18px;
    color:var(--text);
  }

  .cnbc-meta{
    display:flex;
    align-items:center;
    gap:10px;
    color:var(--muted);
    font-size:13px;
    letter-spacing:.10em;
    text-transform:uppercase;
    margin-bottom:20px;
    flex-wrap:wrap;
  }

  .cnbc-divider{
    height:6px;
    width:100%;
    background:var(--gold);
    margin:0 0 18px;
  }

  .post-gold-divider{
    width:100%;
    height:1px;
    background:#CDA578;
    margin:18px 0 10px;
  }

  .cnbc-lead{
    max-width:none;
    font-size:18px;
    line-height:1.6;
    margin:0 0 26px;
  }

  .cnbc-photo{margin:0 0 28px}
  .cnbc-photo__rule{height:1px;background:var(--rule);width:100%}
  .cnbc-photo__rule--top{margin:0 0 14px}
  .cnbc-photo__rule--bottom{margin:14px 0 0}
  .cnbc-photo__img{width:100%;height:auto;display:block;border-radius:0}
  .cnbc-photo__cap{margin-top:12px}
  .cnbc-photo__caption{font-size:16px;line-height:1.45;color:#111827;font-weight:600}
  .cnbc-photo__credit{margin-top:6px;font-size:14px;color:var(--muted);font-style:italic}

  .article{
    background:transparent;
    border:0;
    box-shadow:none;
    padding:0;
    margin-top:22px;
  }

  .entry{
    max-width:100%;
    margin:0;
    font-size:18px;
    line-height:1.75;
    color:var(--text);
  }

  .entry h2,
  .entry h3,
  .entry h4{
    font-family:"Playfair Display", serif;
    font-weight:700;
    color:var(--text);
  }

  .entry h2{
    font-size:34px;
    line-height:1.25;
  }

  .entry h3{
    font-size:28px;
    line-height:1.3;
  }

  .entry h4{
    font-size:22px;
    line-height:1.35;
  }

  .entry img{
    max-width:100%;
    height:auto;
    border-radius:0;
  }

  .entry a{
    color:#1a73e8;
    text-decoration:underline;
    text-underline-offset:3px;
  }

  @media (max-width:900px){
    .breadcrumbs{padding-top:120px;}
    .cnbc-title{font-size:30px}
    .cnbc-lead{font-size:14px}
    .entry{font-size:14px}
    .entry h2{font-size:30px;line-height:1.25;}
    .entry h3{font-size:28px;line-height:1.3;}
    .entry h4{font-size:22px;line-height:1.35;}
  }
</style>

<div class="wrap page-align">
  <div class="breadcrumbs">
    <?php if (function_exists('yoast_breadcrumb')) yoast_breadcrumb('', ''); ?>
  </div>

  <section class="cnbc-hero">
    <div class="cnbc-kicker">
      <?php echo esc_html(mb_strtoupper($legal_program_name)); ?>
    </div>

    <h1 class="cnbc-title"><?php the_title(); ?></h1>

    <div class="cnbc-meta">
      <span>Данные актуализированы <?php echo esc_html(get_the_date('d.m.Y')); ?></span>
      <span>•</span>
      <?php
        $words = str_word_count(wp_strip_all_tags(get_post_field('post_content', get_the_ID())));
        $mins  = max(1, ceil($words / 180));
      ?>
      <span><?php echo $mins; ?> мин. чтения</span>
    </div>

    <div class="post-gold-divider"></div>
    <div class="cnbc-divider"></div>

    <div class="cnbc-lead">
      <?php echo esc_html(gi_legal_lead(get_the_ID())); ?>
    </div>

    <?php if (has_post_thumbnail()): ?>
      <figure class="cnbc-photo">
        <div class="cnbc-photo__rule cnbc-photo__rule--top"></div>

        <?php the_post_thumbnail('full', ['class'=>'cnbc-photo__img','alt'=>get_the_title()]); ?>

        <?php if ($photo_caption || $photo_credit): ?>
          <figcaption class="cnbc-photo__cap">
            <?php if ($photo_caption): ?>
              <div class="cnbc-photo__caption"><?php echo wp_kses_post(nl2br($photo_caption)); ?></div>
            <?php endif; ?>
            <?php if ($photo_credit): ?>
              <div class="cnbc-photo__credit"><?php echo esc_html($photo_credit); ?></div>
            <?php endif; ?>
          </figcaption>
        <?php endif; ?>

        <div class="cnbc-photo__rule cnbc-photo__rule--bottom"></div>
      </figure>
    <?php endif; ?>
  </section>

  <article class="article">
    <div class="entry">
      <?php the_content(); ?>
    </div>
  </article>
</div>

<?php
$thumb = get_the_post_thumbnail_url(get_the_ID(), 'large');
$publisher_logo = get_site_icon_url();
?>
<script type="application/ld+json">
{
  "@context":"https://schema.org",
  "@type":"Article",
  "headline": <?php echo json_encode(get_the_title()); ?>,
  "datePublished":"<?php echo get_the_date('c'); ?>",
  "dateModified":"<?php echo get_the_modified_date('c'); ?>",
  "image":[<?php echo $thumb ? json_encode($thumb) : '""'; ?>],
  "mainEntityOfPage":"<?php the_permalink(); ?>",
  "author":{"@type":"Organization","name":<?php echo json_encode(get_bloginfo('name')); ?>},
  "publisher":{"@type":"Organization","name":<?php echo json_encode(get_bloginfo('name')); ?>,"logo":{"@type":"ImageObject","url":<?php echo json_encode($publisher_logo); ?>}}
}
</script>

<?php
/**
 * Другие новости — только по той же стране
 */
$more_news_args = [
  'post_type'      => 'news',
  'posts_per_page' => 6,
  'orderby'        => 'date',
  'order'          => 'DESC',
  'no_found_rows'  => true,
];

if ($legal_country_name && taxonomy_exists('news_country')) {
  $more_news_args['tax_query'] = [
    [
      'taxonomy' => 'news_country',
      'field'    => 'name',
      'terms'    => $legal_country_name,
    ]
  ];
}

$more_news_q = new WP_Query($more_news_args);

if ($more_news_q->have_posts()) : ?>
  <div class="wrap page-align">
    <section class="more-news-cnbc">
      <div class="more-news-cnbc__head">
        <h2 class="more-news-cnbc__title">ДРУГИЕ <span>НОВОСТИ</span></h2>
      </div>

      <div class="more-news-list">
        <?php while ($more_news_q->have_posts()) : $more_news_q->the_post(); ?>
          <article class="mn-row">
            <a class="mn-row__imglink" href="<?php the_permalink(); ?>">
              <?php if (has_post_thumbnail()) the_post_thumbnail('medium_large', ['class'=>'mn-row__img','alt'=>get_the_title()]); ?>
            </a>

            <div class="mn-row__text">
              <div class="mn-row__rubric">
                <?php echo get_the_date('j F Y'); ?>
              </div>

              <h3 class="mn-row__title">
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
              </h3>
            </div>
          </article>
        <?php endwhile; wp_reset_postdata(); ?>
      </div>
    </section>
  </div>
<?php endif; ?>

<style>
.more-news-cnbc{ margin:10px 0; }

.more-news-cnbc__head{
  border-top:1px solid #CDA578;
  padding-top:18px;
  margin-bottom:18px;
}

.more-news-cnbc__title{
  margin:0;
  font-family:"Open Sans", sans-serif;
  font-weight:400;
  font-size:26px;
  text-transform:uppercase;
  color:#2A2A2A;
}
.more-news-cnbc__title span{ font-weight:750; }

.more-news-list{
  display:grid;
  grid-template-columns:1fr 1fr;
  column-gap:60px;
  row-gap:40px;
}

.mn-row{
  display:grid;
  grid-template-columns:260px 1fr;
  column-gap:26px;
  align-items:center;
  padding-bottom:30px;
  border-bottom:1px solid #CDA578;
  transition: transform .25s ease, background-color .25s ease;
}

.mn-row__img{
  width:100%;
  height:140px;
  object-fit:cover;
  display:block;
  transition: transform .35s ease, filter .35s ease;
}

.mn-row__rubric{
  font-family:"Open Sans", sans-serif;
  font-size:16px;
  letter-spacing:.04em;
  text-transform:uppercase;
  color:#334257;
  margin-bottom:8px;
}

.mn-row__title{
  margin:0;
  font-family:"Playfair Display", serif;
  font-weight:900;
  font-size:20px;
  line-height:1.1;
}

.mn-row__title a{
  color:#0b0f14;
  text-decoration:none;
  position:relative;
  transition:color .25s ease;
}

.mn-row__title a::after{
  content:"";
  position:absolute;
  left:0;
  bottom:-4px;
  width:0;
  height:1px;
  background:#0b0f14;
  transition: width .3s ease;
}

.mn-row:hover{
  transform: translateX(6px);
}

.mn-row:hover .mn-row__img{
  transform: scale(1.04);
  filter: brightness(.95);
}

.mn-row:hover .mn-row__title a::after{
  width:100%;
}

@media (max-width:1100px){
  .mn-row{ grid-template-columns:220px 1fr; }
  .mn-row__title{ font-size:26px; }
}

@media (max-width:900px){
  .more-news-list{
    grid-template-columns:1fr;
    column-gap:0;
    row-gap:0;
  }

  .mn-row{
    grid-template-columns:150px 1fr;
    column-gap:18px;
    align-items:center;
    padding:18px 0;
    border-bottom:1px solid #d7dce2;
  }

  .mn-row__img{
    height:92px;
    width:100%;
    object-fit:cover;
    display:block;
  }

  .mn-row__rubric{
    font-size:14px;
    letter-spacing:.04em;
    margin-bottom:6px;
  }

  .mn-row__title{
    font-size:16px;
    line-height:1.15;
  }
}

@media (max-width:420px){
  .mn-row{
    grid-template-columns:132px 1fr;
    column-gap:14px;
  }
  .mn-row__img{ height:86px; }
  .mn-row__title{ font-size:14px; }
}
</style>

<?php get_footer(); ?>

Что этот шаблон делает

Он меняет логику именно так, как ты описала:

1. Верхняя строка

Берёт термин из legal_program и выводит его вместо страны.

2. Заголовок

Выводит the_title() — ты сможешь писать любой заголовок вида:

  • Регуляторно-правовая база Visiteur во Франции

  • Правовая база Digital Nomad в Испании

  • Нормативная база Golden Visa Portugal

3. Дата

Показывает:

  • Данные актуализированы 10.04.2026

4. Описание

Берёт excerpt, а если его нет — делает lead из начала текста.

5. Основной текст

Берёт из редактора WordPress:

  • h2

  • h3

  • h4

  • абзацы

  • списки

  • ссылки

6. Другие новости

Подтягивает news только по той же стране, что указана у правового материала в legal_country.


Что важно проверить у тебя в админке

Чтобы блок «Другие новости» работал корректно, нужно чтобы:

У

legal

были термины:

  • legal_country

  • legal_program

У новостей была таксономия:

  • news_country

И названия стран должны совпадать. Например:

  • в legal_country: Франция

  • в news_country: Франция

Если в одной таксономии France, а в другой Франция, фильтр не сработает.


Что ещё рекомендую добавить в ACF для legal

Если хочешь, чтобы этот шаблон был совсем как news, добавь для legal такие поля:

1.

legal_photo_caption

Тип: Textarea

2.

legal_photo_credit

Тип: Text

Тогда подпись и кредит под картинкой тоже будут работать.


Как теперь создавать страницы

Ты идёшь в:

Право → Добавить правовой материал

И заполняешь:

  • заголовок

  • excerpt

  • featured image

  • страну

  • программу

  • контент

И каждая запись автоматически откроется через этот шаблон.


Что потом сделать следующим шагом

После этого уже можно будет переделать карточки на странице Право, чтобы они ссылались не на старые page_id, а на записи legal.

Если хочешь, следующим сообщением я дам тебе ещё и адаптированную версию page-pravo.php, чтобы карточки автоматически тянулись из legal, но визуально оставались такими же, как сейчас.

telegram-app
whatsapp--v1