Разделение контента и галереи

6 нояб. 2013 г., 22:52:55
Просмотры: 14.6K
Голосов: 23

Есть ли способ разделить контент записи и шорткод галереи? Я хочу отображать галерею вне основного контента, независимо от того, где и как она размещена. Я могу использовать этот код для получения самого шорткода:

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() не срабатывает). Не уверен, почему так происходит.

3
Комментарии

Вы не думали добавить отдельный WYSIWIG метабокс специально для галереи? Тогда вы могли бы вызывать его после the_content(). Хотя сложнее, если уже много страниц создано таким образом.

GhostToast GhostToast
6 нояб. 2013 г. 23:29:14

Согласен, это вариант, но я пытался избежать необходимости в еще одном большом редакторе — хотел сделать максимально просто и понятно. Хотелось бы (конечно, без плагина) просто иметь метабокс "добавить галерею" или что-то подобное.

Howdy_McGee Howdy_McGee
6 нояб. 2013 г. 23:41:23

Почему бы не использовать решение из Использование preg_replace для отделения галереи от the_content?

fuxia fuxia
6 апр. 2014 г. 20:12:56
Все ответы на вопрос 3
2
24

Открыто для всех, кто сможет упростить это, но вот что у меня получилось и сработало.

Первое дело - получить галерею, используя 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:

Исходный материал, который не сработал, как ожидалось:

7 нояб. 2013 г. 01:03:33
Комментарии

единственная проблема в том, что это также удаляет все стили контента, такие как <p> и <br>.

Al Rosado Al Rosado
5 янв. 2020 г. 22:53:58

@AlRosado Я не думал, что это произойдет, но если так, вы можете пропустить контент через echo apply_filters( 'the_content', $content );

Howdy_McGee Howdy_McGee
6 янв. 2020 г. 07:27:31
3

Регулярные выражения для шорткодов в ядре 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() )
);

Это сначала добавит все галереи, затем наш контент без галерей, разделенные горизонтальной линией. Это всего лишь отправная точка.

6 апр. 2014 г. 19:44:46
Комментарии

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

Adeerlike Adeerlike
4 июл. 2015 г. 19:02:35

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

kaiser kaiser
5 июл. 2015 г. 13:22:25

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

Adeerlike Adeerlike
6 июл. 2015 г. 16:28:48
0

Это не должно быть так сложно. Код ниже можно сократить до нескольких строк при желании.

Подход 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);
12 окт. 2017 г. 12:04:00