Получите и обрежьте полный контент поста в WP Query
Вопрос или проблема
Простая задача, но она не работает:
<?php
$content = apply_filters( 'the_content', get_the_content() );
$contentWithoutHTML = wp_strip_all_tags($content);
$pos = strpos($contentWithoutHTML, " ", 100);
$contentFinal = substr($contentWithoutHTML,0,$pos );
echo $contentFinal . "...";
?>
Мой пост сильно перевысит 100 символов (с пробелами), и все же я получаю ошибку strpos(): Offset not contained in string
, что заставляет меня думать, что на самом деле не получается получить всю строку контента. Но я применил фильтры, как я полагаю, должен был… пожалуйста, помогите. Также иногда, даже если я не получаю ошибку смещения, я просто получаю ...
, хотя снова, более 100 символов с пробелами… хотя иногда это работает. Почему такая непоследовательность?
Это в цикле WP_Query
, в котором большинство работает, но некоторые не работают… так что я довольно уверен, что ему передают строку, потому что я вижу это у других постов в цикле…
Полный цикл:
<?php
$args = array(
'orderby' => 'ID',
'order' => 'ASC',
'posts_per_page' => 7,
'meta_query' => array(
array(
'key' => '_thumbnail_id'
)
)
);
$query = new WP_Query($args);
while ($query->have_posts()):
$query->the_post();
?>
<div class="articleboxs boxs">
<div class="col-sm-4 noleft">
<div class="aricleleft boxs">
<?php the_post_thumbnail('medium', array(
'class' => 'img-responsive'
)) ?>
</div>
</div>
<div class="col-sm-8 noright">
<div class="aricleright boxs">
<div class="boxs">
<a href="https://wordpress.stackexchange.com/questions/310201/<?php echo get_permalink(); ?>"><h2 class="heading font_Libre"><?php the_title(); ?></h2></a>
<?php
$content = apply_filters('the_content', get_the_content('', true));
print_r($content);
$contentWithoutHTML = wp_strip_all_tags($content);
$pos = strpos($contentWithoutHTML, " ", 100);
$contentFinal = substr($contentWithoutHTML, 0, $pos);
?>
<p class="font_Roboto"><?php echo $contentFinal . "..."; ?></p>
</div>
</div>
</div>
</div>
<?php
endwhile;
wp_reset_postdata();
?>
Я думаю, что лучше всего было бы просто упростить то, что вы делаете. Я бы просто сделал что-то простое с этим, если все, что вы хотите сделать, это сократить количество выводимых символов. Я бы использовал mb_strimwidth
для сокращения символов, а внутри этого применил бы wp_strip_all_tags()
к get_the_content()
. Вот так:
$content = mb_strimwidth(wp_strip_all_tags(get_the_content()), 0, 100, '...');
echo $content;
Правка: Забыл упомянуть, что если у вас будут шорткоды в контенте, что я настоятельно не рекомендую, вам также может понадобиться обернуть get_the_content()
с помощью strip_shortcodes()
.
Ответ на этот вопрос заключается в роли
Как теперь ясно для меня, эта функция не предназначена для получения всей части контента поста в цикле, поэтому часть функции говорит о $more_link_text
и $strip_teaser
в качестве аргументов, касающихся текста, который будет обрезан.
Более того, apply_filters('the_content', get_the_content('', true))
не решает эту основополагающую проблему, она лишь делает некоторые изменения HTML в контенте.
Поэтому вместо этого в моем цикле я обращаюсь к глобальному $post
.
$post->post_content
и делаю strpos
и substr
оттуда.
В основном, так как я выполняю свою собственную функцию обрезки/аннотации, я могу полностью обойти get_the_content()
. Поскольку я также хочу вставить это прямо в тег <p>
, мой код может выглядеть вот так:
<?php
$contentWithoutHTML = wp_strip_all_tags($post->post_content);
$pos = strpos($contentWithoutHTML, " ", 100);
$contentFinal = substr($contentWithoutHTML,0,$pos );
?>
<p class="font_Roboto"><?php echo $contentFinal . "..."; ?></p>
Не забудьте сбросить WP_Query
после, чтобы продолжать успешно использовать $post
, с помощью wp_reset_postdata();
после цикла.
Ответ или решение
Получение и обрезка полного содержимого поста в WP Query
В процессе работы с циклом WP_Query может возникнуть необходимость получить и отформатировать содержимое постов. Однако, как показано в вашем коде, есть несколько аспектов, которые могут вызывать ошибки и непонятные результаты. Давайте рассмотрим основные проблемы и предложим оптимальное решение.
Проблемы исходного кода
-
Ошибка "strpos(): Offset not contained in string" указывает на то, что функция
strpos()
не находит пробел на позиции 100 или не может обработать полученную строку. Это может происходить по нескольким причинам, включая наличие пустого значения в$contentWithoutHTML
. -
Неоднородность результата может быть связана с тем, что функция
get_the_content()
не всегда возвращает полное содержимое поста в зависимости от контекста, в котором она вызывается. Например, если у вас есть настройка для обрезки контента, это может повлиять на результат. -
Использование
apply_filters('the_content', get_the_content('', true))
не всегда эффективно, так как это может возвращать упрощенное содержание, в зависимости от аргументов.
Оптимальное решение
Для того чтобы избежать описанных ошибок и упростить логику обрезки контента, рекомендуется использовать глобальный объект $post
. Также оптимальным вариантом будет использование mb_strimwidth()
для обрезки строки.
Шаги для решения проблемы:
-
Использовать глобальный объект
$post
. Это позволит вам получить полное содержимое поста без применения лишних аргументов и фильтров. -
Применить функцию
wp_strip_all_tags()
для удаления HTML-тегов. Это гарантирует, что вы работаете только с чистым текстом. -
Использовать
mb_strimwidth()
для безопасного обрезания строки. Эта функция позволяет избежать возможных проблем с кодировкой и сохраняет корректность формата.
Пример кода
Вот переработанный пример вашего кода:
<?php
$args = array(
'orderby' => 'ID',
'order' => 'ASC',
'posts_per_page' => 7,
'meta_query' => array(
array(
'key' => '_thumbnail_id'
)
)
);
$query = new WP_Query($args);
while ($query->have_posts()):
$query->the_post();
?>
<div class="articleboxs boxs">
<div class="col-sm-4 noleft">
<div class="aricleleft boxs">
<?php the_post_thumbnail('medium', array('class' => 'img-responsive')); ?>
</div>
</div>
<div class="col-sm-8 noright">
<div class="aricleright boxs">
<div class="boxs">
<a href="<?php echo get_permalink(); ?>">
<h2 class="heading font_Libre"><?php the_title(); ?></h2>
</a>
<?php
// Получаем текст без HTML
$contentWithoutHTML = wp_strip_all_tags($post->post_content);
// Обрезаем строку до 100 символов
$contentFinal = mb_strimwidth($contentWithoutHTML, 0, 100, '...');
// Выводим результат
?>
<p class="font_Roboto"><?php echo $contentFinal; ?></p>
</div>
</div>
</div>
</div>
<?php
endwhile;
wp_reset_postdata();
?>
Заключение
Данное решение устраняет ошибки и обеспечивает более стабильную работу при получении и обработке содержимого постов в WordPress. Использование глобального объекта $post
, а также безопасные функции обрезки текста гарантируют корректный вывод информации без лишних пробелов или HTML-тегов. Помните о том, что всегда следует выполнять wp_reset_postdata()
после каждого цикла WP_Query для предотвращения возможных конфликтов с глобальным объектом поста.