Avoid duplication of code in git_read_revlist
Avoid duplication of code in git_read_revlist

file:a/README -> file:b/README
--- a/README
+++ b/README
@@ -79,3 +79,47 @@
 If you want to edit the text header that appears above the project list on the
 home page, edit templates/hometext.tpl.
 
+
+[Caching]
+
+To turn on caching, set the 'cache' config item to true.  Gitphp will cache
+every page's output, including plaintext output and binary output such as
+blobs and snapshots, for the number of seconds specified in the
+'cachelifetime' config key.
+The 'cacheexpire' key is recommended for most users.  With this option on,
+gitphp will attempt to keep the cache in sync by automatically expiring any
+cached pages that are older than the most recent commit, on any branch.
+It is a slight performance hit to make this check, but the performance hit
+is tiny compared to the gain you get from turning on caching.  It will
+avoid situations where users are getting a cached version of a page that
+isn't up to date and doesn't reflect the most recent commit, or worse,
+pages that have been cached at different times and show data from both
+before and after a commit (eg page 1 of the shortlog shows the most recent
+commit but page 1 of the log was cached a while ago and doesn't show the
+most recent commit).
+However, if your project is so active that commits are constantly coming in
+and invalidating the cache, rendering it useless, it would be better to
+turn cache expiration off and just set a really short cache lifetime of
+a few seconds.  In other words:
+
+Most users:
+* Set 'cacheexpire' to TRUE
+* Set 'cachelifetime' high, 3600 seconds (1 hour) or more.  -1 means
+  cache forever
+
+Extremely active projects, with commits every few seconds, or advanced
+users that know exactly how often commits come in and want to save
+the performance of the expiration check:
+* Set 'cacheexpire' to FALSE
+* Set 'cachelifetime' low, between 5-10 seconds.
+
+If you ever run into problems with your cache not syncing correctly, or
+showing out of date information, you can use the 'expire' action to force
+expiration of all cache.  This action is not linked anywhere because it
+is not supposed to be run by users, it's more of an administrative function.
+To use it, you want to set a=expire.  So, for example, you would visit this
+address in a browser (obviously with the correct path to your gitphp
+index.php):
+
+http://yourserver.com/gitphp/index.php?a=expire
+

file:b/cache/.gitignore (new)
--- /dev/null
+++ b/cache/.gitignore
@@ -1,1 +1,2 @@
+*
 

--- a/config/gitphp.conf.php.example
+++ b/config/gitphp.conf.php.example
@@ -176,11 +176,35 @@
 $gitphp_conf['debug'] = FALSE;
 
 /*
- * lang
- * Sets the language of the interface
- * Must be a valid translation in include/locale/
- */
-$gitphp_conf['lang'] = "en_US";
+ * cache
+ * Turns on smarty caching
+ * Be careful with this.  If in doubt, leave it off
+ */
+$gitphp_conf['cache'] = FALSE;
+
+/*
+ * cacheexpire
+ * Attempts to automatically expire cache when a new commit renders
+ * it out of date.
+ * This is a good option for most users because it ensures the cache
+ * is always up to date and users are seeing correct information,
+ * although it is a slight performance hit.
+ * However, if your commits are coming in so quickly that the cache
+ * is constantly being expired, turn this off.
+ */
+$gitphp_conf['cacheexpire'] = TRUE;
+
+/*
+ * cachelifetime
+ * Sets how long a page will be cached, in seconds
+ * If you are automatically expiring the cache
+ * (see the 'cacheexpire' option above), then this can be set
+ * relatively high - 3600 seconds (1 hour) or even longer.
+ * -1 means no timeout.
+ * If you have turned cacheexpire off because of too many
+ * cache expirations, set this low (5-10 seconds).
+ */
+$gitphp_conf['cachelifetime'] = 3600;
 
 /*
  * git_projects

--- /dev/null
+++ b/include/cache.cache_expire.php
@@ -1,1 +1,36 @@
+<?php
+/*
+ *  cache.cache_expire.pehe
+ *  gitphp: A PHP git repository browser
+ *  Component: Cache - cache expire
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+require_once('gitutil.git_read_refs.php');
+
+function cache_expire($projectroot, $project, $projectlist, $expireall = false)
+{
+	global $tpl;
+
+	if ($expireall) {
+		$tpl->clear_all_cache();
+		return;
+	}
+
+	if ((!isset($projectroot)) || (!isset($project)))
+		return;
+
+	$headlist = git_read_refs($projectroot, $project, "refs/heads");
+
+	if (count($headlist) > 0) {
+		$age = $headlist[0]['age'];
+
+		$tpl->clear_cache(null, sha1($project), null, $age);
+
+		$tpl->clear_cache('projectlist.tpl', sha1(serialize($projectlist)), null, $age);
+	}
+}
+
+?>
+

--- a/include/defs.constants.php
+++ b/include/defs.constants.php
@@ -15,7 +15,5 @@
 define("GITPHP_COMPRESS_GZ", 2);
 define("GITPHP_COMPRESS_ZIP", 3);
 
-define("GITPHP_LOCALE_DIR", "include/locale/");
-
 ?>
 

--- a/include/display.git_blob.php
+++ b/include/display.git_blob.php
@@ -18,72 +18,77 @@
 function git_blob($projectroot, $project, $hash, $file, $hashbase)
 {
 	global $gitphp_conf,$tpl;
-	$head = git_read_head($projectroot . $project);
-	if (!isset($hashbase))
-		$hashbase = $head;
-	if (!isset($hash) && isset($file))
-		$hash = git_get_hash_by_path($projectroot . $project, $hashbase,$file,"blob");
-	$catout = git_cat_file($projectroot . $project, $hash);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("hashbase",$hashbase);
-	$tpl->assign("head", $head);
-	if ($co = git_read_commit($projectroot . $project, $hashbase)) {
-		$tpl->assign("fullnav",TRUE);
-		$refs = read_info_ref($projectroot . $project);
-		$tpl->assign("tree",$co['tree']);
-		$tpl->assign("title",$co['title']);
-		if (isset($file))
-			$tpl->assign("file",$file);
-		if ($hashbase == "HEAD") {
-			if (isset($refs[$head]))
-				$tpl->assign("hashbaseref",$refs[$head]);
+
+	$cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . sha1($file);
+
+	if (!$tpl->is_cached('blob.tpl',$cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		if (!isset($hashbase))
+			$hashbase = $head;
+		if (!isset($hash) && isset($file))
+			$hash = git_get_hash_by_path($projectroot . $project, $hashbase,$file,"blob");
+		$catout = git_cat_file($projectroot . $project, $hash);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("hashbase",$hashbase);
+		$tpl->assign("head", $head);
+		if ($co = git_read_commit($projectroot . $project, $hashbase)) {
+			$tpl->assign("fullnav",TRUE);
+			$refs = read_info_ref($projectroot . $project);
+			$tpl->assign("tree",$co['tree']);
+			$tpl->assign("title",$co['title']);
+			if (isset($file))
+				$tpl->assign("file",$file);
+			if ($hashbase == "HEAD") {
+				if (isset($refs[$head]))
+					$tpl->assign("hashbaseref",$refs[$head]);
+			} else {
+				if (isset($refs[$hashbase]))
+					$tpl->assign("hashbaseref",$refs[$hashbase]);
+			}
+		}
+		$paths = git_path_trees($projectroot . $project, $hashbase, $file);
+		$tpl->assign("paths",$paths);
+
+		if ($gitphp_conf['filemimetype']) {
+			$mime = file_mime($catout,$file);
+			if ($mime)
+				$mimetype = strtok($mime, "/");
+		}
+
+		if ($mimetype == "image") {
+			$tpl->assign("mime", $mime);
+			$tpl->assign("data", base64_encode($catout));
 		} else {
-			if (isset($refs[$hashbase]))
-				$tpl->assign("hashbaseref", $refs[$hashbase]);
-		}
-	}
-	$paths = git_path_trees($projectroot . $project, $hashbase, $file);
-	$tpl->assign("paths",$paths);
-
-	if ($gitphp_conf['filemimetype']) {
-		$mime = file_mime($catout,$file);
-		if ($mime)
-			$mimetype = strtok($mime, "/");
-	}
-
-	if ($mimetype == "image") {
-		$tpl->assign("mime", $mime);
-		$tpl->assign("data", base64_encode($catout));
-	} else {
-		$usedgeshi = $gitphp_conf['geshi'];
-		if ($usedgeshi) {
-			$usedgeshi = FALSE;
-			include_once($gitphp_conf['geshiroot'] . "geshi.php");
-			if (class_exists("GeSHi")) {
-				$geshi = new GeSHi("",'php');
-				if ($geshi) {
-					$lang = "";
-					if (isset($file))
-						$lang = $geshi->get_language_name_from_extension(substr(strrchr($file,'.'),1));
-					if (isset($lang) && (strlen($lang) > 0)) {
-						$geshi->set_source($catout);
-						$geshi->set_language($lang);
-						$geshi->set_header_type(GESHI_HEADER_DIV);
-						$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS);
-						$tpl->assign("geshiout",$geshi->parse_code());
-						$usedgeshi = TRUE;
+			$usedgeshi = $gitphp_conf['geshi'];
+			if ($usedgeshi) {
+				$usedgeshi = FALSE;
+				include_once($gitphp_conf['geshiroot'] . "geshi.php");
+				if (class_exists("GeSHi")) {
+					$geshi = new GeSHi("",'php');
+					if ($geshi) {
+						$lang = "";
+						if (isset($file))
+							$lang = $geshi->get_language_name_from_extension(substr(strrchr($file,'.'),1));
+						if (isset($lang) && (strlen($lang) > 0)) {
+							$geshi->set_source($catout);
+							$geshi->set_language($lang);
+							$geshi->set_header_type(GESHI_HEADER_DIV);
+							$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS);
+							$tpl->assign("geshiout",$geshi->parse_code());
+							$usedgeshi = TRUE;
+						}
 					}
 				}
 			}
-		}
 
-		if (!$usedgeshi) {
-			$lines = explode("\n",$catout);
-			$tpl->assign("lines",$lines);
+			if (!$usedgeshi) {
+				$lines = explode("\n",$catout);
+				$tpl->assign("lines",$lines);
+			}
 		}
 	}
 
-	$tpl->display("blob.tpl");
+	$tpl->display('blob.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_blob_plain.php
+++ b/include/display.git_blob_plain.php
@@ -12,26 +12,49 @@
 
 function git_blob_plain($projectroot,$project,$hash,$file)
 {
-	global $gitphp_conf;
+	global $gitphp_conf, $tpl;
 
-	if ($file)
-		$saveas = $file;
-	else
-		$saveas = $hash . ".txt";
+	$cachekey = sha1($project) . "|" . $hash . "|" . sha1($file);
 
-	$buffer = git_cat_file($projectroot . $project, $hash);
+	$buffer = null;
 
-	if ($gitphp_conf['filemimetype'])
-		$mime = file_mime($buffer, $file);
+	// XXX: Nasty hack to cache headers
+	if (!$tpl->is_cached('blobheaders.tpl', $cachekey)) {
+		if ($file)
+			$saveas = $file;
+		else
+			$saveas = $hash . ".txt";
 
-	if ($mime)
-		header("Content-type: " . $mime);
-	else
-		header("Content-type: text/plain; charset=UTF-8");
+		$buffer = git_cat_file($projectroot . $project, $hash);
 
-	header("Content-disposition: inline; filename=\"" . $saveas . "\"");
+		if ($gitphp_conf['filemimetype'])
+			$mime = file_mime($buffer, $file);
 
-	echo $buffer;
+		$headers = array();
+
+		if ($mime)
+			$headers[] = "Content-type: " . $mime;
+		else
+			$headers[] = "Content-type: text/plain; charset=UTF-8";
+
+		$headers[] = "Content-disposition: inline; filename=\"" . $saveas . "\"";
+
+		$tpl->assign("blobheaders", serialize($headers));
+	}
+	$out = $tpl->fetch('blobheaders.tpl', $cachekey);
+
+	$returnedheaders = unserialize($out);
+
+	foreach ($returnedheaders as $i => $header)
+		header($header);
+
+
+	if (!$tpl->is_cached('blobplain.tpl', $cachekey)) {
+		if (!$buffer)
+			$buffer = git_cat_file($projectroot . $project, $hash);
+		$tpl->assign("blob", $buffer);
+	}
+	$tpl->display('blobplain.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_blobdiff.php
+++ b/include/display.git_blobdiff.php
@@ -16,29 +16,34 @@
 function git_blobdiff($projectroot,$project,$hash,$hashbase,$hashparent,$file)
 {
 	global $tpl;
-	$ret = prep_tmpdir();
-	if ($ret !== TRUE) {
-		echo $ret;
-		return;
+
+	$cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . $hashparent . "|" . sha1($file);
+
+	if (!$tpl->is_cached('blobdiff.tpl', $cachekey)) {
+		$ret = prep_tmpdir();
+		if ($ret !== TRUE) {
+			echo $ret;
+			return;
+		}
+		$tpl->assign("hash",$hash);
+		$tpl->assign("hashparent",$hashparent);
+		$tpl->assign("hashbase",$hashbase);
+		if (isset($file))
+			$tpl->assign("file",$file);
+		if ($co = git_read_commit($projectroot . $project, $hashbase)) {
+			$tpl->assign("fullnav",TRUE);
+			$tpl->assign("tree",$co['tree']);
+			$tpl->assign("title",$co['title']);
+			$refs = read_info_ref($projectroot . $project);
+			if (isset($refs[$hashbase]))
+				$tpl->assign("hashbaseref",$refs[$hashbase]);
+		}
+		$paths = git_path_trees($projectroot . $project, $hashbase, $file);
+		$tpl->assign("paths",$paths);
+		$diffout = explode("\n",git_diff($projectroot . $project, $hashparent,($file?$file:$hashparent),$hash,($file?$file:$hash)));
+		$tpl->assign("diff",$diffout);
 	}
-	$tpl->assign("hash",$hash);
-	$tpl->assign("hashparent",$hashparent);
-	$tpl->assign("hashbase",$hashbase);
-	if (isset($file))
-		$tpl->assign("file",$file);
-	if ($co = git_read_commit($projectroot . $project, $hashbase)) {
-		$tpl->assign("fullnav",TRUE);
-		$tpl->assign("tree",$co['tree']);
-		$tpl->assign("title",$co['title']);
-		$refs = read_info_ref($projectroot . $project);
-		if (isset($refs[$hashbase]))
-			$tpl->assign("hashbaseref",$refs[$hashbase]);
-	}
-	$paths = git_path_trees($projectroot . $project, $hashbase, $file);
-	$tpl->assign("paths",$paths);
-	$diffout = explode("\n",git_diff($projectroot . $project, $hashparent,($file?$file:$hashparent),$hash,($file?$file:$hash)));
-	$tpl->assign("diff",$diffout);
-	$tpl->display("blobdiff.tpl");
+	$tpl->display('blobdiff.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_blobdiff_plain.php
+++ b/include/display.git_blobdiff_plain.php
@@ -12,13 +12,21 @@
 
 function git_blobdiff_plain($projectroot,$project,$hash,$hashbase,$hashparent,$file)
 {
-	$ret = prep_tmpdir();
-	if ($ret !== TRUE) {
-		echo $ret;
-		return;
+	global $tpl;
+
+	header("Content-type: text/plain; charset=UTF-8");
+
+	$cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . $hashparent . "|" . sha1($file);
+
+	if (!$tpl->is_cached('blobdiffplain.tpl', $cachekey)) {
+		$ret = prep_tmpdir();
+		if ($ret !== TRUE) {
+			echo $ret;
+			return;
+		}
+		$tpl->assign("blobdiff",git_diff($projectroot . $project, $hashparent,($file?"a/".$file:$hashparent),$hash,($file?"b/".$file:$hash)));
 	}
-	header("Content-type: text/plain; charset=UTF-8");
-	echo git_diff($projectroot . $project, $hashparent,($file?"a/".$file:$hashparent),$hash,($file?"b/".$file:$hash));
+	$tpl->display('blobdiffplain.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_commit.php
+++ b/include/display.git_commit.php
@@ -16,77 +16,83 @@
 function git_commit($projectroot,$project,$hash)
 {
 	global $tpl;
-	$co = git_read_commit($projectroot . $project, $hash);
-	$ad = date_str($co['author_epoch'],$co['author_tz']);
-	$cd = date_str($co['committer_epoch'],$co['committer_tz']);
-	if (isset($co['parent'])) {
-		$root = "";
-		$parent = $co['parent'];
-	} else {
-		$root = "--root";
-		$parent = "";
+
+	$cachekey = sha1($project) . "|" . $hash;
+
+	if (!$tpl->is_cached('commit.tpl', $cachekey)) {
+		$co = git_read_commit($projectroot . $project, $hash);
+		$ad = date_str($co['author_epoch'],$co['author_tz']);
+		$cd = date_str($co['committer_epoch'],$co['committer_tz']);
+		if (isset($co['parent'])) {
+			$root = "";
+			$parent = $co['parent'];
+		} else {
+			$root = "--root";
+			$parent = "";
+		}
+		$diffout = git_diff_tree($projectroot . $project, $root . " " . $parent . " " . $hash, TRUE);
+		$difftree = explode("\n",$diffout);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("tree",$co['tree']);
+		if (isset($co['parent']))
+			$tpl->assign("parent",$co['parent']);
+		$tpl->assign("title",$co['title']);
+		$refs = read_info_ref($projectroot . $project);
+		if (isset($refs[$co['id']]))
+			$tpl->assign("commitref",$refs[$co['id']]);
+		$tpl->assign("author",$co['author']);
+		$tpl->assign("adrfc2822",$ad['rfc2822']);
+		$tpl->assign("adhourlocal",$ad['hour_local']);
+		$tpl->assign("adminutelocal",$ad['minute_local']);
+		$tpl->assign("adtzlocal",$ad['tz_local']);
+		$tpl->assign("committer",$co['committer']);
+		$tpl->assign("cdrfc2822",$cd['rfc2822']);
+		$tpl->assign("cdhourlocal",$cd['hour_local']);
+		$tpl->assign("cdminutelocal",$cd['minute_local']);
+		$tpl->assign("cdtzlocal",$cd['tz_local']);
+		$tpl->assign("id",$co['id']);
+		$tpl->assign("parents",$co['parents']);
+		$tpl->assign("comment",$co['comment']);
+		$tpl->assign("difftreesize",count($difftree)+1);
+		$difftreelines = array();
+		foreach ($difftree as $i => $line) {
+			if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$line,$regs)) {
+				$difftreeline = array();
+				$difftreeline["from_mode"] = $regs[1];
+				$difftreeline["to_mode"] = $regs[2];
+				$difftreeline["from_mode_cut"] = substr($regs[1],-4);
+				$difftreeline["to_mode_cut"] = substr($regs[2],-4);
+				$difftreeline["from_id"] = $regs[3];
+				$difftreeline["to_id"] = $regs[4];
+				$difftreeline["status"] = $regs[5];
+				$difftreeline["similarity"] = ltrim($regs[6],"0");
+				$difftreeline["file"] = $regs[7];
+				$difftreeline["from_file"] = strtok($regs[7],"\t");
+				$difftreeline["from_filetype"] = file_type($regs[1]);
+				$difftreeline["to_file"] = strtok("\t");
+				$difftreeline["to_filetype"] = file_type($regs[2]);
+				if ((octdec($regs[2]) & 0x8000) == 0x8000)
+					$difftreeline["isreg"] = TRUE;
+				$modestr = "";
+				if ((octdec($regs[1]) & 0x17000) != (octdec($regs[2]) & 0x17000))
+					$modestr .= " from " . file_type($regs[1]) . " to " . file_type($regs[2]);
+				if ((octdec($regs[1]) & 0777) != (octdec($regs[2]) & 0777)) {
+					if ((octdec($regs[1]) & 0x8000) && (octdec($regs[2]) & 0x8000))
+						$modestr .= " mode: " . (octdec($regs[1]) & 0777) . "->" . (octdec($regs[2]) & 0777);
+					else if (octdec($regs[2]) & 0x8000)
+						$modestr .= " mode: " . (octdec($regs[2]) & 0777);
+				}
+				$difftreeline["modechange"] = $modestr;
+				$simmodechg = "";
+				if ($regs[1] != $regs[2])
+					$simmodechg .= ", mode: " . (octdec($regs[2]) & 0777);
+				$difftreeline["simmodechg"] = $simmodechg;
+				$difftreelines[] = $difftreeline;
+			}
+		}
+		$tpl->assign("difftreelines",$difftreelines);
 	}
-	$diffout = git_diff_tree($projectroot . $project, $root . " " . $parent . " " . $hash, TRUE);
-	$difftree = explode("\n",$diffout);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("tree",$co['tree']);
-	if (isset($co['parent']))
-		$tpl->assign("parent",$co['parent']);
-	$tpl->assign("title",$co['title']);
-	$refs = read_info_ref($projectroot . $project);
-	if (isset($refs[$co['id']]))
-		$tpl->assign("commitref",$refs[$co['id']]);
-	$tpl->assign("author",$co['author']);
-	$tpl->assign("adrfc2822",$ad['rfc2822']);
-	$tpl->assign("adhourlocal",$ad['hour_local']);
-	$tpl->assign("adminutelocal",$ad['minute_local']);
-	$tpl->assign("adtzlocal",$ad['tz_local']);
-	$tpl->assign("committer",$co['committer']);
-	$tpl->assign("cdrfc2822",$cd['rfc2822']);
-	$tpl->assign("cdhourlocal",$cd['hour_local']);
-	$tpl->assign("cdminutelocal",$cd['minute_local']);
-	$tpl->assign("cdtzlocal",$cd['tz_local']);
-	$tpl->assign("id",$co['id']);
-	$tpl->assign("parents",$co['parents']);
-	$tpl->assign("comment",$co['comment']);
-	$tpl->assign("difftreesize",count($difftree)+1);
-	$difftreelines = array();
-	foreach ($difftree as $i => $line) {
-		if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$line,$regs)) {
-			$difftreeline = array();
-			$difftreeline["from_mode"] = $regs[1];
-			$difftreeline["to_mode"] = $regs[2];
-			$difftreeline["from_mode_cut"] = substr($regs[1],-4);
-			$difftreeline["to_mode_cut"] = substr($regs[2],-4);
-			$difftreeline["from_id"] = $regs[3];
-			$difftreeline["to_id"] = $regs[4];
-			$difftreeline["status"] = $regs[5];
-			$difftreeline["similarity"] = ltrim($regs[6],"0");
-			$difftreeline["file"] = $regs[7];
-			$difftreeline["from_file"] = strtok($regs[7],"\t");
-			$difftreeline["from_filetype"] = file_type($regs[1]);
-			$difftreeline["from_filetype_localized"] = lookupstring($difftreeline["from_filetype"]);
-			$difftreeline["to_file"] = strtok("\t");
-			$difftreeline["to_filetype"] = file_type($regs[2]);
-			$difftreeline["to_filetype_localized"] = lookupstring($difftreeline["to_filetype"]);
-			if ((octdec($regs[2]) & 0x8000) == 0x8000)
-				$difftreeline["isreg"] = TRUE;
-			$modestr = "";
-			if ((octdec($regs[1]) & 0x17000) != (octdec($regs[2]) & 0x17000))
-				$difftreeline["typechange"] = TRUE;
-			if ((octdec($regs[1]) & 0777) != (octdec($regs[2]) & 0777)) {
-				if ((octdec($regs[1]) & 0x8000) && (octdec($regs[2]) & 0x8000))
-					$difftreeline["modechange"] = (octdec($regs[1]) & 0777) . "->" . (octdec($regs[2]) & 0777);
-				else if (octdec($regs[2]) & 0x8000)
-					$difftreeline["modechange"] = (octdec($regs[2]) & 0777);
-			}
-			if ($regs[1] != $regs[2])
-				$difftreeline["simmodechg"] = (octdec($regs[2]) & 0777);
-			$difftreelines[] = $difftreeline;
-		}
-	}
-	$tpl->assign("difftreelines",$difftreelines);
-	$tpl->display("commit.tpl");
+	$tpl->display('commit.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_commitdiff.php
+++ b/include/display.git_commitdiff.php
@@ -13,54 +13,56 @@
  require_once('gitutil.git_diff_tree.php');
  require_once('gitutil.read_info_ref.php');
  require_once('gitutil.git_diff.php');
- require_once('i18n.lookupstring.php');
 
 function git_commitdiff($projectroot,$project,$hash,$hash_parent)
 {
 	global $tpl;
-	$ret = prep_tmpdir();
-	if ($ret !== TRUE) {
-		echo $ret;
-		return;
+
+	$cachekey = sha1($project) . "|" . $hash . "|" . $hash_parent;
+
+	if (!$tpl->is_cached('commitdiff.tpl', $cachekey)) {
+		$ret = prep_tmpdir();
+		if ($ret !== TRUE) {
+			echo $ret;
+			return;
+		}
+		$co = git_read_commit($projectroot . $project, $hash);
+		if (!isset($hash_parent))
+			$hash_parent = $co['parent'];
+		$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
+		$difftree = explode("\n",$diffout);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("tree",$co['tree']);
+		$tpl->assign("hashparent",$hash_parent);
+		$tpl->assign("title",$co['title']);
+		if (isset($refs[$co['id']]))
+			$tpl->assign("commitref",$refs[$co['id']]);
+		$tpl->assign("comment",$co['comment']);
+		$difftreelines = array();
+		foreach ($difftree as $i => $line) {
+			if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs)) {
+				$difftreeline = array();
+				$difftreeline["from_mode"] = $regs[1];
+				$difftreeline["to_mode"] = $regs[2];
+				$difftreeline["from_id"] = $regs[3];
+				$difftreeline["to_id"] = $regs[4];
+				$difftreeline["status"] = $regs[5];
+				$difftreeline["file"] = $regs[6];
+				$difftreeline["from_type"] = file_type($regs[1]);
+				$difftreeline["to_type"] = file_type($regs[2]);
+				if ($regs[5] == "A")
+					$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, null,"/dev/null",$regs[4],"b/" . $regs[6]));
+				else if ($regs[5] == "D")
+					$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],null,"/dev/null"));
+				else if (($regs[5] == "M") && ($regs[3] != $regs[4]))
+					$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],$regs[4],"b/" . $regs[6]));
+				$difftreelines[] = $difftreeline;
+			}
+		}
+		$tpl->assign("difftreelines",$difftreelines);
 	}
-	$co = git_read_commit($projectroot . $project, $hash);
-	if (!isset($hash_parent))
-		$hash_parent = $co['parent'];
-	$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
-	$difftree = explode("\n",$diffout);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("tree",$co['tree']);
-	$tpl->assign("hashparent",$hash_parent);
-	$tpl->assign("title",$co['title']);
-	if (isset($refs[$co['id']]))
-		$tpl->assign("commitref",$refs[$co['id']]);
-	$tpl->assign("comment",$co['comment']);
-	$difftreelines = array();
-	foreach ($difftree as $i => $line) {
-		if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs)) {
-			$difftreeline = array();
-			$difftreeline["from_mode"] = $regs[1];
-			$difftreeline["to_mode"] = $regs[2];
-			$difftreeline["from_id"] = $regs[3];
-			$difftreeline["to_id"] = $regs[4];
-			$difftreeline["status"] = $regs[5];
-			$difftreeline["file"] = $regs[6];
-			$difftreeline["from_type"] = file_type($regs[1]);
-			$difftreeline["to_type"] = file_type($regs[2]);
-			$difftreeline["from_type_localized"] = lookupstring($difftreeline["from_type"]);
-			$difftreeline["to_type_localized"] = lookupstring($difftreeline["to_type"]);
-			if ($regs[5] == "A")
-				$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, null,"/dev/null",$regs[4],"b/" . $regs[6]));
-			else if ($regs[5] == "D")
-				$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],null,"/dev/null"));
-			else if (($regs[5] == "M") && ($regs[3] != $regs[4]))
-				$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],$regs[4],"b/" . $regs[6]));
-			$difftreelines[] = $difftreeline;
-		}
-	}
-	$tpl->assign("difftreelines",$difftreelines);
-	$tpl->display("commitdiff.tpl");
+	$tpl->display('commitdiff.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_commitdiff_plain.php
+++ b/include/display.git_commitdiff_plain.php
@@ -12,56 +12,60 @@
  require_once('util.script_url.php');
  require_once('gitutil.git_read_commit.php');
  require_once('gitutil.git_diff_tree.php');
- require_once('gitutil.git_rev_list.php');
+ require_once('gitutil.git_read_revlist.php');
  require_once('gitutil.read_info_ref.php');
  require_once('gitutil.git_diff.php');
 
 function git_commitdiff_plain($projectroot,$project,$hash,$hash_parent)
 {
 	global $tpl;
-	$ret = prep_tmpdir();
-	if ($ret !== TRUE) {
-		echo $ret;
-		return;
-	}
-	$co = git_read_commit($projectroot . $project, $hash);
-	if (!isset($hash_parent))
-		$hash_parent = $co['parent'];
-	$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
-	$difftree = explode("\n",$diffout);
-	$refs = read_info_ref($projectroot . $project,"tags");
-	$listout = git_rev_list($projectroot . $project, "HEAD");
-	$tok = strtok($listout,"\n");
-	while ($tok !== false) {
-		if (isset($refs[$tok]))
-			$tagname = $refs[$tok];
-		if ($tok == $hash)
-			break;
-		$tok = strtok("\n");
-	}
+
+	$cachekey = sha1($project) . "|" . $hash . "|" . $hash_parent;
+
 	header("Content-type: text/plain; charset=UTF-8");
 	header("Content-disposition: inline; filename=\"git-" . $hash . ".patch\"");
-	$ad = date_str($co['author_epoch'],$co['author_tz']);
-	$tpl->assign("from",$co['author']);
-	$tpl->assign("date",$ad['rfc2822']);
-	$tpl->assign("subject",$co['title']);
-	if (isset($tagname))
-		$tpl->assign("tagname",$tagname);
-	$tpl->assign("url",script_url() . "?p=" . $project . "&a=commitdiff&h=" . $hash);
-	$tpl->assign("comment",$co['comment']);
-	$diffs = array();
-	foreach ($difftree as $i => $line) {
-		if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs)) {
-			if ($regs[5] == "A")
-				$diffs[] = git_diff($projectroot . $project, null, "/dev/null", $regs[4], "b/" . $regs[6]);
-			else if ($regs[5] == "D")
-				$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], null, "/dev/null");
-			else if ($regs[5] == "M")
-				$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], $regs[4], "b/" . $regs[6]);
+
+	if (!$tpl->is_cached('diff_plaintext.tpl', $cachekey)) {
+		$ret = prep_tmpdir();
+		if ($ret !== TRUE) {
+			echo $ret;
+			return;
 		}
+		$co = git_read_commit($projectroot . $project, $hash);
+		if (!isset($hash_parent))
+			$hash_parent = $co['parent'];
+		$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
+		$difftree = explode("\n",$diffout);
+		$refs = read_info_ref($projectroot . $project,"tags");
+		$listout = git_read_revlist($projectroot . $project, "HEAD");
+		foreach ($listout as $i => $rev) {
+			if (isset($refs[$rev]))
+				$tagname = $refs[$rev];
+			if ($rev == $hash)
+				break;
+		}
+		$ad = date_str($co['author_epoch'],$co['author_tz']);
+		$tpl->assign("from",$co['author']);
+		$tpl->assign("date",$ad['rfc2822']);
+		$tpl->assign("subject",$co['title']);
+		if (isset($tagname))
+			$tpl->assign("tagname",$tagname);
+		$tpl->assign("url",script_url() . "?p=" . $project . "&a=commitdiff&h=" . $hash);
+		$tpl->assign("comment",$co['comment']);
+		$diffs = array();
+		foreach ($difftree as $i => $line) {
+			if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs)) {
+				if ($regs[5] == "A")
+					$diffs[] = git_diff($projectroot . $project, null, "/dev/null", $regs[4], "b/" . $regs[6]);
+				else if ($regs[5] == "D")
+					$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], null, "/dev/null");
+				else if ($regs[5] == "M")
+					$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], $regs[4], "b/" . $regs[6]);
+			}
+		}
+		$tpl->assign("diffs",$diffs);
 	}
-	$tpl->assign("diffs",$diffs);
-	$tpl->display("diff_plaintext.tpl");
+	$tpl->display('diff_plaintext.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_heads.php
+++ b/include/display.git_heads.php
@@ -13,11 +13,16 @@
 function git_heads($projectroot,$project)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	$tpl->assign("head",$head);
-	$headlist = git_read_refs($projectroot, $project, "refs/heads");
-	$tpl->assign("headlist",$headlist);
-	$tpl->display("heads.tpl");
+
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('heads.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		$tpl->assign("head",$head);
+		$headlist = git_read_refs($projectroot, $project, "refs/heads");
+		$tpl->assign("headlist",$headlist);
+	}
+	$tpl->display('heads.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_history.php
+++ b/include/display.git_history.php
@@ -17,46 +17,51 @@
 function git_history($projectroot,$project,$hash,$file)
 {
 	global $tpl;
-	if (!isset($hash))
-		$hash = git_read_head($projectroot . $project);
-	$co = git_read_commit($projectroot . $project, $hash);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	if (isset($refs[$hash]))
-		$tpl->assign("hashbaseref",$refs[$hash]);
-	$tpl->assign("tree",$co['tree']);
-	$tpl->assign("title",$co['title']);
-	$paths = git_path_trees($projectroot . $project, $hash, $file);
-	$tpl->assign("paths",$paths);
-	$cmdout = git_history_list($projectroot . $project, $hash, $file);
-	$lines = explode("\n", $cmdout);
-	$historylines = array();
-	foreach ($lines as $i => $line) {
-		if (ereg("^([0-9a-fA-F]{40})",$line,$regs))
-			$commit = $regs[1];
-		else if (ereg(":([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs) && isset($commit)) {
-				$historyline = array();
-				$co = git_read_commit($projectroot . $project, $commit);
-				$historyline["agestringage"] = $co['age_string_age'];
-				$historyline["agestringdate"] = $co['age_string_date'];
-				$historyline["authorname"] = $co['author_name'];
-				$historyline["commit"] = $commit;
-				$historyline["file"] = $file;
-				$historyline["title"] = $co['title_short'];
-				if (isset($refs[$commit]))
-					$historyline["commitref"] = $refs[$commit];
-				$blob = git_get_hash_by_path($projectroot . $project, $hash,$file);
-				$blob_parent = git_get_hash_by_path($projectroot . $project, $commit,$file);
-				if ($blob && $blob_parent && ($blob != $blob_parent)) {
-					$historyline["blob"] = $blob;
-					$historyline["blobparent"] = $blob_parent;
-				}
-				$historylines[] = $historyline;
-				unset($commit);
+
+	$cachekey = sha1($project) . "|" . $hash . "|" . sha1($file);
+
+	if (!$tpl->is_cached('history.tpl', $cachekey)) {
+		if (!isset($hash))
+			$hash = git_read_head($projectroot . $project);
+		$co = git_read_commit($projectroot . $project, $hash);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		if (isset($refs[$hash]))
+			$tpl->assign("hashbaseref",$refs[$hash]);
+		$tpl->assign("tree",$co['tree']);
+		$tpl->assign("title",$co['title']);
+		$paths = git_path_trees($projectroot . $project, $hash, $file);
+		$tpl->assign("paths",$paths);
+		$cmdout = git_history_list($projectroot . $project, $hash, $file);
+		$lines = explode("\n", $cmdout);
+		$historylines = array();
+		foreach ($lines as $i => $line) {
+			if (ereg("^([0-9a-fA-F]{40})",$line,$regs))
+				$commit = $regs[1];
+			else if (ereg(":([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs) && isset($commit)) {
+					$historyline = array();
+					$co = git_read_commit($projectroot . $project, $commit);
+					$historyline["agestringage"] = $co['age_string_age'];
+					$historyline["agestringdate"] = $co['age_string_date'];
+					$historyline["authorname"] = $co['author_name'];
+					$historyline["commit"] = $commit;
+					$historyline["file"] = $file;
+					$historyline["title"] = $co['title_short'];
+					if (isset($refs[$commit]))
+						$historyline["commitref"] = $refs[$commit];
+					$blob = git_get_hash_by_path($projectroot . $project, $hash,$file);
+					$blob_parent = git_get_hash_by_path($projectroot . $project, $commit,$file);
+					if ($blob && $blob_parent && ($blob != $blob_parent)) {
+						$historyline["blob"] = $blob;
+						$historyline["blobparent"] = $blob_parent;
+					}
+					$historylines[] = $historyline;
+					unset($commit);
+			}
 		}
+		$tpl->assign("historylines",$historylines);
 	}
-	$tpl->assign("historylines",$historylines);
-	$tpl->display("history.tpl");
+	$tpl->display('history.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_log.php
+++ b/include/display.git_log.php
@@ -16,51 +16,56 @@
 function git_log($projectroot,$project,$hash,$page)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	if (!isset($hash))
-		$hash = $head;
-	if (!isset($page))
-		$page = 0;
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("head",$head);
 
-	if ($page)
-		$tpl->assign("page",$page);
+	$cachekey = sha1($project) . "|" . $hash . "|" . (isset($page) ? $page : 0);
 
-	$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+	if (!$tpl->is_cached('log.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		if (!isset($hash))
+			$hash = $head;
+		if (!isset($page))
+			$page = 0;
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("head",$head);
 
-	$revlistcount = count($revlist);
-	$tpl->assign("revlistcount",$revlistcount);
+		if ($page)
+			$tpl->assign("page",$page);
 
-	if (!$revlist) {
-		$tpl->assign("norevlist",TRUE);
-		$co = git_read_commit($hash);
-		$tpl->assign("lastchange",$co['age_string']);
+		$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+
+		$revlistcount = count($revlist);
+		$tpl->assign("revlistcount",$revlistcount);
+
+		if (!$revlist) {
+			$tpl->assign("norevlist",TRUE);
+			$co = git_read_commit($hash);
+			$tpl->assign("lastchange",$co['age_string']);
+		}
+
+		$commitlines = array();
+		$commitcount = min(100,$revlistcount);
+		for ($i = 0; $i < $commitcount; $i++) {
+			$commit = $revlist[$i];
+			if (isset($commit) && strlen($commit) > 1) {
+				$commitline = array();
+				$co = git_read_commit($projectroot . $project, $commit);
+				$ad = date_str($co['author_epoch']);
+				$commitline["project"] = $project;
+				$commitline["commit"] = $commit;
+				if (isset($refs[$commit]))
+					$commitline["commitref"] = $refs[$commit];
+				$commitline["agestring"] = $co['age_string'];
+				$commitline["title"] = $co['title'];
+				$commitline["authorname"] = $co['author_name'];
+				$commitline["rfc2822"] = $ad['rfc2822'];
+				$commitline["comment"] = $co['comment'];
+				$commitlines[] = $commitline;
+			}
+		}
+		$tpl->assign("commitlines",$commitlines);
 	}
-
-	$commitlines = array();
-	$commitcount = min(100,$revlistcount);
-	for ($i = 0; $i < $commitcount; $i++) {
-		$commit = $revlist[$i];
-		if (isset($commit) && strlen($commit) > 1) {
-			$commitline = array();
-			$co = git_read_commit($projectroot . $project, $commit);
-			$ad = date_str($co['author_epoch']);
-			$commitline["project"] = $project;
-			$commitline["commit"] = $commit;
-			if (isset($refs[$commit]))
-				$commitline["commitref"] = $refs[$commit];
-			$commitline["agestring"] = $co['age_string'];
-			$commitline["title"] = $co['title'];
-			$commitline["authorname"] = $co['author_name'];
-			$commitline["rfc2822"] = $ad['rfc2822'];
-			$commitline["comment"] = $co['comment'];
-			$commitlines[] = $commitline;
-		}
-	}
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("log.tpl");
+	$tpl->display('log.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_message.php
+++ b/include/display.git_message.php
@@ -10,12 +10,17 @@
 function git_message($message, $error = FALSE, $standalone = TRUE)
 {
 	global $tpl;
-	$tpl->assign("message",$message);
-	if ($error)
-		$tpl->assign("error", TRUE);
-	if ($standalone)
-		$tpl->assign("standalone", TRUE);
-	$tpl->display("message.tpl");
+
+	$cachekey = sha1($message) . "|" . ($error ? "1" : "0") . "|" . ($standalone ? "1" : "0");
+
+	if (!$tpl->is_cached('message.tpl', $cachekey)) {
+		$tpl->assign("message",$message);
+		if ($error)
+			$tpl->assign("error", TRUE);
+		if ($standalone)
+			$tpl->assign("standalone", TRUE);
+	}
+	$tpl->display('message.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_opml.php
+++ b/include/display.git_opml.php
@@ -13,22 +13,27 @@
 function git_opml($projectroot,$projectlist)
 {
 	global $tpl,$gitphp_conf;
-	$projlist = git_read_projects($projectroot,$projectlist);
-	header("Content-type: text/xml; charset=UTF-8");
-	$tpl->assign("title",$gitphp_conf['title']);
-	$tpl->assign("self",script_url());
-	$opmllist = array();
-	foreach ($projlist as $cat => $plist) {
-		if (is_array($plist)) {
-			foreach ($plist as $i => $proj) {
-				$opmllist[] = $proj;
+
+	$cachekey = sha1(serialize($projectlist));
+
+	if (!$tpl->is_cached('opml.tpl', $cachekey)) {
+		header("Content-type: text/xml; charset=UTF-8");
+		$projlist = git_read_projects($projectroot,$projectlist);
+		$tpl->assign("title",$gitphp_conf['title']);
+		$tpl->assign("self",script_url());
+		$opmllist = array();
+		foreach ($projlist as $cat => $plist) {
+			if (is_array($plist)) {
+				foreach ($plist as $i => $proj) {
+					$opmllist[] = $proj;
+				}
+			} else {
+				$opmllist[] = $plist;
 			}
-		} else {
-			$opmllist[] = $plist;
 		}
+		$tpl->assign("opmllist",$opmllist);
 	}
-	$tpl->assign("opmllist",$opmllist);
-	$tpl->display("opml.tpl");
+	$tpl->display('opml.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_project_index.php
+++ b/include/display.git_project_index.php
@@ -11,16 +11,20 @@
 
 function git_project_index($projectroot, $projectlist)
 {
-	$projlist = git_read_projects($projectroot, $projectlist);
+	global $tpl, $git_projects;
+
 	header("Content-type: text/plain; charset=utf-8");
 	header("Content-Disposition: inline; filename=\"index.aux\"");
-	foreach ($projlist as $cat => $plist) {
-		if (is_array($plist)) {
-			foreach ($plist as $i => $proj)
-				echo $proj . "\n";
-		} else
-			echo $plist . "\n";
+
+	$cachekey = sha1(serialize($projectlist));
+
+	if (!$tpl->is_cached('projectindex.tpl', $cachekey)) {
+		if (isset($git_projects))
+			$tpl->assign("categorized", TRUE);
+		$projlist = git_read_projects($projectroot, $projectlist);
+		$tpl->assign("projlist", $projlist);
 	}
+	$tpl->display('projectindex.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_project_list.php
+++ b/include/display.git_project_list.php
@@ -11,61 +11,65 @@
  require_once('util.descrcmp.php');
  require_once('util.ownercmp.php');
  require_once('util.agecmp.php');
- require_once('i18n.lookupstring.php');
  require_once('gitutil.git_read_projects.php');
 
 function git_project_list($projectroot,$projectlist,$order = "project")
 {
 	global $tpl,$git_projects;
-	$projects = git_read_projects($projectroot,$projectlist, TRUE);
-	if (is_array($projects)) {
-		if (count($projects) > 0) {
-			if ($order)
-				$tpl->assign("order",$order);
-			if (!isset($git_projects)) {
-				switch ($order) {
-					case "project":
-						usort($projects,"projectcmp");
-						break;
-					case "descr":
-						usort($projects,"descrcmp");
-						break;
-					case "owner":
-						usort($projects,"ownercmp");
-						break;
-					case "age":
-						usort($projects,"agecmp");
-						break;
-				}
-				$tpl->assign("projects",$projects);
-			} else {
-				foreach ($projects as $cat => $plist) {
+
+	$cachekey = sha1(serialize($projectlist)) . "|" . sha1($order);
+
+	if (!$tpl->is_cached('projectlist.tpl', $cachekey)) {
+		$projects = git_read_projects($projectroot,$projectlist, TRUE);
+		if (is_array($projects)) {
+			if (count($projects) > 0) {
+				if ($order)
+					$tpl->assign("order",$order);
+				if (!isset($git_projects)) {
 					switch ($order) {
 						case "project":
-							usort($projects[$cat],"projectcmp");
+							usort($projects,"projectcmp");
 							break;
 						case "descr":
-							usort($projects[$cat],"descrcmp");
+							usort($projects,"descrcmp");
 							break;
 						case "owner":
-							usort($projects[$cat],"ownercmp");
+							usort($projects,"ownercmp");
 							break;
 						case "age":
-							usort($projects[$cat],"agecmp");
+							usort($projects,"agecmp");
 							break;
 					}
+					$tpl->assign("projects",$projects);
+				} else {
+					foreach ($projects as $cat => $plist) {
+						switch ($order) {
+							case "project":
+								usort($projects[$cat],"projectcmp");
+								break;
+							case "descr":
+								usort($projects[$cat],"descrcmp");
+								break;
+							case "owner":
+								usort($projects[$cat],"ownercmp");
+								break;
+							case "age":
+								usort($projects[$cat],"agecmp");
+								break;
+						}
+					}
+					$tpl->assign("categorizedprojects",$projects);
 				}
-				$tpl->assign("categorizedprojects",$projects);
+			} else {
+				$tpl->assign("message","No projects found");
+				$tpl->assign("error",TRUE);
 			}
 		} else {
-			$tpl->assign("message",lookupstring("No projects found"));
+			$tpl->assign("message",$projects);
 			$tpl->assign("error",TRUE);
 		}
-	} else {
-		$tpl->assign("message",$projects);
-		$tpl->assign("error",TRUE);
 	}
-	$tpl->display("projectlist.tpl");
+	$tpl->display('projectlist.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_rss.php
+++ b/include/display.git_rss.php
@@ -18,41 +18,46 @@
 function git_rss($projectroot,$project)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	$revlist = git_read_revlist($projectroot . $project, $head, GITPHP_RSS_ITEMS);
 	header("Content-type: text/xml; charset=UTF-8");
-	$tpl->assign("self",script_url());
 
-	$commitlines = array();
-	for ($i = 0; $i <= count($revlist); $i++) {
-		$commit = $revlist[$i];
-		$co = git_read_commit($projectroot . $project, $commit);
-		if (($i >= 20) && ((time() - $co['committer_epoch']) > 48*60*60))
-			break;
-		$cd = date_str($co['committer_epoch']);
-		$difftree = array();
-		$diffout = git_diff_tree($projectroot . $project, $co['parent'] . " " . $co['id']);
-		$tok = strtok($diffout,"\n");
-		while ($tok !== false) {
-			if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$tok,$regs))
-				$difftree[] = $regs[7];
-			$tok = strtok("\n");
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('rss.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		$revlist = git_read_revlist($projectroot . $project, $head, GITPHP_RSS_ITEMS);
+		$tpl->assign("self",script_url());
+
+		$commitlines = array();
+		for ($i = 0; $i <= count($revlist); $i++) {
+			$commit = $revlist[$i];
+			$co = git_read_commit($projectroot . $project, $commit);
+			if (($i >= 20) && ((time() - $co['committer_epoch']) > 48*60*60))
+				break;
+			$cd = date_str($co['committer_epoch']);
+			$difftree = array();
+			$diffout = git_diff_tree($projectroot . $project, $co['parent'] . " " . $co['id']);
+			$tok = strtok($diffout,"\n");
+			while ($tok !== false) {
+				if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$tok,$regs))
+					$difftree[] = $regs[7];
+				$tok = strtok("\n");
+			}
+			$commitline = array();
+			$commitline["cdmday"] = $cd['mday'];
+			$commitline["cdmonth"] = $cd['month'];
+			$commitline["cdhour"] = $cd['hour'];
+			$commitline["cdminute"] = $cd['minute'];
+			$commitline["title"] = $co['title'];
+			$commitline["author"] = $co['author'];
+			$commitline["cdrfc2822"] = $cd['rfc2822'];
+			$commitline["commit"] = $commit;
+			$commitline["comment"] = $co['comment'];
+			$commitline["difftree"] = $difftree;
+			$commitlines[] = $commitline;
 		}
-		$commitline = array();
-		$commitline["cdmday"] = $cd['mday'];
-		$commitline["cdmonth"] = $cd['month'];
-		$commitline["cdhour"] = $cd['hour'];
-		$commitline["cdminute"] = $cd['minute'];
-		$commitline["title"] = $co['title'];
-		$commitline["author"] = $co['author'];
-		$commitline["cdrfc2822"] = $cd['rfc2822'];
-		$commitline["commit"] = $commit;
-		$commitline["comment"] = $co['comment'];
-		$commitline["difftree"] = $difftree;
-		$commitlines[] = $commitline;
+		$tpl->assign("commitlines",$commitlines);
 	}
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("rss.tpl");
+	$tpl->display('rss.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_search.php
+++ b/include/display.git_search.php
@@ -9,76 +9,80 @@
 
 require_once('defs.constants.php');
 require_once('util.highlight.php');
-require_once('i18n.lookupstring.php');
 require_once('gitutil.git_read_commit.php');
-require_once('gitutil.git_rev_list.php');
+require_once('gitutil.git_read_revlist.php');
 require_once('display.git_message.php');
 
 function git_search($projectroot, $project, $hash, $search, $searchtype, $page = 0)
 {
 	global $tpl,$gitphp_conf;
 
-	if (!$gitphp_conf['search']) {
-		git_message(lookupstring('Search has been disabled'), TRUE, TRUE);
-		return;
+	$cachekey = sha1($project) . "|" . $hash . "|" . sha1($searchtype) . "|" . sha1($search) . "|" . (isset($page) ? $page : 0);
+
+	if (!$tpl->is_cached('search.tpl', $cachekey)) {
+
+		if (!$gitphp_conf['search']) {
+			git_message("Search has been disabled", TRUE, TRUE);
+			return;
+		}
+
+		if (!isset($search) || (strlen($search) < 2)) {
+			git_message("You must enter search text of at least 2 characters", TRUE, TRUE);
+			return;
+		}
+		if (!isset($hash)) {
+			//$hash = git_read_head($projectroot . $project);
+			$hash = "HEAD";
+		}
+
+		$co = git_read_commit($projectroot . $project, $hash);
+
+		$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100), FALSE, FALSE, $searchtype, $search);
+		if (count($revlist) < 1 || (strlen($revlist[0]) < 1)) {
+			git_message("No matches for '" . $search . "'.", FALSE, TRUE);
+			return;
+		}
+
+		$tpl->assign("hash",$hash);
+		$tpl->assign("treehash",$co['tree']);
+
+		$tpl->assign("search",$search);
+		$tpl->assign("searchtype",$searchtype);
+		$tpl->assign("page",$page);
+		$revlistcount = count($revlist);
+		$tpl->assign("revlistcount",$revlistcount);
+
+		$tpl->assign("title",$co['title']);
+
+		$commitlines = array();
+		$commitcount = min(100,$revlistcount);
+		for ($i = 0; $i < $commitcount; $i++) {
+			$commit = $revlist[$i];
+			if (strlen(trim($commit)) > 0) {
+				$commitline = array();
+				$co2 = git_read_commit($projectroot . $project, $commit);
+				$commitline["commit"] = $commit;
+				$commitline["agestringage"] = $co2['age_string_age'];
+				$commitline["agestringdate"] = $co2['age_string_date'];
+				$commitline["authorname"] = $co2['author_name'];
+				$commitline["title_short"] = $co2['title_short'];
+				if (strlen($co2['title_short']) < strlen($co2['title']))
+					$commitline["title"] = $co2['title'];
+				$commitline["committree"] = $co2['tree'];
+				$matches = array();
+				foreach ($co2['comment'] as $comline) {
+					$hl = highlight($comline, $search, "searchmatch", GITPHP_TRIM_LENGTH);
+					if ($hl && (strlen($hl) > 0))
+						$matches[] = $hl;
+				}
+				$commitline["matches"] = $matches;
+				$commitlines[] = $commitline;
+			}
+		}
+		
+		$tpl->assign("commitlines",$commitlines);
 	}
-
-	if (!isset($search) || (strlen($search) < 2)) {
-		git_message(lookupstring('You must enter search text of at least 2 characters'), TRUE, TRUE);
-		return;
-	}
-	if (!isset($hash)) {
-		//$hash = git_read_head($projectroot . $project);
-		$hash = "HEAD";
-	}
-
-	$co = git_read_commit($projectroot . $project, $hash);
-
-	$revlist = explode("\n",trim(git_rev_list($projectroot . $project, $hash, 101, ($page * 100), FALSE, FALSE, $searchtype, $search)));
-	if (count($revlist) < 1 || (strlen($revlist[0]) < 1)) {
-		git_message(sprintf(lookupstring('No matches for \'%1$s\'.'), $search), FALSE, TRUE);
-		return;
-	}
-
-	$tpl->assign("hash",$hash);
-	$tpl->assign("treehash",$co['tree']);
-
-	$tpl->assign("search",$search);
-	$tpl->assign("searchtype",$searchtype);
-	$tpl->assign("page",$page);
-	$revlistcount = count($revlist);
-	$tpl->assign("revlistcount",$revlistcount);
-
-	$tpl->assign("title",$co['title']);
-
-	$commitlines = array();
-	$commitcount = min(100,$revlistcount);
-	for ($i = 0; $i < $commitcount; $i++) {
-		$commit = $revlist[$i];
-		if (strlen(trim($commit)) > 0) {
-			$commitline = array();
-			$co2 = git_read_commit($projectroot . $project, $commit);
-			$commitline["commit"] = $commit;
-			$commitline["agestringage"] = $co2['age_string_age'];
-			$commitline["agestringdate"] = $co2['age_string_date'];
-			$commitline["authorname"] = $co2['author_name'];
-			$commitline["title_short"] = $co2['title_short'];
-			if (strlen($co2['title_short']) < strlen($co2['title']))
-				$commitline["title"] = $co2['title'];
-			$commitline["committree"] = $co2['tree'];
-			$matches = array();
-			foreach ($co2['comment'] as $comline) {
-				$hl = highlight($comline, $search, "searchmatch", GITPHP_TRIM_LENGTH);
-				if ($hl && (strlen($hl) > 0))
-					$matches[] = $hl;
-			}
-			$commitline["matches"] = $matches;
-			$commitlines[] = $commitline;
-		}
-	}
-	
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("search.tpl");
+	$tpl->display('search.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_search_files.php
+++ b/include/display.git_search_files.php
@@ -9,7 +9,6 @@
 
 require_once('defs.constants.php');
 require_once('util.highlight.php');
-require_once('i18n.lookupstring.php');
 require_once('gitutil.git_filesearch.php');
 require_once('gitutil.git_read_commit.php');
 require_once('display.git_message.php');
@@ -18,79 +17,84 @@
 {
 	global $tpl,$gitphp_conf;
 
-	if (!($gitphp_conf['search'] && $gitphp_conf['filesearch'])) {
-		git_message(lookupstring('File search has been disabled'), TRUE, TRUE);
-		return;
+	$cachekey = sha1($project) . "|" . $hash . "|" . "filesearch" . "|" . sha1($search) . "|" . (isset($page) ? $page : 0);
+
+	if (!$tpl->is_cached('searchfiles.tpl', $cachekey)) {
+
+		if (!($gitphp_conf['search'] && $gitphp_conf['filesearch'])) {
+			git_message("File search has been disabled", TRUE, TRUE);
+			return;
+		}
+
+		if (!isset($search) || (strlen($search) < 2)) {
+			git_message("You must enter search text of at least 2 characters", TRUE, TRUE);
+			return;
+		}
+		if (!isset($hash)) {
+			//$hash = git_read_head($projectroot . $project);
+			$hash = "HEAD";
+		}
+
+		$co = git_read_commit($projectroot . $project, $hash);
+
+		$filesearch = git_filesearch($projectroot . $project, $hash, $search, false, ($page * 100), 101);
+
+		if (count($filesearch) < 1) {
+			git_message("No matches for '" . $search . "'.", FALSE, TRUE);
+			return;
+		}
+
+		$tpl->assign("hash",$hash);
+		$tpl->assign("treehash",$co['tree']);
+
+		$tpl->assign("search",$search);
+		$tpl->assign("searchtype","file");
+		$tpl->assign("page",$page);
+		$filesearchcount = count($filesearch);
+		$tpl->assign("filesearchcount",$filesearchcount);
+
+		$tpl->assign("title",$co['title']);
+
+		$filesearchlines = array();
+		$i = 0;
+		foreach ($filesearch as $file => $data) {
+			$filesearchline = array();
+			$filesearchline["file"] = $file;
+			if (strpos($file,"/") !== false) {
+				$f = basename($file);
+				$d = dirname($file);
+				if ($d == "/")
+					$d = "";
+				$hlt = highlight($f, $search, "searchmatch");
+				if ($hlt)
+					$hlt = $d . "/" . $hlt;
+			} else
+				$hlt = highlight($file, $search, "searchmatch");
+			if ($hlt)
+				$filesearchline["filename"] = $hlt;
+			else
+				$filesearchline["filename"] = $file;
+			$filesearchline["hash"] = $data['hash'];
+			if ($data['type'] == "tree")
+				$filesearchline["tree"] = TRUE;
+			if (isset($data['lines'])) {
+				$matches = array();
+				foreach ($data['lines'] as $line) {
+					$hlt = highlight($line,$search,"searchmatch",floor(GITPHP_TRIM_LENGTH*1.5),true);
+					if ($hlt)
+						$matches[] = $hlt;
+				}
+				if (count($matches) > 0)
+					$filesearchline["matches"] = $matches;
+			}
+			$filesearchlines[] = $filesearchline;
+			$i++;
+			if ($i >= 100)
+				break;
+		}
+		$tpl->assign("filesearchlines",$filesearchlines);
 	}
-
-	if (!isset($search) || (strlen($search) < 2)) {
-		git_message(lookupstring('You must enter search text of at least 2 characters'), TRUE, TRUE);
-		return;
-	}
-	if (!isset($hash)) {
-		//$hash = git_read_head($projectroot . $project);
-		$hash = "HEAD";
-	}
-
-	$co = git_read_commit($projectroot . $project, $hash);
-
-	$filesearch = git_filesearch($projectroot . $project, $hash, $search, false, ($page * 100), 101);
-
-	if (count($filesearch) < 1) {
-		git_message(sprintf(lookupstring('No matches for \'%1$s\'.'), $search), FALSE, TRUE);
-		return;
-	}
-
-	$tpl->assign("hash",$hash);
-	$tpl->assign("treehash",$co['tree']);
-
-	$tpl->assign("search",$search);
-	$tpl->assign("searchtype","file");
-	$tpl->assign("page",$page);
-	$filesearchcount = count($filesearch);
-	$tpl->assign("filesearchcount",$filesearchcount);
-
-	$tpl->assign("title",$co['title']);
-
-	$filesearchlines = array();
-	$i = 0;
-	foreach ($filesearch as $file => $data) {
-		$filesearchline = array();
-		$filesearchline["file"] = $file;
-		if (strpos($file,"/") !== false) {
-			$f = basename($file);
-			$d = dirname($file);
-			if ($d == "/")
-				$d = "";
-			$hlt = highlight($f, $search, "searchmatch");
-			if ($hlt)
-				$hlt = $d . "/" . $hlt;
-		} else
-			$hlt = highlight($file, $search, "searchmatch");
-		if ($hlt)
-			$filesearchline["filename"] = $hlt;
-		else
-			$filesearchline["filename"] = $file;
-		$filesearchline["hash"] = $data['hash'];
-		if ($data['type'] == "tree")
-			$filesearchline["tree"] = TRUE;
-		if (isset($data['lines'])) {
-			$matches = array();
-			foreach ($data['lines'] as $line) {
-				$hlt = highlight($line,$search,"searchmatch",floor(GITPHP_TRIM_LENGTH*1.5),true);
-				if ($hlt)
-					$matches[] = $hlt;
-			}
-			if (count($matches) > 0)
-				$filesearchline["matches"] = $matches;
-		}
-		$filesearchlines[] = $filesearchline;
-		$i++;
-		if ($i >= 100)
-			break;
-	}
-	$tpl->assign("filesearchlines",$filesearchlines);
-	$tpl->display("searchfiles.tpl");
+	$tpl->display('searchfiles.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_shortlog.php
+++ b/include/display.git_shortlog.php
@@ -16,45 +16,50 @@
 function git_shortlog($projectroot,$project,$hash,$page)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	if (!isset($hash))
-		$hash = $head;
-	if (!isset($page))
-		$page = 0;
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("head",$head);
 
-	if ($page)
-		$tpl->assign("page",$page);
+	$cachekey = sha1($project) . "|" . $hash . "|" . (isset($page) ? $page : 0);
 
-	$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+	if (!$tpl->is_cached('shortlog.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		if (!isset($hash))
+			$hash = $head;
+		if (!isset($page))
+			$page = 0;
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("head",$head);
 
-	$revlistcount = count($revlist);
-	$tpl->assign("revlistcount",$revlistcount);
+		if ($page)
+			$tpl->assign("page",$page);
 
-	$commitlines = array();
-	$commitcount = min(100,count($revlist));
-	for ($i = 0; $i < $commitcount; $i++) {
-		$commit = $revlist[$i];
-		if (strlen(trim($commit)) > 0) {
-			$commitline = array();
-			if (isset($refs[$commit]))
-				$commitline["commitref"] = $refs[$commit];
-			$co = git_read_commit($projectroot . $project, $commit);
-			$ad = date_str($co['author_epoch']);
-			$commitline["commit"] = $commit;
-			$commitline["agestringage"] = $co['age_string_age'];
-			$commitline["agestringdate"] = $co['age_string_date'];
-			$commitline["authorname"] = $co['author_name'];
-			$commitline["title_short"] = $co['title_short'];
-			if (strlen($co['title_short']) < strlen($co['title']))
-				$commitline["title"] = $co['title'];
-			$commitlines[] = $commitline;
+		$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+
+		$revlistcount = count($revlist);
+		$tpl->assign("revlistcount",$revlistcount);
+
+		$commitlines = array();
+		$commitcount = min(100,count($revlist));
+		for ($i = 0; $i < $commitcount; $i++) {
+			$commit = $revlist[$i];
+			if (strlen(trim($commit)) > 0) {
+				$commitline = array();
+				if (isset($refs[$commit]))
+					$commitline["commitref"] = $refs[$commit];
+				$co = git_read_commit($projectroot . $project, $commit);
+				$ad = date_str($co['author_epoch']);
+				$commitline["commit"] = $commit;
+				$commitline["agestringage"] = $co['age_string_age'];
+				$commitline["agestringdate"] = $co['age_string_date'];
+				$commitline["authorname"] = $co['author_name'];
+				$commitline["title_short"] = $co['title_short'];
+				if (strlen($co['title_short']) < strlen($co['title']))
+					$commitline["title"] = $co['title'];
+				$commitlines[] = $commitline;
+			}
 		}
+		$tpl->assign("commitlines",$commitlines);
 	}
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("shortlog.tpl");
+	$tpl->display('shortlog.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_snapshot.php
+++ b/include/display.git_snapshot.php
@@ -12,33 +12,46 @@
 
 function git_snapshot($projectroot,$project,$hash)
 {
-	global $gitphp_conf;
+	global $gitphp_conf, $tpl;
+
 	if (!isset($hash))
 		$hash = "HEAD";
+
+	$cachekey = sha1($project) . "|" . $hash;
+
+	$bzcompress = false;
+	$gzencode = false;
+
 	$rname = str_replace(array("/",".git"),array("-",""),$project);
-	$arc = git_archive($projectroot . $project, $hash, $rname,
-		(($gitphp_conf['compressformat'] == GITPHP_COMPRESS_ZIP) ? "zip" : "tar"));
-
 	if ($gitphp_conf['compressformat'] == GITPHP_COMPRESS_ZIP) {
 		header("Content-Type: application/x-zip");
 		header("Content-Disposition: attachment; filename=" . $rname . ".zip");
-		echo $arc;
-		return;
 	} else if (($gitphp_conf['compressformat'] == GITPHP_COMPRESS_BZ2) && function_exists("bzcompress")) {
+		$bzcompress = true;
 		header("Content-Type: application/x-bzip2");
 		header("Content-Disposition: attachment; filename=" . $rname . ".tar.bz2");
-		echo bzcompress($arc,(isset($gitphp_conf['compresslevel'])?$gitphp_conf['compresslevel']:4));
-		return;
 	} else if (($gitphp_conf['compressformat'] == GITPHP_COMPRESS_GZ) && function_exists("gzencode")) {
+		$gzencode = true;
 		header("Content-Type: application/x-gzip");
 		header("Content-Disposition: attachment; filename=" . $rname . ".tar.gz");
-		echo gzencode($arc,(isset($gitphp_conf['compresslevel'])?$gitphp_conf['compresslevel']:-1));
-		return;
+	} else {
+		header("Content-Type: application/x-tar");
+		header("Content-Disposition: attachment; filename=" . $rname . ".tar");
 	}
 
-	header("Content-Type: application/x-tar");
-	header("Content-Disposition: attachment; filename=" . $rname . ".tar");
-	echo $arc;
+	if (!$tpl->is_cached('snapshot.tpl', $cachekey)) {
+
+		$arc = git_archive($projectroot . $project, $hash, $rname,
+			(($gitphp_conf['compressformat'] == GITPHP_COMPRESS_ZIP) ? "zip" : "tar"));
+
+		if (($gitphp_conf['compressformat'] == GITPHP_COMPRESS_BZ2) && $bzcompress) {
+			$arc = bzcompress($arc,(isset($gitphp_conf['compresslevel'])?$gitphp_conf['compresslevel']:4));
+		} else if (($gitphp_conf['compressformat'] == GITPHP_COMPRESS_GZ) && $gzencode) {
+			$arc = gzencode($arc,(isset($gitphp_conf['compresslevel'])?$gitphp_conf['compresslevel']:-1));
+		}
+		$tpl->assign("archive",$arc);
+	}
+	$tpl->display('snapshot.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_summary.php
+++ b/include/display.git_summary.php
@@ -19,53 +19,58 @@
 function git_summary($projectroot,$project)
 {
 	global $tpl;
-	$descr = git_project_descr($projectroot,$project);
-	$head = git_read_head($projectroot . $project);
-	$commit = git_read_commit($projectroot . $project, $head);
-	$commitdate = date_str($commit['committer_epoch'],$commit['committer_tz']);
-	$owner = git_project_owner($projectroot,$project);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("head",$head);
-	$tpl->assign("description",$descr);
-	$tpl->assign("owner",$owner);
-	$tpl->assign("lastchange",$commitdate['rfc2822']);
-	$revlist = git_read_revlist($projectroot . $project, $head, 17);
-	foreach ($revlist as $i => $rev) {
-		$revdata = array();
-		$revco = git_read_commit($projectroot . $project, $rev);
-		$authordate = date_str($revco['author_epoch']);
-		$revdata["commit"] = $rev;
-		if (isset($refs[$rev]))
-			$revdata["commitref"] = $refs[$rev];
-		$revdata["commitage"] = $revco['age_string'];
-		$revdata["commitauthor"] = $revco['author_name'];
-		if (strlen($revco['title_short']) < strlen($revco['title'])) {
-			$revdata["title"] = $revco['title'];
-			$revdata["title_short"] = $revco['title_short'];
-		} else
-			$revdata["title_short"] = $revco['title'];
-		$revlist[$i] = $revdata;
+
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('project.tpl', $cachekey)) {
+		$descr = git_project_descr($projectroot,$project);
+		$head = git_read_head($projectroot . $project);
+		$commit = git_read_commit($projectroot . $project, $head);
+		$commitdate = date_str($commit['committer_epoch'],$commit['committer_tz']);
+		$owner = git_project_owner($projectroot,$project);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("head",$head);
+		$tpl->assign("description",$descr);
+		$tpl->assign("owner",$owner);
+		$tpl->assign("lastchange",$commitdate['rfc2822']);
+		$revlist = git_read_revlist($projectroot . $project, $head, 17);
+		foreach ($revlist as $i => $rev) {
+			$revdata = array();
+			$revco = git_read_commit($projectroot . $project, $rev);
+			$authordate = date_str($revco['author_epoch']);
+			$revdata["commit"] = $rev;
+			if (isset($refs[$rev]))
+				$revdata["commitref"] = $refs[$rev];
+			$revdata["commitage"] = $revco['age_string'];
+			$revdata["commitauthor"] = $revco['author_name'];
+			if (strlen($revco['title_short']) < strlen($revco['title'])) {
+				$revdata["title"] = $revco['title'];
+				$revdata["title_short"] = $revco['title_short'];
+			} else
+				$revdata["title_short"] = $revco['title'];
+			$revlist[$i] = $revdata;
+		}
+		$tpl->assign("revlist",$revlist);
+
+		$taglist = git_read_refs($projectroot,$project,"refs/tags");
+		if (isset($taglist) && (count($taglist) > 0)) {
+			foreach ($taglist as $i => $tag) {
+				if (isset($tag['comment'])) {
+					$com = trim($tag['comment'][0]);
+					if (strlen($com) > GITPHP_TRIM_LENGTH)
+						$com = substr($trimmed,0,GITPHP_TRIM_LENGTH) . "...";
+					$taglist[$i]['comment'] = $com;
+				}
+			}
+			$tpl->assign("taglist",$taglist);
+		}
+
+		$headlist = git_read_refs($projectroot,$project,"refs/heads");
+		if (isset($headlist) && (count($headlist) > 0)) {
+			$tpl->assign("headlist",$headlist);
+		}
 	}
-	$tpl->assign("revlist",$revlist);
-
-	$taglist = git_read_refs($projectroot,$project,"refs/tags");
-	if (isset($taglist) && (count($taglist) > 0)) {
-		foreach ($taglist as $i => $tag) {
-			if (isset($tag['comment'])) {
-				$com = trim($tag['comment'][0]);
-				if (strlen($com) > GITPHP_TRIM_LENGTH)
-					$com = substr($trimmed,0,GITPHP_TRIM_LENGTH) . "...";
-				$taglist[$i]['comment'] = $com;
-			}
-		}
-		$tpl->assign("taglist",$taglist);
-	}
-
-	$headlist = git_read_refs($projectroot,$project,"refs/heads");
-	if (isset($headlist) && (count($headlist) > 0)) {
-		$tpl->assign("headlist",$headlist);
-	}
-	$tpl->display("project.tpl");
+	$tpl->display('project.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_tag.php
+++ b/include/display.git_tag.php
@@ -15,18 +15,23 @@
 {
 	global $tpl;
 
-	$head = git_read_head($projectroot . $project);
-	$tpl->assign("head",$head);
-	$tpl->assign("hash", $hash);
+	$cachekey = sha1($project) . "|" . $hash;
 
-	$tag = git_read_tag($projectroot . $project, $hash);
+	if (!$tpl->is_cached('tag.tpl', $cachekey)) {
 
-	$tpl->assign("tag",$tag);
-	if (isset($tag['author'])) {
-		$ad = date_str($tag['epoch'],$tag['tz']);
-		$tpl->assign("datedata",$ad);
+		$head = git_read_head($projectroot . $project);
+		$tpl->assign("head",$head);
+		$tpl->assign("hash", $hash);
+
+		$tag = git_read_tag($projectroot . $project, $hash);
+
+		$tpl->assign("tag",$tag);
+		if (isset($tag['author'])) {
+			$ad = date_str($tag['epoch'],$tag['tz']);
+			$tpl->assign("datedata",$ad);
+		}
 	}
-	$tpl->display("tag.tpl");
+	$tpl->display('tag.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_tags.php
+++ b/include/display.git_tags.php
@@ -13,13 +13,18 @@
 function git_tags($projectroot,$project)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	$tpl->assign("head",$head);
-	$taglist = git_read_refs($projectroot, $project, "refs/tags");
-	if (isset($taglist) && (count($taglist) > 0)) {
-		$tpl->assign("taglist",$taglist);
+
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('tags.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		$tpl->assign("head",$head);
+		$taglist = git_read_refs($projectroot, $project, "refs/tags");
+		if (isset($taglist) && (count($taglist) > 0)) {
+			$tpl->assign("taglist",$taglist);
+		}
 	}
-	$tpl->display("tags.tpl");
+	$tpl->display('tags.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_tree.php
+++ b/include/display.git_tree.php
@@ -18,46 +18,51 @@
 function git_tree($projectroot,$project,$hash,$file,$hashbase)
 {
 	global $tpl;
-	if (!isset($hash)) {
-		$hash = git_read_head($projectroot . $project);
+
+	$cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . sha1($file);
+
+	if (!$tpl->is_cached('tree.tpl', $cachekey)) {
+		if (!isset($hash)) {
+			$hash = git_read_head($projectroot . $project);
+			if (isset($file))
+				$hash = git_get_hash_by_path($projectroot . $project, ($hashbase?$hashbase:$hash),$file,"tree");
+				if (!isset($hashbase))
+					$hashbase = $hash;
+		}
+		$lsout = git_ls_tree($projectroot . $project, $hash, TRUE);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		if (isset($hashbase))
+			$tpl->assign("hashbase",$hashbase);
+		if (isset($hashbase) && ($co = git_read_commit($projectroot . $project, $hashbase))) {
+			$basekey = $hashbase;
+			$tpl->assign("fullnav",TRUE);
+			$tpl->assign("title",$co['title']);
+			if (isset($refs[$hashbase]))
+				$tpl->assign("hashbaseref",$refs[$hashbase]);
+		}
+		$paths = git_path_trees($projectroot . $project, $hashbase, $file);
+		$tpl->assign("paths",$paths);
+
 		if (isset($file))
-			$hash = git_get_hash_by_path($projectroot . $project, ($hashbase?$hashbase:$hash),$file,"tree");
-			if (!isset($hashbase))
-				$hashbase = $hash;
+			$tpl->assign("base",$file . "/");
+
+		$treelines = array();
+		$tok = strtok($lsout,"\0");
+		while ($tok !== false) {
+			if (ereg("^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$",$tok,$regs)) {
+				$treeline = array();
+				$treeline["filemode"] = mode_str($regs[1]);
+				$treeline["type"] = $regs[2];
+				$treeline["hash"] = $regs[3];
+				$treeline["name"] = $regs[4];
+				$treelines[] = $treeline;
+			}
+			$tok = strtok("\0");
+		}
+		$tpl->assign("treelines",$treelines);
 	}
-	$lsout = git_ls_tree($projectroot . $project, $hash, TRUE);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	if (isset($hashbase))
-		$tpl->assign("hashbase",$hashbase);
-	if (isset($hashbase) && ($co = git_read_commit($projectroot . $project, $hashbase))) {
-		$basekey = $hashbase;
-		$tpl->assign("fullnav",TRUE);
-		$tpl->assign("title",$co['title']);
-		if (isset($refs[$hashbase]))
-			$tpl->assign("hashbaseref",$refs[$hashbase]);
-	}
-	$paths = git_path_trees($projectroot . $project, $hashbase, $file);
-	$tpl->assign("paths",$paths);
-
-	if (isset($file))
-		$tpl->assign("base",$file . "/");
-
-	$treelines = array();
-	$tok = strtok($lsout,"\0");
-	while ($tok !== false) {
-		if (ereg("^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$",$tok,$regs)) {
-			$treeline = array();
-			$treeline["filemode"] = mode_str($regs[1]);
-			$treeline["type"] = $regs[2];
-			$treeline["hash"] = $regs[3];
-			$treeline["name"] = $regs[4];
-			$treelines[] = $treeline;
-		}
-		$tok = strtok("\0");
-	}
-	$tpl->assign("treelines",$treelines);
-	$tpl->display("tree.tpl");
+	$tpl->display('tree.tpl', $cachekey);
 }
 
 ?>

--- a/include/gitutil.git_exec_nix.php
+++ b/include/gitutil.git_exec_nix.php
@@ -10,7 +10,10 @@
  function git_exec_nix($project, $command)
  {
  	global $gitphp_conf;
-	$cmd = $gitphp_conf['gitbin'] . " --git-dir=" . $project . " " . $command;
+	$cmd = $gitphp_conf['gitbin'];
+	if (isset($project) && (strlen($project) > 0))
+		$cmd .= " --git-dir=" . $project;
+	$cmd .= " " . $command;
 	return shell_exec($cmd);
  }
 

--- a/include/gitutil.git_exec_win.php
+++ b/include/gitutil.git_exec_win.php
@@ -10,7 +10,10 @@
 function git_exec_win($project, $command)
 {
 	global $gitphp_conf;
-	$cmd = $gitphp_conf['gitbin'] . " --git-dir=" . $project . " " . $command;
+	$cmd = $gitphp_conf['gitbin'];
+	if (isset($project) && (strlen($project) > 0))
+		$cmd .= " --git-dir=" . $project;
+	$cmd .= " " . $command;
 	return shell_exec($cmd);
 }
 

--- a/include/gitutil.git_read_commit.php
+++ b/include/gitutil.git_read_commit.php
@@ -9,12 +9,11 @@
 
  require_once('defs.constants.php');
  require_once('util.age_string.php');
- require_once('gitutil.git_rev_list.php');
+ require_once('gitutil.git_read_revlist.php');
 
 function git_read_commit($proj,$head)
 {
-	$revlist = git_rev_list($proj,$head,1,NULL,TRUE,TRUE);
-	$lines = explode("\n",$revlist);
+	$lines = git_read_revlist($proj,$head,1,NULL,TRUE,TRUE);
 	if (!($lines[0]) || !ereg("^[0-9a-fA-F]{40}",$lines[0]))
 		return null;
 	$commit = array();

--- a/include/gitutil.git_read_projects.php
+++ b/include/gitutil.git_read_projects.php
@@ -7,7 +7,6 @@
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
 
- require_once('i18n.lookupstring.php');
  require_once('gitutil.git_recurse_projects.php');
  require_once('gitutil.git_project_info.php');
 
@@ -47,9 +46,9 @@
 				}
 			}
 		} else
-			return lookupstring("Projectroot is not a directory");
+			return "Projectroot is not a directory";
 	} else
-		return lookupstring("No projectroot set");
+		return "No projectroot set";
 	return $projects;
 }
 

--- a/include/gitutil.git_read_refs.php
+++ b/include/gitutil.git_read_refs.php
@@ -13,7 +13,6 @@
  require_once('gitutil.git_read_hash.php');
  require_once('gitutil.git_read_tag.php');
  require_once('gitutil.git_read_commit.php');
- require_once('i18n.lookupstring.php');
 
 function git_read_refs($projectroot,$project,$refdir)
 {
@@ -45,10 +44,9 @@
 		if ($type) {
 			$ref_item = array();
 			$ref_item['type'] = $type;
-			$ref_item['type_localized'] = lookupstring($type);
 			$ref_item['id'] = $ref_id;
 			$ref_item['epoch'] = 0;
-			$ref_item['age'] = "unknown";
+			$ref_item['age_string'] = "unknown";
 
 			if ($type == "tag") {
 				$tag = git_read_tag($projectroot . $project, $ref_id);
@@ -56,11 +54,13 @@
 				if ($tag['type'] == "commit") {
 					$co = git_read_commit($projectroot . $project, $tag['object']);
 					$ref_item['epoch'] = $co['committer_epoch'];
-					$ref_item['age'] = $co['age_string'];
+					$ref_item['age_string'] = $co['age_string'];
+					$ref_item['age'] = $co['age'];
 				} else if (isset($tag['epoch'])) {
 					$age = time() - $tag['epoch'];
 					$ref_item['epoch'] = $tag['epoch'];
-					$ref_item['age'] = age_string($age);
+					$ref_item['age_string'] = age_string($age);
+					$ref_item['age'] = $age;
 				}
 				$ref_item['reftype'] = $tag['type'];
 				$ref_item['name'] = $tag['name'];
@@ -72,9 +72,9 @@
 				$ref_item['title'] = $co['title'];
 				$ref_item['refid'] = $ref_id;
 				$ref_item['epoch'] = $co['committer_epoch'];
-				$ref_item['age'] = $co['age_string'];
+				$ref_item['age_string'] = $co['age_string'];
+				$ref_item['age'] = $co['age'];
 			}
-			$ref_item['reftype_localized'] = lookupstring($ref_item['reftype']);
 			$reflist[] = $ref_item;
 		}
 	}

--- a/include/gitutil.git_read_revlist.php
+++ b/include/gitutil.git_read_revlist.php
@@ -9,9 +9,9 @@
 
  require_once('gitutil.git_rev_list.php');
 
-function git_read_revlist($proj,$head,$count,$skip = NULL)
+function git_read_revlist($proj,$head,$count = NULL,$skip = NULL,$header = FALSE,$parents = FALSE,$greptype = NULL, $search = NULL)
 {
-	$revs = trim(git_rev_list($proj,$head,$count, $skip));
+	$revs = trim(git_rev_list($proj,$head,$count, $skip, $header, $parents, $greptype, $search));
 	$revlist = explode("\n",$revs);
 	return $revlist;
 }

--- a/include/gitutil.git_read_tag.php
+++ b/include/gitutil.git_read_tag.php
@@ -8,7 +8,6 @@
  */
 
  require_once('gitutil.git_cat_file.php');
- require_once('i18n.lookupstring.php');
 
 function git_read_tag($project, $tag_id)
 {
@@ -20,10 +19,9 @@
 	while ($tok !== false) {
 		if (ereg("^object ([0-9a-fA-F]{40})$",$tok,$regs))
 			$tag['object'] = $regs[1];
-		else if (ereg("^type (.+)$",$tok,$regs)) {
+		else if (ereg("^type (.+)$",$tok,$regs))
 			$tag['type'] = $regs[1];
-			$tag['type_localized'] = lookupstring($tag['type']);
-		} else if (ereg("^tag (.+)$",$tok,$regs))
+		else if (ereg("^tag (.+)$",$tok,$regs))
 			$tag['name'] = $regs[1];
 		else if (ereg("^tagger (.*) ([0-9]+) (.*)$",$tok,$regs)) {
 			$tag['author'] = $regs[1];

--- /dev/null
+++ b/include/gitutil.git_version.php
@@ -1,1 +1,21 @@
+<?php
+/*
+ *  gitutil.git_version.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Git utility - version
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+ require_once('gitutil.git_exec.php');
+
+ function git_version()
+ {
+ 	$verstr = explode(" ",git_exec(null, "--version"));
+	if (($verstr[0] == "git") && ($verstr[1] == "version"))
+		return $verstr[2];
+	return null;
+ }
+
+?>
+

--- a/include/i18n.initlocale.php
+++ /dev/null
@@ -1,27 +1,1 @@
-<?php
-/*
- *  i18n.initlocale.php
- *  gitphp: A PHP git repository browser
- *  Component: i18n - load locale
- *
- *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
- */
 
-require_once('i18n.lookupstring.php');
-
-function initlocale($locale = "en_US")
-{
-	global $tpl;
-
-	if (!include(GITPHP_LOCALE_DIR . $locale . ".php"))
-		include(GITPHP_LOCALE_DIR . "en_US.php");
-
-	if (isset($strings)) {
-		$tpl->assign("localize",$strings);
-	}
-
-	return $strings;
-}
-
-?>
-

--- a/include/i18n.lookupstring.php
+++ /dev/null
@@ -1,29 +1,1 @@
-<?php
-/*
- *  i18n.lookupstring.php
- *  gitphp: A PHP git repository browser
- *  Component: i18n - look up a string
- *
- *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
- */
 
-function lookupstring($str, $strings = null)
-{
-	global $localestrings;
-
-	if (!$str)
-		return null;
-
-	if (isset($strings) && (count($strings) > 0)) {
-		if (isset($strings[$str]))
-			return $strings[$str];
-	} else {
-		if (isset($localestrings[$str]))
-			return $localestrings[$str];
-	}
-
-	return $str;
-}
-
-?>
-

 Binary files a/include/locale/._zz_DEBUG.php and /dev/null differ
--- a/include/locale/en_US.php
+++ /dev/null
@@ -1,366 +1,1 @@
-<?php
-/*
- *  en_US.php
- *  gitphp: A PHP git repository browser
- *  Component: i18n - en_US
- */
 
-$strings = array(
-	/*
-	 * Error message that tells the user that
-	 * there were no projects found in the projectroot
-	 */
-	'No projects found' => 'No projects found',
-
-	/*
-	 * Error message that tells the user that the projectroot
-	 * they have set up is not a directory
-	 */
-	'Projectroot is not a directory' => 'Projectroot is not a directory',
-
-	/*
-	 * Error message that tells the user that they have not set
-	 * a projectroot
-	 */
-	'No projectroot set' => 'No projectroot set',
-
-	/*
-	 * Tells the user that all searching has been disabled
-	 */
-	'Search has been disabled' => 'Search has been disabled',
-
-	/*
-	 * Tells the user that searching with files has been disabled
-	 */
-	'File search has been disabled' => 'File search has been disabled',
-
-	/*
-	 * Tells the user that their search string must be a minimum of 2 characters
-	 */
-	'You must enter search text of at least 2 characters' => 'You must enter search text of at least 2 characters',
-
-	/*
-	 * Tells the user that no matches were found for their search, where
-	 * %1$s is the search string
-	 */
-	'No matches for \'%1$s\'.' => 'No matches for \'%1$s\'.',
-
-	/*
-	 * Used to indicate multiple projects - links back to the project
-	 * listing page
-	 */
-	'projects' => 'projects',
-
-	/*
-	 * Used as the header for the project name column on the project list
-	 */
-	'headerproject' => 'Project',
-
-	/*
-	 * Used as the header for the description column on the project list
-	 */
-	'headerdescription' => 'Description',
-
-	/*
-	 * Used as the header for the owner column on the project list
-	 */
-	'headerowner' => 'Owner',
-
-	/*
-	 * Used as the header for the age (last time project was changed) column in the
-	 * project list
-	 */
-	'headerlastchange' => 'Last Change',
-
-	/*
-	 * Used as the header for the actions column (links to various other pages for
-	 * that project)
-	 */
-	'headeractions' => 'Actions',
-
-	/*
-	 * Used as the name for the main project summary page
-	 */
-	'summary' => 'summary',
-
-	/*
-	 * Used as the name for the shortlog (abbreviated commit log) page
-	 */
-	'shortlog' => 'shortlog',
-
-	/*
-	 * Used as the name for the log (full commit log) page
-	 */
-	'log' => 'log',
-
-	/*
-	 * Used as the name for a single "commit" to the repository - 
-	 * for the commit page, as well as on other pages when referencing
-	 * a single commit object
-	 */
-	'commit' => 'commit',
-
-	/*
-	 * Used as the name for the commitdiff page, which shows all changes
-	 * in a single commit
-	 */
-	'commitdiff' => 'commitdiff',
-
-	/*
-	 * Used as the name for the tree page and to reference tree objects - 
-	 * "trees" being a particular project's directory of files (or subdirectory)
-	 * at a given revision
-	 */
-	'tree' => 'tree',
-
-	/*
-	 * Used as the name for the snapshot action, which sends a tarball of the
-	 * project at a given revision
-	 */
-	'snapshot' => 'snapshot',
-
-	/*
-	 * Used as the name for the tags page/section, which lists all tags for a project
-	 */
-	'tags' => 'tags',
-
-	/*
-	 * Used as the name for the single tag page, which shows all info on a single
-	 * tag object
-	 */
-	'tag' => 'tag',
-
-	/*
-	 * Used as the name for the heads page/section, which lists all heads for a project
-	 */
-	'heads' => 'heads',
-
-	/*
-	 * Used as the name for the history page, which lists all commits where a particular
-	 * file was changed
-	 */
-	'history' => 'history',
-
-	/*
-	 * Used as the name for the blob page, which shows the content of a file at a given
-	 * revision (its 'blob' data)
-	 */
-	'blob' => 'blob',
-
-	/*
-	 * Used as a link to show the differences in a file for a commit
-	 */
-	'diff' => 'diff',
-
-	/*
-	 * Used as a link to diff a particular revision of a file to the current version
-	 */
-	'difftocurrent' => 'diff to current',
-
-	/*
-	 * Used as the name for the search action, and to caption the search box
-	 */
-	'search' => 'search',
-
-	/*
-	 * Used as the caption on the 'RSS' button, which gets a feed of the most recent
-	 * commits to a project
-	 */
-	'RSS' => 'RSS',
-
-	/*
-	 * Used as the caption for the 'OPML' button, which gets a list of projects in OPML format
-	 */
-	'OPML' => 'OPML',
-
-	/*
-	 * Used as the caption for the 'TXT' button, which gets a list of projects in plaintext
-	 */
-	'TXT' => 'TXT',
-
-	/*
-	 * Used as a link on various actions (blob, blobdiff, commitdiff, etc) to get the plaintext
-	 * version of it
-	 */
-	'plain' => 'plain',
-
-	/*
-	 * Used as an indicator that something was added
-	 */
-	'new' => 'new',
-
-	/*
-	 * Used as an indicator that something was deleted
-	 */
-	'deleted' => 'deleted',
-
-	/*
-	 * Used as an indicator that something is a file - for example, that we are diffing a
-	 * file or searching within files
-	 */
-	'file' => 'file',
-
-	/*
-	 * Used to denote the author of a particular commit, or that we want to search
-	 * authors
-	 */
-	'author' => 'author',
-
-	/*
-	 * Used to denote the committer of a particular commit, or that we want to search
-	 * committers
-	 */
-	'committer' => 'committer',
-
-	/*
-	 * Used as the link to the previous page, when paginating through log entries
-	 * or search results
-	 */
-	'prev' => 'prev',
-
-	/*
-	 * Used as the link to the next page, when paginating through log entries
-	 * or search results
-	 */
-	'next' => 'next',
-
-	/*
-	 * Used as the link to the first page, when paginating through search results
-	 */
-	'first' => 'first',
-
-	/*
-	 * Used as the link to the HEAD, when paginating through log entries
-	 */
-	'HEAD' => 'HEAD',
-
-	/*
-	 * Used to indicate the description of the project, on the project summary page
-	 */
-	'description' => 'description',
-
-	/*
-	 * Used to indicate the owner of the project, on the project summary page
-	 */
-	'owner' => 'owner',
-
-	/*
-	 * Used to indicate the age (last change) of the project, on the project summary page
-	 */
-	'lastchange' => 'last change',
-
-	/*
-	 * Used to indicate the object that is the parent of this one (eg the commit that
-	 * came right before this one)
-	 */
-	'parent' => 'parent',
-
-	/*
-	 * Used to indicate the object (commit, etc) that is attached to a tag
-	 */
-	'object' => 'object',
-
-	/*
-	 * Used to indicate a new object was added, where
-	 * %1$s is the type of object (file or tree)
-	 */
-	'newobject' => 'new %1$s',
-
-	/*
-	 * Used to indicate a new object was added, where
-	 * %1$s is the type of object (file or tree) and
-	 * %2$s is the new mode
-	 */
-	'newobjectwithmode' => 'new %1$s with mode: %2$s',
-
-	/*
-	 * Used to indicate an object was deleted, where
-	 * %1$s is the type of object (file or tree)
-	 */
-	'deletedobject' => 'deleted %1$s',
-
-	/*
-	 * Used to indicate an object's type was changed, where
-	 * %1$s is the old type and %2$s is the new type
-	 */
-	'changedobjecttype' => 'changed from %1$s to %2$s',
-
-	/*
-	 * Used to indicate an object's mode was changed, where
-	 * %1$s is the mode change (either just one mode or
-	 * mode1->mode2)
-	 */
-	'changedobjectmode' => 'changed mode: %1$s',
-
-	/*
-	 * Used to indicate that an object was moved/renamed,
-	 * where %1$s is the original name, and
-	 * %2$d is the percentage similarity
-	 */
-	'movedobjectwithsimilarity' => 'moved from %1$s with %2$d%% similarity',
-
-	/*
-	 * Used to indicate that an object was moved/renamed,
-	 * where %1$s is the original name,
-	 * %2$d is the percentage similarity, and
-	 * %3$s is the mode
-	 */
-	'movedobjectwithsimilaritymodechange' => 'moved from %1$s with %2$d%% similarity, mode: $3$s',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * years ago, where %1$d is the number of years
-	 */
-	'ageyearsago' => '%1$d years ago',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * years ago, where %1$d is the number of years
-	 */
-	'agemonthsago' => '%1$d months ago',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * weeks ago, where %1$d is the number of weeks
-	 */
-	'ageweeksago' => '%1$d weeks ago',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * days ago, where %1$d is the number of days
-	 */
-	'agedaysago' => '%1$d days ago',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * hours ago, where %1$d is the number of hours
-	 */
-	'agehoursago' => '%1$d hours ago',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * minutes ago, where %1$d is the number of minutes
-	 */
-	'ageminago' => '%1$d min ago',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * seconds ago, where %1$d is the number of seconds
-	 */
-	'agesecago' => '%1$d sec ago',
-
-	/*
-	 * Used to indicate something is happening right now
-	 * (less than 3 seconds ago)
-	 */
-	'agerightnow' => 'right now',
-
-	/*
-	 * Used to indicate a certain number of files were changed in a commit
-	 * where %1$d is the numebr of files changed
-	 */
-	'fileschanged' => '%1$d files changed',
-);
-
-?>
-

--- a/include/locale/zz_DEBUG.php
+++ /dev/null
@@ -1,366 +1,1 @@
-<?php
-/*
- *  zz_DEBUG.php
- *  gitphp: A PHP git repository browser
- *  Component: i18n - zz_DEBUG
- */
 
-$strings = array(
-	/*
-	 * Error message that tells the user that
-	 * there were no projects found in the projectroot
-	 */
-	'No projects found' => 'No projects found',
-
-	/*
-	 * Error message that tells the user that the projectroot
-	 * they have set up is not a directory
-	 */
-	'Projectroot is not a directory' => 'Projectroot is not a directory',
-
-	/*
-	 * Error message that tells the user that they have not set
-	 * a projectroot
-	 */
-	'No projectroot set' => 'No projectroot set',
-
-	/*
-	 * Tells the user that all searching has been disabled
-	 */
-	'Search has been disabled' => 'Search has been disabled',
-
-	/*
-	 * Tells the user that searching with files has been disabled
-	 */
-	'File search has been disabled' => 'File search has been disabled',
-
-	/*
-	 * Tells the user that their search string must be a minimum of 2 characters
-	 */
-	'You must enter search text of at least 2 characters' => 'You must enter search text of at least 2 characters',
-
-	/*
-	 * Tells the user that no matches were found for their search, where
-	 * %1$s is the search string
-	 */
-	'No matches for \'%1$s\'.' => 'No matches for \'%1$s\'.',
-
-	/*
-	 * Used to indicate multiple projects - links back to the project
-	 * listing page
-	 */
-	'projects' => '{prőjėčts••}',
-
-	/*
-	 * Used as the header for the project name column on the project list
-	 */
-	'headerproject' => '{Pröjèct••}',
-
-	/*
-	 * Used as the header for the description column on the project list
-	 */
-	'headerdescription' => '{Dèscrîptîön•••}',
-
-	/*
-	 * Used as the header for the owner column on the project list
-	 */
-	'headerowner' => '{Öwnèr•}',
-
-	/*
-	 * Used as the header for the age (last time project was changed) column in the
-	 * project list
-	 */
-	'headerlastchange' => '{Låst Chångè•••}',
-
-	/*
-	 * Used as the header for the actions column (links to various other pages for
-	 * that project)
-	 */
-	'headeractions' => '{Åctîöns••}',
-
-	/*
-	 * Used as the name for the main project summary page
-	 */
-	'summary' => '{sûmmäry••}',
-
-	/*
-	 * Used as the name for the shortlog (abbreviated commit log) page
-	 */
-	'shortlog' => '{shõrtlög••}',
-
-	/*
-	 * Used as the name for the log (full commit log) page
-	 */
-	'log' => '{lõg•}',
-
-	/*
-	 * Used as the name for a single "commit" to the repository - 
-	 * for the commit page, as well as on other pages when referencing
-	 * a single commit object
-	 */
-	'commit' => '{cömmït•}',
-
-	/*
-	 * Used as the name for the commitdiff page, which shows all changes
-	 * in a single commit
-	 */
-	'commitdiff' => '{cõmmïtdîff•••}',
-
-	/*
-	 * Used as the name for the tree page and to reference tree objects - 
-	 * "trees" being a particular project's directory of files (or subdirectory)
-	 * at a given revision
-	 */
-	'tree' => '{tréè•}',
-
-	/*
-	 * Used as the name for the snapshot action, which sends a tarball of the
-	 * project at a given revision
-	 */
-	'snapshot' => '{snãpshöt••}',
-
-	/*
-	 * Used as the name for the tags page/section, which lists all tags for a project
-	 */
-	'tags' => '{tágs•}',
-
-	/*
-	 * Used as the name for the single tag page, which shows all info on a single
-	 * tag object
-	 */
-	'tag' => '{tàg•}',
-
-	/*
-	 * Used as the name for the heads page/section, which lists all heads for a project
-	 */
-	'heads' => '{hèáds•}',
-
-	/*
-	 * Used as the name for the history page, which lists all commits where a particular
-	 * file was changed
-	 */
-	'history' => '{hîstöry••}',
-
-	/*
-	 * Used as the name for the blob page, which shows the content of a file at a given
-	 * revision (its 'blob' data)
-	 */
-	'blob' => '{blôb•}',
-	
-	/*
-	 * Used as a link to show the differences in a file for a commit
-	 */
-	'diff' => '{dîff•}',
-
-	/*
-	 * Used as a link to diff a particular revision of a file to the current version
-	 */
-	'difftocurrent' => '{dîff tò cürrênt••••}',
-
-	/*
-	 * Used as the name for the search action, and to caption the search box
-	 */
-	'search' => '{sêàrch••}',
-
-	/*
-	 * Used as the caption on the 'RSS' button, which gets a feed of the most recent
-	 * commits to a project
-	 */
-	'RSS' => '{RSS•}',
-
-	/*
-	 * Used as the caption for the 'OPML' button, which gets a list of projects in OPML format
-	 */
-	'OPML' => '{ÖPML•}',
-
-	/*
-	 * Used as the caption for the 'TXT' button, which gets a list of projects in plaintext
-	 */
-	'TXT' => '{TXT•}',
-
-	/*
-	 * Used as a link on various actions (blob, blobdiff, commitdiff, etc) to get the plaintext
-	 * version of it
-	 */
-	'plain' => '{plåïn•}',
-
-    /*
-     * Used as an indicator that something was added
-     */
-    'new' => '{ñêw•}',
-
-	/*
-	 * Used as an indicator that something was deleted
-	 */
-	'deleted' => '{délètëd••}',
-
-	/*
-	 * Used as an indicator that something is a file - for example, that we are diffing a
-	 * file or searching within files
-	 */
-	'file' => '{fílĕ•}',
-
-	/*
-	 * Used to denote the author of a particular commit, or that we want to search
-	 * authors
-	 */
-	'author' => '{åûthōr••}',
-
-	/*
-	 * Used to denote the committer of a particular commit, or that we want to search
-	 * committers
-	 */
-	'committer' => '{cōmmĩttęr••}',
-
-	/*
-	 * Used as the link to the previous page, when paginating through log entries
-	 * or search results
-	 */
-	'prev' => '{prěv•}',
-
-	/*
-	 * Used as the link to the next page, when paginating through log entries
-	 * or search results
-	 */
-	'next' => '{ńėxt•}',
-
-	/*
-	 * Used as the link to the first page, when paginating through search results
-	 */
-	'first' => '{fĩrst•}',
-
-	/*
-	 * Used as the link to the HEAD, when paginating through log entries
-	 */
-	'HEAD' => '{HĚĂD•}',
-	
-	/*
-     * Used to indicate the description of the project, on the project summary page
-     */
-    'description' => '{dêscrïptìõn•••}',
-
-    /*
-     * Used to indicate the owner of the project, on the project summary page
-     */
-    'owner' => '{öwnêr•}',
-
-    /*
-     * Used to indicate the age (last change) of the project, on the project summary page
-     */
-    'lastchange' => '{låst chãngë•••}',
-
-	/*
-	 * Used to indicate the object that is the parent of this one (eg the commit that
-	 * came right before this one)
-	 */
-	'parent' => '{pārėnt••}',
-
-	/*
-	 * Used to indicate the object (commit, etc) that is attached to a tag
-	 */
-	'object' => '{őbjěct••}',
-
-	/*
-	 * Used to indicate a new object was added, where
-	 * %1$s is the type of object (file or tree)
-	 */
-	'newobject' => '{‹%1$s› ñėw•}',
-
-	/*
-	 * Used to indicate a new object was added, where
-	 * %1$s is the type of object (file or tree) and
-	 * %2$s is the new mode
-	 */
-	'newobjectwithmode' => '{mõdę ‹%2$s› ñėw ‹%1$s›•••••}',
-
-	/*
-	 * Used to indicate an object was deleted, where
-	 * %1$s is the type of object (file or tree)
-	 */
-	'deletedobject' => '{‹%1$s› dėlětē••}',
-	
-	/*
-	 * Used to indicate an object's type was changed, where
-	 * %1$s is the old type and %2$s is the new type
-	 */
-	'changedobjecttype' => '{‹%1$s› tö ‹%2$s› chăngěd•••••}',
-	
-	/*
-	 * Used to indicate an object's mode was changed, where
-	 * %1$s is the mode change (either just one mode or
-	 * mode1->mode2)
-	 */
-    'changedobjectmode' => '{‹%1$s› mõdêchångè••••}',
-
-	/*
-	 * Used to indicate that an object was moved/renamed,
-	 * where %1$s is the original name, ande
-	 * %2$d is the percentage similarity,
-	 */
-	'movedobjectwithsimilarity' => '{%%‹%2$d› sĩmīląrĭtŷ, mővɛd frŏm ‹%1$s›•••••••••}',
-	
-    /*
-     * Used to indicate that an object was moved/renamed,
-     * where %1$s is the original name,
-     * %2$d is the percentage similarity, and
-     * %3$s is the mode
-     */
-    'movedobjectwithsimilaritymodechange' => '{%%‹%2$d› sĩmīląrĭtŷ, mővɛd frŏm ‹%1$s› mode ‹%3$s›•••••••••}',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * years ago, where %1$d is the number of years
-	 */
-	'ageyearsago' => '{ŷrs ‹%1$d› ăgő•••}',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * years ago, where %1$d is the number of years
-	 */
-	'agemonthsago' => '{mős ‹%1$d› ăgő•••}',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * weeks ago, where %1$d is the number of weeks
-	 */
-	'ageweeksago' => '{wks ‹%1$d› ăgő•••}',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * days ago, where %1$d is the number of days
-	 */
-	'agedaysago' => '{dŷs ‹%1$d› ăgő•••}',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * hours ago, where %1$d is the number of hours
-	 */
-	'agehoursago' => '{hrs ‹%1$d› ăgő•••}',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * minutes ago, where %1$d is the number of minutes
-	 */
-	'ageminago' => '{mñs ‹%1$d› ăgő••}',
-
-	/*
-	 * Used to indicate something happened a certain number of
-	 * seconds ago, where %1$d is the number of seconds
-	 */
-	'agesecago' => '{scs ‹%1$d› ăgő••}',
-
-	/*
-	 * Used to indicate something is happening right now
-	 * (less than 3 seconds ago)
-	 */
-	'agerightnow' => '{rĩght nøw•••}',
-	
-     /*
-      * Used to indicate a certain number of files were changed in a commit
-      * where %1$d is the numebr of files changed
-      */
-     'fileschanged' => '{chângëd ‹%1$d› fĭlēs••••}',
-);
-
-?>
-

--- a/include/util.age_string.php
+++ b/include/util.age_string.php
@@ -7,34 +7,23 @@
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
 
-include('i18n.lookupstring.php');
-
 function age_string($age)
 {
-	if ($age > 60*60*24*365*2) {
-		return sprintf(lookupstring('ageyearsago'), (int)($age/60/60/24/365));
-		//i18n: return sprintf(lookupstring('%1$d years ago'), (int)($age/60/60/24/365));
-	} else if ($age > 60*60*24*(365/12)*2) {
-		return sprintf(lookupstring('agemonthsago'), (int)($age/60/60/24/(365/12)));
-		//i18n: return sprintf(lookupstring('%1$d months ago'), (int)($age/60/60/24/(365/12)));
-	} else if ($age > 60*60*24*7*2) {
-		return sprintf(lookupstring('ageweeksago'), (int)($age/60/60/24/7));
-		//i18n: return sprintf(lookupstring('%1$d weeks ago'), (int)($age/60/60/24/7));
-	} else if ($age > 60*60*24*2) {
-		return sprintf(lookupstring('agedaysago'), (int)($age/60/60/24));
-		//i18n: return sprintf(lookupstring('%1$d days ago'), (int)($age/60/60/24));
-	} else if ($age > 60*60*2) {
-		return sprintf(lookupstring('agehoursago'), (int)($age/60/60));
-		//i18n: return sprintf(lookupstring('%1$d hours ago'), (int)($age/60/60));
-	} else if ($age > 60*2) {
-		return sprintf(lookupstring('ageminago'), (int)($age/60));
-		//i18n: return sprintf(lookupstring('%1$d min ago'), (int)($age/60));
-	} else if ($age > 2) {
-		return sprintf(lookupstring('agesecago'), (int)$age);
-		//i18n: return sprintf(lookupstring('%1$d sec ago'), (int)$age);
-	}
-	return lookupstring('agerightnow');
-	//i18n: return lookupstring("right now");
+	if ($age > 60*60*24*365*2)
+		return (int)($age/60/60/24/365) . " years ago";
+	else if ($age > 60*60*24*(365/12)*2)
+		return (int)($age/60/60/24/(365/12)) . " months ago";
+	else if ($age > 60*60*24*7*2)
+		return (int)($age/60/60/24/7) . " weeks ago";
+	else if ($age > 60*60*24*2)
+		return (int)($age/60/60/24) . " days ago";
+	else if ($age > 60*60*2)
+		return (int)($age/60/60) . " hours ago";
+	else if ($age > 60*2)
+		return (int)($age/60) . " min ago";
+	else if ($age > 2)
+		return (int)$age . " sec ago";
+	return "right now";
 }
 
 ?>

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -22,33 +22,45 @@
   */
  require_once('config/gitphp.conf.php');
 
- /*
-  * Debug
-  */
- if ($gitphp_conf['debug']) {
- 	define('GITPHP_START_TIME', microtime(true));
-	error_reporting(E_ALL|E_STRICT);
- }
+ $extraoutput = FALSE;
 
  /*
   * Instantiate Smarty
   */
  require_once($gitphp_conf['smarty_prefix'] . "Smarty.class.php");
  $tpl =& new Smarty;
- if (isset($_GET['a']) &&
-     ($_GET['a'] != "commitdiff_plain") &&
-     ($_GET['a'] != "blob_plain") &&
-     ($_GET['a'] != "blobdiff_plain") &&
-     ($_GET['a'] != "rss") &&
-     ($_GET['a'] != "opml")) {
+ if ((!isset($_GET['a'])) || (
+     	($_GET['a'] != "commitdiff_plain") &&
+     	($_GET['a'] != "blob_plain") &&
+     	($_GET['a'] != "blobdiff_plain") &&
+     	($_GET['a'] != "rss") &&
+     	($_GET['a'] != "opml") &&
+	($_GET['a'] != "snapshot"))) {
 	$tpl->load_filter('output','trimwhitespace');
+	$extraoutput = TRUE;
 }
 
  /*
-  * Init i18n
-  */
- require_once('include/i18n.initlocale.php');
- $localestrings = initlocale($gitphp_conf['lang']);
+  * Debug
+  */
+ if ($gitphp_conf['debug']) {
+ 	if ($extraoutput) {
+		define('GITPHP_START_TIME', microtime(true));
+		error_reporting(E_ALL|E_STRICT);
+	}
+ }
+
+/*
+ * Caching
+ */
+ if ($gitphp_conf['cache']) {
+ 	$tpl->caching = 2;
+	$tpl->cache_lifetime = $gitphp_conf['cachelifetime'];
+	if ($gitphp_conf['cacheexpire']) {
+		require_once('include/cache.cache_expire.php');
+		cache_expire($gitphp_conf['projectroot'], (isset($_GET['p']) ? $_GET['p'] : null), $git_projects);
+	}
+ }
 
 /*
  * Setup global assigns used everywhere (such as header/footer)
@@ -82,7 +94,12 @@
 	$tpl->assign("filesearch",TRUE);
 
 
- if (isset($_GET['a']) && $_GET['a'] == "opml") {
+ if (isset($_GET['a']) && $_GET['a'] == "expire") {
+ 	require_once('include/cache.cache_expire.php');
+	require_once('include/display.git_message.php');
+	cache_expire(null, null, null, true);
+	git_message("Cache expired");
+ } else if (isset($_GET['a']) && $_GET['a'] == "opml") {
 	require_once('include/display.git_opml.php');
 	git_opml($gitphp_conf['projectroot'],$git_projects);
  } else if (isset($_GET['a']) && $_GET['a'] == "project_index") {
@@ -193,7 +210,7 @@
  	git_project_list($gitphp_conf['projectroot'],$git_projects,(isset($_GET['o']) ? $_GET['o'] : "project"));
  }
 
- if ($gitphp_conf['debug'])
+ if ($gitphp_conf['debug'] && $extraoutput)
  	echo "Execution time: " . round(microtime(true) - GITPHP_START_TIME, 8) . " sec";
 
 ?>

--- a/templates/blob.tpl
+++ b/templates/blob.tpl
@@ -11,25 +11,17 @@
  {* If we managed to look up commit info, we have enough info to display the full header - othewise just use a simple header *}
  <div class="page_nav">
    {if $fullnav}
-     {* i18n: summary = summary *}
-     {* i18n: shortlog = shortlog *}
-     {* i18n: log = log *}
-     {* i18n: commit = commit *}
-     {* i18n: comitdiff = commitdiff *}
-     {* i18n: tree = tree *}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hashbase}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hashbase}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hashbase}">{$localize.tree}</a><br />
-     {* i18n: plain = plain *}
+     <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hashbase}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hashbase}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hashbase}">tree</a><br />
      {if $file}
-       <a href="{$SCRIPT_NAME}?p={$project}&a=blob_plain&h={$hash}&f={$file}">{$localize.plain}</a> | 
-       {* i18n: HEAD = HEAD *}
+       <a href="{$SCRIPT_NAME}?p={$project}&a=blob_plain&h={$hash}&f={$file}">plain</a> | 
        {if ($hashbase != "HEAD") && ($hashbase != $head)}
-         <a href="{$SCRIPT_NAME}?p={$project}&a=blob&hb=HEAD&f={$file}">{$localize.HEAD}</a>
+         <a href="{$SCRIPT_NAME}?p={$project}&a=blob&hb=HEAD&f={$file}">HEAD</a>
        {else}
-         {$localize.HEAD}
+         HEAD
        {/if}
        <br />
      {else}
-       <a href="{$SCRIPT_NAME}?p={$project}&a=blob_plain&h={$hash}">{$localize.plain}</a><br />
+       <a href="{$SCRIPT_NAME}?p={$project}&a=blob_plain&h={$hash}">plain</a><br />
      {/if}
    {else}
      <br /><br />

--- a/templates/blobdiff.tpl
+++ b/templates/blobdiff.tpl
@@ -11,16 +11,9 @@
  {* If we managed to look up commit info, we have enough info to display the full header - othewise just use a simple header *}
  <div class="page_nav">
    {if $fullnav}
-     {* i18n: summary = summary *}
-     {* i18n: shortlog = shortlog *}
-     {* i18n: log = log *}
-     {* i18n: commit = commit *}
-     {* i18n: commitdiff = commitdiff *}
-     {* i18n: tree = tree *}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hashbase}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hashbase}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hashbase}">{$localize.tree}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hashbase}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hashbase}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hashbase}">tree</a>
      <br />
-     {* i18n: plain = plain *}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff_plain&h={$hash}&hp={$hashparent}&f={$file}">{$localize.plain}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff_plain&h={$hash}&hp={$hashparent}&f={$file}">plain</a>
    {else}
      <br /><br />
    {/if}
@@ -52,8 +45,7 @@
  <div class="page_body">
    <div class="diff_info">
      {* Display the from -> to diff header *}
-     {* i18n: blob = blob *}
-     {$localize.blob}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$hashparent}&hb={$hashbase}&f={$file}">{if $file}a/{$file}{else}{$hashparent}{/if}</a> -&gt; {$localize.blob}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$hash}&hb={$hashbase}&f={$file}">{if $file}b/{$file}{else}{$hash}{/if}</a>
+     blob:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$hashparent}&hb={$hashbase}&f={$file}">{if $file}a/{$file}{else}{$hashparent}{/if}</a> -&gt; blob:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$hash}&hb={$hashbase}&f={$file}">{if $file}b/{$file}{else}{$hash}{/if}</a>
    </div>
    {* Display the diff *}
    {include file='filediff.tpl'}

--- /dev/null
+++ b/templates/blobdiffplain.tpl
@@ -1,1 +1,9 @@
+{*
+ *  blobdiffplain.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Blobdiff plain template
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *}
+{$blobdiff}
 

--- /dev/null
+++ b/templates/blobheaders.tpl
@@ -1,1 +1,9 @@
+{*
+ *  blobheaders.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Blob header dummy template
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *}
+{$blobheaders}
 

--- /dev/null
+++ b/templates/blobplain.tpl
@@ -1,1 +1,9 @@
+{*
+ *  blobplain.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Blob plain template
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *}
+{$blob}
 

--- a/templates/commit.tpl
+++ b/templates/commit.tpl
@@ -10,13 +10,7 @@
 
  <div class="page_nav">
    {* Nav *}
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">{$localize.log}</a> | {$localize.commit} | {if $parent}<a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">{$localize.commitdiff}</a> | {/if}<a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">{$localize.tree}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">log</a> | commit | {if $parent}<a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">commitdiff</a> | {/if}<a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">tree</a>
    <br /><br />
  </div>
  <div>
@@ -35,8 +29,7 @@
    {* Commit data *}
    <table cellspacing="0">
      <tr>
-       {* i18n: author = author *}
-       <td>{$localize.author}</td>
+       <td>author</td>
        <td>{$author}</td>
      </tr>
      <tr>
@@ -44,8 +37,7 @@
        <td> {$adrfc2822} ({if $adhourlocal < 6}<span class="latenight">{/if}{$adhourlocal}:{$adminutelocal}{if $adhourlocal < 6}</span>{/if} {$adtzlocal})</td>
      </tr>
      <tr>
-       {* i18n: committer = committer *}
-       <td>{$localize.committer}</td>
+       <td>committer</td>
        <td>{$committer}</td>
      </tr>
      <tr>
@@ -53,26 +45,19 @@
        <td> {$cdrfc2822} ({$cdhourlocal}:{$cdminutelocal} {$cdtzlocal})</td>
      </tr>
      <tr>
-       {* i18n: commit = commit *}
-       <td>{$localize.commit}</td>
+       <td>commit</td>
        <td class="monospace">{$id}</td>
      <tr>
      <tr>
-       {* i18n: tree = tree *}
-       <td>{$localize.tree}</td>
+       <td>tree</td>
        <td class="monospace"><a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}" class="list">{$tree}</a></td>
-       {* i18n: snapshot = snapshot *}
-       {* i18n: tree = tree *}
-       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">{$localize.tree}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$hash}">{$localize.snapshot}</a></td>
+       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">tree</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$hash}">snapshot</a></td>
      </tr>
      {foreach from=$parents item=par}
        <tr>
-         {* i18n: parent = parent *}
-         <td>{$localize.parent}</td>
+         <td>parent</td>
 	 <td class="monospace"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$par}" class="list">{$par}</a></td>
-	 {* i18n: commit = commit *}
-	 {* i18n: commitdiff = commitdiff *}
-         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$par}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}&hp={$par}">{$localize.commitdiff}</a></td>
+         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$par}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}&hp={$par}">commitdiff</a></td>
        </tr>
      {/foreach}
    </table>
@@ -84,8 +69,7 @@
  </div>
  <div class="list_head">
    {if $difftreesize > 11}
-     {* i18n: fileschanged = %1$d files changed *}
-     {$localize.fileschanged|sprintf:$difftreesize}:
+     {$difftreesize} files changed:
    {/if}
  </div>
  <table cellspacing="0">
@@ -95,22 +79,12 @@
 	 
        {if $difftreelines[difftree].status == "A"}
          <td><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}" class="list">{$difftreelines[difftree].file}</a></td>
-	 {if $difftreelines[difftree].isreg}
-	   {* i18n: newobjectwithmode = new %1$s with mode: %2$s *}
-           <td><span class="newfile">[{$localize.newobjectwithmode|sprintf:$difftreelines[difftree].to_filetype_localized:$difftreelines[difftree].to_mode_cut}]</span></td>
-	 {else}
-	   {* i18n: newobject = new %1$s *}
-           <td><span class="newfile">[{$localize.newobject|sprintf:$difftreelines[difftree].to_filetype_localized}]</span></td>
-	 {/if}
-	 {* i18n: blob = blob *}
-         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">{$localize.blob}</a></td>
+         <td><span class="newfile">[new {$difftreelines[difftree].to_filetype}{if $difftreelines[difftree].isreg} with mode: {$difftreelines[difftree].to_mode_cut}{/if}]</span></td>
+         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">blob</a></td>
        {elseif $difftreelines[difftree].status == "D"}
          <td><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}" class="list">{$difftreelines[difftree].file}</a></td>
-	 {* i18n: deletedobject = deleted %1$s *}
-         <td><span class="deletedfile">[{$localize.deletedobject|sprintf:$difftreelines[difftree].from_filetype_localized}]</span></td>
-	 {* i18n: blob = blob *}
-	 {* i18n: history = history *}
-         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">{$localize.blob}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hash}&f={$difftreelines[difftree].file}">{$localize.history}</a></td>
+         <td><span class="deletedfile">[deleted {$difftreelines[difftree].from_filetype}]</span></td>
+         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">blob</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hash}&f={$difftreelines[difftree].file}">history</a></td>
        {elseif $difftreelines[difftree].status == "M" || $difftreelines[difftree].status == "T"}
          <td>
            {if $difftreelines[difftree].to_id != $difftreelines[difftree].from_id}
@@ -119,38 +93,13 @@
              <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}" class="list">{$difftreelines[difftree].file}</a>
            {/if}
          </td>
-         <td>
-	   {if $difftreelines[difftree].from_mode != $difftreelines[difftree].to_mode}
-	     <span class="changedfile">
-	       {if $difftreelines[difftree].typechange}
-	         {* i18n: changedobjecttype = changed from %1$s to %2$s *}
-	         [{$localize.changedobjecttype|sprintf:$difftreelines[difftree].from_filetype_localized:$difftreelines[difftree].to_filetype_localized}]
-	       {/if}
-	       {if $difftreelines[difftree].modechange}
-	         {* i18n: changedobjectmode = changed mode: %1$s *}
-	         [{$localize.changedobjectmode|sprintf:$difftreelines[difftree].modechange}]
-	       {/if}
-	     </span>
-	   {/if}
-	 </td>
+         <td>{if $difftreelines[difftree].from_mode != $difftreelines[difftree].to_mode} <span class="changedfile">[changed{$difftreelines[difftree].modechange}]</span>{/if}</td>
          <td class="link">
-	   {* i18n: blob = blob *}
-	   {* i18n: diff = diff *}
-	   {* i18n: history = history *}
-           <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">{$localize.blob}</a>{if $difftreelines[difftree].to_id != $difftreelines[difftree].from_id} | <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff&h={$difftreelines[difftree].to_id}&hp={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">{$localize.diff}</a>{/if} | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hash}&f={$difftreelines[difftree].file}">{$localize.history}</a></td>
+           <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">blob</a>{if $difftreelines[difftree].to_id != $difftreelines[difftree].from_id} | <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff&h={$difftreelines[difftree].to_id}&hp={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">diff</a>{/if} | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hash}&f={$difftreelines[difftree].file}">history</a></td>
        {elseif $difftreelines[difftree].status == "R"}
          <td><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].to_file}" class="list">{$difftreelines[difftree].to_file}</a></td>
-	 {capture name='oldfile' assign='oldfile'}<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].from_file}" class="list">{$difftreelines[difftree].from_file}</a>{/capture}
-         {if $difftreelines[difftree].simmodechg}
-           {* i18n: movedobjectwithsimilaritymodechange = moved from %1$s with %2$d%% similarity, mode: %3$s *}
-           <td><span class="movedfile">[{$localize.movedobjectwithsimilaritymodechange|sprintf:$oldfile:$difftreelines[difftree].similarity:$difftreelines[difftree].simmodechg}]</span></td>
-	 {else}
-           {* i18n: movedobjectwithsimilarity = moved from %1$s with %2$d%% similarity *}
-           <td><span class="movedfile">[{$localize.movedobjectwithsimilarity|sprintf:$oldfile:$difftreelines[difftree].similarity}]</span></td>
-	 {/if}
-	 {* i18n: blob = blob *}
-	 {* i18n: diff = diff *}
-         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].to_file}">{$localize.blob}</a>{if $difftreelines[difftree].to_id != $difftreelines[difftree].from_id} | <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff&h={$difftreelines[difftree].to_id}&hp={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].to_file}">{$localize.diff}</a>{/if}</td>
+         <td><span class="movedfile">[moved from <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].from_file}" class="list">{$difftreelines[difftree].from_file}</a> with {$difftreelines[difftree].similarity}% similarity{$difftreelines[difftree].simmodechg}]</span></td>
+         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].to_file}">blob</a>{if $difftreelines[difftree].to_id != $difftreelines[difftree].from_id} | <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff&h={$difftreelines[difftree].to_id}&hp={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].to_file}">diff</a>{/if}</td>
        {/if}
 
      </tr>

--- a/templates/commitdiff.tpl
+++ b/templates/commitdiff.tpl
@@ -10,14 +10,7 @@
 
  {* Nav *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: plain = plain *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">{$localize.commit}</a> | {$localize.commitdiff} | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">{$localize.tree}</a><br /><a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff_plain&h={$hash}&hp={$hashparent}">{$localize.plain}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">commit</a> | commitdiff | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">tree</a><br /><a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff_plain&h={$hash}&hp={$hashparent}">plain</a>
  </div>
  <div>
    <br /><br />
@@ -34,18 +27,16 @@
    {section name=difftree loop=$difftreelines}
      {if $difftreelines[difftree].status == "A"}
        <div class="diff_info">
-         {* i18n: deleted = deleted *}
-         {$difftreelines[difftree].to_type_localized}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}{$difftreelines[difftree].file}{else}{$difftreelines[difftree].to_id}{/if}</a>({$localize.new})
+         {$difftreelines[difftree].to_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}{$difftreelines[difftree].file}{else}{$difftreelines[difftree].to_id}{/if}</a>(new)
        </div>
      {elseif $difftreelines[difftree].status == "D"}
        <div class="diff_info">
-         {* i18n: deleted = deleted *}
-         {$difftreelines[difftree].from_type_localized}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}{$difftreelines[difftree].file}{else}{$difftreelines[difftree].from_id}{/if}</a>({$localize.deleted})
+         {$difftreelines[difftree].from_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}{$difftreelines[difftree].file}{else}{$difftreelines[difftree].from_id}{/if}</a>(deleted)
        </div>
      {elseif $difftreelines[difftree].status == "M"}
        {if $difftreelines[difftree].from_id != $difftreelines[difftree].to_id}
          <div class="diff_info">
-	   {$difftreelines[difftree].from_type_localized}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}a/{$difftreelines[difftree].file}{else}{$difftreelines[difftree].from_id}{/if}</a> -&gt; {$difftreelines[difftree].to_type_localized}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}b/{$difftreelines[difftree].file}{else}{$difftreelines[difftree].to_id}{/if}</a>
+	   {$difftreelines[difftree].from_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].from_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}a/{$difftreelines[difftree].file}{else}{$difftreelines[difftree].from_id}{/if}</a> -&gt; {$difftreelines[difftree].to_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$difftreelines[difftree].to_id}&hb={$hash}&f={$difftreelines[difftree].file}">{if $difftreelines[difftree].file}b/{$difftreelines[difftree].file}{else}{$difftreelines[difftree].to_id}{/if}</a>
 	 </div>
        {/if}
      {/if}

--- a/templates/footer.tpl
+++ b/templates/footer.tpl
@@ -11,14 +11,11 @@
           <div class="page_footer_text">{$projectdescription}</div>
         {/if}
 	{if $validproject}
-	  {* i18n: RSS = RSS *}
-          <a href="{$SCRIPT_NAME}?p={$project}&a=rss" class="rss_logo">{$localize.RSS}</a>
+          <a href="{$SCRIPT_NAME}?p={$project}&a=rss" class="rss_logo">RSS</a>
 	{/if}
       {else}
-        {* i18n: OPML = OPML *}
-        <a href="{$SCRIPT_NAME}?a=opml" class="rss_logo">{$localize.OPML}</a>
-	{* i18n: TXT = TXT *}
-        <a href="{$SCRIPT_NAME}?a=project_index" class="rss_logo">{$localize.TXT}</a>
+        <a href="{$SCRIPT_NAME}?a=opml" class="rss_logo">OPML</a>
+        <a href="{$SCRIPT_NAME}?a=project_index" class="rss_logo">TXT</a>
       {/if}
     </div>
   </body>

--- a/templates/header.tpl
+++ b/templates/header.tpl
@@ -10,7 +10,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
   <!-- gitphp web interface {$version}, (C) 2006 Christopher Han <xiphux@gmail.com> -->
   <head>
-    <title>{$pagetitle}{if $project && $validproject} :: {$project}{if $action && $validaction}/{$localize.$action}{/if}{/if}</title>
+    <title>{$pagetitle}{if $project && $validproject} :: {$project}{if $action && $validaction}/{$action}{/if}{/if}</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     {if $validproject}
       <link rel="alternate" title="{$project} log" href="{$SCRIPT_NAME}?p={$project}&a=rss" type="application/rss+xml" />
@@ -23,12 +23,11 @@
       <a href="http://www.kernel.org/pub/software/scm/git/docs/" title="git documentation">
         <img src="git-logo.png" width="72" height="27" alt="git" class="logo" />
       </a>
-      {* i18n: projects = projects *}
-      <a href="index.php">{$localize.projects}</a> / 
+      <a href="index.php">projects</a> / 
       {if $project && $validproject}
         <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$project}</a>
         {if $action && $validaction}
-           / {$localize.$action}
+           / {$action}
         {/if}
         {if $enablesearch}
           <form method="get" action="index.php" enctype="application/x-www-form-urlencoded">
@@ -37,18 +36,13 @@
               <input type="hidden" name="a" value="search" />
               <input type ="hidden" name="h" value="{if $currentsearchhash}{$currentsearchhash}{else}HEAD{/if}" />
               <select name="st">
-	        {* i18n: commit = commit *}
-                <option {if $currentsearchtype == 'commit'}selected="selected"{/if} value="commit">{$localize.commit}</option>
-                {* i18n: author = author *}
-                <option {if $currentsearchtype == 'author'}selected="selected"{/if} value="author">{$localize.author}</option>
-                {* i18n: committer = committer *}
-                <option {if $currentsearchtype == 'committer'}selected="selected"{/if} value="committer">{$localize.committer}</option>
+                <option {if $currentsearchtype == 'commit'}selected="selected"{/if} value="commit">commit</option>
+                <option {if $currentsearchtype == 'author'}selected="selected"{/if} value="author">author</option>
+                <option {if $currentsearchtype == 'committer'}selected="selected"{/if} value="committer">committer</option>
                 {if $filesearch}
-		  {* i18n: file = file *}
-                  <option {if $currentsearchtype == 'file'}selected="selected"{/if} value="file">{$localize.file}</option>
+                  <option {if $currentsearchtype == 'file'}selected="selected"{/if} value="file">file</option>
                 {/if}
-		{* i18n: search = search *}
-              </select> {$localize.search}: <input type="text" name="s" {if $currentsearch}value="{$currentsearch}"{/if} />
+              </select> search: <input type="text" name="s" {if $currentsearch}value="{$currentsearch}"{/if} />
             </div>
           </form>
         {/if}

--- a/templates/heads.tpl
+++ b/templates/heads.tpl
@@ -1,5 +1,5 @@
 {*
- *  heads.tpl
+ *  heads_nav.tpl
  *  gitphp: A PHP git repository browser
  *  Component: Head view template
  *
@@ -10,13 +10,7 @@
 
  {* Nav *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&hb={$head}">{$localize.tree}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&hb={$head}">tree</a>
    <br /><br />
  </div>
  <div>
@@ -26,12 +20,9 @@
    {* Loop and display each head *}
    {foreach from=$headlist item=head}
      <tr class="{cycle values="light,dark"}">
-       <td><i>{$head.age}</i></td>
+       <td><i>{$head.age_string}</i></td>
        <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$head.name}" class="list"><b>{$head.name}</b></a></td>
-       {* i18n: shortlog = shortlog *}
-       {* i18n: log = log *}
-       {* i18n: tree = tree *}
-       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$head.name}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$head.name}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$head.name}&hb={$head.name}">{$localize.tree}</a></td>
+       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$head.name}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$head.name}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$head.name}&hb={$head.name}">tree</a></td>
      </tr>
    {/foreach}
  </table>

--- a/templates/history.tpl
+++ b/templates/history.tpl
@@ -10,13 +10,7 @@
 
  {* Page header *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">{$localize.tree}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">tree</a>
    <br /><br />
  </div>
  <div>
@@ -46,11 +40,7 @@
        <td title="{$historylines[history].agestringage}"><i>{$historylines[history].agestringdate}</i></td>
        <td><i>{$historylines[history].authorname}</i></td>
        <td><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$historylines[history].commit}" class="list"><b>{$historylines[history].title}{if $historylines[history].commitref} <span class="tag">{$historylines[history].commitref}</span>{/if}</b></a></td>
-       {* i18n: difftocurrent = diff to current *}
-       {* i18n: blob = blob *}
-       {* i18n: commit = commit *}
-       {* i18n: commitdiff = commitdiff *}
-       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$historylines[history].commit}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$historylines[history].commit}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=blob&hb={$historylines[history].commit}&f={$historylines[history].file}">{$localize.blob}</a>{if $historylines[history].blob && $historylines[history].blobparent} | <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff&h={$historylines[history].blob}&hp={$historylines[history].blobparent}&hb={$historylines[history].commit}&f={$historylines[history].file}">{$localize.difftocurrent}</a>{/if}
+       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$historylines[history].commit}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$historylines[history].commit}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=blob&hb={$historylines[history].commit}&f={$historylines[history].file}">blob</a>{if $historylines[history].blob && $historylines[history].blobparent} | <a href="{$SCRIPT_NAME}?p={$project}&a=blobdiff&h={$historylines[history].blob}&hp={$historylines[history].blobparent}&hb={$historylines[history].commit}&f={$historylines[history].file}">diff to current</a>{/if}
        </td>
      </tr>
    {/section}

--- a/templates/log.tpl
+++ b/templates/log.tpl
@@ -10,33 +10,24 @@
 
  {* Nav *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">{$localize.shortlog}</a> | {$localize.log} | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$hash}&hb={$hash}">{$localize.tree}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">shortlog</a> | log | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$hash}&hb={$hash}">tree</a>
    <br />
-   {* i18n: HEAD = HEAD *}
    {if ($hash != $head) || $page}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.HEAD}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=log">HEAD</a>
    {else}
-     {$localize.HEAD}
+     HEAD
    {/if}
    &sdot; 
-   {* i18n: prev = prev *}
    {if $page > 0}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}&pg={$page-1}" accesskey="p" title="Alt-p">{$localize.prev}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}&pg={$page-1}" accesskey="p" title="Alt-p">prev</a>
    {else}
-     {$localize.prev}
+     prev
    {/if}
    &sdot; 
-   {* i18n: next = next *}
    {if $revlistcount > 100}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}&pg={$page+1}" accesskey="n" title="Alt-n">{$localize.next}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}&pg={$page+1}" accesskey="n" title="Alt-n">next</a>
    {else}
-     {$localize.next}
+     next
    {/if}
    <br />
  </div>
@@ -60,10 +51,7 @@
    </div>
    <div class="title_text">
      <div class="log_link">
-       {* i18n: tree = tree *}
-       {* i18n: commit = commit *}
-       {* i18n: commitdiff = commitdiff *}
-       <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[log].commit}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$commitlines[log].commit}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$commitlines[log].commit}&hb={$commitlines[log].commit}">{$localize.tree}</a>
+       <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[log].commit}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$commitlines[log].commit}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$commitlines[log].commit}&hb={$commitlines[log].commit}">tree</a>
        <br />
      </div>
      <i>{$commitlines[log].authorname} [{$commitlines[log].rfc2822}]</i><br />

--- a/templates/project.tpl
+++ b/templates/project.tpl
@@ -10,28 +10,18 @@
 
  {* Nav *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   {$localize.summary} | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree">{$localize.tree}</a>
+   summary | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree">tree</a>
    <br /><br />
  </div>
  <div class="title">&nbsp;</div>
  {* Project brief *}
  <table cellspacing="0">
-   {* i18n: description = description *}
-   {* i18n: owner = owner *}
-   {* i18n: lastchange = last change *}
-   <tr><td>{$localize.description}</td><td>{$description}</td></tr>
-   <tr><td>{$localize.owner}</td><td>{$owner}</td></tr>
-   <tr><td>{$localize.lastchange}</td><td>{$lastchange}</td></tr>
+   <tr><td>description</td><td>{$description}</td></tr>
+   <tr><td>owner</td><td>{$owner}</td></tr>
+   <tr><td>last change</td><td>{$lastchange}</td></tr>
  </table>
  <div>
-   {* i18n: shortlog = shortlog *}
-   <a class="title" href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a>
+   <a class="title" href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a>
  </div>
  <table cellspacing="0">
    {* Recent revisions *}
@@ -49,13 +39,9 @@
              {if $revlist[rev].commitref}
                <span class="tag">{$revlist[rev].commitref}</span>
              {/if}
-           </b></a>
+           </b>
          </td>
-	 {* i18n: snapshot = snapshot *}
-	 {* i18n: tree = tree *}
-	 {* i18n: commit = commit *}
-	 {* i18n: commitdiff = commitdiff *}
-         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$revlist[rev].commit}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$revlist[rev].commit}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$revlist[rev].commit}&hb={$revlist[rev].commit}">{$localize.tree}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$revlist[rev].commit}">{$localize.snapshot}</a></td>
+         <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$revlist[rev].commit}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$revlist[rev].commit}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$revlist[rev].commit}&hb={$revlist[rev].commit}">tree</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$revlist[rev].commit}">snapshot</a></td>
        </tr>
      {/if}
    {/section}
@@ -63,8 +49,7 @@
  {if $taglist}
    {* Tags *}
    <div>
-     {* i18n: tags = tags *}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=tags" class="title">{$localize.tags}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=tags" class="title">tags</a>
    </div>
    <table cellspacing="0">
      {section name=tag max=17 loop=$taglist}
@@ -72,7 +57,7 @@
          {if $smarty.section.tag.index == 16}
            <td><a href="{$SCRIPT_NAME}?p={$project}&a=tags">...</a></td>
          {else}
-           <td><i>{$taglist[tag].age}</i></td>
+           <td><i>{$taglist[tag].age_string}</i></td>
            <td><a href="{$SCRIPT_NAME}?p={$project}&a={$taglist[tag].reftype}&h={$taglist[tag].refid}" class="list"><b>{$taglist[tag].name}</b></a></td>
            <td>
              {if $taglist[tag].comment}
@@ -81,13 +66,9 @@
            </td>
            <td class="link">
              {if $taglist[tag].type == "tag"}
-	       {* i18n: tag = tag *}
-   	       <a href="{$SCRIPT_NAME}?p={$project}&a=tag&h={$taglist[tag].id}">{$localize.tag}</a> | 
+   	       <a href="{$SCRIPT_NAME}?p={$project}&a=tag&h={$taglist[tag].id}">tag</a> | 
              {/if}
-	     {* i18n: shortlog = shortlog *}
-	     {* i18n: log = log *}
-	     {* i18n: snapshot = snapshot *}
-             <a href="{$SCRIPT_NAME}?p={$project}&a={$taglist[tag].reftype}&h={$taglist[tag].refid}">{$taglist[tag].reftype_localized}</a>{if $taglist[tag].reftype == "commit"} | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/tags/{$taglist[tag].name}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/tags/{$taglist[tag].name}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$taglist[tag].refid}">{$localize.snapshot}</a>{/if}
+             <a href="{$SCRIPT_NAME}?p={$project}&a={$taglist[tag].reftype}&h={$taglist[tag].refid}">{$taglist[tag].reftype}</a>{if $taglist[tag].reftype == "commit"} | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/tags/{$taglist[tag].name}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/tags/{$taglist[tag].name}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$taglist[tag].refid}">snapshot</a>{/if}
            </td>
          {/if}
        </tr>
@@ -97,8 +78,7 @@
  {if $headlist}
    {* Heads *}
    <div>
-     {* i18n: heads = heads *}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=heads" class="title">{$localize.heads}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=heads" class="title">heads</a>
    </div>
    <table cellspacing="0">
      {section name=head max=17 loop=$headlist}
@@ -106,12 +86,9 @@
          {if $smarty.section.head.index == 16}
            <td><a href="{$SCRIPT_NAME}?p={$project}&a=heads">...</a></td>
          {else}
-           <td><i>{$headlist[head].age}</i></td>
+           <td><i>{$headlist[head].age_string}</i></td>
            <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$headlist[head].name}" class="list"><b>{$headlist[head].name}</b></td>
-	   {* i18n: shortlog = shortlog *}
-	   {* i18n: log = log *}
-	   {* i18n: tree = tree *}
-           <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$headlist[head].name}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$headlist[head].name}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$headlist[head].name}&hb={$headlist[head].name}">{$localize.tree}</a></td>
+           <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$headlist[head].name}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$headlist[head].name}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$headlist[head].name}&hb={$headlist[head].name}">tree</a></td>
          {/if}
        </tr>
      {/section}

--- /dev/null
+++ b/templates/projectindex.tpl
@@ -1,1 +1,19 @@
+{*
+ *  projectindex.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Project index template
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *}
+{if $categorized}
+{foreach from=$projlist item=plist}
+{foreach from=$plist item=proj}
+{$proj}
+{/foreach}
+{/foreach}
+{else}
+{foreach from=$projlist item=proj}
+{$proj}
+{/foreach}
+{/if}
 

--- a/templates/projectlist.tpl
+++ b/templates/projectlist.tpl
@@ -17,32 +17,27 @@
   <table cellspacing="0">
     {* Header *}
     <tr>
-      {* i18n: headerproject = Project *}
       {if $order == "project"}
-        <th>{$localize.headerproject}</th>
+        <th>Project</th>
       {else}
-        <th><a class="header" href="{$SCRIPT_NAME}?o=project">{$localize.headerproject}</a></th>
+        <th><a class="header" href="{$SCRIPT_NAME}?o=project">Project</a></th>
       {/if}
-      {* i18n: headerdescription = Description *}
       {if $order == "descr"}
-        <th>{$localize.headerdescription}</th>
+        <th>Description</th>
       {else}
-        <th><a class="header" href="{$SCRIPT_NAME}?o=descr">{$localize.headerdescription}</a></th>
+        <th><a class="header" href="{$SCRIPT_NAME}?o=descr">Description</a></th>
       {/if}
-      {* i18n: headerowner = Owner *}
       {if $order == "owner"}
-        <th>{$localize.headerowner}</th>
+        <th>Owner</th>
       {else}
-        <th><a class="header" href="{$SCRIPT_NAME}?o=owner">{$localize.headerowner}</a></th>
+        <th><a class="header" href="{$SCRIPT_NAME}?o=owner">Owner</a></th>
       {/if}
-      {* i18n: headerlastchange = Last Change *}
       {if $order == "age"}
-        <th>{$localize.headerlastchange}</th>
+        <th>Last Change</th>
       {else}
-        <th><a class="header" href="{$SCRIPT_NAME}?o=age">{$localize.headerlastchange}</a></th>
+        <th><a class="header" href="{$SCRIPT_NAME}?o=age">Last Change</a></th>
       {/if}
-      {* i18n: headeractions = Actions *}
-      <th>{$localize.headeractions}</th>
+      <th>Actions</th>
     </tr>
 
     {if $categorizedprojects}
@@ -74,12 +69,7 @@
                 <i>{$plist[proj].age_string}</i>
               {/if}
             </td>
-	    {* i18n: summary = summary *}
-	    {* i18n: shortlog = shortlog *}
-	    {* i18n: log = log *}
-	    {* i18n: snapshot = snapshot *}
-	    {* i18n: tree = tree *}
-            <td class="link"><a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=tree">{$localize.tree}</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=snapshot&h=HEAD">{$localize.snapshot}</a></td>
+            <td class="link"><a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=tree">tree</a> | <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=snapshot&h=HEAD">snapshot</a></td>
           </tr>
         {/section}
       {/foreach}
@@ -103,12 +93,7 @@
               <i>{$projects[proj].age_string}</i>
             {/if}
           </td>
-	  {* i18n: summary = summary *}
-	  {* i18n: shortlog = shortlog *}
-	  {* i18n: log = log *}
-	  {* i18n: snapshot = snapshot *}
-	  {* i18n: tree = tree *}
-          <td class="link"><a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=tree">{$localize.tree}</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=snapshot&h=HEAD">{$localize.snapshot}</a></td>
+          <td class="link"><a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=tree">tree</a> | <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=snapshot&h=HEAD">snapshot</a></td>
         </tr>
       {/section}
 

--- a/templates/search.tpl
+++ b/templates/search.tpl
@@ -10,33 +10,24 @@
 
 {* Nav *}
 <div class="page_nav">
-  {* i18n: summary = summary *}
-  {* i18n: shortlog = shortlog *}
-  {* i18n: log = log *}
-  {* i18n: commit = commit *}
-  {* i18n: commitdiff = commitdiff *}
-  {* i18n: tree = tree *}
-  <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$treehash}&hb={$hash}">{$localize.tree}</a>
+  <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$treehash}&hb={$hash}">tree</a>
   <br />
-  {* i18n: first = first *}
   {if $page > 0}
-    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}">{$localize.first}</a>
+    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}">first</a>
   {else}
-    {$localize.first}
+    first
   {/if}
     &sdot; 
-  {* i18n: prev = prev *}
   {if $page > 0}
-    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}{if $page > 1}&pg={$page-1}{/if}" accesskey="p" title="Alt-p">{$localize.prev}</a>
+    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}{if $page > 1}&pg={$page-1}{/if}" accesskey="p" title="Alt-p">prev</a>
   {else}
-    {$localize.prev}
+    prev
   {/if}
     &sdot; 
-  {* i18n: next = next *}
   {if $revlistcount > 100}
-    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" accesskey="n" title="Alt-n">{$localize.next}</a>
+    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" accesskey="n" title="Alt-n">next</a>
   {else}
-    {$localize.next}
+    next
   {/if}
   <br />
 </div>
@@ -49,24 +40,19 @@
     <tr class="{cycle values="light,dark"}">
       <td title="{$commitlines[match].agestringage}"><i>{$commitlines[match].agestringdate}</i></td>
       <td><i>{$commitlines[match].authorname}</i></td>
-      <td><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[match].commit}" class="list" {if $title}title="{$commitlines[match].title}"{/if}><b>{$commitlines[match].title_short}</b></a>
+      <td><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[match].commit}" class="list" {if $title}title="{$commitlines[match].title}"{/if}><b>{$commitlines[match].title_short}</b>
         {foreach from=$commitlines[match].matches item=line name=match}
           {if $smarty.foreach.match.first}<br />{/if}{$line}<br />
         {/foreach}
       </td>
-      {* i18n: snapshot = snapshot *}
-      {* i18n: tree = tree *}
-      {* i18n: commit = commit *}
-      {* i18n: commitdiff = commitdiff *}
-      <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[match].commit}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$commitlines[match].commit}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$commitlines[match].committree}&hb={$commitlines[match].commit}">{$localize.tree}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$commitlines[match].commit}">{$localize.snapshot}</a>
+      <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[match].commit}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$commitlines[match].commit}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$commitlines[match].committree}&hb={$commitlines[match].commit}">tree</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$commitlines[match].commit}">snapshot</a>
       </td>
     </tr>
   {/section}
 
   {if $revlistcount > 100}
     <tr>
-      {* i18n: next = next *}
-      <td><a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" title="Alt-n">{$localize.next}</a></td>
+      <td><a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" title="Alt-n">next</a></td>
     </tr>
   {/if}
 </table>

--- a/templates/searchfiles.tpl
+++ b/templates/searchfiles.tpl
@@ -10,33 +10,24 @@
 
 {* Nav *}
 <div class="page_nav">
-  {* i18n: summary = summary *}
-  {* i18n: shortlog = shortlog *}
-  {* i18n: log = log *}
-  {* i18n: commit = commit *}
-  {* i18n: commitdiff = commitdiff *}
-  {* i18n: tree = tree *}
-  <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$treehash}&hb={$hash}">{$localize.tree}</a>
+  <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$treehash}&hb={$hash}">tree</a>
   <br />
-  {* i18n: first = first *}
   {if $page > 0}
-    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}">{$localize.first}</a>
+    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}">first</a>
   {else}
-    {$localize.first}
+    first
   {/if}
     &sdot; 
-  {* i18n: prev = prev *}
   {if $page > 0}
-    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}{if $page > 1}&pg={$page-1}{/if}" accesskey="p" title="Alt-p">{$localize.prev}</a>
+    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}{if $page > 1}&pg={$page-1}{/if}" accesskey="p" title="Alt-p">prev</a>
   {else}
-    {$localize.prev}
+    prev
   {/if}
     &sdot; 
-  {* i18n: next = next *}
   {if $filesearchcount > 100}
-    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" accesskey="n" title="Alt-n">{$localize.next}</a>
+    <a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" accesskey="n" title="Alt-n">next</a>
   {else}
-    {$localize.next}
+    next
   {/if}
   <br />
 </div>
@@ -59,12 +50,9 @@
       </td>
       <td class="link">
         {if $filesearchlines[match].tree}
-	  {* i18n: tree = tree *}
-          <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$filesearchlines[match].hash}&hb={$hash}&f={$filesearchlines[match].file}">{$localize.tree}</a>
+          <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$filesearchlines[match].hash}&hb={$hash}&f={$filesearchlines[match].file}">tree</a>
         {else}
-	  {* i18n: blob = blob *}
-	  {* i18n: history = history *}
-          <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$filesearchlines[match].hash}&hb={$hash}&f={$filesearchlines[match].file}">{$localize.blob}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hash}&f={$filesearchlines[match].file}">{$localize.history}</a>
+          <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$filesearchlines[match].hash}&hb={$hash}&f={$filesearchlines[match].file}">blob</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hash}&f={$filesearchlines[match].file}">history</a>
         {/if}
       </td>
     </tr>
@@ -72,8 +60,7 @@
 
   {if $filesearchcount > 100}
     <tr>
-      {* i18n: next = next *}
-      <td><a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" title="Alt-n">{$localize.next}</a></td>
+      <td><a href="{$SCRIPT_NAME}?p={$project}&a=search&h={$hash}&s={$search}&st={$searchtype}&pg={$page+1}" title="Alt-n">next</a></td>
     </tr>
   {/if}
 </table>

--- a/templates/shortlog.tpl
+++ b/templates/shortlog.tpl
@@ -10,33 +10,24 @@
 
  {* Nav *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | {$localize.shortlog} | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$hash}&hb={$hash}">{$localize.tree}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | shortlog | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hash}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$hash}&hb={$hash}">tree</a>
    <br />
-   {* i18n: HEAD = HEAD *}
    {if ($hash != $head) || $page}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.HEAD}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">HEAD</a>
    {else}
-     {$localize.HEAD}
+     HEAD
    {/if}
      &sdot; 
-   {* i18n: prev = prev *}
    {if $page > 0}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}&pg={$page-1}" accesskey="p" title="Alt-p">{$localize.prev}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}&pg={$page-1}" accesskey="p" title="Alt-p">prev</a>
    {else}
-     {$localize.prev}
+     prev
    {/if}
      &sdot; 
-   {* i18n: next = next *}
    {if $revlistcount > 100}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}&pg={$page+1}" accesskey="n" title="Alt-n">{$localize.next}</a>
+     <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}&pg={$page+1}" accesskey="n" title="Alt-n">next</a>
    {else}
-     {$localize.next}
+     next
    {/if}
    <br />
  </div>
@@ -54,21 +45,16 @@
          {if $commitlines[log].commitref}
            <span class="tag">{$commitlines[log].commitref}</span>
          {/if}
-         </b></a>
+         </b>
        </td>
-       {* i18n: snapshot = snapshot *}
-       {* i18n: commit = commit *}
-       {* i18n: commitdiff = commitdiff *}
-       {* i18n: tree = tree *}
-       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[log].commit}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$commitlines[log].commit}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$commitlines[log].commit}&hb={$commitlines[log].commit}">{$localize.tree}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$commitlines[log].commit}">{$localize.snapshot}</a>
+       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$commitlines[log].commit}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$commitlines[log].commit}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$commitlines[log].commit}&hb={$commitlines[log].commit}">tree</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$commitlines[log].commit}">snapshot</a>
        </td>
      </tr>
    {/section}
 
    {if $revlistcount > 100}
      <tr>
-       {* i18n: next = next *}
-       <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}&pg={$page+1}" title="Alt-n">{$localize.next}</a></td>
+       <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}&pg={$page+1}" title="Alt-n">next</a></td>
      </tr>
    {/if}
  </table>

--- /dev/null
+++ b/templates/snapshot.tpl
@@ -1,1 +1,9 @@
+{*
+ *  snapshots.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Snapshot template
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *}
+{$archive}
 

--- a/templates/tag.tpl
+++ b/templates/tag.tpl
@@ -10,13 +10,7 @@
 
  {* Nav *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&hb={$head}">{$localize.tree}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&hb={$head}">tree</a>
    <br /><br />
  </div>
  {* Tag data *}
@@ -26,15 +20,13 @@
  <div class="title_text">
    <table cellspacing="0">
      <tr>
-       {* i18n: object = object *}
-       <td>{$localize.object}</td>
+       <td>object</td>
        <td class="monospace"><a href="{$SCRIPT_NAME}?p={$project}&a={$tag.type}&h={$tag.object}" class="list">{$tag.object}</a></td>
-       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a={$tag.type}&h={$tag.object}">{$tag.type_localized}</a></td>
+       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a={$tag.type}&h={$tag.object}">{$tag.type}</a></td>
      </tr>
      {if $tag.author}
        <tr>
-         {* i18n: author = author *}
-         <td>{$localize.author}</td>
+         <td>author</td>
 	 <td>{$tag.author}</td>
        </tr>
        <tr>

--- a/templates/tags.tpl
+++ b/templates/tags.tpl
@@ -10,13 +10,7 @@
 
  {* Nav *}
  <div class="page_nav">
-   {* i18n: summary = summary *}
-   {* i18n: shortlog = shortlog *}
-   {* i18n: log = log *}
-   {* i18n: commit = commit *}
-   {* i18n: commitdiff = commitdiff *}
-   {* i18n: tree = tree *}
-   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">{$localize.commitdiff}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&hb={$head}">{$localize.tree}</a>
+   <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$head}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$head}">commitdiff</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&hb={$head}">tree</a>
    <br /><br />
  </div>
  <div>
@@ -26,7 +20,7 @@
  <table cellspacing="0">
    {section name=tag loop=$taglist}
      <tr class="{cycle values="light,dark"}">
-       <td><i>{$taglist[tag].age}</i></td>
+       <td><i>{$taglist[tag].age_string}</i></td>
        <td><a href="{$SCRIPT_NAME}?p={$project}&a={$taglist[tag].reftype}&h={$taglist[tag].refid}" class="list"><b>{$taglist[tag].name}</b></a></td>
        <td>
          {if count($taglist[tag].comment) > 0}
@@ -35,15 +29,11 @@
        </td>
        <td class="link">
          {if $taglist[tag].type == "tag"}
-	   {* i18n: tag = tag *}
-	   <a href="{$SCRIPT_NAME}?p={$project}&a=tag&h={$taglist[tag].id}">{$localize.tag}</a> | 
+	   <a href="{$SCRIPT_NAME}?p={$project}&a=tag&h={$taglist[tag].id}">tag</a> | 
 	 {/if}
-	 <a href="{$SCRIPT_NAME}?p={$project}&a={$taglist[tag].reftype}&h={$taglist[tag].refid}">{$taglist[tag].reftype_localized}</a>
+	 <a href="{$SCRIPT_NAME}?p={$project}&a={$taglist[tag].reftype}&h={$taglist[tag].refid}">{$taglist[tag].reftype}</a>
 	 {if $taglist[tag].reftype == "commit"}
-	   {* i18n: shortlog = shortlog *}
-	   {* i18n: log = log *}
-	   {* i18n: snapshot = snapshot *}
-	   | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/tags/{$taglist[tag].name}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/tags/{$taglist[tag].name}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$taglist[tag].refid}">{$localize.snapshot}</a>
+	   | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/tags/{$taglist[tag].name}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/tags/{$taglist[tag].name}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h={$taglist[tag].refid}">snapshot</a>
 	 {/if}
        </td>
      </tr>

--- a/templates/tree.tpl
+++ b/templates/tree.tpl
@@ -11,13 +11,7 @@
  {* Nav *}
  {if $fullnav}
    <div class="page_nav">
-     {* i18n: summary = summary *}
-     {* i18n: shortlog = shortlog *}
-     {* i18n: log = log *}
-     {* i18n: commit = commit *}
-     {* i18n: commitdiff = commitdiff *}
-     {* i18n: tree = tree *}
-     <a href="{$SCRIPT_NAME}?p={$project}&a=summary">{$localize.summary}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hashbase}">{$localize.shortlog}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hashbase}">{$localize.log}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hashbase}">{$localize.commit}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hashbase}">{$localize.commitdiff}</a> | {$localize.tree}<br /><br />
+     <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hashbase}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hashbase}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hashbase}">commit</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff&h={$hashbase}">commitdiff</a> | tree<br /><br />
    </div>
    <div>
      <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hashbase}" class="title">{$title}
@@ -50,17 +44,14 @@
              <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$treelines[tree].hash}{if $hashbase}&hb={$hashbase}{/if}&f={if $base}{$base}{/if}{$treelines[tree].name}" class="list">{$treelines[tree].name}</a>
 	   </td>
            <td class="link">
-	     {* i18n: blob = blob *}
-	     {* i18n: history = history *}
-	     <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$treelines[tree].hash}{if $hashbase}&hb={$hashbase}{/if}&f={if $base}{$base}{/if}{$treelines[tree].name}">{$localize.blob}</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hashbase}&f={if $base}{$base}{/if}{$treelines[tree].name}">{$localize.history}</a>
+	     <a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$treelines[tree].hash}{if $hashbase}&hb={$hashbase}{/if}&f={if $base}{$base}{/if}{$treelines[tree].name}">blob</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=history&h={$hashbase}&f={if $base}{$base}{/if}{$treelines[tree].name}">history</a>
 	   </td>
          {elseif $treelines[tree].type == "tree"}
            <td class="list">
              <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$treelines[tree].hash}{if $hashbase}&hb={$hashbase}{/if}&f={if $base}{$base}{/if}{$treelines[tree].name}">{$treelines[tree].name}</a>
 	   </td>
            <td class="link">
-	     {* i18n: tree = tree *}
-	     <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$treelines[tree].hash}{if $hashbase}&hb={$hashbase}{/if}&f={if $base}{$base}{/if}{$treelines[tree].name}">{$localize.tree}</a>
+	     <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$treelines[tree].hash}{if $hashbase}&hb={$hashbase}{/if}&f={if $base}{$base}{/if}{$treelines[tree].name}">tree</a>
 	   </td>
          {/if}
        </tr>

comments