[Home]WikiPatches/WikiTemplate

UseModWiki | WikiPatches | RecentChanges | Preferences

Wiki Template Patch

Description

This patch allows templates to be inserted into a page. Any wiki page can be a template, and any number of patches can be inserted into a page.

Templates cannot be nested, this is a measure to prevent template looping (that is, a template which contains itself directly or indirectly). Until I find a valid use case for nested templates, laziness dictates that I not implement it. :)

The syntax for using templates is follows:

 {{template <template-name> <template-parameters>}} 

The template name can be any wiki page's name, the template parameters are NAME=VALUE pairs, in separate rows. If you put a word between '$' signs, e.g. $TEMPLATEPARAM$, then it will be properly substituted.

Usage Example

Consider a wiki about handheld devices. This wiki contains a page page, called DeviceTemplate.

The contents of the DeviceTemplate page

|||| '''Device description''' ||
|| Device ID: || $DEVICEID$ ||
|| Key mapping: || $KEYMAPPING$ ||
|| Backlight: || $BACKLIGHT$ ||
|| Storage card path: || $STORAGECARDPATH$ ||
|| Internal storage: || $INTERNALSTORAGE$ ||

The code inserted into the AcmeDevice101 page

{{template DeviceTemplate
DEVICEID=Acme device 101
BACKLIGHT =
KEYMAPPING=75 (info) 76 (menu) 77 (vol-) 78 (vol+)
STORAGECARDPATH=''currently unknown!'' <br> CategoryUnknownStorageCard
}}

This will yield

Device description
Device ID: Acme device 101
Key mapping: 75 (info) 76 (menu) 77 (vol-) 78 (vol+)
Backlight:  
Storage card path: currently unknown!
CategoryUnknownStorageCard?
Internal storage:  

The Patch

--- OriginalUsemodWiki.pl       2006-05-08 15:41:32.000000000 +0200
+++ WikiTemplate.pl     2006-05-23 11:11:57.000000000 +0200
@@ -1572,6 +1572,7 @@
   }
   $pageText = &QuoteHtml($pageText);
   $pageText =~ s/\\ *\r?\n/ /g;          # Join lines with backslash at end
+  $pageText =~ s/{{template(.*?)}}/&StoreTemplate($1, $id)/iges;
   if ($ParseParas) {
     # Note: The following 3 rules may span paragraphs, so they are
     #       copied from CommonMarkup
@@ -1894,6 +1895,63 @@
   return &StoreRaw("<$tag>" . $html . "</$tag>");
 }

+sub ReadWikiFile {
+  my ($fileName) = @_;
+  my ($fileData, %tempPage, %tempSection, %tempText);
+
+  return unless -f $fileName;
+  $fileData = &ReadFileOrDie($fileName);
+  %tempPage = split(/$FS1/, $fileData, -1);
+  %tempSection = split(/$FS2/, $tempPage{'text_default'}, -1);
+  %tempText = split(/$FS3/, $tempSection{'data'}, -1);
+  return $tempText{'text'};
+}
+
+sub WikiFileToHTML {
+  my ($text) = @_;
+  my ($output);
+  my ($mySaveUrlIndex, $mySaveNumUrlIndex, $myTableMode, %mySaveUrl, %mySaveNumUrl);
+
+  return unless $text;
+
+  # Global variables do not help this code. Nasty, but easiest solution.
+  %mySaveUrl= %SaveUrl;
+  %mySaveNumUrl= %SaveNumUrl;
+  $mySaveUrlIndex= $SaveUrlIndex;
+  $mySaveNumUrlIndex = $SaveNumUrlIndex;
+  $myTableMode= $TableMode;
+
+  $output = &WikiToHTML($text);
+
+  %SaveUrl = %mySaveUrl;
+  %SaveNumUrl = %mySaveNumUrl;
+  $SaveUrlIndex = $mySaveUrlIndex;
+  $SaveNumUrlIndex = $mySaveNumUrlIndex;
+  $TableMode = $myTableMode;
+
+  return $output;
+}
+
+sub StoreTemplate {
+  my ($params, $id) = @_;
+  my ($templateId, $templateFile, $templateText, $output, %substitutes);
+
+  $params =~ s/^\s*(\S+)\s*/$templateId=$1,''/e;
+  return &StoreRaw(T('No template name')) unless $templateId;
+  $templateFile = &GetPageFile($templateId);
+  return &StoreRaw(Ts('Template %s not found', $templateId)) unless -f $templateFile;
+
+  while ($params =~ /^(\S+)\s*=(.*)$/gm) {
+    $substitutes{$1} = $2;
+  }
+  $templateText = &ReadWikiFile($templateFile);
+  $templateText =~ s/\$(\S+)\$/$substitutes{$1}/gi;
+  $templateText =~ s/{{template//g; # Avoid nesting.
+  $output = &WikiFileToHTML($templateText);
+
+  return &StoreRaw($output);
+}
+
 sub StoreHref {
   my ($anchor, $text) = @_;


This patch contains some code from the BlogUsingSubPages patch.

-- UngarPeter


I installed this against v1.0 but had to make a small change: the 'id' parameter caused an error; I also cut out the word 'template' to simplify its use.

$pageText =~ s/{{template(.*?)}}/&StoreTemplate($1, $id)/iges;
becomes
$pageText =~ s/{{(.*?)}}/&StoreTemplate($1)/iges;

my ($params, $id) = @_;
becomes
my ($params) = @_;

$templateText =~ s/{{template//g; # Avoid nesting.
becomes
$templateText =~ s/{{//g; # Avoid nesting.

Great extension to code! joe1011010


UseModWiki | WikiPatches | RecentChanges | Preferences
Edit text of this page | View other revisions | Search MetaWiki
Last edited June 4, 2010 6:40 pm by tide533.microsoft.com (diff)
Search: