Разделение контента и галереи
Есть ли способ разделить контент записи и шорткод галереи? Я хочу отображать галерею вне основного контента, независимо от того, где и как она размещена. Я могу использовать этот код для получения самого шорткода:
if(has_shortcode(get_the_content(), 'gallery')){
$pattern = get_shortcode_regex();
preg_match("/$pattern/s", get_the_content(), $matches);
echo do_shortcode($matches[0]);
}
Но это не работает, если шорткод галереи не является первым в контенте. Есть ли способ полностью разделить мой контент и галерею?
Редактирование: У меня есть частичное решение, но оно кажется слишком сложным. Оно сначала получает первый шорткод в записи (это нужно исправить, так как мне нужен только шорткод "Галерея"), затем удаляет все шорткоды из контента (опять же, не совсем то, что я хочу сделать).
<?php if(has_shortcode(get_the_content(), 'gallery')) : ?>
<?php
$pattern = get_shortcode_regex();
preg_match("/$pattern/s", get_the_content(), $matches);
?>
<div id="content">
<?php echo strip_shortcodes(get_the_content()); ?>
</div>
<div id="gallery">
<?php echo do_shortcode($matches[0]); ?>
</div>
<?php endif; ?>
Редактирование #2 - Теперь я смог получить только шорткоды галереи в записи. Я также добавил фильтр для удаления шорткода галереи из the_content()
- проблема в том, что он не совсем удаляет шорткод, так как он все равно выводится, но не позволяет выполнить "do_shortcode()"
Functions.php
function remove_gallery($content) {
global $post;
if($post->post_type == 'artcpt')
remove_shortcode('gallery', $content);
return $content;
}
add_filter( 'the_content', 'remove_gallery', 6);
Цикл
<?php preg_match('/\[gallery ids=[^\]]+\]/', get_the_content(), $matches); ?>
<div id="content">
<?php the_content(); ?>
</div>
<div id="gallery">
<?php echo do_shortcode($matches[0]); ?>
</div>
В цикле мой шорткод возвращается дважды (я на странице single, цикл должен выполняться дважды - поэтому do_shortcode() не срабатывает). Не уверен, почему так происходит.

Открыто для всех, кто сможет упростить это, но вот что у меня получилось и сработало.
Первое дело - получить галерею, используя get_post_gallery()
, сразу при начале цикла:
<?php if( have_posts() ) : ?>
<?php while( have_posts() ) :
the_post();
$gallery = get_post_gallery();
$content = strip_shortcode_gallery( get_the_content() );
?>
<div id="content">
<?php echo $content; ?>
</div> <!-- id="content" -->
<div id="gallery">
<?php echo $gallery; ?>
</div> <!-- id="gallery" -->
<?php endwhile; ?>
<?php endif; ?>
strip_shortcode_gallery()
Функция - functions.php
function strip_shortcode_gallery( $content ) {
preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER );
if ( ! empty( $matches ) ) {
foreach ( $matches as $shortcode ) {
if ( 'gallery' === $shortcode[2] ) {
$pos = strpos( $content, $shortcode[0] );
if( false !== $pos ) {
return substr_replace( $content, '', $pos, strlen( $shortcode[0] ) );
}
}
}
}
return $content;
}
Ресурсы:
Stackoverflow:
Исходный материал, который не сработал, как ожидалось:

Регулярные выражения для шорткодов в ядре WordPress
По сути, мы можем сделать это с помощью регулярного выражения - даже с тем, которое предоставляет ядро через функцию get_shortcode_regex()
.
Сначала нам нужно получить теги шорткодов и построить регулярное выражение. К сожалению, функция ядра get_shortcode_regex()
не позволяет передавать аргументы, поэтому мы получим регулярное выражение, которое соответствует всем шорткодам, что нежелательно, так как нам нужно обрабатывать только шорткод [gallery]
.
// Получаем все теги в виде массива
$tags = $GLOBALS['shortcode_tags'];
// Удаляем шорткод галереи; 'gallery' - это ключ
unset( $tags['gallery'] );
// Получаем все шорткоды (кроме 'gallery'), разделенные вертикальной чертой - символом "или" в регулярных выражениях
$tags = join( '|', array_map(
'preg_quote',
array_keys( $GLOBALS['shortcode_tags'] )
) );
Захват всех галерей
Далее нам нужно регулярное выражение, которое захватывает все галереи. Для этого мы вызываем preg_match_all()
, так как она возвращает все совпадения для шорткода галереи в виде массива с индексом 0
(остальное - частичные совпадения и может быть проигнорировано).
$pattern = get_shortcode_regex();
preg_match_all( "/$pattern/s", get_the_content(), $galleries );
Теперь массив $galleries[0]
содержит все шорткоды галерей.
Контент без галерей
Следующее, что нам нужно сделать - это удалить все шорткоды [gallery]
из контента. Мы снова используем то же регулярное выражение и применяем его к get_the_content()
. Конечно же, мы применяем фильтр the_content
, так как шорткоды могли быть добавлены через callback во время рендеринга.
$content = preg_replace_callback(
"/$pattern/s",
'strip_shortcode_tag',
apply_filters( 'the_content', get_the_content() )
);
Теперь переменная $content
содержит наш контент.
Пример callback для изменения контента
или: Как разделить контент на галереи и остальную часть записи
Мы можем легко заменить контент нашим новым контентом во время callback:
$tags = $GLOBALS['shortcode_tags'];
unset( $tags['gallery'] );
$tags = join( '|', array_map(
'preg_quote',
array_keys( $GLOBALS['shortcode_tags'] )
) );
$pattern = get_shortcode_regex();
preg_match_all( "/{$pattern}/s", get_the_content(), $galleries );
echo $galleries;
echo "<hr>";
echo preg_replace_callback(
"/{$pattern}/s",
'strip_shortcode_tag',
apply_filters( 'the_content', get_the_content() )
);
Это сначала добавит все галереи, затем наш контент без галерей, разделенные горизонтальной линией. Это всего лишь отправная точка.

используя другой подход, как в http://wordpress.stackexchange.com/questions/193511/formatting-post-content-to-exclude-gallery. когда я пробую ваш код, я получаю php ошибки - не могли бы вы взглянуть?

Какой именно код? Какие ошибки? Пожалуйста, уточните. Это разработка, а не игры в угадайку.

код и детали по ссылке > http://wordpress.stackexchange.com/questions/193511/formatting-post-content-to-exclude-gallery

Это не должно быть так сложно. Код ниже можно сократить до нескольких строк при желании.
Подход 1. Получение чистого контента записи путем удаления всех шорткодов, включая галерею, из содержимого записи.
Внимание: все остальные шорткоды также будут удалены из записи. Если вы не используете пользовательские шорткоды, этот подход для вас.
Предположим, вы находитесь в цикле WordPress:
$ctt = apply_filters('the_content', strip_shortcodes(get_the_content())); // Это ваш очищенный контент
$glry = get_post_gallery(); // А здесь находится галерея.
Если вы находитесь вне цикла:
$my_postid = 12;
$my_post = get_post($my_postid);
$ctt = apply_filters('the_content', strip_shortcodes($my_post->post_content));
$glry = get_post_gallery($my_postid);
Подход 2. Удаление только шорткода [gallery]
с сохранением остальных шорткодов.
Основан на внутренней реализации шорткода [gallery]
, которая может быть изменена командой WordPress, поэтому менее надежен, чем первый подход:
В цикле WordPress:
$ctt = preg_replace('/\[gallery.*\]/', '', get_the_content());
$ctt = apply_filters('the_content', $ctt); // Это ваш очищенный контент
$glry = get_post_gallery();
Вне цикла:
$my_postid = 12;
$my_post = get_post($my_postid);
$ctt = apply_filters('the_content', preg_replace('/\[gallery.*\]/', '', $my_post->post_content));
$glry = get_post_gallery($my_postid);
