[pmwiki-users] shortening Links with $LinkFunctions

adam overton a at plus1plus1plus.org
Sun Apr 3 08:10:02 CDT 2011

well, with much toil wrapping my head around the innards of MakeLink and more, i think i've located a solution that seems to [mostly] work, and have posted it below. i wonder if others can spot a better way than this, or can foresee any problems that might arise from this implementation? this seems to successfully make all links in the form [[Group/|txt]] or [[Group/DefaultPage|txt]] spit out as http://mysite.com/Group rather than http://mysite.com/Group/DefaultPage. it also seems to successfully preserve arguments in the url, and accepts [[Group.DefaultPage|txt]] dot-syntax as well.

however, the only problem i'm left with now is that if i edit a DefaultPage page via http://mysite.com/Group?action=edit, and then click save, the form always returns me to http://mysite.com/Group/DefaultPage. i've tried implementing a RewriteRule in my .htaccess to avert this, but it sadly seems to only result in a redirect loop.

anyways, at this point i can live with this minor issue - in my particular situation, the cleanurls are intended more as an aesthetic delight for the visitor of the site than for the editor(s). but if anyone could tell me how to get my save window to follow the same redirection cues, i'd be much obliged. and of course, if anyone foresees other bugs or problems, i'd appreciate their input.

thanks again,

in .htaccess:

### Supply requests for Group/ with the page at Group/index (assuming $DefaultPage = "index")
RewriteRule ^([^/]+)/?$ $1/index  [L]

in config.php, towards the bottom:

## [[target/ | text]]  &  [[target/DefaultPage | text]]
## this takes any link in the form [[target/ | text]], [[target/?args | text]], [[target/DefaultPage | text]], or [[target/DefaultPage?args | text]], and prepends the $imap identifier GROUPONLY:
## it then returns the path minus the Default page i.e. GROUPONLY:target, or GROUPONLY:target/?args
## this markup also preserves #anchors

$LinkFunctions['GROUPONLY:'] = 'ShortenLinkUrl';
function ShortenLinkUrl($pagename,$imap,$path,$title,$txt,$fmt=NULL) {
	global $DomainName;

	# remove last forwardslash/ - this is only removed if no ?aruments are appended to the url
	$path = (preg_match("#^([^\/]*)/?$#", $path, $m)) ? $m[1] : $path;
	$path = "//$DomainName/$path";  # create a path, with two leading forwardslashes //
	$imap = 'http:';  # change imap from GROUPONLY: to http:
	#echo "$pagename,$imap,$path,$title,$txt,$fmt<br />";

	return LinkIMap($pagename,$imap,$path,$title,$txt,$fmt);

On 2 Apr 2011, at 5:53 PM, adam overton wrote:

> my original question still stands, but here's more info after doing some research:
> it seems like $LinkFunctions is in fact the correct place to be trying to do what i want to do (shorten urls from Group/index to Group/), but i'm having trouble figuring out the correct identifier for the $LinkFunctions['identifier']. the identifier is used in the MakeLink function to determine the variable $LinkPattern, which basically presents the MakeLink function with a list of prefixes to choose from: (http:|ftp:|etc:) within a regular expression. what i've discovered is that at this point in the function, Markup like [[Group/index]] is still appearing as 'Group/index' in the variable $tgt. how then can i tell my LinkFunctions function to fire when NO prefix is found? $LinkFunctions[''] doesn't work.
> is there a way to do this in the regular expression/identifier?
> or will i need to change the [[markup]] for links to insert some kind of prefix that my function then finds and replaces?
> i know that i could also just create another RewriteRule in .htaccess to have any Group/index page redirect to Group/, but i'd rather avoid that by just providing the correct links in the first place.
> thanks for the advice,
> adam
> earlier in pmwiki.php:
> $LinkPattern = implode('|',array_keys($LinkFunctions));
> . . .
> function MakeLink($pagename,$tgt,$txt=NULL,$suffix=NULL,$fmt=NULL) {
>  global $LinkPattern,$LinkFunctions,$UrlExcludeChars,$ImgExtPattern,$ImgTagFmt;
>  $t = preg_replace('/[()]/','',trim($tgt));
>  $t = preg_replace('/<[^>]*>/','',$t);
>  preg_match("/^($LinkPattern)?(.+?)(\"(.*)\")?$/",$t,$m);
>  if (!$m[1]) $m[1]='<:page>';
>  if (preg_match("/(($LinkPattern)([^$UrlExcludeChars]+$ImgExtPattern))(\"(.*)\")?$/",$txt,$tm)) 
>    $txt = $LinkFunctions[$tm[2]]($pagename,$tm[2],$tm[3],@$tm[5],
>      $tm[1],$ImgTagFmt);
>  else {
>    if (is_null($txt)) {
>      $txt = preg_replace('/\\([^)]*\\)/','',$tgt);
>      if ($m[1]=='<:page>') {
>        $txt = preg_replace('!/\\s*$!', '', $txt);
>        $txt = preg_replace('!^.*[^<]/!', '', $txt);
>      }
>    }
>    $txt .= $suffix;
>  }
>  $out = $LinkFunctions[$m[1]]($pagename,$m[1],$m[2],@$m[4],$txt,$fmt);
>  return $out;
> }
> On 2 Apr 2011, at 8:20 AM, adam overton wrote:
>> hi
>> i'm wondering if i'm going about something the wrong way.
>> i'm trying to get a link like [[Group/]] to output http://mysite.com/Group, as opposed to http://mysite.com/Group/DefaultName
>> here's some background:
>> the $DefaultPage for my site is "index";
>> via some fancy clean urls and .htaccess footwork, my site now successfully displays the correct default page (Group/index) with either:
>> http://mysite.com/Group/index
>> or
>> http://mysite.com/Group
>> this much works.
>> but now i'd like for any links like [[Group/]] to resolve to 
>> http://mysite.com/Group
>> instead of
>> http://mysite.com/Group/index
>> so, i tried creating the following $LinkFunctions, but it turns out it seems to only works for links beginning with http://...
>> for instance, the following function successfully shortens http://mysite.com/Group/index
>> $DefaultName = "index";
>> $LinkFunctions['http:'] = 'ShortenLinkUrl';
>> function ShortenLinkUrl($pagename,$imap,$path,$title,$txt,$fmt=NULL) {
>> 	global $DefaultName;
>> 	$path = (preg_match("#^(.*)/".$DefaultName."$#", $path, $m)) ? $m[1] : $path;
>> 	return LinkIMap($pagename,$imap,$path,$title,$txt,$fmt);
>> }
>> how do i go about doing the same thing for [[Group/]] markup?
>> thanks a bunch for the advice,
>> adam

More information about the pmwiki-users mailing list