views:

51

answers:

5

I am having a bit of an issue with autogenerating shortcodes, based on database entries.

I am able to get a normal shortcode working i.e:

function route_sc5() {
        return "<div>Route 5</div>";
    }
    add_shortcode('route 5','route_sc');

and the following shortcode to activate it would be [route 5]

This works. But what I need is the shortcode to be produced for each database entry. something like:

$routes = $wpdb->get_results( $wpdb->prepare("SELECT * FROM wp_routes") );
foreach($routes as $route)
{
    function route_sc$route->id () {
        return "<div>Route $route->id</div>";
    }
    add_shortcode('route $route->id','route_sc$route->id');
}

The above is just an example of how I want it to work. Not literally the code I am using. How would I go about achieving this? ): Thanks.

+2  A: 

Dynamic function names are not possible in PHP.

But you could try eval.

eval('function route_sc'.$route->id.' () { return "<div>Route '.$route->id.'</div>"; }');
aRagnis
Dynamic function names are perfectly possible in PHP: "$func = 'my_function'; $func();"
Bobby Jack
@Bobby You can easily call [variable functions](http://php.net/manual/en/functions.variable-functions.php), but they're slightly harder to create.
Adam Backstrom
A: 

Thanks, I tried this as well as a few other solutions. At the moment I am able to ECHO the correct function i need, with all the right values in.

foreach($buses as $bus)
    {               
        $out = "function route_sc".$bus->id."() { ";
        $out .= "return \"<div>".$bus->route_name."</div>\";";
        $out .= "} add_shortcode('route ".$bus->route_name."','route_sc".$bus->id."');";
        echo $out;
    }   

this gievs me something like:

function route_sc1() { return "1";} add_shortcode('route 1','route_sc1');

but when i replace echo with return, it does not replace anything on the page like it should.

any ideas? thanks

Adam
You should modify your question to include this new attempt, rather than have it as an answer.
Adam Backstrom
+1  A: 

Here's an example of dynamic shortcode callbacks using PHP 5.3 anonymous functions:

for( $i = 1; $i <= 5; $i++ ) { 
    $cb = function() use ($i) {
        return "<div>Route $i</div>";
    };  

    add_shortcode( "route $i", $cb );
}

I have to ask, though: can you just accomplish what you need to do using shortcode arguments? ie. [route num=3]. Then you could just have one handle_route() function and one [route] shortcode, which may simplify things.

Also, while technically you can include a shortcode with a space in the name, I think it creates a confusing ambiguity. If you decide you need specific shortcodes for each route, I would recommend "route5" or "route-5" rather than "route 5."

Adam Backstrom
What actually is in the <div> route $id</div> (as this is just an example).. is a set of divs which has a class set to a value stored in the database, a style=backround color also set from a value n the database, aswell as the route name from the database.with one hanle_route() function, i dont fully understand how i could pull this data out without the user having to do something like: [route num=5 bgcolor=#123456 class=W]but i am going to have a go to have a go to see if i can simplify it for the user as much as possible.
Adam
A: 

Go about it a different way: Shortcodes can take parameters. So instead of [route 5] do [route rt="5"]. This way your shortcode processing function stays generic and the part that changes is meant to be dynamic. It also means that if an unexpected shortcode is encountered during the page load you can handle it properly instead of WordPress just stripping the code and replacing it with nothing.

See here for more info: http://codex.wordpress.org/Shortcode_API

Gipetto
A: 

Thanks guys, finally got it working. here is the code for any1 who may need it in the future:

function route_sc($atts, $content = null) {
    extract(shortcode_atts(array(
    'num' => '',
    'bg' => '',
    'text' => '',
), $atts)); 
    global $wpdb;
    $bus = $wpdb->get_row( $wpdb->prepare("SELECT * FROM wp_route WHERE id = '$num'") );
    return "<div class='".$bus->text_colour."' style='background-color:".$bus->bg_colour."'>".$bus->route_id."</div></div>";
}
add_shortcode('route','route_sc');

with the shortcode at [route num="5a"]

Adam