Web development and useful information

Nathan's Blog

WordPress shortcode: if-elseif-else statements

I found a great post which shows how to easily use an if-else shortcode in WordPress.

[if is_user_logged_in]
    You are already logged in.
[else]
    Display registration form.
[/if]

A callable must be used in the [if] condition.

In the above example, is_user_logged_in is the callable. This is a built in WordPress function to check whether the current visitor is a logged in user. It’s a shortcode equivalent of this PHP code:

<?php
if ( is_user_logged_in() ) { echo "You are already logged in."; } else { echo "Display registration form."; }

The callable you use will likely be the name of a WordPress function, or function added by a plugin. It can also be an object method or a static class method.

Callables support parameters, just like functions.

[if is_singular book]
    Show related books
[/if]

What if you need to check more than one condition?

I needed to check two conditions:
1. Is user a “Member”
2. Is user logged in to WordPress

I needed support for if-elseif-else statements.

If a user was a member I needed to show, “You are already a member”.
If a user was logged in, I needed to show a signup form.
Otherwise, I needed to show a different signup form.

I modified the code in the article above and found a solution for doing if-elseif-else conditions.

I changed the code to return a string (error message) instead of an Exception. A thrown Exception will not allow you to access the WordPress editor, if a non-callable is used in the shortcode. We need access to the editor to resolve this.

Install the plugin

Clone the repo to your /wp-content/plugins/ folder and the activate the plugin.

git clone https://github.com/n8kowald/if-elseif-else-shortcode

This allows you to use the following shortcode:

[if is_admin]
    Hi God, you're up late
[elseif is_user_logged_in]
    Hi Zero Cool, welcome back
[else]
    Welcome to the website. Please register to continue.
[/if]

We can use multiple elseif statements for an unlimited amount of conditions.

[if is_admin]
    Hi Mr The Plague.
[elseif is_user_logged_in]
    Hi Zero Cool, hack the planet!
[elseif is_single]
   Pool on the roof must have a leak.
[else]
    Welcome an0n. Please look around but don't steal my fries.
[/if]

You can use if on its own

[if is_admin]
    Hi Mr The Plague.
[/if]

You can use if-else without the elseif

[if is_admin]
    Hi Mr The Plague.
[else]
    Welcome an0n. Please look around but don't steal my fries.
[/if]

Allowed callables

The following callable functions are allowed by default:

comments_open
get_field is_404 is_admin is_archive is_author is_category is_day is_feed is_front_page is_home is_month is_page is_search is_single is_singular is_sticky is_super_admin is_tag is_tax is_time is_user_logged_in is_year pings_open

Adding callables

To allow other callables you must use the if_elseif_else_shortcode_allowed_callables filter.

This “allow other functions” filter should be added to wherever you put your hooks. That could be in:

  • a custom plugin: wp-content/plugins/plugin/plugin.php
  • a child theme’s functions.php: wp-content/themes/theme-child/functions.php
  • or a theme’s functions.php: wp-content/themes/theme/functions.php
<?php
add_filter( 'if_elseif_else_shortcode_allowed_callables', function( $whitelist ) {
    $whitelist[] = 'your_callable_here';
   
    return $whitelist;
}); 

Supported callable types

  • Function names: is_user_logged_in
  • Static class method calls (>=PHP 5.2.3): MyClass::myCallbackMethod
[if is_user_logged_in]
    Hello user
[elseif User::is_member_logged_in]
    Hello member
[else]
    Hello, please log in
[/if]

Note: in the above example, you would need to add User::is_member_logged_in to the allowed callables list.

Passing parameters to callables

Parameters are passed as space separated strings

[if is_singular books]
    Related books here.
[/if] 

If your callable accepts multiple parameters

<?php
function is_garfield( $animal, $colour ) {
    return $animal === 'cat' && $colour === 'orange';
}
[if is_garfield cat orange]
     Yes, this is garfield.
[/if]

Testing

If you want to simplify the main function or fix a bug, the plugin includes WordPress tests for refactored code.

Install PHPUnit and PHPUnit Polyfills

composer install

Install the WordPress testing library and database

Run this from the plugin directory.
Replace mysql_username and mysql_password with your MySQL username and password:

./bin/install-wp-tests.sh wordpress_tests mysql_username mysql_password

You can then run tests with:

vendor/bin/phpunit

Previous

Font size detective

Next

Listen to play / pause / play Radio on a LaMetric Time

6 Comments

  1. I’m using the Display URL Params plugin to parse values passed to my page via the $_GET array. The shortcode for doing this is:

    [URLParam param=’paramName’]

    I need to examine one or more of these values to display parameter-specific text content:

    [if [URLParam param=’paramName’] == “value1”]
    text option #1
    [elseif [URLParam param=’paramName’] == “value2”]
    text option #2
    [else]
    text option #3
    [/if]

    Is your plugin a viable solution for this?

    If so, specifically how do I implement?

    If not, would this be a feature you would be willing to add to your existing plugin?

    Thanks!

    Steve

    • Hi Steve, you can’t use a shortcode inside of my shortcode sorry. A shortcode is not a callable. But you can use my plugin to do what you want with a bit of extra code.

      Add this code to your theme’s functions.php file:

      // Register your $_GET params with WordPress.
      add_filter( 'query_vars', function( $vars ) {
      	// Add any other $_GET params you want to use.
      	$vars[] = 'paramName';
      
      	return $vars;
      });
      
      // Define a new function that takes in a param name and checks if it matches a values.
      function param_is( $param_name, $val ) {
      	return get_query_var( $param_name ) === $val;
      }
      
      // To allow my plugin to use param_is, add it to the allowed list.
      // For security reasons, my plugin requires unknown functions to be allowed manually.
      add_filter( 'if_elseif_else_shortcode_allowed_callables', function( $whitelist ) {
      	$whitelist[] = 'param_is';
      
      	return $whitelist;
      })
      

      In your WordPress editor, you can do what you want using these if elseif else shortcodes.

      [if param_is paramName value1]
      text option #1
      [elseif param_is paramName value2]
      text option #2
      [else]
      text option #3
      [/if]
      

      We’re using our created “param_is” callable function and passing in two params.
      1. Our registered $_GET parameter.
      2. The value we want to check for a match.
      The callable function returns true if the param exists in the URL and matches the value.

      Note: if you have another parameters you want to use, you need to add them to the query_vars filter like this:

      add_filter( 'query_vars', function( $vars ) {
      	$vars[] = 'paramName';
              $vars[] = 'anotherParamName';
      
      	return $vars;
      });
      

      // Now these params will work with param_is

      [if param_is anotherParamName value1]
      text option #1
      [else]
      text option #3
      [/if]
      

      I’ve tested this code as working.

      Hope that helps! Let me know if you have any questions.

      Here’s a link to the code for easier reading: https://gist.github.com/n8kowald/1ccf396f47ba6e6fc9b16e5e7063ed00

  2. Hi Nathan,

    I’ve been trying to use your plugin to help me display dynamic content on my page depending on if a custom field is filled in or not. Essentially IF a custom field is filled in with a price (or anything) then it will display a specific set of content.

    I’m having some trouble understanding how to add callable for those custom fields.

    Is this possible at all? Am I completely off base on trying to use your plugin. Where specifically do I add the additional callables in the plugin file?

    Any help would be great.

    Thank you

    • Hi Phil,

      This should be easy enough.

      Add this code into where you put your action/filter hooks.
      That could be a plugin, the functions.php file of your theme or functions.php of a child theme.
      As long as the filter is called from some file that’s loaded by WordPress, the shortcode will allow it.

      I’ll assume you’re using Advanced Custom Fields. If it’s something else I can provide code for that, but the idea is the same.
      We need to allow the “does this custom field have a value” function to be called by the shortcode.

      Here’s how you’d add ACF’s get_field function to the allowed list.

      // Put this filter into your theme's functions.php or a plugin.
      add_filter( 'if_elseif_else_shortcode_allowed_callables', function( $whitelist ) {
          // The function you want to allow.
          $whitelist[] = 'get_field';
         
          return $whitelist;
      });
      

      You should now be able to use this shortcode to do what you want:

      [if get_field acfFieldSelectorName]
          Custom field has a price.
      [else]
          Custom field does NOT have a price.
      [/if]
      

      This will output “Custom field has a price” if acfFieldSelectorName has a value for the post.
      To get this value with PHP you’d normally use: get_field( ‘acfFieldSelectorName’ );

      I use ACF on this blog and just tested this as working.

      Cheers,
      Nathan

      • Hi Nathan,

        Thank you for the help! I did want to reply and inform you that I tried your first step (installing the code into the plugin file) and it crashed my site. I removed it and everything was back to normal.

        I uninstalled the plugin and then re-downloaded and installed the plug in and simply just put in the if/else statement you provided with my desired Advanced Custom Fields selector name and it worked just fine.

        Not sure if you updated the files on get hub or anything but they worked just fine with out the additional .php.

        Thanks for your help!

        • Hi Phil,

          Glad it’s working for you now!

          You’re right, after your comment I updated my plugin to include “get_field” as one of the allowed functions by default. As it’s common for people to use ACF in their WP sites. I know I use it on just about every WP site I build.

          I also updated this blog post to try and explain callables better. As they sound complex, but they’re usually just function names.

          Cheers!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Powered by WordPress & Theme by Anders Norén