Support » Developing with WordPress » Autogenerate shortcodes from an array of strings

  • Resolved giannit

    (@giannit)


    I have to create a lot of shortcodes of the form

    function foobar_sc( $atts ) {
    	remove_filter( 'the_content', 'wpautop' );
    	$content = apply_filters( 'the_content', '<div class=con>[block slug=foobar]</div>' );
    	add_filter( 'the_content', 'wpautop' );
    	return $content;
    }
    add_shortcode( 'foobar', 'foobar_sc' );

    whose names are listed in an array

    $shortcodes = array("foo", "bar", ...);

    I tried with

    $shortcodes = array("foo", "bar");
    foreach ($shortcodes as $name) {
    	add_shortcode( '$name', '$name_sc' );
    	function $name_sc( $atts ) {
    		remove_filter( 'the_content', 'wpautop' );
    		$content = apply_filters( 'the_content', '<div class=con>[block slug=$name]</div>' );
    		add_filter( 'the_content', 'wpautop' );
    		return $content;
    	}
    }

    but I get the error Fatal error: syntax error, unexpected ‘$name_sc’ (T_VARIABLE), expecting ‘(‘ on line function $name_sc( $atts ) {

    Is it possible to solve it?

Viewing 12 replies - 1 through 12 (of 12 total)
  • Moderator Steven Stern (sterndata)

    (@sterndata)

    Forum Moderator & Support Team Volunteer

    A function name cannot begin with $.

    If you’re using a variable to create a function, I’ve been googling about but have not found anything definite.

    In your code, you’re showing that all of the shortcodes going to have exactly the same code so that they’ll do exactly the saem thing. Is that what’s actually going to happen?

    If every shortcode is the same, just define a single function and set that for each shortcode.

    If you need different functionality for each one, have a look at this and see if it works for your purposes. https://stackoverflow.com/a/38185072

    Thread Starter giannit

    (@giannit)

    If every shortcode is the same, just define a single function and set that for each shortcode.

    @catacaustic yes I have to define dozens of shortcodes with same funcionality (the only difference is the name in [block slug=$name]). I would like to avoid to manually write the definition of each shortcode, is it possibile to do it automatically?

    That’s my point… If the functionality is all the same, why do you need separate functions for each one? You just need one function, and you can assign it to each shortcode that you have.

    As an example…

    function my_shortcode_function() {
       // Do your stuff in here
    }
    
    foreach( $shortcodes as $name ){
        add_shortcode ($name, 'my_shortcode_function');
    }
    Thread Starter giannit

    (@giannit)

    Oh thanks, is this correct?

    $shortcodes = array("foo", "bar");
    function my_shortcode_function( $name ) {
    	remove_filter( 'the_content', 'wpautop' );
    	$content = apply_filters( 'the_content', '<div class=con>[block slug=$name]</div>' );
    	add_filter( 'the_content', 'wpautop' );
    	return $content;
    }
    foreach( $shortcodes as $name ){
        add_shortcode ($name, 'my_shortcode_function( $name )');
    }

    Not, it’s not right. When you define the shortcode, it gets passed two values – $args (an array of values passed in) and $content. See do_shortcode() for more information.

    Your PHP Syntax is wrong when you call add_shortcode(). The value for $name can’t be added in there, It’s got to be done the way that I had it in my first example.

    Thread Starter giannit

    (@giannit)

    Ok thanks, I’m having some problem with variable name, so let simplify the problem so that each auto generated shortcode just has to print my name is: "shortcode name"

    $shortcodes = array("foo", "bar");
    function my_shortcode_function() {
        return ???;
    }
    foreach( $shortcodes as $name ){
        add_shortcode ($name, 'my_shortcode_function');
    }

    I tried with return 'my name is: $name'; and return 'my name is: ' . $name; but it doesn’t work since the output is my name is: $name in the first case and my name is: in the second case.

    Which is the correct syntax?

    • This reply was modified 1 year, 6 months ago by giannit.
    • This reply was modified 1 year, 6 months ago by giannit.

    Honestly… that sounds like a terrible idea. Why do you need multiple shortcodes for that? If you’re just trying to print a name out you need a single shortcode that reads in a variable for name from the shortcode in the post/page content. Something like this…

    PHP code:

    function my_shortcode ($args = array ()) {
        return "May name is " . $args ['name'];
    }
    
    add_shortcode ('my_name_shortcode', 'my_shortcode');

    In your post/page/etc:

    [my_name_shortcode name="My Name"]

    Thread Starter giannit

    (@giannit)

    I know it is not a common usage, but since in my posts there will be only this kind of shortcodes, it is useless to have to write each time [my_name_shortcode name="shortcode_name"] when I can more rapidly write [shortcode_name].

    The previous example (print the name of the shortcode) is just an example to let you understand that what I need is to be able to handle a string variable (taken from an array of strings) and use it inside the definition of a shortcode.

    What have I to write in place of ??? in order to generate the shortcodes [foo] and [bar] having as content <div class=con>[block slug=foo]</div> and <div class=con>[block slug=bar]</div> respectively?

    $shortcodes = array("foo", "bar");
    function my_shortcode_function() {
    	remove_filter( 'the_content', 'wpautop' );
    	$content = apply_filters( 'the_content', '<div class=con>[block slug=???]</div>' );
    	add_filter( 'the_content', 'wpautop' );
    	return $content;
    }
    foreach( $shortcodes as $name ){
        add_shortcode ($name, 'my_shortcode_function');
    }
    Thread Starter giannit

    (@giannit)

    Solution

    $shortcodes = array("foo", "bar");
    foreach ($shortcodes as $name) {
        add_shortcode( $name, function ( $atts ) use ( $name ) {
            remove_filter( 'the_content', 'wpautop' );
            $content = apply_filters( 'the_content', '<div class=con>[block slug=' . $name . ']</div>' );
            add_filter( 'the_content', 'wpautop' );
            return $content;
        });
    }
    Moderator bcworkz

    (@bcworkz)

    So you’re basically a lazy typist? 😛
    It’s OK, I get it. Your scheme is flawed in that the shortcodes that get expanded are limited to your hard coded array. By using a common tag and passing an argument, you’re able to expand any arbitrary text. Additionally, as Steve alludes to, you need to have a dynamically named function. We’re not sure if that’s possible with PHP, no one seems to do that. I think you would need to somehow use a closure (anonymous function).

    Why not use the “enclosing” form of shortcodes, using a brief shortcode tag? As in [foo]any text you like here[/foo]. It can become
    <div class="con">The expansion of [block slug="any text you like here"] could be output</div>

    Another thing, nested or recursive shortcodes are problematic. Either have your shortcode handler call the handler for [block] directly or use do_shortcode(). Don’t in part literally return [block slug="foo"] or whatever and expect it to be expanded.

    What you want just can’t work. There’s no way that the standard shortcode system does things that way. I get it, it would be a few milliseconds faster each time to write that, but, then it’s also going to be slower because you also need to go back and define every variable in your name array anyway.

    If you really feel the need that this is how you have to do it, I’d suggest an alternative. Forget shortcodes, and use filters to set the various details that you want.

    Something like this…

    function my_content_filter ($content) {
        $names = array ('First Name', 'Second Name');
    
        foreach ($names as $name) {
            $content = str_replace ($name, '<div class="con">'.$name.'</div>', $content);
        }
    
        return $content;
    }
    
    add_filter ('the_content', 'my_content_filter');
    • This reply was modified 1 year, 6 months ago by catacaustic.
Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘Autogenerate shortcodes from an array of strings’ is closed to new replies.