@matheusbsbs / matheus-bagliano / commits / d940c9015d
Fork 0

gitweb: Optional grouping of projects by category

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 'gitweb.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 code. The CSS for categories is inspired from Gustavo Sverzut Barbieri's patch to group projects by path. Thanks to Florian Ragwitz for Perl tips. [jn: Updated to post restructuring projects list generation, fixed bugs, added very basic test in t9500 that there are no warnings from Perl.] Signed-off-by: Sebastien Cevey <seb@cine7.net> Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Sebastien Cevey committed Apr 29, 2011 at 19:52 UTC d940c9015d1a770b4f8ed8e9b38cf3d16f47a6cd
4 files changed +90 -3
gitweb/README
+16
@@ -207,6 +207,15 @@ not include variables usually directly set during build):
207 full description is available as 'title' attribute (usually shown on
208 mouseover). By default set to 25, which might be too small if you
209 use long project descriptions.
210 + * $projects_list_group_categories
211 + Enables the grouping of projects by category on the project list page.
212 + The category of a project is determined by the $GIT_DIR/category
213 + file or the 'gitweb.category' variable in its repository configuration.
214 + Disabled by default.
215 + * $project_list_default_category
216 + Default category for projects for which none is specified. If set
217 + to the empty string, such projects will remain uncategorized and
218 + listed at the top, above categorized projects.
219 * @git_base_url_list
220 List of git base URLs used for URL to where fetch project from, shown
221 in project summary page. Full URL is "$git_base_url/$project".
@@ -314,6 +323,13 @@ You can use the following files in repository:
323 from the template during repository creation. You can use the
324 gitweb.description repo configuration variable, but the file takes
325 precedence.
326 + * category (or gitweb.category)
327 + Singe line category of a project, used to group projects if
328 + $projects_list_group_categories is enabled. By default (file and
329 + configuration variable absent), uncategorized projects are put in
330 + the $project_list_default_category category. You can use the
331 + gitweb.category repo configuration variable, but the file takes
332 + precedence.
333 * cloneurl (or multiple-valued gitweb.url)
334 File with repository URL (used for clone and fetch), one per line.
335 Displayed in the project summary page. You can use multiple-valued
gitweb/gitweb.perl
+59 -3
@@ -115,6 +115,14 @@ our $projects_list = "++GITWEB_LIST++";
115 # the width (in characters) of the projects list "Description" column
116 our $projects_list_description_width = 25;
117
118 +# group projects by category on the projects list
119 +# (enabled if this variable evaluates to true)
120 +our $projects_list_group_categories = 0;
121 +
122 +# default category if none specified
123 +# (leave the empty string for no category)
124 +our $project_list_default_category = "";
125 +
126 # default order of projects list
127 # valid values are none, project, descr, owner, and age
128 our $default_projects_order = "project";
@@ -2584,6 +2592,12 @@ sub git_get_project_description {
2592 return git_get_file_or_project_config($path, 'description');
2593 }
2594
2595 +sub git_get_project_category {
2596 + my $path = shift;
2597 + return git_get_file_or_project_config($path, 'category');
2598 +}
2599 +
2600 +
2601 # supported formats:
2602 # * $GIT_DIR/ctags/<tagname> file (in 'ctags' subdirectory)
2603 # - if its contents is a number, use it as tag weight,
@@ -4877,8 +4891,9 @@ sub git_patchset_body {
4891
4892 # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4893
4880 -# fills project list info (age, description, owner, forks) for each
4881 -# project in the list, removing invalid projects from returned list
4894 +# fills project list info (age, description, owner, category, forks)
4895 +# for each project in the list, removing invalid projects from
4896 +# returned list
4897 # NOTE: modifies $projlist, but does not remove entries from it
4898 sub fill_project_list_info {
4899 my $projlist = shift;
@@ -4904,6 +4919,12 @@ sub fill_project_list_info {
4919 if ($show_ctags) {
4920 $pr->{'ctags'} = git_get_project_ctags($pr->{'path'});
4921 }
4922 + if ($projects_list_group_categories && !defined $pr->{'category'}) {
4923 + my $cat = git_get_project_category($pr->{'path'}) ||
4924 + $project_list_default_category;
4925 + $pr->{'category'} = to_utf8($cat);
4926 + }
4927 +
4928 push @projects, $pr;
4929 }
4930
@@ -4931,6 +4952,23 @@ sub sort_projects_list {
4952 return @projects;
4953 }
4954
4955 +# returns a hash of categories, containing the list of project
4956 +# belonging to each category
4957 +sub build_projlist_by_category {
4958 + my ($projlist, $from, $to) = @_;
4959 + my %categories;
4960 +
4961 + $from = 0 unless defined $from;
4962 + $to = $#$projlist if (!defined $to || $#$projlist < $to);
4963 +
4964 + for (my $i = $from; $i <= $to; $i++) {
4965 + my $pr = $projlist->[$i];
4966 + push @{$categories{ $pr->{'category'} }}, $pr;
4967 + }
4968 +
4969 + return wantarray ? %categories : \%categories;
4970 +}
4971 +
4972 # print 'sort by' <th> element, generating 'sort by $name' replay link
4973 # if that order is not selected
4974 sub print_sort_th {
@@ -5059,7 +5097,25 @@ sub git_project_list_body {
5097 "</tr>\n";
5098 }
5099
5062 - git_project_list_rows(\@projects, $from, $to, $check_forks);
5100 + if ($projects_list_group_categories) {
5101 + # only display categories with projects in the $from-$to window
5102 + @projects = sort {$a->{'category'} cmp $b->{'category'}} @projects[$from..$to];
5103 + my %categories = build_projlist_by_category(\@projects, $from, $to);
5104 + foreach my $cat (sort keys %categories) {
5105 + unless ($cat eq "") {
5106 + print "<tr>\n";
5107 + if ($check_forks) {
5108 + print "<td></td>\n";
5109 + }
5110 + print "<td class=\"category\" colspan=\"5\">".esc_html($cat)."</td>\n";
5111 + print "</tr>\n";
5112 + }
5113 +
5114 + git_project_list_rows($categories{$cat}, undef, undef, $check_forks);
5115 + }
5116 + } else {
5117 + git_project_list_rows(\@projects, $from, $to, $check_forks);
5118 + }
5119
5120 if (defined $extra) {
5121 print "<tr>\n";
gitweb/static/gitweb.css
+7
@@ -295,6 +295,13 @@ td.current_head {
295 text-decoration: underline;
296 }
297
298 +td.category {
299 + background-color: #d9d8d1;
300 + border-top: 1px solid #000000;
301 + border-left: 1px solid #000000;
302 + font-weight: bold;
303 +}
304 +
305 table.diff_tree span.file_status.new {
306 color: #008000;
307 }
t/t9500-gitweb-standalone-no-errors.sh
+8
@@ -644,4 +644,12 @@ test_expect_success \
644 'ctags: search projects by non existent tag' \
645 'gitweb_run "by_tag=non-existent"'
646
647 +# ----------------------------------------------------------------------
648 +# categories
649 +
650 +test_expect_success \
651 + 'categories: projects list, only default category' \
652 + 'echo "\$projects_list_group_categories = 1;" >>gitweb_config.perl &&
653 + gitweb_run'
654 +
655 test_done