integrate smarty modifier close_tags

Discussion corner for Developers of Serendipity.
Post Reply
User avatar
Timbalu
Regular
Posts: 4598
Joined: Sun May 02, 2004 3:04 pm

integrate smarty modifier close_tags

Post by Timbalu » Fri Oct 30, 2009 5:58 pm

Hi Garvin,

I just tried to use the smarty modifier

Code: Select all

{...|@truncate:30:" [...]"|close_tags}

with setting $serendipity['smarty']->security = false; for this purpose only.
But it isn't in Serendipities Smarty functions yet.

Is it possible to integrate this smarty function to s9y 1.5, please?
http://smarty.incutio.com/?page=CloseTags

Regards,
Ian

edit
I just found a modified version, which is working as expected:
to put in Smarty/libs/plugins/ as modifier.close_tags.php

Code: Select all

<?php 
/**
 * modified by Gunnar Tillmann,
 * http://www.gunnart.de?p=353
 */

/**
 * Smarty plugin
 *
 * @package Smarty
 * @subpackage plugins
 */

/**
 * Smarty close all unclosed xhtml tags
 *
 * Type:   modifier<br>
 * Name:   close_tags<br>
 *
 * @param  string
 * @return string
 */

function smarty_modifier_close_tags($string) {

   $tags = 'a|b|p|i|u|h1|h2|h3|h4|h5|h6|em|strong|code|pre|del|font|span|div|center|table|tr|td|th|form|ul|ol|li|caption|small|dd|dl|dt|fieldset|option|select';

   // match opened tags
   //if(preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $start_tags)){
   if(preg_match_all('/<('.$tags.')[^\/>]*>/i', $string, $start_tags)){ // <-- GUNNAR
      $start_tags = $start_tags[1];
   
      // match closed tags
      //if(preg_match_all('/<\/([a-z]+)>/', $string, $end_tags)){
      if(preg_match_all('/<\/('.$tags.')>/i', $string, $end_tags)){ // <-- GUNNAR
         $complete_tags = array();
         $end_tags = $end_tags[1];
   
         foreach($start_tags as $key => $val){   
            $posb = array_search($val, $end_tags);
            if(is_integer($posb)){
               unset($end_tags[$posb]);
            } else {
               $complete_tags[] = $val;
            }
         }

      } else {

         $complete_tags = $start_tags;
      }

      $complete_tags = array_reverse($complete_tags);

      // replaced the post-incrementation with pre-incrementation, which is faster * ian *
      for($i = 0; $i < count($complete_tags); ++$i){
         $string .= '</' . $complete_tags[$i] . '>';
      }
   }
   return $string;
}
?>


edit 10-31
but this was not enough universal, so I modified it to:

Code: Select all

<?php 
/**
 * modified by ian for s9y 2009-10-31
 */

/**
 * Smarty plugin
 *
 * @package Smarty
 * @subpackage plugins
 */

/**
 * Smarty close all unclosed xhtml tags
 *
 * Type:   modifier<br>
 * Name:   close_tags<br>
 *
 * @param  string
 * @return string
 */

function smarty_modifier_close_tags($string) {

    $patt2open    = "%((?<!</)(?<=<)[\s]*[^/!>\s]+(?=>|[\s]+[^>]*[^/]>)(?!/>))%";
    $patt2close   = "%((?<=</)([^>]+)(?=>))%";
   
   // match opened tags
   if(preg_match_all($patt2open, strtolower($string), $start_tags)) {
      $start_tags = $start_tags[1];
   
      // match closed tags
      if(preg_match_all($patt2close, strtolower($string), $end_tags)) {
         $complete_tags = array();
         $end_tags = $end_tags[1];
   
         foreach($start_tags as $key => $val){   
            $posb = array_search($val, $end_tags);
            if(is_integer($posb)){
               unset($end_tags[$posb]);
            } else {
               $complete_tags[] = $val;
            }
         }

      } else {

         $complete_tags = $start_tags;
      }

      $complete_tags = array_reverse($complete_tags);

      for($i = 0; $i < count($complete_tags); ++$i){
         $string .= '</' . $complete_tags[$i] . '>';
      }
   }
   return $string;
}
?>

How about adding this to s9y smarty plugins, or is there a better solution to do, Garvin?
I can't do it in the plugin itself, thats why I need the |close_tags modifier.

Ian

Post Reply