在短代码中包含短代码时,将do_shortcode()替换为直接函数

问题描述 投票:0回答:1

我试图避免使用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)bidys - 短代码标签= [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 wordpress shortcode
1个回答
0
投票

不要重写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,你将获得无限递归(或者至少会员资格将运行2倍)。我非常确定wordpress删除了当前的短代码标签,并用该短代码功能的返回值替换它们......或者这将是一个主要问题。但目前还不清楚你的短代码是什么,以及你想在短代码中包含哪些短代码。

此外,如果您查看WP文档中的封闭短代码HERE

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

[这里是]会员短信的功能:

这导致人们相信[membership]称之为功能,然后你试图在相同的短码do_shortcode上做[membership ...]。这对我来说不是很明智。

首先

短代码(通常)写成:

 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]

你得到(作为$内容)

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

因为您无法在代码中承认此案例,所以您必须对其进行说明。要做到这一点,你必须自己解析短代码(获取级别属性),这是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可能比简单的<div>更复杂。所以结束短码实际上是最不重要的问题。

也许这不是你的情况,但是不值得重新发明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

可以简化,因为我们知道只能从shortcode属性传递字符串。而不是那些东西:

  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应该没问题。

干杯!

UPDATE

对于超过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得到的内容,所以一切正常(在大多数情况下)。

© www.soinside.com 2019 - 2024. All rights reserved.