diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-06-27 23:19:22 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-06-27 23:19:22 +0200 |
| commit | b94de9fe8c30210469953bbd9880e9cbcc7a3ef5 (patch) | |
| tree | 1cc64d91634bf197fe12fa1c675ab0c92c1877a5 | |
| parent | 9a19a0494ef51cdac9a78e24d517ca48ba44c453 (diff) | |
rss: add per-tag Atom feed at /rss/tags/:tag/updates.xml
- rss#tag_updates action: filters Page.heads by tag name, default
locale, 20 items, same caching as updates feed
- tag_updates.xml.builder: Atom feed with CGI.escapeHTML on title
and summary, consistent with updates.xml.builder
- tags/show.html.erb: add subscription link above article list
- routes: two routes per existing pattern (format-less + .:format
constrained to /xml/)
| -rw-r--r-- | app/controllers/rss_controller.rb | 18 | ||||
| -rw-r--r-- | app/views/rss/tag_updates.xml.builder | 27 | ||||
| -rw-r--r-- | app/views/tags/show.html.erb | 6 | ||||
| -rw-r--r-- | config/routes.rb | 3 |
4 files changed, 54 insertions, 0 deletions
diff --git a/app/controllers/rss_controller.rb b/app/controllers/rss_controller.rb index 4b47218..489a732 100644 --- a/app/controllers/rss_controller.rb +++ b/app/controllers/rss_controller.rb | |||
| @@ -22,6 +22,24 @@ class RssController < ApplicationController | |||
| 22 | end | 22 | end |
| 23 | end | 23 | end |
| 24 | 24 | ||
| 25 | def tag_updates | ||
| 26 | expires_in 31.minutes, :public => true | ||
| 27 | |||
| 28 | I18n.locale = I18n.default_locale | ||
| 29 | @tag = params[:tag] | ||
| 30 | @items = Page.heads | ||
| 31 | .joins("JOIN taggings ON taggings.taggable_id = pages.id | ||
| 32 | AND taggings.taggable_type = 'Page' | ||
| 33 | AND taggings.context = 'tags'") | ||
| 34 | .joins("JOIN tags ON tags.id = taggings.tag_id") | ||
| 35 | .where("LOWER(tags.name) = ?", @tag.downcase) | ||
| 36 | .order("published_at DESC").limit(20) | ||
| 37 | |||
| 38 | respond_to do |format| | ||
| 39 | format.xml {} | ||
| 40 | end | ||
| 41 | end | ||
| 42 | |||
| 25 | def recent_changes | 43 | def recent_changes |
| 26 | @items = Page.where( | 44 | @items = Page.where( |
| 27 | "updated_at < ? AND updated_at > ?", Time.now, Time.now - 14.days | 45 | "updated_at < ? AND updated_at > ?", Time.now, Time.now - 14.days |
diff --git a/app/views/rss/tag_updates.xml.builder b/app/views/rss/tag_updates.xml.builder new file mode 100644 index 0000000..6491cfc --- /dev/null +++ b/app/views/rss/tag_updates.xml.builder | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | xml.instruct! | ||
| 2 | |||
| 3 | xml.feed(:xmlns => "http://www.w3.org/2005/Atom", "xml:base" => @host) do | ||
| 4 | xml.title("Chaos Computer Club: #{@tag}") | ||
| 5 | xml.link(:href => "#{@host}/") | ||
| 6 | xml.link(:rel => "self", :href => "#{@host}/rss/tags/#{@tag}/updates.xml") | ||
| 7 | xml.updated(@items.first.published_at.xmlschema) unless @items.empty? | ||
| 8 | xml.author do | ||
| 9 | xml.name("Chaos Computer Club e. V.") | ||
| 10 | end | ||
| 11 | xml.id("#{@host}/rss/tags/#{@tag}/updates") | ||
| 12 | |||
| 13 | @items.each do |item| | ||
| 14 | xml.entry do | ||
| 15 | xml.title(CGI.escapeHTML(item.title.to_s)) | ||
| 16 | xml.link( | ||
| 17 | :href => content_url(:page_path => item.node.unique_path), | ||
| 18 | :rel => "alternate", | ||
| 19 | :type => "text/html" | ||
| 20 | ) | ||
| 21 | xml.id(content_url(:page_path => item.node.feed_id)) | ||
| 22 | xml.updated(item.updated_at.xmlschema) | ||
| 23 | xml.published(item.published_at.xmlschema) | ||
| 24 | xml.summary(CGI.escapeHTML(item.abstract.to_s)) | ||
| 25 | end | ||
| 26 | end | ||
| 27 | end | ||
diff --git a/app/views/tags/show.html.erb b/app/views/tags/show.html.erb index b09cc15..3a23522 100644 --- a/app/views/tags/show.html.erb +++ b/app/views/tags/show.html.erb | |||
| @@ -1,5 +1,11 @@ | |||
| 1 | <h2><%= t(:show_tag_headline) %> »<%=h @tag %>«</h2> | 1 | <h2><%= t(:show_tag_headline) %> »<%=h @tag %>«</h2> |
| 2 | 2 | ||
| 3 | <p class="feed_link"> | ||
| 4 | <%= link_to "Subscribe to updates tagged »#{@tag}«", | ||
| 5 | rss_tag_url(:tag => @tag, :format => :xml), | ||
| 6 | :type => "application/atom+xml" %> | ||
| 7 | </p> | ||
| 8 | |||
| 3 | <%= | 9 | <%= |
| 4 | render( | 10 | render( |
| 5 | :partial => 'custom/partials/no_date_and_author', | 11 | :partial => 'custom/partials/no_date_and_author', |
diff --git a/config/routes.rb b/config/routes.rb index 2df9d46..92f2452 100644 --- a/config/routes.rb +++ b/config/routes.rb | |||
| @@ -70,6 +70,9 @@ Cccms::Application.routes.draw do | |||
| 70 | get 'rss/updates.:format', :to => 'rss#updates', :as => :rss_feed, | 70 | get 'rss/updates.:format', :to => 'rss#updates', :as => :rss_feed, |
| 71 | :constraints => { :format => /xml|rdf/ } | 71 | :constraints => { :format => /xml|rdf/ } |
| 72 | get 'rss/recent_changes', :to => 'rss#recent_changes' | 72 | get 'rss/recent_changes', :to => 'rss#recent_changes' |
| 73 | get 'rss/tags/:tag/updates', :to => 'rss#tag_updates', :as => :rss_tag | ||
| 74 | get 'rss/tags/:tag/updates.:format', :to => 'rss#tag_updates', :as => :rss_tag_feed, | ||
| 75 | :constraints => { :format => /xml/ } | ||
| 73 | 76 | ||
| 74 | match 'galleries/*page_path' => 'content#render_gallery', :via => :get | 77 | match 'galleries/*page_path' => 'content#render_gallery', :via => :get |
| 75 | match '/*page_path' => 'content#render_page', :as => :content, :via => :get | 78 | match '/*page_path' => 'content#render_page', :as => :content, :via => :get |
