1 | 2

1 - 5   [7]

Few More Changes

Relates to PEAR and Blogging

The comments forms on this blog has now been updated to accept a few XHTML tags again. Of course this means validating markup before submitting the data. This server is running PHP4, so unfotunately no access to the new Tidy Library. Therefore I had to look around for some code to handle the validation.

In a previous incarnation of this blog I had put Simon Willison's SafeHtmlChecker class to work. This time round I have decided to allow only a few inline elements. This keep formatting of the comments data to a minimum (for speed), and allows the XHTML validation to be plugged straight into my current validator class. To achieve this I have utilised a simple parser based around the PEAR::XML_HTMLSax package. This SAX based parser is ideal since it will not fail automatically on badly formed XML.

The new form is still in beta so I apologise if anything goes belly-up in use!

Posted on Aug 14, 2004 at 16:52:05. [Comments for Few More Changes- 6]

Array Prototyping for Legacy Support

Relates to DOM Scripting and Exploder

This is a reminder to self (since this trap keeps stinging me!) that IE 5.01 does not support the principle Array object methods in Javascript. A way around this problem is to test for the presence of these methods in the Array prototype property and if they do not exist define them. Here are examples for Array.push and Array.splice which I find myself using regularly in DOM based scripts.


if (typeof Array.prototype.push == "undefined") {
  Array.prototype.push = function(str) {
    this[this.length] = str;
  }
}

if (typeof Array.prototype.splice == "undefined") {
  Array.prototype.splice = function(offset, length) {
    var temp = [];
    for (var i = this.length - 1; i >= 0; i–) {
      if (i < offset || i > (offset + length - 1)) {
        temp[temp.length] = this[i];
      }
      this.length–;
    }
    for (i = temp.length - 1; i >= 0; i–) {
      this[this.length] = temp[i];
    }
  }
}

Posted on Aug 13, 2004 at 06:07:03. [Comments for Array Prototyping for Legacy Support- 2]

HTML List Slicer

Relates to PHP

Here is a neat little solution I concocted the other day to slice an HTML list. The list is stored in a cached object wrapped around additional mark-up and I wanted to display only a part of the list.

Original mark-up:


<div id="menu">
<h3>Some Links</h3>
<ul>
<li><a href="">Item 1</a></li>
<li><a href="">Item 2</a></li>
<li><a href="">Item 3</a></li>
..
<li><a href="">Item n</a></li>
</ul>
</div>

Desired output:


<div id="menu">
<h3>Some Links</h3>
<ul>
<li><a href="">Item 1</a></li>
<li><a href="">Item 2</a></li>
<li><a href="">Item 3</a></li>
</ul>
</div>

One solution is to create an array of all the list elements extract the required indexes and wrap the rest of the mark-up back around the retrieved set. This could be achieved using <a href="http://www.php.net/preg_replace_callback" title="PHP Doc for preg_replace_callback">preg_replace_callback()</a>, <a href="http://www.php.net/preg_match" title="PHP Doc for preg_match">preg_match()</a> and some array manipulations. However a condensed and far more elegant solution is a single call to <a href="http://www.php.net/preg_replace" title="PHP Doc for preg_replace">preg_replace()</a> making use of the /e modifier and a user-defined function. The /e modifier makes preg_replace treat the replacement parameter as PHP code after the appropriate references substitution is done.


class SS_Cached_Item {
  
  [snip]
  
  function getMenu($length, $offset = 0) {
    ss_fns_reset_range();  
    $str = htmlentities($this->_menu, ENT_QUOTES);      
    $str = preg_replace('#(<li>.+</li>\s+)#e',
                       "ss_fns_in_range('\\1', $offset, $length)",
                       $str);
    return unhtmlentities($str);
  }

}

function ss_fns_in_range($str, $offset = 0, $length = 10) {
  static $i = -1;  
  if ($str === NULL) { $i = -1; return false; }
  return (++$i >= $offset && $i < ($offset + $length)) ?
                                      $str : "";  
}
function ss_fns_reset_range() { ss_fns_in_range(NULL); }

The function ss_fns_in_range utilises a static variable to determine the equivalent index of the current match to the pattern. If the index is within the defined range the pattern is returned intact, otherwise it is replaced by an empty string. The supporting function ss_fns_reset_range will reset the static variable hence allowing multiple occurances of the callback in a single script execution. Note, <a href="http://www.php.net/htmlentities" title="PHP Doc for htmlentities">htmlentities()</a> is applied to the string to ensure special characters are not escaped during the replacement.


// display the first five list items
$obj->getMenu(5);    

 // display four items start at offset 2
$obj->getMenu(4, 2);

This functionality could easily be extended to generate random selections from the menu list.

Posted on Aug 13, 2004 at 06:01:50. [Comments for HTML List Slicer- 0]

Simple Acronym Handler

Relates to PHP and Web Standards

Many code snippets for handling acronyms seem to rely on <a href="http://www.php.net/preg_replace" title="PHP Doc for preg_replace">preg_replace()</a>. The problem with this method is ensuring that double replacements do not occur (e.g. with XHTML and HTML). A much better function to use is <a href="http://www.php.net/strtr" title="PHP Doc for strtr">strtr()</a> with two arguments:


$translation_array = array(
  'XHTML' => '<acronym title="eXtensible Hypertext Markup Language">',
  'HTML'  => '<acronym title="Hypertext Markup Language">'
                           );
$str = strtr($str, $translation_array);

It will always look for the longest pattern first and will not try to replace stuff it has already worked on. It is also really quick.

I have been test running the following function on this site to automate acronym handling:


function ss_fns_parse_acronyms($copy) {
  
  static $trans = array();
  
  if (empty($trans)) {
    $dat_file = SOME_PATH . '/data/acronyms.dat';
    $acronyms = parse_ini_file($dat_file);
    foreach($acronyms as $a => $d) {
      $trans[$a] = "<acronym title=\"$d\">$a</acronym>";  
    }    
  }
  
  return strtr($copy, $trans);        
}

The acronyms can be stored in php_ini format in a file, thus new acronyms can be added without interfering with this code. There are occassional limitations and gotchas - e.g. OS inadvertantly appearing in $_POST, but it is an efficient and clean alternative to preg_replace.

Posted on Aug 13, 2004 at 05:58:50. [Comments for Simple Acronym Handler- 0]

All Change Slowly

Relates to Blogging

Lots of changes been going on here this week, so I apologise if any one has stumbled across strange looking pages at any stage! Most of the change so far has been subtle or backend stuff. The main new inclusion is a caching system based around PEAR::Cache_Lite which has dramatically improved performance on the site. Categories and archives also have paginators now to ease the download burden a bit. More improvements to follow when time allows.

Posted on Aug 13, 2004 at 05:58:06. [Comments for All Change Slowly- 0]

Breadcrumbs Trail

[ Home ] -> TW Blog -> Archives for August 2004
Site Map

The Severn Solutions website achieves the following standards:

[ XHTML 1.0 ] [ CSS 2 ] [ WAI AA ] [ Bobby AA ]

Page compiled in 0.010 seconds