@@ -115,6 +115,14 @@ sub evaluate_uri {
115
115
# the width (in characters) of the projects list "Description" column
116
116
our $projects_list_description_width = 25;
117
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
+
118
126
# default order of projects list
119
127
# valid values are none, project, descr, owner, and age
120
128
our $default_projects_order = " project" ;
@@ -2574,20 +2582,34 @@ sub git_get_path_by_hash {
2574
2582
# # ......................................................................
2575
2583
# # git utility functions, directly accessing git repository
2576
2584
2577
- sub git_get_project_description {
2578
- my $path = shift ;
2585
+ # get the value of config variable either from file named as the variable
2586
+ # itself in the repository ($GIT_DIR/$name file), or from gitweb.$name
2587
+ # configuration variable in the repository config file.
2588
+ sub git_get_file_or_project_config {
2589
+ my ($path , $name ) = @_ ;
2579
2590
2580
2591
$git_dir = " $projectroot /$path " ;
2581
- open my $fd , ' <' , " $git_dir /description "
2582
- or return git_get_project_config(' description ' );
2583
- my $descr = <$fd >;
2592
+ open my $fd , ' <' , " $git_dir /$name "
2593
+ or return git_get_project_config($name );
2594
+ my $conf = <$fd >;
2584
2595
close $fd ;
2585
- if (defined $descr ) {
2586
- chomp $descr ;
2596
+ if (defined $conf ) {
2597
+ chomp $conf ;
2587
2598
}
2588
- return $descr ;
2599
+ return $conf ;
2600
+ }
2601
+
2602
+ sub git_get_project_description {
2603
+ my $path = shift ;
2604
+ return git_get_file_or_project_config($path , ' description' );
2589
2605
}
2590
2606
2607
+ sub git_get_project_category {
2608
+ my $path = shift ;
2609
+ return git_get_file_or_project_config($path , ' category' );
2610
+ }
2611
+
2612
+
2591
2613
# supported formats:
2592
2614
# * $GIT_DIR/ctags/<tagname> file (in 'ctags' subdirectory)
2593
2615
# - if its contents is a number, use it as tag weight,
@@ -4881,8 +4903,9 @@ sub git_patchset_body {
4881
4903
4882
4904
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4883
4905
4884
- # fills project list info (age, description, owner, forks) for each
4885
- # project in the list, removing invalid projects from returned list
4906
+ # fills project list info (age, description, owner, category, forks)
4907
+ # for each project in the list, removing invalid projects from
4908
+ # returned list
4886
4909
# NOTE: modifies $projlist, but does not remove entries from it
4887
4910
sub fill_project_list_info {
4888
4911
my $projlist = shift ;
@@ -4908,6 +4931,12 @@ sub fill_project_list_info {
4908
4931
if ($show_ctags ) {
4909
4932
$pr -> {' ctags' } = git_get_project_ctags($pr -> {' path' });
4910
4933
}
4934
+ if ($projects_list_group_categories && !defined $pr -> {' category' }) {
4935
+ my $cat = git_get_project_category($pr -> {' path' }) ||
4936
+ $project_list_default_category ;
4937
+ $pr -> {' category' } = to_utf8($cat );
4938
+ }
4939
+
4911
4940
push @projects , $pr ;
4912
4941
}
4913
4942
@@ -4935,6 +4964,23 @@ sub sort_projects_list {
4935
4964
return @projects ;
4936
4965
}
4937
4966
4967
+ # returns a hash of categories, containing the list of project
4968
+ # belonging to each category
4969
+ sub build_projlist_by_category {
4970
+ my ($projlist , $from , $to ) = @_ ;
4971
+ my %categories ;
4972
+
4973
+ $from = 0 unless defined $from ;
4974
+ $to = $# $projlist if (!defined $to || $# $projlist < $to );
4975
+
4976
+ for (my $i = $from ; $i <= $to ; $i ++) {
4977
+ my $pr = $projlist -> [$i ];
4978
+ push @{$categories { $pr -> {' category' } }}, $pr ;
4979
+ }
4980
+
4981
+ return wantarray ? %categories : \%categories ;
4982
+ }
4983
+
4938
4984
# print 'sort by' <th> element, generating 'sort by $name' replay link
4939
4985
# if that order is not selected
4940
4986
sub print_sort_th {
@@ -4958,6 +5004,55 @@ sub format_sort_th {
4958
5004
return $sort_th ;
4959
5005
}
4960
5006
5007
+ sub git_project_list_rows {
5008
+ my ($projlist , $from , $to , $check_forks ) = @_ ;
5009
+
5010
+ $from = 0 unless defined $from ;
5011
+ $to = $# $projlist if (!defined $to || $# $projlist < $to );
5012
+
5013
+ my $alternate = 1;
5014
+ for (my $i = $from ; $i <= $to ; $i ++) {
5015
+ my $pr = $projlist -> [$i ];
5016
+
5017
+ if ($alternate ) {
5018
+ print " <tr class=\" dark\" >\n " ;
5019
+ } else {
5020
+ print " <tr class=\" light\" >\n " ;
5021
+ }
5022
+ $alternate ^= 1;
5023
+
5024
+ if ($check_forks ) {
5025
+ print " <td>" ;
5026
+ if ($pr -> {' forks' }) {
5027
+ my $nforks = scalar @{$pr -> {' forks' }};
5028
+ if ($nforks > 0) {
5029
+ print $cgi -> a({-href => href(project => $pr -> {' path' }, action => " forks" ),
5030
+ -title => " $nforks forks" }, " +" );
5031
+ } else {
5032
+ print $cgi -> span({-title => " $nforks forks" }, " +" );
5033
+ }
5034
+ }
5035
+ print " </td>\n " ;
5036
+ }
5037
+ print " <td>" . $cgi -> a({-href => href(project => $pr -> {' path' }, action => " summary" ),
5038
+ -class => " list" }, esc_html($pr -> {' path' })) . " </td>\n " .
5039
+ " <td>" . $cgi -> a({-href => href(project => $pr -> {' path' }, action => " summary" ),
5040
+ -class => " list" , -title => $pr -> {' descr_long' }},
5041
+ esc_html($pr -> {' descr' })) . " </td>\n " .
5042
+ " <td><i>" . chop_and_escape_str($pr -> {' owner' }, 15) . " </i></td>\n " ;
5043
+ print " <td class=\" " . age_class($pr -> {' age' }) . " \" >" .
5044
+ (defined $pr -> {' age_string' } ? $pr -> {' age_string' } : " No commits" ) . " </td>\n " .
5045
+ " <td class=\" link\" >" .
5046
+ $cgi -> a({-href => href(project => $pr -> {' path' }, action => " summary" )}, " summary" ) . " | " .
5047
+ $cgi -> a({-href => href(project => $pr -> {' path' }, action => " shortlog" )}, " shortlog" ) . " | " .
5048
+ $cgi -> a({-href => href(project => $pr -> {' path' }, action => " log" )}, " log" ) . " | " .
5049
+ $cgi -> a({-href => href(project => $pr -> {' path' }, action => " tree" )}, " tree" ) .
5050
+ ($pr -> {' forks' } ? " | " . $cgi -> a({-href => href(project => $pr -> {' path' }, action => " forks" )}, " forks" ) : ' ' ) .
5051
+ " </td>\n " .
5052
+ " </tr>\n " ;
5053
+ }
5054
+ }
5055
+
4961
5056
sub git_project_list_body {
4962
5057
# actually uses global variable $project
4963
5058
my ($projlist , $order , $from , $to , $extra , $no_header ) = @_ ;
@@ -5013,47 +5108,27 @@ sub git_project_list_body {
5013
5108
print " <th></th>\n " . # for links
5014
5109
" </tr>\n " ;
5015
5110
}
5016
- my $alternate = 1;
5017
- for (my $i = $from ; $i <= $to ; $i ++) {
5018
- my $pr = $projects [$i ];
5019
5111
5020
- if ($alternate ) {
5021
- print " <tr class=\" dark\" >\n " ;
5022
- } else {
5023
- print " <tr class=\" light\" >\n " ;
5024
- }
5025
- $alternate ^= 1;
5026
-
5027
- if ($check_forks ) {
5028
- print " <td>" ;
5029
- if ($pr -> {' forks' }) {
5030
- my $nforks = scalar @{$pr -> {' forks' }};
5031
- if ($nforks > 0) {
5032
- print $cgi -> a({-href => href(project => $pr -> {' path' }, action => " forks" ),
5033
- -title => " $nforks forks" }, " +" );
5034
- } else {
5035
- print $cgi -> span({-title => " $nforks forks" }, " +" );
5112
+ if ($projects_list_group_categories ) {
5113
+ # only display categories with projects in the $from-$to window
5114
+ @projects = sort {$a -> {' category' } cmp $b -> {' category' }} @projects [$from ..$to ];
5115
+ my %categories = build_projlist_by_category(\@projects , $from , $to );
5116
+ foreach my $cat (sort keys %categories ) {
5117
+ unless ($cat eq " " ) {
5118
+ print " <tr>\n " ;
5119
+ if ($check_forks ) {
5120
+ print " <td></td>\n " ;
5036
5121
}
5122
+ print " <td class=\" category\" colspan=\" 5\" >" .esc_html($cat )." </td>\n " ;
5123
+ print " </tr>\n " ;
5037
5124
}
5038
- print " </td>\n " ;
5125
+
5126
+ git_project_list_rows($categories {$cat }, undef , undef , $check_forks );
5039
5127
}
5040
- print " <td>" . $cgi -> a({-href => href(project => $pr -> {' path' }, action => " summary" ),
5041
- -class => " list" }, esc_html($pr -> {' path' })) . " </td>\n " .
5042
- " <td>" . $cgi -> a({-href => href(project => $pr -> {' path' }, action => " summary" ),
5043
- -class => " list" , -title => $pr -> {' descr_long' }},
5044
- esc_html($pr -> {' descr' })) . " </td>\n " .
5045
- " <td><i>" . chop_and_escape_str($pr -> {' owner' }, 15) . " </i></td>\n " ;
5046
- print " <td class=\" " . age_class($pr -> {' age' }) . " \" >" .
5047
- (defined $pr -> {' age_string' } ? $pr -> {' age_string' } : " No commits" ) . " </td>\n " .
5048
- " <td class=\" link\" >" .
5049
- $cgi -> a({-href => href(project => $pr -> {' path' }, action => " summary" )}, " summary" ) . " | " .
5050
- $cgi -> a({-href => href(project => $pr -> {' path' }, action => " shortlog" )}, " shortlog" ) . " | " .
5051
- $cgi -> a({-href => href(project => $pr -> {' path' }, action => " log" )}, " log" ) . " | " .
5052
- $cgi -> a({-href => href(project => $pr -> {' path' }, action => " tree" )}, " tree" ) .
5053
- ($pr -> {' forks' } ? " | " . $cgi -> a({-href => href(project => $pr -> {' path' }, action => " forks" )}, " forks" ) : ' ' ) .
5054
- " </td>\n " .
5055
- " </tr>\n " ;
5128
+ } else {
5129
+ git_project_list_rows(\@projects , $from , $to , $check_forks );
5056
5130
}
5131
+
5057
5132
if (defined $extra ) {
5058
5133
print " <tr>\n " ;
5059
5134
if ($check_forks ) {
0 commit comments