@matheusbsbs / matheus-bagliano / commits / 3562198b7d
Fork 0

gitweb: Use feed link according to current view

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 af6feeb (gitweb: Refactor feed generation, make output prettier, add Atom feed, 2006-11-19), 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@mail.gmail.com> 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@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jakub Narebski committed Apr 20, 2008 at 22:09 UTC 3562198b7da7ef6597af27b3a7fcaeee41608999
2 files changed +104 -25
gitweb/gitweb.css
+8
@@ -464,6 +464,14 @@ a.rss_logo:hover {
464 background-color: #ee5500;
465 }
466
467 +a.rss_logo.generic {
468 + background-color: #ff8800;
469 +}
470 +
471 +a.rss_logo.generic:hover {
472 + background-color: #ee7700;
473 +}
474 +
475 span.refs span {
476 padding: 0px 4px;
477 font-size: 70%;
gitweb/gitweb.perl
+96 -25
@@ -592,7 +592,7 @@ exit;
592 ## ======================================================================
593 ## action links
594
595 -sub href(%) {
595 +sub href (%) {
596 my %params = @_;
597 # default is to use -absolute url() i.e. $my_uri
598 my $href = $params{-full} ? $my_url : $my_uri;
@@ -1448,6 +1448,46 @@ sub format_snapshot_links {
1448 }
1449 }
1450
1451 +## ......................................................................
1452 +## functions returning values to be passed, perhaps after some
1453 +## transformation, to other functions; e.g. returning arguments to href()
1454 +
1455 +# returns hash to be passed to href to generate gitweb URL
1456 +# in -title key it returns description of link
1457 +sub get_feed_info {
1458 + my $format = shift || 'Atom';
1459 + my %res = (action => lc($format));
1460 +
1461 + # feed links are possible only for project views
1462 + return unless (defined $project);
1463 + # some views should link to OPML, or to generic project feed,
1464 + # or don't have specific feed yet (so they should use generic)
1465 + return if ($action =~ /^(?:tags|heads|forks|tag|search)$/x);
1466 +
1467 + my $branch;
1468 + # branches refs uses 'refs/heads/' prefix (fullname) to differentiate
1469 + # from tag links; this also makes possible to detect branch links
1470 + if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) ||
1471 + (defined $hash && $hash =~ m!^refs/heads/(.*)$!)) {
1472 + $branch = $1;
1473 + }
1474 + # find log type for feed description (title)
1475 + my $type = 'log';
1476 + if (defined $file_name) {
1477 + $type = "history of $file_name";
1478 + $type .= "/" if ($action eq 'tree');
1479 + $type .= " on '$branch'" if (defined $branch);
1480 + } else {
1481 + $type = "log of $branch" if (defined $branch);
1482 + }
1483 +
1484 + $res{-title} = $type;
1485 + $res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef);
1486 + $res{'file_name'} = $file_name;
1487 +
1488 + return %res;
1489 +}
1490 +
1491 ## ----------------------------------------------------------------------
1492 ## git utility subroutines, invoking git commands
1493
@@ -2510,30 +2550,49 @@ EOF
2550 }
2551 }
2552 if (defined $project) {
2513 - printf('<link rel="alternate" title="%s log RSS feed" '.
2514 - 'href="%s" type="application/rss+xml" />'."\n",
2515 - esc_param($project), href(action=>"rss"));
2516 - printf('<link rel="alternate" title="%s log RSS feed (no merges)" '.
2517 - 'href="%s" type="application/rss+xml" />'."\n",
2518 - esc_param($project), href(action=>"rss",
2519 - extra_options=>"--no-merges"));
2520 - printf('<link rel="alternate" title="%s log Atom feed" '.
2521 - 'href="%s" type="application/atom+xml" />'."\n",
2522 - esc_param($project), href(action=>"atom"));
2523 - printf('<link rel="alternate" title="%s log Atom feed (no merges)" '.
2524 - 'href="%s" type="application/atom+xml" />'."\n",
2525 - esc_param($project), href(action=>"atom",
2526 - extra_options=>"--no-merges"));
2553 + my %href_params = get_feed_info();
2554 + if (!exists $href_params{'-title'}) {
2555 + $href_params{'-title'} = 'log';
2556 + }
2557 +
2558 + foreach my $format qw(RSS Atom) {
2559 + my $type = lc($format);
2560 + my %link_attr = (
2561 + '-rel' => 'alternate',
2562 + '-title' => "$project - $href_params{'-title'} - $format feed",
2563 + '-type' => "application/$type+xml"
2564 + );
2565 +
2566 + $href_params{'action'} = $type;
2567 + $link_attr{'-href'} = href(%href_params);
2568 + print "<link ".
2569 + "rel=\"$link_attr{'-rel'}\" ".
2570 + "title=\"$link_attr{'-title'}\" ".
2571 + "href=\"$link_attr{'-href'}\" ".
2572 + "type=\"$link_attr{'-type'}\" ".
2573 + "/>\n";
2574 +
2575 + $href_params{'extra_options'} = '--no-merges';
2576 + $link_attr{'-href'} = href(%href_params);
2577 + $link_attr{'-title'} .= ' (no merges)';
2578 + print "<link ".
2579 + "rel=\"$link_attr{'-rel'}\" ".
2580 + "title=\"$link_attr{'-title'}\" ".
2581 + "href=\"$link_attr{'-href'}\" ".
2582 + "type=\"$link_attr{'-type'}\" ".
2583 + "/>\n";
2584 + }
2585 +
2586 } else {
2587 printf('<link rel="alternate" title="%s projects list" '.
2529 - 'href="%s" type="text/plain; charset=utf-8"/>'."\n",
2588 + 'href="%s" type="text/plain; charset=utf-8" />'."\n",
2589 $site_name, href(project=>undef, action=>"project_index"));
2590 printf('<link rel="alternate" title="%s projects feeds" '.
2532 - 'href="%s" type="text/x-opml"/>'."\n",
2591 + 'href="%s" type="text/x-opml" />'."\n",
2592 $site_name, href(project=>undef, action=>"opml"));
2593 }
2594 if (defined $favicon) {
2536 - print qq(<link rel="shortcut icon" href="$favicon" type="image/png"/>\n);
2595 + print qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
2596 }
2597
2598 print "</head>\n" .
@@ -2601,23 +2660,35 @@ EOF
2660 }
2661
2662 sub git_footer_html {
2663 + my $feed_class = 'rss_logo';
2664 +
2665 print "<div class=\"page_footer\">\n";
2666 if (defined $project) {
2667 my $descr = git_get_project_description($project);
2668 if (defined $descr) {
2669 print "<div class=\"page_footer_text\">" . esc_html($descr) . "</div>\n";
2670 }
2610 - print $cgi->a({-href => href(action=>"rss"),
2611 - -class => "rss_logo"}, "RSS") . " ";
2612 - print $cgi->a({-href => href(action=>"atom"),
2613 - -class => "rss_logo"}, "Atom") . "\n";
2671 +
2672 + my %href_params = get_feed_info();
2673 + if (!%href_params) {
2674 + $feed_class .= ' generic';
2675 + }
2676 + $href_params{'-title'} ||= 'log';
2677 +
2678 + foreach my $format qw(RSS Atom) {
2679 + $href_params{'action'} = lc($format);
2680 + print $cgi->a({-href => href(%href_params),
2681 + -title => "$href_params{'-title'} $format feed",
2682 + -class => $feed_class}, $format)."\n";
2683 + }
2684 +
2685 } else {
2686 print $cgi->a({-href => href(project=>undef, action=>"opml"),
2616 - -class => "rss_logo"}, "OPML") . " ";
2687 + -class => $feed_class}, "OPML") . " ";
2688 print $cgi->a({-href => href(project=>undef, action=>"project_index"),
2618 - -class => "rss_logo"}, "TXT") . "\n";
2689 + -class => $feed_class}, "TXT") . "\n";
2690 }
2620 - print "</div>\n" ;
2691 + print "</div>\n"; # class="page_footer"
2692
2693 if (-f $site_footer) {
2694 open (my $fd, $site_footer);