用短码实现If-ElseIf-Else-EndIf

时间:2011-12-05 作者:Snekse

我对WordPress和PHP几乎没有经验,所以我提前为语法问题道歉

我想知道是否可以将if/Else逻辑实现为短代码。类似于:

[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]
如果你想了解我为什么要做这样一件愚蠢的事的更多背景,请参阅SO上的参考帖子。

Parse CFML tags in PHP

3 个回复
SO网友:Adam

看看你的SO帖子,看看CF标签输出,然后看看你在这里试图用短代码做什么,正如奥托所说,这将是一个不连贯的混乱。

已经存在允许您在帖子内容中编写PHP逻辑的插件,如下所示Allow PHP in Posts and Pages 将以如下形式的短代码语法为您提供这种能力;

[php]
     
    if ( condition ) {

        //do something...

    } elseif ( condition ) {

       //do something...
    
    } else {

       //do something...

    }

[/php]
简单。

您的[php] <-- --> [/php] 是常规PHP。无需编写自己的短代码函数来模拟if/elseif/else 思维方式这将是浪费时间,之所以如此,是因为你将面临的最大问题与if/elseif/else PHP的语法,但能够通过logic现有的CFTags,它们的预期用途,然后将该用途转换为其在PHP中的物理等价物,其仍然需要遵守WordPress API,尤其是如果任何功能依赖于WordPress框架(?)

以我上面的例子为例,你的逻辑很快就会失控(就大小而言),而这并不是一堆代码(无论如何都要扔进你的帖子内容编辑器)的真正位置。

您可以做的是,仍然使用上面相同的概念,创建执行CFTags等效操作的函数,并将这些函数存储在functions.php 然后从上面相同的代码块中执行以下操作:;


  //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] 

这些函数与您为执行特定任务而创建的方法相对应,只是如果必须将代码插入到您的帖子内容中,您的代码现在更易于管理。

这还意味着,如果需要扩展这些功能,您可以在帖子功能之外控制上述功能的功能,以提高灵活性。

但是

如果您的经验如您所建议的那样有限,您是否能够解析CFTags,然后将它们转换为您实际可以使用的PHP逻辑?因为如果没有,那么在你克服这个绊脚石之前,前面提到的这些都不会对你有什么好处。

这就是为什么我必须同意Otto的观点,你最好过滤你的内容挂钩,但作为一个替代建议,如果很难进行严格的正则表达式匹配,我会使用SimpleHTMLDom Parser 在您的职能范围内HELPER CLASS 这将允许您迭代HTML并基于标记选择元素,提取所需的内容,对其进行操作,并将其作为the_content 过滤器继续过滤,你几乎和金子一样好。。。

示例(非常粗糙…)

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;
}
这里还有一个相当不错的教程,

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

这将使您进一步了解如何使用SimpleHTMLDom解析器来帮助您对内容进行解析,作为某些正则表达式匹配的替代甚至补充。

值得深思。。。

SO网友:Otto

不容易,而且无论如何,这将是一个痛苦和混乱的局面。

相反,我建议您编写自己的自定义解析器代码,以按原样处理cf:自定义标记,而无需将它们转换为任何其他格式或短代码或您拥有的其他格式。您可以在\\u内容和(shubder)regexp上使用过滤器来查找代码并进行适当的处理。

基本筛选器如下所示:

add_filter(\'the_content\',\'my_filter\');
function my_filter($content) {
  // do whatever you like to the $content here
  return $content;
}
返回的内容将替换内容。此外,过滤器在WordPress中链接,每个过滤器都接收前一个过滤器的输出。因此,如果您在其中有一些自定义CF:标记,那么您可以为每个(或一组)都有一个过滤器,并让它只更改和替换过滤器所属的相关内容部分。

SO网友:sMyles

这可能相当容易做到。这里有一个旧的basic,它只是一个文件,可以执行以下操作:

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

结束

相关推荐

Ajax, filters and shortcodes

您能理解为什么我无法在ajax帖子包含中应用短代码过滤器吗?让我更好地解释一下:我已经设法在另一篇文章中包含一篇文章,通过admin-ajax.php, 正如著名的5 tips.很明显,我不想显示快捷码标签,也不想去掉它们,所以我在回应do_shortcode($post->post_content)此时,虽然我正在运行“Cleaner gallery”插件,但post gallery会被渲染,但未被过滤add_filter( \'post_gallery\', \'cleaner_gallery\