6

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

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.

4
  • Note - this is NOT for a Wordpress site, so I can't use existing WP shortcode functions. Commented Dec 31, 2010 at 8:05
  • Maybe this also involves preg_replace_callback? Commented Dec 31, 2010 at 15:29
  • I would venture a guess and say that you could probably extract the related code out of WordPress easily enough. Alternatively, you can just do what Kyle suggested and use one of many approaches to create your own solution. Commented Dec 31, 2010 at 17:52
  • With a function getimage($id) that does the MySQL query, this almost does everything I need: [not enough space—see answer] Commented Jan 4, 2011 at 1:49

5 Answers 5

9

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Oh ok, I thought that this works in PHP 5.4+ because you code didn't work at first attempt. Then I found out that you have a typo in your function name. You call a function shortcodify() but it's definded as shortcodifiy() - the "i" makes the difference. I corrected this for you.
Nice catch. Thanks a lot!
4

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.

Comments

1

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!

Comments

0

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

1 Comment

The PHP documentation page should not change. I will add it @MegaTron :D
0

The regex, I believe, would be:

/\[\[[1-9]{1,3}\]\]/g

(for a 1-to-3 digit number inside double brackets.)

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.