Implement If-ElseIf-Else-EndIf with short codes

I have very little experience with WordPress and PHP, so I apologize in advance for syntax problems.

I’d like to know if it’s possible to implement If/Else logic as short codes. Something like:

Read More
[if] Version: IF [elseif] Version: ELSEIF [else] Version: ELSE [/if]
// OR...
[if] Version: IF [if branch="elseif"] Version: ELSEIF [if branch="else"] Version: ELSE [/if]

If you want more background into why I would want to do such an idiotic thing, see the referenced post on SO.

Parse CFML tags in PHP

Related posts

Leave a Reply

3 comments

  1. Having a look at your SO post, seeing the CF Tag output, then seeing what you’re trying to attempt here with shortcodes is, as Otto said, going to be an incoherent mess.

    There already exists plugins that allow you to write PHP logic amongst your post content, and the following Allow PHP in Posts and Pages will give you that ability in the form shortcode syntax like this;

    [php]
         
        if ( condition ) {
    
            //do something...
    
        } elseif ( condition ) {
    
           //do something...
        
        } else {
    
           //do something...
    
        }
    
    [/php]
    

    Simple.

    Everything between your [php] <-- --> [/php] is regular PHP. No need to write your own shortcode functions to mimic the if/elseif/else logic. That would be a waste of time and why that’s so is because the biggest problem you’re going to face has nothing to do with the if/elseif/else syntax of PHP but rather being able to parse and interpret via logic the existing CFTags, their intended purpose and then translating that purpose into its physical equivalent in PHP of which needs to still comply with the WordPress API especially if any of that functionality is reliant on the WordPress framework (?)

    Taking my example above, its not going to take long before your logic is running out of control (in terms of size) and that’s no real place to be throwing a bunch of code (into your post content editor anyway).

    What you could do, still using the same concept above is create functions that perform the equivalent actions of your CFTags and have those functions stored within your functions.php file in your theme folder then from within the same block of code above you could do something like;

      //shortcode followed by reference to your function
    
      [php] echo do_tag_condtional(); [/php]
    
      //example function that accept arguments etc  
    
      [php] echo cftag_feature($args = 'bla');  [/php] 
    
      //if your function returns its output as echo then you don't need to echo within your post
    
      [php] quick_tag(); [/php] 
    
    

    Those functions correspond to methods you’ve created to perform particular tasks, only that your code is now much more manageable if having to insert it amongst your post content.

    It also means you can control the functionality of your said functions external to that of your posts for increased flexibility should you need to expand upon those functions.

    BUT…

    If your experience is limited as you suggested, are you going to be capable in parsing CFTags and then turning them into some PHP logic that you can actually use? Because if not, then the aforementioned isn’t going to do a great for you until you overcome that stumbling block.

    This is why I have to agree with Otto that you would be better off filtering your content hook but as an alternative suggestion if serious regular expression matching is going to be to difficult, I would use SimpleHTMLDom Parser within your functions as a HELPER CLASS which will allow you to iterate over HTML and select elements based on tags, extract the content you need, manipulate it and pass it out the other end as the the_content filter moves on through and you’re almost as good as gold…

    Example (very crude…)

    add_filter('the_content','cftag_parser');
    
    function cftag_parser($content) {
       
        include('path/to/simple_html_dom.php');  
    
        $html = new simple_html_dom();  
        $html->load($content);  
      
        //get an element  
        $element = $html->find("<cf_taglinks></cf_taglinks>");  
      
        //modify it  
        $element[1]->innertext .= " insert this text inbetween the above tags";  
      
        //output it  
        $html->save();     
    
      return $content;
    }
    

    There’s also a pretty decent tutorial here,

    http://net.tutsplus.com/tutorials/php/html-parsing-and-screen-scraping-with-the-simple-html-dom-library/

    Which will give you some additional insight on how you can use SimpleHTMLDom Parser to help you parse over your content as an alternative to, or even an addition to some regular expression matching.

    Food for thought…

  2. Not easily, and anyway it would be painful and an incoherent mess.

    Instead, I recommend writing your own custom parser code to handle your cf:custom tags as-is, without converting them to any other format or shortcode or what have you. You can use filters on the_content and (shudder) regexp to find your codes and deal with them appropriately.

    Your basic filter looks like this:

    add_filter('the_content','my_filter');
    function my_filter($content) {
      // do whatever you like to the $content here
      return $content;
    }
    

    Whatever it returns replaces the content. Also, filters are chained in WordPress, with each one receiving the output of the previous. So if you have some custom CF: tags in there, then you can have a filter for each one (or set of them) and have it only alter and replace the relevant content section that the filter pertains to.

  3. It is possible fairly easy to do. Here’s an old basic that is only a single file that does just this:

    https://plugins.svn.wordpress.org/if-shortcode/tags/0.2.1/plugin.php

    <?php
    /*
    Plugin Name: If Shortcode
    Author: geomagas
    Description: Provides an "if" shortcode to conditionally render content
    Text Domain: if-shortcode
    Version: 0.2.1
    */
    
    $if_shortcode_filter_prefix = 'evaluate_condition_';
    $if_shortcode_block         = NULL;
    
    add_shortcode( 'if', 'process_if_shortcode' );
    
    function process_if_shortcode( $atts, $content ) {
    
        global $if_shortcode_filter_prefix;
        $false_strings = array( '0', '', 'false', 'null', 'no' );
        $atts          = normalize_empty_atts( $atts );
        $result        = FALSE;
        foreach ( $atts as $condition => $val ) {
            $mustbe   = ! in_array( $val, $false_strings, TRUE ); // strict, or else emty atts don't work as expected
            $evaluate = apply_filters( "{$if_shortcode_filter_prefix}{$condition}", FALSE );
            $result   |= $evaluate == $mustbe;
        }
        global $if_shortcode_block;
        $save_block         = $if_shortcode_block;
        $if_shortcode_block = array( 'result' => $result, 'else' => '', );
        $then               = do_shortcode( $content );
        $else               = $if_shortcode_block['else'];
        $if_shortcode_block = $save_block;
    
        return $result ? $then : $else;
    }
    
    add_shortcode( 'else', 'process_else_shortcode' );
    
    function process_else_shortcode( $atts, $content ) {
    
        global $if_shortcode_block;
        if ( $if_shortcode_block && ! $if_shortcode_block['result'] ) {
            $if_shortcode_block['else'] .= do_shortcode( $content );
        }
    
        return '';
    }
    
    add_shortcode( 'eitherway', 'process_eitherway_shortcode' );
    
    function process_eitherway_shortcode( $atts, $content ) {
    
        $content = do_shortcode( $content );
        global $if_shortcode_block;
        if ( $if_shortcode_block ) {
            $if_shortcode_block['else'] .= $content;
        }
    
        return $content;
    }
    
    // add supported conditional tags
    add_action( 'init', 'if_shortcode_conditional_tags' );
    
    function if_shortcode_conditional_tags() {
    
        $supported = array(
            'is_single',
            'is_singular',
            'is_page',
            'is_home',
            'is_front_page',
            'is_category',
            'is_tag',
            'is_tax',
            'is_sticky',
            'is_author',
            'is_archive',
            'is_year',
            'is_month',
            'is_day',
            'is_time',
            'is_feed',
            'is_search',
            'comments_open',
            'pings_open',
            'is_404',
            'is_user_logged_in',
            'is_super_admin',
        );
        global $if_shortcode_filter_prefix;
        foreach ( $supported as $tag ) {
            add_filter( "{$if_shortcode_filter_prefix}{$tag}", $tag );
        }
    }
    
    // normalize_empty_atts found here: http://wordpress.stackexchange.com/a/123073/39275
    function normalize_empty_atts( $atts ) {
    
        foreach ( $atts as $attribute => $value ) {
            if ( is_int( $attribute ) ) {
                $atts[ strtolower( $value ) ] = TRUE;
                unset( $atts[ $attribute ] );
            }
        }
    
        return $atts;
    }