Wordpress 短代码传递值数组
Wordpress shortcodes pass array of values
我正在创建一些 WordPress 短代码,旨在在页面上提供内部导航(一个页面有很多内容部分和它自己的菜单)。
这是我的:
//menu
function internal_menu($atts) {
extract(shortcode_atts(array(
'href1' => '#jl1',
'href2' => '#jl2',
'href3' => '#jl3',
'href4' => '#jl4',
), $atts));
return '<div id="internalPageMenu">
<ul>
<li><a href="' . $href1 . '"><i class="fa fa-bars"></i>link 1</a></li>
<li><a href="' . $href2 . '">link 2</a></li>
<li><a href="' . $href3 . '">link 3</a></li>
<li><a href="' . $href4 . '">link 4</a></li>
</ul>
</div>';
}
add_shortcode('internal-menu', 'internal_menu');
//menu target
function internal_menu_target($atts) {
extract(shortcode_atts(array(
'id' => 'jl1',
'text' => '',
), $atts));
return '<h3 id="' . $id . '">' . $text . '</h3>';
}
add_shortcode('internal-menu-target', 'internal_menu_target');
并在我的 Wordpress 管理面板中使用它:
[internal-menu]
[internal-menu-target id="jl1"]
Some content
[internal-menu-target id="jl2"]
...etc...
如何使菜单动态化(不限制它可以包含的项目数)?例如,短代码为:
[internal-menu targets="jl1, jl2, jl3, jl4, jl5, ...etc..."]
foreach
将是您的答案。在我看来,这将是最简单和最干净的。在我给你一个代码示例之前,让我们分析你的代码并看看你的所有缺陷以及我们将如何纠正它们
缺陷
永远不要使用 extract()
。 exctract()
即时创建变量,这是有问题的。您无法正确调试 extract()
( 如果您甚至可以 ),所以当它失败时,您的工作确实会不必要地被切断。由于这些原因,它已从核心和法典中完全删除。参见 trac ticket 22400。你应该有一个邪恶的列表,前两个位置是 query_posts
和 extract()
,我知道这两个有多糟糕。
您没有清理和验证输入数据,这可能导致黑客将 jquery 注入您的代码以入侵您的网站。 从不相信来自用户端和URL的任何数据,它可能被感染。
如您所知,从您的代码中可以看出,短代码不能除数组值外,值必须是字符串。在您的情况下,我们需要从字符串值创建一个数组。同样,因为您不能相信用户不在逗号前后使用空格,所以明智的做法是删除所有空格(如果有),以便 explode
函数正确创建数组
使用这种新方法,您需要确保字符串中的值顺序正确并且字符串的长度正确。如果没有,你会得到意想不到的输出
让我们解决第一个短代码:(请注意:下面的所有代码都未经测试。它可能有错误或语法错误 )
internal-menu
//menu
function internal_menu( $atts )
{
$attributes = shortcode_atts(
array(
'href' => '',
),
$atts
);
$output = '',
// Check if href has a value before we continue to eliminate bugs
if ( !$attribute['href'] )
return $output;
// Create our array of values
// First, sanitize the data and remove white spaces
$no_whitespaces = preg_replace( '/\s*,\s*/', ',', filter_var( $attributes['href'], FILTER_SANITIZE_STRING ) );
$href_array = explode( ',', $no_whitespaces );
$output .= '<div id="internalPageMenu">';
$output .= '<ul>';
foreach ( $href_array as $k => $v ) {
// From your code, link 1 is different, so I kept it as is
if ( $k == 0 ) {
$output .= '<li><a href="#' . $v . '"><i class="fa fa-bars"></i>link 1</a></li>';
} else {
$output .= '<li><a href="#' . $v . '">link ' . ($k + 1 ) . '</a></li>';
}
}
$output .= '</ul>';
$output .= '</div>';
return $output;
}
add_shortcode( 'internal-menu', 'internal_menu' );
然后您可以使用如下简码
[internal-menu href='jl1, jl2, jl3, jl4']
internal-menu-target
//menu target
function internal_menu_target($atts)
{
$attributes = shortcode_atts(
array(
'id' => '',
'text' => '',
),
$atts
);
$output = '',
// Check if href has a value before we continue to eliminate bugs
if ( !$attribute['id'] || !$attribute['text'] )
return $output;
// Create our array of values
// First, sanitize the data and remove white spaces
$no_whitespaces_ids = preg_replace( '/\s*,\s*/', ',', filter_var( $attributes['id'], FILTER_SANITIZE_STRING ) );
$ids_array = explode( ',', $no_whitespaces_ids );
$no_whitespaces_text = preg_replace( '/\s*,\s*/', ',', filter_var( $attributes['text'], FILTER_SANITIZE_STRING ) );
$text_array = explode( ',', $no_whitespaces_text );
// We need to make sure that our two arrays are exactly the same lenght before we continue
if ( count( $ids_array ) != count( $text_array ) )
return $output;
// We now need to combine the two arrays, ids will be keys and text will be value in our new arrays
$combined_array = array_combine( $ids_array, $text_array );
foreach ( $combined_array as $k => $v )
$output .= '<h3 id="' . $k . '">' . $v . '</h3>';
return $output;
}
add_shortcode('internal-menu-target', 'internal_menu_target');
您可以按如下方式使用此简码:
[internal-menu-target id='1,2,3,4' text='text 1, text 2, text 3, text 4']
问题:
Wordpress 短代码在可以传递的数据格式方面有一些痛苦的限制...
space-定界变量:
[shortcode a="1 2"]
结果:$atts=['a'='"1', 0='2"']
']' 关闭简码:
[shortcode b=[yay]]
结果:$atts=['b'='[yay']
解决方案:
您可以使用 urlencode()
:
来解决这个问题
[shortcode atts=a=1+2&b=%5Byay%5D]
像这样解析它:
parse_string($atts['atts'],$atts);
结果:$atts=['a'=>'1 2', b=>'[yay]']
这会给你传递你想要的数组。
现在关于构建菜单:
function internal_menu($atts) {
// allow passing + and ] in the text of the links:
parse_string($atts["links"],$links);
// the defaults, verbatim from the question:
if (!count($links)) $links=[
'href1' => '#jl1',
'href2' => '#jl2',
'href3' => '#jl3',
'href4' => '#jl4',
];
foreach ($links as $text=>$href) $ul=."<li><a href=\"$href\">$text</a></li>";
return '<div id="internalPageMenu"><ul>'.$ul.'</ul></div>';
}
add_shortcode('internal-menu', 'internal_menu');
//menu target
function internal_menu_target($atts) {
// allow passing + and ] in the text:
if (@$atts[text]) $atts['text']) = urldecode($atts['text']);
// the defaults, verbatim from the question:
$atts=array($atts)+['text'=>'','id'=>'jl1'];
return '<h3 id="' . $link['id'] . '">' . $link['text'] . '</h3>';
}
add_shortcode('internal-menu-target', 'internal_menu_target');
然后像这样喂它:
[internal-menu links=First+Link=#jl1&Second+Link=#jl2&Google=https://google.com]
[internal-menu-target text=Section+1 id=jl1]
等等
顺便说一句,如果您负责任地使用它,extract()
完全没问题:
/* concatenates 3 words of wisdom into a polite policy direction
*
* @param $attr: hash of function args
* foo = the first word (Kindly)
* bar = the second word (ignore)
* baz = the third word (totalitarians)
*/
function excellent_policy($attr){
$defaults=['foo'=>'Kindly', 'bar'=>'ignore', 'baz'=>'totalitarians'];
extract((array)array_intersect_key($attr,$defaults)+$defaults);
echo "$foo $bar $baz!";
}
这会以可读和可预测的方式将 $foo、$bar 和 $baz 从 $attr 导入本地作用域,为那些未传递的变量提供默认值,并防止创建任何意外变量。
使用语言功能有好有坏。 禁止所有人使用某种语言功能,因为有人可能会用得不好,这就像禁止所有人呼吸,因为有人可能会尝试吸入果冻。
我使用的简单方法:
[my param="key1=value1&key2=value2"]
在短代码回调中,只需执行:
parse_str( str_replace("&", "&", $attrs['param']), $array);
// var_dump( $array );
我正在创建一些 WordPress 短代码,旨在在页面上提供内部导航(一个页面有很多内容部分和它自己的菜单)。
这是我的:
//menu
function internal_menu($atts) {
extract(shortcode_atts(array(
'href1' => '#jl1',
'href2' => '#jl2',
'href3' => '#jl3',
'href4' => '#jl4',
), $atts));
return '<div id="internalPageMenu">
<ul>
<li><a href="' . $href1 . '"><i class="fa fa-bars"></i>link 1</a></li>
<li><a href="' . $href2 . '">link 2</a></li>
<li><a href="' . $href3 . '">link 3</a></li>
<li><a href="' . $href4 . '">link 4</a></li>
</ul>
</div>';
}
add_shortcode('internal-menu', 'internal_menu');
//menu target
function internal_menu_target($atts) {
extract(shortcode_atts(array(
'id' => 'jl1',
'text' => '',
), $atts));
return '<h3 id="' . $id . '">' . $text . '</h3>';
}
add_shortcode('internal-menu-target', 'internal_menu_target');
并在我的 Wordpress 管理面板中使用它:
[internal-menu]
[internal-menu-target id="jl1"]
Some content
[internal-menu-target id="jl2"]
...etc...
如何使菜单动态化(不限制它可以包含的项目数)?例如,短代码为:
[internal-menu targets="jl1, jl2, jl3, jl4, jl5, ...etc..."]
foreach
将是您的答案。在我看来,这将是最简单和最干净的。在我给你一个代码示例之前,让我们分析你的代码并看看你的所有缺陷以及我们将如何纠正它们
缺陷
永远不要使用
extract()
。exctract()
即时创建变量,这是有问题的。您无法正确调试extract()
( 如果您甚至可以 ),所以当它失败时,您的工作确实会不必要地被切断。由于这些原因,它已从核心和法典中完全删除。参见 trac ticket 22400。你应该有一个邪恶的列表,前两个位置是query_posts
和extract()
,我知道这两个有多糟糕。您没有清理和验证输入数据,这可能导致黑客将 jquery 注入您的代码以入侵您的网站。 从不相信来自用户端和URL的任何数据,它可能被感染。
如您所知,从您的代码中可以看出,短代码不能除数组值外,值必须是字符串。在您的情况下,我们需要从字符串值创建一个数组。同样,因为您不能相信用户不在逗号前后使用空格,所以明智的做法是删除所有空格(如果有),以便
explode
函数正确创建数组使用这种新方法,您需要确保字符串中的值顺序正确并且字符串的长度正确。如果没有,你会得到意想不到的输出
让我们解决第一个短代码:(请注意:下面的所有代码都未经测试。它可能有错误或语法错误 )
internal-menu
//menu
function internal_menu( $atts )
{
$attributes = shortcode_atts(
array(
'href' => '',
),
$atts
);
$output = '',
// Check if href has a value before we continue to eliminate bugs
if ( !$attribute['href'] )
return $output;
// Create our array of values
// First, sanitize the data and remove white spaces
$no_whitespaces = preg_replace( '/\s*,\s*/', ',', filter_var( $attributes['href'], FILTER_SANITIZE_STRING ) );
$href_array = explode( ',', $no_whitespaces );
$output .= '<div id="internalPageMenu">';
$output .= '<ul>';
foreach ( $href_array as $k => $v ) {
// From your code, link 1 is different, so I kept it as is
if ( $k == 0 ) {
$output .= '<li><a href="#' . $v . '"><i class="fa fa-bars"></i>link 1</a></li>';
} else {
$output .= '<li><a href="#' . $v . '">link ' . ($k + 1 ) . '</a></li>';
}
}
$output .= '</ul>';
$output .= '</div>';
return $output;
}
add_shortcode( 'internal-menu', 'internal_menu' );
然后您可以使用如下简码
[internal-menu href='jl1, jl2, jl3, jl4']
internal-menu-target
//menu target
function internal_menu_target($atts)
{
$attributes = shortcode_atts(
array(
'id' => '',
'text' => '',
),
$atts
);
$output = '',
// Check if href has a value before we continue to eliminate bugs
if ( !$attribute['id'] || !$attribute['text'] )
return $output;
// Create our array of values
// First, sanitize the data and remove white spaces
$no_whitespaces_ids = preg_replace( '/\s*,\s*/', ',', filter_var( $attributes['id'], FILTER_SANITIZE_STRING ) );
$ids_array = explode( ',', $no_whitespaces_ids );
$no_whitespaces_text = preg_replace( '/\s*,\s*/', ',', filter_var( $attributes['text'], FILTER_SANITIZE_STRING ) );
$text_array = explode( ',', $no_whitespaces_text );
// We need to make sure that our two arrays are exactly the same lenght before we continue
if ( count( $ids_array ) != count( $text_array ) )
return $output;
// We now need to combine the two arrays, ids will be keys and text will be value in our new arrays
$combined_array = array_combine( $ids_array, $text_array );
foreach ( $combined_array as $k => $v )
$output .= '<h3 id="' . $k . '">' . $v . '</h3>';
return $output;
}
add_shortcode('internal-menu-target', 'internal_menu_target');
您可以按如下方式使用此简码:
[internal-menu-target id='1,2,3,4' text='text 1, text 2, text 3, text 4']
问题:
Wordpress 短代码在可以传递的数据格式方面有一些痛苦的限制...
space-定界变量:
[shortcode a="1 2"]
结果:$atts=['a'='"1', 0='2"']
']' 关闭简码:
[shortcode b=[yay]]
结果:$atts=['b'='[yay']
解决方案:
您可以使用 urlencode()
:
[shortcode atts=a=1+2&b=%5Byay%5D]
像这样解析它:
parse_string($atts['atts'],$atts);
结果:$atts=['a'=>'1 2', b=>'[yay]']
这会给你传递你想要的数组。
现在关于构建菜单:
function internal_menu($atts) {
// allow passing + and ] in the text of the links:
parse_string($atts["links"],$links);
// the defaults, verbatim from the question:
if (!count($links)) $links=[
'href1' => '#jl1',
'href2' => '#jl2',
'href3' => '#jl3',
'href4' => '#jl4',
];
foreach ($links as $text=>$href) $ul=."<li><a href=\"$href\">$text</a></li>";
return '<div id="internalPageMenu"><ul>'.$ul.'</ul></div>';
}
add_shortcode('internal-menu', 'internal_menu');
//menu target
function internal_menu_target($atts) {
// allow passing + and ] in the text:
if (@$atts[text]) $atts['text']) = urldecode($atts['text']);
// the defaults, verbatim from the question:
$atts=array($atts)+['text'=>'','id'=>'jl1'];
return '<h3 id="' . $link['id'] . '">' . $link['text'] . '</h3>';
}
add_shortcode('internal-menu-target', 'internal_menu_target');
然后像这样喂它:
[internal-menu links=First+Link=#jl1&Second+Link=#jl2&Google=https://google.com]
[internal-menu-target text=Section+1 id=jl1]
等等
顺便说一句,如果您负责任地使用它,extract()
完全没问题:
/* concatenates 3 words of wisdom into a polite policy direction
*
* @param $attr: hash of function args
* foo = the first word (Kindly)
* bar = the second word (ignore)
* baz = the third word (totalitarians)
*/
function excellent_policy($attr){
$defaults=['foo'=>'Kindly', 'bar'=>'ignore', 'baz'=>'totalitarians'];
extract((array)array_intersect_key($attr,$defaults)+$defaults);
echo "$foo $bar $baz!";
}
这会以可读和可预测的方式将 $foo、$bar 和 $baz 从 $attr 导入本地作用域,为那些未传递的变量提供默认值,并防止创建任何意外变量。
使用语言功能有好有坏。 禁止所有人使用某种语言功能,因为有人可能会用得不好,这就像禁止所有人呼吸,因为有人可能会尝试吸入果冻。
我使用的简单方法:
[my param="key1=value1&key2=value2"]
在短代码回调中,只需执行:
parse_str( str_replace("&", "&", $attrs['param']), $array);
// var_dump( $array );