01462: printable view changes links with actions

Summary: printable view changes links with actions
Created: 2021-01-11 23:20
Status: Closed, documented
Category: Documentation
From: Frank
Priority: 3
Version: 2.2.134

Description: With action=print the relative/local links (_?action=...) don't work, they are transformed in _?action=print,

but the absolute links work fine:

Frank January 11, 2021, at 11:34 PM

Apparently this is by design, I suppose to allow easy browsing to other pages in the "print" view. $LinkPageExistsFmt is redefined in pub/skins/print/print.php and instead of $LinkUrl it uses $PageUrl; the former keeps the query fragments of the link, the latter doesn't. As with almost anything in PmWiki, it can be overridden with the following code placed at the very bottom of local/config.php or local/Group.php or local/Group.Page.php.

$LinkPageExistsFmt = "<a class='wikilink' href='\$LinkUrl' title='\$LinkAlt'>\$LinkText</a>";

This is now documented at PmWiki:Skins#print and enabled on this page, and can be tested at 01462?action=print. --Petko January 12, 2021, at 07:13 AM

Thank You. -- Frank January 12, 2021, at 02:48 PM

Excuse me Petko, just one more thing, I noticed that the 'page' that appears with ?action=search cannot be displayed with ?action=print. I guess two actions at the same time are not possible... however, since it would be very useful (at least for those who, like me, use extract), I ask you anyway, is there a way around this problem? -- Frank January 16, 2021, at 08:20 PM

You can enable Skins:SkinChange and do ?skin=print&action=search&q=TERM like 01462?skin=print&action=search&q=SkinChange. Note that the some recent skins have a "print" media query with a layout adapted for printing, so you could simply do in your browser "File->Print preview" (Firefox) or "Menu->Print..." to preview and print the page. The core PmWiki-responsive skin enabled on the website is one of these. --Petko January 16, 2021, at 08:33 PM

I enabled Skins:SkinChange and I managed to put a string in the search-form as an option (...checkbox name=skin value=print... → url result: ...&skin=print) and it works fine for a new search, but I'd need to achieve the printed version of a search already displayed (my search-form, with a custom markup, is already overflowing with options).
I tried, but I was unable to create a button or a link (not even within php with a simple custom markup, e.g. ...href='$LinkUrl&skin=print...' or with a simple form), because the 'search' part (?q=...&action=search...) of the url was overwritten with ?action=print or (?|&)skin=print.
So after several attemps, I have used the code found here, it works fine, but it seems to have security implications (not clear to me). Is there any pmwiki-variable that I can use to achieve the same goal? I don't understand why I can't simply concatenate &skin=print (not even within a php variable) after $LinkUrl! -- Frank January 17, 2021, at 07:53 AM

I am not sure where you would use $LinkUrl, in $LinkPageExistsFmt? This $LinkUrl is a placeholder (temporary replacement) and contains the URL written in wiki links like [[Link]] or [[Other?q=something]]. If you have such a link in brackets with various query fragments, $LinkUrl holds them all. It does not hold the URL of the "current page with any query fragments" coming from a search form. There is currently no PmWiki variable that holds the current full request URI but if required, such a recipe can be written and supported. --Petko January 17, 2021, at 09:52 AM

Sorry, I didn't explain it well. I am now using this code in a simple custom markup:

$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$print = "&skin=print";

so I can get: [[$actual_link$print|$[Print]]]

It works fine, but I was hoping that there was something similar in pmwiki core, to replace $actual_link (e.g. with something similar to $LinkUrl), just to avoid a code taken from the web, fearing that it could create (now or in the future) some problem. I certainly didn't mean to ask you to write a recipe on this thing just for me, if you think it's a safe code, I will use it, that's all. -- Frank January 17, 2021, at 10:29 AM

[There is a global variable $UrlScheme that will be either http or https so you could simplify it.]
Is your code safe? It really depends if, how, and when, these variables are processed by the markup engine, but I cannot guarantee it is safe since the request URI can be modified by an attacker and is not sanitized.

The following code in config.php should be more secure:

$CurrentPagePrintSkin = 'print';
$FmtPV['$QueryPrintUrl'] = 'QueryPrintUrl($pn)';
function QueryPrintUrl($pn) {
  global $CurrentPagePrintSkin;
  $url = PageVar($pn, '$PageUrl');
  $url .= (strpos($url, '?') === false) ? "?" : "&";
  $url .= "skin=$CurrentPagePrintSkin";
  foreach($_GET as $k=>$v) {
    if(preg_match('/^(n|pagename|skin)$/', $k)) continue;
    $url .= '&' . rawurlencode($k) . '=' . rawurlencode($v);
  return $url;

Then, in Site.PageActions, you can use [[ {*$QueryPrintUrl} | $[Print] ]]. Then the print link will start with (?|&)skin=print and contain all query fragments appended. It should work unless if your form produces variable arrays with square brackets like (:input checkbox name="check[]" value=A:). --Petko January 17, 2021, at 11:54 AM

It's perfect, thank you very much. I really appreciated your help, as always. I'm sure it will be useful to other pmwiki users as well. --Frank January 17, 2021, at 09:55 PM