详细解析WordPress短代码API以及如何创建短代码

短代码API或简码API

简码API 是一个用于创建在WordPress文章和网页使用的一组简单功能的代码 。例如,以下简短代码(在文章或页面的正文中)将添加附加到该文章或页面的图像的相册: [ gallery ]

API使插件开发人员可以创建特殊种类的内容(例如,表单,内容生成器),用户可以通过将相应的短代码添加到页面文本中来附加到某些页面。

使用简码API,可以轻松创建支持以下属性的短代码:

[ gallery id="123" size="medium" ]

该API处理所有棘手的解析,无需为每个短代码编写自定义正则表达式。包括了辅助功能,用于设置和获取默认属性。该API支持自封闭式和闭包式的短代码。

下面是创建简码所需的PHP代码的简单示例:

// [foobar]
function wporg_foobar_func( $atts ) {
    return "foo and bar";
}
add_shortcode( 'foobar', 'wporg_foobar_func' );

这将创建[foobar]返回为:foo和bar的简码

带属性的短代码:

// [bartag foo="foo-value"]
function bartag_func( $atts ) {
    $a = shortcode_atts( array(
        'foo' => 'something',
        'bar' => 'something else',
    ), $atts );
 
    return "foo = {$a['foo']}";
}
add_shortcode( 'bartag', 'bartag_func' );

这将创建一个[bartag]支持两个属性的简码:“ foo”和“ bar”。这两个属性都是可选的,[foo="something" bar="something else"]如果未提供,则将采用默认选项。简码将返回为foo = {the value of the foo attribute}

历史

Shortcode API是在WordPress 2.5中引入的。

概述

短代码是通过提供处理函数来编写的。简码处理程序与WordPress过滤器大致相似:它们接受参数(属性)并返回结果(简码输出)。

简码名称应全部小写并使用所有字母,但数字和下划线也应能正常工作。注意不要使用连字符(破折号),最好不要使用连字符。

该  add_shortcode 函数用于注册简码处理程序。它有两个参数:简码名称(在文章正文中使用的字符串)和回调函数名称。

三个参数传递给shortcode回调函数。您可以选择使用任意数量的它们,包括没有一个。

  • $atts:属性的关联数组;如果未提供属性,则为空字符串
  • $content:包含的内容(如果简短代码以其包含形式使用)
  • $tag:shortcode标记,对于共享的回调函数很有用

注册短代码处理程序的API调用如下所示:

add_shortcode( 'wporgshortcode', 'wporg_shortcode_handler' );

当调用the_content()时,简码API将解析任何已注册的简码(例如)[myshortcode],分离并解析属性和内容(如果有),并将相应的简码处理函数传递给它们。 短代码处理程序返回的任何字符串  (未回显)都将插入到文章正文中,以代替短代码本身。

输入的简码属性如下:

[wporgshortcode foo="bar" bar="bing"]

这些属性将转换为如下所示的关联数组,并作为其$atts 参数传递给处理函数  :

array( 'foo' => 'bar', 'bar' => 'bing' )

数组键是属性名称。数组值是相应的属性值。此外,第0个属性项($atts[0])将保存与短代码正则表达式匹配的字符串,但仅在与回调名称不同的情况下保存。

处理属性

原始  $atts 数组可以包括用户指定的任何任意属性。(此外,数组的第零个条目可能包含正则表达式可识别的字符串;请参见下面的注释。)

为了帮助设置缺少属性的默认值,并消除您的短代码无法识别的任何属性,API提供了shortcode_atts()函数。

shortcode_atts() 类似于  wp_parse_args 功能,但有一些重要区别。其参数为:

shortcode_atts( $defaults_array, $atts );

这两个参数都是必需的。 $defaults_array 是一个关联数组,用于指定识别的属性名称及其默认值。 $atts 是传递到您的shortcode处理程序中的原始属性数组。 shortcode_atts() 将返回一个规范化的数组,其中包含来自的所有键  $defaults_array,并以该$atts 数组中的值(如果存在)填充  。例如:

$a = shortcode_atts( array(
    'title' => 'My Title',
    'foo' => 123,
), $atts );

如果  $atts 要包含  array( 'foo' => 456, 'bar' => 'something' ),则结果  $a 为  array( 'title' => 'My Title', 'foo' => 456 )。值  $atts['foo'] 覆盖的123默认  $atts['title'] 是没有设置的,所以默认的“我的标题”被使用。默认数组中没有“ bar”项,因此它不包含在结果中。

在将属性名称传递到处理程序函数之前,它们总是转换为小写形式。值保持不变。[myshortcode FOO="BAR"] 产生  $atts = array( 'foo' => 'BAR' )

建议在短代码处理程序中声明默认值和解析属性的代码惯用法如下:

function wporg_shortcode_handler( $atts, $content = null ) {
    $a = shortcode_atts( array(
        'attr_1' => 'attribute 1 default',
        'attr_2' => 'attribute 2 default',
        // ...etc
    ), $atts );
}

这将解析属性,设置默认值,消除任何不支持的属性,并将结果存储在以$a 属性为键–  $a['attr_1'],  $a['attr_2']等等的本地数组变量中  。换句话说,默认数组近似于局部变量声明的列表。

重要提示-请勿将驼峰命名法或含大写字母的名字用作您的  $atts 属性名称

$atts 值在处理期间是小写的shortcode_atts( array( 'attr_1' => 'attr_1 default', // ...etc ), $atts ),因此您可能  只能使用小写

关于易混淆的正则表达式/回调名称引用的说明:

属性数组($atts[0])的第零个条目将包含与短代码正则表达式匹配的字符串,但只有与回调名称不同的字符串,否则将作为回调函数的第三个参数出现。

add_shortcode('foo','foo'); // two shortcodes referencing the same callback
 add_shortcode('bar','foo');
    produces this behavior:
 [foo a='b'] ==> callback to: foo(array('a'=>'b'),NULL,"foo");
 [bar a='c'] ==> callback to: foo(array(0 => 'bar', 'a'=>'c'),NULL,"");

这令人困惑,也许反映出潜在的错误,但是重载的回调例程可以通过检查回调的第三个参数和0号属性,来正确确定使用了什么短代码来调用它。(让两个短代码引用同一个回调例程是没有错误的,这允许使用通用代码。)

输出

简码处理程序函数的返回值将插入到文章内容输出中,以代替简码宏。 记住要使用return而不是echo-被回显的任何内容都将输出到浏览器,但不会出现在页面上的位置

在应用wpautop  和wptexturize  文章格式后,  将解析简码  。这意味着您的简码输出HTML不会自动应用卷曲引号,不会添加p和br标签,等等。如果确实要格式化您的简码输出,则应在从简码处理程序返回输出时调用wpautop()wptexturize()直接调用。

wpautop可以识别短代码语法,并且将尝试不将p或br标签包裹在单独一行的短代码周围。打算以这种方式使用的短代码应确保将输出包装在适当的块标记中,例如<p><div>

如果简码产生大量HTML,则ob_start可以用来捕获输出并将其转换为字符串,如下所示:

function wporg_shortcode() {
    ob_start();
    ?> <HTML> <here> ... <?php
    return ob_get_clean();
}

闭合式vs自闭合式短代码

上面的示例显示了自闭合的短代码宏,例如[myshortcode]。该API还支持封装短代码,例如[myshortcode]content[/myshortcode]

如果使用shortcode宏来封闭内容,则其处理函数将接收包含该内容的第二个参数。用户可能以任何一种形式编写简码,因此有必要通过为处理函数提供第二个参数的默认值来允许两种情况:

function wporg_shortcode_handler( $atts, $content = null )

empty( $content ) 可用于区分自动闭合和闭合情况。

当包含内容时,包括其内容在内的完整短码宏将被函数输出替换。处理程序函数负责提供原始内容字符串的任何必要的转义或编码,并将其包括在输出中。

这是一个简短的简短代码示例:

function wporg_caption_shortcode( $atts, $content = null ) {
    return '<span class="caption">' . $content . '</span>';
}
add_shortcode( 'caption', 'wporg_caption_shortcode' );

当这样使用时:

My Caption

输出为:

<span class="caption">My Caption</span>

由于$content包含在返回值中,没有任何转义或编码,因此用户可以包含原始HTML:

<a href="http://example.com/">My Caption</a>

会产生:

<span class="caption"><a href="http://example.com/">My Caption</a></span>

这可能是预期的行为,也可能不是预期的行为–如果简码不应在其输出中允许使用原始HTML,则应在返回结果之前使用转义或过滤功能对其进行处理。

简码解析器对文章内容使用一次传递。这意味着,如果$content一个简码处理程序的参数包含另一个简码,则不会对其进行解析:

Caption: [myshortcode]

这将产生:

<span class="caption">Caption: [myshortcode]</span>

如果封闭的短代码旨在允许其输出中包含其他短代码,则处理函数可以 递归调用  do_shortcode()

function wporg_caption_shortcode( $atts, $content = null ) {
    return '<span class="caption">' . do_shortcode($content) . '</span>';
}

在前面的示例中,这将确保[myshortcode]解析包含内容的宏,并在标题范围内包含其输出:

<span class="caption">Caption: The result of myshortcode's handler function</span>

解析器不会像您希望的那样处理相同短代码的封闭形式和非封闭形式的混合。例如,如果您有:

[myshortcode example='non-enclosing' /] non-enclosed content [myshortcode] enclosed content [/myshortcode]

解析器不是将其视为由文本“非封闭内容”分隔的两个短代码,而是将其视为包含“非封闭内容[myshortcode]封闭的内容” 的单个短代码。

封闭式简码支持属性的方式与自动封闭式简码相同。这是经过caption_shortcode()改进以支持“ class”属性的示例:

function wporg_caption_shortcode( $atts, $content = null ) {
    $a = shortcode_atts( array(
        'class' => 'caption',
    ), $atts );
 
    return '<span class="' . esc_attr($a['class']) . '">' . $content . '</span>';
}

其它功能简述

  • 解析器支持xhtml样式的关闭短代码,例如[myshortcode /],但这是可选的。
  • 简码宏可以为属性值使用单引号或双引号,或者如果属性值不包含空格,则可以完全省略它们。[myshortcode foo='123' bar=456]等同于[myshortcode foo="123" bar="456"]。请注意,最后一个位置的属性值可能不会以正斜杠结尾,因为上面段落中的功能将使用该斜杠。
  • 为了与较早的临时简短代码向后兼容,可以省略属性名称。如果属性没有名称,则会在$atts数组中为其指定位置数字键。例如,[myshortcode 123]将产生$atts = array( 0 => 123 )。位置属性可以与命名属性混合使用,如果值包含空格或其他有效字符,则可以使用引号。
  • 简码API具有测试用例。可以在http://svn.automattic.com/wordpress-tests/trunk/tests/shortcode.php中找到这些测试-包含许多错误案例和异常语法的示例。

函数引用/函数调用

可以使用以下Shortcode API函数:

function add_shortcode( $tag, $func )

注册一个新的shortcode处理函数。$tag是用户编写的短代码字符串(不带花括号),例如“ myshortcode”。$ func是处理程序函数名称。

对于给定的短码,只能存在一个处理函数。add_shortcode()再次使用相同的$ tag名称调用将覆盖以前的处理程序。

function remove_shortcode( $tag )

注销现有的简码。$tag是在中使用的简称add_shortcode()

function remove_all_shortcodes()

注销所有短代码。

function shortcode_atts( $pairs, $atts )

$atts根据中指定的一组默认值处理原始属性数组$pairs。返回一个数组。结果将包含from中的每个键$pairs,并与from中的值合并$atts$atts$ pair中不存在的任何键都将被忽略。

function do_shortcode( $content )

解析$content字符串中所有已知的shortcode宏。返回一个包含原始内容的字符串,其中短代码宏被其处理函数输出替换。

do_shortcode()  被注册为“ the_content”上的默认过滤器,优先级为11。

使用限制

嵌套短代码

短代码解析器可以正确处理嵌套的短代码宏,前提是它们的处理函数通过递归调用do_shortcode()来支持它  :

[tag-a]
   [tag-b]
      [tag-c]
   [/tag-b]
[/tag-a]

但是,如果使用短码宏将另一个同名宏封装起来,则解析器将失败:

[tag-a]
   [tag-a]
   [/tag-a]
[/tag-a]

这是使用上下文无关的正则表达式解析器的局限性  do_shortcode() -它非常快,但不计算嵌套级别,因此在这种情况下,它无法将每个开始标记与其正确的结束标记匹配。

在未来的WordPress版本中,可能有必要使用具有嵌套短代码语法的插件来确保wptexturize()处理器不会干扰内部代码。对于这种复杂的语法,建议   在外部标签上使用no_texturize_shortcodes过滤器。在此处使用的示例中,应将tag-a添加到短代码列表中,以免纹理化。如果标记-a或标记-b的内容仍需要进行纹理处理,则可以 如上所述wptexturize() 进行呼叫  ,然后再呼叫  do_shortcode()

未注册的名称

一些插件作者选择了不注册简码名称的策略,例如在调用父简码的处理函数之前禁用嵌套的简码。这可能会产生意想不到的后果,例如无法解析短码属性值。例如:

[tag-a unit="north"]
   [tag-b size="24"]
      [tag-c color="red"]
   [/tag-b]
[/tag-a]

从版本4.0.1开始,如果插件未能将tag-b和tag-c注册为有效的短代码,则wptexturize()处理器将在解析任何短代码之前输出以下文本:

[tag-a unit="north"]
   [tag-b size=”24”]
      [tag-c color=”red”]
   [/tag-b]
[/tag-a]

未注册的简码应被视为没有特殊含义的普通纯文本,不建议使用未注册的简码。如果必须将原始代码括在短代码标签之间,请至少考虑使用  no_texturize_shortcodes过滤器以防止对标签a的内容进行纹理化:

add_shortcode( 'tag-a', 'wporg_tag_a_handler' );
add_filter( 'no_texturize_shortcodes', 'wporg_ignore_tag_a' );
 
function wporg_ignore_tag_a( $list ) {
  $list[] = 'tag-a';
  return $list;
}

未闭合的短代码

在某些情况下,简码解析器无法正确处理闭合和未闭合的简码的使用。例如,在这种情况下,解析器将仅正确识别短码的第二个实例:

[tag]
[tag]
   CONTENT
[/tag]

但是,在这种情况下,解析器将识别这两个:

[tag]
   CONTENT
[/tag]
[tag]

连字符

在您的简码名称中使用连字符时请多加注意。在以下情况下,WordPress可能会看到第二个开始的简码等同于第一个(简而言之,WordPress看到了连字符前面的第一部分):

[tag]
[tag-a]

这完全取决于首先定义哪个短代码。如果要使用连字符,请先定义最短的短代码。

为避免这种情况,请使用下划线或不使用分隔符:

[tag]
[tag_a]
 
[tag]
[taga]

如果短代码的第一部分彼此不同,则可以避免使用连字符:

[tag]
[tagfoo-a]

重要提示:  使用连字符可能会引起您可能不了解的含义;例如,如果其他已安装的短代码也使用连字符,则带连字符的通用单词可能会导致冲突(如果在同一请求中一起使用了短代码):

// plugin-A
[is-logged-in]
 
// plugin-B
[is-admin]

方括号

简码解析器不接受属性中的方括号。因此,以下操作将失败:

[tag attribute="[Some value]"]

wptexturize()或其过滤器尚未完全支持用修饰括号包围的标签。这些代码可能会产生意外的结果:

[I put random text near my captions. ]

注意:  这些限制可能会在未来的WordPress版本中发生变化,您应该进行测试以确保绝对正确。

HTML

从3.9.3版开始,HTML的使用仅限于简码属性内。例如,此短代码将无法正常工作,因为它包含一个>字符:

[tag value1="35" value2="25" compare=">"]

4.0版旨在允许经过验证的HTML,因此可以使用:

[tag description="<b>Greetings</b>"]

对于HTML限制,建议的解决方法是对所有用户输入使用HTML编码,然后在自定义简码处理程序中添加HTML解码。计划额外的API功能。

从未正式支持在shortcode属性中完全使用HTML,并且在以后的版本中不会对此进行扩展。

从4.2.3版开始,在HTML中使用短码也有类似的限制。例如,此短代码无法嵌套,因为它嵌套在脚本属性中:

<a onclick="[tag]">

对于动态属性,建议的解决方法是设计一个短代码,该短代码输出所有需要的HTML,而不只是一个值。这将更好地工作:

[link onclick="tag"]

还要注意,由于属性引用不正确,不再允许使用以下短代码:

<a title="[tag attr="id"]">

将其解析为有效HTML的唯一方法是以嵌套方式使用单引号和双引号:

<a title="[tag attr='id']">

注册数量

已知在注册数百个短代码时,API会变得不稳定。插件作者应创建仅依赖少数短代码名称的解决方案。在将来的版本中,此限制可能会更改。

正式语法

WordPress短代码不会以与HTML相同的方式使用特殊字符。乍看之下,方括号似乎很神奇,但它们并不是任何语言的真正组成部分。例如:

[ gallery ]

API将画廊短代码解析为特殊符号,因为它是注册的短代码。另一方面,如果未注册简码,则忽略方括号:

[randomthing]

随机符号及其方括号将被忽略,因为它们不是任何已注册的简码的一部分。

在理想的情况下,[*]API可以处理任何符号,但是我们必须考虑以下挑战:HTML中允许使用方括号,并且不一定总是使用短代码,仅在有限的情况下,才允许在短代码中使用尖括号,并且所有此代码必须在输出之前通过多层可定制的过滤器和解析器运行。由于存在这些语言兼容性问题,方括号不可能是神奇的。

简码语法使用以下常规部分:

[name attributes close]
[name attributes]Any HTML or shortcode may go here.[/name]

转义的短代码是相同的,但恰好有两个大括号:

[[name attributes close]]
[[name attributes]Any HTML or shortcode may go here.[/name]]

同样,必须注册简码名称,否则将忽略所有四个示例。

名称

简码名称不得包含以下字符:

  • 方括号: [ ]
  • 角括号: < >
  • &符: &
  • 正斜杠: /
  • 空格:空格换行标签
  • 非印刷字符:\x00\x20

建议也避免在短代码名称中使用引号。

属性

属性是可选的。简码名称和简码属性之间必须有一个空格。如果使用多个属性,则每个属性必须至少间隔一个空格。

每个属性应符合以下格式之一:

1
attribute_name = 'value'
1
attribute_name = "value"
1
attribute_name = value
1
"value"
1
value

属性名称是可选的,并且应仅包含以下字符,以在所有平台上兼容:

  • 大写和小写字母: A-Z a-z
  • 位数: 0-9
  • 下划线: _
  • 连字号: -

属性名称中不允许使用空格。名称和=符号之间可以使用可选的空格。在=符号和值之间也可以使用可选的空格。

应该注意的是,即使属性可以在编辑器中混合大小写使用,但在解析后它们始终是小写的。

属性值不得包含以下字符:

  • 方括号: [ ]
  • 行情:"'

不带引号的值也不能包含空格。

HTML字符,<并且>对属性的支持有限。

在shortcode属性中转义特殊字符的推荐方法是HTML编码。最重要的是,任何出现在shortcode属性中的用户输入都必须转义或去除特殊字符。

注意,在单引号中允许双引号,反之亦然,但是在处理用户输入时不建议这样做。

如果以下字符未在属性值中转义,则将自动去除这些字符并将其转换为空格:

  • 不间断空间: \xC2\xA0
  • 零宽度空间: \xE2\x80\x8B

自闭包

自闭包标记(一个正斜杠)是可选的。标记前的空格是可选的。标记后不能有空格。

[example /]

自闭包标记纯粹是装饰性的,没有任何作用,只不过它会迫使简码解析器忽略其后的所有关闭标记。

闭包类型的短代码不能使用自闭包标记。

转义

WordPress尝试在[name][/name]标记之间插入大括号。它将像处理其他内容一样处理该内容。从4.0.1版本开始,未注册的短代码也会被“纹理化”,这可能会产生意外的曲解:

1
[randomthing param="test"]

一个更好的例子是:

1
<code>[randomthing param="test"]</code>

<code>元素用于避免曲解。

已注册的简码仍在<code>元素内部处理。为了避免注册的简码显示在您的网站上,语法变为:

1
[caption param="test"]

将输出:

1
[ caption param="test" ]

在这种情况下,<code>元素是可选的。

要封装简短代码,请使用以下语法:

1
[My Caption]

 

外部资源

默认短代码

[ audio ]
[ wp_caption ]
[ caption ]
[ embed ]
[ gallery ]
[ video ]
[ playlist ]

简码API函数列表

发表评论