Вопрос или проблема
Я использовал <!-- wp:post-title /-->
внутри цикла постов, но это просто показывает один и тот же заголовок пять раз. Если использовать the_title(), то вроде бы работает, но WordPress заявил, что блок содержит неожиданный или неверный контент. Каковы основные причины?
/**
* Title: Most Viewed Posts
* Slug: the-bulletin/most-viewed-posts
* Categories: posts
*/
$args = array(
'post_type' => 'post',
'posts_per_page' => 5,
'meta_key' => 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC'
);
$query = new WP_Query($args);
if ($query->have_posts()) {
?>
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph {"fontSize":"large"} -->
<p class="has-large-font-size">Must Read</p>
<!-- /wp:paragraph -->
<?php while ($query->have_posts()) {
$query->the_post(); ?>
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:post-title /--></div>
<!-- /wp:group -->
<?php }; ?>
<?php
wp_reset_postdata();
?>
</div>
<!-- /wp:group -->
<?php
}
?>
Одним из предложений для содержимого шаблонов вашей темы является использование Query Loop <!-- wp:query {"query":{...}} -->
и разметки блока Post Template <!-- wp:post-template -->
с разметкой блока заголовка поста <!-- wp:post-title /-->
.
Это не сработает, как вы ожидаете, PHP предназначен для рендеринга блоков на сервере, он не знает о контексте редактора, если ему не указать контекст. Но для этого нужно прочитать его и передать компоненту на стороне JS, а затем снова прочитать на стороне PHP. Кроме того, нельзя использовать разметку блока в чистом виде внутри блока, рендеримого PHP, такие блоки должны быть монолитными без внутренних блоков, редактор не знает и не понимает, когда возвращаются внутренние блоки, которые выводятся через PHP таким образом.
Ключевые выводы:
- Нельзя возвращать разметку блока в чистом виде в рендеринге PHP
- Внутренние блоки должны оставаться внутренними, нельзя полностью определить их в PHP.
- Это, скорее всего, вызовет проблемы совместимости и нарушит проверку блоков, так как он не ожидает дочерних блоков в блоке, который их не поддерживает. Это также может вызвать проблемы, потому что компонент сохранения не сгенерирует ожидаемое.
- Этот подход является тупиковым и непоправимым, вам нужно выбрать другой подход
- Вместо
<!-- wp:post-title /-->
вам нужно рендерить блок напрямую и возвращать рендеренную версию- Скорее всего, это означает
the_title()
- Если вы настаиваете на использовании разметки блока, ее нужно будет пропустить через функцию, которая рендерит блок, такую как
do_blocks
( https://developer.wordpress.org/reference/functions/do_blocks/ ), но они не будут редактируемы, редактор увидит это как чистый HTML. Также понадобится- Может понадобиться использовать
parse_blocks
иrender_block
для предоставления контекста, например, текущего поста, чтобы они отображали правильно.
- Может понадобиться использовать
- Скорее всего, это означает
- Действительно ли вам нужен кастомный блок? Шаблон блока с циклом запроса и блоком заголовка, который заблокирован, чтобы пользователь не мог его редактировать/переставлять, был бы проще, легче и более перспективен на будущее
По сути, серверный блок рендеринга – это возможность использовать PHP для рендеринга фрагмента HTML, который может изменяться при каждом просмотре. Он не предназначен как контейнерный блок и задуман как единый монолитный компонент. Возможно, есть способы разрешить дочерние блоки, если отказаться от использования PHP в редакторе и использовать его только на фронтенде, но это добавляет сложности, по-прежнему полагается на чистый JS блок редактора и компоненты сохранения, и по-прежнему не использует разметку блока в чистом виде, как в вашем вопросе (синхронизированный шаблон или шаблон блока были бы методом для определения внутренних блоков).
.
Ответ или решение
Ваш вопрос касается проблемы отображения названий постов внутри WP_Query при использовании блоковой разметки, такой как <!– wp:post-title /–>. Давайте разберем эту ситуацию с точки зрения теории, примеров и практической реализации.
Теория
Когда речь идет о WordPress и его блоковом редакторе (ранее известном как Гутенберг), важно понимать, что блоки разрабатывались для работы в интерфейсе браузера и для взаимодействия с JavaScript API. Блоки предназначены для создания, редактирования и манипуляции контентом в браузере, поэтому их использование в традиционном PHP-шаблоне может привести к ошибкам и неожиданному поведению.
PHP в WordPress традиционно использовался для серверной обработки и генерации HTML-контента до появления блокового редактора. Это означает, что пробовать запихнуть блоковую разметку непосредственно в циклах PHP может быть проблематичным, как в вашем случае. Блоковый редактор не знает о контексте, заданном с помощью PHP, что приводит к некорректной обработке внутреннего содержания блока.
Пример
Предположим, у вас есть код, который вы привели. Вы пытаетесь использовать блок <!– wp:post-title /–> внутри PHP-цикла. Несмотря на то, что теоретически это может быть возможно, на практике это создает некорректный HTML, так как серверная реализация (PHP) не предназначена для внутренней обработки или манипуляции блоками.
Ваш текущий код:
$args = array(
'post_type' => 'post',
'posts_per_page' => 5,
'meta_key' => 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC'
);
$query = new WP_Query($args);
if ($query->have_posts()) {
?>
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group">
<!-- wp:paragraph {"fontSize":"large"} -->
<p class="has-large-font-size">Must Read</p>
<!-- /wp:paragraph -->
<?php while ($query->have_posts()) {
$query->the_post(); ?>
<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:post-title /--></div>
<!-- /wp:group -->
<?php }; ?>
<?php wp_reset_postdata(); ?>
</div>
<!-- /wp:group -->
<?php
}
?>
Практическая реализация
Чтобы корректно отобразить названия постов в вашем цикле, уберите блок-маркировки и замените их на прямой PHP. Используйте the_title()
, который является серверной функцией для получения и вывода названия поста:
while ($query->have_posts()) {
$query->the_post();
echo '<h2>' . get_the_title() . '</h2>';
}
Если же вы всё-таки хотите использовать блоки, то вам следует рассмотреть использование блоков Query и Post Template, которые были специально разработаны для таких случаев. Вы можете создать для этого блок-шаблон в редакторе.
Использование Query Loop блока
Вместо написания всего цикла в PHP, вы можете создать блок-шаблон, который содержит блок Query. Внутри Query блока найдите Post Template блок, который позволит вам организовать посты так, как вы этого хотите. Это может быть сделано через визуальный редактор в WordPress. Вот как это примерно будет выглядеть в разметке блоков:
<!-- wp:query {"query":{"perPage":5,"orderBy":"meta_value_num","order":"DESC","metaKey":"post_views_count"}} -->
<!-- wp:post-template -->
<!-- wp:post-title /-->
<!-- /wp:post-template -->
<!-- /wp:query -->
Заключение
Учитывая вышеизложенное, программный подход с использованием PHP и прямых блоков неэффективен и может вызвать ошибки в блок-редакторе WordPress. Вместо этого рекомендуется использовать соответствующие блоки через пользовательский интерфейс WordPress. Это не только решает проблему, но и улучшает редактируемость, упрощая взаимодействие с содержимым при использовании редактора блоков.
Переосмыслите использование PHP-блоков в современных темах для WordPress и сосредоточьтесь на возможностях, предоставляемых блоковым редактором, для создания динамического и удобного в работе контента.