Module: Nanoc3::Helpers::Blogging
Nanoc3::Helpers::Blogging provides some functionality for building blogs, such as finding articles and constructing feeds.
This helper has a few requirements. First, all blog articles should have the following attributes:
- ‘kind’, set to ‘article’.
- ‘created_at’, set to the creation timestamp.
Some functions in this blogging helper, such as the atom_feed function, require additional attributes to be set; these attributes are described in the documentation for these functions.
The two main functions are sorted_articles and atom_feed.
To activate this helper, include it, like this:
include Nanoc3::Helpers::Blogging
Public Visibility
Public Instance Method Summary
| #articles |
Returns an unsorted list of articles. |
|---|---|
| #atom_feed(params = {}) |
Returns a string representing the atom feed containing recent articles, sorted by descending creation date. |
| #atom_tag_for(item) |
Returns an URI containing an unique ID for the given item. |
| #feed_url |
Returns the URL of the feed. |
| #sorted_articles |
Returns a list of articles, sorted by descending creation date (so newer articles appear first). |
| #url_for(item) |
Returns the URL for the given item. |
Public Instance Method Details
articles
Returns an unsorted list of articles.
27 28 29 |
# File 'lib/nanoc3/helpers/blogging.rb', line 27 def articles @items.select { |item| item[:kind] == 'article' } end |
atom_feed
Returns a string representing the atom feed containing recent articles, sorted by descending creation date. params is a hash where the following keys can be set:
| limit: | The maximum number of articles to show. Defaults to 5. |
| articles: | A list of articles to include in the feed. Defaults to the list of articles returned by the articles function. |
| content_proc: | A proc that returns the content of the given article, passed as a parameter. By default, given the argument article, this proc will return article.reps[0].content. This function may not return nil. |
| excerpt_proc: | A proc that returns the excerpt of the given article, passed as a parameter. By default, given the argument article, this proc will return article.excerpt. This function may return nil. |
The following attributes must be set on blog articles:
- ‘title’, containing the title of the blog post.
- all other attributes mentioned above.
The following attributes can optionally be set on blog articles to change the behaviour of the Atom feed:
- ‘excerpt’, containing an excerpt of the article, usually only a few lines long.
- ‘custom_path_in_feed’, containing the path that will be used instead of the normal path in the feed. This can be useful when including non-outputted items in a feed; such items could have their custom feed path set to the blog path instead, for example.
The feed will also include dates on which the articles were updated. These are generated automatically; the way this happens depends on the used data source (the filesystem data source checks the file mtimes, for instance).
The site configuration will need to have the following attributes:
- ‘base_url’, containing the URL to the site, without trailing slash. For example, if the site is at "http://example.com/", the base_url would be "http://example.com".
The feed item will need to have the following attributes:
- ‘title’, containing the title of the feed, which is usually also the title of the blog.
- ‘author_name’, containing the name of the item’s author. This will likely be a global attribute, unless the site is managed by several people/
- ‘author_uri’, containing the URI for the item’s author, such as the author’s web site URL. This will also likely be a global attribute.
The feed item can have the following optional attributes:
- ‘feed_url’, containing the custom URL of the feed. This can be useful when the private feed URL shouldn’t be exposed; for example, when using FeedBurner this would be set to the public FeedBurner URL.
To construct a feed, create a blank item with no layout, only the ‘erb’ (or ‘erubis’) filter, and an ‘xml’ extension. It may also be useful to set ‘is_hidden’ to true, so that helpers such as the sitemap helper will ignore the item. The content of the feed item should be:
<%= atom_feed %>
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/nanoc3/helpers/blogging.rb', line 110 def atom_feed(params={}) require 'builder' require 'time' # Extract parameters limit = params[:limit] || 5 relevant_articles = params[:articles] || articles || [] content_proc = params[:content_proc] || lambda { |a| a.reps[0].content_at_snapshot(:pre) } excerpt_proc = params[:excerpt_proc] || lambda { |a| a[:excerpt] } # Check config attributes if @site.config[:base_url].nil? raise RuntimeError.new('Cannot build Atom feed: site configuration has no base_url') end # Check feed item attributes if @item[:title].nil? raise RuntimeError.new('Cannot build Atom feed: feed item has no title') end if @item[:author_name].nil? raise RuntimeError.new('Cannot build Atom feed: feed item has no author_name') end if @item[:author_uri].nil? raise RuntimeError.new('Cannot build Atom feed: feed item has no author_uri') end # Check article attributes if relevant_articles.empty? raise RuntimeError.new('Cannot build Atom feed: no articles') end if relevant_articles.any? { |a| a[:created_at].nil? } raise RuntimeError.new('Cannot build Atom feed: one or more articles lack created_at') end # Get sorted relevant articles sorted_relevant_articles = relevant_articles.sort_by { |a| Time.parse(a[:created_at]) }.reverse.first(limit) # Get most recent article last_article = sorted_relevant_articles.first # Create builder buffer = '' xml = Builder::XmlMarkup.new(:target => buffer, :indent => 2) # Build feed xml.instruct! xml.feed(:xmlns => 'http://www.w3.org/2005/Atom') do # Add primary attributes xml.id @site.config[:base_url] + '/' xml.title @item[:title] # Add date xml.updated Time.parse(last_article[:created_at]).to_iso8601_time # Add links xml.link(:rel => 'alternate', :href => @site.config[:base_url]) xml.link(:rel => 'self', :href => feed_url) # Add author information xml. do xml.name @item[:author_name] xml.uri @item[:author_uri] end # Add articles sorted_relevant_articles.each do |a| xml.entry do # Add primary attributes xml.id atom_tag_for(a) xml.title a[:title], :type => 'html' # Add dates xml.published Time.parse(a[:created_at]).to_iso8601_time xml.updated a.mtime.to_iso8601_time # Add link xml.link(:rel => 'alternate', :href => url_for(a)) # Add content summary = excerpt_proc.call(a) xml.content content_proc.call(a), :type => 'html' xml.summary summary, :type => 'html' unless summary.nil? end end end buffer end |
atom_tag_for
Returns an URI containing an unique ID for the given item. This will be used in the Atom feed to uniquely identify articles. These IDs are created using a procedure suggested by Mark Pilgrim in this blog post: http://diveintomark.org/archives/2004/05/28/howto-atom-id.
215 216 217 218 219 220 221 222 |
# File 'lib/nanoc3/helpers/blogging.rb', line 215 def atom_tag_for(item) require 'time' hostname = @site.config[:base_url].sub(/.*:\/\/(.+?)\/?$/, '\1') formatted_date = Time.parse(item[:created_at]).to_iso8601_date 'tag:' + hostname + ',' + formatted_date + ':' + (item.reps[0].path || item.identifier) end |
feed_url
Returns the URL of the feed. It will return the custom feed URL if set, or otherwise the normal feed URL.
207 208 209 |
# File 'lib/nanoc3/helpers/blogging.rb', line 207 def feed_url @item[:feed_url] || @site.config[:base_url] + @item.reps[0].path end |
sorted_articles
Returns a list of articles, sorted by descending creation date (so newer articles appear first).
33 34 35 36 |
# File 'lib/nanoc3/helpers/blogging.rb', line 33 def sorted_articles require 'time' articles.sort_by { |a| Time.parse(a[:created_at]) }.reverse end |
url_for
Returns the URL for the given item. It will return the URL containing the custom path in the feed if possible, otherwise the normal path.
201 202 203 |
# File 'lib/nanoc3/helpers/blogging.rb', line 201 def url_for(item) @site.config[:base_url] + (item[:custom_path_in_feed] || item.reps[0].path) end |