0

I need to allow users to use a shortcode [warning] in the frontend of my site. This shortcode may be followed by only one [warning](arg1) or two arguments [warning](optional-arg)(arg1).When the two arguments are entered the first one optional-arg will be considered as the heading and the second arg1 as the body text and if only one is entered arg1 it will be considered as the body text.

Here is the code I'm managing

function warning($text) {
    $text = preg_replace('/\[warning\]\s*\((.*?)\)/', '<div class="alert alert-error"><div class="alert-content"> $1 </div></div>', $text); //for warning with body text only
    $text = preg_replace('/\[warning\]\s*\((.*?)\)\s*\((.*?)\)/', '<div class="alert alert-error"><div class="alert-content"><h2 class="alert-title"> $1 </h2><div class="alert-body"><p> $2 </p></div></div></div>', $text); //for warning with heading 
    return $text;
}
add_filter('the_content', 'warning');
add_filter( 'the_excerpt', 'warning');

The problem is that the second argument is not considered and is out of the warning box.

Hamed
  • 159
  • 8
  • once the `[warning]` has been replaced by the first `preg_replace`, it is not there anymore for the second `preg_replace` to take effect. You need either to test first if there are 2 parameters (switch the 2 lines if that works) or make the regex for 1 argument to not match the case when there are 2 of them – Kaddath Mar 04 '19 at 15:40

1 Answers1

1

This is a job for preg_replace_callback

function warning($text) {
    return preg_replace_callback('/\[warning\]\s*\((.*?)\)(?:\s*\((.+?)\))?/', 
        function ($m) {
            if (isset($m[2])) {
                return '<div class="alert alert-error"><div class="alert-content"><h2 class="alert-title"> '.$m[1].' </h2><div class="alert-body"><p> '.$m[2].' </p></div></div></div>';
            } else {
                return '<div class="alert alert-error"><div class="alert-content"> '.$m[1].' </div></div>';
            }
        }
        , $text);
}
echo warning("[warning](body)"), "\n";
echo warning("[warning](header)(body)"), "\n";

Output:

<div class="alert alert-error"><div class="alert-content"> body </div></div>
<div class="alert alert-error"><div class="alert-content"><h2 class="alert-title"> header </h2><div class="alert-body"><p> body </p></div></div></div>
Toto
  • 89,455
  • 62
  • 89
  • 125