Hi,
playing with templates and extensions I'am not happy that template variables between the extension tags are not expanded because in Parser.php replaceVariables() is called _after_ strip().
Don't know if this is a design decision, but as a result of that you can't have parametrized templates which uses extensions which is quite bad.
For example a "Template:Inventarnummer" which is: <db>SELECT inventarnum FROM rechner WHERE name = '{{{1}}}'</db> can't be used as {{Inventarnummer|Hermes}} because the "db" extension gets the variable literally as "{{{1}}}" not as "Hermes". This way it's impossible to hide "extensions calls" inside templates.
Don't know if this is generally useful at all but the attached patch of Parser.php (against current cvs) works for me quite ok.
Mikesch
Sorry, Mailman dropped the attachment ;-)
Mikesch
---snipp--- diff -u -r -w -N wikipedia/phase3/includes/Parser.php mywikipedia/phase3/includes/Parser.php --- wikipedia/phase3/includes/Parser.php 2005-01-06 20:25:14.000000000 +0100 +++ mywikipedia/phase3/includes/Parser.php 2005-01-06 20:54:46.000000000 +0100 @@ -96,7 +96,7 @@ var $mTagHooks;
# Cleared with clearState(): - var $mOutput, $mAutonumber, $mDTopen, $mStripState = array(); + var $mOutput, $mAutonumber, $mDTopen, $mStripState = array(), $mStripStateClear; var $mVariables, $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
# Temporary: @@ -163,6 +163,7 @@ // VOODOO MAGIC FIX! Sometimes the above segfaults in PHP5. $x =& $this->mStripState; $text = $this->strip( $text, $x ); + $text = $this->stripExtensions( $text, $x );
$text = $this->internalParse( $text, $linestart ); $text = $this->unstrip( $text, $this->mStripState ); @@ -286,7 +287,6 @@ $math_content = array(); $pre_content = array(); $comment_content = array(); - $ext_content = array(); $gallery_content = array();
# Replace any instances of the placeholders @@ -360,6 +360,49 @@ } }
+ # Merge state with the pre-existing state, if there is one + if ( $state ) { + $this->mStripStateClear = false; + $state['html'] = $state['html'] + $html_content; + $state['nowiki'] = $state['nowiki'] + $nowiki_content; + $state['math'] = $state['math'] + $math_content; + $state['pre'] = $state['pre'] + $pre_content; + $state['comment'] = $state['comment'] + $comment_content; + $state['gallery'] = $state['gallery'] + $gallery_content; + } else { + $this->mStripStateClear = true; + $state = array( + 'html' => $html_content, + 'nowiki' => $nowiki_content, + 'math' => $math_content, + 'pre' => $pre_content, + 'comment' => $comment_content, + 'gallery' => $gallery_content, + ); + } + return $text; + } + + /** + * Strips and renders extensions + * If $render is set, performs necessary rendering operations on plugins + * Returns the text, and fills an array with data needed in unstrip() + * If the $state is already a valid strip state, it adds to the state + * + * @param bool $stripcomments when set, HTML comments <!-- like this --> + * will be stripped in addition to other tags. This is important + * for section editing, where these comments cause confusion when + * counting the sections in the wikisource + * + * @access private + */ + function stripExtensions( $text, &$state, $stripcomments = false ) { + $render = ($this->mOutputType == OT_HTML); + $ext_content = array(); + + # Replace any instances of the placeholders + $uniq_prefix = UNIQ_PREFIX; + # Extensions foreach ( $this->mTagHooks as $tag => $callback ) { $ext_contents[$tag] = array(); @@ -374,28 +417,14 @@ }
# Merge state with the pre-existing state, if there is one - if ( $state ) { - $state['html'] = $state['html'] + $html_content; - $state['nowiki'] = $state['nowiki'] + $nowiki_content; - $state['math'] = $state['math'] + $math_content; - $state['pre'] = $state['pre'] + $pre_content; - $state['comment'] = $state['comment'] + $comment_content; - $state['gallery'] = $state['gallery'] + $gallery_content; - + if ( !$this->mStripStateClear ) { foreach( $ext_content as $tag => $array ) { if ( array_key_exists( $tag, $state ) ) { $state[$tag] = $state[$tag] + $array; } } } else { - $state = array( - 'html' => $html_content, - 'nowiki' => $nowiki_content, - 'math' => $math_content, - 'pre' => $pre_content, - 'comment' => $comment_content, - 'gallery' => $gallery_content, - ) + $ext_content; + $state = $state + $ext_content; } return $text; } @@ -2109,8 +2138,9 @@ $this->mTemplatePath[$part1] = 1;
$text = $this->strip( $text, $this->mStripState ); - $text = $this->removeHTMLtags( $text ); $text = $this->replaceVariables( $text, $assocArgs ); + $text = $this->stripExtensions( $text, $this->mStripState ); + $text = $this->removeHTMLtags( $text );
# Resume the link cache and register the inclusion as a link if ( $this->mOutputType == OT_HTML && !is_null( $title ) ) { @@ -2801,6 +2831,7 @@ ); $text = str_replace( array_keys( $pairs ), array_values( $pairs ), $text ); $text = $this->strip( $text, $stripState, false ); + $text = $this->stripExtensions( $text, $stripState, false ); $text = $this->pstPass2( $text, $user ); $text = $this->unstrip( $text, $stripState ); $text = $this->unstripNoWiki( $text, $stripState ); ---snipp---
Hi,
<db>SELECT inventarnum FROM rechner WHERE name = '{{{1}}}'</db>
how do you get this working? This looks like you are performing a SQL query inside wiki text. In my wiki the db-tag is not known, although I have set$wgAllowSysopQueries = true; in my LocalSettings.php.
Thanks,
- Moritz
Am Freitag, 7. Januar 2005 11:03 schrieb Moritz Karbach:
<db>SELECT inventarnum FROM rechner WHERE name = '{{{1}}}'</db>
how do you get this working? This looks like you are performing a SQL query inside wiki text.
Shure. See below this very simple and danger (!) example:
--- file extensions/db.php --- <?php # This is a simple and danger example! Never ever use this in production! $wgExtensionFunctions[] = "wfDBExtension"; function wfdbExtension() { global $wgParser; $wgParser->setHook( "db", "renderDB" ); } function renderDB( $input ) { list ( $database, $query ) = explode( "|", $input ); global $wgDBserver, $wgDBuser, $wgDBpassword; $conn = mysql_connect( $wgDBserver, $wgDBuser, $wgDBpassword ); if ( !$conn ) { return '?'; } if ( !mysql_select_db( $database )) { return '?'; } $rs = mysql_query( $query ); if ( !$rs ) { return ''; } $wert = mysql_fetch_array( $rs ); mysql_close(); return $wert[0]; } ?>
--- page Template:EMail --- <db>testwiki|SELECT user_email FROM user WHERE user_name = '{{{1}}}'</db>
---page Test --- Nutzer WikiSysop hat die EMail '''{{EMail|WikiSysop}}'''.
It renders as "Nutzer WikiSysop hat die EMail wikisysop@nostromo.lv49.space." Probably you get the idea. I'am using this in an extensions which generates self modifying pages for server status reports.
Mikesch
mediawiki-l@lists.wikimedia.org