1

I am trying to make a shortcode that will create a dynamic dropdown list of downloadable file links, that once selected, html will show a download link below the dropdown.

Here is the end result of how the shortcode will function: http://jsfiddle.net/KKyE9/

I am struggling with how to turn the shortcode array into a multidimensional array or if that is the right approach.

For example, via the shortcode I am passing attributes that are not defined in the shortcode function but beed to be created inside the function.

[sc total_options="10" option1="module 1" link1="http://cisco.com" label1="Click Here to download Module 2 audio file"  option2="module 2" link2="http://wordpress.com" label2="Click Here to download Module 2 audio file" option3="module 3" label3="Click Here to download Module 3 audio file" link3="http://cisco.com" option4="module 4" label4="Click Here to download Module 4 audio file" link4="http://wordpress.com"]

So option1, link1, label1, option2, link2, label2...etc. need to be created when the shortcode attributes are extracted.

I have a working model that creates the dropdown list and displays the html link below but that only works for a single link.

My challenge is passing the keyed attributes (option1, option2from the shortcode into the shortcode function so that I can use them in a loop and dynamically create the dropdown list options.

I am sure the code can be better but I was just trying to get it to work first for a single attribute.

function shortcode_dd_list($atts, $content = null) {

    extract(shortcode_atts(array(
        "total_options" => '',
        "option" => '',
        "label" => '',
        "link" => ''
    ), $atts));

    $output  = '';
    $output .= '<select id="wlmm-select-dropdown">';
    $output .= '<option value="option0">Please select a module to download</option>';

    $i = 1; 
    while ( $i <= $total_options ) {
      $output .= '<option value="'.$option'">'.$option.'</option>';     
        $i++;       
    }

    $output .= '</select>';

    $i = 1; 
    while ( $i <= $total_options ) {        
        $output .='<div id="'.$option.'" class="wlmm-select-dropdown-group">'.'<a href="'.$link.'">'.$label.'</a></div>';           
        $i++;
    }

    return $output;
}
add_shortcode("sc", "shortcode_dd_list");

Ideally I would rather setup the dropdown like this from the following series of schortcodes, its easier to read but I keep getting 4 dropdown boxes.

[sc total_options="4"]
[sc option1="Module 1" label1="Module 1 download" link1="http://bitBucket.com"]
[sc option2="Module 2" label2="Module 2 download" link="http://lostInSpace"]
[sc option3="Module 3" label3="Module 3 download" link="http://null"]
[sc option4="Module 4" label4="Module 4 download" link="http://error.com"]
5
  • Do you have to pass everything through the shortcode? Can you define your URLs elsewhere? That would simplify this a lot.
    – s_ha_dum
    Feb 9, 2013 at 0:26
  • Defining the urls somewhere else kind of defeats the function of shortcode...where were you thinking? Passing the url to me does not seem like a problem. In the function I have the url works perfect. The problem is...I need to loop through the shortcode attributes without having to define them in the array beforehand. So I don't have to crate a unnecessary array values like option1...option50. That way I can take total_options=x and loop the shortcode X times...i.e., total_options=3 (option1, option2 and option3) is created.
    – Jason
    Feb 9, 2013 at 1:29
  • I asked because you mentioned readability. When you have to shove a lot of information through a shortcode they get cumbersome and messy, it isn't a technical problem just a usability one.
    – s_ha_dum
    Feb 9, 2013 at 6:09
  • Sorry, no. Flattering, but I am looking at several major projects already.
    – s_ha_dum
    Feb 12, 2013 at 4:55
  • Do you have someone you respect that you could recommend. The coder I had, disappeared. This not a hopeful wanna be project. It has been in R&D for two years. I have the mass marketing / JV relationships with the big players now we need the take the beta project and turn it into a sellable version which will retail for around $800. This will be a good opportunity for the right coder. It's just so hard to find people that are good and execute to completion.
    – Jason
    Feb 12, 2013 at 8:15

2 Answers 2

1

Based on your example at the bottom of your question, and your statement that you would like something like that for readability, I'd do something like this:

function dropdown_option($atts) {
  $dropid = (isset($atts['dropid'])) ? $atts['dropid'] : '';
  global $sco_array;
  if (!empty($atts['value']) && !empty($atts['text'])) {
    $sco_array[$dropid][$atts['value']] = $atts['text'];
  }
}
add_shortcode('sco','dropdown_option');

function sc_dropdown($atts) {
  $id = (isset($atts['id'])) ? $atts['id'] : 'sc_dropdown';
  $dropid = (isset($atts['dropid'])) ? $atts['dropid'] : '';
  global $sco_array;
  $sel = '';
  if (!empty($sco_array[$dropid])) {
    $sel .= '<select id="'.$id.'" >';
      $sel .= '<option value="option0">Please select a module to download</option>';
      foreach($sco_array[$dropid] as $k=>$v) {
        $sel .= '<option value="'.$k.'">'.$v.'</option>';
      }
    $sel .= '</select>';
  }
  return $sel;
}
add_shortcode('scd','sc_dropdown');

Then you can build and display your dropdown with two shortcodes:

[sco dropid="one" value="http://example.com" text="Option1"]
[sco dropid="one" value="http://example1.com" text="Option2"]
[sco dropid="one" value="http://example2.com" text="Option3"]
[scd dropid="one" id="wlmm-select-dropdown"]

The first shortcode builds your options one at a time-- three shown. The second one displays it. The dropid value should let you put multiple selects on the same page, if you wanted to.

4
  • There was poetry in that answer. That was exactly what I was looking for. I had to add in the <div> tag line so that when the option is selected the anchor link showed. I had a problem with the <option> having special characters in it. So I added a counter for the <option value='option1' and did the same with the <div id='option1'> and it all came together. Code poetry. Thanks so much.
    – Jason
    Feb 11, 2013 at 17:46
  • I have been trying to figure out how to add additional attributes to sco. I want to pass label='Module 1'. How can I add the extra attribute and call it up to display in some html like <div id='optoin1' class='bla'><a href='bla'>Module 1</a>
    – Jason
    Feb 12, 2013 at 1:04
  • All of your attributes should be in the $atts array. You can add as many as you want, more or less. Just alter the processing function(s) to handle the new material.
    – s_ha_dum
    Feb 12, 2013 at 1:20
  • do you freelance, I have a huge project that requires a top notch wordpress developer?
    – Jason
    Feb 12, 2013 at 2:15
1

A simple solution would be using especial separators and the PHP function explode.

Like [multiarray options="option1a#option1b#option1c%option2a#option2b#option2c"]. Using % as first level separator, and # as second level.

This example prints this in the post content:

Array
(
    [0] => Array
        (
            [0] => option1a
            [1] => option1b
            [2] => option1c
        )

    [1] => Array
        (
            [0] => option2a
            [1] => option2b
            [2] => option2c
        )

)

Code for the shortcode

add_shortcode( 'multiarray', 'shortcode_wpse_85159' );

/**
 * Shortcode options to Multidimensional Array
 * Usage: [multiarray options="one#two#three%four#five#six%seven#eight#nine"]
 */
function shortcode_wpse_85159( $atts, $content = null ) 
{
    // options not defined, do nothing
    if( !$atts['options'] )
        return;

    $first_level = explode( '%', $atts['options'] );
    $final_array = array();

    foreach( $first_level as $level )
    {
        $second_level = explode( '#', $level );
        $final_array[] = $second_level;
    }

    // Returns a <pre> block of human readable variable value
    // http://www.php.net/manual/en/function.print-r.php 
    return '<pre>' . print_r( $final_array, true ) . '</pre>';
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.