当您在简码中包含简码时,将 do_shortcode() 替换为直接函数

Replace do_shortcode() with direct function when you have shortcode within shortcode

我试图避免使用 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] 标签中时才能正常工作。

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

ANSWER/CODE 来自 ArtisticPhoenix:

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

不要重写do_shortcode

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

这里我假设你的 post 是这样的

 [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 会删除当前的简码标签并将它们替换为该简码函数的 return 值……否则这将是一个主要问题。但不清楚您的短代码是什么以及您尝试在短代码中包含的短代码是什么。

此外,如果您在 WP 文档中查找包含的短代码 HERE

没有提到删除当前短代码的结束标记。如您所说,请注意我的困惑:

[here is the] Function for the membership shortcode:

这让人相信 [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]

因为您不能在您的代码中允许这种情况,所以您必须考虑到它。为此,您必须自己解析短代码(以获取级别属性),这就是 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来节省几微秒(充其量,也许你自己解析后会更糟)。

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

终于

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

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

//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']"
);

如上所示,您仍然可以将内部简码作为简码传递给第一个method/function。这样它将被放置在任何 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中。这在这个例子中有效,但如果嵌套更深,你会遇到一些问题......

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

希望这是有道理的。

最后一件事(这让我有点烦)

这段代码:

  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。因为你 "properly" 使用 shortcode_atts 如果没有设置级别,它将默认为 NULL (所以我们不必担心 undefined/notset)。因此,这两段代码大致相同,只是一段更短。

可能看起来有点"weird"但是如果我们知道我们只需要处理基元(非数组,非对象)并且它保证被设置(这里就是这种情况)。比 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'],
                    ......
               )
          )
   )
);

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

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