git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 3/3] gitweb: Optional grouping of projects by category

From
Jakub Narebski <jnareb@gmail.com>
Date
Dec 5, 2008, 02:08 UTC
Message-ID
<200812050308.52891.jnareb@gmail.com>
In-Reply-To
<87hc5k22dr.wl%seb@cine7.net>
On Thu, 4 Dec 2008, Sébastien Cevey wrote:
Show 18 quoted lines
> This adds the $projects_list_group_categories option which, if enabled,
> will result in grouping projects by category on the project list page.
> The category is specified for each project by the $GIT_DIR/category file
> or the 'category' variable in its configuration file. By default, projects
> are put in the $project_list_default_category category.
> 
> Note:
> - Categories are always sorted alphabetically, with projects in
>   each category sorted according to the globally selected $order.
> - When displaying a subset of all the projects (page limiting), the
>   category headers are only displayed for projects present on the page.
> 
> The feature is inspired from Sham Chukoury's patch for the XMMS2
> gitweb, but has been rewritten for the current gitweb development
> HEAD. The CSS for categories is inspired from Gustavo Sverzut Barbieri's
> patch to group projects by path.
> 
> Thanks to Florian Ragwitz for Perl tips.
Very nice, and nicely done and thought out, idea.
Show 32 quoted lines
> 
> Signed-off-by: Sebastien Cevey <seb@cine7.net>
> ---
> 
> Cleaner patch this time indeed.  Still no fancy sorting of categories,
> only alphabetical.
> 
>  gitweb/README      |   16 ++++++++++++
>  gitweb/gitweb.css  |    7 +++++
>  gitweb/gitweb.perl |   67 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 87 insertions(+), 3 deletions(-)
> 
> diff --git a/gitweb/README b/gitweb/README
> index 825162a..f8f8872 100644
> --- a/gitweb/README
> +++ b/gitweb/README
> @@ -188,6 +188,15 @@ not include variables usually directly set during build):
>     full description is available as 'title' attribute (usually shown on
>     mouseover).  By default set to 25, which might be too small if you
>     use long project descriptions.
> + * $projects_list_group_categories
> +   Enables the grouping of projects by category on the project list page.
> +   The category of a project is determined by the $GIT_DIR/category
> +   file or the 'gitweb.category' variable in its repository configuration.
> +   Disabled by default.
> + * $project_list_default_category
> +   Default category for projects for which none is specified.  If set
> +   to the empty string, such projects will remain uncategorized and
> +   listed at the top, above categorized projects.
>   * @git_base_url_list
>     List of git base URLs used for URL to where fetch project from, shown
>     in project summary page.  Full URL is "$git_base_url/$project".
Good.
Show 14 quoted lines
> @@ -269,6 +278,13 @@ You can use the following files in repository:
>     from the template during repository creation. You can use the
>     gitweb.description repo configuration variable, but the file takes
>     precedence.
> + * category (or gitweb.category)
> +   Singe line category of a project, used to group projects if
> +   $projects_list_group_categories is enabled. By default (file and
> +   configuration variable absent), uncategorized projects are put in
> +   the $project_list_default_category category. You can use the
> +   gitweb.category repo configuration variable, but the file takes
> +   precedence.
>   * cloneurl (or multiple-valued gitweb.url)
>     File with repository URL (used for clone and fetch), one per line.
>     Displayed in the project summary page. You can use multiple-valued
Good.
Show 37 quoted lines
> diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
> index a01eac8..64f2a41 100644
> --- a/gitweb/gitweb.css
> +++ b/gitweb/gitweb.css
> @@ -264,6 +264,13 @@ td.current_head {
>  	text-decoration: underline;
>  }
>  
> +td.category {
> +	background-color: #d9d8d1;
> +	border-top: 1px solid #000000;
> +	border-left: 1px solid #000000;
> +	font-weight: bold;
> +}
> +
>  table.diff_tree span.file_status.new {
>  	color: #008000;
>  }
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index a6bb702..97a9b73 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -87,6 +87,14 @@ our $projects_list = "++GITWEB_LIST++";
>  # the width (in characters) of the projects list "Description" column
>  our $projects_list_description_width = 25;
>  
> +# group projects by category on the projects list
> +# (enabled if this variable evaluates to true)
> +our $projects_list_group_categories = 0;
> +
> +# default category if none specified
> +# (leave the empty string for no category)
> +our $project_list_default_category = "";
> +
>  # default order of projects list
>  # valid values are none, project, descr, owner, and age
>  our $default_projects_order = "project";
Nice.
Show 9 quoted lines
> @@ -2023,6 +2031,11 @@ sub git_get_project_description {
>  	return git_get_file_or_project_config('description', $path);
>  }
>  
> +sub git_get_project_category {
> +	my $path = shift;
> +	return git_get_file_or_project_config('category', $path);
> +}
> +
Good. Nicely uses earlier patch, which adds this infrastructure.
Show 27 quoted lines
>  sub git_get_project_ctags {
>  	my $path = shift;
>  	my $ctags = {};
> @@ -3915,8 +3928,9 @@ sub git_patchset_body {
>  
>  # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
>  
> -# fills project list info (age, description, owner, forks) for each
> -# project in the list, removing invalid projects from returned list
> +# fills project list info (age, description, owner, category, forks)
> +# for each project in the list, removing invalid projects from
> +# returned list
>  # NOTE: modifies $projlist, but does not remove entries from it
>  sub fill_project_list_info {
>  	my ($projlist, $check_forks) = @_;
> @@ -3939,6 +3953,11 @@ sub fill_project_list_info {
>  		if (!defined $pr->{'owner'}) {
>  			$pr->{'owner'} = git_get_project_owner("$pr->{'path'}") || "";
>  		}
> +		if ($projects_list_group_categories && !defined $pr->{'category'}) {
> +			my $cat = git_get_project_category($pr->{'path'}) ||
> +			                                   $project_list_default_category;
> +			$pr->{'category'} = to_utf8($cat);
> +		}
>  		if ($check_forks) {
>  			my $pname = $pr->{'path'};
>  			if (($pname =~ s/\.git$//) &&

Nice. I see that you choose to go with $pr->{'category'} like existing $pr->{'owner'}, rather than $pr->{'cat'} like existing $pr->{'descr'}.

Show 16 quoted lines
> @@ -3956,6 +3975,19 @@ sub fill_project_list_info {
>  	return @projects;
>  }
>  
> +# returns a hash of categories, containing the list of project
> +# belonging to each category
> +sub build_projlist_by_category {
> +	my $projlist = shift;
> +	my %categories;
> +
> +	for my $pr (@$projlist) {
> +		push @{$categories{ $pr->{'category'} }}, $pr;
> +	}
> +
> +	return %categories;
> +}

This is very nice and simple way to group by categories, and it works quite well with sorting (assuming that @$projlist is already sorted), but I wonder how it works with $from / $to, i.e. with selecting projects.

Show 12 quoted lines
> +
>  # print 'sort by' <th> element, generating 'sort by $name' replay link
>  # if that order is not selected
>  sub print_sort_th {
> @@ -4077,7 +4109,36 @@ sub git_project_list_body {
>  		      "</tr>\n";
>  	}
>  
> -	print_project_rows(\@projects, $from, $to, $check_forks, $show_ctags);
> +	if ($projects_list_group_categories) {
> +		# only display categories with projects in the $from-$to window
> +		my %categories = build_projlist_by_category(\@projects);

Nice... but perhaps it would be better to simply pass $from / $to to build_projlist_by_category function, and have in %categories only projects which are shown... well, unless filtered out in print_project_rows() by $show_ctags; so I think that there is nonzero probability of empty (no project shown) categories.

Show 23 quoted lines
> +		foreach my $cat (sort keys %categories) {
> +			my $num_cats = @{$categories{$cat}};
> +
> +			# out of the window to display, done
> +			last if defined $to and $to < 0;
> +
> +			# in the window to display
> +			if (!defined $from or $from < $num_cats) {
> +				unless ($cat eq "") {
> +					print "<tr>\n";
> +					if ($check_forks) {
> +						print "<td></td>\n";
> +					}
> +					print "<td class=\"category\" colspan=\"5\">$cat</td>\n";
> +					print "</tr>\n";
> +				}
> +
> +				print_project_rows($categories{$cat}, $from, $to, $check_forks, $show_ctags);
> +			}
> +
> +			# adjust $from/$to offset, keep $from positive
> +			$from = ($from > $num_cats) ? $from - $num_cats : 0 if defined $from;
> +			$to -= $num_cats if defined $to;

I don't think that the games we play with $from / $to would be enough. Check what happens (I think that it wouldn't work correctly) if we have something like that:

 project | category | shown
 --------------------------
  1      | A        |
  2      | A        |
  3      | B        | Y
  4      | C        | Y
  5      | B        | Y
  6      | C        |
  7      | C        |
It means that we display for example second page in projects list.
> +		}
> +	} else {
> +		print_project_rows(\@projects, $from, $to, $check_forks, $show_ctags);
> +	}
Nice.
Show 7 quoted lines
>  
>  	if (defined $extra) {
>  		print "<tr>\n";
> -- 
> 1.5.6.5
> 
> 

I'll try to examine the code in more detail later... currently I don't know why but I can't git-am the second patch (this patch) correctly...

-- 
Jakub Narębski
Poland
Previous: Junio C HamanoNext: Sébastien Cevey
Message 12 of 24 in “gitweb: Optional grouping of projects by category”
  1. gitweb: Optional grouping of projects by categorySebastien Cevey, Dec 2, 2008
  2. Jakub NarebskiDec 2, 2008
  3. gitweb: Optional grouping of projects by categorySébastien Cevey, Dec 3, 2008
  4. Junio C HamanoDec 3, 2008
  5. Jakub NarebskiDec 3, 2008
  6. 0/3 gitweb: Optional grouping of projects by categorySébastien Cevey, Dec 4, 2008
  7. Junio C HamanoDec 4, 2008
  8. 1/3 gitweb: Modularized git_get_project_description to be more genericSébastien Cevey, Dec 4, 2008
  9. 2/3 gitweb: Split git_project_list_body in two functionsSébastien Cevey, Dec 4, 2008
  10. 3/3 gitweb: Optional grouping of projects by categorySébastien Cevey, Dec 4, 2008
  11. Junio C HamanoDec 4, 2008
  12. Jakub NarebskiDec 5, 2008
  13. Sébastien CeveyDec 5, 2008
  14. Jakub NarebskiDec 5, 2008
  15. Sébastien CeveyDec 11, 2008
  16. Jakub NarebskiDec 12, 2008
  17. Sébastien CeveyDec 12, 2008
  18. Jakub NarebskiDec 12, 2008
  19. Sébastien CeveyDec 12, 2008
  20. Jakub NarebskiDec 12, 2008
  21. Jakub NarebskiDec 5, 2008
  22. Jakub NarebskiDec 5, 2008
  23. Sébastien CeveyDec 3, 2008
  24. Junio C HamanoDec 3, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.