L'uso di questo sito
autorizza anche l'uso dei cookie
necessari al suo funzionamento.
(Altre informazioni)

Saturday, September 12, 2015

Building a query string with the Smarty template engine

Curse the pesky "?" and "&"!" The first one separates the query string part from its url, the second separates the various parameters as in the very well known idiom:


So why did the HTML creators, in their wisdom, decide to have two different  separators, rather than one? Go read the W3C docs, if you feel like it (I don't). Regardless, it sucks like a tornado. Because you cannot now very well do things like:


because, depending on what's in $url, you may and up with things like:

/bar/baz.php?sna=foo"  //right
/bar/baz.php??sna=foo"    //wrong
/bar/baz.php?b=1?sna=foo" //wrong

sucky sucky, as stated. Wanna see which browsers will puke (and which will digest) the above wrong instances and write a nice table? I don't. But you go ahead, if you feel so inclined.

Having solved the problem in oomph languages and currently involved in Smarty+php development, I give you, elusive reader, this (rather involved) solution. Basically, tear apart query_string in an array, add your thingies to the array, glue it back together with "&"s, tack it to the end of your $smarty.server.SCRIPT_NAME variable. Unless, of course, you also have PATH_INFO. Stick these antics in a smarty plugin, use to your heart content in templates. Usage and credits are in the code comments.

//  href="{$smarty.server.SCRIPT_NAME}?{add_to_query_string q="foo=bar&sna=fu"}}
// also:
//{capture name="qstring" assign="qstring"}{$pfield}={$ct->id}&sna="foo"{/capture}
//  href="{$smarty.server.SCRIPT_NAME}?{add_to_query_string q=$qstring}"
// OR
// {$qsedit="edit=1&id=`$product->id`"}
//  href="{$smarty.server.SCRIPT_NAME}?{add_to_query_string q=$qsedit}"
// See: http://www.smarty.net/forums/viewtopic.php?p=608&sid=5601319f7015ef49edaca38455c2517e
// https://cameronspear.com/blog/smart-query-strings/
function smarty_function_add_to_query_string($param, $smarty) 
  // turn current query string and changes into arrays  
  parse_str($_SERVER['QUERY_STRING'], $return);
  parse_str($param['q'], $new);

  foreach ($new as $key => $value) $return[$key] = $value;
  return http_build_query($return, '', '&');