How to Filter Content passed to a WordPress Shortcode

Viewed 47

I am using the following custom WordPress shortcode to display a list on a page, I am trying to find the 5th LI element and inject a DIV at this point.

[expander]
<ul>
    <li>step1</li>
    <li>step 2</li>
    <li>step 3</li>
    <li>step 4</li>
    <li>step 5</li>
    <li>step 6</li>
    <li>step 7</li>
</ul>
[/expander]

Shortcode:

add_shortcode( 'expander', 'my_function' );


function my_function($atts, $content) {

  echo substr_count($content, '<li>'); // 7
  return $content;
}

Intended Output:

<ul>
    <li>step1</li>
    <li>step 2</li>
    <li>step 3</li>
    <li>step 4</li>
    <li>step 5</li>

    <div>
      <li>step 6</li>
      <li>step 7</li>
    </div>

</ul>
1 Answers

There are multiple ways to set this up. The following code will wrap a <div> tag around the last two <li> tags starting after the 5th element exactly like you requested in your "Intended Output" section of your question, BUT please notice that you could use the shordcode attributes to make it dynamic NOT hard-coded by passing the starting and ending numbers as attributes.

The following code is the hard-coded version as you've asked it!

add_shortcode('expander', 'my_function');


function my_function($atts, $content)
{
  $lists_itmes = substr_count($content, '<li>');
  $list_array = explode('<li>', $content); // This will return an array containing of the values between each <li> tag starting from index 1
  $main_content = "";
  for ($i = 0; $i < $lists_itmes + 1; $i++) {
    switch ($i) {
      case 6:
        $main_content .= "<div><li>" . $list_array[6] . "</li>";
        break;
      case 7:
        $main_content .= "<li>" . $list_array[7] . "</li></div>";
        break;
      default:
        $main_content .= "<li>" . $list_array[$i] . "</li></div>";
        break;
    };
  }
  return $main_content;
}

And it'll output:

<ul>
    <li>step 1</li>
    <li>step 2</li>
    <li>step 3</li>
    <li>step 4</li>
    <li>step 5</li>

    <div>
      <li>step 6</li>
      <li>step 7</li>
    </div>

</ul>
Related