%audience% admins (advanced) This page describes an internal function in PmWiki's engine called [@FmtPageName()@]. The contents are not intended for those with a weak heart ;-) Also see: [[PmWiki.Functions]] !![[#FmtPageName]] [@FmtPageName@]($fmt, $pagename) [[#FmtPageName-desc]]Returns [@$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. The function [@FmtPageName()@] applies internationalization-substitutions and $Variable-substitions to the string $fmt under the assumption that the current page is $pagename. The substitutions goes as follows: # Replace any sequences of the form [@$XyzFmt@] with value of any \ corresponding global variable. # Process the string for any [@$[...]@] phrases (internationalized phrase), \ using the currently loaded translation tables. # Perform any pattern replacements from the array $FmtP. Typically \ this is used to handle things like $Name and $Group etc that are \ specific to the name of the current page. # If $EnablePathInfo isn't set, convert [@URIs@] to use the syntax \ $ScriptUrl?n=. instead of $ScriptUrl//. # Replace any $-sequences with global variables (caching as needed) \ of the same name (in reverse alphabetical order) * # Replace any $-sequences with values out of the array $FmtV. Note that [@FmtPageName@]() is automatically aware of any global variables. However, since modifying global variables may be expensive, the array $FmtV exists as a way to avoid rebuilding the variable cache for values that change frequently. To be very specific, here's what Pm wrote regarding different ways of defining a variable that can be used by FmtPageName (when it is formatting a string): * Set a global variable. FmtPageName() automatically performs \ substitution on all global variables that aren't arrays. \ If the variable is going to change value over repeated calls \ to FmtPageName, it's probably better to use $FmtV as in the next item. * Set a value in the $FmtV array. $FmtV['$MyVariable']='something' \ means to replace instances of '$MyVariable' with 'something'. \ Use this for variables that change value frequently over \ multiple calls to FmtPageName. * Set a pattern/replacement in the $FmtP array. This is normally \ done for substitutions that have to be dynamic somehow based on \ the pagename being referenced, such as '$Title', '$Group', '$Name', \ '$PageUrl', etc. Also see: [[Cookbook:Functions#FmtPageName]] Finally, here's something else Pm wrote that is related and explains why we have this function: -> In order to produce its output, PmWiki has to do a variety of string \ substitutions: ## Generating the full name, group, title, or url of a page \ (other than the currently displayed page) ## Substituting the values of global variables ## Performing internationalization substitutions ## Converting $ScriptUrl/$Group/$Name to $ScriptUrl?n=$Group.$Name \ for sites that cannot handle PATH_INFO urls ## Other substitutions needed by specific functions -> PmWiki centralizes all of that substitute-a-dynamic-value-in-a-string \ into the FmtPageName() subroutine. Because some things are extremely \ dynamic, such as the url or group for an arbitrary page that is not the \ current one, those things cannot be simple global PHP variables. Or, if \ they do become global variables, they're variables that cannot be \ trusted to hold a value for very long because some other routine (that \ may happen to be formatting a string for a different page) will come \ along and change that global variable for whatever it happens to be doing. -> A limited set of $-substitutions -- basically anything that \ corresponds to a page attribute -- are not PHP variables and \ are only available through the FmtPageName() subroutine. \ The complete set of these special substitutions is $Group, \ $Name, $FullName, $PageUrl, $Title, $Titlespaced, $Namespaced, \ $Groupspaced, $LastModifiedBy, $LastModifiedHost, and $LastModified. \ These items cannot just be standard PHP variables because often\ PmWiki needs to obtain the url, name, group, title, etc. of a page \ other than the one currently being viewed by a browser. -> At the moment, $Title, $LastModified, $LastModifiedBy, and \ $LastModifiedHost can only work if the page's attributes have been \ loaded and cached using the `PCache function. So, to get\ at these values one must typically do: -> [@ $page = `ReadPage($pagename); PCache($pagename, $page); $pvar = `FmtPageName('$Title', $pagename); $pvar = `FmtPageName('$`LastModifiedBy', $pagename); @] !! Source code for [@FmtPageName()@] Note: The source code below was taken from "pmwiki-2.0.beta55", while the current version is {$Version}. -> [@ ## FmtPageName handles $[internationalization] and $Variable ## substitutions in strings based on the $pagename argument. function FmtPageName($fmt,$pagename) { # Perform $-substitutions on $fmt relative to page given by $pagename global $GroupPattern, $NamePattern, $EnablePathInfo, $ScriptUrl, $GCount, $UnsafeGlobals, $FmtV, $FmtP, $PCache, $AsSpacedFunction; if (strpos($fmt,'$')===false) return $fmt; $fmt = preg_replace('/\\$([A-Z]\\w*Fmt)\\b/e','$GLOBALS[\'$1\']',$fmt); $fmt = preg_replace('/\\$\\[(?>([^\\]] ))\\]/e',"XL(PSS('$1'))",$fmt); $match = array('','$Group','$Name'); if (preg_match("/^($GroupPattern)[\\/.]($NamePattern)\$/", $pagename, $m)) $match = $m; $fmt = preg_replace(array_keys($FmtP),array_values($FmtP),$fmt); $fmt = preg_replace('!\\$ScriptUrl/([^?#\'"\\s<>] )!e', (@$EnablePathInfo) ? "'$ScriptUrl/'.PUE('$1')" : "'$ScriptUrl?n='.str_replace('/','.',PUE('$1'))", $fmt); if (strpos($fmt,'$')===false) return $fmt; static $g; if ($GCount != count($GLOBALS) count($FmtV)) { $g = array(); foreach($GLOBALS as $n=>$v) { if (is_array($v) || is_object($v) || isset($FmtV["\$$n"]) || in_array($n,$UnsafeGlobals)) continue; $g["\$$n"] = $v; } $GCount = count($GLOBALS) count($FmtV); krsort($g); reset($g); } $fmt = str_replace(array_keys($g),array_values($g),$fmt); $fmt = str_replace(array_keys($FmtV),array_values($FmtV),$fmt); return $fmt; } @]