Extension:TemplateEdit

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual - list
Crystal Clear action run.png
TemplateEdit

Release status: beta

Implementation Special page
Description Edit Form for used Templates
Author(s) (VolkoVtalk)
Last version 0.5 (2011-12-02)
MediaWiki 1.16.0
License GPL
Download No link
Hooks used
AdminLinks

SkinTemplateToolboxEnd

Check usage and version matrix

Contents

What can this extension do? [edit]

Allow users editing used Templates in a form and defining those forms based on the templates used inside the wiki. Creating new Articles using templates is also supported.

Since writing a "real" grammar parser for Mediawiki Markup is not an easy task, for now the parser provided below is only working for standard cases. As you can see in the comments of code, some Magic Words etc. are still missing.

The idea for this extension was given by users confused with large templates with documentation on a seperate page. The editor allows presenting those in forms, resorting the parameters and removing used old or undefined parameters. The possibility of defining pick-lists also stops another source of typos.

Usage [edit]

Let us say, we used two nested templates in a page

{{Example
 |Name=TheName
 |Status=beta
 |Logo={{Logo|Logo.png|150px}}
 |Author=VolkoV
 }}

If we now defined editors for those under Template:Example/Editor and Template:Logo/Editor, like this one:

|Example Template=TITLE
|Name=TEXT!MUST!Please enter the name here
|Status=PICK!MUST!Status of the page!alpha;beta;released
|Logo=TEXT!!Pleas use the Logo-Template here
|Author=TEXT!!If you know him, enter the Author

If you now hit the new Link "Edit Templates" in your Toolbox, you receive something like this:

TemplateEditSelectTemplate.png

After selecting template Example, you woul get an editor as defined above:

TemplateEditEditor.png

Download instructions [edit]

Please cut and paste the code found below and place it in $IP/extensions/TemplateEdit/TemplateEdit.php etc. Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php.

Installation [edit]

To install this extension, add the following to LocalSettings.php:

require_once("$IP/extensions/TemplateEdit/TemplateEdit.php");

Code [edit]

TemplateEdit.php [edit]

Place the following in $IP/extensions/TemplateEdit/TemplateEdit.php:

<?php
/**
 * TemplateEdit.
 */
 
if ( !defined( 'MEDIAWIKI' ) ) die();
 
// credits
$wgExtensionCredits['specialpage'][] = array(
        'path' => __FILE__,
        'name' => 'Template Edit',
        'version' => '0.5',
        'author' => array( 'VolkoV' ),
        'url' => 'http://www.garetien.de',
        'descriptionmsg'  => 'templateedit-description',
);
 
$rtgIP = dirname( __FILE__ ) . '/';
$wgHooks['AdminLinks'][] = 'TemplateEdit::addToAdminLinks';
 
// This extension uses its own permission type, 'replacetext'
$wgSpecialPages['TemplateEdit'] = 'TemplateEdit';
$wgSpecialPageGroups['TemplateEdit'] = 'wiki';
$wgAutoloadClasses['TemplateParser'] = $rtgIP . 'TemplateParser.php';
$wgAutoloadClasses['TemplateEdit']   = $rtgIP . 'SpecialTemplateEdit.php';
 
$wgExtensionAliasesFiles['TemplateEdit'] = $rtgIP . 'TemplateEdit.alias.php';
$wgExtensionMessagesFiles['TemplateEdit'] = $rtgIP . 'TemplateEdit.i18n.php';
 
 
// Add a shortcut link to the toolbox.
$wgHooks['SkinTemplateToolboxEnd'][] = 'editTemplate_AddToolboxLink';
 
function editTemplate_AddToolboxLink( &$tpl ) {
        global $wgRequest;
 
        // 1. Determine whether to actually add the link at all.
        // There are certain cases, e.g. in the edit dialog, in a special page,
        // where it's inappropriate for the link to appear.
        // 2. Check the title. Is it a "Special:" page? Don't display the link.
        $action = $wgRequest->getText( 'action', 'view' );
        if ( method_exists( $tpl, 'getSkin' ) ) {
                $title = $tpl->getSkin()->getTitle();
        } else {
                global $wgTitle;
                $title = $wgTitle;
        }
 
        if( $action != 'view' && $action != 'purge' && !$title->isSpecialPage() ) {
                return true;
        }
 
        // 3. Add the link!
        $href = SpecialPage::getTitleFor( 'TemplateEdit' )->getLocalURL(Array("article"=>$title->getPrefixedURL()));
        echo Html::rawElement( 'li', null, Html::element( 'a', array( 'href' => $href ), 'Vorlagen editieren' ) );
 
        return true;
}

TemplateEdit.i18n.php [edit]

Place the following in $IP/extensions/TemplateEdit/TemplateEdit.i18n.php:

<?php
 
$messages = array();
 
$messages['en'] = array(
        // user messages
        'templateedit'                        => 'Template Edit',
        'templateedit-description'            => 'Edit Form for used Templates',
        'templateedit-unknown'                => 'Unknown Article',
        'templateedit-continue'               => 'Continue',
        'templateedit-save'                   => 'Save',
        'templateedit-showstartingform'       => 'Please enter the article you would like to edit:',
        'templateedit-showselecttemplateform' => 'Please select the template you would like to edit:',
        'templateedit-showeditform'           => 'Please edit the template:',
        'templateedit-templatecreated'        => 'Template $1 created',
        'templateedit-createwithtemplate'     => 'Create with [[Template:$1]]:',
        'templateedit-templateeditortitle'    => 'Template:$1/Editor',
        'templateedit-noeditor'               => 'Error, no editor defined!',
        'templateedit-mustfield'              => 'Obligatory!',
        'templateedit-remove'                 => 'Remove',
        'templateedit-editformintro'          => '[[$1]] - definition of editor: [[Template:$2/Editor]]',
        'templateedit-fieldundefined'         => 'Field is not (yet) defined!',
        'templateedit-oldfieldstitle'         => 'Old Fields',
        'templateedit-oldfield'               => 'Field is not valid (anymore) or not defined!',
        'templateedit-articlesaved'           => 'Article saved.',
        'templateedit-templateedited'         => 'Template $1 edited.',
);
 
$messages['de'] = array(
        // user messages
        'templateedit'                        => 'Vorlagen Editor',
        'templateedit-description'            => 'Formular zum Bearbeiten benutzter Templates',
        'templateedit-unknown'                => 'Unbekannter Artikel',
        'templateedit-continue'               => 'Weiter',
        'templateedit-save'                   => 'Speichern',
        'templateedit-showstartingform'       => 'Bitte geben Sie den Artikel ein, den Sie editieren wollen:',
        'templateedit-showselecttemplateform' => 'Bitte w&auml;hlen Sie die Vorlage, die Sie editieren wollen:',
        'templateedit-showeditform'           => 'Bitte editieren Sie die Vorlage:',
        'templateedit-templatecreated'        => 'Vorlage $1 erstellt',
        'templateedit-createwithtemplate'     => 'Erstellen mit [[Vorlage:$1]]:',
        'templateedit-templateeditortitle'    => 'Vorlage:$1/Editor',
        'templateedit-noeditor'               => 'Fehler, Editor nicht definiert!',
        'templateedit-mustfield'              => 'Pflichtfeld!',
        'templateedit-remove'                 => 'Entfernen',
        'templateedit-editformintro'          => '[[$1]] - Editor-Definition unter: [[Vorlage:$2/Editor]]',
        'templateedit-fieldundefined'         => 'Dieses Feld ist (noch) nicht gef&uuml;llt!',
        'templateedit-oldfieldstitle'         => 'Veraltete Felder',
        'templateedit-oldfield'               => 'Dieses Feld ist nicht (mehr) vorhanden oder nicht definiert!',
        'templateedit-articlesaved'           => 'Artikel gespeichert.',
        'templateedit-templateedited'         => 'Vorlage $1 editiert.',
);

TemplateEdit.alias.php [edit]

Place the following in $IP/extensions/TemplateEdit/TemplateEdit.alias.php:

<?php
 
$aliases = array();
 
/** English */
$aliases['en'] = array(
        'TemplateEdit' => array( 'Template Edit' )
);
 
/** German */
$aliases['de'] = array(
        'TemplateEdit' => array( 'Vorlagen Editor' )
);

TemplateParser.php [edit]

Place the following in $IP/extensions/TemplateEdit/TemplateParser.php:

<?php
//The template parser isn't a parser in the computer science way of putting it.
//Anyways it is doing a pretty good job on templates inside templates etc.
//
//Some problems are not solved yet:
//-nowiki, pre, includeonly, noinclude, onlyinclude, html-comments
//-the list of Magic Words is far from complete (see http://www.mediawiki.org/wiki/Help:Magic_words)
//-simple links with a maximum of one "|" work - pictures with more than on don't
 
class TemplateParser {
 
        //This function recursively divides the source into elements , which can either be
        //"UNPARSED" source, "IN" brackets "{{" or "OUT" brackets "}}"
        // $article is the source to be divided
        // $elements is the array to which those elements are appended
        protected static function tokenizeTemplates(&$elements,$article) {
                if($article=='') return;
                //find the first "{{" or "}}" if any exist
                $i1=strpos($article,'{{');
                $i2=strpos($article,'}}');
                if(($i1===FALSE)&&($i2===FALSE)) {
                        //nothing found - recursion ends.
                        $elements[]=Array('type'=>'UNPARSED','source'=>$article);
                        return;
                }
                $type='IN';
                $i=$i1;
                $source='{{';
                if($i2<$i1) {
                        $type='OUT';
                        $i=$i2;
                        $source='}}';
                }
                if($i1===FALSE) {
                        $i=$i2;
                        $type='OUT';
                        $source='}}';
                }
                if($i2===FALSE) {
                        $i=$i1;
                        $type='IN';
                        $source='{{';
                }
                //divide the article source and recursively call this function on both parts
                //TODO: shouldn't the second part be sufficient?
                $part1=substr($article,0,$i);
                TemplateParser::tokenizeTemplates($elements,$part1);
                $elements[]=Array('type'=>$type,'source'=>$source);
                $part2=substr($article,$i+2);
                TemplateParser::tokenizeTemplates($elements,$part2);
        }
 
        //Add a level field to all elements to later find matching closing brackets
        //Since we are only interested in templates, all outside of those get the type "TEXT"
        //and are ignored later on
        // $elements is the array to work on
        protected static function parseTemplateStructure(&$elements) {
        //Rücke den Code gedanklich ein und aus - wenn unterschiedliche Anzahl Error
        //Alles außerhalb wird plaintext
        $level=0;
        for($i=0;$i<count($elements);$i++) {
                if($elements[$i]["type"]=="OUT")
                        $level--;
                $elements[$i]["level"]=$level;
                if(($level==0)&&($elements[$i]["type"]=="UNPARSED"))
                        $elements[$i]["type"]="TEXT";
                if($elements[$i]["type"]=="IN")
                        $level++;
        }
        if($level!=0)
                //TODO: Language dependant
                //TODO: Proper error message inside mediawiki
                die('Number of "{{" and "}}" not equal! '.$level);
        }
 
        //Get rid of all magic words and all parser functions
        // $elements is the array to work on
        protected static function removeMagicWordsAndParserFunctions(&$elements) {
                //TODO: Get the list of Magic Words from MediaWiki
                $magicwords=Array("FULLPAGENAME","PAGENAME","BASEPAGENAME","ARTICLENAME");
                for($i=0;$i<count($elements);$i++)
                        if ($elements[$i]["type"]=="UNPARSED") {
                                if(in_array($elements[$i]["source"],$magicwords))
                                        $elements[$i]["type"]="MAGICWORD";
                                if(substr($elements[$i]["source"],0,1)=="#")
                                        $elements[$i]["type"]="PARSERFUNCTION";
                        }
        }
 
        //In order to use an explode on a template params, the "|" in the links have to be replaced
        //first and back later on. Since we already filtered out "{{" in the first step, we use it
        //for replace.
        // $elements is the array to work on
        protected static function explodeTemplates(&$elements) {
                for($i=0;$i<count($elements);$i++)
                        if (($elements[$i]["type"]=="UNPARSED")&&($elements[$i]["level"]>0)) {
                                $elements[$i]["type"]="PARSED";
                                //Replace "|" in Links by "{{"
                                $replaced=preg_replace(
                                        "%\[\[([^\]\|]*)\|([^\]\|]*)\]\]%",
                                        '[[$1{{$2]]',
                                        $elements[$i]["source"]
                                );
                                //Explode Template by "|"
                                $params=explode("|",$replaced);
                                for($j=1;$j<count($params);$j++) {
                                        //Replace "{{" in Links by "|"
                                        $params[$j]=preg_replace(
                                                "%\[\[([^\]\|]*){{([^\]\|]*)\]\]%",
                                                '[[$1|$2]]',
                                                trim($params[$j]));
                                        $paramsexplode=explode("=",$params[$j],2);
                                        if(count($paramsexplode)==2) {
                                                //Templates with parameter names
                                                $params[$j]=Array(
                                                        "name" =>trim($paramsexplode[0]),
                                                        "value"=>trim($paramsexplode[1])
                                                );
                                        } else {
                                                //Templates without parameter names
                                                $params[$j]=Array(
                                                        "name" =>$j,
                                                        "value"=>trim($paramsexplode[0])
                                                );
                                        }
                                }
                                if($elements[$i-1]['type']!='OUT') {
                                        $template=trim(array_shift($params));
                                        $elements[$i]["template"]=$template;
                                }
                                $elements[$i]["params"]=$params;
                        }
        }
 
        //Return an array of indexes in the elements, which mark the beginning of a template
        // $elements is the array to get the information from
        protected static function getTemplateList($elements) {
                $templateix=Array();
                for($i=0;$i<(count($elements)-1);$i++)
                        if(($elements[$i]["type"]=="IN")&&($elements[$i+1]["type"]=="PARSED"))
                                $templateix[]=$i+1;
                return $templateix;
        }
 
        //Return the index of the end of the template
        // $elements is the array to get the information from
        // $index is the index of the template begin
        protected static function getTemplateEnd($elements,$index) {
                $closing=-1;
                $level=$elements[$index]['level']-1;
                $i=$index;
                while(($i<count($elements))&&($closing==-1)) {
                        if(($elements[$i]['type']=='OUT')&&($elements[$i]['level']==$level))
                                $closing=$i;
                        $i++;
                };
                return $closing;
        }
 
        //Return the full template with all parameters including sub-templates.
        // $elements is the array to get the information from
        // $index is the index of the template begin
        protected static function getFullTemplate($elements,$index) {
                $closing=TemplateParser::getTemplateEnd($elements,$index);
                if($closing==-1) return;
 
                $result=$elements[$index]['params'];
                $append='';
                $i=$index+1;
                $baselevel=$elements[$index]['level'];
                while($i!=$closing) {
                        if(($elements[$i]['level']==$baselevel)&&($elements[$i]['type']=='PARSED')) {
                                $append.=$elements[$i]['params'][0]['value'];
                                $result[count($result)-1]['value'].=$append;
                                for($j=1;$j<count($elements[$i]['params']);$j++)
                                        $result[]=$elements[$i]['params'][$j];
                                $append='';
                        } else {
                                $append.=$elements[$i]['source'];
                        }
                        $i++;
                }
                if($append!='')
                        $result[count($result)-1]['value'].=$append;
 
                return Array('template'=>$elements[$index]['template'],'params'=>$result);
        }
 
        //Return the full template with all parameters including sub-templates.
        // $elements is the array to get the information from
        // $index is the index of the template begin
        protected static function getSource($elements,$begin,$end) {
                $result="";
                for($i=$begin;$i<$end;$i++)
                        $result.=$elements[$i]['source'];
                return($result);
        }
 
        //the public function to get the list of templates for the article's source
        public static function getTemplates($source) {
                $elements=Array();
                TemplateParser::tokenizeTemplates($elements,$source);
                TemplateParser::parseTemplateStructure($elements);
                TemplateParser::removeMagicWordsAndParserFunctions($elements);
                TemplateParser::explodeTemplates($elements);
                $templatelist=TemplateParser::getTemplateList($elements);
                $result=Array();
                for($i=0;$i<count($templatelist);$i++)
                        $result[]=Array(
                                "level"=>$elements[$templatelist[$i]]["level"],
                                "name"=>$elements[$templatelist[$i]]["template"]
                        );
                return $result;
        }
 
        //the public funtion to get a template with all params depending on soucr and index
        public static function getTemplateParts($source,$index) {
                $elements=Array();
                TemplateParser::tokenizeTemplates($elements,$source);
                TemplateParser::parseTemplateStructure($elements);
                TemplateParser::removeMagicWordsAndParserFunctions($elements);
                TemplateParser::explodeTemplates($elements);
                $templatelist=TemplateParser::getTemplateList($elements);
                $result=TemplateParser::getFullTemplate($elements,$templatelist[$index]);
                return $result;
        }
 
        //the public function to replace one template defined by index in the source
        public static function replaceTemplate($source,$index,$replace) {
                $elements=Array();
                TemplateParser::tokenizeTemplates($elements,$source);
                TemplateParser::parseTemplateStructure($elements);
                TemplateParser::removeMagicWordsAndParserFunctions($elements);
                TemplateParser::explodeTemplates($elements);
                $templatelist=TemplateParser::getTemplateList($elements);
                $closing=TemplateParser::getTemplateEnd($elements,$templatelist[$index]);
                $result=TemplateParser::getSource($elements,0,$templatelist[$index]);
                $result.=$replace;
                $result.=TemplateParser::getSource($elements,$closing,count($elements));
                return $result;
        }
 
}

SpecialTemplateEdit.php [edit]

Place the following in $IP/extensions/TemplateEdit/SpecialTemplateEdit.php:

<?php
 
if ( !defined( 'MEDIAWIKI' ) ) die();
 
class TemplateEdit extends SpecialPage {
 
        /**
         * Constructor
         */
        public function __construct() {
                parent::__construct( 'TemplateEdit' , 'edit' );
        }
 
        static public function addToAdminLinks( &$admin_links_tree ) {
                $general_section = $admin_links_tree->getSection( wfMsg( 'adminlinks_general' ) );
        $extensions_row = $general_section->getRow( 'extensions' );
                if ( is_null( $extensions_row ) ) {
                        $extensions_row = new ALRow( 'extensions' );
                        $general_section->addRow( $extensions_row );
                }
                $extensions_row->addItem( ALItem::newFromSpecialPage( 'TemplateEdit' ) );
                return true;
        }
 
        function execute( ) {
                global $wgUser, $wgOut, $wgRequest, $wgLang;
 
                $this->article=$wgRequest->getText('article');
                $this->articleprefix=$wgRequest->getText('articleprefix');
                $this->templatename=$wgRequest->getText('templatename');
                $this->template=$wgRequest->getText('template');
                $this->save=$wgRequest->getText('save');
                $this->user = $wgUser;
 
                $this->setHeaders();
 
                //Title valid
                $title=Title::newFromText($this->article);
                if($title!=null) {
                        if ( ! $title->userCan( 'edit' ) ) {
                                $wgOut->permissionRequired( 'edit' );
                                return;
                        }
                        $source="";
                        if($title!=null) {
                                $article=new Article($title);
                                if($title->exists()) {
                                        //Existing article
                                        $source=$article->getContent();
                                } elseif ($this->templatename!='') {
                                        //New article
                                        $source='{{'.$this->templatename.'}}';
                                        $article->doEdit( $source,wfMsg('templateedit-templatecreated',$this->templatename), null );
                                }
                        };
                        //No template selected
                        if($this->template=="") {
                                $this->showSelectTemplateForm($title,$source);
                                return;
                        } else {
                                if($this->save!="1") {
                                        //Edit Template
                                        $this->showEditForm($title,$source);
                                        return;
                                } else {
                                        //Save Template
                                        $this->showSavedMessage($title,$source,$article);
                                        return;
                                }
                        }
                }
 
                // if we're still here, show the starting form
                $this->showStartingForm();
        }
 
        function showStartingForm() {
                global  $wgOut;
                if ($this->templatename!="")
                        $wgOut->addWikiText(wfMsg('templateedit-createwithtemplate',$this->templatename));
                $wgOut->addHTML(
                        Xml::openElement( 'form', array( 'id' => 'templateedit', 'action' => $this->getTitle()->getFullUrl(), 'method' => 'post' ) ) .
                        Xml::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
                        Xml::hidden( 'templatename', $this->templatename ) .
                        Xml::tags( 'p', null , wfMsg('templateedit-showstartingform') ) .
                        Xml::input( 'article', 50, $this->articleprefix ) .
                        Xml::submitButton(wfMsg('templateedit-continue')) .
                        Xml::closeElement( 'form' )
                );
        }
 
        function showSelectTemplateForm($title,$source) {
                global $wgOut;
                if($source=="") die ('Something is wrong!');
                $templates=TemplateParser::getTemplates($source);
                $wgOut->addWikiText('[['.$title->getPrefixedText().']]');
                $wgOut->addHTML(
                        Xml::openElement( 'form', array( 'id' => 'templateedit', 'action' => $this->getTitle()->getFullUrl(), 'method' => 'post' ) ) .
                        Xml::hidden( 'title',  $this->getTitle()->getPrefixedText() ) .
                        Xml::hidden( 'article', $this->article ).
                        Xml::tags( 'p', null , wfMsg('templateedit-showselecttemplateform') )
                );
 
                for($i=0;$i<count($templates);$i++)
                        $wgOut->addHTML( Xml::radio( "template", "$i", $i==0 ,
                                Array('style'=>'margin-left:'.$templates[$i]["level"].'em;') ).$templates[$i]["name"]."<br />"
                        );
 
                $wgOut->addHTML(
                        Xml::submitButton(wfMsg('templateedit-continue')) .
                        Xml::closeElement( 'form' )
                );
        }
 
        function getTemplateDefinitions($template) {
                $this->deleteold=TRUE;
                $title=Title::newFromText(wfMsg('templateedit-templateeditortitle',$template));
                if(($title!=null)&&($title->exists())) {
                        $article=new Article($title);
                        $source=$article->getContent();
                        $sourceexplode=explode("|",$source);
                        $fields=Array();
                        for($i=0;$i<count($sourceexplode);$i++)
                                if(trim($sourceexplode[$i])!="")
                                        $fields[]=trim($sourceexplode[$i]);
                        $indexedFields=Array();
                        for($i=0;$i<count($fields);$i++) {
                                $explode=explode("=",$fields[$i],2);
                                if(count($explode)==1) $explode[]='TEXT!!!';
                                $params=explode("!",$explode[1],4);
                                if(count($params)<1) $params[]='TEXT';
                                if(count($params)<2) $params[]='';
                                if(count($params)<3) $params[]='';
                                if(count($params)<4) $params[]='';
                                $indexedfields[$explode[0]]=Array(
                                        'type'        => $params[0],
                                        'must'        => ($params[1]=='MUST'),
                                        'description' => $params[2],
                                        'picklist'    => $params[3],
                                );
                        }
                        return $indexedfields;
                }
                $this->deleteold=FALSE;
                return Array(wfMsg('templateedit-noeditor')=>Array('type'=>'TITLE','must'=>FALSE,'description'=>'','picklist'=>''));
        }
 
        function addInput($wgOut,$name,$def,$value,$style) {
                $techname="Field".str_replace(' ','',$name);
                if($def['type']=='TITLE') {
                        $wgOut->addHTML(
                                '<tr><td colspan="2" class="dunkel" style="border-bottom:1px solid gray;"><h3>'.$name.'</h3></td></tr>'
                        );
                        return;
                }
                $must='';
                if($def['must'])
                        $must='<span style="color:red;">'.wfMsg('templateedit-mustfield').'</span> ';
                $wgOut->addHTML(
                        '<tr><td style="border-bottom:1px solid gray;"><b>'.$name.':</b><br/> '
                        .$must.$def['description'].'</td><td style="border-bottom:1px solid gray;">'
                );
                if($def['type']=='PICK') {
                        $wgOut->addHTML(
                                Xml::openElement( 'select', array('name'=>$techname,'size'=>'1', 'style' => 'width: 95%;'.$style ) )
                        );
                        $picks=explode(';',$def['picklist']);
                        for($i=0;$i<count($picks);$i++) {
                                $selected=null;
                                if($picks[$i]==$value)
                                        $selected=Array( 'selected'=>'selected');
                                $wgOut->addHTML(
                                        Xml::tags('option', $selected,$picks[$i])
                                );
                        }
                        $wgOut->addHTML(
                                Xml::closeElement( 'select' )
                        );
                }
                if($def['type']=='TEXTAREA')
                        $wgOut->addHTML(
                                Xml::textarea( $techname, $value , 50, 5, array( 'style' => 'width: 95%;'.$style ) )
                        );
                if(($def['type']=='TEXT')||($def['type']=='LINK')||($def['type']=='NUMBER'))
                        $wgOut->addHTML(
                                Xml::input( $techname, 250, $value , array( 'style' => 'width: 95%;'.$style ) )
                        );
                if($def['type']=='OLD')
                        $wgOut->addHTML(
                                Xml::checklabel( wfMsg('templateedit-remove') , 'Remove'.$techname , 'Remove'.$techname , $this->deleteold ) .
                                Xml::input( $techname, 250, $value , array( 'style' => 'width: 95%; background-color:#ff7f7f;'.$style ) )
                        );
                $wgOut->addHTML('</td></tr>');
        }
 
        function showEditForm($title,$source) {
                global  $wgOut;
                if($source=="") die ('Something is wrong!');
                $templateparts=TemplateParser::getTemplateParts($source,$this->template);
                $definitions=$this->getTemplateDefinitions($templateparts['template']);
                $wgOut->addWikiText(wfMsg('templateedit-editformintro',$title->getPrefixedText(),$templateparts['template']));
                $wgOut->addHTML(
                        Xml::openElement( 'form', array( 'id' => 'templateedit', 'action' => $this->getTitle()->getFullUrl(), 'method' => 'post' ) ) .
                        Xml::hidden( 'title',  $this->getTitle()->getPrefixedText() ) .
                        Xml::hidden( 'article', $this->article ).
                        Xml::hidden( 'template', $this->template ).
                        Xml::hidden( 'save', "1" ).
                        Xml::tags( 'p', null , wfMsg('templateedit-showeditform') ) .
                        Xml::openElement('table', array('style' => 'border-collapse:collapse;') )
                );
                $indexedtp=Array();
                for($i=0;$i<count($templateparts['params']);$i++) {
                        $indexedtp[$templateparts['params'][$i]['name']]['value']=$templateparts['params'][$i]['value'];
                        $indexedtp[$templateparts['params'][$i]['name']]['used']=FALSE;
                }
                foreach($definitions as $name=>$def) {
                        if(isset($indexedtp[$name])) {
                                $value=$indexedtp[$name]['value'];
                                $indexedtp[$name]['used']=TRUE;
                                $background='';
                        } else {
                                $value='';
                                $def['description'].=' '.wfMsg('templateedit-fieldundefined');
                                $background='background-color:#ffff7f;';
                        }
                        $this->addInput($wgOut,$name,$def,$value,$background);
                };
                $def=Array('type'=>'TITLE','must'=>FALSE,'description'=>'','picklist'=>'');
                $this->addInput($wgOut,wfMsg('templateedit-oldfieldstitle'),$def,'','');
                foreach($indexedtp as $name=>$field)
                        if(!$field['used']) {
                        $def=Array('type'=>'OLD','must'=>FALSE,'description'=>wfMsg('templateedit-oldfield'),'picklist'=>'');
                        $this->addInput($wgOut,$name,$def,$field['value'],'');
                };
 
                $wgOut->addHTML(
                        Xml::closeElement( 'table' ) .
                        Xml::submitButton(wfMsg('templateedit-save')) .
                        Xml::closeElement( 'form' )
                );
        }
 
        function showSavedMessage($title,$source,$article) {
                global $wgOut,$wgRequest;
                if($source=="") die ('Something is wrong!');
                $templateparts=TemplateParser::getTemplateParts($source,$this->template);
                $definitions=$this->getTemplateDefinitions($templateparts['template']);
                $indexedtp=Array();
                for($i=0;$i<count($templateparts['params']);$i++) {
                        $indexedtp[$templateparts['params'][$i]['name']]['value']=$templateparts['params'][$i]['value'];
                        $indexedtp[$templateparts['params'][$i]['name']]['used']=FALSE;
                }
                foreach($definitions as $name=>$def) {
                        $techname="Field".str_replace(' ','',$name);
                        $definitions[$name]['value']=$wgRequest->getText($techname);
                        if(isset($indexedtp[$name]))
                                $indexedtp[$name]['used']=TRUE;
                }
                foreach($indexedtp as $name=>$field) {
                        $techname="Field".str_replace(' ','',$name);
                        if((!$field['used'])&&($wgRequest->getText('Remove'.$techname)!='1')) {
                                $definitions[$name]=Array(
                                        'type'=>'OLD','must'=>FALSE,'description'=>wfMsg('templateedit-oldfield'),'picklist'=>'',
                                        'value'=>$wgRequest->getText($techname)
                                );
                        }
                }
                $insert=$templateparts['template'];
                $i=1;
                foreach($definitions as $name=>$def) {
                        if($def['type']!='TITLE') {
                                if($name==$i)
                                        $insert.='|'.$def['value'];
                                else
                                        $insert.='|'.$name.'='.$def['value']."\n";
                                $i++;
                        }
                }
 
                $newsource=TemplateParser::replaceTemplate($source,$this->template,$insert);
                $article->doEdit( $newsource,wfMsg('templateedit-templateedited',$templateparts['template']), null );
                $wgOut->addWikiText('[['.$title->getPrefixedText().']]');
                $wgOut->addHTML(
                        Xml::tags( 'p', null , wfMsg('templateedit-articlesaved') )
                );
        }
 
 
}