Unify project list template
Unify project list template

file:a/gitphp.css -> file:b/gitphp.css
--- a/gitphp.css
+++ b/gitphp.css
@@ -105,4 +105,7 @@
 div.error {
 	color: #ff0000;
 }
+.indent {
+	margin-left: 8px;
+}
 

--- a/include/display.git_project_list.php
+++ b/include/display.git_project_list.php
@@ -11,19 +11,17 @@
  require_once('util.descrcmp.php');
  require_once('util.ownercmp.php');
  require_once('util.agecmp.php');
- require_once('display.git_project_listentry.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);
+	$projects = git_read_projects($projectroot,$projectlist, TRUE);
 	if (is_array($projects)) {
 		if (count($projects) > 0) {
 			$tpl->clear_all_assign();
 			if ($order)
 				$tpl->assign("order",$order);
-			$tpl->display("projlist_header.tpl");
 			if (!isset($git_projects)) {
 				switch ($order) {
 					case "project":
@@ -39,46 +37,31 @@
 						usort($projects,"agecmp");
 						break;
 				}
-			}
-			$alternate = false;
-			foreach ($projects as $cat => $plist) {
-				if (is_array($plist)) {
-					if ($cat != "none") {
-						$tpl->clear_all_assign();
-						$tpl->assign("category",$cat);
-						$tpl->display("projlist_category.tpl");
+			} else {
+				$tpl->assign("categorized",TRUE);
+				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;
 					}
-					if (isset($git_projects)) {
-						switch ($order) {
-							case "project":
-								usort($plist,"projectcmp");
-								break;
-							case "descr":
-								usort($plist,"descrcmp");
-								break;
-							case "owner":
-								usort($plist,"ownercmp");
-								break;
-							case "age":
-								usort($plist,"agecmp");
-								break;
-						}
-					}
-					foreach ($plist as $i => $proj) {
-						git_project_listentry($projectroot,$proj,($alternate?"dark":"light"),($cat=="none"?FALSE:TRUE));
-						$alternate = !$alternate;
-					}
-				} else {
-					git_project_listentry($projectroot,$plist,($alternate?"dark":"light"),FALSE);
-					$alternate = !$alternate;
 				}
 			}
-			$tpl->clear_all_assign();
-			$tpl->display("projlist_footer.tpl");
+			$tpl->assign("projects",$projects);
 		} else
-			echo "No projects found";
+			$tpl->assign("errmsg","No projects found");
 	} else
-		echo $projects;
+		$tpl->assign("errmsg",$projects);
+	$tpl->display("projlist.tpl");
 }
 
 ?>

--- a/include/display.git_project_listentry.php
+++ /dev/null
@@ -1,36 +1,1 @@
-<?php
-/*
- *  display.git_project_listentry.php
- *  gitphp: A PHP git repository browser
- *  Component: Display - single project list item
- *
- *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
- */
 
- require_once('gitutil.git_project_descr.php');
- require_once('gitutil.git_project_owner.php');
- require_once('gitutil.git_read_head.php');
- require_once('gitutil.git_read_commit.php');
-
-function git_project_listentry($projectroot,$project,$class,$indent)
-{
-	global $tpl;
-	$tpl->clear_all_assign();
-	$tpl->assign("class",$class);
-	$tpl->assign("project",$project);
-	$tpl->assign("descr",git_project_descr($projectroot,$project,TRUE));
-	$tpl->assign("owner",git_project_owner($projectroot,$project));
-	if ($indent)
-		$tpl->assign("idt",TRUE);
-	$head = git_read_head($projectroot . $project);
-	$commit = git_read_commit($projectroot . $project,$head);
-	if ($commit['age'] < 60*60*24*2)
-		$tpl->assign("age_colored",TRUE);
-	if ($commit['age'] < 60*60*2)
-		$tpl->assign("age_bold",TRUE);
-	$tpl->assign("age_string",$commit['age_string']);
-	$tpl->display("projlist_item.tpl");
-}
-
-?>
-

--- /dev/null
+++ b/include/gitutil.git_project_info.php
@@ -1,1 +1,29 @@
+<?php
+/*
+ *  gitutil.git_project_info.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Git utility - single project info
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+ require_once('gitutil.git_project_descr.php');
+ require_once('gitutil.git_project_owner.php');
+ require_once('gitutil.git_read_head.php');
+ require_once('gitutil.git_read_commit.php');
+
+function git_project_info($projectroot,$project)
+{
+	$projinfo = array();
+	$projinfo["project"] = $project;
+	$projinfo["descr"] = git_project_descr($projectroot,$project,TRUE);
+	$projinfo["owner"] = git_project_owner($projectroot,$project);
+	$head = git_read_head($projectroot . $project);
+	$commit = git_read_commit($projectroot . $project,$head);
+	$projinfo["age"] = $commit['age'];
+	$projinfo["age_string"] = $commit['age_string'];
+	return $projinfo;
+}
+
+?>
+

--- a/include/gitutil.git_read_projects.php
+++ b/include/gitutil.git_read_projects.php
@@ -8,8 +8,9 @@
  */
 
  require_once('gitutil.git_recurse_projects.php');
+ require_once('gitutil.git_project_info.php');
 
-function git_read_projects($projectroot,$projectlist)
+function git_read_projects($projectroot,$projectlist,$projdata = FALSE)
 {
 	$projects = array();
 	if (isset($projectroot)) {
@@ -19,8 +20,12 @@
 					if (is_array($plist)) {
 						$projs = array();
 						foreach ($plist as $pname => $ppath) {
-							if (is_dir($projectroot . $ppath) && is_file($projectroot . $ppath . "/HEAD"))
-								$projs[] = $ppath;
+							if (is_dir($projectroot . $ppath) && is_file($projectroot . $ppath . "/HEAD")) {
+								if ($projdata)
+									$projs[] = git_project_info($projectroot, $ppath);
+								else
+									$projs[] = $ppath;
+							}
 						}
 						if (count($projs) > 0) {
 							sort($projs);
@@ -33,7 +38,11 @@
 				$len = count($projects);
 				$cut = strlen($projectroot);
 				for ($i = 0; $i < $len; $i++) {
-					$projects[$i] = substr($projects[$i],$cut + 1);
+					$p = substr($projects[$i],$cut + 1);
+					if ($projdata)
+						$projects[$i] = git_project_info($projectroot, $p);
+					else
+						$projects[$i] = $p;
 				}
 			}
 		} else

--- a/include/util.agecmp.php
+++ b/include/util.agecmp.php
@@ -7,17 +7,11 @@
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
 
- require_once('gitutil.git_read_commit.php');
- require_once('gitutil.git_read_head.php');
-
 function agecmp($a,$b)
 {
-	global $gitphp_conf;
-	$ca = git_read_commit($gitphp_conf['projectroot'] . $a, git_read_head($gitphp_conf['projectroot'] . $a));
-	$cb = git_read_commit($gitphp_conf['projectroot'] . $b, git_read_head($gitphp_conf['projectroot'] . $b));
-	if ($ca['age'] == $cb['age'])
+	if ($a["age"] == $b["age"])
 		return 0;
-	return ($ca['age'] < $cb['age'] ? -1 : 1);
+	return ($a["age"] < $b["age"] ? -1 : 1);
 }
 
 ?>

--- a/include/util.descrcmp.php
+++ b/include/util.descrcmp.php
@@ -7,12 +7,9 @@
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
 
- require_once('gitutil.git_project_descr.php');
-
 function descrcmp($a,$b)
 {
-	global $gitphp_conf;
-	return strcmp(git_project_descr($gitphp_conf['projectroot'],$a),git_project_descr($gitphp_conf['projectroot'],$b));
+	return strcmp($a["descr"],$b["descr"]);
 }
 
 ?>

--- a/include/util.ownercmp.php
+++ b/include/util.ownercmp.php
@@ -7,12 +7,9 @@
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
 
- require_once('gitutil.git_project_owner.php');
-
 function ownercmp($a,$b)
 {
-	global $gitphp_conf;
-	return strcmp(git_project_owner($gitphp_conf['projectroot'],$a),git_project_owner($gitphp_conf['projectroot'],$b));
+	return strcmp($a["owner"],$b["owner"]);
 }
 
 ?>

--- a/include/util.projectcmp.php
+++ b/include/util.projectcmp.php
@@ -9,7 +9,7 @@
 
 function projectcmp($a,$b)
 {
-	return strcmp($a,$b);
+	return strcmp($a["project"],$b["project"]);
 }
 
 ?>

--- /dev/null
+++ b/templates/projlist.tpl
@@ -1,1 +1,99 @@
+{*
+ *  projlist.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Project list template
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *}
+{if $errmsg}
+  {* Something is wrong; display an error message instead of trying to list *}
+  {$errmsg}
+{else}
+  <table cellspacing="0">
+    {* Header *}
+    <tr>
+      {if $order == "project"}
+        <th>Project</th>
+      {else}
+        <th><a class="header" href="{$SCRIPT_NAME}?o=project">Project</a></th>
+      {/if}
+      {if $order == "descr"}
+        <th>Description</th>
+      {else}
+        <th><a class="header" href="{$SCRIPT_NAME}?o=descr">Description</a></th>
+      {/if}
+      {if $order == "owner"}
+        <th>Owner</th>
+      {else}
+        <th><a class="header" href="{$SCRIPT_NAME}?o=owner">Owner</a></th>
+      {/if}
+      {if $order == "age"}
+        <th>Last Change</th>
+      {else}
+        <th><a class="header" href="{$SCRIPT_NAME}?o=age">Last Change</a></th>
+      {/if}
+      <th>Actions</th>
+    </tr>
 
+    {if $categorized}
+      {* Show categorized; categorized project lists nested associatively in the project
+         list by category key *}
+      {foreach from=$projects key=categ item=plist}
+        {if $categ != "none"}
+          <tr>
+            <th>{$categ}</th>
+            <th></th>
+            <th></th>
+            <th></th>
+            <th></th>
+          </tr>
+	{/if}
+        {section name=proj loop=$plist}
+          <tr class="{cycle values="light,dark"}">
+            <td>
+              <a href="{$SCRIPT_NAME}?p={$plist[proj].project}&a=summary" class="list {if $categ != "none"}indent{/if}">{$plist[proj].project}</a>
+            </td>
+            <td>{$plist[proj].descr}</td>
+            <td><i>{$plist[proj].owner}</i></td>
+            <td>
+              {if $plist[proj].age < 7200}   {* 60*60*2, or 2 hours *}
+                <span class="agehighlight"><b><i>{$plist[proj].age_string}</i></b></span>
+	      {elseif $plist[proj].age < 172800}   {* 60*60*24*2, or 2 days *}
+                <span class="agehighlight"><i>{$plist[proj].age_string}</i></span>
+              {else}
+                <i>{$plist[proj].age_string}</i>
+              {/if}
+            </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}
+
+    {else}
+      
+      {* Show flat uncategorized project array *}
+      {section name=proj loop=$projects}
+        <tr class="{cycle values="light,dark"}">
+          <td>
+            <a href="{$SCRIPT_NAME}?p={$projects[proj].project}&a=summary" class="list">{$projects[proj].project}</a>
+          </td>
+          <td>{$projects[proj].descr}</td>
+          <td><i>{$projects[proj].owner}</i></td>
+          <td>
+            {if $projects[proj].age < 7200}   {* 60*60*2, or 2 hours *}
+              <span class="agehighlight"><b><i>{$projects[proj].age_string}</i></b></span>
+	    {elseif $projects[proj].age < 172800}   {* 60*60*24*2, or 2 days *}
+              <span class="agehighlight"><i>{$projects[proj].age_string}</i></span>
+	    {else}
+              <i>{$projects[proj].age_string}</i>
+            {/if}
+          </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}
+
+    {/if}
+
+  </table>
+{/if}
+

--- a/templates/projlist_category.tpl
+++ /dev/null
@@ -1,15 +1,1 @@
-{*
- *  projlist_category.tpl
- *  gitphp: A PHP git repository browser
- *  Component: Project list category template
- *
- *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
- *}
-<tr>
-<th>{$category}</th>
-<th></th>
-<th></th>
-<th></th>
-<th></th>
-</tr>
 

--- a/templates/projlist_footer.tpl
+++ /dev/null
@@ -1,9 +1,1 @@
-{*
- *  projlist_footer.tpl
- *  gitphp: A PHP git repository browser
- *  Component: Project list footer template
- *
- *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
- *}
-</table>
 

--- a/templates/projlist_header.tpl
+++ /dev/null
@@ -1,32 +1,1 @@
-{*
- *  projlist_header.tpl
- *  gitphp: A PHP git repository browser
- *  Component: Project list header template
- *
- *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
- *}
-<table cellspacing="0">
-<tr>
-{if $order == "project"}
-<th>Project</th>
-{else}
-<th><a class="header" href="{$SCRIPT_NAME}?o=project">Project</a></th>
-{/if}
-{if $order == "descr"}
-<th>Description</th>
-{else}
-<th><a class="header" href="{$SCRIPT_NAME}?o=descr">Description</a></th>
-{/if}
-{if $order == "owner"}
-<th>Owner</th>
-{else}
-<th><a class="header" href="{$SCRIPT_NAME}?o=owner">Owner</a></th>
-{/if}
-{if $order == "age"}
-<th>Last Change</th>
-{else}
-<th><a class="header" href="{$SCRIPT_NAME}?o=age">Last Change</a></th>
-{/if}
-<th>Actions</th>
-</tr>
 

--- a/templates/projlist_item.tpl
+++ /dev/null
@@ -1,33 +1,1 @@
-{*
- *  projlist_item.tpl
- *  gitphp: A PHP git repository browser
- *  Component: Project list item template
- *
- *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
- *}
-<tr class="{$class}">
-<td>
-{if $idt}<span class="respectwhitespace">  {/if}<a href="{$SCRIPT_NAME}?p={$project}&a=summary" class="list">{$project}</a>{if $idt}</span>{/if}
-</td>
-<td>{$descr}</td>
-<td><i>{$owner}</i></td>
-<td>
-{if $age_colored}
-<span class="agehighlight">
-{/if}
-{if $age_bold}
-<b>
-{/if}
-<i>
-{$age_string}
-</i>
-{if $age_bold}
-</b>
-{/if}
-{if $age_colored}
-</span>
-{/if}
-</td>
-<td class="link"><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=tree">tree</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=snapshot&h=HEAD">snapshot</a></td>
-</tr>
 

comments