How to create a WordPress shortcode-style function in PHP

I am trying to create a WordPress shortcode-style feature in PHP to replace shortcodes like “[[133]]” with images. Basically, I have a MySQL table of image URLs/titles/subtitles with IDs 1-150, and I want to be able to dynamically insert them into the text of my pages with shortcodes like this:

Blabla bla bla bla bla. [[5]] Also, bla bla bla bla bla [[27]]
Hey, and bla bla bla! [[129]]

Read More

So, I just want to grab the ID as $id, and then feed it to a MySQL query like
mysql_query(“SELECT title,subtitle,url FROM images WHERE id = $id”)
and then replace the “[[id]]” with the img/title/subtitle. I would like to be able to do this multiple times on the same page.

I know this has to involve regex and some combination of preg_match, preg_replace, strstr, strpos, substr… but I don’t know where to start and which functions I should be using to do which things. Can you recommend a strategy? I don’t need the code itself—just knowing what to use for which parts would be extremely helpful.

Related posts

Leave a Reply

5 comments

  1. If you want to be able to write shortcodes like this :

    [[function_name_suffix parameter1 parameter2 ...]]
    

    here is a more complete way, using preg_replace_callback and call_user_func_array to implement parameterized shortcodes.

    function shortcodify($string){
        return preg_replace_callback('#[[(.*?)]]#', function ($matches) {
            $whitespace_explode = explode(" ", $matches[1]);
            $fnName = 'shortcode_'.array_shift($whitespace_explode);
            return function_exists($fnName) ? call_user_func_array($fnName,$whitespace_explode) : $matches[0];
        }, $string);
    }
    

    If this function is defined :

    function shortcode_name($firstname="",$lastname=""){
        return "<span class='firstname'>".$firstname."</span>&nbsp;<span class='lastname'>".$lastname."</span>";
    }
    

    Then this call

    print shortcodify("My name is [[name armel larcier]]");
    

    Will output :

    My name is <span class='firstname'>armel</span>&nbsp;<span class='lastname'>larcier</span>
    

    This is just something I implemented right now based on supertrue’s idea.

    Any feedback is more than welcome.

  2. With a function getimage($id) that does the MySQL query and formats the replacement text, this almost does everything you need:

    $text = "Blabla [[5]] and [[111]] bla bla bla [[27]] and bla bla bla! [[129]]";
    
    $zpreg = preg_match_all('#[[(d{1,3})]]#', $text, $matches );
    
    var_dump( $matches[1] );  
    
    $newtext = preg_replace('#[[(d{1,3})]]#', getimage($matches[1][?????]), $text);
    
    echo $newtext;
    

    I just need to figure out what to put inside getimage() (where ????? is) that will make it put in the right image for the right [[id]].

    Refer preg_match_all and preg_replace on official documentation for more details.

  3. Various different approaches can be taken for this, depending on how you plan to display ect,

    Take the sentence “Hello [34] world”

    Create a simple function e.g replaceCode($string)

    function replaceCode($string){
    
        $pos = strpos($string, '['); // Find the first occurrence of the bracket
    
        if($pos != false){
    
              // If everything is ok take the next 2 numbers from it
    
              // Check for a close bracket & remove ]
    
              // call another function to replace the number with the image text
    
        }
    
    
    
    
    }
    

    If anymore occurrences of brackets are found, recursively call the function again, passing the rest of the string to the function again.

    Note: Validation may need to be done first to ensure the [ and ] are properly balanced!

  4. My bet is PHP’s strtr function…

    <?php
    function get_profile_image($image_url){
        return "<img src='{$image_url}' height='200px' width='200px' />";
    }
    
    $trans = array(
        "[[1]]" => "Vishal",
        "[[2]]" => "Kumar",
        "[[3]]" => "Sahu",
        "[[4]]" => "Web Designer",
        "[[5]]" => "Draw and Paint",
        "[[6]]" => ucwords("any programming language"),
        "[[7]]" => strtoupper("PHP, JAVASCRIPT and HTML"),
        "[[8]]" => get_profile_image("http://php.net/images/logos/php-logo.svg"),
        "[[9]]" => "http://php.net/images/logos/php-logo.svg"
        );
    $str = <<<HEREDOC_1
    [[8]]
    <pre>My name is [[1]] [[2]] [[3]].
    I am a [[4]] and I love to [[5]].
    I don't know [[6]] but I know [[7]] little bit.</pre>
    Here is my profile image <img src='[[9]]' alt='[[1]]-[[2]]-[[3]]-[[4]]' />
    HEREDOC_1;
    echo strtr($str, $trans);
    

    it’s output is

    [http://php.net/images/logos/php-logo.svg%5D My name is Vishal Kumar
    Sahu. I am a Web Designer and I love to Draw and Paint. I don’t know
    Any Programming Language but I know PHP, JAVASCRIPT AND HTML little
    bit. Here is my profile image [Vishal-Kumar-Sahu-Web Designer]

    It is working fine on 5.6.