问题描述

有没有办法分割帖子内容和图库的短代码。我想要将图库显示在我正常的内容之外,无论放置在何处或何处。我可以使用它来获取短代码本身:

if(has_shortcode(get_the_content(), 'gallery')){
    $pattern = get_shortcode_regex();
    preg_match("/$pattern/s", get_the_content(), $matches);
    echo do_shortcode($matches[0]);
}

但是如果画廊的短码不是第一个实例,这不行。有没有办法完全拆分我的内容和图库?


编辑:我有一个 semi-solution,但它似乎是一个漫长的方式去做。它首先抓住了帖子中的第一个短代码 (需要修复,因为我只想要”Gallery” 短代码),然后从内容中删除所有的快捷码 (再次,不是我真正想做的)

<?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('/]+]/', get_the_content(), $matches); ?>
<div id="content">
    <?php the_content(); ?>
</div>
<div id="gallery">
    <?php echo do_shortcode($matches[0]); ?>
</div>

在循环中,它将返回我的短代码两次 (我在一个页面上,应该循环两次 – 所以它不运行 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() );
            $content = str_replace( ']]>', ']]&gt;', apply_filters( 'the_content', $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;
}

资源:

堆栈溢出:

我原本打算什么,没有按预期工作:

次佳解决方案

核心短码正则表达式

基本上我们可以用正则表达式来实现,实际上即使是由 get_shortcode_regex()由核心提供的正则表达式。

首先,我们需要抓取短代码标签并构建一个正则表达式。核心功能 get_shortcode_regex()不幸的是没有机会抛出一个参数,所以我们会留下一个正则表达式,匹配每个短代码,这是不需要的,因为我们只想要定位短代码。

// Get all tags as Array
$tags = $GLOBALS['shortcode_tags'];
// remove the gallery-shortcode; 'gallery' is the key
unset( $tags['gallery'] );
// retrieve all shortcodes (but not 'gallery') separated by a vertical pipe char/the "or" Regex char
$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]拥有一系列图库短码标签。

内容没有画廊

接下来,我们需要做的是从内容中删除所有短码。我们将再次使用相同的正则表达式,并在 get_the_content()上运行它。当然,我们应用 the_content 过滤器,因为在渲染时可以通过回调添加短代码。

$content = preg_replace_callback(
    "/$pattern/s",
    'strip_shortcode_tag',
    apply_filters( 'the_content', get_the_content() )
);

$content 变量现在保存我们的内容。

示例回调来更改内容

或者:您如何将内容分割成画廊和其他帖子

在回调期间,我们可以轻松地将内容替换为我们的新内容:

$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() )
);

这将首先添加所有画廊,然后添加我们的内容没有画廊,两者都用水平规则分隔。这只是一个起点。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。