aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpetko <petko@524c5546-5005-0410-9a3e-e25e191bd360>2024-08-21 06:59:56 +0000
committerpetko <petko@524c5546-5005-0410-9a3e-e25e191bd360>2024-08-21 06:59:56 +0000
commit574209a000543025023494bae0afff5f53c752e9 (patch)
tree3fa26e7b1056d88b29419556223b3f496b4e22a8
parent016ccca923dc19207a4e4bae707c97e90c4caeb9 (diff)
downloadpmwiki.svn-574209a000543025023494bae0afff5f53c752e9.tar.bz2
Documentation update.
git-svn-id: svn://pmwiki.org/pmwiki/trunk@4795 524c5546-5005-0410-9a3e-e25e191bd360
-rw-r--r--wikilib.d/PmWiki.ChangeLog8
-rw-r--r--wikilib.d/PmWiki.CustomMarkup12
-rw-r--r--wikilib.d/PmWiki.Functions10
-rw-r--r--wikilib.d/PmWiki.PagelistVariables10
4 files changed, 20 insertions, 20 deletions
diff --git a/wikilib.d/PmWiki.ChangeLog b/wikilib.d/PmWiki.ChangeLog
index 3b7654e9..01c38a49 100644
--- a/wikilib.d/PmWiki.ChangeLog
+++ b/wikilib.d/PmWiki.ChangeLog
@@ -1,9 +1,9 @@
version=pmwiki-2.3.36 ordered=1 urlencoded=1
author=Petko
charset=UTF-8
-csum= (+8)
+csum=Anchors remove name="" attr; Meta Content-type moved early (+97)
name=PmWiki.ChangeLog
-rev=1891
+rev=1892
targets=Cookbook.RecentChanges,PmWiki.MailingLists,PmWiki.LayoutVariables,Cookbook.InputStar,PmWiki.BasicVariables,PmWiki.EditVariables,PmWiki.LinkVariables,PITS.01511,PmWiki.OtherVariables,Cookbook.DragDropMultiUpload,PmWiki.UploadVariables,PITS.01510,PITS.01507,PITS.01502,PITS.01499,PITS.01498,PmWiki.WikiStyles,PITS.01497,Cookbook.DarkColorScheme,Cookbook.PmSyntax-Talk,PmWiki.Notify,PITS.01431,PITS.01495,PITS.01493,PmWiki.PagelistVariables,PITS.01494,Cookbook.FuseEdit,PmWiki.SecurityVariables,PITS.01488,PITS.01489,Cookbook.SectionEdit,PITS.01486,PITS.01297,PITS.01485,Cookbook.EditHelp,PITS.01484,PITS.01208,PITS.01483,PITS.01480,PmWiki.PageVariables,PITS.01478,PITS.01477,Cookbook.PmSyntax,Cookbook.CustomSyntax,PITS.01418,PITS.00447,PITS.01475,PITS.00908,PITS.01095,PmWiki.ChangeLogArchive
-text=(:Summary: Log of changes made to PmWiki by [[Release(Notes)]]:)\%0aSee [[Cookbook:RecentChanges | the cookbook recent changes page]] for additional updates and activity by other developers, or join the [[PmWiki (/) mailing lists]] to discuss feature development with us.%0a%0a(:Prerelease:Changes made to the [[PmWiki:Subversion | subversion pre-release]] of PmWiki. You can get \%0a[[https://www.pmwiki.org/pub/pmwiki-devel/pmwiki-latest-svn.zip|a full ZIP archive]] of the nightly version, or \%0a[[https://www.pmwiki.org/pub/pmwiki-devel/pmwiki-nightly.zip|a partial export]] with only the files changed since {$Version}.:)\%0a{$:xPrerelease}%0a%0a(:comment PosArgs and $MessagesFmt were released in 2.3.34 but are undocumented and may change, so I'll announce about them in a future version:)%0a* Add helper function PosArgs($args, $posnames).%0a* Refactor $MessagesFmt to allow nested arrays with keys and %25pmhlt%25 [@(:messages key=a,b:)@]%25%25 that can be set from recipes.%0a* Responsive skin: cache SkinElements pages.%0a* Update for PHP 8.%0a* Add helper function PRI() "PmWiki Recursive Implode".%0a* pmwiki-utils.js add "draggable".%0a* Add PageVariable %25pmhlt%25[@{$GroupHomePageUrl}@].%0a* $EnableSortable, $EnableSimpleTableRowspan enabled by default.%0a* PmSyntax update for $EnableSimpleTableRowspan and for Cookbook:InputStar; fix line-height for some skin configurations.%0a* Add $EnableCommonEnhancements, update docs/sample-config.php, remove from sample-config.php $EnableNotSavedWarning which was enabled in 2.3.0.%0a* Add $EnableObfuscateEmails, $EnablePreserveLineBreaks.%0a* Add $EnableUrlApprove, $EnablePmForm, $EnableCreole, $EnableRefCount, $EnableFeeds (PITS:01511).%0a* %25pmhlt%25[@(:input e_minorcheckbox:)@]%25%25 to include label and title per $EnableMergeLastMinorEdit, update Site.EditForm, XLPage.%0a[[#svn-revision-4790]]%0a* Update documentation.%0a%0a%0a!!! Version 2.3.36 (2024-08-07) [[#v2336]]%0a* Add $EnableUploadDrop based on Cookbook:DragDropMultiUpload.%0a* Add $TROEPatterns.%0a* Update for PHP 8 (PITS:01510)%0a* Store a history entry when a page is deleted.%0a* Update documentation.%0a%0a!!! Version 2.3.35 (2024-07-07) [[#v2335]]%0a* PmSyntax [@(:comment ...:)@] add required space; add [@(:input defaults ...:)@] (with "s"). %25item pmhlt%25%0a* Enable highlighted source with ?action=source&highlight=1.%0a* Update default sidebar, https links, PITS and Mailing lists in conditional.%0a* Remove upload extensions "svg", "svgz", "htm", "html", "css", "swf", "fla", "epub", and files with no extension. Fix mime types for "wmf", "psd".%0a* Fix page title could accidentally include raw HTML.%0a* Update documentation.%0a%0a!!! Version 2.3.34 (2024-05-27) [[#v2334]]%0a* Delete wikilib.d/PmWiki.PerGroupCustomizations (unused redirect), content moved to GroupCustomizations 14 years ago.%0a* RecipeCheck remove table width attribute (suggested by Simon).%0a* Add %25pmhlt%25[@(:if action browse,edit:)@] conditional.%0a* $GUIButtons remove invalid elements (warning reported by Simon).%0a* phpdiff.php fix for PHP 8 when saving new pages (reported by Simon).%0a* Responsive skin: remove old CSS declarations like @-moz-keyframes (PITS:01507).%0a* Add upload extension 'm4a'.%0a* Update documentation.%0a%0a!!! Version 2.3.33 (2024-04-21) [[#v2333]]%0a* $EnablePreviewChanges to show "%25diffadd%25No changes%25%25" if there are no changes.%0a* PmSyntax add rules for colored pagenames and URLs inside bracket links.%0a* Responsive skin hide dropdown icons from printing.%0a* Fix some cases with conditional markup and markup expressions where an empty code could be evaluated (suggested by Goodguy00).%0a* Add $HTMLTitleFmt (PITS:01502).%0a* Cache auth conditional results for %25pmhlt%25[@(:if auth level:)@].%0a* Update blocklist.php for PHP 8, reported by Foster Schucker.%0a* Update documentation.%0a%0a!!! Version 2.3.32 (2024-03-24) [[#v2332]]%0a* Dark theme: add toggleImages(), add $ImgDarkSuffix, $FmtV['$PathUpload']. Restore light styles and pictures for printing.%0a* Responsive skin: white background when printing, move dark toggle label styles into skin.css.%0a* PmSyntax: only apply dark theme colors on screen (not print).%0a* Add upload extensions and image extension patterns AVIF, AVIFS.%0a* Lock AllRecentChanges in case of concurrent uploads.%0a* FileSizeCompact() allow for base 1000 (PITS:01499).%0a* Update documentation.%0a%0a!!! Version 2.3.31 (2024-02-23) [[#v2331]]%0a* Add $EnableDarkThemeToggle, enable 3-way theme toggle, "Light", "Dark" and "Auto", add annotation tooltip showing the current theme on tap and on mouse over.%0a* Refactor config data passed to pmwiki-utils.php, refactor dark toggle functions into a separate script. %0a* Responsive skin add body attributes for group and page name, update dark theme, enable auto theme (browser preferences) by default.%0a* PmSyntax improve dark theme thanks to a script by Said Achmiz; expose color properties for reuse.%0a* Refactor redirect quiet (PITS:01498).%0a* Page attributes passwords form: allow for +addition and -removal of passwords, users, groups.%0a* Allow $EditTemplatesFmt entries to apply to specific pages with name= specification (suggested by Simon).%0a* Forms add attribute "form".%0a* Refactor $PostConfig to allow called functions to update it.%0a* Update RecipeCheck to also list skins, suggested by Simon.%0a* Refactor PrintFmt, add $EnablePrePrintFmt.%0a* [[WikiStyles]] add 'columns'.%0a* When Highlight.js is enabled, Vardoc links will be the same color as variables in highlighted code blocks.%0a* Refactor $EnableUploadVersions.%0a* Update documentation.%0a%0a!!! Version 2.3.30 (2024-01-22) [[#v2330]]%0a* Add prototype for dark theme toggle. See PITS:01497 and Cookbook:DarkColorScheme.%0a** PmWiki-responsive skin converted CSS colors to variables, added dark theme styles.%0a** Add skins/pmwiki/pmwiki-32.svg, enable default for $PageLogoUrl.%0a** PmSyntax added dark theme styles.%0a* $EnableUploadMimeMatch with Fileinfo not enabled to deny uploads.%0a* upload.php fix warning for PHP 8.%0a* RecipeCheck use https, suggested by Simon.%0a* PrintDiff() add $since argument.%0a* Add $EnableRedirectQuiet = 2. Prevent infinite redirect loops.%0a* Fix Attach: links with escaped path and filename.%0a* Improved readability for inline diffs in page history.%0a* Forms enable input e_author not only for action=edit, fix unquoted positional form action URL.%0a* Update documentation.%0a%0a!!! Version 2.3.29 (2023-12-18) [[#v2329]]%0a* Fix urlapprove.php for PHP 8.2. %0a* PmSyntax textarea remove styles for width, height (Cookbook:PmSyntax-Talk), allow for fractional dimensions of the highlighted area.%0a* $MarkupDirectiveFunctions allow dashes in attribute names.%0a* Update documentation.%0a%0a!!! Version 2.3.28 (2023-11-27) [[#v2328]]%0a* Add input ''month'' and ''color'' fields.%0a* Add $NotifyRelatedTrailFmt.%0a* Reverse simpletable row backgrounds when there is a thead element.%0a* Fix pmwiki-utils.js when window.localStorage is disabled.%0a* UrlApprovals allow https: URLs if the http: URL for the same domain has been approved (PITS:01431).%0a* Update documentation.%0a%0a!!! Version 2.3.27 (2023-10-23) [[#v2327]]%0a* When merging last edit, if there is no change summary, reuse the last one. %0a* Keep unknown date/time formats for undefined timezone (PITS:01495).%0a* DiffRenderSource() fix for PHP 8, keep ins/del tags on the same line.%0a* The ".diffmarkup" element now has the style "white-space: pre-wrap".%0a* Add new keyword shortcuts Ctrl+B (bold), Ctrl+I (italic), Ctrl+K (link/unlink).%0a* Update documentation.%0a%0a%0a!!! Version 2.3.26 (2023-09-28) [[#v2326]]%0a* Add configurable $InputLabelFmt snippet (PITS:01493).%0a* Add configurable $TrailFmt snippets.%0a* Add $EnableSearchAtLeastOneTerm, default disabled.%0a* Unset upload extensions if size for the extension is set to 0.%0a* Update feeds.php for PHP 8.2 (PITS:01494).%0a* Update documentation.%0a%0a%0a!!! Version 2.3.25 (2023-07-29) [[#v2325]]%0a* Updates for PHP 8.2.%0a* Fix pagelist when 2+ directives on the same line, reported by Simon.%0a* Fix possible bug with internal group(header|footer) directives caused by PRR().%0a* Update documentation.%0a%0a%0a!!! Version 2.3.24 (2023-06-06) [[#v2324]]%0a* Add $EnableUploadMimeMatch.%0a* Add $EnableMergeLastMinorEdit, edit functions MergeLastMinorEdit (based on Cookbook:FuseEdit), SaveChangeSummary (refactored out of HandleEdit).%0a* Fix LogoutCookies() doesn't use a $pagename argument.%0a* PmForm add condition 'validemail' for use in template require.%0a* Add $PmCryptAlgo, pmcrypt() to call password_verify() if it exists. %0a* Refactor HandleDownload() split ServeDownload($filepath, $upname).%0a* Add InsertEditFunction($newfn, $where='%3cPostPage').%0a* Add $AuthFormRespCode.%0a* Add $EnableDownloadRanges, default 1.%0a* When the token is expired, reopen edit form rather than abort.%0a* LocalTimes add $EnableRCListLastEdit.%0a* Update documentation.%0a%0a!!! Version 2.3.23 (2023-05-03) [[#v2323]]%0a* Refactor pmtoken() to use session tokens, enable for core actions.%0a* Add %25pmhlt%25[@(:input pmtoken:)@] helper.%0a* PmForm add $PmFormEnablePmToken.%0a* Refactor @@HandleLogoutA()@@ split @@LogoutCookies()@@. %0a* Fix PRCB() for PHP %3c 7.4.%0a* Update documentation.%0a%0a!!! Version 2.3.22 (2023-04-06) [[#v2322]]%0a* Add scripts/pmform.php, Site.PmFormTemplates.%0a* FmtDateTimeZ() can now accept Unix timestamps.%0a* Pagelists fix bug with multiple category=+A,+B entries.%0a* Update for PHP 8.1 (PITS:01488).%0a* MarkupDirectiveFunctions will now cast numeric arguments to floats.%0a* Prevent errors in custom PageVariables from generating internal server errors (PITS:01489).%0a* Improve inline diff for rare cases (end of page).%0a* Forms/buttons with @@data-pmconfirm="Question"@@ will ask the question before they are submitted.%0a* Update documentation.%0a%0a%0a!!! Version 2.3.21 (2023-03-06) [[#v2321]]%0a* Add $IsPmArchive, $PmArchiveDir.%0a* Sortable tables with %3ctime datetime=""> elements can be sorted by the datetime attribute. Fix for tables with preexisting %3cthead> element.%0a* Updates for PHP8.%0a* Add CSV upload extension.%0a* LocalTimes add mode=3 to show old dates as MM'YY.%0a* Fix bug with multiline $MarkupDirectiveFunctions, reported by Antti Tikanm&auml;ki.%0a* Add $EnableCopyCode and Copy code button to %3cpre> blocks, suggested by Alex Dor&eacute;.%0a* Update PmTOC to work better with Cookbook:SectionEdit.%0a* Update documentation.%0a%0a!!! Version 2.3.20 (2023-02-12) [[#v2320]]%0a* Fix undefined variable warning, reported by Gregor Klari&ccaron;.%0a%0a!!! Version 2.3.19 (2023-02-11) [[#v2319]]%0a* Only set cookie params if headers not sent. %0a* Update for PHP8.2, reported by Dfaure. PageVar() update for PHP 8.%0a* Add variable $DiffPrepareInlineFunction.%0a* PageListCache() remove unused global $PageIndexFile.%0a* Add configurable $LocalCSSDir, $LocalCSSDirUrl.%0a* DownloadUrl() add $FmtV['$LinkDownload'] with current or future download link.%0a* Add pm_recode() helper function (based on PageStore::recodefn), check for more transcode options.%0a* HandleBrowse() add $FmtV['$PageSourceText'].%0a* Add helper function KeepBlock().%0a* Add $FarmPubDirPrefix, pm_servefile(), $ServeFileExts.%0a* Update documentation.%0a%0a!!! Version 2.3.18 (2023-01-15) [[#v2318]]%0a* Refactor scripts/utils.php, add pm_json_encode() (PITS:01486).%0a* EditAutoText() fix for lines ending with multiple backslashes.%0a* PmSyntax optimize/refactor for large pages (cont.), fix inline escaped texts could ignore line markups, add EnableStopwatch.%0a* Notify fix typo in regular expression.%0a* {-Add $EnableUploadVersions >=10 to rename base.ext to base-1.ext, base-2.ext,...-} ''Redesigned in 2.3.31''%0a* CondAuth() fix bug with global $AuthList.%0a* Add helper function PRCB() for simpler preg_replace_callback passing variables.%0a* Update scripts/refcount.php for PHP 8, reported by George Murray.%0a* Add PageVariable $PageLogoUrl (PITS:01297).%0a* Update documentation.%0a%0a!!! Version 2.3.17 (2022-12-17) [[#v2317]]%0a* WikiStyles trim class names (PITS:01485).%0a* GUIEditButtons refactor to enable Undo in textarea; allow for custom functions to configure mopen, mclose, and unselect for their buttons.%0a* [[Cookbook:EditHelp|EditHelp]] refactor to allow undo; add shortcuts Ctrl+L convert selection to lowercase, Ctrl+Shift+L to uppercase, Ctrl+Shift+ArrowUp and ArrowDown to swap lines.%0a* Skip upgrade check if $EnableReadOnly.%0a* Fix bug with multiple $MarkupDirectiveFunctions.%0a* Add $EnableBaseNameConfig.%0a* PmSyntax optimize for larger pages (cont.).%0a* Input password add class "inputbox" like the other fields.%0a* CondAuth() added way to check for usergroup permissions.%0a* Update in pagelist.php for PHP 8.%0a* Documentation update.%0a%0a!!! Version 2.3.16 (2022-11-28) [[#v2316]]%0a* Class PPRC add generic callbacks.%0a* IncludeText() update for PHP 8, reported by V.Krishn.%0a* WikiStyle add 'overflow', 'notoc'.%0a* Add PmNonce().%0a* PmTOC update indented link style->classname. %0a* Responsive skin: replace %25pmhlt%25[@[[%3c%3c]]@] with %25hlt html%25[@%3cbr class='clearboth' />@], update PmTOC styles.%0a* $EnableListIncludedPages use class name instead of style. %0a* guiedit.js remove unneeded style.%0a* PmSyntax realign font for nested programming languages in the edit form, optimize for large pages.%0a* Only call session_status() if function exists.%0a* Edit form remove unsafe-inline script.%0a* Revert WikiStyleToClassName(), PrePrintFmt() -- need more work (PITS:01484).%0a* Documentation update.%0a%0a!!! Version 2.3.15 (2022-11-21) [[#v2315]]%0a* CSS pre, code relative/scalable font-size (pmwiki-responsive skin).%0a* PmSyntax add variable --pmsyntax-fontsize-editform and split from --pmsyntax-fontsize [[https://www.pmichaud.com/pipermail/pmwiki-users/2022-November/064936.html|#]].%0a* PmSyntax fix [@[[Highlight]]@] label font size and family (reported by Hans).%0a* Add variable $CookieSameSite default to 'Lax'%0a* Add argument $samesite to pmsetcookie(), default to $CookieSameSite, refactor for old and new PHP versions. %0a* Add function pm_session_start() respecting local configuration.%0a* CSP header add base-uri=self; object-src 'none'.%0a* Add $HTTPHeaders['XSSP'] = 'X-XSS-Protection: 1; mode=block'.%0a* Rewrite GUIButtons logic to avoid unsafe-inline JavaScript.%0a* Refactor WikiStyles, replace inline styles with class names to avoid unsafe-inline CSS.%0a* Refactor PQA(), tables, cells, to replace inline style="..." with class names to avoid unsafe-inline CSS.%0a* Add PrePrintFmt(), refactor PrintFmt(), PrintSkin() to process wiki pages, skin parts, and skin functions to HTML before outputting headers.%0a* Fix XSS vulnerability.%0a* Documentation update.%0a%0a!!! Version 2.3.14 (2022-11-03) [[#v2314]]%0a* Searchbox also escape custom field names.%0a* Prevent double-encoded entities in searchbox (reported by Simon).%0a* Trim $Author (PITS:01208).%0a* Replace autofocus inline JavaScript with attributes.%0a* Edit form: the label next to the "Minor edit" checkbox now toggles the checkbox.%0a* PmSyntax recognize %25pmhlt%25[@(:template requires? ...:)@].%0a* Update for PHP 8. %0a* Obsolete PCCF() from PHP 7.2 not 8.0.%0a* Add array $ObsoleteMarkups, function TraceMarkup(), update Markup(), Markup_e() and ObsoleteMarkup(), to retrieve and show files and line numbers for obsolete/disabled markup rules.%0a* Fix bug with PSFT format %25L.%0a* Update documentation.%0a%0a!!! Version 2.3.13 (2022-10-07) [[#v2313]]%0a* Close potential XSS vulnerability, reported by lukystreik (PITS:01483).%0a* Refactor $MultiFactorAuthFunction, add $FailedLoginsFunction.%0a* Update documentation.%0a%0a!!! Version 2.3.12 (2022-09-25) [[#v2312]]%0a* Stripmagic() cast null to "" and other fixes for PHP 8.%0a* Fix parse error for complex conditionals with empty variables (PITS:01480).%0a* PSFT() and MarkupExpression [@ftime@] add %25L as human readable local timestamp. %0a* MarkupRestore() fix wrong cast to empty string of false-ish values.%0a* PrintAuthForm() split from PmWikiAuth(). %0a* Fix warning for unneeded session_regenerate_id() (reported by George Murray).%0a* Update documentation.%0a%0a!!! Version 2.3.11 (2022-08-30) [[#v2311]]%0a* Add [[PageVariables]] %25pmhlt%25 [@{$GroupHomePage}@], [@{$GroupHomePageName}@], [@{$GroupHomePageTitle}@], [@{$GroupHomePageTitlespaced}@].%0a* Add $MarkupDirectiveFunctions.%0a* Fix stripmagic() for arrays recently broke after PHP8 update.%0a* Update documentation.%0a%0a!!! Version 2.3.10 (2022-08-20) [[#v2310]]%0a* Update for PHP 8.1 (reported by Armin Bühler).%0a* Forms will now prefill wildcard variables from $DefaultUnsetPageTextVars or $DefaultEmptyPageTextVars.%0a* $EnablePmSyntax = 3; will enable syntax highlighting in the edit form by default, without the user clicking on "Highlight". Fix occasional text mis-alignment between the text area and the highlighted block.%0a* Update documentation.%0a%0a!!! Version 2.3.9 (2022-08-18) [[#v239]]%0a* Add non-wildcard $DefaultUnsetPageTextVars to %25pmhlt%25[@(:input default:)@] (reported by Johnny).%0a* PmSyntax handles new selectors pre.pmhlt, code.pmhlt.%0a* Update for PHP 8 (PITS:01478).%0a* Update documentation.%0a%0a%0a!!! Version 2.3.8 (2022-07-22) [[#v238]]%0a* PmSyntax fix for 2 different %25pmhlt%25 [@%25hlt%25@] on the same line (reported by Simon).%0a* Fix broken include when the first page doesn't exist.%0a* Update documentation.%0a%0a!!! Version 2.3.7 (2022-06-28) [[#v237]]%0a* $HTTPHeaders add X-Frame-Options (suggested by Imagine Dragon) and Content-Security-Policy to disallow embedding in external websites by default.%0a* $EnableHighlight will now remember any links to PmWiki variables and restore them after the highlighting, see [[thread->https://www.pmwiki.org/pipermail/pmwiki-users/2022-June/064887.html]].%0a* $EnablePmSyntax will now process %25pmhlt%25[@%25hlt pmwiki%25@] in addition to [@%25pmhlt%25@] blocks, and escaped markup after it will be tentatively highlighted.%0a* Update documentation.%0a%0a!!! Version 2.3.6 (2022-06-19) [[#v236]]%0a* Fixes for PHP 8.%0a* Add form attribute "lang".%0a* Sortable tables allow for table headers to have markup such as bold (except links). It will now use a case-insensitive natural ordering.%0a* Allow for $UploadVerifyFunction to modify $upname.%0a* Add variable $PageIndexTermsFunction.%0a* Searchbox allow for removal of submit button if [@label=""@]; add default [@placeholder="$[Search]"@].%0a* Fix author.php may be included before some variables are defined, reported by Said Achmiz.%0a* $EnableHighlight convert code blocks to plain text, see [[thread->https://www.pmwiki.org/pipermail/pmwiki-users/2022-June/064887.html]].%0a* Documentation update.%0a%0a%0a!!! Version 2.3.5 (2022-05-23) [[#v235]]%0a* Fix broken list=grouphomes (PITS:01477).%0a* Add DisableSkinParts() helper function for recipes.%0a* HandlePostUpload: add @@$FmtV["$filepath"]@@ and @@$FmtV["$upurl"]@@ with the file path and direct URL to the newly uploaded file.%0a* In pmwiki-utils.js, replace forgotten ''let'' with ''var'' (suggested by SteP).%0a* Update for PHP 8.1.%0a* Update documentation.%0a%0a!!! Version 2.3.4 (2022-04-22) [[#v234]]%0a* Fixes for PHP 8 warnings, reported by Siegfried Seibert.%0a* Update documentation.%0a%0a!!! Version 2.3.3 (2022-03-26) [[#v233]]%0a* Fix for PHP 8 warnings, reported by Jean-Patrick Charrey, Dominique Faure and Siegfried Seibert.%0a* Update README.txt and docs/ files, suggested by Simon Davis.%0a* Update documentation.%0a%0a!!! Version 2.3.2 (2022-02-09) [[#v232]]%0a* Allow for $EnableLocalTimes to define custom duration of the pulled page history.%0a* Rename variable $EnableIncludedPages to $EnableListIncludedPages (avoid ambiguity).%0a* Remove $LinkAlt when an embedded picture without an alternative text fails to load.%0a* PmSyntax:%0a** Allow for line breaks \\ inside headings, tables, list items (like the core).%0a** Parallel processing of multiple blocks.%0a* Add scripts/utils.php; move loading of pmwiki-utils.js and PmSyntax to scripts/utils.js.%0a** Add $EnablePmUtils, default enabled.%0a** Parallel processing of the pmwiki-utils.js utility functions.%0a** Move pmwiki-utils.js move to $HTMLHeaderFmt (often prevents page redraw with the TOC/PmToggle/LocalTimes).%0a* Fix bug causing invalid page name when the name is "Group.0".%0a* Fix PHP 8.1.2 warnings, reported by J&uuml;rgen Godau and Dominique Faure.%0a* LocaltTimes fix "rcnew" classes for wikis with the older format.%0a* Update documentation.%0a%0a!!! Version 2.3.1 (2022-01-15) [[#v231]]%0a%0a* Fix the release script which broke the $VersionNum variable and the [@[[#anchor]]@] markup with the PmWiki-responsive skin.%0a%0a!!! Version 2.3.0 (2022-01-15) [[#v230]]%0a* Add PmSyntax, $EnablePmSyntax, $CustomSyntax, [@{$EnabledIMap}@], see Cookbook:PmSyntax, Cookbook:CustomSyntax.%0a* [@(:markup:)@] can now have @@class=norender@@ to only show the source code without processing it.%0a* Updates for PHP 8.1, hide warnings, add PSFT() replacement for strftime() and 2 callbacks, $EnableFTimeNew, update core function calls, add [@%25o@] for the ordinal suffix of the date (PITS:01418).%0a* Notify: @@tz=@@ (timezone) per-user.%0a* PageList add category= argument (PITS:00447, PITS:01475); link= and category= now accept multiple pages, wildcards, and negations (PITS:00908).%0a* [=[[!Category]]=] links can have alternative text (PITS:01095).%0a* Simplify/optimize pmwiki-utils.js when using datasets, simplify sorting of table rows without cloning, add LocalTimes().%0a* Page history diff anchors to also have "id=" attributes in addition to "name=".%0a* Add $EnableLocalTimes (default disabled) and styles, add HandleDiffList().%0a* Add markup %25pmhlt%25[@@2022-01-09T08:35:00Z@]%25%25 output as %3ctime>; localized if $EnableLocalTimes.%0a** Add $CurrentLocalTime in the above format, used by default in $RecentChangesFmt.%0a* Add $EnableRecentUploads (only Site.AllRecentChanges, only if $RecentUploadsFmt not defined).%0a* PmTOC update CSS for properly indented subheadings.%0a* Edit form $EnableIncludedPages, add placeholders to e_changesummary and e_author. Enable $EnableNotSavedWarning, add to sample-config.php. EditHelp to behave more like a word processor, typing "Enter" twice without writing text removes the preceding bullet.%0a* Responsive skin details>summary:hover {color:navy, cursor: pointer;}.%0a* PrintDiff() add classes for the delay between edits: diffday, diffweek, diffmonth, diffyear.%0a* Add helper function @@DownloadUrl($pagename, $path)@@ moved from @@LinkUpload()@@.%0a* Add [=$[ULby]=] i18n string 'uploaded by'.%0a* Update documentation.%0a%0a!!! [[#older]] Older versions%0a[[(PmWiki:)ChangeLog Archive]] - changes prior to version 2.3.0.%0a
-time=1724056500
+text=(:Summary: Log of changes made to PmWiki by [[Release(Notes)]]:)\%0aSee [[Cookbook:RecentChanges | the cookbook recent changes page]] for additional updates and activity by other developers, or join the [[PmWiki (/) mailing lists]] to discuss feature development with us.%0a%0a(:Prerelease:Changes made to the [[PmWiki:Subversion | subversion pre-release]] of PmWiki. You can get \%0a[[https://www.pmwiki.org/pub/pmwiki-devel/pmwiki-latest-svn.zip|a full ZIP archive]] of the nightly version, or \%0a[[https://www.pmwiki.org/pub/pmwiki-devel/pmwiki-nightly.zip|a partial export]] with only the files changed since {$Version}.:)\%0a{$:xPrerelease}%0a%0a(:comment PosArgs and $MessagesFmt were released in 2.3.34 but are undocumented and may change, so I'll announce about them in a future version:)%0a* Add helper function PosArgs($args, $posnames).%0a* Refactor $MessagesFmt to allow nested arrays with keys and %25pmhlt%25 [@(:messages key=a,b:)@]%25%25 that can be set from recipes.%0a* Responsive skin: cache SkinElements pages.%0a* Update for PHP 8.%0a* Add helper function PRI() "PmWiki Recursive Implode".%0a* pmwiki-utils.js add "draggable".%0a* Add PageVariable %25pmhlt%25[@{$GroupHomePageUrl}@].%0a* $EnableSortable, $EnableSimpleTableRowspan enabled by default.%0a* PmSyntax update for $EnableSimpleTableRowspan and for Cookbook:InputStar; fix line-height for some skin configurations.%0a* Add $EnableCommonEnhancements, update docs/sample-config.php, remove from sample-config.php $EnableNotSavedWarning which was enabled in 2.3.0.%0a* Add $EnableObfuscateEmails, $EnablePreserveLineBreaks.%0a* Add $EnableUrlApprove, $EnablePmForm, $EnableCreole, $EnableRefCount, $EnableFeeds (PITS:01511).%0a* %25pmhlt%25[@(:input e_minorcheckbox:)@]%25%25 to include label and title per $EnableMergeLastMinorEdit, update Site.EditForm, XLPage.%0a* Anchors remove deprecated name="" attribute.%0a* Meta Content-type moved early and configurable.%0a[[#svn-revision-4794]]%0a* Update documentation.%0a%0a%0a!!! Version 2.3.36 (2024-08-07) [[#v2336]]%0a* Add $EnableUploadDrop based on Cookbook:DragDropMultiUpload.%0a* Add $TROEPatterns.%0a* Update for PHP 8 (PITS:01510)%0a* Store a history entry when a page is deleted.%0a* Update documentation.%0a%0a!!! Version 2.3.35 (2024-07-07) [[#v2335]]%0a* PmSyntax [@(:comment ...:)@] add required space; add [@(:input defaults ...:)@] (with "s"). %25item pmhlt%25%0a* Enable highlighted source with ?action=source&highlight=1.%0a* Update default sidebar, https links, PITS and Mailing lists in conditional.%0a* Remove upload extensions "svg", "svgz", "htm", "html", "css", "swf", "fla", "epub", and files with no extension. Fix mime types for "wmf", "psd".%0a* Fix page title could accidentally include raw HTML.%0a* Update documentation.%0a%0a!!! Version 2.3.34 (2024-05-27) [[#v2334]]%0a* Delete wikilib.d/PmWiki.PerGroupCustomizations (unused redirect), content moved to GroupCustomizations 14 years ago.%0a* RecipeCheck remove table width attribute (suggested by Simon).%0a* Add %25pmhlt%25[@(:if action browse,edit:)@] conditional.%0a* $GUIButtons remove invalid elements (warning reported by Simon).%0a* phpdiff.php fix for PHP 8 when saving new pages (reported by Simon).%0a* Responsive skin: remove old CSS declarations like @-moz-keyframes (PITS:01507).%0a* Add upload extension 'm4a'.%0a* Update documentation.%0a%0a!!! Version 2.3.33 (2024-04-21) [[#v2333]]%0a* $EnablePreviewChanges to show "%25diffadd%25No changes%25%25" if there are no changes.%0a* PmSyntax add rules for colored pagenames and URLs inside bracket links.%0a* Responsive skin hide dropdown icons from printing.%0a* Fix some cases with conditional markup and markup expressions where an empty code could be evaluated (suggested by Goodguy00).%0a* Add $HTMLTitleFmt (PITS:01502).%0a* Cache auth conditional results for %25pmhlt%25[@(:if auth level:)@].%0a* Update blocklist.php for PHP 8, reported by Foster Schucker.%0a* Update documentation.%0a%0a!!! Version 2.3.32 (2024-03-24) [[#v2332]]%0a* Dark theme: add toggleImages(), add $ImgDarkSuffix, $FmtV['$PathUpload']. Restore light styles and pictures for printing.%0a* Responsive skin: white background when printing, move dark toggle label styles into skin.css.%0a* PmSyntax: only apply dark theme colors on screen (not print).%0a* Add upload extensions and image extension patterns AVIF, AVIFS.%0a* Lock AllRecentChanges in case of concurrent uploads.%0a* FileSizeCompact() allow for base 1000 (PITS:01499).%0a* Update documentation.%0a%0a!!! Version 2.3.31 (2024-02-23) [[#v2331]]%0a* Add $EnableDarkThemeToggle, enable 3-way theme toggle, "Light", "Dark" and "Auto", add annotation tooltip showing the current theme on tap and on mouse over.%0a* Refactor config data passed to pmwiki-utils.php, refactor dark toggle functions into a separate script. %0a* Responsive skin add body attributes for group and page name, update dark theme, enable auto theme (browser preferences) by default.%0a* PmSyntax improve dark theme thanks to a script by Said Achmiz; expose color properties for reuse.%0a* Refactor redirect quiet (PITS:01498).%0a* Page attributes passwords form: allow for +addition and -removal of passwords, users, groups.%0a* Allow $EditTemplatesFmt entries to apply to specific pages with name= specification (suggested by Simon).%0a* Forms add attribute "form".%0a* Refactor $PostConfig to allow called functions to update it.%0a* Update RecipeCheck to also list skins, suggested by Simon.%0a* Refactor PrintFmt, add $EnablePrePrintFmt.%0a* [[WikiStyles]] add 'columns'.%0a* When Highlight.js is enabled, Vardoc links will be the same color as variables in highlighted code blocks.%0a* Refactor $EnableUploadVersions.%0a* Update documentation.%0a%0a!!! Version 2.3.30 (2024-01-22) [[#v2330]]%0a* Add prototype for dark theme toggle. See PITS:01497 and Cookbook:DarkColorScheme.%0a** PmWiki-responsive skin converted CSS colors to variables, added dark theme styles.%0a** Add skins/pmwiki/pmwiki-32.svg, enable default for $PageLogoUrl.%0a** PmSyntax added dark theme styles.%0a* $EnableUploadMimeMatch with Fileinfo not enabled to deny uploads.%0a* upload.php fix warning for PHP 8.%0a* RecipeCheck use https, suggested by Simon.%0a* PrintDiff() add $since argument.%0a* Add $EnableRedirectQuiet = 2. Prevent infinite redirect loops.%0a* Fix Attach: links with escaped path and filename.%0a* Improved readability for inline diffs in page history.%0a* Forms enable input e_author not only for action=edit, fix unquoted positional form action URL.%0a* Update documentation.%0a%0a!!! Version 2.3.29 (2023-12-18) [[#v2329]]%0a* Fix urlapprove.php for PHP 8.2. %0a* PmSyntax textarea remove styles for width, height (Cookbook:PmSyntax-Talk), allow for fractional dimensions of the highlighted area.%0a* $MarkupDirectiveFunctions allow dashes in attribute names.%0a* Update documentation.%0a%0a!!! Version 2.3.28 (2023-11-27) [[#v2328]]%0a* Add input ''month'' and ''color'' fields.%0a* Add $NotifyRelatedTrailFmt.%0a* Reverse simpletable row backgrounds when there is a thead element.%0a* Fix pmwiki-utils.js when window.localStorage is disabled.%0a* UrlApprovals allow https: URLs if the http: URL for the same domain has been approved (PITS:01431).%0a* Update documentation.%0a%0a!!! Version 2.3.27 (2023-10-23) [[#v2327]]%0a* When merging last edit, if there is no change summary, reuse the last one. %0a* Keep unknown date/time formats for undefined timezone (PITS:01495).%0a* DiffRenderSource() fix for PHP 8, keep ins/del tags on the same line.%0a* The ".diffmarkup" element now has the style "white-space: pre-wrap".%0a* Add new keyword shortcuts Ctrl+B (bold), Ctrl+I (italic), Ctrl+K (link/unlink).%0a* Update documentation.%0a%0a%0a!!! Version 2.3.26 (2023-09-28) [[#v2326]]%0a* Add configurable $InputLabelFmt snippet (PITS:01493).%0a* Add configurable $TrailFmt snippets.%0a* Add $EnableSearchAtLeastOneTerm, default disabled.%0a* Unset upload extensions if size for the extension is set to 0.%0a* Update feeds.php for PHP 8.2 (PITS:01494).%0a* Update documentation.%0a%0a%0a!!! Version 2.3.25 (2023-07-29) [[#v2325]]%0a* Updates for PHP 8.2.%0a* Fix pagelist when 2+ directives on the same line, reported by Simon.%0a* Fix possible bug with internal group(header|footer) directives caused by PRR().%0a* Update documentation.%0a%0a%0a!!! Version 2.3.24 (2023-06-06) [[#v2324]]%0a* Add $EnableUploadMimeMatch.%0a* Add $EnableMergeLastMinorEdit, edit functions MergeLastMinorEdit (based on Cookbook:FuseEdit), SaveChangeSummary (refactored out of HandleEdit).%0a* Fix LogoutCookies() doesn't use a $pagename argument.%0a* PmForm add condition 'validemail' for use in template require.%0a* Add $PmCryptAlgo, pmcrypt() to call password_verify() if it exists. %0a* Refactor HandleDownload() split ServeDownload($filepath, $upname).%0a* Add InsertEditFunction($newfn, $where='%3cPostPage').%0a* Add $AuthFormRespCode.%0a* Add $EnableDownloadRanges, default 1.%0a* When the token is expired, reopen edit form rather than abort.%0a* LocalTimes add $EnableRCListLastEdit.%0a* Update documentation.%0a%0a!!! Version 2.3.23 (2023-05-03) [[#v2323]]%0a* Refactor pmtoken() to use session tokens, enable for core actions.%0a* Add %25pmhlt%25[@(:input pmtoken:)@] helper.%0a* PmForm add $PmFormEnablePmToken.%0a* Refactor @@HandleLogoutA()@@ split @@LogoutCookies()@@. %0a* Fix PRCB() for PHP %3c 7.4.%0a* Update documentation.%0a%0a!!! Version 2.3.22 (2023-04-06) [[#v2322]]%0a* Add scripts/pmform.php, Site.PmFormTemplates.%0a* FmtDateTimeZ() can now accept Unix timestamps.%0a* Pagelists fix bug with multiple category=+A,+B entries.%0a* Update for PHP 8.1 (PITS:01488).%0a* MarkupDirectiveFunctions will now cast numeric arguments to floats.%0a* Prevent errors in custom PageVariables from generating internal server errors (PITS:01489).%0a* Improve inline diff for rare cases (end of page).%0a* Forms/buttons with @@data-pmconfirm="Question"@@ will ask the question before they are submitted.%0a* Update documentation.%0a%0a%0a!!! Version 2.3.21 (2023-03-06) [[#v2321]]%0a* Add $IsPmArchive, $PmArchiveDir.%0a* Sortable tables with %3ctime datetime=""> elements can be sorted by the datetime attribute. Fix for tables with preexisting %3cthead> element.%0a* Updates for PHP8.%0a* Add CSV upload extension.%0a* LocalTimes add mode=3 to show old dates as MM'YY.%0a* Fix bug with multiline $MarkupDirectiveFunctions, reported by Antti Tikanm&auml;ki.%0a* Add $EnableCopyCode and Copy code button to %3cpre> blocks, suggested by Alex Dor&eacute;.%0a* Update PmTOC to work better with Cookbook:SectionEdit.%0a* Update documentation.%0a%0a!!! Version 2.3.20 (2023-02-12) [[#v2320]]%0a* Fix undefined variable warning, reported by Gregor Klari&ccaron;.%0a%0a!!! Version 2.3.19 (2023-02-11) [[#v2319]]%0a* Only set cookie params if headers not sent. %0a* Update for PHP8.2, reported by Dfaure. PageVar() update for PHP 8.%0a* Add variable $DiffPrepareInlineFunction.%0a* PageListCache() remove unused global $PageIndexFile.%0a* Add configurable $LocalCSSDir, $LocalCSSDirUrl.%0a* DownloadUrl() add $FmtV['$LinkDownload'] with current or future download link.%0a* Add pm_recode() helper function (based on PageStore::recodefn), check for more transcode options.%0a* HandleBrowse() add $FmtV['$PageSourceText'].%0a* Add helper function KeepBlock().%0a* Add $FarmPubDirPrefix, pm_servefile(), $ServeFileExts.%0a* Update documentation.%0a%0a!!! Version 2.3.18 (2023-01-15) [[#v2318]]%0a* Refactor scripts/utils.php, add pm_json_encode() (PITS:01486).%0a* EditAutoText() fix for lines ending with multiple backslashes.%0a* PmSyntax optimize/refactor for large pages (cont.), fix inline escaped texts could ignore line markups, add EnableStopwatch.%0a* Notify fix typo in regular expression.%0a* {-Add $EnableUploadVersions >=10 to rename base.ext to base-1.ext, base-2.ext,...-} ''Redesigned in 2.3.31''%0a* CondAuth() fix bug with global $AuthList.%0a* Add helper function PRCB() for simpler preg_replace_callback passing variables.%0a* Update scripts/refcount.php for PHP 8, reported by George Murray.%0a* Add PageVariable $PageLogoUrl (PITS:01297).%0a* Update documentation.%0a%0a!!! Version 2.3.17 (2022-12-17) [[#v2317]]%0a* WikiStyles trim class names (PITS:01485).%0a* GUIEditButtons refactor to enable Undo in textarea; allow for custom functions to configure mopen, mclose, and unselect for their buttons.%0a* [[Cookbook:EditHelp|EditHelp]] refactor to allow undo; add shortcuts Ctrl+L convert selection to lowercase, Ctrl+Shift+L to uppercase, Ctrl+Shift+ArrowUp and ArrowDown to swap lines.%0a* Skip upgrade check if $EnableReadOnly.%0a* Fix bug with multiple $MarkupDirectiveFunctions.%0a* Add $EnableBaseNameConfig.%0a* PmSyntax optimize for larger pages (cont.).%0a* Input password add class "inputbox" like the other fields.%0a* CondAuth() added way to check for usergroup permissions.%0a* Update in pagelist.php for PHP 8.%0a* Documentation update.%0a%0a!!! Version 2.3.16 (2022-11-28) [[#v2316]]%0a* Class PPRC add generic callbacks.%0a* IncludeText() update for PHP 8, reported by V.Krishn.%0a* WikiStyle add 'overflow', 'notoc'.%0a* Add PmNonce().%0a* PmTOC update indented link style->classname. %0a* Responsive skin: replace %25pmhlt%25[@[[%3c%3c]]@] with %25hlt html%25[@%3cbr class='clearboth' />@], update PmTOC styles.%0a* $EnableListIncludedPages use class name instead of style. %0a* guiedit.js remove unneeded style.%0a* PmSyntax realign font for nested programming languages in the edit form, optimize for large pages.%0a* Only call session_status() if function exists.%0a* Edit form remove unsafe-inline script.%0a* Revert WikiStyleToClassName(), PrePrintFmt() -- need more work (PITS:01484).%0a* Documentation update.%0a%0a!!! Version 2.3.15 (2022-11-21) [[#v2315]]%0a* CSS pre, code relative/scalable font-size (pmwiki-responsive skin).%0a* PmSyntax add variable --pmsyntax-fontsize-editform and split from --pmsyntax-fontsize [[https://www.pmichaud.com/pipermail/pmwiki-users/2022-November/064936.html|#]].%0a* PmSyntax fix [@[[Highlight]]@] label font size and family (reported by Hans).%0a* Add variable $CookieSameSite default to 'Lax'%0a* Add argument $samesite to pmsetcookie(), default to $CookieSameSite, refactor for old and new PHP versions. %0a* Add function pm_session_start() respecting local configuration.%0a* CSP header add base-uri=self; object-src 'none'.%0a* Add $HTTPHeaders['XSSP'] = 'X-XSS-Protection: 1; mode=block'.%0a* Rewrite GUIButtons logic to avoid unsafe-inline JavaScript.%0a* Refactor WikiStyles, replace inline styles with class names to avoid unsafe-inline CSS.%0a* Refactor PQA(), tables, cells, to replace inline style="..." with class names to avoid unsafe-inline CSS.%0a* Add PrePrintFmt(), refactor PrintFmt(), PrintSkin() to process wiki pages, skin parts, and skin functions to HTML before outputting headers.%0a* Fix XSS vulnerability.%0a* Documentation update.%0a%0a!!! Version 2.3.14 (2022-11-03) [[#v2314]]%0a* Searchbox also escape custom field names.%0a* Prevent double-encoded entities in searchbox (reported by Simon).%0a* Trim $Author (PITS:01208).%0a* Replace autofocus inline JavaScript with attributes.%0a* Edit form: the label next to the "Minor edit" checkbox now toggles the checkbox.%0a* PmSyntax recognize %25pmhlt%25[@(:template requires? ...:)@].%0a* Update for PHP 8. %0a* Obsolete PCCF() from PHP 7.2 not 8.0.%0a* Add array $ObsoleteMarkups, function TraceMarkup(), update Markup(), Markup_e() and ObsoleteMarkup(), to retrieve and show files and line numbers for obsolete/disabled markup rules.%0a* Fix bug with PSFT format %25L.%0a* Update documentation.%0a%0a!!! Version 2.3.13 (2022-10-07) [[#v2313]]%0a* Close potential XSS vulnerability, reported by lukystreik (PITS:01483).%0a* Refactor $MultiFactorAuthFunction, add $FailedLoginsFunction.%0a* Update documentation.%0a%0a!!! Version 2.3.12 (2022-09-25) [[#v2312]]%0a* Stripmagic() cast null to "" and other fixes for PHP 8.%0a* Fix parse error for complex conditionals with empty variables (PITS:01480).%0a* PSFT() and MarkupExpression [@ftime@] add %25L as human readable local timestamp. %0a* MarkupRestore() fix wrong cast to empty string of false-ish values.%0a* PrintAuthForm() split from PmWikiAuth(). %0a* Fix warning for unneeded session_regenerate_id() (reported by George Murray).%0a* Update documentation.%0a%0a!!! Version 2.3.11 (2022-08-30) [[#v2311]]%0a* Add [[PageVariables]] %25pmhlt%25 [@{$GroupHomePage}@], [@{$GroupHomePageName}@], [@{$GroupHomePageTitle}@], [@{$GroupHomePageTitlespaced}@].%0a* Add $MarkupDirectiveFunctions.%0a* Fix stripmagic() for arrays recently broke after PHP8 update.%0a* Update documentation.%0a%0a!!! Version 2.3.10 (2022-08-20) [[#v2310]]%0a* Update for PHP 8.1 (reported by Armin Bühler).%0a* Forms will now prefill wildcard variables from $DefaultUnsetPageTextVars or $DefaultEmptyPageTextVars.%0a* $EnablePmSyntax = 3; will enable syntax highlighting in the edit form by default, without the user clicking on "Highlight". Fix occasional text mis-alignment between the text area and the highlighted block.%0a* Update documentation.%0a%0a!!! Version 2.3.9 (2022-08-18) [[#v239]]%0a* Add non-wildcard $DefaultUnsetPageTextVars to %25pmhlt%25[@(:input default:)@] (reported by Johnny).%0a* PmSyntax handles new selectors pre.pmhlt, code.pmhlt.%0a* Update for PHP 8 (PITS:01478).%0a* Update documentation.%0a%0a%0a!!! Version 2.3.8 (2022-07-22) [[#v238]]%0a* PmSyntax fix for 2 different %25pmhlt%25 [@%25hlt%25@] on the same line (reported by Simon).%0a* Fix broken include when the first page doesn't exist.%0a* Update documentation.%0a%0a!!! Version 2.3.7 (2022-06-28) [[#v237]]%0a* $HTTPHeaders add X-Frame-Options (suggested by Imagine Dragon) and Content-Security-Policy to disallow embedding in external websites by default.%0a* $EnableHighlight will now remember any links to PmWiki variables and restore them after the highlighting, see [[thread->https://www.pmwiki.org/pipermail/pmwiki-users/2022-June/064887.html]].%0a* $EnablePmSyntax will now process %25pmhlt%25[@%25hlt pmwiki%25@] in addition to [@%25pmhlt%25@] blocks, and escaped markup after it will be tentatively highlighted.%0a* Update documentation.%0a%0a!!! Version 2.3.6 (2022-06-19) [[#v236]]%0a* Fixes for PHP 8.%0a* Add form attribute "lang".%0a* Sortable tables allow for table headers to have markup such as bold (except links). It will now use a case-insensitive natural ordering.%0a* Allow for $UploadVerifyFunction to modify $upname.%0a* Add variable $PageIndexTermsFunction.%0a* Searchbox allow for removal of submit button if [@label=""@]; add default [@placeholder="$[Search]"@].%0a* Fix author.php may be included before some variables are defined, reported by Said Achmiz.%0a* $EnableHighlight convert code blocks to plain text, see [[thread->https://www.pmwiki.org/pipermail/pmwiki-users/2022-June/064887.html]].%0a* Documentation update.%0a%0a%0a!!! Version 2.3.5 (2022-05-23) [[#v235]]%0a* Fix broken list=grouphomes (PITS:01477).%0a* Add DisableSkinParts() helper function for recipes.%0a* HandlePostUpload: add @@$FmtV["$filepath"]@@ and @@$FmtV["$upurl"]@@ with the file path and direct URL to the newly uploaded file.%0a* In pmwiki-utils.js, replace forgotten ''let'' with ''var'' (suggested by SteP).%0a* Update for PHP 8.1.%0a* Update documentation.%0a%0a!!! Version 2.3.4 (2022-04-22) [[#v234]]%0a* Fixes for PHP 8 warnings, reported by Siegfried Seibert.%0a* Update documentation.%0a%0a!!! Version 2.3.3 (2022-03-26) [[#v233]]%0a* Fix for PHP 8 warnings, reported by Jean-Patrick Charrey, Dominique Faure and Siegfried Seibert.%0a* Update README.txt and docs/ files, suggested by Simon Davis.%0a* Update documentation.%0a%0a!!! Version 2.3.2 (2022-02-09) [[#v232]]%0a* Allow for $EnableLocalTimes to define custom duration of the pulled page history.%0a* Rename variable $EnableIncludedPages to $EnableListIncludedPages (avoid ambiguity).%0a* Remove $LinkAlt when an embedded picture without an alternative text fails to load.%0a* PmSyntax:%0a** Allow for line breaks \\ inside headings, tables, list items (like the core).%0a** Parallel processing of multiple blocks.%0a* Add scripts/utils.php; move loading of pmwiki-utils.js and PmSyntax to scripts/utils.js.%0a** Add $EnablePmUtils, default enabled.%0a** Parallel processing of the pmwiki-utils.js utility functions.%0a** Move pmwiki-utils.js move to $HTMLHeaderFmt (often prevents page redraw with the TOC/PmToggle/LocalTimes).%0a* Fix bug causing invalid page name when the name is "Group.0".%0a* Fix PHP 8.1.2 warnings, reported by J&uuml;rgen Godau and Dominique Faure.%0a* LocaltTimes fix "rcnew" classes for wikis with the older format.%0a* Update documentation.%0a%0a!!! Version 2.3.1 (2022-01-15) [[#v231]]%0a%0a* Fix the release script which broke the $VersionNum variable and the [@[[#anchor]]@] markup with the PmWiki-responsive skin.%0a%0a!!! Version 2.3.0 (2022-01-15) [[#v230]]%0a* Add PmSyntax, $EnablePmSyntax, $CustomSyntax, [@{$EnabledIMap}@], see Cookbook:PmSyntax, Cookbook:CustomSyntax.%0a* [@(:markup:)@] can now have @@class=norender@@ to only show the source code without processing it.%0a* Updates for PHP 8.1, hide warnings, add PSFT() replacement for strftime() and 2 callbacks, $EnableFTimeNew, update core function calls, add [@%25o@] for the ordinal suffix of the date (PITS:01418).%0a* Notify: @@tz=@@ (timezone) per-user.%0a* PageList add category= argument (PITS:00447, PITS:01475); link= and category= now accept multiple pages, wildcards, and negations (PITS:00908).%0a* [=[[!Category]]=] links can have alternative text (PITS:01095).%0a* Simplify/optimize pmwiki-utils.js when using datasets, simplify sorting of table rows without cloning, add LocalTimes().%0a* Page history diff anchors to also have "id=" attributes in addition to "name=".%0a* Add $EnableLocalTimes (default disabled) and styles, add HandleDiffList().%0a* Add markup %25pmhlt%25[@@2022-01-09T08:35:00Z@]%25%25 output as %3ctime>; localized if $EnableLocalTimes.%0a** Add $CurrentLocalTime in the above format, used by default in $RecentChangesFmt.%0a* Add $EnableRecentUploads (only Site.AllRecentChanges, only if $RecentUploadsFmt not defined).%0a* PmTOC update CSS for properly indented subheadings.%0a* Edit form $EnableIncludedPages, add placeholders to e_changesummary and e_author. Enable $EnableNotSavedWarning, add to sample-config.php. EditHelp to behave more like a word processor, typing "Enter" twice without writing text removes the preceding bullet.%0a* Responsive skin details>summary:hover {color:navy, cursor: pointer;}.%0a* PrintDiff() add classes for the delay between edits: diffday, diffweek, diffmonth, diffyear.%0a* Add helper function @@DownloadUrl($pagename, $path)@@ moved from @@LinkUpload()@@.%0a* Add [=$[ULby]=] i18n string 'uploaded by'.%0a* Update documentation.%0a%0a!!! [[#older]] Older versions%0a[[(PmWiki:)ChangeLog Archive]] - changes prior to version 2.3.0.%0a
+time=1724221963
diff --git a/wikilib.d/PmWiki.CustomMarkup b/wikilib.d/PmWiki.CustomMarkup
index fd56042b..048e5c87 100644
--- a/wikilib.d/PmWiki.CustomMarkup
+++ b/wikilib.d/PmWiki.CustomMarkup
@@ -1,9 +1,9 @@
-version=pmwiki-2.3.30 ordered=1 urlencoded=1
-author=simon
+version=pmwiki-2.3.36 ordered=1 urlencoded=1
+author=Petko
charset=UTF-8
-csum=add Keep Block (+154)
+csum=patterns must use "/" (forward slash) as the delimiters (+316)
name=PmWiki.CustomMarkup
-rev=199
+rev=201
targets=Cookbook.MarkupDirectiveFunctions,PmWiki.PageTextVariables,PmWiki.Links,PmWiki.CustomMarkup,PmWiki.DebugVariables,Cookbook.Cookbook,PmWiki.LocalCustomizations,Cookbook.ParseArgs,PmWiki.ReleaseNotes,PmWiki.Functions,PmWiki.BasicVariables,PmWiki.CustomMarkup-Talk,PmWiki.MailingLists,Cookbook.JavaScript,Cookbook.JavaScript-Editable,PmWiki.Skins,PmWiki.LayoutVariables,PmWiki.CustomMarkupAlt,Category.Markup,!Markup
-text=(:Summary: Using the Markup() function for custom wiki syntax; migration to PHP 5.5:)%0a(:Audience: administrators (intermediate) :)%0a%0aPmWiki's markup translation engine is handled by a set of rules; each rule searches for a specific pattern in the markup text and replaces it with some replacement text. Internally, this is accomplished by using PHP's "[[https://www.php.net/manual/en/function.preg-replace.php | preg_replace]]" function.%0a%0a!! Introduction%0aRules are added to the translation engine via PmWiki's %25hlt php%25@@Markup()@@ function, which looks like%0a->%25hlt php%25[@Markup($name, $when, $pattern, $replace); # if no evaluation is needed, or if PHP %3c 5.5@]%0a->%25hlt php%25@@Markup($name, $when, $pattern, $replace_function); # if evaluation is needed@@'%0a'^#^' DEPRECATED, will not work as of PHP 7.2%0a->@@{-Markup_e($name, $when, $pattern, $replace); # if evaluation is needed and 5.5%3c=PHP%3c=7.1-}@@%0a%0a* %25hlt php%25[@$name@] is a unique name (a string) given to the rule%0a* %25hlt php%25[@$when@] says when the rule should be applied relative to other rules or phases, can be preceded by "@@%3c@@" or "@@>@@"%0a* %25hlt php%25[@$pattern@] is the pattern to be searched for in the markup text%0a* %25hlt php%25[@$replace@] is the text or HTML that should replace the matched pattern.%0a* %25hlt php%25[@$replace_function@] is the name of the function which should be called with the match, and should return the replacement.%0a%0a!! Simple markup%0aSee [[Cookbook:Markup Directive Functions]] a new helper function (as of PmWiki 2.3.11) that makes it easy to add custom markup directives.%0a%0a%0a!!! Example%0aFor example, here's the code that creates the rule for %25pmhlt%25[@''emphasized text''@] (in ''@@scripts/stdmarkup.php@@''):%0a->%25hlt php%25[@Markup("em", "inline", "/''(.*?)''/", "%3cem>$1%3c/em>");@]%0a%0aBasically this statement says to create a rule called "@@em@@" to be performed with the other "@@inline@@" markups, and the rule replaces any text inside two pairs of single quotes with the same text ($1) surrounded by %25hlt html%25[@%3cem>@] and [@%3c/em>@].%0a%0a!!! Sequence in which rules are applied%0aThe first two parameters to %25hlt php%25@@Markup()@@ are used to specify the sequence in which rules should be applied. The first parameter provides a name for a rule -- "[@em@]" in the example above. We could've chosen other names such as "[@''@]", or even "[@twosinglequotes@]". In general PmWiki uses the markup itself to name the rule (i.e., PmWiki uses "[@''@]" instead of "[@em@]"), but to keep this example easier to read later on we'll use a mnemonic name for now.%0a%0aThe second parameter says that this rule is to be done along with the other "inline" markups. PmWiki divides the translation process into a number of phases (or placeholder rules):%0a%0a _begin start of translation%0a [={$var}=] [[Page Text Variables]] happen here.%0a fulltext translations to be performed on the full text %0a split conversion of the full markup text into lines to be processed%0a directives directive processing%0a inline inline markups%0a links conversion of [[links]], url-links, and WikiWords %0a block block markups%0a style style handling %0a _end end of translation%0a%0a%0aThis argument is normally specified as a left-angle bracket "@@%3c@@" ("before") or a right-angle bracket "@@>@@" ("after") followed by the name of another rule or the name of a phase. %0a%0aThus, specifying "@@inline@@" for the second parameter says that this rule should be applied when the other "@@inline@@" rules are being performed. If we want a rule to be performed with the directives -- i.e., before inline rules are processed, we would specify "@@directives@@" or "@@%3cinline@@" for the second parameter.%0a%0a!!! [={$var}=] and [=(:if ...:)=] conditionals%0aA significant rule in terms of ordering is "[@{$var}@]" which substitutes variables -- if you say "[@%3c{$var}@]" then your markup will be processed before variables are substituted whereas if you say ">[={$var}=]" then your markup will be processed after variables are substituted. This happens before conditional %25pmhlt%25[@(:if...:)@] expressions, which is why page text variables are processed even if they are defined inside [@(:if false:)@].%0a%0a!!! Markup regular expression definition%0aThe third parameter is a Perl-compatible regular expression. Basically, it is a slash, a [[regular expression -> https://www.php.net/manual/en/reference.pcre.pattern.syntax.php]], another slash, and a set of optional [[modifiers -> https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php]].%0a%0aThe example uses the pattern string [@"/''(.*?)''/"@], which uses [@''(.*?)''@] as the regular expression and no options. (The regular expression says "find two single quotes in succession, then as few arbitrary characters as are needed to make the match find something, then two additional single quotes in succession"; the parentheses "capture" a part of the wikitext for later use.)%0a%0a!!! Replacement text%0aThe fourth parameter is the replacement text that should be inserted instead of the marked-up wikitext. You can use [@$1@], [@$2@], etc. to insert the text from the first, second etc. parenthesised part of the regular expression.%0a%0aIn the example, we have %25hlt html%25[@"%3cem>$1%3c/em>"@], which is an [@%3cem>@], the text matched by the first parentheses (i.e. by the [@.*?@] section of the pattern), and [@%3c/em>@].%0a%0aHere's a rule for %25pmhlt%25[@@@monospaced@@@] text:%0a%0a->%25hlt php%25[@Markup("@@", "inline", "/@@(.*?)@@/", "%3ccode>$1%3c/code>");@]%0a%0aand for a [@[:comment ...:]@] directive that is simply removed from the output:%0a%0a->%25hlt php%25[@Markup("comment", "directives", "/\\[:comment .*?:\\]/", '');@]%0a%0aOkay, now how about the rule for %25pmhlt%25[@'''strong emphasis'''@]? We have to be a bit careful here, because although this translation should be performed along with other inline markup, we also have to make sure that the rule for [@'''@] is handled ''before'' the rule for [@''@], because [@'''@] also contains [@''@]. The second parameter to %25hlt php%25@@Markup()@@ can be used to specify the new rule's relationship to any other rule:%0a%0a->%25hlt php%25[@Markup("strong", "%3cem", "/'''(.*?)'''/", "%3cstrong>$1%3c/strong>");@]%0a%0aThis creates a rule called "@@strong@@", and the second parameter "@@%3cem@@" says to be sure that this rule is processed before the "@@em@@" rule we defined above. If we wanted to do something after the "@@em@@" rule, we would use "@@>em@@" instead. Thus, it's possible to add rules at any point in PmWiki's markup translation process in an extensible manner. (In fact, the "@@inline@@", "@@block@@", "@@directives@@", etc., phases above are just placeholder rules used to provide an overall sequence for other rules. Thus one can use "@@%3cinline@@" to specify rules that should be handled before any other inline rules.) %0a%0aIf you want to disable available markup just call e.g.:%0a%0a->%25hlt php%25[@DisableMarkup("strong");@]%0a%0aPmWiki's default markup rules are defined in the ''@@scripts/stdmarkup.php@@'' file. To see the entire translation table as the program is running, the @@scripts/diag.php@@ module adds "[@?action=ruleset@]", which displays the set of defined markup rules in the sequence in which they will be processed. You can see it at [[CustomMarkup?action=ruleset | CustomMarkup?action=ruleset]]. You must first enable the action by setting $EnableDiag = 1 in your configuration file.%0a%0a!! @@%3c:vspace>@@ and @@%3c:block>@@%0a@@%3c:vspace>@@ is inserted into the page text very early in page text processing to preserve an empty line (i.e. two newlines in a row). Very late in processing HTML is inserted into the page output to preserve the empty lines.%0aUnless markup processing detects this it can be ignored.%0a%0a@@%3c:block>@@\\%0aFrom 2.3.19 please use:%0a-> %25hlt php%25[@return KeepBlock($out); @]%0aPreviously usage could look like this: %0a-> %25hlt php%25[@return '%3c:block>'. Keep($out); @]%0a%0aAt the start of a line, @@%3c:block>@@ means "start a block-level element",%0ai.e. break out of the paragraphs.%0a%0aSay you have these markups:%0a* %25pmhlt%25@@(:abc:)@@ returns 'ABC'%0a* %25pmhlt%25@@(:def:)@@ returns '%3c:block>DEF'%0a%0aThis wiki text:%0a Some text%0a %25pmhlt%25@@(:abc:)@@%0a some other text%0a%0awill produce this HTML (simplified):%0a %25hlt html%25[@%3cp>Some text%0a ABC%0a some other text%3c/p>@]%0a%0aWhile this wiki text:%0a Some text%0a %25pmhlt%25@@(:def:)@@%0a some other text%0a%0awill produce this HTML (simplified):%0a %25hlt html%25[@%3cp>Some text%3c/p>%0a DEF%0a %3cp>some other text%3c/p>@]%0a%0aThis is intended for a markup rule to return a block level element like%0a%25hlt html%25@@%3cdiv>...%3c/div>@@ that is not allowed inside an HTML paragraph.%0a%0a!! Other common examples%0a!!! Define a custom markup to produce a specific HTML or Javascript sequence%0a%0aSuppose an admin wants to have a simple "%25pmhlt%25[@(:example:)@]" markup that will always produce a fixed HTML string in the output, such as for a webring, Google AdSense display, or Javascript. The %25hlt php%25@@Markup()@@ call to do this would be:%0a-> %25hlt php%25[@%0aMarkup('example', 'directives',%0a '/\\(:example:\\)/',%0a Keep("%3cdiv class='example'>%3cp>Here is a %0a %3ca target='_blank' href='https://www.example.com'>link%3c/a> to%0a %3cem>example.com%3c/em>%3c/p>%3c/div>") );%0a@]%0a%0a* The first argument is a unique name for the markup ("example").%0a* The second argument says to perform this markup along with other directives.%0a* The third argument is the pattern to look for "(:example:)".%0a* The fourth argument is the HTML that "(:example:)" is to be replaced with. We use the %25hlt php%25@@Keep()@@ function here to prevent the output from being further processed by PmWiki's markup rule -- in the above example, we don't want the https://www.example.com url to be again converted to a link.%0a%0a[[#random]]%0a!!! Define a markup to call a custom function that returns content%0a%0a->%25red%25 The /e modifier has been deprecated and should not be used in ongoing development. See [[#php55|below]] for more details.%25%25%0a%0aFor older PHP versions (%3c 7.2) an 'e' option on the [@$pattern@] parameter causes the [@$replace@] parameter to be treated as a PHP expression to be evaluated instead of replacement text. To avoid using the deprecated e/ parameter, a markup to produce a random number between 1 and 100 might now look like:%0a-> %25hlt php%25[@%0aMarkup('random', 'directives',%0a '/\\(:random:\\)/',%0a "MyRandomFunction");%0afunction MyRandomFunction() {%0a return rand(1, 100);%0a}%0a@]%0a%0aThis calls the PHP built-in %25hlt php%25@@rand()@@ function and substitutes the directive with the result. Any function can be called, including functions defined in a [[local customization(s)]] file or in [[Cookbook:Cookbook|Cookbook]] recipes.%0a%0aArguments can also be passed by using regular expression capturing parentheses, thus%0a-> %25hlt php%25[@%0aMarkup('randomargs', 'directives',%0a '/\\(:random (\\d+) (\\d+):\\)/',%0a "MyRandomFunction");%0afunction MyRandomFunction($m) {%0a return rand($m[1], $m[2]);%0a}%0a@]%0a%0awill cause the markup %25pmhlt%25[@(:random 50 100:)@] to generate a random number between 50 and 100.%0a%0a->%25note%25 Note: the /e modifier in regular expressions is deprecated since PHP version 5.5, and removed since PHP version 7. The reason for this is, that malicious authors could pass strings that could cause arbitrary and undesirable PHP functions to be executed.%0a%0aFor a PmWiki function to help with parsing arbitrary sequences of arguments and key=value pairs, see Cookbook:ParseArgs.%0a%0a[[#php55]]%0a!! Migration to PHP 5.5 and @@Markup_e()@@%0aSince PHP version 5.5, the @@/e@@ evaluation modifier is deprecated and some hosting providers don't allow its use.%0a%0aRecent [[ReleaseNotes | versions]] of the PmWiki core (2.2.58 and newer) allow new ways to define markup rules without being dependent on the @@/e@@ eval modifier. The historical ways to define markup rules are not removed and work, but may be incompatible with PHP 5.5 installations.%0a%0a''Note: whether your replacement pattern needs evaluation or not, you must use %25hlt php%25@@Markup()@@%25%25 and %25red%25not @@Markup_e()@@.%25%25'' The latter is deprecated and should no longer be used for new recipes and customizations, and old recipes using @@Markup_e@@ should be upgraded to the new format.%0a%0aThe examples below all require PmWiki 2.2.58 (2013-12-25) or newer but the latest version is recommended.%0a%0a>>frame%3c%3c%0aTHE SHORT ANSWER: If your markup regular expression (the 3rd argument) contains an "e" after the closing slash (i.e., @@/regex/e@@ or @@/regex/se@@ or etc) AND your 4th argument is entirely surrounded with double-quotes then you may be able to get away with simply following these simple steps:%0a%0a# Delete the "e" from after the closing slash in the 3rd argument%0a# Create a new replacement function with $m as argument.%0a# In your function, the previous occurrences of '$1', '$2', etc. are now found as $m[1], $m[2], etc. You should no longer call @@[[Functions#PSS|PSS()]]@@.%0a# In your function, call %25hlt php%25@@extract($GLOBALS['MarkupToHTML']);@@ in order to get the current $pagename and @@$markupid@@.%0a# Your function needs to '''return''' the result from the markup processing, either html or another markup.%0a# Set the name of the replacement function as 4th argument of the Markup() call.%0a%0aIn some cases this will not suffice - it depends on how quoting was done - but in many cases following these simple steps will result in PHP 5.5+ compatibility. %0a%0aIf you try those steps and are still having problems then continue to read below for a deeper understanding.%0a>>%3c%3c%0a%0aThe following is acceptable for PHP 5.5+ (compatible with PmWiki 2.2.58+, will also work in PHP 5.4 and older)%0a* %25hlt php%25@@Markup($name, $when, $pattern, $replace)@@; %0a** @@$pattern@@ can no longer have an "@@/e@@" modifier%0a** @@$replace@@ can be a function name (callback) which will be called with the array of matches as argument%0a** instead of a string, the fourth parameter can be a definition of an anonymous function (note you can use anon functions this way since [[https://www.php.net/manual/en/functions.anonymous.php | PHP 5.3.0+]]).%0a%0a* {-@@Markup_e($name, $when, $pattern, $replace)@@;-} %25red%25 DEPRECATED, should no longer be used%0a%0aExamples:%0a%0a* For PHP 5.4 and older, this was acceptable:%25hlt php%25[@%0aMarkup('randomargs', 'directives',%0a '/\\(:random (\\d+) (\\d+):\\)/e',%0a "rand('$1', '$2')"%0a );@]%0a%0a* For PHP 5.5 and newer, $replace is callback, we call %25hlt php%25@@Markup()@@:[@%0aMarkup('randomargs', 'directives',%0a '/\\(:random (\\d+) (\\d+):\\)/',%0a "MyRandom"%0a );%0afunction MyRandom($m) { # $m = matches%0a return rand($m[1], $m[2]); # note "return" is used, unlike before%0a}%0a@]%0a %25note%25 This will also work in PHP 5.4 and older%25%25%0a%0aOther example:%0a* PHP 5.4 or older: %25hlt php%25[@%0aMarkup('Maxi:','%3clinks',%0a "/\\b([Mm]axi:)([^\\s\"\\|\\[\\]]+)(\"([^\"]*)\")?/e",%0a "Keep(LinkMaxi(\$pagename,'$1','$2','$4','$1$2'),'L')"%0a );%0a@]%0a%0a* PHP 5.5 or newer, PmWiki 2.2.58+, $replace is a function name: %25hlt php%25[@%0aMarkup('Maxi:','%3clinks',%0a "/\\b([Mm]axi:)([^\\s\"\\|\\[\\]]+)(\"([^\"]*)\")?/",%0a "LinkMaxi"%0a );%0afunction LinkMaxi($m) {%0a extract($GLOBALS['MarkupToHTML']); # to get $pagename%0a # do stuff with $m[1], $m[2], etc.%0a return Keep($out, 'L');%0a}%0a@]%0a %25note%25 This will also work in PHP 5.4 and older%25%25%0a%0a* $replace can also be a callback function, we call %25hlt php%25@@Markup()@@: [@%0aMarkup('Maxi:','%3clinks',%0a "/\\b([Mm]axi:)([^\\s\"\\|\\[\\]]+)(\"([^\"]*)\")?/",%0a "CallbackMaxi"%0a);%0afunction CallbackMaxi($m) {%0a extract($GLOBALS["MarkupToHTML"]); # to get $pagename%0a return Keep(LinkMaxi($pagename,$m[1],$m[2],$m[4],$m[1].$m[2]),'L');%0a}%0a@]%0a %25note%25 This will also work in PHP 5.4 and older%25%25%0a%0aThe above may seem complicated, but it is actually simpler to use your own callback function:%0a-> %25hlt php%25[@%0aMarkup('mykey', 'directives', %0a '/\\(:mydirective (.*?) (.*?):\\)/i',%0a 'MyFunction'%0a);%0afunction MyFunction($m) {%0a extract($GLOBALS["MarkupToHTML"]);%0a%0a # ... do stuff with $m (the matches), drop PSS() ...%0a%0a return $out; # or return Keep($html);%0a}%0a@]%0a%0aIf you have any questions about the new way to define custom markup, you can ask us [[PmWiki:CustomMarkup-Talk|at the talk page]] or on the [[PmWiki/mailing lists]].%0a%0a%0a!!FAQ%0a>>faq%3c%3c [[#faq]]%0aQ: How can I embed JavaScript into a page's output?%0aA: There are several ways to do this. The [[Cookbook:JavaScript]] recipe describes a simple means for embedding static JavaScript into web pages using [[custom markup]]. For editing JavaScript directly in wiki pages (which can pose various security risks), see the [[(Cookbook:)JavaScript-Editable]] recipe. For JavaScript that is to appear in headers or footers of pages, the [[skin(s)]] template can be modified directly, or %3cscript> statements can be inserted using the $HTMLHeaderFmt array.%0a%0aQ: How would I create a markup %25pmhlt%25(''[@(:nodiscussion:)@]'') that will set a page variable (''[@{$HideDiscussion}@]'') which can be used by ''[@(:if enabled HideDiscussion:)@]'' in [=.PageActions=]?%0aA: Add the following section of code to your @@config.php@@%0a-> %25hlt php%25[@%0aSDV($HideDiscussion, 0); #define var name%0aMarkup('hideDiscussion', '%3c{$var}',%0a '/\\(:nodiscussion:\\)/', 'setHideDiscussion'); %0afunction setHideDiscussion() { %0a global $HideDiscussion; %0a $HideDiscussion = true;%0a} %0a@]%0a%0aThis will enable the %25pmhlt%25@@[=(:if enabled HideDiscussion:)=]@@ markup to be used. If you want to print the current value of [={$HideDiscussion}=] (for testing purposes) on the page, you'll also need to add the line: \\%0a%25hlt php%25@@[=$FmtPV['$HideDiscussion'] = '$GLOBALS["HideDiscussion"]';=]@@%0a%0a%0aQ: It appears that (.*?) does not match newlines in these functions, making the above example inoperable if the text to be wrapped in %3cem> contains new lines.%0aA: If you include the "s" modifier on the regular expression then the dot (.) will match newlines. Thus your regular expression will be "/STUFF(.*?)/s". That s at the very end is what you are looking for. If you start getting into multi-line regexes you may be forced to look at the m option as well - let's anchors (^ and $) match not begin/end of strings but also begin/end of lines (i.e., right before/after a newline). Also make sure your markup is executed during the fulltext phase.%0a %0aQ: [[#PRR]] How can the text returned by my markup function be re-processed by the markup engine? %0aA: If the result of your markup contains more markup that should be processed, you have two options. First is to select a "when" argument that is processed earlier than the markup in your result. For example, if your markup may return [=[[links]]=], your "when" argument could be @@"%3clinks"@@ and your markup will be processed before the links markup. The second option is to call the %25hlt php%25@@PRR()@@ function in your markup definition or inside your markup function. In this case, after your markup is processed, PmWiki will restart all markups from the beginning. %0a%0aQ: How do I get started writing recipes and creating my own custom markup?%0aA: [[PmWiki:CustomMarkupAlt|(alternate) Introduction to custom markup for Beginners]]%0a%0aQ: How do I make a rule that runs once at the end of all other rule processing?%0aA: Use this statement instead of the usual %25hlt php%25@@Markup()@@ call:%0a-->%25hlt php%25@@$MarkupFrameBase['posteval']['myfooter'] = "\$out = onetimerule(\$out);";@@%0a%0aCategory: [[!Markup]]
-time=1708148675
+text=(:Summary: Using the Markup() function for custom wiki syntax; migration to PHP 5.5:)%0a(:Audience: administrators (intermediate) :)%0a%0aPmWiki's markup translation engine is handled by a set of rules; each rule searches for a specific pattern in the markup text and replaces it with some replacement text. Internally, this is accomplished by using PHP's "[[https://www.php.net/manual/en/function.preg-replace.php | preg_replace]]" function.%0a%0a%25note%25 Note: The patterns provided to the Markup() function must use "/" (forward slash) as the delimiters. Unlike preg_replace(), which allows a variety of punctuation characters as delimiters, this function strictly requires the use of "/" for delimiting the regular expression pattern.%0a%0a!! Introduction%0aRules are added to the translation engine via PmWiki's %25hlt php%25@@Markup()@@ function, which looks like%0a->%25hlt php%25[@Markup($name, $when, $pattern, $replace); # if no evaluation is needed, or if PHP %3c 5.5@]%0a->%25hlt php%25@@Markup($name, $when, $pattern, $replace_function); # if evaluation is needed@@'%0a'^#^' DEPRECATED, will not work as of PHP 7.2%0a->@@{-Markup_e($name, $when, $pattern, $replace); # if evaluation is needed and 5.5%3c=PHP%3c=7.1-}@@%0a%0a* %25hlt php%25[@$name@] is a unique name (a string) given to the rule%0a* %25hlt php%25[@$when@] says when the rule should be applied relative to other rules or phases, can be preceded by "@@%3c@@" or "@@>@@"%0a* %25hlt php%25[@$pattern@] is the pattern to be searched for in the markup text, using "/" as delimiters.%0a* %25hlt php%25[@$replace@] is the text or HTML that should replace the matched pattern.%0a* %25hlt php%25[@$replace_function@] is the name of the function which should be called with the match, and should return the replacement.%0a%0a!! Simple markup%0aSee [[Cookbook:Markup Directive Functions]] a new helper function (as of PmWiki 2.3.11) that makes it easy to add custom markup directives.%0a%0a%0a!!! Example%0aFor example, here's the code that creates the rule for %25pmhlt%25[@''emphasized text''@] (in ''@@scripts/stdmarkup.php@@''):%0a->%25hlt php%25[@Markup("em", "inline", "/''(.*?)''/", "%3cem>$1%3c/em>");@]%0a%0aBasically this statement says to create a rule called "@@em@@" to be performed with the other "@@inline@@" markups, and the rule replaces any text inside two pairs of single quotes with the same text ($1) surrounded by %25hlt html%25[@%3cem>@] and [@%3c/em>@].%0a%0a!!! Sequence in which rules are applied%0aThe first two parameters to %25hlt php%25@@Markup()@@ are used to specify the sequence in which rules should be applied. The first parameter provides a name for a rule -- "[@em@]" in the example above. We could've chosen other names such as "[@''@]", or even "[@twosinglequotes@]". In general PmWiki uses the markup itself to name the rule (i.e., PmWiki uses "[@''@]" instead of "[@em@]"), but to keep this example easier to read later on we'll use a mnemonic name for now.%0a%0aThe second parameter says that this rule is to be done along with the other "inline" markups. PmWiki divides the translation process into a number of phases (or placeholder rules):%0a%0a _begin start of translation%0a [={$var}=] [[Page Text Variables]] happen here.%0a fulltext translations to be performed on the full text %0a split conversion of the full markup text into lines to be processed%0a directives directive processing%0a inline inline markups%0a links conversion of [[links]], url-links, and WikiWords %0a block block markups%0a style style handling %0a _end end of translation%0a%0a%0aThis argument is normally specified as a left-angle bracket "@@%3c@@" ("before") or a right-angle bracket "@@>@@" ("after") followed by the name of another rule or the name of a phase. %0a%0aThus, specifying "@@inline@@" for the second parameter says that this rule should be applied when the other "@@inline@@" rules are being performed. If we want a rule to be performed with the directives -- i.e., before inline rules are processed, we would specify "@@directives@@" or "@@%3cinline@@" for the second parameter.%0a%0a!!! [={$var}=] and [=(:if ...:)=] conditionals%0aA significant rule in terms of ordering is "[@{$var}@]" which substitutes variables -- if you say "[@%3c{$var}@]" then your markup will be processed before variables are substituted whereas if you say ">[={$var}=]" then your markup will be processed after variables are substituted. This happens before conditional %25pmhlt%25[@(:if...:)@] expressions, which is why page text variables are processed even if they are defined inside [@(:if false:)@].%0a%0a!!! Markup regular expression definition%0aThe third parameter is a Perl-compatible regular expression. Basically, it is a slash, a [[regular expression -> https://www.php.net/manual/en/reference.pcre.pattern.syntax.php]], another slash, and a set of optional [[modifiers -> https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php]].%0a%0aThe example uses the pattern string [@"/''(.*?)''/"@], which uses [@''(.*?)''@] as the regular expression and no options. (The regular expression says "find two single quotes in succession, then as few arbitrary characters as are needed to make the match find something, then two additional single quotes in succession"; the parentheses "capture" a part of the wikitext for later use.)%0a%0a!!! Replacement text%0aThe fourth parameter is the replacement text that should be inserted instead of the marked-up wikitext. You can use [@$1@], [@$2@], etc. to insert the text from the first, second etc. parenthesised part of the regular expression.%0a%0aIn the example, we have %25hlt html%25[@"%3cem>$1%3c/em>"@], which is an [@%3cem>@], the text matched by the first parentheses (i.e. by the [@.*?@] section of the pattern), and [@%3c/em>@].%0a%0aHere's a rule for %25pmhlt%25[@@@monospaced@@@] text:%0a%0a->%25hlt php%25[@Markup("@@", "inline", "/@@(.*?)@@/", "%3ccode>$1%3c/code>");@]%0a%0aand for a [@[:comment ...:]@] directive that is simply removed from the output:%0a%0a->%25hlt php%25[@Markup("comment", "directives", "/\\[:comment .*?:\\]/", '');@]%0a%0aOkay, now how about the rule for %25pmhlt%25[@'''strong emphasis'''@]? We have to be a bit careful here, because although this translation should be performed along with other inline markup, we also have to make sure that the rule for [@'''@] is handled ''before'' the rule for [@''@], because [@'''@] also contains [@''@]. The second parameter to %25hlt php%25@@Markup()@@ can be used to specify the new rule's relationship to any other rule:%0a%0a->%25hlt php%25[@Markup("strong", "%3cem", "/'''(.*?)'''/", "%3cstrong>$1%3c/strong>");@]%0a%0aThis creates a rule called "@@strong@@", and the second parameter "@@%3cem@@" says to be sure that this rule is processed before the "@@em@@" rule we defined above. If we wanted to do something after the "@@em@@" rule, we would use "@@>em@@" instead. Thus, it's possible to add rules at any point in PmWiki's markup translation process in an extensible manner. (In fact, the "@@inline@@", "@@block@@", "@@directives@@", etc., phases above are just placeholder rules used to provide an overall sequence for other rules. Thus one can use "@@%3cinline@@" to specify rules that should be handled before any other inline rules.) %0a%0aIf you want to disable available markup just call e.g.:%0a%0a->%25hlt php%25[@DisableMarkup("strong");@]%0a%0aPmWiki's default markup rules are defined in the ''@@scripts/stdmarkup.php@@'' file. To see the entire translation table as the program is running, the @@scripts/diag.php@@ module adds "[@?action=ruleset@]", which displays the set of defined markup rules in the sequence in which they will be processed. You can see it at [[CustomMarkup?action=ruleset | CustomMarkup?action=ruleset]]. You must first enable the action by setting $EnableDiag = 1 in your configuration file.%0a%0a!! @@%3c:vspace>@@ and @@%3c:block>@@%0a@@%3c:vspace>@@ is inserted into the page text very early in page text processing to preserve an empty line (i.e. two newlines in a row). Very late in processing HTML is inserted into the page output to preserve the empty lines.%0aUnless markup processing detects this it can be ignored.%0a%0a@@%3c:block>@@\\%0aFrom 2.3.19 please use:%0a-> %25hlt php%25[@return KeepBlock($out); @]%0aPreviously usage could look like this: %0a-> %25hlt php%25[@return '%3c:block>'. Keep($out); @]%0a%0aAt the start of a line, @@%3c:block>@@ means "start a block-level element",%0ai.e. break out of the paragraphs.%0a%0aSay you have these markups:%0a* %25pmhlt%25@@(:abc:)@@ returns 'ABC'%0a* %25pmhlt%25@@(:def:)@@ returns '%3c:block>DEF'%0a%0aThis wiki text:%0a Some text%0a %25pmhlt%25@@(:abc:)@@%0a some other text%0a%0awill produce this HTML (simplified):%0a %25hlt html%25[@%3cp>Some text%0a ABC%0a some other text%3c/p>@]%0a%0aWhile this wiki text:%0a Some text%0a %25pmhlt%25@@(:def:)@@%0a some other text%0a%0awill produce this HTML (simplified):%0a %25hlt html%25[@%3cp>Some text%3c/p>%0a DEF%0a %3cp>some other text%3c/p>@]%0a%0aThis is intended for a markup rule to return a block level element like%0a%25hlt html%25@@%3cdiv>...%3c/div>@@ that is not allowed inside an HTML paragraph.%0a%0a!! Other common examples%0a!!! Define a custom markup to produce a specific HTML or Javascript sequence%0a%0aSuppose an admin wants to have a simple "%25pmhlt%25[@(:example:)@]" markup that will always produce a fixed HTML string in the output, such as for a webring, Google AdSense display, or Javascript. The %25hlt php%25@@Markup()@@ call to do this would be:%0a-> %25hlt php%25[@%0aMarkup('example', 'directives',%0a '/\\(:example:\\)/',%0a Keep("%3cdiv class='example'>%3cp>Here is a %0a %3ca target='_blank' href='https://www.example.com'>link%3c/a> to%0a %3cem>example.com%3c/em>%3c/p>%3c/div>") );%0a@]%0a%0a* The first argument is a unique name for the markup ("example").%0a* The second argument says to perform this markup along with other directives.%0a* The third argument is the pattern to look for "(:example:)".%0a* The fourth argument is the HTML that "(:example:)" is to be replaced with. We use the %25hlt php%25@@Keep()@@ function here to prevent the output from being further processed by PmWiki's markup rule -- in the above example, we don't want the https://www.example.com url to be again converted to a link.%0a%0a[[#random]]%0a!!! Define a markup to call a custom function that returns content%0a%0a->%25red%25 The /e modifier has been deprecated and should not be used in ongoing development. See [[#php55|below]] for more details.%25%25%0a%0aFor older PHP versions (%3c 7.2) an 'e' option on the [@$pattern@] parameter causes the [@$replace@] parameter to be treated as a PHP expression to be evaluated instead of replacement text. To avoid using the deprecated e/ parameter, a markup to produce a random number between 1 and 100 might now look like:%0a-> %25hlt php%25[@%0aMarkup('random', 'directives',%0a '/\\(:random:\\)/',%0a "MyRandomFunction");%0afunction MyRandomFunction() {%0a return rand(1, 100);%0a}%0a@]%0a%0aThis calls the PHP built-in %25hlt php%25@@rand()@@ function and substitutes the directive with the result. Any function can be called, including functions defined in a [[local customization(s)]] file or in [[Cookbook:Cookbook|Cookbook]] recipes.%0a%0aArguments can also be passed by using regular expression capturing parentheses, thus%0a-> %25hlt php%25[@%0aMarkup('randomargs', 'directives',%0a '/\\(:random (\\d+) (\\d+):\\)/',%0a "MyRandomFunction");%0afunction MyRandomFunction($m) {%0a return rand($m[1], $m[2]);%0a}%0a@]%0a%0awill cause the markup %25pmhlt%25[@(:random 50 100:)@] to generate a random number between 50 and 100.%0a%0a->%25note%25 Note: the /e modifier in regular expressions is deprecated since PHP version 5.5, and removed since PHP version 7. The reason for this is, that malicious authors could pass strings that could cause arbitrary and undesirable PHP functions to be executed.%0a%0aFor a PmWiki function to help with parsing arbitrary sequences of arguments and key=value pairs, see Cookbook:ParseArgs.%0a%0a[[#php55]]%0a!! Migration to PHP 5.5 and @@Markup_e()@@%0aSince PHP version 5.5, the @@/e@@ evaluation modifier is deprecated and some hosting providers don't allow its use.%0a%0aRecent [[ReleaseNotes | versions]] of the PmWiki core (2.2.58 and newer) allow new ways to define markup rules without being dependent on the @@/e@@ eval modifier. The historical ways to define markup rules are not removed and work, but may be incompatible with PHP 5.5 installations.%0a%0a''Note: whether your replacement pattern needs evaluation or not, you must use %25hlt php%25@@Markup()@@%25%25 and %25red%25not @@Markup_e()@@.%25%25'' The latter is deprecated and should no longer be used for new recipes and customizations, and old recipes using @@Markup_e@@ should be upgraded to the new format.%0a%0aThe examples below all require PmWiki 2.2.58 (2013-12-25) or newer but the latest version is recommended.%0a%0a>>frame%3c%3c%0aTHE SHORT ANSWER: If your markup regular expression (the 3rd argument) contains an "e" after the closing slash (i.e., @@/regex/e@@ or @@/regex/se@@ or etc) AND your 4th argument is entirely surrounded with double-quotes then you may be able to get away with simply following these simple steps:%0a%0a# Delete the "e" from after the closing slash in the 3rd argument%0a# Create a new replacement function with $m as argument.%0a# In your function, the previous occurrences of '$1', '$2', etc. are now found as $m[1], $m[2], etc. You should no longer call @@[[Functions#PSS|PSS()]]@@.%0a# In your function, call %25hlt php%25@@extract($GLOBALS['MarkupToHTML']);@@ in order to get the current $pagename and @@$markupid@@.%0a# Your function needs to '''return''' the result from the markup processing, either html or another markup.%0a# Set the name of the replacement function as 4th argument of the Markup() call.%0a%0aIn some cases this will not suffice - it depends on how quoting was done - but in many cases following these simple steps will result in PHP 5.5+ compatibility. %0a%0aIf you try those steps and are still having problems then continue to read below for a deeper understanding.%0a>>%3c%3c%0a%0aThe following is acceptable for PHP 5.5+ (compatible with PmWiki 2.2.58+, will also work in PHP 5.4 and older)%0a* %25hlt php%25@@Markup($name, $when, $pattern, $replace)@@; %0a** @@$pattern@@ can no longer have an "@@/e@@" modifier%0a** @@$replace@@ can be a function name (callback) which will be called with the array of matches as argument%0a** instead of a string, the fourth parameter can be a definition of an anonymous function (note you can use anon functions this way since [[https://www.php.net/manual/en/functions.anonymous.php | PHP 5.3.0+]]).%0a%0a* {-@@Markup_e($name, $when, $pattern, $replace)@@;-} %25red%25 DEPRECATED, should no longer be used%0a%0aExamples:%0a%0a* For PHP 5.4 and older, this was acceptable:%25hlt php%25[@%0aMarkup('randomargs', 'directives',%0a '/\\(:random (\\d+) (\\d+):\\)/e',%0a "rand('$1', '$2')"%0a );@]%0a%0a* For PHP 5.5 and newer, $replace is callback, we call %25hlt php%25@@Markup()@@:[@%0aMarkup('randomargs', 'directives',%0a '/\\(:random (\\d+) (\\d+):\\)/',%0a "MyRandom"%0a );%0afunction MyRandom($m) { # $m = matches%0a return rand($m[1], $m[2]); # note "return" is used, unlike before%0a}%0a@]%0a %25note%25 This will also work in PHP 5.4 and older%25%25%0a%0aOther example:%0a* PHP 5.4 or older: %25hlt php%25[@%0aMarkup('Maxi:','%3clinks',%0a "/\\b([Mm]axi:)([^\\s\"\\|\\[\\]]+)(\"([^\"]*)\")?/e",%0a "Keep(LinkMaxi(\$pagename,'$1','$2','$4','$1$2'),'L')"%0a );%0a@]%0a%0a* PHP 5.5 or newer, PmWiki 2.2.58+, $replace is a function name: %25hlt php%25[@%0aMarkup('Maxi:','%3clinks',%0a "/\\b([Mm]axi:)([^\\s\"\\|\\[\\]]+)(\"([^\"]*)\")?/",%0a "LinkMaxi"%0a );%0afunction LinkMaxi($m) {%0a extract($GLOBALS['MarkupToHTML']); # to get $pagename%0a # do stuff with $m[1], $m[2], etc.%0a return Keep($out, 'L');%0a}%0a@]%0a %25note%25 This will also work in PHP 5.4 and older%25%25%0a%0a* $replace can also be a callback function, we call %25hlt php%25@@Markup()@@: [@%0aMarkup('Maxi:','%3clinks',%0a "/\\b([Mm]axi:)([^\\s\"\\|\\[\\]]+)(\"([^\"]*)\")?/",%0a "CallbackMaxi"%0a);%0afunction CallbackMaxi($m) {%0a extract($GLOBALS["MarkupToHTML"]); # to get $pagename%0a return Keep(LinkMaxi($pagename,$m[1],$m[2],$m[4],$m[1].$m[2]),'L');%0a}%0a@]%0a %25note%25 This will also work in PHP 5.4 and older%25%25%0a%0aThe above may seem complicated, but it is actually simpler to use your own callback function:%0a-> %25hlt php%25[@%0aMarkup('mykey', 'directives', %0a '/\\(:mydirective (.*?) (.*?):\\)/i',%0a 'MyFunction'%0a);%0afunction MyFunction($m) {%0a extract($GLOBALS["MarkupToHTML"]);%0a%0a # ... do stuff with $m (the matches), drop PSS() ...%0a%0a return $out; # or return Keep($html);%0a}%0a@]%0a%0aIf you have any questions about the new way to define custom markup, you can ask us [[PmWiki:CustomMarkup-Talk|at the talk page]] or on the [[PmWiki/mailing lists]].%0a%0a%0a!!FAQ%0a>>faq%3c%3c [[#faq]]%0aQ: How can I embed JavaScript into a page's output?%0aA: There are several ways to do this. The [[Cookbook:JavaScript]] recipe describes a simple means for embedding static JavaScript into web pages using [[custom markup]]. For editing JavaScript directly in wiki pages (which can pose various security risks), see the [[(Cookbook:)JavaScript-Editable]] recipe. For JavaScript that is to appear in headers or footers of pages, the [[skin(s)]] template can be modified directly, or %3cscript> statements can be inserted using the $HTMLHeaderFmt array.%0a%0aQ: How would I create a markup %25pmhlt%25(''[@(:nodiscussion:)@]'') that will set a page variable (''[@{$HideDiscussion}@]'') which can be used by ''[@(:if enabled HideDiscussion:)@]'' in [=.PageActions=]?%0aA: Add the following section of code to your @@config.php@@%0a-> %25hlt php%25[@%0aSDV($HideDiscussion, 0); #define var name%0aMarkup('hideDiscussion', '%3c{$var}',%0a '/\\(:nodiscussion:\\)/', 'setHideDiscussion'); %0afunction setHideDiscussion() { %0a global $HideDiscussion; %0a $HideDiscussion = true;%0a} %0a@]%0a%0aThis will enable the %25pmhlt%25@@[=(:if enabled HideDiscussion:)=]@@ markup to be used. If you want to print the current value of [={$HideDiscussion}=] (for testing purposes) on the page, you'll also need to add the line: \\%0a%25hlt php%25@@[=$FmtPV['$HideDiscussion'] = '$GLOBALS["HideDiscussion"]';=]@@%0a%0a%0aQ: It appears that (.*?) does not match newlines in these functions, making the above example inoperable if the text to be wrapped in %3cem> contains new lines.%0aA: If you include the "s" modifier on the regular expression then the dot (.) will match newlines. Thus your regular expression will be "/STUFF(.*?)/s". That s at the very end is what you are looking for. If you start getting into multi-line regexes you may be forced to look at the m option as well - let's anchors (^ and $) match not begin/end of strings but also begin/end of lines (i.e., right before/after a newline). Also make sure your markup is executed during the fulltext phase.%0a %0aQ: [[#PRR]] How can the text returned by my markup function be re-processed by the markup engine? %0aA: If the result of your markup contains more markup that should be processed, you have two options. First is to select a "when" argument that is processed earlier than the markup in your result. For example, if your markup may return [=[[links]]=], your "when" argument could be @@"%3clinks"@@ and your markup will be processed before the links markup. The second option is to call the %25hlt php%25@@PRR()@@ function in your markup definition or inside your markup function. In this case, after your markup is processed, PmWiki will restart all markups from the beginning. %0a%0aQ: How do I get started writing recipes and creating my own custom markup?%0aA: [[PmWiki:CustomMarkupAlt|(alternate) Introduction to custom markup for Beginners]]%0a%0aQ: How do I make a rule that runs once at the end of all other rule processing?%0aA: Use this statement instead of the usual %25hlt php%25@@Markup()@@ call:%0a-->%25hlt php%25@@$MarkupFrameBase['posteval']['myfooter'] = "\$out = onetimerule(\$out);";@@%0a%0aCategory: [[!Markup]]
+time=1724101183
diff --git a/wikilib.d/PmWiki.Functions b/wikilib.d/PmWiki.Functions
index e307a623..3cc35992 100644
--- a/wikilib.d/PmWiki.Functions
+++ b/wikilib.d/PmWiki.Functions
@@ -1,9 +1,9 @@
-version=pmwiki-2.3.33 ordered=1 urlencoded=1
+version=pmwiki-2.3.36 ordered=1 urlencoded=1
author=Petko
charset=UTF-8
-csum=fix hlt (+31)
+csum=Markup() pattern needs to have "/" as delimiters. (+48)
name=PmWiki.Functions
-rev=204
+rev=205
targets=Cookbook.Functions,PmWiki.CustomMarkup,PmWiki.CustomActions,PmWiki.BasicVariables,PmWiki.LayoutVariables,PmWiki.Forms,PmWiki.SecurityVariables,Cookbook.PccfToPcfOverride,PmWiki.LinkVariables,PmWiki.OtherVariables,PmWiki.EditVariables,PmWiki.UploadVariables,PmWiki.Functions,PmWiki.Variables,PmWiki.Internationalizations,PmWiki.FmtPageName,PmWiki.MakeLink,PmWiki.ConditionalMarkup,PmWiki.Drafts,PmWiki.IncludeOtherPages,PmWiki.UpdatePage,Cookbook.MarkupExpressionSamples,Cookbook.ParseArgs,Category.PmWikiDeveloper,!PmWikiDeveloper
-text=(:Summary: How some of the functions in pmwiki.php work:)%0a(:Audience: admins (advanced) :)%0a%0aThis page describes some of the internal workings of PmWiki by explaining how some of the functions in @@pmwiki.php@@ work. For a more brief list/overview on functions useful to for instance cookbook writers, see Cookbook:Functions. %0a%0aTo use this functions you have to make sure that all relevant internal variables have been initialized correctly. See [[Custom Markup]] and [[(PmWiki:)Custom Actions]] for more information on how these functions are typically called via %25hlt php%25[@Markup()@] or [@$HandleActions[]@].%0a%0a!! [[#PSFT]] PSFT()%0a%0a%25hlt php%25[@PSFT($format, $timestamp=null, $locale=null, $tz=null)@]%0a%0aThe %25hlt php%25@@PSFT()@@ function (''PmWiki String Format Time'', added in 2.3.0) is intended to be a safe replacement for the very widely used PHP functions @@[[https://www.php.net/strftime|strftime()]]@@ and @@[[https://www.php.net/gmstrftime|gmtstrftime()]]@@ which became deprecated in PHP 8.1.%0a%0aUnlike %25hlt php%25@@strftime()@@, @@PSFT()@@ accepts 2 additional arguments @@$locale@@ and @@$tz@@, which allow to set a different language or timezone.%0a%0aPmWiki 2.3.0 uses this function in all cases where it previously used %25hlt php%25@@strftime()@@, including the %25pmhlt%25[@{(ftime)}@] Markup Expression. If your local customizations and recipes use %25hlt php%25@@strftime()@@, you should be able to safely replace all calls to @@strftime()@@ with @@PSFT()@@, without changing the arguments. Any calls to @@gmtstrftime($fmt, $stamp)@@ can be replaced with @@PSFT($fmt, $stamp, null, 'GMT')@@.%0a%0aThe old functions were deprecated by the PHP developers because they behaved inconsistently on different platforms, and were dependent on installed system locales (i.e. a language would only work if the system had its locale installed). The new function uses the PHP class [[https://www.php.net/manual/en/class.intldateformatter.php|IntlDateFormatter]] and should be better. Unfortunately, it is not always enabled by hosting providers. %0a%0aSo depending on your installation, a specific language may be available with %25hlt php%25@@strftime()@@ and/or with @@IntlDateFormatter@@.%0a%0aIn addition, some rarely used shortcut percent-formats [@%25c, %25x, %25X@] also behave inconsistently on different platforms, and the new formatter may show a slightly different output. You can always replace these shortcut formats with the full formats you require.%0a%0aFor these reasons, %25hlt php%25@@PSFT()@@ is currently a compromise, by default reusing @@strftime()@@ for PHP 8.0 or earlier. Updating your calls from @@strftime()@@ shouldn't cause any changes in your outputs.%0a%0aYou can set in @@config.php@@ the variable %25hlt php%25@@$EnableFTimeNew = 1;@@ for @@PSFT()@@ to try using @@IntlDateFormatter@@ before PHP 8.1. If @@IntlDateFormatter@@ is not available, it will show the month and day names in English. Check what works.%0a%0aSince the %25hlt php%25@@strftime()@@ function is deprecated, it is unlikely for it to add new formats. We have added 2 custom formats:%0a* [@%25o@] for the "ordinal suffix" of the date, as "st" in "January 1st". If @@IntlDateFormatter@@ is not available, it will show the suffix in English%0a* [@%25L@] for a human-readable timestamp of the format %25pmhlt%25[@@2022-09-25T11:49:08Z@]%25%25 which will be displayed formatted either as $TimeFmt or in the local time zone of the visitor, see $EnableLocalTimes.%0a%0a(:include MarkupExpressions#ftimeformats#ftimeformatsend:)%0a%0a>>frame%3c%3c%0aA difference between %25hlt php%25@@strftime($format, $stamp)@@ and @@PSFT($format, $stamp)@@ is how they interpret a false, empty or non-numeric @@$stamp@@ argument.%0a|| class=simpletable%0a||! @@$stamp@@ argument ||! @@strftime($format, $stamp)@@ ||! @@PSFT($format, $stamp)@@ ||%0a|| numeric || the stamp || the stamp ||%0a|| missing or ''null'' || current time || current time ||%0a|| ''false'' || 1970-01-01 || current time ||%0a|| "" (empty string) \\%0aother non-numeric || 1970-01-01 or ''false'' (older PHP versions) \\%0a ''Warning: TypeError'' (PHP 7.4+) || current time ||%0aFor PmWiki, it seemed reasonable to make empty strings and other non-numeric values default to the current time. If your %25hlt php%25@@$stamp@@ variable may be empty or ''false'', and your recipes rely on @@strftime()@@ returning "1970-01-01", you can cast the stamp to integer:%0a%25hlt php%25[@%0a PSFT($format, intval($stamp));%0a@]%0a>>%3c%3c%0a%0a%0a!! [[#pmtoken]] pmtoken()%0a%25hlt php%25[@pmtoken($check = 0, $abort = false)@]%0a%0aThe %25hlt php%25@@pmtoken()@@ function sets or checks a unique session identifier to be used in input forms, with the goal of preventing cross-site request forgeries (CSRF).%0a%0aCalling %25hlt php%25@@pmtoken()@@ or @@pmtoken(0)@@ will create a token if it doesn't exist, store it in the @@$_SESSION@@ array, and return it. It will also set the variables [@$FmtV['$TokenValue']@] which can be used in HTML templates and [@$InputValues['pmtoken']@] to be used in markup [[forms]], although it may be simpler to use %25pmhlt%25[@(:input pmtoken:)@] instead.%0a%0aThe name of the input element, by default 'pmtoken', can be changed by setting for example %25hlt php%25[@$FmtV['$TokenName'] = 'CSRFtoken';@].%0a%0aCalling %25hlt php%25@@pmtoken(1)@@ will check the @@$_POST['pmtoken']@@ value and will return true if it is valid.%0a%0aCalling %25hlt php%25@@pmtoken(2)@@ will check the @@$_GET['pmtoken']@@ value and will return true if it is valid.%0a%0aCalling %25hlt php%25@@pmtoken(1, true)@@ or @@pmtoken(2, true)@@ with a second truthy argument, and the token is invalid, will directly call @@Abort()@@ and exit.%0a%0a%0a!! [[#pmcrypt]] pmcrypt()%0a%25hlt php%25[@pmcrypt($password, $salt = null)@]%0a%0aThe %25hlt php%25@@pmcrypt()@@ function is intended to be a safe replacement for the [[https://www.php.net/crypt|PHP 5.6+ crypt() function]] without providing a $salt, which would raise a notice. If a salt is provided, crypt() is called to check an existing password. If a salt is not provided, [[https://www.php.net/password_hash|password_hash()]] will be called to create a cryptographically strong password hash.%0a%0a!! [[#pmsetcookie]] pmsetcookie()%0a%25hlt php%25[@pmsetcookie($name, $val="", $exp=0, $path="", $dom="", $secure=null, $httponly=null)@]%0a%0aThis function is intended as a replacement for [[https://www.php.net/setcookie|setcookie()]]. It will automatically set the $secure and $httponly arguments if they are not set by the caller function and if $EnableCookieSecure and $EnableCookieHTTPOnly are enabled.%0a%0a!![[#PCCF]] PCCF() %25red%25 Deprecated since PHP 7.2%25%25%0a%25hlt php%25[@PCCF($php_code, $callback_template='default', $callback_arguments = '$m')@] %0a%0aThe %25hlt php%25@@PCCF()@@ function (''PmWiki Create Callback Function'') can be used to create callback functions used with [[https://www.php.net/preg_replace_callback|preg_replace_callback]]. It is required for PHP 5.5, but will also work with earlier PHP versions.%0a%0aThe first argument is the PHP code to be evaluated. %0a%0aThe second argument (optional) is the callback template, a key from the global @@$CallbackFnTemplates@@ array. There are two templates that can be used by recipe authors: %0a* 'default' will pass @@$php_code@@ as a function code%0a* 'return' will wrap @@$php_code@@ like "@@return $php_code;@@" (since PmWiki 2.2.62)%0a%0aThe third argument (optional) is the argument of the callback function. Note that PmWiki uses the '$m' argument to pass the matches of a regular expression search, but your function can use other argument(s).%0a%0a%25hlt php%25@@PCCF()@@ will create an anonymous (lambda) callback function containing the supplied code, and will cache it. On subsequent calls with the same @@$php_code@@, @@PCCF()@@ will return the cached function name.%0a%0aSee the [[https://www.php.net/create_function | PHP create function]].%0a%0a>>font-style=italic%3c%3c%0aPHP 7.2 deprecates %25hlt php%25@@create_function()@@ and future versions will remove it. If you need to migrate older code that used @@PCCF()@@, you can usually write regular functions and pass the function name where you previously passed the result of PCCF(). For example, suppose you had a pattern like this:%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => PCCF("return strtoupper(\$m[1]);"),@@%0a%0aFor PHP 7.2 compatibility, you can write a callback function:%0a-> %25hlt php%25@@function @@%25green%25my_callback%25hlt php%25@@($m) { return strtoupper($m[1]); }@@%0a%0athen change the pattern to look like this:%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => '%25green%25my_callback%25%25',@@%0a%0aSee also: the recipe [[(Cookbook:)PccfToPcfOverride]] allows existing recipes to run on PHP 7 without causing deprecated @@create_function()@@ messages.%0a>>%3c%3c%0a%0a!![[#PPRA]] PPRA()%0a%25hlt php%25[@PPRA($array_search_replace, $string)@]%0a%0aThe %25hlt php%25@@PPRA()@@ function (''PmWiki Preg Replace Array'') can be used to perform a regular expression replacement with or without evaluation, for PHP 5.5 compatibility. %0a%0aSince PmWiki 2.2.56, PmWiki uses this function to process the following arrays: $MakePageNamePatterns, $FmtP, $QualifyPatterns, $ROEPatterns, $ROSPatterns, $SaveAttrPatterns, $MakeUploadNamePatterns. Any custom settings should continue to work for PHP 5.4 and earlier, but wikis running on PHP 5.5 may need to make a few changes.%0a%0aThe first argument contains the 'search'=>'replace' pairs, the second is the "haystack" string to be manipulated.%0a%0aThe 'replace' parts of the array can be strings or function names. If the 'replace' part is a callable function name, it will be called with the array of matches as a first argument via %25hlt php%25@@preg_replace_callback()@@. If not a callable function, a simple @@preg_replace()@@ will be performed.%0a%0aPreviously, PmWiki used such constructs:%0a-> %25hlt php%25@@$fmt = preg_replace(array_keys($FmtP), array_values($FmtP), $fmt);@@%0a%0aIt is now possible to use simply this:%0a-> %25hlt php%25@@$fmt = PPRA($FmtP, $fmt);@@%0a%0aNote that since PHP 5.5, the search patterns cannot have an /e evaluation flag. When creating the $array_search_replace array, before PHP 5.5 we could use something like (eg. for $MakePageNamePatterns):%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/e' => "strtoupper('$1')",@@%0a%0aSince PHP 5.5, we should use this (will also work in PHP 5.4 and earlier):%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => PCCF("return strtoupper(\$m[1]);"),@@%0a%0aNote that the @@/e@@ flag should be now omitted, instead of @@'$0', '$1', '$2',@@ we should use @@$m[0], $m[1], $m[2],@@ etc. in the replacement code, and there is no need to call @@PSS()@@ in the replacement code, as backslashes are not automatically added.%0a%0a>>font-style=italic%3c%3c%0aFor PHP 7.2 and newer, instead of using %25hlt php%25@@PCCF()@@ to create anonymous functions, we add a real function in our add-on, and then pass the function name as the pattern replacement (see example at [[#PCCF|PCCF]], which will also work on PHP 4 and 5):%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => '%25green%25my_callback%25%25',@@%0a>>%3c%3c%0a%0a!![[#PPRE]] PPRE() %25red%25 Deprecated since PHP 7.2%25%25%0a%25hlt php%25[@PPRE($search_pattern, $replacement_code, $string)@]%0a%0aThe %25hlt php%25@@PPRE()@@ function (''PmWiki Preg Replace Evaluate'') can be used to perform a regular expression replacement with evaluation.%0a%0aSince PHP 5.5, the %25hlt php%25@@preg_replace()@@ function has deprecated the /e evaluation flag, and displays warnings when the flag is used. The @@PPRE()@@ function automatically creates a callback function with the replacement code and calls it.%0a%0aBefore PHP 5.5, it was possible to use such calls:%0a-> %25hlt php%25@@$fmt = preg_replace('/\\$([A-Z]\\w*Fmt)\\b/e','$GLOBALS["$1"]',$fmt);@@%0a%0aSince PHP 5.5, it is possible to replace the previous snippet with the following (also works before PHP 5.5):%0a-> %25hlt php%25@@$fmt = PPRE('@@%25green%25/\\$([A-Z]\\w*Fmt)\\b/%25hlt php%25@@','$GLOBALS[$m[1]]',$fmt);@@%0a%0aNote that the @@/e@@ flag should be now omitted, instead of @@'$0', '$1', '$2',@@ we should use @@$m[0], $m[1], $m[2],@@ etc. in the replacement code, and there is no need to call @@PSS()@@ in the replacement code, as backslashes are not automatically added.%0a%0a>>font-style=italic%3c%3c%0aFor PHP 7.2 and newer, calling this function will raise "deprecated" notices. You need to rewrite your code to use [[https://www.php.net/preg_replace_callback|preg_replace_callback]], by moving the code into real functions:%0a%0a-> %25hlt php%25@@$fmt = preg_replace_callback('@@%25green%25/\\$([A-Z]\\w*Fmt)\\b/%25hlt php%25@@', 'my_global_var_callback',$fmt);@@%0a-> %25hlt php%25@@function my_global_var_callback($m) { return $GLOBALS[$m[1]]; }@@%0a%0ainstead of using %25hlt php%25@@PCCF()@@ to create anonymous functions, we add a real function in our add-on, and then pass the function name as the pattern replacement (see example at [[#PCCF|PCCF]], which will also work on PHP 4 and 5):%0a=> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => '%25green%25my_callback%25%25',@@%0a>>%3c%3c%0a%0a(:if false:)(:comment Needs review and may change:)%0a!![[#PRCB]] PRCB()%0a%25hlt php%25[@PRCB($pat, $repl, $subj, $vars=null, $limit=-1, &$count=null, $flags=0)@]%0a%0aThe %25hlt php%25@@PRCB()@@ function (''PmWiki Regex Replace Callback'') makes it simple to pass variables to a named callback function with [[https://php.net/preg_replace_callback|preg_replace_callback()]].%0a%0aIf you need to use preg_replace_callback() and pass some variables to the callback function, you can do something like:%0a%0a%25hlt php%25[@$result = PRCB($patern, 'my_callback', $subject, $pagename);@]%0a%0aThen your function will be called this way: %25hlt php%25[@my_callback($matches, $pagename);@]. You can pass multiple variables with an array.%0a%0aThe function can also be used without passing variables, just shorter than @@preg_replace_callback()@@:%0a%0a%25hlt php%25[@$result = PRCB($patern, 'my_callback', $subject);@]%0a%0a(:ifend:)%0a%0a!![[#Qualify]] Qualify()%0a%25hlt php%25[@Qualify($pagename, $text)@]%0a%0a%25hlt php%25@@Qualify()@@ applies $QualifyPatterns to convert relative links and references into absolute equivalents.%0aThis function is called by usual wiki markups that include text from other pages.%0aIt will rewrite links like %25pmhlt%25[@[[Page]]@] into [@[[Group/Page]]@], and page (text) variables like [@{$Title}@] into [@{Group.Page$Title}@]%0aso that they work the same way in the source page and in the including page.%0aSee also $QualifyPatterns and %25pmhlt%25@@[[({$Name}#)RetrieveAuthSection]]()@@.%0a%0a%0a!![[#PHSC]] PHSC()%0a%25hlt php%25[@PHSC($string_or_array, $flags=ENT_COMPAT, $encoding=null, $double_encode=true)@]%0a%0aThe %25hlt php%25@@PHSC()@@ function (''PmWiki HTML Special Characters'') is a replacement for the PHP function [[https://www.php.net/htmlspecialchars|htmlspecialchars]]. %0a%0aThe %25hlt php%25@@htmlspecialchars()@@ function was modified since PHP 5.4 in two ways: it now requires a valid string for the supplied encoding, and it changes the default encoding to UTF-8. This can cause sections of the page to become blank/empty on many sites using the ISO-8859-1 encoding without having set the third argument ($encoding) when calling @@htmlspecialchars()@@.%0a%0aThe %25hlt php%25@@PHSC()@@ function calls @@htmlspecialchars()@@ with an 8-bit encoding as third argument, whatever the encoding of the wiki (unless you supply an encoding). This way the string never contains invalid characters.%0a%0aIt should be safe for recipe developers to replace all calls to %25hlt php%25@@htmlspecialchars()@@ with calls to @@PHSC()@@. Only the first argument is required when calling @@PHSC()@@, although authors may wish to call @@PHSC($string_or_array, ENT_QUOTES)@@.%0a%0aUnlike %25hlt php%25@@htmlspecialchars()@@, the @@PHSC()@@ function can process arrays recursively (only the values are converted, not the keys of the array).%0a%0a!![[#PSS]] PSS()%0a%25hlt php%25[@PSS($string)@]%0a%0aThe %25hlt php%25@@PSS()@@ function (''PmWiki Strip Slashes'') removes the backslashes that are automatically inserted in front of quotation marks by the /e option of PHP's preg_replace function. @@PSS()@@ is%0amost commonly used in replacement arguments to @@Markup()@@, when the pattern specifies /e and one or more of the parenthesized subpatterns could contain a quote or backslash. %0a("PSS" stands for "PmWiki Strip Slashes".)%0a->From PM: PmWiki expects %25hlt php%25@@PSS()@@ to always occur inside of double-quoted strings and to contain single quoted strings internally. The reason for this is that we don't want the @@$1@@ or @@$2@@ to accidentally contain characters that would then be interpreted inside of the double-quoted string when the PSS is evaluated.%0a-->%25hlt php%25@@Markup('foo', 'inline', '/(something)/e', 'Foo(PSS("$1"))'); # wrong@@%0a-->%25hlt php%25@@Markup('foo', 'inline', '/(something)/e', "Foo(PSS('$1'))"); # right@@%0a%0a%25note%25 Note, the extra slashes are only added by %25hlt php%25@@preg_replace()@@ with an @@/e@@ modifier. The markup definitions with @@Markup_e()@@ do NOT need to use @@PSS()@@ in the replacement strings. The new-type markup definitions with @@Markup()@@ and a simple function name as a replacement do NOT need to use @@PSS()@@ inside the replacement function. If you migrate old markup rules to the new format, delete the @@PSS()@@ calls.%0a%0a!!! Example %25block notoc%25%0aThis is a fictitious example where %25hlt php%25@@PSS()@@ should be used.%0aLet us assume that you wish to define a directive %25pmhlt%25[@(:example:)@]%0asuch that %25pmhlt%25[@(:example "A horse":)@] results in the HTML%0a-> %25hlt html%25[@%3cdiv>"A horse"%3c/div>@].%0aHere is how the markup rule can be created:%0a-> %25hlt php%25[@%0aMarkup('example', 'directives',%0a '/\\(:example\\s(.*?):\\)/e',%0a "Keep('%3cdiv>'.PSS('$1').'%3c/div>')");%0a@]%0aWe need to use %25hlt php%25@@PSS()@@ around the '@@$1@@' because the matched text could contain quotation marks, and the @@/e@@ will add backslashes in front of them.%0a%0a!![[#stripmagic]] stripmagic()%0a%25hlt php%25[@stripmagic($string)@]%0a%0aThis function should be used when processing the contents of %25hlt php%25[@$_POST@] or [@$_GET@] variables when they could contain quotes or backslashes. It verifies [@get_magic_quotes()@], if true, strips the automatically inserted escapes from the string.%0a%0aThe function can process arrays recursively (only the values are processed).%0a%0a!![[#FmtPageName]] FmtPageName()%0a%0a%25hlt php%25[@FmtPageName($fmt, $pagename)@]%0a%0a[[#FmtPageName-desc]]Returns %25hlt php%25[@$fmt@], with @@$variable@@ and [=$[internationalisation]=] substitutions performed, under the assumption that the current page is [@pagename@]. See [[PmWiki.Variables]] for an (incomplete) list of available variables, [[PmWiki.Internationalizations]] for internationalisation. Security: not to be run on user-supplied data.%0a%0aThis is one of the major functions in PmWiki, see [[PmWiki.FmtPageName]] for%0alots of details.%0a%0a%0a!![[#Markup]] Markup()%0a%25hlt php%25[@Markup($name, $when, $pattern, $replace)@]%0a%0a[[#Markup-desc]]Adds a new markup to the conversion table. Described in greater detail at [[PmWiki.CustomMarkup]].%0a%0aThis function is used to insert translation rules into the PmWiki's translation engine. The arguments to %25hlt php%25[@Markup()@] are all strings, where:%0a%0a:%25hlt php%25[@$name@]: The string names the rule that is inserted. If a rule of the same name already exists, then this rule is ignored.%0a:%25hlt php%25[@$when@]: This string is used to control ''when'' a rule is to be applied relative to other rules. A specification of "[@%3cxyz@]" says to apply this rule prior to the rule named "xyz", while "[@>xyz@]" says to apply this rule after the rule "xyz". See [[(PmWiki:)CustomMarkup]] for more details on the order of rules.%0a:%25hlt php%25[@$pattern@]: This string is a [[regular expression -> https://www.php.net/preg_replace]] that is used by the translation engine to look for occurrences of this rule in the markup source.%0a:%25hlt php%25[@$replace@]: This string will replace the matched text when a match occurs, or the function name that will return the replacement text.%0a%0aAlso see: [[PmWiki.CustomMarkup]] and [[Cookbook:Functions#Markup]]%0a%0a!![[#MarkupToHTML]] MarkupToHTML()%0a%0a%25hlt php%25[@MarkupToHTML($pagename, $str)@]%0a%0a[[#MarkupToHTML-desc]] Converts the string %25hlt php%25[@$str@] containing PmWiki markup into the corresponding HTML code, assuming the current page is [@$pagename@].%0a%25hlt php%25@@MarkupToHTML()@@ replaces @@\n\n@@ sequences by @@%3c:vspace>@@ first thing when text is passed to it. Subsequently @@%3c:vspace>@@ is processed by the markup rules:%0a-> '@@!vspace@@' removes @@%3c:vspace>@@ after headings.%0a-> '@@%3cvspace>%3cp>@@' replaces @@%3c:vspace>%3cp>@@ with @@%3cp class='vspace'>@@%0a-> '@@%3cvspace>@@' replaces %3c:vspace> with @@%3cdiv class='vspace'>@@%0a-> and finally%0a-> '@@^%3c:@@' removes any remaining @@%3c:vspace>@@, mostly from restored [=[=]=escaped text=].%0a%0aAlso see: [[Cookbook:Functions#MarkupToHTML]]%0a%0a!![[#mkdirp]] mkdirp()%0a%25hlt php%25[@mkdirp($dir)@]%0a%0aThe function %25hlt php%25[@mkdirp($dir)@] creates a directory, [@$dir@], if it doesn't already exist, including any parent directories that might be needed. For each directory created, it checks that the permissions on the directory are sufficient to allow PmWiki scripts to read and write files in that directory. This includes checking for restrictions imposed by PHP's safe_mode setting. If [@mkdirp()@] is unable to successfully create a read/write directory, [@mkdirp()@] aborts with an error message telling the administrator the steps to take to either create @@$dir@@ manually or give PmWiki sufficient permissions to be able to do it.%0a%0a!![[#Lock]] Lock()%0a%25hlt php%25[@Lock(0)@]%0a%0aThis function is used to make sure only one instance of PmWiki is running when files are being written. It does not "lock pages" for editing.%0a%0aFrom a recipe, use:%0a* %25hlt php%25[@Lock(2);@] to acquire an ''exclusive'' lock, so that no other PHP processes can modify files. This can be used when your function is writing files on the server.%0a* %25hlt php%25[@Lock(1);@] to acquire a ''shared'' lock. This may be used when your function is reading files from the server, in case another process is writing them at the same time.%0a* %25hlt php%25[@Lock(0);@] to ''release'' a previous exclusive or shared lock. Use this immediately after your function finishes reading or writing the files.%0a%0aIf you don't release an acquired lock, it should be automatically released at the end of the processing.%0a%0a%0a!![[#MakeLink]] MakeLink()%0a%25hlt php%25[@MakeLink($pagename, $target, $txt, $suffix, $fmt)@]%0a%0aThe function %25hlt php%25[@MakeLink($pagename, $target, $txt, $suffix, $fmt)@] returns an html-formatted anchor link. Its arguments are as follows:%0a $pagename is the source page%0a $target is where the link should go%0a $txt is the value to use for '$LinkText' in the output %0a $suffix is any suffix string to be added to $txt%0a $fmt is a format string to use%0a%0aIf $txt is NULL or not specified, then it is automatically computed from $target.%0a%0aIf $fmt is NULL or not specified, then MakeLink uses the default%0aformat as specified by the type of link. For page links this%0ameans the $LinkPageExistsFmt and $LinkPageCreateFmt variables,%0afor intermap-style links it comes from either the $IMapLinkFmt%0aarray or from $UrlLinkFmt. Inside of the formatting strings,%0a$LinkUrl is replaced by the resolved url for the link, $LinkText%0ais replaced with the appropriate text, and $LinkAlt is replaced%0aby any "title" (alternate text) information associated with the%0alink.%0a%0aAlso see: [[PmWiki:MakeLink]] and [[Cookbook:Functions#MakeLink]]%0a%0a!![[#MakeUploadName]] MakeUploadName()%0a%25hlt php%25@@MakeUploadName($pagename, $x)@@%0a%0a%25hlt php%25@@MakeUploadName()@@ simply takes a string @@$x@@ (representing an attachment's%0aname) and converts it to a valid name by removing any unwanted characters.%0aIt also requires the name to begin and end with an alphanumeric character,%0aand as of 2.0.beta28 it forces any file extensions to lowercase.%0aThis function is defined in @@scripts/upload.php@@ and only used when uploads%0aare enabled.%0a%0a!![[#DownloadUrl]] DownloadUrl()%0a%25hlt php%25@@DownloadUrl($pagename, $path)@@%0a%0aThis function returns the public URL of an attached file. The arguments are as follow:%0a* $pagename - the currently processed page%0a* %25hlt php%25@@$path@@ - the file path, as in @@file.ext@@ or @@OtherPage/file.ext@@ or @@Group/OtherPage/file.ext@@%0a%0aIf the file doesn't exist, the function returns false. The global variable %25hlt php%25@@$FmtV['$LinkUpload']@@ contains the URL to the upload form, for a file with such a name to be attached. The global variable %25hlt php%25@@$FmtV['$LinkDownload']@@ contains the URL to the file, as if it were uploaded to the wiki.%0a%0aThe function calls [[#MakeUploadName|%25hlt php%25@@MakeUploadName()@@]] on the @@$path@@ argument so you don't need to do it before calling it.%0a%0aThe returned URL respects $UploadPrefixFmt and $EnableDirectDownload of the wiki.%0a%0a%0a!![[#SessionAuth]] SessionAuth()%0a%25hlt php%25[@SessionAuth($pagename, $auth=NULL)@]%0a%0a%25hlt php%25@@SessionAuth()@@ manages keeping authentication via cookie-sessions. Session contains every password or validated id and associated groups from previous calls. It adds elements passed by @@$auth@@ to session. It also writes every element saved in session to @@$AuthPw(passwords)@@ and @@$AuthList(ids and groups)@@.%0a%0a!![[#IsAuthorized]] IsAuthorized()%0a%25hlt php%25[@IsAuthorized($chal, $source, &$from)@]%0a%0a%25hlt php%25@@IsAuthorized()@@ takes a pageattributesstring (e. g. "id:user1 $1$Ff3w34HASH...") in @@$chal@@.%0a%0a%25hlt php%25@@$source@@ is simply returned and used for building the authcascade (pageattributes - groupattributes - @@$DefaultPassword@@).%0a%0a%25hlt php%25@@$from@@ will be returned if @@$chal@@ is empty, because it is not checked before calling @@IsAuthorized()@@, this is needed for the authcascade. %0a%25hlt php%25@@IsAuthorized()@@ returns an array with three values: @@$auth@@ @@1@@ - authenticated, @@0@@ - not authenticated, @@-1@@ - refused; @@$passwd@@; @@$source@@ from the parameter list.%0a%0a!![[#CondAuth]] CondAuth()%0a%25hlt php%25[@CondAuth($pagename, 'auth level')@]%0a%0a%25hlt php%25[@CondAuth()@]%25%25 implements the [[ConditionalMarkup]] for %25pmhlt%25[@(:if auth level:)@]%25%25. For instance %25hlt php%25[@ CondAuth($pagename,'edit')@]%25%25 is true if authorization level is 'edit'. Use inside local configuration files to build conditionals with a check of authorization level, similar to using %25pmhlt%25[@(:if auth level:)@]%25%25 on a wiki page.%0a%0aNote that %25hlt php%25@@CondAuth()@@ should be called after all authorization levels and passwords have been defined. For example, if you use it with [[Drafts]], you should include the @@draft.php@@ script before calling @@CondAuth()@@:%0a%25hlt php%25[@%0a $EnableDrafts = 1;%0a $DefaultPasswords['publish'] = pmcrypt('secret');%0a include_once("$FarmD/scripts/draft.php");%0a if (! CondAuth($pagename, 'edit')) { /* whatever */ }%0a@]%0aBest is to use %25hlt php%25@@CondAuth()@@ near the bottom of your @@config.php@@ script.%0a%0a!! [[#RetrieveAuthPage]] RetrieveAuthPage()%0a%25hlt php%25@@RetrieveAuthPage($pagename, $level, $authprompt=true, $since=0)@@%0a%0aPm words as said in https://www.pmwiki.org/pipermail/pmwiki-users/2005-April/012804.html %0awhere:%0a%0a $pagename - name of page to be read%0a $level - authorization level required (read/edit/auth/upload)%0a $authprompt - true if user should be prompted for a password if needed%0a $since - how much of the page history to read%0a 0 == read entire page including all of history%0a READPAGE_CURRENT == read page without loading history%0a timestamp == read history only back through timestamp%0a%0aThe @@$since@@ parameter allows PmWiki to stop reading from a page file%0aas soon as it has whatever information is needed -- i.e., if an operation%0asuch as browsing isn't going to need the page's history, then specifying%0aREADPAGE_CURRENT can result in a much faster loading time. (This can be %0aespecially important for things such as searching and page listings.)%0aHowever, if combined with %25hlt php%25@@UpdatePage()@@, the updated page will have no history.%0a%0aUse e.g. %25hlt php%25[@$page = @RetrieveAuthPage('Main.MyPage', 'read')@] to obtain a page object that contains all the information of the correspondent file in separate keys, e.g. [@$page['text']@] will contain a string with the current wiki markup of Main.MyPage. Use this generally in preference to the alternative function [@ReadPage($pagename, $since=0)@] since it respects the authorisation of the user, i.e. it checks the authorisation level before loading the page, or it can be set to do so. [@ReadPage()@] reads a page regardless of permission.%0a%0aPassing 'ALWAYS' as the authorization level (instead of 'read', 'edit', etc.) will cause %25hlt php%25@@RetrieveAuthPage()@@ to always read and return the page, even if it happens to be protected by a read password.%0a%0a%0a!! [[#RetrieveAuthSection]] RetrieveAuthSection()%0a%25hlt php%25@@RetrieveAuthSection($pagename, $pagesection, $list=NULL, $auth='read')@@%0a%0a%25hlt php%25@@RetrieveAuthSection()@@ extracts a section of text from a page. If @@$pagesection@@ starts with anything other than '@@#@@', the text before the first '@@#@@' (or all of it, if there is no '@@#@@') identifies the page to extract text from. Otherwise @@RetrieveAuthSection()@@ looks in the pages given by @@$list@@ (should be an array), or in @@$pagename@@ if @@$list@@ is not specified. %0a* The selected page is placed in the global @@$RASPageName@@ variable. %0a* The caller is responsible for calling %25hlt php%25@@Qualify()@@ as needed, i.e. if you need to control how unqualified page and variable names shall be resolved.%0a** To have them act as in the original text, let %25hlt php%25@@Qualify()@@ resolve them relative to the source page.%0a** If the imported text was not meant as wikitext but as some other kind of markup that might happen to contain double pairs of square brackets, (:comment %3c-- not: pairs of 〚double square brackets〛 = U+301A/U+301B:) or dollar signs inside curly brackets, you probably don't want to %25hlt php%25@@Qualify()@@ them. If you output them into wikitext, you'll probably need to @@Keep()@@ the text (:comment %3c-- translators: conceptually this means to have Keep() pack the text in a container that marks it as "final".:) (in case of HTML, XML, RSS or similar output, @@PHSC()@@ first!), to prevent later stages of processing from interpreting the apparent wiki markups in context of the target page.%0a** If your code produces wikitext for an auxiliary page that is meant to be included by another page higher up in the inclusion chain, and want links and variables to work as if they were in the auxiliary page, use the auxiliary page's "GroupName.PageName" as the $pagename argument for %25hlt php%25@@Qualify()@@.%0a%0aProvides a way to limit the array that is returned by ReadPage, so that it only pulls the content up to a specific section marker. For example, pulling from start of page to '##blogend':%0a->%25hlt php%25[@%0afunction FeedText($pagename, &$page, $tag) {%0a $text = RetrieveAuthSection($pagename, '##blogend');%0a $content = MarkupToHTML($pagename, $text);%0a return "%3c$tag>%3c![CDATA[$content]]>%3c/$tag>";%0a}%0a@]%0a%0aThe '##blogend' argument says to read from the beginning of the page to just before the line containing the [[#blogend]] marker. See%0a[[PmWiki:IncludeOtherPages | IncludeOtherPages]] for more information about the section specifications.%0a%0aThis version won't read text from pages that are read-protected; if you want to get text even from read-protected pages, then %0a->%25hlt php%25[@%0a $text = RetrieveAuthSection($pagename, '##blogend', NULL, 'ALWAYS');%0a@]%0a%0a%0a!! [[#UpdatePage]] UpdatePage()%0a%25hlt php%25@@UpdatePage($pagename, $old (page object), $new (page object));@@%0a%0a''[[PmWiki:UpdatePage|More Technical Notes]]''%0a%0a%25hlt php%25[@UpdatePage()@] allows cookbook recipes to mimic the behavior of editing wiki pages via the browser. Internally, PmWiki does several housekeeping tasks which are accessible via this function (preserving history/diff information, updating page revision numbers, updating RecentChanges pages, sending email notifications, etc._%0a* "Page object" refers to an array pulled from %25hlt php%25[@RetrieveAuthPage($pagename, $level, $authprompt=true, $since=0);@] (preferred), or [@ReadPage($pagename); @] (disregards page security). Note that @@$new['text']@@ should contain all page data for the new version of the page. %0a* If a page doesn't exist, %25hlt php%25@@UpdatePage()@@ will attempt to create it.%0a* Ignoring @@$old@@ (e.g. %25hlt php%25[@UpdatePage($pagename, '', $new);@]) will erase all historical page data---a ''tabula rasa''.%0a** If you retrieved @@$old@@ using %25hlt php%25@@RetrieveAuthPage($pagename,$auth,$prompt,READPAGE_CURRENT)@@ and set @@$new=$old@@, then @@UpdatePage()@@ will also erase all historical data%0a%25hlt php%25@@UpdatePage()@@ cannot be called directly from @@config.php@@ because there are necessary initializations which occur later in @@pmwiki.php@@. It is not enough to just load @@stdconfig.php@@. If you want to use @@UpdatePage()@@ you will need to do it within a [[PmWiki:CustomMarkup | custom markup]], a [[Cookbook:MarkupExpressionSamples | custom markup expression]], or a [[PmWiki:CustomActions | custom action]].%0a%0a%0a!! [[#InsertEditFunction]] InsertEditFunction()%0a%25hlt php%25@@InsertEditFunction($newfn, $where='%3cPostPage')@@%0a%0aThis function makes it easy for recipe authors to insert a custom function in a specific position of the processing, see $EditFunctions and [[#UpdatePage|UpdatePage()]]. %0a%0aThe first argument is the name of the new function.%0a%0aThe second argument is the position where to place the new function, related to other edit functions? It can be:%0a* @@"%3c"@@ at the start, before the first edit function%0a* @@">"@@ at the end, after the last edit function%0a* @@"%3cExistingEditFunction"@@ before a specified edit function%0a* @@">ExistingEditFunction"@@ after a specified edit function%0a%0aThe function will return ''true'' on success, and ''false'' on failure (when the specified position or existing function was not recognized).%0a%0a!! [[#DisableSkinParts]] DisableSkinParts()%0a%25hlt php%25@@DisableSkinParts('parts to disable');@@%0a%0aThis function allows easy disabling of the skin sections header, footer, title, actions, and sidebars, like the corresponding directives %25pmhlt%25@@[=(:notitle:) (:noleft:)=]@@ etc. In your function, use something like:%0a->%25hlt php%25[@%0a DisableSkinParts('Left Header Footer Action Title');%0a@]%0a%0a!! [[#ParseArgs]] ParseArgs()%0aSee Cookbook:ParseArgs. %0a%0a!! [[#Redirect]] Redirect()%0a%0a!! [[#PageIndexTerms]] PageIndexTerms()%0a%0a!! [[#AsSpaced]] AsSpacedUTF8(), AsSpaced()%0a>>hlt php%3c%3c%0a@@AsSpaced()@@ is declared in @@pmwiki.php@@ \\%0a@@AsSpaced()@@ converts a string with WikiWords into a spaced version of that string.%0aIt can be overridden via $AsSpacedFunction, as it is in @@AsSpacedUTF8()@@. \\%0a@@AsSpacedUTF8()@@ is declared in the @@xlpage-utf-8.php@@ script.%0a>>%3c%3c%0a%0aCategories: [[!PmWiki Developer]]
-time=1715681109
+text=(:Summary: How some of the functions in pmwiki.php work:)%0a(:Audience: admins (advanced) :)%0a%0aThis page describes some of the internal workings of PmWiki by explaining how some of the functions in @@pmwiki.php@@ work. For a more brief list/overview on functions useful to for instance cookbook writers, see Cookbook:Functions. %0a%0aTo use this functions you have to make sure that all relevant internal variables have been initialized correctly. See [[Custom Markup]] and [[(PmWiki:)Custom Actions]] for more information on how these functions are typically called via %25hlt php%25[@Markup()@] or [@$HandleActions[]@].%0a%0a!! [[#PSFT]] PSFT()%0a%0a%25hlt php%25[@PSFT($format, $timestamp=null, $locale=null, $tz=null)@]%0a%0aThe %25hlt php%25@@PSFT()@@ function (''PmWiki String Format Time'', added in 2.3.0) is intended to be a safe replacement for the very widely used PHP functions @@[[https://www.php.net/strftime|strftime()]]@@ and @@[[https://www.php.net/gmstrftime|gmtstrftime()]]@@ which became deprecated in PHP 8.1.%0a%0aUnlike %25hlt php%25@@strftime()@@, @@PSFT()@@ accepts 2 additional arguments @@$locale@@ and @@$tz@@, which allow to set a different language or timezone.%0a%0aPmWiki 2.3.0 uses this function in all cases where it previously used %25hlt php%25@@strftime()@@, including the %25pmhlt%25[@{(ftime)}@] Markup Expression. If your local customizations and recipes use %25hlt php%25@@strftime()@@, you should be able to safely replace all calls to @@strftime()@@ with @@PSFT()@@, without changing the arguments. Any calls to @@gmtstrftime($fmt, $stamp)@@ can be replaced with @@PSFT($fmt, $stamp, null, 'GMT')@@.%0a%0aThe old functions were deprecated by the PHP developers because they behaved inconsistently on different platforms, and were dependent on installed system locales (i.e. a language would only work if the system had its locale installed). The new function uses the PHP class [[https://www.php.net/manual/en/class.intldateformatter.php|IntlDateFormatter]] and should be better. Unfortunately, it is not always enabled by hosting providers. %0a%0aSo depending on your installation, a specific language may be available with %25hlt php%25@@strftime()@@ and/or with @@IntlDateFormatter@@.%0a%0aIn addition, some rarely used shortcut percent-formats [@%25c, %25x, %25X@] also behave inconsistently on different platforms, and the new formatter may show a slightly different output. You can always replace these shortcut formats with the full formats you require.%0a%0aFor these reasons, %25hlt php%25@@PSFT()@@ is currently a compromise, by default reusing @@strftime()@@ for PHP 8.0 or earlier. Updating your calls from @@strftime()@@ shouldn't cause any changes in your outputs.%0a%0aYou can set in @@config.php@@ the variable %25hlt php%25@@$EnableFTimeNew = 1;@@ for @@PSFT()@@ to try using @@IntlDateFormatter@@ before PHP 8.1. If @@IntlDateFormatter@@ is not available, it will show the month and day names in English. Check what works.%0a%0aSince the %25hlt php%25@@strftime()@@ function is deprecated, it is unlikely for it to add new formats. We have added 2 custom formats:%0a* [@%25o@] for the "ordinal suffix" of the date, as "st" in "January 1st". If @@IntlDateFormatter@@ is not available, it will show the suffix in English%0a* [@%25L@] for a human-readable timestamp of the format %25pmhlt%25[@@2022-09-25T11:49:08Z@]%25%25 which will be displayed formatted either as $TimeFmt or in the local time zone of the visitor, see $EnableLocalTimes.%0a%0a(:include MarkupExpressions#ftimeformats#ftimeformatsend:)%0a%0a>>frame%3c%3c%0aA difference between %25hlt php%25@@strftime($format, $stamp)@@ and @@PSFT($format, $stamp)@@ is how they interpret a false, empty or non-numeric @@$stamp@@ argument.%0a|| class=simpletable%0a||! @@$stamp@@ argument ||! @@strftime($format, $stamp)@@ ||! @@PSFT($format, $stamp)@@ ||%0a|| numeric || the stamp || the stamp ||%0a|| missing or ''null'' || current time || current time ||%0a|| ''false'' || 1970-01-01 || current time ||%0a|| "" (empty string) \\%0aother non-numeric || 1970-01-01 or ''false'' (older PHP versions) \\%0a ''Warning: TypeError'' (PHP 7.4+) || current time ||%0aFor PmWiki, it seemed reasonable to make empty strings and other non-numeric values default to the current time. If your %25hlt php%25@@$stamp@@ variable may be empty or ''false'', and your recipes rely on @@strftime()@@ returning "1970-01-01", you can cast the stamp to integer:%0a%25hlt php%25[@%0a PSFT($format, intval($stamp));%0a@]%0a>>%3c%3c%0a%0a%0a!! [[#pmtoken]] pmtoken()%0a%25hlt php%25[@pmtoken($check = 0, $abort = false)@]%0a%0aThe %25hlt php%25@@pmtoken()@@ function sets or checks a unique session identifier to be used in input forms, with the goal of preventing cross-site request forgeries (CSRF).%0a%0aCalling %25hlt php%25@@pmtoken()@@ or @@pmtoken(0)@@ will create a token if it doesn't exist, store it in the @@$_SESSION@@ array, and return it. It will also set the variables [@$FmtV['$TokenValue']@] which can be used in HTML templates and [@$InputValues['pmtoken']@] to be used in markup [[forms]], although it may be simpler to use %25pmhlt%25[@(:input pmtoken:)@] instead.%0a%0aThe name of the input element, by default 'pmtoken', can be changed by setting for example %25hlt php%25[@$FmtV['$TokenName'] = 'CSRFtoken';@].%0a%0aCalling %25hlt php%25@@pmtoken(1)@@ will check the @@$_POST['pmtoken']@@ value and will return true if it is valid.%0a%0aCalling %25hlt php%25@@pmtoken(2)@@ will check the @@$_GET['pmtoken']@@ value and will return true if it is valid.%0a%0aCalling %25hlt php%25@@pmtoken(1, true)@@ or @@pmtoken(2, true)@@ with a second truthy argument, and the token is invalid, will directly call @@Abort()@@ and exit.%0a%0a%0a!! [[#pmcrypt]] pmcrypt()%0a%25hlt php%25[@pmcrypt($password, $salt = null)@]%0a%0aThe %25hlt php%25@@pmcrypt()@@ function is intended to be a safe replacement for the [[https://www.php.net/crypt|PHP 5.6+ crypt() function]] without providing a $salt, which would raise a notice. If a salt is provided, crypt() is called to check an existing password. If a salt is not provided, [[https://www.php.net/password_hash|password_hash()]] will be called to create a cryptographically strong password hash.%0a%0a!! [[#pmsetcookie]] pmsetcookie()%0a%25hlt php%25[@pmsetcookie($name, $val="", $exp=0, $path="", $dom="", $secure=null, $httponly=null)@]%0a%0aThis function is intended as a replacement for [[https://www.php.net/setcookie|setcookie()]]. It will automatically set the $secure and $httponly arguments if they are not set by the caller function and if $EnableCookieSecure and $EnableCookieHTTPOnly are enabled.%0a%0a!![[#PCCF]] PCCF() %25red%25 Deprecated since PHP 7.2%25%25%0a%25hlt php%25[@PCCF($php_code, $callback_template='default', $callback_arguments = '$m')@] %0a%0aThe %25hlt php%25@@PCCF()@@ function (''PmWiki Create Callback Function'') can be used to create callback functions used with [[https://www.php.net/preg_replace_callback|preg_replace_callback]]. It is required for PHP 5.5, but will also work with earlier PHP versions.%0a%0aThe first argument is the PHP code to be evaluated. %0a%0aThe second argument (optional) is the callback template, a key from the global @@$CallbackFnTemplates@@ array. There are two templates that can be used by recipe authors: %0a* 'default' will pass @@$php_code@@ as a function code%0a* 'return' will wrap @@$php_code@@ like "@@return $php_code;@@" (since PmWiki 2.2.62)%0a%0aThe third argument (optional) is the argument of the callback function. Note that PmWiki uses the '$m' argument to pass the matches of a regular expression search, but your function can use other argument(s).%0a%0a%25hlt php%25@@PCCF()@@ will create an anonymous (lambda) callback function containing the supplied code, and will cache it. On subsequent calls with the same @@$php_code@@, @@PCCF()@@ will return the cached function name.%0a%0aSee the [[https://www.php.net/create_function | PHP create function]].%0a%0a>>font-style=italic%3c%3c%0aPHP 7.2 deprecates %25hlt php%25@@create_function()@@ and future versions will remove it. If you need to migrate older code that used @@PCCF()@@, you can usually write regular functions and pass the function name where you previously passed the result of PCCF(). For example, suppose you had a pattern like this:%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => PCCF("return strtoupper(\$m[1]);"),@@%0a%0aFor PHP 7.2 compatibility, you can write a callback function:%0a-> %25hlt php%25@@function @@%25green%25my_callback%25hlt php%25@@($m) { return strtoupper($m[1]); }@@%0a%0athen change the pattern to look like this:%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => '%25green%25my_callback%25%25',@@%0a%0aSee also: the recipe [[(Cookbook:)PccfToPcfOverride]] allows existing recipes to run on PHP 7 without causing deprecated @@create_function()@@ messages.%0a>>%3c%3c%0a%0a!![[#PPRA]] PPRA()%0a%25hlt php%25[@PPRA($array_search_replace, $string)@]%0a%0aThe %25hlt php%25@@PPRA()@@ function (''PmWiki Preg Replace Array'') can be used to perform a regular expression replacement with or without evaluation, for PHP 5.5 compatibility. %0a%0aSince PmWiki 2.2.56, PmWiki uses this function to process the following arrays: $MakePageNamePatterns, $FmtP, $QualifyPatterns, $ROEPatterns, $ROSPatterns, $SaveAttrPatterns, $MakeUploadNamePatterns. Any custom settings should continue to work for PHP 5.4 and earlier, but wikis running on PHP 5.5 may need to make a few changes.%0a%0aThe first argument contains the 'search'=>'replace' pairs, the second is the "haystack" string to be manipulated.%0a%0aThe 'replace' parts of the array can be strings or function names. If the 'replace' part is a callable function name, it will be called with the array of matches as a first argument via %25hlt php%25@@preg_replace_callback()@@. If not a callable function, a simple @@preg_replace()@@ will be performed.%0a%0aPreviously, PmWiki used such constructs:%0a-> %25hlt php%25@@$fmt = preg_replace(array_keys($FmtP), array_values($FmtP), $fmt);@@%0a%0aIt is now possible to use simply this:%0a-> %25hlt php%25@@$fmt = PPRA($FmtP, $fmt);@@%0a%0aNote that since PHP 5.5, the search patterns cannot have an /e evaluation flag. When creating the $array_search_replace array, before PHP 5.5 we could use something like (eg. for $MakePageNamePatterns):%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/e' => "strtoupper('$1')",@@%0a%0aSince PHP 5.5, we should use this (will also work in PHP 5.4 and earlier):%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => PCCF("return strtoupper(\$m[1]);"),@@%0a%0aNote that the @@/e@@ flag should be now omitted, instead of @@'$0', '$1', '$2',@@ we should use @@$m[0], $m[1], $m[2],@@ etc. in the replacement code, and there is no need to call @@PSS()@@ in the replacement code, as backslashes are not automatically added.%0a%0a>>font-style=italic%3c%3c%0aFor PHP 7.2 and newer, instead of using %25hlt php%25@@PCCF()@@ to create anonymous functions, we add a real function in our add-on, and then pass the function name as the pattern replacement (see example at [[#PCCF|PCCF]], which will also work on PHP 4 and 5):%0a-> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => '%25green%25my_callback%25%25',@@%0a>>%3c%3c%0a%0a!![[#PPRE]] PPRE() %25red%25 Deprecated since PHP 7.2%25%25%0a%25hlt php%25[@PPRE($search_pattern, $replacement_code, $string)@]%0a%0aThe %25hlt php%25@@PPRE()@@ function (''PmWiki Preg Replace Evaluate'') can be used to perform a regular expression replacement with evaluation.%0a%0aSince PHP 5.5, the %25hlt php%25@@preg_replace()@@ function has deprecated the /e evaluation flag, and displays warnings when the flag is used. The @@PPRE()@@ function automatically creates a callback function with the replacement code and calls it.%0a%0aBefore PHP 5.5, it was possible to use such calls:%0a-> %25hlt php%25@@$fmt = preg_replace('/\\$([A-Z]\\w*Fmt)\\b/e','$GLOBALS["$1"]',$fmt);@@%0a%0aSince PHP 5.5, it is possible to replace the previous snippet with the following (also works before PHP 5.5):%0a-> %25hlt php%25@@$fmt = PPRE('@@%25green%25/\\$([A-Z]\\w*Fmt)\\b/%25hlt php%25@@','$GLOBALS[$m[1]]',$fmt);@@%0a%0aNote that the @@/e@@ flag should be now omitted, instead of @@'$0', '$1', '$2',@@ we should use @@$m[0], $m[1], $m[2],@@ etc. in the replacement code, and there is no need to call @@PSS()@@ in the replacement code, as backslashes are not automatically added.%0a%0a>>font-style=italic%3c%3c%0aFor PHP 7.2 and newer, calling this function will raise "deprecated" notices. You need to rewrite your code to use [[https://www.php.net/preg_replace_callback|preg_replace_callback]], by moving the code into real functions:%0a%0a-> %25hlt php%25@@$fmt = preg_replace_callback('@@%25green%25/\\$([A-Z]\\w*Fmt)\\b/%25hlt php%25@@', 'my_global_var_callback',$fmt);@@%0a-> %25hlt php%25@@function my_global_var_callback($m) { return $GLOBALS[$m[1]]; }@@%0a%0ainstead of using %25hlt php%25@@PCCF()@@ to create anonymous functions, we add a real function in our add-on, and then pass the function name as the pattern replacement (see example at [[#PCCF|PCCF]], which will also work on PHP 4 and 5):%0a=> %25hlt php%25@@'/(?%3c=^| )([a-z])/' => '%25green%25my_callback%25%25',@@%0a>>%3c%3c%0a%0a(:if false:)(:comment Needs review and may change:)%0a!![[#PRCB]] PRCB()%0a%25hlt php%25[@PRCB($pat, $repl, $subj, $vars=null, $limit=-1, &$count=null, $flags=0)@]%0a%0aThe %25hlt php%25@@PRCB()@@ function (''PmWiki Regex Replace Callback'') makes it simple to pass variables to a named callback function with [[https://php.net/preg_replace_callback|preg_replace_callback()]].%0a%0aIf you need to use preg_replace_callback() and pass some variables to the callback function, you can do something like:%0a%0a%25hlt php%25[@$result = PRCB($patern, 'my_callback', $subject, $pagename);@]%0a%0aThen your function will be called this way: %25hlt php%25[@my_callback($matches, $pagename);@]. You can pass multiple variables with an array.%0a%0aThe function can also be used without passing variables, just shorter than @@preg_replace_callback()@@:%0a%0a%25hlt php%25[@$result = PRCB($patern, 'my_callback', $subject);@]%0a%0a(:ifend:)%0a%0a!![[#Qualify]] Qualify()%0a%25hlt php%25[@Qualify($pagename, $text)@]%0a%0a%25hlt php%25@@Qualify()@@ applies $QualifyPatterns to convert relative links and references into absolute equivalents.%0aThis function is called by usual wiki markups that include text from other pages.%0aIt will rewrite links like %25pmhlt%25[@[[Page]]@] into [@[[Group/Page]]@], and page (text) variables like [@{$Title}@] into [@{Group.Page$Title}@]%0aso that they work the same way in the source page and in the including page.%0aSee also $QualifyPatterns and %25pmhlt%25@@[[({$Name}#)RetrieveAuthSection]]()@@.%0a%0a%0a!![[#PHSC]] PHSC()%0a%25hlt php%25[@PHSC($string_or_array, $flags=ENT_COMPAT, $encoding=null, $double_encode=true)@]%0a%0aThe %25hlt php%25@@PHSC()@@ function (''PmWiki HTML Special Characters'') is a replacement for the PHP function [[https://www.php.net/htmlspecialchars|htmlspecialchars]]. %0a%0aThe %25hlt php%25@@htmlspecialchars()@@ function was modified since PHP 5.4 in two ways: it now requires a valid string for the supplied encoding, and it changes the default encoding to UTF-8. This can cause sections of the page to become blank/empty on many sites using the ISO-8859-1 encoding without having set the third argument ($encoding) when calling @@htmlspecialchars()@@.%0a%0aThe %25hlt php%25@@PHSC()@@ function calls @@htmlspecialchars()@@ with an 8-bit encoding as third argument, whatever the encoding of the wiki (unless you supply an encoding). This way the string never contains invalid characters.%0a%0aIt should be safe for recipe developers to replace all calls to %25hlt php%25@@htmlspecialchars()@@ with calls to @@PHSC()@@. Only the first argument is required when calling @@PHSC()@@, although authors may wish to call @@PHSC($string_or_array, ENT_QUOTES)@@.%0a%0aUnlike %25hlt php%25@@htmlspecialchars()@@, the @@PHSC()@@ function can process arrays recursively (only the values are converted, not the keys of the array).%0a%0a!![[#PSS]] PSS()%0a%25hlt php%25[@PSS($string)@]%0a%0aThe %25hlt php%25@@PSS()@@ function (''PmWiki Strip Slashes'') removes the backslashes that are automatically inserted in front of quotation marks by the /e option of PHP's preg_replace function. @@PSS()@@ is%0amost commonly used in replacement arguments to @@Markup()@@, when the pattern specifies /e and one or more of the parenthesized subpatterns could contain a quote or backslash. %0a("PSS" stands for "PmWiki Strip Slashes".)%0a->From PM: PmWiki expects %25hlt php%25@@PSS()@@ to always occur inside of double-quoted strings and to contain single quoted strings internally. The reason for this is that we don't want the @@$1@@ or @@$2@@ to accidentally contain characters that would then be interpreted inside of the double-quoted string when the PSS is evaluated.%0a-->%25hlt php%25@@Markup('foo', 'inline', '/(something)/e', 'Foo(PSS("$1"))'); # wrong@@%0a-->%25hlt php%25@@Markup('foo', 'inline', '/(something)/e', "Foo(PSS('$1'))"); # right@@%0a%0a%25note%25 Note, the extra slashes are only added by %25hlt php%25@@preg_replace()@@ with an @@/e@@ modifier. The markup definitions with @@Markup_e()@@ do NOT need to use @@PSS()@@ in the replacement strings. The new-type markup definitions with @@Markup()@@ and a simple function name as a replacement do NOT need to use @@PSS()@@ inside the replacement function. If you migrate old markup rules to the new format, delete the @@PSS()@@ calls.%0a%0a!!! Example %25block notoc%25%0aThis is a fictitious example where %25hlt php%25@@PSS()@@ should be used.%0aLet us assume that you wish to define a directive %25pmhlt%25[@(:example:)@]%0asuch that %25pmhlt%25[@(:example "A horse":)@] results in the HTML%0a-> %25hlt html%25[@%3cdiv>"A horse"%3c/div>@].%0aHere is how the markup rule can be created:%0a-> %25hlt php%25[@%0aMarkup('example', 'directives',%0a '/\\(:example\\s(.*?):\\)/e',%0a "Keep('%3cdiv>'.PSS('$1').'%3c/div>')");%0a@]%0aWe need to use %25hlt php%25@@PSS()@@ around the '@@$1@@' because the matched text could contain quotation marks, and the @@/e@@ will add backslashes in front of them.%0a%0a!![[#stripmagic]] stripmagic()%0a%25hlt php%25[@stripmagic($string)@]%0a%0aThis function should be used when processing the contents of %25hlt php%25[@$_POST@] or [@$_GET@] variables when they could contain quotes or backslashes. It verifies [@get_magic_quotes()@], if true, strips the automatically inserted escapes from the string.%0a%0aThe function can process arrays recursively (only the values are processed).%0a%0a!![[#FmtPageName]] FmtPageName()%0a%0a%25hlt php%25[@FmtPageName($fmt, $pagename)@]%0a%0a[[#FmtPageName-desc]]Returns %25hlt php%25[@$fmt@], with @@$variable@@ and [=$[internationalisation]=] substitutions performed, under the assumption that the current page is [@pagename@]. See [[PmWiki.Variables]] for an (incomplete) list of available variables, [[PmWiki.Internationalizations]] for internationalisation. Security: not to be run on user-supplied data.%0a%0aThis is one of the major functions in PmWiki, see [[PmWiki.FmtPageName]] for%0alots of details.%0a%0a%0a!![[#Markup]] Markup()%0a%25hlt php%25[@Markup($name, $when, $pattern, $replace)@]%0a%0a[[#Markup-desc]]Adds a new markup to the conversion table. Described in greater detail at [[PmWiki.CustomMarkup]].%0a%0aThis function is used to insert translation rules into the PmWiki's translation engine. The arguments to %25hlt php%25[@Markup()@] are all strings, where:%0a%0a:%25hlt php%25[@$name@]: The string names the rule that is inserted. If a rule of the same name already exists, then this rule is ignored.%0a:%25hlt php%25[@$when@]: This string is used to control ''when'' a rule is to be applied relative to other rules. A specification of "[@%3cxyz@]" says to apply this rule prior to the rule named "xyz", while "[@>xyz@]" says to apply this rule after the rule "xyz". See [[(PmWiki:)CustomMarkup]] for more details on the order of rules.%0a:%25hlt php%25[@$pattern@]: This string is a [[regular expression -> https://www.php.net/preg_replace]] that is used by the translation engine to look for occurrences of this rule in the markup source. ''The pattern needs to use "/" as delimiters.''%0a:%25hlt php%25[@$replace@]: This string will replace the matched text when a match occurs, or the function name that will return the replacement text.%0a%0aAlso see: [[PmWiki.CustomMarkup]] and [[Cookbook:Functions#Markup]]%0a%0a!![[#MarkupToHTML]] MarkupToHTML()%0a%0a%25hlt php%25[@MarkupToHTML($pagename, $str)@]%0a%0a[[#MarkupToHTML-desc]] Converts the string %25hlt php%25[@$str@] containing PmWiki markup into the corresponding HTML code, assuming the current page is [@$pagename@].%0a%25hlt php%25@@MarkupToHTML()@@ replaces @@\n\n@@ sequences by @@%3c:vspace>@@ first thing when text is passed to it. Subsequently @@%3c:vspace>@@ is processed by the markup rules:%0a-> '@@!vspace@@' removes @@%3c:vspace>@@ after headings.%0a-> '@@%3cvspace>%3cp>@@' replaces @@%3c:vspace>%3cp>@@ with @@%3cp class='vspace'>@@%0a-> '@@%3cvspace>@@' replaces %3c:vspace> with @@%3cdiv class='vspace'>@@%0a-> and finally%0a-> '@@^%3c:@@' removes any remaining @@%3c:vspace>@@, mostly from restored [=[=]=escaped text=].%0a%0aAlso see: [[Cookbook:Functions#MarkupToHTML]]%0a%0a!![[#mkdirp]] mkdirp()%0a%25hlt php%25[@mkdirp($dir)@]%0a%0aThe function %25hlt php%25[@mkdirp($dir)@] creates a directory, [@$dir@], if it doesn't already exist, including any parent directories that might be needed. For each directory created, it checks that the permissions on the directory are sufficient to allow PmWiki scripts to read and write files in that directory. This includes checking for restrictions imposed by PHP's safe_mode setting. If [@mkdirp()@] is unable to successfully create a read/write directory, [@mkdirp()@] aborts with an error message telling the administrator the steps to take to either create @@$dir@@ manually or give PmWiki sufficient permissions to be able to do it.%0a%0a!![[#Lock]] Lock()%0a%25hlt php%25[@Lock(0)@]%0a%0aThis function is used to make sure only one instance of PmWiki is running when files are being written. It does not "lock pages" for editing.%0a%0aFrom a recipe, use:%0a* %25hlt php%25[@Lock(2);@] to acquire an ''exclusive'' lock, so that no other PHP processes can modify files. This can be used when your function is writing files on the server.%0a* %25hlt php%25[@Lock(1);@] to acquire a ''shared'' lock. This may be used when your function is reading files from the server, in case another process is writing them at the same time.%0a* %25hlt php%25[@Lock(0);@] to ''release'' a previous exclusive or shared lock. Use this immediately after your function finishes reading or writing the files.%0a%0aIf you don't release an acquired lock, it should be automatically released at the end of the processing.%0a%0a%0a!![[#MakeLink]] MakeLink()%0a%25hlt php%25[@MakeLink($pagename, $target, $txt, $suffix, $fmt)@]%0a%0aThe function %25hlt php%25[@MakeLink($pagename, $target, $txt, $suffix, $fmt)@] returns an html-formatted anchor link. Its arguments are as follows:%0a $pagename is the source page%0a $target is where the link should go%0a $txt is the value to use for '$LinkText' in the output %0a $suffix is any suffix string to be added to $txt%0a $fmt is a format string to use%0a%0aIf $txt is NULL or not specified, then it is automatically computed from $target.%0a%0aIf $fmt is NULL or not specified, then MakeLink uses the default%0aformat as specified by the type of link. For page links this%0ameans the $LinkPageExistsFmt and $LinkPageCreateFmt variables,%0afor intermap-style links it comes from either the $IMapLinkFmt%0aarray or from $UrlLinkFmt. Inside of the formatting strings,%0a$LinkUrl is replaced by the resolved url for the link, $LinkText%0ais replaced with the appropriate text, and $LinkAlt is replaced%0aby any "title" (alternate text) information associated with the%0alink.%0a%0aAlso see: [[PmWiki:MakeLink]] and [[Cookbook:Functions#MakeLink]]%0a%0a!![[#MakeUploadName]] MakeUploadName()%0a%25hlt php%25@@MakeUploadName($pagename, $x)@@%0a%0a%25hlt php%25@@MakeUploadName()@@ simply takes a string @@$x@@ (representing an attachment's%0aname) and converts it to a valid name by removing any unwanted characters.%0aIt also requires the name to begin and end with an alphanumeric character,%0aand as of 2.0.beta28 it forces any file extensions to lowercase.%0aThis function is defined in @@scripts/upload.php@@ and only used when uploads%0aare enabled.%0a%0a!![[#DownloadUrl]] DownloadUrl()%0a%25hlt php%25@@DownloadUrl($pagename, $path)@@%0a%0aThis function returns the public URL of an attached file. The arguments are as follow:%0a* $pagename - the currently processed page%0a* %25hlt php%25@@$path@@ - the file path, as in @@file.ext@@ or @@OtherPage/file.ext@@ or @@Group/OtherPage/file.ext@@%0a%0aIf the file doesn't exist, the function returns false. The global variable %25hlt php%25@@$FmtV['$LinkUpload']@@ contains the URL to the upload form, for a file with such a name to be attached. The global variable %25hlt php%25@@$FmtV['$LinkDownload']@@ contains the URL to the file, as if it were uploaded to the wiki.%0a%0aThe function calls [[#MakeUploadName|%25hlt php%25@@MakeUploadName()@@]] on the @@$path@@ argument so you don't need to do it before calling it.%0a%0aThe returned URL respects $UploadPrefixFmt and $EnableDirectDownload of the wiki.%0a%0a%0a!![[#SessionAuth]] SessionAuth()%0a%25hlt php%25[@SessionAuth($pagename, $auth=NULL)@]%0a%0a%25hlt php%25@@SessionAuth()@@ manages keeping authentication via cookie-sessions. Session contains every password or validated id and associated groups from previous calls. It adds elements passed by @@$auth@@ to session. It also writes every element saved in session to @@$AuthPw(passwords)@@ and @@$AuthList(ids and groups)@@.%0a%0a!![[#IsAuthorized]] IsAuthorized()%0a%25hlt php%25[@IsAuthorized($chal, $source, &$from)@]%0a%0a%25hlt php%25@@IsAuthorized()@@ takes a pageattributesstring (e. g. "id:user1 $1$Ff3w34HASH...") in @@$chal@@.%0a%0a%25hlt php%25@@$source@@ is simply returned and used for building the authcascade (pageattributes - groupattributes - @@$DefaultPassword@@).%0a%0a%25hlt php%25@@$from@@ will be returned if @@$chal@@ is empty, because it is not checked before calling @@IsAuthorized()@@, this is needed for the authcascade. %0a%25hlt php%25@@IsAuthorized()@@ returns an array with three values: @@$auth@@ @@1@@ - authenticated, @@0@@ - not authenticated, @@-1@@ - refused; @@$passwd@@; @@$source@@ from the parameter list.%0a%0a!![[#CondAuth]] CondAuth()%0a%25hlt php%25[@CondAuth($pagename, 'auth level')@]%0a%0a%25hlt php%25[@CondAuth()@]%25%25 implements the [[ConditionalMarkup]] for %25pmhlt%25[@(:if auth level:)@]%25%25. For instance %25hlt php%25[@ CondAuth($pagename,'edit')@]%25%25 is true if authorization level is 'edit'. Use inside local configuration files to build conditionals with a check of authorization level, similar to using %25pmhlt%25[@(:if auth level:)@]%25%25 on a wiki page.%0a%0aNote that %25hlt php%25@@CondAuth()@@ should be called after all authorization levels and passwords have been defined. For example, if you use it with [[Drafts]], you should include the @@draft.php@@ script before calling @@CondAuth()@@:%0a%25hlt php%25[@%0a $EnableDrafts = 1;%0a $DefaultPasswords['publish'] = pmcrypt('secret');%0a include_once("$FarmD/scripts/draft.php");%0a if (! CondAuth($pagename, 'edit')) { /* whatever */ }%0a@]%0aBest is to use %25hlt php%25@@CondAuth()@@ near the bottom of your @@config.php@@ script.%0a%0a!! [[#RetrieveAuthPage]] RetrieveAuthPage()%0a%25hlt php%25@@RetrieveAuthPage($pagename, $level, $authprompt=true, $since=0)@@%0a%0aPm words as said in https://www.pmwiki.org/pipermail/pmwiki-users/2005-April/012804.html %0awhere:%0a%0a $pagename - name of page to be read%0a $level - authorization level required (read/edit/auth/upload)%0a $authprompt - true if user should be prompted for a password if needed%0a $since - how much of the page history to read%0a 0 == read entire page including all of history%0a READPAGE_CURRENT == read page without loading history%0a timestamp == read history only back through timestamp%0a%0aThe @@$since@@ parameter allows PmWiki to stop reading from a page file%0aas soon as it has whatever information is needed -- i.e., if an operation%0asuch as browsing isn't going to need the page's history, then specifying%0aREADPAGE_CURRENT can result in a much faster loading time. (This can be %0aespecially important for things such as searching and page listings.)%0aHowever, if combined with %25hlt php%25@@UpdatePage()@@, the updated page will have no history.%0a%0aUse e.g. %25hlt php%25[@$page = @RetrieveAuthPage('Main.MyPage', 'read')@] to obtain a page object that contains all the information of the correspondent file in separate keys, e.g. [@$page['text']@] will contain a string with the current wiki markup of Main.MyPage. Use this generally in preference to the alternative function [@ReadPage($pagename, $since=0)@] since it respects the authorisation of the user, i.e. it checks the authorisation level before loading the page, or it can be set to do so. [@ReadPage()@] reads a page regardless of permission.%0a%0aPassing 'ALWAYS' as the authorization level (instead of 'read', 'edit', etc.) will cause %25hlt php%25@@RetrieveAuthPage()@@ to always read and return the page, even if it happens to be protected by a read password.%0a%0a%0a!! [[#RetrieveAuthSection]] RetrieveAuthSection()%0a%25hlt php%25@@RetrieveAuthSection($pagename, $pagesection, $list=NULL, $auth='read')@@%0a%0a%25hlt php%25@@RetrieveAuthSection()@@ extracts a section of text from a page. If @@$pagesection@@ starts with anything other than '@@#@@', the text before the first '@@#@@' (or all of it, if there is no '@@#@@') identifies the page to extract text from. Otherwise @@RetrieveAuthSection()@@ looks in the pages given by @@$list@@ (should be an array), or in @@$pagename@@ if @@$list@@ is not specified. %0a* The selected page is placed in the global @@$RASPageName@@ variable. %0a* The caller is responsible for calling %25hlt php%25@@Qualify()@@ as needed, i.e. if you need to control how unqualified page and variable names shall be resolved.%0a** To have them act as in the original text, let %25hlt php%25@@Qualify()@@ resolve them relative to the source page.%0a** If the imported text was not meant as wikitext but as some other kind of markup that might happen to contain double pairs of square brackets, (:comment %3c-- not: pairs of 〚double square brackets〛 = U+301A/U+301B:) or dollar signs inside curly brackets, you probably don't want to %25hlt php%25@@Qualify()@@ them. If you output them into wikitext, you'll probably need to @@Keep()@@ the text (:comment %3c-- translators: conceptually this means to have Keep() pack the text in a container that marks it as "final".:) (in case of HTML, XML, RSS or similar output, @@PHSC()@@ first!), to prevent later stages of processing from interpreting the apparent wiki markups in context of the target page.%0a** If your code produces wikitext for an auxiliary page that is meant to be included by another page higher up in the inclusion chain, and want links and variables to work as if they were in the auxiliary page, use the auxiliary page's "GroupName.PageName" as the $pagename argument for %25hlt php%25@@Qualify()@@.%0a%0aProvides a way to limit the array that is returned by ReadPage, so that it only pulls the content up to a specific section marker. For example, pulling from start of page to '##blogend':%0a->%25hlt php%25[@%0afunction FeedText($pagename, &$page, $tag) {%0a $text = RetrieveAuthSection($pagename, '##blogend');%0a $content = MarkupToHTML($pagename, $text);%0a return "%3c$tag>%3c![CDATA[$content]]>%3c/$tag>";%0a}%0a@]%0a%0aThe '##blogend' argument says to read from the beginning of the page to just before the line containing the [[#blogend]] marker. See%0a[[PmWiki:IncludeOtherPages | IncludeOtherPages]] for more information about the section specifications.%0a%0aThis version won't read text from pages that are read-protected; if you want to get text even from read-protected pages, then %0a->%25hlt php%25[@%0a $text = RetrieveAuthSection($pagename, '##blogend', NULL, 'ALWAYS');%0a@]%0a%0a%0a!! [[#UpdatePage]] UpdatePage()%0a%25hlt php%25@@UpdatePage($pagename, $old (page object), $new (page object));@@%0a%0a''[[PmWiki:UpdatePage|More Technical Notes]]''%0a%0a%25hlt php%25[@UpdatePage()@] allows cookbook recipes to mimic the behavior of editing wiki pages via the browser. Internally, PmWiki does several housekeeping tasks which are accessible via this function (preserving history/diff information, updating page revision numbers, updating RecentChanges pages, sending email notifications, etc._%0a* "Page object" refers to an array pulled from %25hlt php%25[@RetrieveAuthPage($pagename, $level, $authprompt=true, $since=0);@] (preferred), or [@ReadPage($pagename); @] (disregards page security). Note that @@$new['text']@@ should contain all page data for the new version of the page. %0a* If a page doesn't exist, %25hlt php%25@@UpdatePage()@@ will attempt to create it.%0a* Ignoring @@$old@@ (e.g. %25hlt php%25[@UpdatePage($pagename, '', $new);@]) will erase all historical page data---a ''tabula rasa''.%0a** If you retrieved @@$old@@ using %25hlt php%25@@RetrieveAuthPage($pagename,$auth,$prompt,READPAGE_CURRENT)@@ and set @@$new=$old@@, then @@UpdatePage()@@ will also erase all historical data%0a%25hlt php%25@@UpdatePage()@@ cannot be called directly from @@config.php@@ because there are necessary initializations which occur later in @@pmwiki.php@@. It is not enough to just load @@stdconfig.php@@. If you want to use @@UpdatePage()@@ you will need to do it within a [[PmWiki:CustomMarkup | custom markup]], a [[Cookbook:MarkupExpressionSamples | custom markup expression]], or a [[PmWiki:CustomActions | custom action]].%0a%0a%0a!! [[#InsertEditFunction]] InsertEditFunction()%0a%25hlt php%25@@InsertEditFunction($newfn, $where='%3cPostPage')@@%0a%0aThis function makes it easy for recipe authors to insert a custom function in a specific position of the processing, see $EditFunctions and [[#UpdatePage|UpdatePage()]]. %0a%0aThe first argument is the name of the new function.%0a%0aThe second argument is the position where to place the new function, related to other edit functions? It can be:%0a* @@"%3c"@@ at the start, before the first edit function%0a* @@">"@@ at the end, after the last edit function%0a* @@"%3cExistingEditFunction"@@ before a specified edit function%0a* @@">ExistingEditFunction"@@ after a specified edit function%0a%0aThe function will return ''true'' on success, and ''false'' on failure (when the specified position or existing function was not recognized).%0a%0a!! [[#DisableSkinParts]] DisableSkinParts()%0a%25hlt php%25@@DisableSkinParts('parts to disable');@@%0a%0aThis function allows easy disabling of the skin sections header, footer, title, actions, and sidebars, like the corresponding directives %25pmhlt%25@@[=(:notitle:) (:noleft:)=]@@ etc. In your function, use something like:%0a->%25hlt php%25[@%0a DisableSkinParts('Left Header Footer Action Title');%0a@]%0a%0a!! [[#ParseArgs]] ParseArgs()%0aSee Cookbook:ParseArgs. %0a%0a!! [[#Redirect]] Redirect()%0a%0a!! [[#PageIndexTerms]] PageIndexTerms()%0a%0a!! [[#AsSpaced]] AsSpacedUTF8(), AsSpaced()%0a>>hlt php%3c%3c%0a@@AsSpaced()@@ is declared in @@pmwiki.php@@ \\%0a@@AsSpaced()@@ converts a string with WikiWords into a spaced version of that string.%0aIt can be overridden via $AsSpacedFunction, as it is in @@AsSpacedUTF8()@@. \\%0a@@AsSpacedUTF8()@@ is declared in the @@xlpage-utf-8.php@@ script.%0a>>%3c%3c%0a%0aCategories: [[!PmWiki Developer]]
+time=1724101330
diff --git a/wikilib.d/PmWiki.PagelistVariables b/wikilib.d/PmWiki.PagelistVariables
index 39529d69..bb47759a 100644
--- a/wikilib.d/PmWiki.PagelistVariables
+++ b/wikilib.d/PmWiki.PagelistVariables
@@ -1,10 +1,10 @@
-version=pmwiki-2.3.25 ordered=1 urlencoded=1
+version=pmwiki-2.3.36 ordered=1 urlencoded=1
author=Petko
charset=UTF-8
-csum=$EnableSearchAtLeastOneTerm (+433)
+csum=Clarify $EnablePageListProtect may or may not be faster, %25hlt php%25 (+348)
ctime=1136054369
name=PmWiki.PagelistVariables
-rev=45
+rev=47
targets=PmWiki.PagelistVariables,PmWiki.CustomPagelistSortOrder,PmWiki.PageLists,Cookbook.SearchPatterns,PmWiki.PathVariables,Site.LocalTemplates,Site.PageListTemplates,PmWiki.IncludeOtherPages,PmWiki.PageListTemplates,Site.Search
-text=(:Summary:variables used with [[PmWiki/page lists]] and search results:)%0a:$EnablePageListProtect:When set to 1 (which is the default), causes [@(:pagelist:)@] and [@(:searchresults:)@] to exclude listing any pages for which the browser does not currently have read authorization. Setting this to zero means that read-protected pages can appear in a listing, but can also speed up searches considerably (because page permissions do not need to be checked).%0a%0a:$PageListSortCmpFunction:The function used to compare values when ordering a page list, for historical reasons the default is '[[(http://php.net/)strcasecmp]]' and sorts alphabetically and case insensitively. If you regularly order numbers or strings with numbers, you can set this variable to '[[(http://php.net/)strnatcasecmp]]' and the list will be sorted according to a [[https://github.com/sourcefrog/natsort#readme|natural order]], case insensitively:\\%0a[@ $PageListSortCmpFunction = 'strnatcasecmp';# "natural" sorting of pagelists@]\\%0aOr you can write here the name of a custom function you have defined. This is the general sorting function, for specific needs you can create specific functions, see [[(PmWiki:)CustomPagelistSortOrder]].%0a%0a:$PageListVarFoldFn: PageList and Search terms, including page variable search terms are always case insensitive for the Latin alphabet. For international characters the page variable terms were case sensitive until PmWiki 2.2.115, and became case insensitive from 2.2.116 (like for the Latin characters). If your pagelists relied on the previous behavior, you can set here a function name that does not change the case of the international characters, for example [@$PageListVarFoldFn = 'strval';@]%0a%0a:$SearchPatterns:An array of page name patterns to be required or excluded from search and [[PmWiki/PageLists|pagelist]] results. In order to be included in a search listing or page listing, a page's name must not match any pattern that is delimited by exclamation points (!) and must match all other patterns. See [[Cookbook:SearchPatterns]].%0a--> [@# Limit all searches to Main group%0a$SearchPatterns['default'][] = '/^Main\\./';%0a# Exclude the Main group from search results%0a$SearchPatterns['default'][] = '!^Main\\.!';%0a# Exclude RecentChanges pages from search results%0a$SearchPatterns['default'][] = '!\\.(All)?RecentChanges$!';%0a# Prevent a page from listing itself in (:pagelist:) or (:searchresults:)%0a$SearchPatterns['default'][] = FmtPageName('!^$FullName$!', $pagename);%0a@]%0a%0a:$SearchBoxOpt:%0a--> For example [@ $SearchBoxOpt ['target'] = '$DefaultGroup.Search'; @]%0a%0a:$SearchBoxInputType:The HTML "type" attribute for the search field. Default is "text" which is valid HTML4. If your skin uses HTML5, you can change this to "search":%0a--> @@ $SearchBoxInputType = "search";@@%0a%0a%0a:$EnablePageIndex:When set to 0, disables default indexing. By default PmWiki maintains a "link and word index" in $PageIndexFile which significantly speeds up categories, backlinks, and searches.%0a%0a:$PageIndexFile:The location of the "page index" file for [@(:pagelist:)@], defaults to @@$WorkDir/.pageindex@@.%0a%0a:$PageListCacheDir:The name of a writable directory where PmWiki can cache results of [@(:pagelist:)@] directives to speed up subsequent displays of the same list. Default is empty, which disables the pagelist cache.%0a--> [@# Enable pagelist caching in work.d/.pagelistcache%0a$PageListCacheDir = 'work.d/.pagelistcache';%0a@]%0a%0a:$PageSearchForm:The page to be used to format search results for [@?action=search@] (unless the current page has a "searchresults" directive in it). This variable can be an array, in which case the first page found from the array is used.%0a--> [@# Simple use of page search form in the default group%0a$PageSearchForm = '$DefaultGroup.Search';%0a@]%0a--> [@# Use Search page in current group if it exists, otherwise use Site.Search%0a$PageSearchForm = array('$Group.Search', '[=$[$SiteGroup/Search]=]');%0a@]%0a%0a:$FPLTemplatePageFmt:The pages to be searched for a pagelist template specified by a [@fmt=#xyz@] parameter. Defaults to searching the current page, [[Site.LocalTemplates]] and [[Site.PageListTemplates]].%0a%0a--> [@# PMWiki default setup%0aglobal $FPLTemplatePageFmt;%0a$FPLTemplatePageFmt = array(%0a '{$FullName}', %0a '{$SiteGroup}.LocalTemplates', %0a '{$SiteGroup}.PageListTemplates');@]%0a%0a-> It can be customized to look in other pages.%0a%0a--> [@# Search a Group.Templates page as well as the Site templates%0aglobal $FPLTemplatePageFmt;%0a$FPLTemplatePageFmt = array(%0a '{$Group}.Templates',%0a '{$SiteGroup}.LocalTemplates',%0a '{$SiteGroup}.PageListTemplates');@]%0a%0a-> Or declare defaults for the template array:%0a--> [@# Search a Group.Templates page as well as the Site templates%0aglobal $FPLTemplatePageFmt;%0aSDV($FPLTemplatePageFmt, array('{$FullName}',%0a '{$Group}.Templates',%0a '{$SiteGroup}.LocalTemplates', '{$SiteGroup}.PageListTemplates')%0a );@]%0a%0a:$EnableUndefinedTemplateVars: This variable controls how undefined [={$$Variable}=] is processed in [[IncludeOtherPages|includes]] and [[PageList templates]]. If set to 0 (default), undefined [={$$Variable}=]s are removed from the included section or template. If set to 1, undefined [={$$Variable}=]s are displayed as is, with {$$...}. ''Note that PmWiki versions 2.2.13 and earlier '''kept''' unset include/template variables.''%0a: : @@$EnableUndefinedTemplateVars = 0;@@ # Delete unset raw template variables%0a: : @@$EnableUndefinedTemplateVars = 1;@@ # Keep and print unset raw template variables%0a%0a:$PageIndexFoldFunction: A custom function used to 'fold' (simplify, normalize) the page words before storing them in the wiki.d/.pageindex file, and the search terms typed by the users. By default, PmWiki converts these to lowercase, here you can define a function that does it differently (for example, stripping inline HTML tags).%0a%0a:$PageIndexTermsFunction: A function to split the page texts into normalized search terms. By default, the core function PageIndexTerms() is called, with this variable you can override it with a custom function. This may be useful if you need to remove some texts from the page index, for example inline HTML tags. The first and only argument of the function may be either a string, or an array of strings.%0a%0a:$EnableSearchAtLeastOneTerm:By default, searching for several terms like @@term1 term2@@ will list pages containing all the terms. Setting this variable to 1 will cause the search to list pages containing at least one of the typed terms. In this case, required terms can be preceded by "+" like @@+term1 +term2@@. If you change this variable, you may want to update the search instructions in your [[$[{$SiteGroup}/Search]]] page.%0a
-time=1695897026
+text=(:Summary:Variables used with [[PmWiki/page lists]] and search results:)%0a:$EnablePageListProtect:When set to 1 (which is the default), causes %25pmhlt%25[@(:pagelist:)@] and [@(:searchresults:)@]%25%25 to exclude listing any pages for which the browser does not currently have read authorization. Setting this to zero means that read-protected pages can appear in a listing, even if the visitor cannot open them. In some cases this can speed up searches considerably (because page permissions do not need to be checked). OTOH in case of WikiGroups with different GroupAttributes permissions and many pages each, leaving the default enabled may be faster, as then the individual pages from unauthorized groups are not checked.%0a%0a:$PageListSortCmpFunction:The function used to compare values when ordering a page list, for historical reasons the default is '[[(http://php.net/)strcasecmp]]' and sorts alphabetically and case insensitively. If you regularly order numbers or strings with numbers, you can set this variable to '[[(http://php.net/)strnatcasecmp]]' and the list will be sorted according to a [[https://github.com/sourcefrog/natsort#readme|natural order]], case insensitively:\\%0a%25hlt php%25[@$PageListSortCmpFunction = 'strnatcasecmp';# "natural" sorting of pagelists@]%25%25\\%0aOr you can write here the name of a custom function you have defined. This is the general sorting function, for specific needs you can create specific functions, see [[(PmWiki:)CustomPagelistSortOrder]].%0a%0a:$PageListVarFoldFn: PageList and Search terms, including page variable search terms are always case insensitive for the Latin alphabet. For international characters the page variable terms were case sensitive until PmWiki 2.2.115, and became case insensitive from 2.2.116 (like for the Latin characters). If your pagelists relied on the previous behavior, you can set here a function name that does not change the case of the international characters, for example %25hlt php%25[@$PageListVarFoldFn = 'strval';@]%0a%0a:$SearchPatterns:An array of page name patterns to be required or excluded from search and [[PmWiki/PageLists|pagelist]] results. In order to be included in a search listing or page listing, a page's name must not match any pattern that is delimited by exclamation points (!) and must match all other patterns. See [[Cookbook:SearchPatterns]].%0a-> %25hlt php%25[@# Limit all searches to Main group%0a$SearchPatterns['default'][] = '/^Main\\./';%0a# Exclude the Main group from search results%0a$SearchPatterns['default'][] = '!^Main\\.!';%0a# Exclude RecentChanges pages from search results%0a$SearchPatterns['default'][] = '!\\.(All)?RecentChanges$!';%0a# Prevent a page from listing itself in (:pagelist:) or (:searchresults:)%0a$SearchPatterns['default'][] = FmtPageName('!^$FullName$!', $pagename);%0a@]%0a%0a:$SearchBoxOpt:%0a-> For example %25hlt php%25[@ $SearchBoxOpt['target'] = '$DefaultGroup.Search'; @]%0a%0a:$SearchBoxInputType:The HTML "type" attribute for the search field. Default is "text" which is valid HTML4. If your skin uses HTML5, you can change this to "search":%0a-> %25hlt php%25@@ $SearchBoxInputType = "search";@@%0a%0a%0a:$EnablePageIndex:When set to 0, disables default indexing. By default PmWiki maintains a "link and word index" in $PageIndexFile which significantly speeds up categories, backlinks, and searches.%0a%0a:$PageIndexFile:The location of the "page index" file for [@(:pagelist:)@], defaults to @@$WorkDir/.pageindex@@.%0a%0a:$PageListCacheDir:The name of a writable directory where PmWiki can cache results of [@(:pagelist:)@] directives to speed up subsequent displays of the same list. Default is empty, which disables the pagelist cache.%0a-> %25hlt php%25[@# Enable pagelist caching in work.d/.pagelistcache%0a$PageListCacheDir = 'work.d/.pagelistcache';%0a@]%0a%0a:$PageSearchForm:The page to be used to format search results for [@?action=search@] (unless the current page has a "searchresults" directive in it). This variable can be an array, in which case the first page found from the array is used.%0a-> %25hlt php%25[@# Simple use of page search form in the default group%0a$PageSearchForm = '$DefaultGroup.Search';%0a@]%0a-> %25hlt php%25[@# Use Search page in current group if it exists, otherwise use Site.Search%0a$PageSearchForm = array('$Group.Search', '[=$[$SiteGroup/Search]=]');%0a@]%0a%0a:$FPLTemplatePageFmt:The pages to be searched for a pagelist template specified by a [@fmt=#xyz@] parameter. Defaults to searching the current page, [[Site.LocalTemplates]] and [[Site.PageListTemplates]].%0a%0a-> %25hlt php%25[@# PMWiki default setup%0aglobal $FPLTemplatePageFmt;%0a$FPLTemplatePageFmt = array(%0a '{$FullName}', %0a '{$SiteGroup}.LocalTemplates', %0a '{$SiteGroup}.PageListTemplates');@]%0a%0a-> It can be customized to look in other pages.%0a%0a-> %25hlt php%25[@# Search a Group.Templates page as well as the Site templates%0aglobal $FPLTemplatePageFmt;%0a$FPLTemplatePageFmt = array(%0a '{$Group}.Templates',%0a '{$SiteGroup}.LocalTemplates',%0a '{$SiteGroup}.PageListTemplates');@]%0a%0a-> Or declare defaults for the template array:%0a-> %25hlt php%25[@# Search a Group.Templates page as well as the Site templates%0aglobal $FPLTemplatePageFmt;%0aSDV($FPLTemplatePageFmt, array('{$FullName}',%0a '{$Group}.Templates',%0a '{$SiteGroup}.LocalTemplates', '{$SiteGroup}.PageListTemplates')%0a);@]%0a%0a:$EnableUndefinedTemplateVars: This variable controls how undefined [={$$Variable}=] is processed in [[IncludeOtherPages|includes]] and [[PageList templates]]. If set to 0 (default), undefined [={$$Variable}=]s are removed from the included section or template. If set to 1, undefined [={$$Variable}=]s are displayed as is, with {$$...}. ''Note that PmWiki versions 2.2.13 and earlier '''kept''' unset include/template variables.''%0a: : %25hlt php%25@@$EnableUndefinedTemplateVars = 0;@@ # Delete unset raw template variables%0a: : %25hlt php%25@@$EnableUndefinedTemplateVars = 1;@@ # Keep and print unset raw template variables%0a%0a:$PageIndexFoldFunction: A custom function used to 'fold' (simplify, normalize) the page words before storing them in the wiki.d/.pageindex file, and the search terms typed by the users. By default, PmWiki converts these to lowercase, here you can define a function that does it differently (for example, stripping inline HTML tags).%0a%0a:$PageIndexTermsFunction: A function to split the page texts into normalized search terms. By default, the core function PageIndexTerms() is called, with this variable you can override it with a custom function. This may be useful if you need to remove some texts from the page index, for example inline HTML tags. The first and only argument of the function may be either a string, or an array of strings.%0a%0a:$EnableSearchAtLeastOneTerm:By default, searching for several terms like @@term1 term2@@ will list pages containing all the terms. Setting this variable to 1 will cause the search to list pages containing at least one of the typed terms. In this case, required terms can be preceded by "+" like @@+term1 +term2@@. If you change this variable, you may want to update the search instructions in your [[$[{$SiteGroup}/Search]]] page.%0a
+time=1724058754