带有Foreach和参数的短码

时间:2021-01-06 作者:Rafael Viana

我正在钻研短代码专家级

我做了一些搜索,我真的认为我走在了正确的道路上,但我需要你的帮助,因为有些东西找不到我(可能是因为我不太清楚如何编写条件代码)。

所以,在我的网站上,我在很多页面上都有一个带有HTML的块<select>, 通过这些列表,可以从我的服务器打开文件。

原始HTML如下所示:

<form name="example">
  <select name="download_files">
    <option value="">TITLE</option>
    <option value="https://example.com/file1.pdf">FILE 1</option>
    <option value="https://example.com/file2.pdf">FILE 2</option>
  </select>
  <a class="button">Download</a>
</form>
有一些项目我想使其动态化,这样我就可以编写短代码和函数来完成这项工作,就像这样[download title="Configuration" files_title="File 1, File 2" files_name="file1.pdf, file2.pdf"]

function download_files($atts){
    $att = shortcode_atts( array(
      \'title\' => \'Configuration\',
      \'files_title\' => [\'File 1\',\' File 2\'],
      \'files_name\' => [\'file1.pdf\', \'file2.pdf\']
    ), $atts );

  $output = \'<form name="example">
              <span>\' . $att[\'TITLE\'] . \'</span>
              <select name="download_files">\';
                foreach ($files[0] as $file) {
                    $output .= \'<option value="https://example.com/\' . $att[\'files_name\'] . \'">\' . $att[\'files_name\'] . \'</option>\'
                }
  $output .= \'</select><a class="button">Download</a></form>\';

  return $output;
}

add_shortcode( \'form-render\', \'download_files\' );
我知道有些不对劲,但我想不出什么……你能帮我吗?

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

Here is your problem:

foreach ($files[0] as $file) {

There is no $files variable, so there is nothing to loop through.

You can\'t pull variables out of thin air and expect PHP to understand your intent. Computers are very literal, in the most extreme sense. They can\'t intuit what you meant, or want. This code should be generating lots of PHP notices and warnings in your error log file when it runs.

Fundamentally, you can\'t pass arrays/lists like this to shortcodes. Shortcode attributes are strings, text. Because of this, you cannot use an array as a default value, it doesn\'t make sense:

      // this is not possible:
      \'files_title\' => [\'File 1\',\' File 2\'],
      \'files_name\' => [\'file1.pdf\', \'file2.pdf\']

You can pass a comma separated list however, as your shortcode example demonstrates:

      \'files_title\' => \'File 1, File 2\',
      \'files_name\' => \'file1.pdf, file2.pdf\'

Then use explode to get an array, e.g. $file_titles = explode( \',\', $att[\'files_title\'];, then do it again for files_name. At this point, you have a generic PHP problem rather than a WordPress problem. You would have to create a new array from those 2 arrays where each item is an array with a title and name key, e.g. [ [ \'title\'=>\'File 1\', \'name\' => \'file1.pdf\' ], [ \'title\' => \'File 2\' ... etc.

This is the kind of thing you would do in the first year of a computer science degree, or in a general programming book, but anybody can do it if they understand the fundamental basics of the programming language, specifically loops and arrays,

Alternatively, use composition. Don\'t define your files in attributes, give them their own shortcodes:

[files title="title"]
[file url="..."]First file[/file]
[file url="..."]second file[/file]
[/files]

That way the file shortcode can be for just the <option> tag.

Fundamentally though, shortcodes are an old feature, you should consider replacing them with a block instead

相关推荐

是否使用插件覆盖主题中的WooCommerce loop-start.php?

“我的主题”有一个覆盖内容/主题/主题名/woocommerce/循环/loop-start.php.我想使用插件覆盖此文件。我知道可以使用子主题来完成,但我想使用插件(因为我在1个插件中捆绑了许多其他修改)。我在堆栈交换上发现了其他一些类似的问题,但无法找到有效的解决方案。以下是我的尝试:使用theme_file_path:add_filter( \'theme_file_path\', \'override_woocommerce_loop_template\', 9999); fu