【问题标题】:Replace do_shortcode() with direct function when you have shortcode within shortcode当您在短代码中有短代码时,将 do_shortcode() 替换为直接函数
【发布时间】:2019-02-16 19:23:04
【问题描述】:

我试图避免使用do_shortcode(),而是希望将其替换为函数本身。我遇到的问题是结束短代码标签。这是如何使用函数完成的?

重写这个:

echo do_shortcode( "
[membership level='12,41']
[get_biddata type='pending' sport='MLB Baseball']
[/membership]
    " );

有了这个:

echo pmpro_shortcode_membership( array( 'level' => '12,41', 'levels' => NULL, 'delay' => NULL ), $atts);
echo ajax_member_support( array( 'sport' => 'MLB Baseball', 'type' => 'pending' ), $atts );

这个函数中有什么参数(如果有的话):

echo pmpro_shortcode_membership(); 替换这个:[/membership] 结束短代码标签?

有 3 个插件:

1) 付费会员 - 短代码标签 = [membership] [/membership]

短代码回调函数名称:pmpro_shortcode_membership()

2) bidsys - 短代码标签 = [get_biddata]

短代码回调函数名:ajax_member_support()

3) 我自己的自定义插件为我的站点创建短代码,其中 do_shortcode 在文件中使用。

我在对调用进行硬编码以摆脱 do_shortcode() 时遇到的问题。它似乎只有在包裹在 [membership] [/membership] 标签中时才能正常工作。

什么对我的特殊情况有用:

来自 ArtisticPhoenix 的答案/代码:

echo pmpro_shortcode_membership(
   array( 'level' => '12,41', 'levels' => NULL, 'delay' => NULL ),
   ajax_member_support( array( 'sport' => 'MLB Baseball', 'type' => 'pending' ))
);

【问题讨论】:

  • 没有办法知道,因为该字符串仅在第一个示例中显示为 php 可以编辑的内容。它可以像str_replace('[/membership]', '', $string)preg_replace('/\[[-\w]+\]/', '', $sting) 一样简单,但不知道它在哪里,谁能告诉?
  • @ArtisticPhoenix 还需要什么信息?我试图改写我的问题中的内容,因为它可能被误解了。
  • 首先一个简码函数通常是function foo($attr, $content) 而不是function foo($array, $attr) 但是这个文本(在第一个块中)来自它分配给什么等等。如何从(大概)另一个字符串,如果我们不知道它分配给什么。如果您只是用第二个块替换第一个块,则不应有要替换的结束标记。
  • 如果您正在获取另一个简码的内容,并替换 do_shortcode 调用,您将不得不解析简码的内容,此时您最好使用内置函数...换句话说,您的问题没有“上下文”。您要么是从帖子中获取它,要么是手动创建的,但不清楚。
  • @ArtisticPhoenix 我发布了我在文件中回显的实际函数本身。目前我正在编辑的文件使用do_shortcode(),这是我试图避免的。一切正常,直到我到达这个结束标签。我不知道该回应什么

标签: php wordpress shortcode


【解决方案1】:

不要重写do_shortcode

这就是答案……简而言之。

这里我假设你的帖子是这样的

 [myshortcode]
     [membership level='12,41']
         [get_biddata type='pending' sport='MLB Baseball']
     [/membership]
 [/myshortcod]

这是唯一对我有意义的事情。因为如果你有

[membership level='12,41']
    [get_biddata type='pending' sport='MLB Baseball']
[/membership]

您的简码是membership,那么如果您在上面调用do_shortcode,您将获得无限递归(或者至少成员资格会运行2x)。我很确定 wordpress 会删除当前的短代码标签并将它们替换为该短代码函数的返回值......否则这将是一个主要问题。但目前尚不清楚您的简码是什么,以及您试图在简码中包含哪些简码。

另外,如果您在 WP 文档中查看随附的短代码 HERE

没有提到删除当前短代码的结束标记。正如你所说,我很困惑:

[这里是]会员简码的功能:

这导致人们相信[membership] 调用了该函数,然后您尝试在同一短代码[membership ...] 上执行do_shortcode。这对我来说不是很明智。

首发

短代码(通常)是这样编写的:

 function foo($atts, $content)  // array, string

没有

 function foo($myarray, $atts) //array, array

所以当你打电话时:

 echo pmpro_shortcode_membership(
           array( 'level' => '12,41', 'levels' => NULL, 'delay' => NULL ),
            $atts
 );

我认为是短代码导致的,参数是错误的......

现在,让我解释一下(上面的答案,不要重新制作do_shortcode)。

如果你硬编码这个而不是这个:

[membership level='12,41']
   [get_biddata type='pending' sport='MLB Baseball']
[/membership]

你得到(作为 $contents)

[membership level='13,41']  //note the 13,14 not 12,14
   [get_biddata type='pending' sport='MLB Baseball']
[/membership]

因为您不能在您的代码中授予这种情况,所以您必须考虑到它。为此,您必须自己解析短代码(以获取 level 属性),这就是 do_shortcode 所做的。

另外让我们假设这个短代码 membership 添加了一些 HTML

  <div>
        [get_biddata type='pending' sport='MLB Baseball']
  </div>

另一个get_biddata 做了类似的事情

   <a href="example.com" >Click</a>

因为第二个(上面)嵌套在你得到的另一个短代码中

  <div>
        <a href="example.com" >Click</a>
  </div>

如果你一个接一个地运行这些(如你所愿)

   <div>

   </div>
   <a href="example.com" >Click</a>

这个 HTML 可能比简单的&lt;div&gt; 复杂得多。所以结尾的短代码确实是最少的问题。

也许这不是你的情况,但不值得为了节省几微秒而重新发明do_shortcode(充其量,你自己解析后可能会更糟)。

更不用说这将是一个试图解析的雷区,因为需要递归等......

终于

如果您只想在对短代码的所有调用中包含此功能,那么您可以对这些方法的调用进行硬编码(并将它们完全排除在帖子之外)

如果您应该执行其他操作,您可以打开将哪些属性传递给您的简码,但这取决于您。

//do your code like this (in the post):
//    [myshortcode sport='foo' level='12,41']
//instead of like this
//   [myshortcode][membership level='12,41'] ... [/myshortcode]

echo pmpro_shortcode_membership(
     array( 'level' => '12,41', 'levels' => NULL, 'delay' => NULL ),
     "[get_biddata type='pending' sport='MLB Baseball']"
);

如上所示,您仍然可以将内部简码作为简码传递给第一个方法/函数。这样它将被放置在正确位置的任何 HTML 中。这确实允许您在构建该短代码时使用自己的属性。

例如:

//$atts['sport'] could come from your shortcode Attributes (as shown above).
echo pmpro_shortcode_membership(
     array( 'level' => $attr['level'], 'levels' => NULL, 'delay' => NULL ),
     "[get_biddata type='pending' sport='{$atts['sport']}']"
);

您也可以这样做(通过将内部结果作为内容传递给外部结果)并避免do_shortcode

echo pmpro_shortcode_membership(
   array( 'level' => $attr['level'], 'levels' => NULL, 'delay' => NULL ),
   ajax_member_support( array( 'sport' => 'MLB Baseball', 'type' => 'pending' ))
);

基本上ajax_member_support首先执行,然后它的内容放在外部短代码的$contents中。这在本示例中有效,但如果嵌套更深,您将遇到一些问题...

但是,如果您执行上述操作(在此“部分”中),则不应允许将其他短代码嵌套在您的短代码中。相反,您应该将他们的参数作为您自己的简码的一部分传递。如果您将这些属性作为简码的一部分(无论是什么),它将使生活变得更轻松并防止很多问题......

希望这是有道理的。

最后一件事(这有点困扰我)

这段代码:

  if(!empty($level) || $level === "0" || $level === 0)
  //if level is not empty, or it is string '0' or just 0

可以简化,因为我们知道只能从短代码属性传递字符串。所以代替那些东西:

  if(strlen($level))
     //empty (such as null) is 0, but string '0' and 0 are strlen 1.

为了说明这一点,我们不能像这样在短代码中传递数组

[membership level="[3,4]"]

因为它只是一个字符串[3,4]。您知道(因为您必须从字符串中解析级别),但可能没有意识到。所以现在我们同意只能通过短代码传递字符串,我们可以测试一下:

echo strlen(0)."\n";
echo strlen('0')."\n";
echo strlen(false)."\n";
echo strlen(null)."\n";

输出

1 //strlen(0)
1 //strlen('0')
0 //strlen(false)
0 //strlen(null)

Sandbox

很明显strlen('') 也是0。并且因为您“正确”使用了shortcode_atts,如果未设置级别,它将默认为NULL(因此我们不必担心未定义/未设置)。因此,这两段代码大致等价,只是其中一段较短。

这可能看起来有点“奇怪”,但如果我们知道我们只需要处理原语(非数组、非对象)并且保证被设置(这里就是这种情况)。比strlen 应该没问题。

干杯!

更新

对于超过 2 个短代码,您只需继续将函数嵌套到父代码的内容中:

echo pmpro_shortcode_membership(
   array( 'level' => $attr['level'], 'levels' => NULL, 'delay' => NULL ),
   ajax_member_support(
          array( 'sport' => 'MLB Baseball', 'type' => 'pending' ),
          some_other_shortcode(
              ['foo'=>'bar'],
              some_other_shortcode_1(
                   ['biz'=>'baa'],
                    ......
               )
          )
   )
);

以此类推,最内部的函数首先执行并可能返回某种字符串,然后将该字符串传递给父函数。因为父函数正在使用此内容通过$content = do_shortcode($content) 查找其他简码。当在父函数中调用它时,本来是执行的短代码的内容在你调用它之前就已经完成了。但是 do_shortcode 将返回文本,即使那里没有短代码(因为它已经完成了)。因此,如果没有事先完成,它应该是正确的。

基本上,您只是向它提供它本来可以从 do_shortcode 获得的内容,因此一切正常(在大多数情况下)。

【讨论】:

  • 很好的信息谢谢你,但是在我的情况下它似乎仍然不起作用......但是。我在我的问题中提供了更多信息,以帮助您在我继续尝试寻找解决方案时进一步了解正在发生的事情。
  • 抱歉,我不知道这些短代码有什么作用,我只是假设它们返回某种内容,例如 HTML,这是典型的短代码。然而,他们代替做事并非不可能。所以你可能需要做相应的调整。在任何情况下,即使您一个接一个地执行它们,我也会尽可能消除帖子(或其他)中的其他短代码,如我上面概述的那样,因为它使事情更容易处理。祝你好运。
  • 他们确实只是根据[membership] [/membership] 内的用户成员级别从ajax_member_support[get_biddata] 中输出HTML。它只是说明谁可以访问,谁不能访问什么内容。根据会员级别将确定查看的内容。我认为替换do_shortcode() 会很简单,但我一定在某处遗漏了一些东西。尽管如此,您的回答还是很有教育意义的。
  • 只要'level' =&gt; '12,41' 以这种方式编写,您提供的这段代码确实适用于我的情况--echo pmpro_shortcode_membership( array( 'level' =&gt; '12,41', 'levels' =&gt; NULL, 'delay' =&gt; NULL ), ajax_member_support( array( 'sport' =&gt; 'MLB Baseball', 'type' =&gt; 'pending' )) ); 如果我使用:'level' =&gt; $attr['level'],,无论出于何种原因,它都不起作用。
  • 如果您有多个内部简码,例如:[membership level='1,2,3'] [get_biddata type='current' sport='NFL Football'] [get_biddata type='past' sport='NFL Football'] [get_biddata type='detailed' sport='NFL Football'] [/membership] 您将如何使用您的函数对调用进行硬编码:echo pmpro_shortcode_membership( array( 'level' =&gt; '1,2,3, 'levels' =&gt; NULL, 'delay' =&gt; NULL ), ajax_member_support( array( 'sport' =&gt; 'NFL Football', 'type' =&gt; 'current' )) );
猜你喜欢
  • 2023-03-14
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多