拆分内容和库


22

有没有办法拆分帖子内容和画廊短代码。我想无论其放置方式或位置如何,都将画廊显示在正常内容之外。我可以使用它来获取简码本身:

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>

在The Loop中,它将返回我的短代码Twice(我在单个页面上,应该循环两次-因此其未运行do_shortcode())。不知道为什么。


1
您是否考虑过仅为图库添加一个单独的WYSYWIG元框?然后,您随时可以要求它the_content()。但是,如果已经有很多这样的页面,则比较棘手。
GhostToast

我同意这是有可能的,但是我试图避免需要另一位大编辑-试图使其尽可能简单和直接。我希望我可以(当然没有插件)只有一个添加库metabox或类似的东西。
Howdy_McGee

为什么不使用使用preg_replace中
fuxia

Answers:


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;
}

资源:

堆栈溢出:

我本来要去的东西,没有按预期工作:


4

核心简码正则表达式

基本上,我们可以使用Regex来做到这一点-实际上即使使用core由by提供的Regex get_shortcode_regex()

首先,我们需要获取shortcode标签并构建一个正则表达式。get_shortcode_regex()不幸的是,核心函数没有机会抛出参数,因此我们将得到一个正则表达式来匹配每个短码,这是不希望的,因为我们只想将[gallery]短码作为目标。

// 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索引的数组形式返回画廊短代码的所有Matches (其余部分将是部分匹配,可以忽略)。

$pattern = get_shortcode_regex();
preg_match_all( "/$pattern/s", get_the_content(), $galleries );

现在$galleries[0]拥有一个画廊短代码标签数组。

没有画廊的内容

接下来,我们需要做的是[gallery]从内容中删除所有短代码。我们将再次使用相同的Regex并在上运行它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() )
);

这将首先添加所有画廊,然后添加不包含画廊的我们的内容,两者均由水平规则分隔。这仅仅是一个起点。


使用与wordpress.stackexchange.com/questions/193511/…中不同的方法。当我尝试您的代码时,我得到php错误-您可以看看吗?
Adeerlike

哪个代码?有什么错误?请详细。这是发展,不是猜测游戏。
kaiser 2015年


2

它不应该太复杂。可以将以下代码缩短为几行。

方法1.通过从帖子内容中删除所有短代码(包括图库)来获得干净的帖子内容。

注意:所有其他简码将从帖子中删除。如果您不在此处放置自定义的简码,则该方法适合您。

假设您处于WP循环中

$ctt = apply_filters('the_content',strip_shortcodes(get_the_content())); // This is your cleaned content
$glry = get_post_gallery(); // and here is the 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]短代码外观的内部实现,可以由WP团队进行更改,因此可能不像第一种方法那样适用于未来。

在WP循环中

$ctt = preg_replace('/\[gallery.*\]/', '', get_the_content());
$ctt = apply_filters('the_content',$ctt); // This is your cleaned content
$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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.