[PATCH (resend)] gitweb: Use feed link according to current view

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Michael G. Noll said in comments to the "Switching my code repository
from Subversion (SVN) to git" article (http://tinyurl.com/37v67l) in
his "My digital moleskine" blog, that one of the things he is missing
in gitweb from SVN::Web is an RSS feed with news/information of the
current view (including RSS feed for single file or directory).

This is not exactly true, as since refactoring feed generation in
commit-af6feeb229110a0fa77a179c2655fca08e72f879
  "gitweb: Refactor feed generation, make output prettier, add Atom feed"
gitweb can generate feeds (RSS or Atom) for history of a given branch,
history limited to a given directory, or history of a given file.
Nevertheless this required handcrafting the URL to get wanted RSS
feed.


This commit makes gitweb select feed links in the HTML header and in
page footer depending on current view (action).  It is more elaborate,
and I guess more correct, than simple patch adding $hash ('h')
parameter to *all* URLs, including feed links, by Jean-Baptiste Quenot
  Subject: [PATCH] gitweb: Add hash parameter in feed URL when a hash
           is specified in the current request
  Message-ID: <ae63f8b50803211138y6355fd11pa64cda50a1f53011@xxxxxxxxxxxxxx>

If $hash ('h') or $hash_base ('hb') parameter is a branch name
(i.e. it starts with 'refs/heads/'; all generated URLs use this form
to discriminate between tags and heads), it is used in feed URLs; if
$file_name ('f') is defined, it is used in feed URLs.  Feed title is
set according to the kind of web feed: it is either 'log' for generic
feed, 'log of <branch>', 'history of <filename>' for generic history
(using implicit or explicit HEAD, i.e. current branch) or 'history of
<filename> on <branch>'.

There are special cases: 'heads' and 'forks' views should use OPML
providing list of available feeds; 'tags' probably also should use
OPML; there is no web feed equivalent to 'search' view.  Currently all
those cases fallback to (show) default feed.  Such feed link uses
"generic" class, and is shown in slightly lighter color for
distinction.

Currently feed can have but one starting point, and does not support
negative (exclude) commit arguments.  Therefore for now for *diff
views it is chosen that feed follow the "to" part: to-name, to-commit
for 'blobdiff', 'treediff' and 'commitdiff' views.


Generating parameters for href() for feed link was separated
(refactored) into get_feed_info() subroutine.

Signed-off-by: Jakub Narebski <jnareb@xxxxxxxxx>
---
This is resend of earlier patch after 1.5.5 is out.

The only difference is that 'generic' links to feeds in footer are
shown in slightly lighter color, to better distinguish situation
when they refer to alternate version of the page, and when they refer
to generic feed for given project.

Comments?


 gitweb/gitweb.css  |    8 +++
 gitweb/gitweb.perl |  121 +++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 104 insertions(+), 25 deletions(-)

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 446a1c3..aa0eeca 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -464,6 +464,14 @@ a.rss_logo:hover {
 	background-color: #ee5500;
 }
 
+a.rss_logo.generic {
+	background-color: #ff8800;
+}
+
+a.rss_logo.generic:hover {
+	background-color: #ee7700;
+}
+
 span.refs span {
 	padding: 0px 4px;
 	font-size: 70%;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a48bebb..0b2d9e0 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -592,7 +592,7 @@ exit;
 ## ======================================================================
 ## action links
 
-sub href(%) {
+sub href (%) {
 	my %params = @_;
 	# default is to use -absolute url() i.e. $my_uri
 	my $href = $params{-full} ? $my_url : $my_uri;
@@ -1448,6 +1448,46 @@ sub format_snapshot_links {
 	}
 }
 
+## ......................................................................
+## functions returning values to be passed, perhaps after some
+## transformation, to other functions; e.g. returning arguments to href()
+
+# returns hash to be passed to href to generate gitweb URL
+# in -title key it returns description of link
+sub get_feed_info {
+	my $format = shift || 'Atom';
+	my %res = (action => lc($format));
+
+	# feed links are possible only for project views
+	return unless (defined $project);
+	# some views should link to OPML, or to generic project feed,
+	# or don't have specific feed yet (so they should use generic)
+	return if ($action =~ /^(?:tags|heads|forks|tag|search)$/x);
+
+	my $branch;
+	# branches refs uses 'refs/heads/' prefix (fullname) to differentiate
+	# from tag links; this also makes possible to detect branch links
+	if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) ||
+	    (defined $hash      && $hash      =~ m!^refs/heads/(.*)$!)) {
+		$branch = $1;
+	}
+	# find log type for feed description (title)
+	my $type = 'log';
+	if (defined $file_name) {
+		$type  = "history of $file_name";
+		$type .= "/" if ($action eq 'tree');
+		$type .= " on '$branch'" if (defined $branch);
+	} else {
+		$type = "log of $branch" if (defined $branch);
+	}
+
+	$res{-title} = $type;
+	$res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef);
+	$res{'file_name'} = $file_name;
+
+	return %res;
+}
+
 ## ----------------------------------------------------------------------
 ## git utility subroutines, invoking git commands
 
@@ -2510,30 +2550,49 @@ EOF
 		}
 	}
 	if (defined $project) {
-		printf('<link rel="alternate" title="%s log RSS feed" '.
-		       'href="%s" type="application/rss+xml" />'."\n",
-		       esc_param($project), href(action=>"rss"));
-		printf('<link rel="alternate" title="%s log RSS feed (no merges)" '.
-		       'href="%s" type="application/rss+xml" />'."\n",
-		       esc_param($project), href(action=>"rss",
-		                                 extra_options=>"--no-merges"));
-		printf('<link rel="alternate" title="%s log Atom feed" '.
-		       'href="%s" type="application/atom+xml" />'."\n",
-		       esc_param($project), href(action=>"atom"));
-		printf('<link rel="alternate" title="%s log Atom feed (no merges)" '.
-		       'href="%s" type="application/atom+xml" />'."\n",
-		       esc_param($project), href(action=>"atom",
-		                                 extra_options=>"--no-merges"));
+		my %href_params = get_feed_info();
+		if (!exists $href_params{'-title'}) {
+			$href_params{'-title'} = 'log';
+		}
+
+		foreach my $format qw(RSS Atom) {
+			my $type = lc($format);
+			my %link_attr = (
+				'-rel' => 'alternate',
+				'-title' => "$project - $href_params{'-title'} - $format feed",
+				'-type' => "application/$type+xml"
+			);
+
+			$href_params{'action'} = $type;
+			$link_attr{'-href'} = href(%href_params);
+			print "<link ".
+			      "rel=\"$link_attr{'-rel'}\" ".
+			      "title=\"$link_attr{'-title'}\" ".
+			      "href=\"$link_attr{'-href'}\" ".
+			      "type=\"$link_attr{'-type'}\" ".
+			      "/>\n";
+
+			$href_params{'extra_options'} = '--no-merges';
+			$link_attr{'-href'} = href(%href_params);
+			$link_attr{'-title'} .= ' (no merges)';
+			print "<link ".
+			      "rel=\"$link_attr{'-rel'}\" ".
+			      "title=\"$link_attr{'-title'}\" ".
+			      "href=\"$link_attr{'-href'}\" ".
+			      "type=\"$link_attr{'-type'}\" ".
+			      "/>\n";
+		}
+
 	} else {
 		printf('<link rel="alternate" title="%s projects list" '.
-		       'href="%s" type="text/plain; charset=utf-8"/>'."\n",
+		       'href="%s" type="text/plain; charset=utf-8" />'."\n",
 		       $site_name, href(project=>undef, action=>"project_index"));
 		printf('<link rel="alternate" title="%s projects feeds" '.
-		       'href="%s" type="text/x-opml"/>'."\n",
+		       'href="%s" type="text/x-opml" />'."\n",
 		       $site_name, href(project=>undef, action=>"opml"));
 	}
 	if (defined $favicon) {
-		print qq(<link rel="shortcut icon" href="$favicon" type="image/png"/>\n);
+		print qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
 	}
 
 	print "</head>\n" .
@@ -2601,23 +2660,35 @@ EOF
 }
 
 sub git_footer_html {
+	my $feed_class = 'rss_logo';
+
 	print "<div class=\"page_footer\">\n";
 	if (defined $project) {
 		my $descr = git_get_project_description($project);
 		if (defined $descr) {
 			print "<div class=\"page_footer_text\">" . esc_html($descr) . "</div>\n";
 		}
-		print $cgi->a({-href => href(action=>"rss"),
-		              -class => "rss_logo"}, "RSS") . " ";
-		print $cgi->a({-href => href(action=>"atom"),
-		              -class => "rss_logo"}, "Atom") . "\n";
+
+		my %href_params = get_feed_info();
+		if (!%href_params) {
+			$feed_class .= ' generic';
+		}
+		$href_params{'-title'} ||= 'log';
+
+		foreach my $format qw(RSS Atom) {
+			$href_params{'action'} = lc($format);
+			print $cgi->a({-href => href(%href_params),
+			              -title => "$href_params{'-title'} $format feed",
+			              -class => $feed_class}, $format)."\n";
+		}
+
 	} else {
 		print $cgi->a({-href => href(project=>undef, action=>"opml"),
-		              -class => "rss_logo"}, "OPML") . " ";
+		              -class => $feed_class}, "OPML") . " ";
 		print $cgi->a({-href => href(project=>undef, action=>"project_index"),
-		              -class => "rss_logo"}, "TXT") . "\n";
+		              -class => $feed_class}, "TXT") . "\n";
 	}
-	print "</div>\n" ;
+	print "</div>\n"; # class="page_footer"
 
 	if (-f $site_footer) {
 		open (my $fd, $site_footer);
-- 
1.5.5

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux