質問

I'm digging into shortcodes expert level 😄

I made some searches and I really think I'm on the right path but I need your help because something is missing me (probably because I don't know very well how to code a condition).

So, on my website I have in a lot of pages a block with a HTML <select>, with these lists it's possible to open a file from my server.

The original HTML is like this:

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

There are some items that I want to make it dynamic so I can write the shortcode and the function do the job, something like this [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' );

I know something is not right but I can't figure out what… can you help me?

役に立ちましたか?

解決

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

ライセンス: CC-BY-SA帰属
所属していません wordpress.stackexchange
scroll top