Implemented main RSS and Atom feed
h3rald h3rald@h3rald.com
Thu, 27 Aug 2009 15:53:36 +0200
8 files changed,
134 insertions(+),
35 deletions(-)
M
README.textile
→
README.textile
@@ -2,11 +2,12 @@ h2. Dependencies
h3. Ruby Gems -* nanoc (generate static site) +* nanoc3 (generate static site) * extlib (Rake tasks) * mysql (Typo migration) * sequel (Typo migration) * bb-ruby (BBCode filter) +* builder (Feeds) h3. Other
M
Rules
→
Rules
@@ -1,33 +1,5 @@
#!/usr/bin/env ruby -"a-look-at-drupal.bbcode -boolean-search.bbcode -cakephp.bbcode -from-firefox-to-deer-park.bbcode -google-earth.bbcode -ie-lovers-guide-to-firefox.bbcode -ma.gnolia.bbcode -next-generation-dvds.bbcode -pagerank.bbcode -perfect-browser.bbcode -pre-review-of-ie7.bbcode -project-gutenberg.bbcode -project-windstone.bbcode -quick-overview-of-sqlite.bbcode -server-packages.bbcode -slax.bbcode -sqlyog5-review.bbcode -web-promotion.bbcode -what-is-ajax.bbcode -log-jan-2009.bluecloth -the-rails-way-review.bluecloth".split(/\n/).each do |s| - f, ident, fil = s.match(/(.+)\.(.+)$/).to_a - compile "/articles/#{ident}" do - rep.filter fil.to_sym - layout 'default' - end -end - compile /archives/ do rep.filter :erb layout 'default'@@ -38,10 +10,24 @@ rep.filter :erb
rep.filter :redcloth layout 'default' end + +compile /(rss|atom)/ do + rep.filter :erb +end compile '*' do - rep.filter :redcloth + if !item[:filters_pre].empty? then + item[:filters_pre].each do |f| + rep.filter f.to_sym + end + else + rep.filter :redcloth + end layout 'default' +end + +route '/(atom|rss)/' do + item.identifier.gsub(/\/$/, '') + '.xml' end route '*' do
M
config.yaml
→
config.yaml
@@ -4,3 +4,5 @@ - items_root: /
layouts_root: / type: filesystem_combined output_dir: output +base_url: "http://www.h3rald.com" +author: "Fabio Cevasco"
A
content/atom.xml
@@ -0,0 +1,6 @@
+--- +permalink: 'atom' +type: 'feed' +title: 'Latest Articles (Atom) - HERALD' +--- +<%= atom_feed %>
M
content/home.textile
→
content/home.textile
@@ -5,6 +5,7 @@ - erb
- redcloth title: Home type: page +feed: '' ----- <% max_items = 5
A
content/rss.xml
@@ -0,0 +1,6 @@
+--- +permalink: 'rss' +type: 'feed' +title: 'Latest Articles (RSS) - HERALD' +--- +<%= rss_feed %>
M
layouts/default.htm
→
layouts/default.htm
@@ -6,8 +6,10 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title><%= @item[:title] %> - H3RALD</title> - <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.h3rald.com/rss" /> - <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.h3rald.com/atom" /> + <% if @item[:feed] then %> + <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.h3rald.com/<%= @item[:feed]%>rss/" /> + <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.h3rald.com/<%= @item[:feed]%>atom/" /> + <% end %> <meta name="author" content="Fabio Cevasco" /> <meta name="copyright" content="Fabio Cevasco" /> <meta name="robots" content="all, follow" />
M
lib/helpers.rb
→
lib/helpers.rb
@@ -27,10 +27,105 @@ end
end -module Nanoc3::Helpers::Site +module Nanoc3::Helpers::Blogging + + def prepare_feed(params) + # Extract parameters + @item[:limit] ||= 10 + @item[:articles] = params[:articles] || latest_articles(10) || [] + @item[:content_proc] = params[:content_proc] || lambda { |a| a.reps[0].content_at_snapshot(:last)} + @item[:excerpt_proc] = params[:excerpt_proc] || lambda { |a| a[:excerpt] } + @item[:author_name] ||= @site.config[:author] + @item[:author_uri] ||= @site.config[:base_url] + raise RuntimeError.new('Cannot build feed: site configuration has no base_url') if @site.config[:base_url].nil? + raise RuntimeError.new('Cannot build feed: feed item has no title') if @item[:title].nil? + raise RuntimeError.new('Cannot build feed: no articles') if @item[:articles].empty? + raise RuntimeError.new('Cannot build feed: one or more articles doesn\'t have a date') if @item[:articles].any? { |a| a[:date].nil? } + @item[:last] = @item[:articles].first + end + + def rss_feed(params={}) + require 'builder' + require 'time' + prepare_feed params + # Create builder + buffer = '' + xml = Builder::XmlMarkup.new(:target => buffer, :indent => 2) + # Build feed + xml.instruct! + xml.rss(:version => '2.0') do + xml.channel do + xml.title @item[:title] + xml.language 'en-us' + xml.updated @item[:last][:date].rfc822 + xml.ttl '40' + xml.description + @item[:articles].each do |a| + xml.item do + xml.title a[:title] + xml.description @item[:content_proc].call(a) + xml.pubDate a[:date].rfc822 + xml.guid url_for(a) + xml.link url_for(a) + xml.author @site.config[:author] + xml.comments url_for(a)+'#comments' + a[:tags].each do |t| + xml.category t + end + end + end + end + buffer + end + end + + # Redefine atom_feed method + def atom_feed(params={}) + require 'builder' + require 'time' + prepare_feed params + buffer = '' + xml = Builder::XmlMarkup.new(:target => buffer, :indent => 2) + xml.instruct! + xml.feed(:xmlns => 'http://www.w3.org/2005/Atom') do + xml.id @site.config[:base_url] + '/' + xml.title @item[:title] + xml.updated @item[:last][:date].to_iso8601_time + xml.link(:rel => 'alternate', :href => @site.config[:base_url]) + xml.author do + xml.name @item[:author_name] + xml.uri @item[:author_uri] + end + @item[:articles].each do |a| + xml.entry do + xml.id atom_tag_for(a) + xml.title a[:title], :type => 'xhtml' + xml.published a[:date].to_iso8601_time + xml.updated a.mtime.to_iso8601_time + xml.link(:rel => 'alternate', :href => url_for(a)) + a[:tags].each do |t| + xml.category(:term => t, :scheme => "#{@site.config[:base_url]}/tags/#{t}/") + end + summary = @item[:excerpt_proc].call(a) + xml.summary summary, :type => 'xhtml' unless summary.nil? + xml.content @item[:content_proc].call(a), :type => 'xhtml' + end + end + end + buffer + end + + def atom_tag_for(item) + require 'time' + hostname = @site.config[:base_url].sub(/.*:\/\/(.+?)\/?$/, '\1') + formatted_date = item[:date].to_iso8601_date + 'tag:' + hostname + ',' + formatted_date + ':' + (item.reps[0].path || item.identifier) + end + + def latest_articles(max=nil) - total = @site.items.select{|p| p.attributes[:date] && p.attributes[:type] == 'article'}.sort{|a, b| a.attributes[:date] <=> b.attributes[:date]}.reverse + total = @site.items.select{|p| p.attributes[:type] == 'article'}.sort{|a, b| a.attributes[:date] <=> b.attributes[:date]}.reverse max ||= total.length total[0..max-1] end@@ -70,5 +165,5 @@
end include Nanoc3::Helpers::Tagging -include Nanoc3::Helpers::Site +include Nanoc3::Helpers::Blogging include Nanoc3::Helpers::Rendering