MWX/MakePage: Difference between revisions

From Woozle Writes Code
< MWX
Jump to navigation Jump to search
(New page: ==Overview== ''to be written'' ==Code== <php><?php /* NAME: SpecialMakePage PURPOSE: Special page for creating a new page from a form Other extensions can do this, but they don't make i...)
 
No edit summary
 
(26 intermediate revisions by 3 users not shown)
Line 1: Line 1:
==Overview==
[[category:MediaWiki extension]]
''to be written''
{{DEFAULTSORT:MakePage}}
==Code==
==About==
<php><?php
'''Special:MakePage''' (SMP) is a [[MediaWiki]] SpecialPage which can create a wiki page from a form submission, using a template to turn the form inputs into page title and content. It can also use other environmental conditions such as the username of the submitter and when the form was submitted.  
/*
NAME: SpecialMakePage
PURPOSE: Special page for creating a new page from a form
Other extensions can do this, but they don't make it at all easy
to base the title on variables which are substituted from fields on the form.
AUTHOR: Woozle Staddon
VERSION:
2007-11-23 (Wzl) Writing started
2007-11-24 (Wzl) More or less working; doesn't work with _POST data,
and I don't understand why not.
2007-11-29 (Wzl) Adding variable for defining new title name
2008-01-22 (Wzl) Put in some friendly debugging text for when title can't be created
2008-06-25 (Wzl) Added "!TIMESTAMP" internal variable, and framework for adding more internal variables
Future: If it ever turns out that we really want to be able to base these on the contents of a page,
I suggest a syntax like <<@page_name>>. The page would need to be parsed in some cases but possibly
not in others; perhaps <<@@page_name>> to indicate the page should be parsed?
2008-07-24 (Wzl) Minor tweak so it will work with MW v1.12
2008-09-29 (Wzl) - 0.4 - Made keys case-insensitive so it would work again. Don't know why this is suddenly a problem.
2009-02-11 (Wzl) clsStringTemplate is now in a separate php file
2009-02-13 (Wzl) $wgOptCP_SubstFinish "]" -> "$]" so links and other bracketed stuff don't confuse the var parser
2009-02-26 (Wzl) - 0.5 - "$objNewEdit->action = 'submit';" before "->showEditForm()" fixes MW 1.14 problem
*/
require_once('StringTemplate.php');


$wgSpecialPages['MakePage'] = 'SpecialMakePage'; # Let MediaWiki know about your new special page.
* '''source''': [https://gitlab.com/woozalia/Special-MakePage Git repository]
$wgExtensionCredits['other'][] = array(
* '''requires''': {{l/ferreteria}} libraries: 
        'name' => 'Special:MakePage',
** [[W3TPL]] may be useful for prototyping various views of the created pages (e.g. a listing of blog posts, with synopses)
        'description' => 'special page for making new pages using form data plus a template',
==How to use it==
        'author' => 'Woozle (Nick) Staddon',
Basic usage, then, involves creating two things:
'version' => '0.5 2009-02-26'
:'''1.''' an HTML form which includes certain fields that SMP needs, and which submits its contents to SMP
);
:* You can create form within a MediaWiki site by any number of means, including [[w3tpl]], but it doesn't have to be on the same site.
:* In theory, you don't even have to have an actual form; you could use code to POST form data from an application.
:* Either way, you have to be logged in as a user with the ability to create new pages wherever the form has been told to create them.
:'''2.''' a template page that defines how the form data should be formatted in the resulting page


// Options which can be overridden in LocalSettings:
To use it in a MediaWiki installation, save the extension in MediaWiki's <code>extensions</code> folder and include this in <code>LocalSettings.php</code>:
// -- these strings indicate the start and end of a template variable name
wfLoadExtension( 'MakePage' );
/* old defaults
$wgOptCP_SubstStart = '<<';
$wgOptCP_SubstFinish = '>>';
*/
$wgOptCP_SubstStart = '[$';
$wgOptCP_SubstFinish = '$]';


function wfSpecialMakePage() {
(I think the necessary libraries are now required automatically, but you do need to install {{l/ferreteria}} and require <code>ferreteria/start.php</code>.)
// This registers the page's class. I think.
global $wgRequest;


$app = new SpecialMakePage($wgRequest);
==Example Sites==
* I use it on Issuepedia for [[issuepedia:Issuepedia:Link Filing|filing links]]:
** [[issuepedia:Issuepedia:Forms/v3/news/entry|The entry form]] is built using [[w3tpl]] tags.
** MakePage uses [[issuepedia:Issuepedia:Forms/v3/news/template|this template]] to render the form's output as a page.
* I use it on the HypertWiki for [[htwiki:User:Woozle/blog|blogging]]:
** [[htwiki:HypertWiki:Forms/blog/post|The entry form]] is built using [[w3tpl]] tags.
** MakePage uses [[htwiki:project:Forms/handling/blog/post|this template]] to render the form's output as a page.
==How it works==
SMP receives the input of any form POSTed to it and takes the following actions:
# A title is generated according to the value received in !TITLETPLT. Special variables (see below) may be used in this string.
# The template specified by !TPLTPAGE (and !TPLTSTART and !TPLTSTOP) is read, and variables are replaced by POSTed values.
# MediaWiki is requested to start editing a new page (titled according to #1), and the results of #2 are submitted as the possible contents.
#* By default, the new page is not yet saved; the user needs to do this. This is to give the user a chance to review the results before saving.
#* In the future, I may add an option to create the page immediately. I may also want to give forms the ability to create pages that cannot be edited directly by their creators, but can only be edited via forms. (This may be necessary, for example, in order to allow users to create and edit pages that access protected functions in w3tpl without themselves being able to modify the code that accesses those functions, which would be a significant security hole.)
==Special variables==
MakePage will look for the following variables in the POST data:
* '''!TIMEFMT''' is the format MakePage will use for setting the ?TIMESTAMP special variable
* '''!TITLETPLT''' is the template for generating the title of the page to be created
* '''!TPLTPAGE''' is the title of the page from on the creation template may be found
* '''!TPLTTEXT''' is the text to use for the template


$app->doCreate();
MakePage will provide a value for the following variables, if used:
}
* '''@TIMESTAMP''' is the date/time at which the form was submitted, formatted as a string according to !TIMEFMT. It is set by MakePage (i.e. don't set it in the form data).
** This is useful for time-stamping blog entries.
* '''@EDITUSER''' is the login-name of the user submitting the form


require_once( $wgScriptPath.'includes/SpecialPage.php' );
These are being replaced by !TPLTTEXT:
require_once( $wgScriptPath.'includes/EditPage.php' );
* '''!TPLTSTART''' defines where in the template page to start reading the actual template
** This is so you can make notes before and after without having the notes included in every page generated. To do: a proper comment syntax that doesn't conflict with HTML comments.
* '''!TPLTSTOP''' defines where in the template page to stop reading the actual template (see !TPLTSTART).


class SpecialMakePage extends SpecialPage {
==Pages==
  public function __construct() {
* [[/history]]
global $wgMessageCache;
 
SpecialPage::SpecialPage( 'MakePage','edit' );
$this->includable( true );
        $wgMessageCache->addMessage('makepage', 'Make new pages from form data');
  }
  public function doCreate() {
global $wgRequest, $wgOut, $wgTitle;
global $wgOptCP_SubstStart;
global $wgOptCP_SubstFinish;
global $wgErrorText;
global $wxgDebug;
 
$this->setHeaders();
// $in_linkdate = $wgRequest->getText('date'); // link's date string
//$in_newtitle = $wgRequest->getText('!TITLE'); // title for new/modified page
$strNewTitle = $wgRequest->getText('!TITLETPLT'); // template for new page's title
$in_tpltpg = $wgRequest->getText('!TPLTPAGE'); // page to use as a template
$in_tplttxt = $wgRequest->getText('!TPLTTEXT'); // text to use as a template
$strDataStart = $wgRequest->getText('!TPLTSTART'); // optional starting marker
$strDataStop = $wgRequest->getText('!TPLTSTOP'); // optional stopping marker
$referer = $_SERVER['HTTP_REFERER']; // name of page which sent the form data
// $strNewTitle = $in_linkdate.' '.$in_newtitle;
// $strNewTitleTest = '<<date>> <<pagetitle>>'; // debug
// $in_NewTitle = $wgRequest->getText('tplttext'); // text to use as a template
 
// get the text to be used as a template:
if ($in_tpltpg) {
// if it's a page, load that (overrules direct specification):
$objTplt = Title::newFromText($in_tpltpg);
$objArtcl = new Article($objTplt);
$strNewText = $objArtcl->getContent();
} else {
$strNewText = $in_tplttxt;
}
// truncate before/after markers, if any:
if ($strDataStop != '') {
$posSt = strpos ( $strNewText, $strDataStop );
if ($posSt !== FALSE) {
$strNewText = substr($strNewText,0,$posSt);
}
}
if ($strDataStart != '') {
$posSt = strpos ( $strNewText, $strDataStart );
if ($posSt !== FALSE) {
$strNewText = substr($strNewText,$posSt+strlen($strDataStart));
}
}
 
// do variable swapout:
$objTplt = new clsStringTemplate_MWRequest($wgOptCP_SubstStart,$wgOptCP_SubstFinish,$wgOptCP_SubstSetVal);
// calculate contents for new page
$objTplt->Value = $strNewText;
$strNewText = $objTplt->Replace();
/*
$wgOut->AddWikiText('<br>TEXT REPLACEMENT:');
$wgOut->AddWikiText($wxgDebug);
$wxgDebug = '';
*/
// calculate title for new page
$strOldTitle = $strNewTitle;
$objTplt->Value = $strOldTitle;
$strNewTitle = $objTplt->Replace();
/*
$wgOut->AddWikiText("\n* START: [$wgOptCP_SubstStart] : STOP: [$wgOptCP_SubstFinish]");
$wgOut->AddWikiText("\n* TITLE REPLACEMENT [$strOldTitle]->[$strNewTitle]:");
$wgOut->AddWikiText($wxgDebug);
$wxgDebug = '';
/**/
$wgOut->setPageTitle( $strNewTitle );
/*
2008-01-22 For future reference: we might want to just remove any characters not found in $wgLegalTitleChars (=Title::legalChars())
Sometimes CRs or TABs get pasted invisibly into the title, causing mysterious inability to create the page.
*/
$objNewTitle = Title::newFromText( $strNewTitle );
 
/*
// Debugging:
$wgOut->AddWikiText("GET DATA:");
foreach ($_GET AS $key => $value) {
$wgOut->AddWikiText("'''$key''': $value<br>");
}
 
$wgOut->AddWikiText("POST DATA:");
foreach ($_POST AS $key => $value) {
$wgOut->AddWikiText("'''$key''': $value<br>");
}
$wgOut->AddWikiText("--END--");
/**/
 
$doPreview = true; // always preview, for now
if ($doPreview) {
if (is_object($objNewTitle)) {
$objNewArticle = new Article($objNewTitle);
$objNewArticle->mContent = $strNewText;
$objNewEdit = new EditOtherPage($objNewArticle);
$strNewTitle_check = $objNewEdit->mTitle->getPrefixedText();
// $strNewTitle_check = $objNewTitle->getPrefixedText();
// $strNewTitle_check = $objNewArticle->mTitle->getPrefixedText();
$wgOut->AddWikiText("'''New Title''': [[$strNewTitle_check]]<br>'''Template''': [[$in_tpltpg]]<br>");
$wgOut->AddWikiText("'''Preview''': <hr>\n$strNewText<hr>");
// $wgOut->AddHTML($objNewEdit->getPreviewText());
$objNewEdit->textbox1 = $strNewText;
$objNewEdit->preview = true;
// $objNewEdit->edit();
$wgOut->AddWikiText("'''Make final changes to the text here, and save to create the page:'''");
$wgTitle = $objNewTitle; // make the form post to the page we want to create
$objNewEdit->action = 'submit';
$objNewEdit->showEditForm('new page from form at '.$referer);
} else {
$txtOut = 'There seems to be a problem with the title: [['.$strNewTitle.']]';
if ($wgErrorText) {
$txtOut .= ': ' . $wgErrorText;
}
$txtOut .= "\n\n".$wxgDebug;
$wgOut->AddWikiText($txtOut);
}
} else {
$objNewArticle->doEdit( $strNewText, 'new page from form at '.$referer, EDIT_NEW );
}
$wgOut->returnToMain( false );
  }
}
 
class EditOtherPage extends EditPage {
function EditOtherPage( $article ) {
$this->mArticle =& $article;
$this->mTitle =& $article->mTitle;
 
# Placeholders for text injection by hooks (empty per default)
$this->editFormPageTop =
$this->editFormTextTop =
$this->editFormTextAfterWarn =
$this->editFormTextAfterTools =
$this->editFormTextBottom = "";
}
/* private function getContent() {
// content already loaded by SetParams, so do nothing
}
function initialiseForm() {
// overrides parent
$this->edittime = $this->mArticle->getTimestamp();
$this->textbox1 = $this->getContent();
if ( !$this->mArticle->exists() && $this->mArticle->mTitle->getNamespace() == NS_MEDIAWIKI )
$this->textbox1 = wfMsgWeirdKey( $this->mArticle->mTitle->getText() ) ;
wfProxyCheck();
}
*/
function showEditForm($iSummary='') {
if ($iSummary) {
$this->summary = $iSummary;
}
parent::showEditForm();
}
}
 
class clsStringTemplate_array extends clsStringTemplate {
// This version can be used if the values are in an associative array
public $List;
 
protected function GetValue($iName) {
return $this->List[$iName];
}
}
 
class clsStringTemplate_MWRequest extends clsStringTemplate {
// This version is for $wgRequest in MediaWiki code
private $Keys;
 
function __construct($iStartMark, $iFinishMark) {
parent::__construct($iStartMark, $iFinishMark);
foreach ($_POST AS $key => $value) {
$strKey = strtolower($key);
$this->Keys[$strKey] = $key;
}
}
protected function GetValue($iName) {
global $wgRequest, $wxgDebug;
 
$wxgDebug .= '* ['.$iName.'] = ';
switch ($iName) {
  case '!TIMESTAMP':
$strFmt = $this->GetValue('!TIMEFMT');
//$strFmt = $wgRequest->getText('!TIMEFMT');
if ($strFmt == '') {
$strNow = 'must specify !TIMEFMT';
} else {
$strNow = date($strFmt);
}
$strOut = $strNow;
break;
  default:
// $strVal = $wgRequest->getText($iName);
// if ($strVal == '') {
$strName = strtolower($iName);
$strKey = $this->Keys[$strName];
$strVal = $_POST[$strKey];
// }
$strOut = $strVal;
break;
}
$wxgDebug .= '['.$strOut.']';
return $strOut;
}
}</php>

Latest revision as of 16:57, 18 April 2022


About

Special:MakePage (SMP) is a MediaWiki SpecialPage which can create a wiki page from a form submission, using a template to turn the form inputs into page title and content. It can also use other environmental conditions such as the username of the submitter and when the form was submitted.

  • source: Git repository
  • requires: Ferreteria libraries:
    • W3TPL may be useful for prototyping various views of the created pages (e.g. a listing of blog posts, with synopses)

How to use it

Basic usage, then, involves creating two things:

1. an HTML form which includes certain fields that SMP needs, and which submits its contents to SMP
  • You can create form within a MediaWiki site by any number of means, including w3tpl, but it doesn't have to be on the same site.
  • In theory, you don't even have to have an actual form; you could use code to POST form data from an application.
  • Either way, you have to be logged in as a user with the ability to create new pages wherever the form has been told to create them.
2. a template page that defines how the form data should be formatted in the resulting page

To use it in a MediaWiki installation, save the extension in MediaWiki's extensions folder and include this in LocalSettings.php:

wfLoadExtension( 'MakePage' );

(I think the necessary libraries are now required automatically, but you do need to install Ferreteria and require ferreteria/start.php.)

Example Sites

How it works

SMP receives the input of any form POSTed to it and takes the following actions:

  1. A title is generated according to the value received in !TITLETPLT. Special variables (see below) may be used in this string.
  2. The template specified by !TPLTPAGE (and !TPLTSTART and !TPLTSTOP) is read, and variables are replaced by POSTed values.
  3. MediaWiki is requested to start editing a new page (titled according to #1), and the results of #2 are submitted as the possible contents.
    • By default, the new page is not yet saved; the user needs to do this. This is to give the user a chance to review the results before saving.
    • In the future, I may add an option to create the page immediately. I may also want to give forms the ability to create pages that cannot be edited directly by their creators, but can only be edited via forms. (This may be necessary, for example, in order to allow users to create and edit pages that access protected functions in w3tpl without themselves being able to modify the code that accesses those functions, which would be a significant security hole.)

Special variables

MakePage will look for the following variables in the POST data:

  • !TIMEFMT is the format MakePage will use for setting the ?TIMESTAMP special variable
  • !TITLETPLT is the template for generating the title of the page to be created
  • !TPLTPAGE is the title of the page from on the creation template may be found
  • !TPLTTEXT is the text to use for the template

MakePage will provide a value for the following variables, if used:

  • @TIMESTAMP is the date/time at which the form was submitted, formatted as a string according to !TIMEFMT. It is set by MakePage (i.e. don't set it in the form data).
    • This is useful for time-stamping blog entries.
  • @EDITUSER is the login-name of the user submitting the form

These are being replaced by !TPLTTEXT:

  • !TPLTSTART defines where in the template page to start reading the actual template
    • This is so you can make notes before and after without having the notes included in every page generated. To do: a proper comment syntax that doesn't conflict with HTML comments.
  • !TPLTSTOP defines where in the template page to stop reading the actual template (see !TPLTSTART).

Pages