Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add per gem rss feed #479

Merged
merged 1 commit into from

6 participants

@amateurhuman

Add an atom feed for version list of an individual gem. Allows user to subscribe to version changes without registering (by subscribing with an rss reader).

Fixes #466

@grosser grosser commented on the diff
app/views/rubygems/show.html.erb
@@ -27,6 +27,7 @@
<%= documentation_link(@latest_version, @rubygem.linkset) %>
<%= subscribe_link(@rubygem) if @latest_version.indexed %>
<%= unsubscribe_link(@rubygem) %>
+ <%= atom_link(@rubygem) %>
@grosser
grosser added a note

if you also put it into the header the browser can show it in the url-bar rss dropdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@grosser

Some kind of test like 'it renders versions via atom' would be nice so the code gets at least executed once

app/views/versions/index.atom.builder
@@ -0,0 +1,27 @@
+xml.instruct!
+
+xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
+
+ xml.title "Rubygems | Latest Gems"
+ xml.link "rel" => "self", "href" => rubygems_url(:format => :atom)
+ xml.link "rel" => "alternate", "href" => rubygems_url
+ xml.id rubygems_url
+
+ xml.updated(@versions.first.updated_at.strftime("%Y-%m-%dT%H:%M:%SZ")) if @versions.any?
@grosser
grosser added a note

not sure if this needs to be formatted by hand, maybe there is a to_s(:xml) or simply passing a date already renders it correctly

@pjg
pjg added a note

There's #iso8601 for that:

xml.updated(@versions.first.updated_at.iso8601) if @versions.any?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cmeiklejohn
Collaborator

Can we add a test to this?

@cmeiklejohn cmeiklejohn closed this
@cmeiklejohn
Collaborator

Oops, didn't mean to close. Hit the wrong button.

@cmeiklejohn cmeiklejohn reopened this
@qrush
Owner

I am -1 until we have at least a functional test for this.

@amateurhuman

Agreed, it is in the works (with a few other tweaks) but got swamped with a couple conference talks this week. Planning on wrapping this later in the week.

@amateurhuman

Added functional test for the feed, also replaced the hand formated updated string with the Ruby stdlib iso8601 method which was suggested by @pjg

There is a lot of duplication with the index and feed builder, but I haven't spent any time looking at drying that up (I'd say its probably a second issue). Let me know if you'd prefer the refactor now.

@adkron
Collaborator

I think it is easier to DRY it up while you are thinking about it.

@amateurhuman amateurhuman Add atom link for single gem versions feed
Add atom builder for single gem version

Add styles for rss link

Add yield head for injecting atom feed link

Include link tag in head for rss feed

Add gem name to feed title, add test for atom feed

Use ruby stdlib iso8601 method instead of hand formatted

Refactor individual and all versions feeds to share some builder partial
64a7e66
@amateurhuman

Alright, the Latest Versions feeds for both individual gems and the site-wide feed are sharing the same builder partial. I think that completes everyone's suggestions, so I've rebased and squashed all the changes into a single commit.

@adkron adkron merged commit 2e70398 into rubygems:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 12, 2012
  1. @amateurhuman

    Add atom link for single gem versions feed

    amateurhuman authored
    Add atom builder for single gem version
    
    Add styles for rss link
    
    Add yield head for injecting atom feed link
    
    Include link tag in head for rss feed
    
    Add gem name to feed title, add test for atom feed
    
    Use ruby stdlib iso8601 method instead of hand formatted
    
    Refactor individual and all versions feeds to share some builder partial
This page is out of date. Refresh to see the latest.
View
4 app/helpers/rubygems_helper.rb
@@ -39,6 +39,10 @@ def unsubscribe_link(rubygem)
end
end
+ def atom_link(rubygem)
+ link_to 'RSS', rubygem_versions_path(rubygem, format: 'atom'), :id => :rss
+ end
+
def download_link(version)
link_to "Download", "/downloads/#{version.full_name}.gem", :id => :download
end
View
1  app/views/layouts/application.html.erb
@@ -14,6 +14,7 @@
<![endif]-->
<%= render "layouts/feeds" %>
<%= csrf_meta_tag %>
+ <%= yield :head %>
<title><%= page_title %></title>
</head>
<body>
View
3  app/views/rubygems/show.html.erb
@@ -1,6 +1,8 @@
<% @title = @rubygem.name %>
<% @subtitle = @latest_version.try(:slug) %>
+<%= content_for :head, auto_discovery_link_tag(:atom, rubygem_versions_path(@rubygem, format: "atom"), {title: "#{@rubygem.name} Version Feed"}) %>
+
<% if @rubygem.versions.count.zero? %>
<p><%= t '.not_hosted_notice' %></p>
<% else %>
@@ -27,6 +29,7 @@
<%= documentation_link(@latest_version, @rubygem.linkset) %>
<%= subscribe_link(@rubygem) if @latest_version.indexed %>
<%= unsubscribe_link(@rubygem) %>
+ <%= atom_link(@rubygem) %>
@grosser
grosser added a note

if you also put it into the header the browser can show it in the url-bar rss dropdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
</div>
<% if @latest_version.indexed %>
View
27 app/views/versions/_versions_feed.atom.builder
@@ -0,0 +1,27 @@
+builder.instruct!
+
+builder.feed "xmlns" => "http://www.w3.org/2005/Atom" do
+
+ builder.title title
+ builder.link "rel" => "self", "href" => rubygems_url(:format => :atom)
+ builder.link "rel" => "alternate", "href" => rubygems_url
+ builder.id rubygems_url
+
+ builder.updated(versions.first.updated_at.iso8601) if versions.any?
+
+ builder.author { xml.name "Rubygems" }
+
+ versions.each do |version|
+ builder.entry do
+ builder.title version.to_title
+ builder.link "rel" => "alternate", "href" => rubygem_version_url(version.rubygem, version.slug)
+ builder.id rubygem_version_url(version.rubygem, version.slug)
+ builder.updated version.created_at.iso8601
+ builder.author {|author| author.name h(version.authors) }
+ builder.summary version.summary if version.summary?
+ builder.content "type" => "html" do
+ builder.text! h(version.description)
+ end
+ end
+ end
+end
View
34 app/views/versions/feed.atom.builder
@@ -1,27 +1,7 @@
-xml.instruct!
-
-xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
-
- xml.title "Gemcutter | Latest Gems"
- xml.link "rel" => "self", "href" => rubygems_url(:format => :atom)
- xml.link "rel" => "alternate", "href" => rubygems_url
- xml.id rubygems_url
-
- xml.updated(@versions.first.updated_at.strftime("%Y-%m-%dT%H:%M:%SZ")) if @versions.any?
-
- xml.author { xml.name "Gemcutter" }
-
- @versions.each do |version|
- xml.entry do
- xml.title version.to_title
- xml.link "rel" => "alternate", "href" => rubygem_version_url(version.rubygem, version.slug)
- xml.id rubygem_version_url(version.rubygem, version.slug)
- xml.updated version.created_at.strftime("%Y-%m-%dT%H:%M:%SZ")
- xml.author {|author| author.name h(version.authors) }
- xml.summary version.summary if version.summary?
- xml.content "type" => "html" do
- xml.text! h(version.description)
- end
- end
- end
-end
+render(
+ partial: 'versions/versions_feed',
+ locals: {
+ builder: xml,
+ versions: @versions,
+ title: "Rubygems | Latest Gems"
+})
View
7 app/views/versions/index.atom.builder
@@ -0,0 +1,7 @@
+render(
+ partial: 'versions/versions_feed',
+ locals: {
+ builder: xml,
+ versions: @versions,
+ title: "Rubygems | Latest Versions for #{@rubygem.name}"
+})
View
4 public/stylesheets/screen.css
@@ -497,6 +497,10 @@ table {
background: url('/images/download.png') no-repeat;
}
+.main .info .meta .admin #rss {
+ background: url('/images/feed.png') no-repeat;
+}
+
.main .info .meta .admin #docs {
background: url('/images/docs.png') no-repeat;
}
View
28 test/functional/versions_controller_test.rb
@@ -23,6 +23,34 @@ class VersionsControllerTest < ActionController::TestCase
end
end
+ context 'GET to index as an atom feed' do
+ setup do
+ @rubygem = create(:rubygem)
+ @versions = (1..5).map do |version|
+ create(:version, :rubygem => @rubygem)
+ end
+
+ get :index, :rubygem_id => @rubygem.name, :format => "atom"
+ end
+
+ should respond_with :success
+ should assign_to(:versions) { @versions }
+
+ should "render correct gem information in the feed" do
+ assert_select "feed > title", :count => 1, :text => /#{@rubygem.name}/
+ assert_select "feed > updated", :count => 1, :text => @rubygem.updated_at.iso8601
+ end
+
+ should "render information about versions" do
+ @versions.each do |v|
+ assert_select "entry > title", :count => 1, :text => v.to_title
+ assert_select "entry > link[href='#{rubygem_version_url(v.rubygem, v.slug)}']", :count => 1
+ assert_select "entry > id", :count => 1, :text => rubygem_version_url(v.rubygem, v.slug)
+ assert_select "entry > updated", :count => @versions.count, :text => v.updated_at.iso8601
+ end
+ end
+ end
+
context "GET to index for gem with no versions" do
setup do
@rubygem = create(:rubygem)
Something went wrong with that request. Please try again.