'20170418', 'Author'=>'Peter Kay', 'contact'=>'pkay42@gmail.com', ); if (!isset($PkTemplate)) $PkTemplate=array(); /* Admins may easily change: $PkTemplate['addLinkByDefault']=false; SDV($HandleAuth['pkdotemplate'], 'admin'); // change permissions to admin(read/etc) include_once("$FarmD/cookbook/PkTemplate.php"); */ SDVA($PkTemplate, [ // User editable: // Set form default to add a new link to the new page on template page: 'addLinkByDefault' => true, // Change these only if you must: 'templateMarkup' => '(:PkTemplate:)', # case negotiable 'templateExpression' => '/\(:PkTemplate:\)(.*)/is', 'templateExpression2'=> '/(.*?)\(:PkTemplate:\)(.*)/is', #variable Expression: v vs t varName description 'variableExpression' => '/\(:pkt(var|text) (\w*) ?(.*?):\)/i' ]); // Need markup to run before any Includes Markup("PkTemplate", '<_begin', $PkTemplate['templateExpression'], 'PkTemplateMakeForm'); SDV($HandleActions['pkdotemplate'], 'PkImplementTemplate'); SDV($HandleAuth['pkdotemplate'], 'edit'); // creating new page is an edit /* Replace the rest of the page ($m[1]) with form for creating new items from template: * Because we require variable names to be alphanumeric, they should be valid "name" * attributes for a form. So we use the var names to create a form, ask up description * and return the whole thing to the default script page */ function PkTemplateMakeForm($m) { global $PkTemplate, $pagename; $pagename=ResolvePageName($pagename); $pageText=$m[1]; if ($PkTemplate['alreadyRun']) { return "\n----\n%red%$[Error: two templates in the page]%%\n----\n" .$pageText; } $PkTemplate['alreadyRun']=true; // Pull variable requests from page, then put them into a hash (allow multiple instances of each // var in the page; only use description of 1st entry) $tmpVarArray=array(); #'variableExpression' => '/\(:pkt(var|text) (\w*) ?(.*?):\)/' $numVars=preg_match_all($PkTemplate['variableExpression'], $pageText, $tmpVarArray); $templateVars=array(); // Fill hash with {varName} => {variable description} or // {textName} => {text area description} for ($i=0; $i<$numVars; $i++) { $key=$tmpVarArray[1][$i].$tmpVarArray[2][$i]; if (!isset($templateVars[$key])) if ($tmpVarArray[3][$i]) $templateVars[$key]=$tmpVarArray[3][$i]; else $templateVars[$key]=$tmpVarArray[2][$i]; // use variable name if no description } // Messages and instructions $out="\n<:vspace>\n(:messages:)\n" . "'''\$[Create a new page based on the template here {*\$FullName}]:'''\n\\\\\n". '[-$[If you want to edit the template, use the "edit" link above.]-]' . "\n<:vspace>\n"; // Form start $out .= '(:input form "{$PageUrl}":)(:input hidden action pkdotemplate:)'. "(:input hidden PkTemplate $pagename:)(:input hidden n $pagename:)\n"; // Group, new Pagename, and Author // (only table directives allow valign=top as of Jan 10 2017; otherwise I'd use || || || notation) $out .= "(:table:)\n(:cellnr:)\$[Group]:\n(:cell:)(:input text pkgroupname {\$Group} size=80:)\n"; $out .= "(:cellnr:)\$[New page name]:\n(:cell:)(:input text pknewpagename \"\" size=80 focus:)\n(:cellnr:)\$[Author]:\n(:cell:)(:input text author {\$Author} size=60:)\n(:cellnr colspan=2:) \n"; // Input line for each var // order should be as in the page? foreach ($templateVars as $varName => $varDescription) { if ($varName[0] == "t") // textName $out .= "(:cellnr:)$varDescription\n(:cell:)(:input textarea pkt$varName \"\" cols=80 rows=4:)\n"; else // varName $out .= "(:cellnr:)\n$varDescription\n(:cell:)(:input text pkt$varName \"\" size=80:)\n"; } $addLinkByDefault=""; if ($PkTemplate['addLinkByDefault']) $addLinkByDefault="checked=\"checked\""; // Submit and end form $out .= "(:cellnr:)(:input submit value=\"$[Create New Page]\":)\n(:cell:)(:input checkbox pkaddlink pkaddlink $addLinkByDefault \"$[Add link to created page?]\" :)\n(:tableend:)\n(:input end:)\n<:vspace>\n"; // Show the template: // First run page text through ReplaceOnEdit so the template looks like what a user editing the page would see $pageText=PPRA((array)$GLOBALS['ROEPatterns'], $pageText); $out .= "$[Template text:]\n----\n" . Keep("
$pageText
"); return $out; } function PkImplementTemplate($pagename, $auth='edit') { global $PkTemplate, $MessagesFmt, $Now; $pagename=ResolvePageName($pagename); // Get template name: $templatePageName=MakePageName($pagename, $_POST['PkTemplate']); if (!$templatePageName) Abort("$[Error: got lost trying to follow template path]: ".htmlspecialchars($_POST['PkTemplate'])); // Get new page name: $newPageName; if (preg_match('/[.\\/]/', $_POST['pknewpagename'])) { // if name of form GroupX.NewPage $newPageName=MakePageName($pagename, $_POST['pknewpagename']); } else { $newPageName=MakePageName($pagename, "{$_POST['pkgroupname']}.{$_POST['pknewpagename']}"); } if (!$newPageName) { Abort("$[Error: bad page name supplied.] " . htmlspecialchars($_POST['pkgroupname'])." / ".htmlspecialchars($_POST['pknewpagename'])); } // Are we going to add a link to the template page? $addLink=$_POST['pkaddlink']; Lock(2); // only one file writing at a time // Would be nice TODO: have javascript check if the pagename exists before posting if (PageExists($newPageName)) Abort("$[Error: that page already exists. No changes have been made.] $newPageName"); $emptyPage=RetrieveAuthPage($newPageName, $auth, true); if (!$emptyPage) Abort("$[Error: cannot open page for writing]"); $new=$emptyPage; $new['csum'] = $new["csum:$Now"] = "Created from template $templatePageName"; // Prepare template: $templatePage=RetrieveAuthPage($templatePageName, 'read', true, READPAGE_CURRENT); if (!$templatePage['text']) Abort('$[Error: could not load template]'); // Get everything after the (:PkTemplate:) call $new['text']=preg_replace($PkTemplate['templateExpression2'], '$2', $templatePage['text']); // Now swap out all variables! $new['text']=preg_replace_callback($PkTemplate['variableExpression'], # '/\(:pkt(var|text) (\w*) ?(.*?):\)/' function ($matches) { // Looking for pktvarname1, pkttextname1, pktvarname2, etc return $_POST["pkt{$matches[1]}{$matches[2]}"]; }, $new['text']); // Save page if (!UpdatePage($newPageName, $emptyPage, $new)) { Abort("\$[Error: write from template failed]"); } if ($addLink) { $templatePage=RetrieveAuthPage($templatePageName, $auth, false, 0); if ($templatePage) { $newTP=$templatePage; // Just slip the link in right before (:PkTemplate:): * [[Main.MyPage | My Page]] $newTP['text']=preg_replace($PkTemplate['templateExpression2'], "\$1* [[$newPageName | {$_POST['pknewpagename']}]]\n{$PkTemplate['templateMarkup']}\$2", $templatePage['text']); $newTP['csum']=$newTP["csum:$Now"]="Created Page $newPageName from template"; if (!UpdatePage($templatePageName, $templatePage, $newTP)) { // Two super rare failure cases; not going to bother translating $MessagesFmt[]="
WARNING: Your new page $newPageName has been created! But a link could not be added to the template page.
"; } } else { # no template page?! $MessagesFmt[]="
WARNING: Your new page $newPageName has been created! But the template page could not be updated with a link.
"; } } #if addLink unset($GLOBALS['PageExistsCache'][$newPageName]); // See http://www.pmwiki.org/wiki/PITS/01401 // Put a message at the top of the page - the (:message:) markup added earlier will pick it up // for the record, $PageStartFmt is not the way to go $MessagesFmt[]=MarkupToHTML($templatePage, "!\$[New page successfully created]: [[$newPageName]]"); Lock(0); $PkTemplate['alreadyRun']=false; // UpdatePage does some MarkupToHTML processing HandleBrowse($templatePageName); }