You are viewing this site in a simplified layout because your browser does not yet support CSS Subgrid.

op111.net

Search op111.net

How to filter the output of Contact Form 7 or any other shortcode in WordPress

WordPress 4.7, released in December 2017, introduced a new filter hook called do_shortcode_tag. This new filter hook makes it easy to modify the output generated by shortcodes, either all shortcodes or shortcodes that meet specific conditions.

The do_shortcode_tag filter hook supports four arguments.

  1. The first argument is the output to be filtered. It is the only required argument.
  2. The second argument is the tag (that is, the name) of the shortcode to be filtered.
  3. The third argument is an array of the shortcode attributes. This argument makes it possible to target specific instances of a shortcode.
  4. The fourth argument is an array of the six group matches returned by get_shortcode_regex(). With this argument we can, for example, target shortcodes wrapping content that contains a certain string.

Let’s see four examples of using do_shortcode_tag, one for each argument it supports.

Example 1 (shortcode output)

function op111_shortcodes_add_msg($output, $tag, $atts, $m) {
  $msg = '<p>';
  $msg .= 'The above was generated with a WordPress shortcode.';
  $msg .= '</p>';

  return $output . $msg;
}

add_filter('do_shortcode_tag', 'op111_shortcodes_add_msg', 10, 4);

This will add a message under any content generated by any shortcode.

Example 2 (shortcode tag)

Now we will add some text under forms generated by Contact Form 7. In order to limit the filtering to output generated by Contact Form 7, we check if the shortcode tag (that is, the shortcode name) is the one used by Contact Form 7. If it is, we append our text to the output of the shortcode and then return the result. If it is not, we return the output unchanged.

function op111_wpcf7_add_msg($output, $tag, $atts, $m) {
  if ($tag === 'contact-form-7') {
    $msg = '<p>';
    $msg .= 'This form was made with Contact Form 7.';
    $msg .= '</p>';

    $output .= $msg;
  }

  return $output;
}

add_filter('do_shortcode_tag', 'op111_wpcf7_add_msg', 10, 4);

Example 3 (shortcode attributes)

The third argument of do_shortcode_tag allows us to be even more specific. Let’s say that we have several forms made with Contact Form 7 and that we want to add a CSS class to the submit button of the form named Main without changing the output of other forms generated by Contact Form 7:

function op111_wpcf7_main_add_class($output, $tag, $atts, $m) {
  if ($tag === 'contact-form-7' && $atts['title'] === 'Main') {
    $output = str_replace(
      'wpcf7-submit',
      'wpcf7-submit wpcf7-submit-main',
      $output
    );
  }

  return $output;
}

add_filter('do_shortcode_tag', 'op111_wpcf7_main_add_class', 10, 4);

Example 4 (regex matches)

One of our magazine’s authors gets angry when typing text wrapped in shortcodes and sometimes types the swear word foo. The editor said we should print an apology when this happens. Here is how we automated the job:

function op111_offer_apology($output, $tag, $atts, $m) {
  if (preg_match('/\bfoo\b/', $m[5])) {
    $msg = '<p>';
    $msg .= 'Our apologies for the bad language.';
    $msg .= '</p>';

    $output .= $msg;
  }

  return $output;
}

add_filter('do_shortcode_tag', 'op111_offer_apology', 10, 4);

In this example we use a regular expression to look for the string foo at the fifth match returned by get_shortcode_regex(). The fifth match is the content of the shortcode if the shortcode wraps any content. If our string exists there, we add an apology at the end of the shortcode output. If it does not, we return the output unchanged.