Extension talk:LO Parser Functions

Missing i18n File
I've had some real troubles with this extension. After a bit of hackery, I finally got it to work. Here are my files. Note that the instructions make no mention of the i18n file, so I had to develop a new one based on the ControlStructureFunctions i18n file:

 'Left-Over Parser Functions',        'url' => 'http://www.mediawiki.org/wiki/Extension:LO_Parser_Functions',        'author' => 'Tim Starling',        'description' => 'Enhance parser with logical functions', ); $wgHooks['LanguageGetMagic'][]      = 'wfLOParserFunctionsLanguageGetMagic'; class ExtLOParserFunctions { var $mExprParser; var $mTimeCache = array; var $mTimeChars = 0; var $mMaxTimeChars = 6000; # ~10 seconds function clearState { $this->mTimeChars = 0; return true; }       function &getExprParser { if ( !isset( $this->mExprParser ) ) { if ( !class_exists( 'ExprParser' ) ) { require( dirname( __FILE__ ) . '/Expr.php' ); ExprParser::addMessages; }                       $this->mExprParser = new ExprParser; }               return $this->mExprParser; }       function expr( &$parser, $expr = '' ) { try { return $this->getExprParser->doExpression( $expr ); } catch(ExprError $e) { return $e->getMessage; }       }        /**         * Returns the absolute path to a subpage, relative to the current article * title. Treats titles as slash-separated paths. *        * Following subpage link syntax instead of standard path syntax, an          * initial slash is treated as a relative path, and vice versa. */       public function rel2abs( &$parser, $to =  , $from =  ) { $from = trim($from); if( $from == '' ) { $from = $parser->getTitle->getPrefixedText; }               $to = rtrim( $to, ' /' ); // if we have an empty path, or just one containing a dot if( $to == '' || $to == '.' ) { return $from; }               // if the path isn't relative if ( substr( $to, 0 , 1) != '/' &&                substr( $to , 0 , 2) != './' &&                 substr( $to , 0 , 3) != '../' &&                 $to != '..' ) {                       $from = ''; }               // Make a long path, containing both, enclose it in /.../ $fullPath = '/'. $from. '/' . $to. '/';               // remove redundant current path dots $fullPath = preg_replace( '!/(\./)+!', '/', $fullPath ); // remove double slashes $fullPath = preg_replace( '!/{2,}!', '/', $fullPath ); // remove the enclosing slashes now $fullPath = trim( $fullPath, '/' ); $exploded = explode ( '/', $fullPath ); $newExploded = array; foreach ( $exploded as $current ) { if( $current == '..' ) { // removing one level if( !count( $newExploded ) ){ // attempted to access a node above root node return wfMsgForContent( 'pfunc_rel2abs_invalid_depth', $fullPath ); }                               // remove last level from the stack array_pop( $newExploded ); } else { // add the current level to the stack $newExploded[] = $current; }               }                // we can now join it again return implode( '/', $newExploded ); }       function time( &$parser, $format = , $date = , $local = false ) { global $wgContLang, $wgLocaltimezone; if ( isset( $this->mTimeCache[$format][$date][$local] ) ) { return $this->mTimeCache[$format][$date][$local]; }               if ( $date !== '' ) { $unix = @strtotime( $date ); } else { $unix = time; }               if ( $unix == -1 || $unix == false ) { $result = wfMsgForContent( 'pfunc_time_error' ); } else { $this->mTimeChars += strlen( $format ); if ( $this->mTimeChars > $this->mMaxTimeChars ) { return wfMsgForContent( 'pfunc_time_too_long' ); } else { if ( $local ) { # Use the time zone if ( isset( $wgLocaltimezone ) ) { $oldtz = getenv( 'TZ' ); putenv( 'TZ='.$wgLocaltimezone ); }                                       wfSuppressWarnings; // E_STRICT system time bitching $ts = date( 'YmdHis', $unix ); wfRestoreWarnings; if ( isset( $wgLocaltimezone ) ) { putenv( 'TZ='.$oldtz ); }                               } else { $ts = wfTimestamp( TS_MW, $unix ); }                               if ( method_exists( $wgContLang, 'sprintfDate' ) ) { $result = $wgContLang->sprintfDate( $format, $ts ); } else { if ( !class_exists( 'SprintfDateCompat' ) ) { require( dirname( __FILE__ ) . '/SprintfDateCompat.php' ); }                                       $result = SprintfDateCompat::sprintfDate( $format, $ts ); }                       }                }                $this->mTimeCache[$format][$date][$local] = $result; return $result; }       function localTime( &$parser, $format = , $date =  ) { return $this->time( $parser, $format, $date, true ); }       /**         * Obtain a specified number of slash-separated parts of a title, * e.g. => "Hello" *        * @param Parser $parser Parent parser * @param string $title Title to split * @param int $parts Number of parts to keep * @param int $offset Offset starting at 1 * @return string */       public function titleparts( $parser, $title = '', $parts = -1, $offset = 1 ) { $parts = intval( $parts ); $offset = intval( $offset ) - 1; $ntitle = Title::newFromText( $title ); if( $ntitle instanceof Title ) { $bits = explode( '/', $ntitle->getPrefixedText ); if( $parts <= 0 || $parts > count( $bits ) ) { return $ntitle->getPrefixedText; } elseif( $offset < 0 || $offset > count( $bits ) ) { return $ntitle->getPrefixedText; } else { $keep = array; for( $i = 0; $i < $offset; $i++ ) array_shift( $bits ); for( $i = 0; $i < $parts; $i++ ) $keep[] = array_shift( $bits ); return implode( '/', $keep ); }               } else { return $title; }       } } function wfSetupLOParserFunctions { global $wgParser, $wgMessageCache, $wgExtLOParserFunctions, $wgMessageCache, $wgHooks; $wgExtLOParserFunctions = new ExtLOParserFunctions; $wgParser->setFunctionHook( 'expr', array( &$wgExtLOParserFunctions, 'expr' ) ); $wgParser->setFunctionHook( 'time', array( &$wgExtLOParserFunctions, 'time' ) ); $wgParser->setFunctionHook( 'timel', array( &$wgExtLOParserFunctions, 'localTime' ) ); $wgParser->setFunctionHook( 'rel2abs', array( &$wgExtLOParserFunctions, 'rel2abs' ) ); $wgParser->setFunctionHook( 'titleparts', array( &$wgExtLOParserFunctions, 'titleparts' ) ); include_once( dirname( __FILE__ ) . '/LOParserFunctions.i18n.php' ); foreach( LOParserFunctions_i18n::efLOParserFunctionsMessages as $lang => $messages ) $wgMessageCache->addMessages( $messages, $lang ); $wgHooks['ParserClearState'][] = array( &$wgExtLOParserFunctions, 'clearState' ); } function wfLOParserFunctionsLanguageGetMagic( &$magicWords, $langCode ) { include_once( dirname( __FILE__ ) . '/LOParserFunctions.i18n.php' ); foreach( LOParserFunctions_i18n::efLOParserFunctionsWords( $langCode ) as $word => $trans ) $magicWords[$word] = $trans; return true; }
 * LOParserFunctions.php

 array( 'expr'     => array( 0, 'expr' ), 'time'   => array( 0, 'time' ), 'timel' => array( 0, 'timel' ), 'rel2abs' => array( 0, 'rel2abs' ), 'titleparts' => array( 0, 'titleparts' ), ),   );    public static $messages = array(    // English        'en' => array( 'pfunc_rel2abs_invalid_depth' => "Invalid depth on rel2abs", 'pfunc_time_error' => "Time Error", 'pfunc_time_too_long' => "Time too long", )   );    /**     * Get translated magic words, if available *    * @param string $lang Language code * @return array */   public static function efLOParserFunctionsWords( $lang ) {       // English is used as a fallback, and the English synonyms are // used if a translation has not been provided for a given word return ( $lang == 'en' || !isset( self::$words[$lang] ) ) ? self::$words['en'] : array_merge( self::$words['en'], self::$words[$lang] ); }   public static function efLOParserFunctionsMessages {       return self::$messages; } }
 * LOParserFunctions.i18n.php

Listrophy 18:21, 15 November 2007 (UTC)


 * Wow! How did I forget to include that?  I've included the i18n file that I was using during development.  It's little more than a copy/paste of the ParserFunctions' i18n file.  —Sledged (talk) 19:00, 15 November 2007 (UTC)