4

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:

[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

3 Answers 3

4

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
  • Awesome. I had no idea that there would be a plugin that would allow me to embed PHP in my post. I may not know PHP that well, but it can be learned, and probably a lot easier than the deep dive into WordPress. I'll go down this road and circle back to let you know how it worked. I can't accept an answer until I have it fully working, but this looks like it should do the trick.
    – Snekse
    Commented Jul 11, 2012 at 18:25
  • The deep dive into WP, requires you pass through PHP anyways, so they go hand in hand. Learn one and you'll have much more success with the former. http://www.php.net is the official home of PHP docs which are invaluable. Good luck. Be sure to post back with Q's and progress...
    – Adam
    Commented Jul 12, 2012 at 19:23
1

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.

1
  • The custom parser was the original route I started on, but that quickly got messy as we needed to handle nested tags, tags with optional end tags, etc. The short codes has worked fairly well with two exceptions: if/else blocks and setting variables. That will be my next question posted: can you set a PHP variable within WordPress content?
    – Snekse
    Commented Dec 6, 2011 at 14:50
1

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;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.