The One Line Template Engine

Bought to you by vincevincevince over at webmasterworld.

The engine itself:
print preg_replace(“/\{([^\{]{1,100}?)\}/e”,”$$1″,file_get_contents(“template.tpl”));

Format of template.tpl file:

<html>
<head>
<title>{title}</title>
</head>
<body>
<h1>{header}</h1>
{text}
</body>
</html>

Setting variables:
$title=”Example page”;
$header=”My Examples”;
$text=”See the placeholders replaced?”;

“/\{([^\{]{1,100}?)\}/e”,”$$1″
I’m delimiting the regular expression with / / and using the modifier ‘e’ which causes the second argument to be evaluated by php.

Explanation


The pattern looks for an opening curly-brace ( \{ ) – the end of the pattern is a closing curly-brace ( \} ).

In between the two braces I look for any character which isn’t an opening curly-brace [^\{], avoiding mistaken nesting of tags.

I match between 1 and 100 of these non-{ characters by writing {1,100} and then I make the match non-greedy (try to find the shortest strings between { and }, not the longest) by adding a?. (? after *, + or {a,b} expressions changes them to non-greedy – in other situations? means 0 or 1 of the preceding).

The full string of non-{ characters is matched and stored as string $1 by surrounding that part of the pattern with brackets ().

Finally, the second argument of the preg_replace is “$$1”, using variable variables. If the pattern encounters “{title}” then the matched string $1 is “title” and so $$1 is $title.

Javascript Countdown with PHP Fall Back

Perhaps you have an event that happens on your webpage at a certain time, or you want to give a countdown to when the world ends. With this piece of JavaScript you can do this, and a PHP fall back will allow non JavaScript enabled browsers to still view the relevant information.

Let’s start with the JavaScript.

One of the issues here is that we don’t just want to display how much time is left, but also update that display continuously to provide our timer. There are two JavaScript functions that provide this ability, setTimeout which evaluates a function after a set amount of time and setInterval which continuously evaluates a function after a set amount of time.

Another issue we have to look out for is timing and accuracy. The examples on the internet all ran a small amount of code and then ran setTimeout after one second or very close to it. The problem is we don’t know exactly how long the code we are running takes, and this could and is different on every computer that runs the code.

So we need a slightly better approach. Here I’ve assigned a global variable which holds the time when the timer is complete and five times every second the display is updated to show the correct value. Perhaps we can take this further and set our interval uniquely each time based on millisecond comparison of the time? I leave that up to the reader.

The code is fairly self explanatory. The bulk of it is formating code to make the countdown look pretty. I’m not even sure it’s 100%. Onward with the code.

var launchtime = '';

// converts seconds into seconds, minutes, hours, days
function sec_to(secs, num1, num2) {
  return ((Math.floor(secs/num1))%num2).toString();
}

// Our actual function, cb_id is the id of the element to modify
// secs is the time until the event, and message is displayed after time has elapsed.
function countback(cb_id, secs, message) {
  // Our time initialization
  timenow = Math.floor(new Date().getTime() / 1000);
  if(launchtime == '') launchtime = timenow + secs;
  secs = launchtime - timenow;

  // We set up our default text strings
  var DisplayStr = '';
  if(message == undefined) message = 'Times Up!';

  // if we are there display our message
  if (secs < 0) {
    document.getElementById(cb_id).innerHTML = message;
    return;
  }

  // breakdown our time.
  var days = sec_to(secs,86400,100000);
  var hours = sec_to(secs,3600,24);
  var minutes = sec_to(secs,60,60);
  var seconds = sec_to(secs,1,60);

  // just some fancy code to make the time look pretty
  if (days > 0) DisplayStr += days + ' Day';
  if (days > 1) DisplayStr += 's';

  if (days > 0) DisplayStr += ', ';
  if (hours > 0) DisplayStr += hours + ' Hour';
  if (hours > 1) DisplayStr += 's';

  if (hours > 0) DisplayStr += ', ';
  if (minutes > 0) DisplayStr += minutes + ' Minute';
  if (minutes > 1) DisplayStr += 's';

  if (minutes > 0) DisplayStr += ', ';
  if (seconds > 0) DisplayStr += seconds + ' Second';
  if (seconds > 1) DisplayStr += 's';
  
  // Display our pretty time string
  document.getElementById(cb_id).innerHTML = DisplayStr;

  // Run this function five times every second  
  setTimeout("countback(\"countback\"," + (secs) + ",\"" + (message) + "\")", 200);
}

Now for the people who prefer a server side approach. This function pretty much mirrors the JavaScript approach. The one occlusion is the auto-updating feature of the client side script. Our only real recourse here is a meta refresh tag on the top of our page. But at the very least it provides the proper time.

Here is the code:

<?php 

function countback($seconds, $message = 'Times Up!') {
  $displaystr = '';
  if ($seconds < 0) return($message);
  
  $days = (floor($seconds/86400))%100000;
  $hours = (floor($seconds/3600))%24;
  $minutes = (floor($seconds/60))%60;
  $seconds = $seconds%60;

  if ($days > 0) $displaystr .= $days . ' Day';
  if ($days > 1) $displaystr .= 's';

  if ($days > 0) $displaystr .= ', ';
  if ($hours > 0) $displaystr .= $hours . ' Hour';
  if ($hours > 1) $displaystr .= 's';

  if ($hours > 0) $displaystr .= ', ';
  if ($minutes > 0) $displaystr .= $minutes . ' Minute';
  if ($minutes > 1) $displaystr .= 's';

  if ($minutes > 0) $displaystr .= ', ';
  if ($seconds > 0) $displaystr .= $seconds . ' Second';
  if ($seconds > 1) $displaystr .= 's';

  return($displaystr);
}

?>

That’s it in a nutshell. You can see a working example of it here. I’d like to thank Robert Hashemain for his javascript countdown which served as the inspiration for mine.