WordPress 短代码传递值数组

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

我正在创建一些 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..."]
php wordpress shortcode
4个回答
20
投票

foreach
将是您的答案。在我看来,这将是最简单和最干净的。在我给你一个代码示例之前,让我们分析你的代码并看看你所有的缺陷以及我们将如何纠正它们

瑕疵

  • 永远不要使用

    extract()
    exctract()
    即时创建变量,这是有问题的。您无法正确调试
    extract()
    如果您可以),所以当它失败时,您真的会不必要地为您完成工作。由于这些原因,它已从核心和法典中完全删除。请参阅trac 票 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']

3
投票

问题:

Wordpress 短代码在可以传递的数据格式上有一些痛苦的限制......

空格分隔的变量:

[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]

BTW

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 导入本地范围,为这些变量提供默认值(如果它们未被传递),并防止创建任何意外变量。

使用语言功能有好的方法和坏的方法。 禁止每个人使用语言功能,因为有人可能会用得不好就像禁止每个人呼吸,因为someone可能会尝试吸入果冻。


2
投票

我使用的简单方法:

[my param="key1=value1&key2=value2"]

在短代码回调中,只需执行:

parse_str( str_replace("&amp;", "&", $attrs['param']), $array);
// var_dump( $array );

0
投票

我有另一种方法可以在

$content
的短代码中执行此操作。

此解决方案增加数据的可读性/相关性。 但如果你想用你的 $content 做其他事情,这可能不是一个好方法。

使用的简码就像...

// in wordpress editor or your *.php file

[testimonial_carousel_list]
[
  {
    "message": "Lorem ipsum dolor sit amet.",
    "avatar": "https://via.placeholder.com/150",
    "full_name": "John Doe"
  },
  {
    "message": "Vivamus vel ornare purus, in faucibus tellus.",
    "avatar": "https://via.placeholder.com/150",
    "full_name": "Jane Smith"
  },
  {
    "message": "Morbi tristique augue vel mi ornare, sit amet viverra lectus semper.",
    "avatar": "https://via.placeholder.com/150",
    "full_name": "David Lee"
  }
]
[/testimonial_carousel_list]

在这里如何处理它介绍你的简码功能

// it might be in functions.php of your theme

function testimonial_carousel_list_shortcode($_atts, $content = null) {
  $items = json_decode($content);

  // ...rest of your code whatever you what to do with array $items
}
add_shortcode('testimonial_carousel_list', 'testimonial_carousel_list_shortcode');

// this is required if you want to json_decode() on your $content.
// because wptexturize will change your `'` or `"` to `‘` or `“` it will made json_decode got error.
function shortcodes_to_exempt_from_wptexturize( $shortcodes ) {
    $shortcodes[] = 'testimonial_carousel_list';
    return $shortcodes;
}
add_filter('no_texturize_shortcodes', 'shortcodes_to_exempt_from_wptexturize');
© www.soinside.com 2019 - 2024. All rights reserved.