]> Lady’s Gitweb - Gitweb/blobdiff - gitweb.perl
gitweb: Optional grouping of projects by category
[Gitweb] / gitweb.perl
index 6d013f1070543e10a658f8247c265bd7256a32d5741a5d404cfcb4e6a738cc75..cf34c5bebf47687303a4c6a962b9db6834729a8bf1f275f62e8db00d17dfda25 100755 (executable)
@@ -116,6 +116,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";
@@ -2585,6 +2593,12 @@ sub git_get_project_description {
        return git_get_file_or_project_config($path, 'description');
 }
 
+sub git_get_project_category {
+       my $path = shift;
+       return git_get_file_or_project_config($path, 'category');
+}
+
+
 # supported formats:
 # * $GIT_DIR/ctags/<tagname> file (in 'ctags' subdirectory)
 #   - if its contents is a number, use it as tag weight,
@@ -2662,6 +2676,7 @@ sub git_populate_project_tagcloud {
        }
 
        my $cloud;
+       my $matched = $cgi->param('by_tag');
        if (eval { require HTML::TagCloud; 1; }) {
                $cloud = HTML::TagCloud->new;
                foreach my $ctag (sort keys %ctags_lc) {
@@ -2671,17 +2686,22 @@ sub git_populate_project_tagcloud {
                        $title =~ s/ /&nbsp;/g;
                        $title =~ s/^/&nbsp;/g;
                        $title =~ s/$/&nbsp;/g;
+                       if (defined $matched && $matched eq $ctag) {
+                               $title = qq(<span class="match">$title</span>);
+                       }
                        $cloud->add($title, href(project=>undef, ctag=>$ctag),
                                    $ctags_lc{$ctag}->{count});
                }
        } else {
                $cloud = {};
                foreach my $ctag (keys %ctags_lc) {
-                       my $title = $ctags_lc{$ctag}->{topname};
+                       my $title = esc_html($ctags_lc{$ctag}->{topname}, -nbsp=>1);
+                       if (defined $matched && $matched eq $ctag) {
+                               $title = qq(<span class="match">$title</span>);
+                       }
                        $cloud->{$ctag}{count} = $ctags_lc{$ctag}->{count};
                        $cloud->{$ctag}{ctag} =
-                               $cgi->a({-href=>href(project=>undef, ctag=>$ctag)},
-                                 esc_html($title, -nbsp=>1));
+                               $cgi->a({-href=>href(project=>undef, ctag=>$ctag)}, $title);
                }
        }
        return $cloud;
@@ -4804,8 +4824,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) = @_;
@@ -4839,12 +4860,35 @@ sub fill_project_list_info {
                        }
                }
                $show_ctags and $pr->{'ctags'} = git_get_project_ctags($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);
+               }
+
                push @projects, $pr;
        }
 
        return @projects;
 }
 
+# returns a hash of categories, containing the list of project
+# belonging to each category
+sub build_projlist_by_category {
+       my ($projlist, $from, $to) = @_;
+       my %categories;
+
+       $from = 0 unless defined $from;
+       $to = $#$projlist if (!defined $to || $#$projlist < $to);
+
+       for (my $i = $from; $i <= $to; $i++) {
+               my $pr = $projlist->[$i];
+               push @{$categories{ $pr->{'category'} }}, $pr;
+       }
+
+       return wantarray ? %categories : \%categories;
+}
+
 # print 'sort by' <th> element, generating 'sort by $name' replay link
 # if that order is not selected
 sub print_sort_th {
@@ -4967,7 +5011,26 @@ sub git_project_list_body {
                print "<th></th>\n" . # for links
                      "</tr>\n";
        }
-       git_project_list_rows(\@projects, $from, $to, $check_forks);
+
+       if ($projects_list_group_categories) {
+               # only display categories with projects in the $from-$to window
+               @projects = sort {$a->{'category'} cmp $b->{'category'}} @projects[$from..$to];
+               my %categories = build_projlist_by_category(\@projects, $from, $to);
+               foreach my $cat (sort keys %categories) {
+                       unless ($cat eq "") {
+                               print "<tr>\n";
+                               if ($check_forks) {
+                                       print "<td></td>\n";
+                               }
+                               print "<td class=\"category\" colspan=\"5\">".esc_html($cat)."</td>\n";
+                               print "</tr>\n";
+                       }
+
+                       git_project_list_rows($categories{$cat}, undef, undef, $check_forks);
+               }
+       } else {
+               git_project_list_rows(\@projects, $from, $to, $check_forks);
+       }
 
        if (defined $extra) {
                print "<tr>\n";
This page took 0.318684 seconds and 4 git commands to generate.