Module: Nanoc3::Helpers::Blogging
- Defined in:
- lib/nanoc3/helpers/blogging.rb
Overview
Provides 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` - The article’s publication 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.
All “time” item attributes, site configuration attributes or method parameters can either be a ‘Time` instance or a string in any format parseable by `Time.parse`.
The two main functions are #sorted_articles and #atom_feed.
Instance Method Summary collapse
-
#articles ⇒ Array
Returns an unsorted list of articles, i.e.
-
#atom_feed(params = {}) ⇒ String
Returns a string representing the atom feed containing recent articles, sorted by descending creation date.
-
#atom_tag_for(item) ⇒ String
Returns an URI containing an unique ID for the given item.
-
#attribute_to_time(time) ⇒ Time
Converts the given attribute (which can be a string, a Time or a Date) into a Time.
-
#feed_url ⇒ String
Returns the URL of the feed.
-
#sorted_articles ⇒ Array
Returns a sorted list of articles, i.e.
-
#url_for(item) ⇒ String
Returns the URL for the given item.
Instance Method Details
#articles ⇒ Array
Returns an unsorted list of articles, i.e. items where the ‘kind` attribute is set to `“article”`.
30 31 32 |
# File 'lib/nanoc3/helpers/blogging.rb', line 30 def articles @items.select { |item| item[:kind] == 'article' } end |
#atom_feed(params = {}) ⇒ String
Returns a string representing the atom feed containing recent articles, sorted by descending creation date.
The following attributes must be set on blog articles:
-
‘title` - The title of the blog post
-
‘kind` and `created_at` (described above)
The following attributes can optionally be set on blog articles to change the behaviour of the Atom feed:
-
‘excerpt` - An excerpt of the article, which is usually only a few lines long.
-
‘custom_path_in_feed` - 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.
-
‘custom_url_in_feed` - The url that will be used instead of the normal url in the feed (generated from the site’s base url + the item rep’s path). This can be useful when building a link-blog where the URL of article is a remote location.
-
‘updated_at` - The time when the article was last modified. If this attribute is not present, the `created_at` attribute will be used as the time when the article was last modified.
The site configuration will need to have the following attributes:
-
‘base_url` - The URL to the site, without trailing slash. For example, if the site is at “example.com/”, the `base_url` would be “example.com”.
The feed item will need to know about the feed title, the feed author name, and the URI corresponding to the author. These can be specified using parameters, as attributes in the feed item, or in the site configuration.
-
‘title` - The title of the feed, which is usually also the title of the blog.
-
‘author_name` - The name of the item’s author.
-
‘author_uri` - The URI for the item’s author, such as the author’s web site URL.
The feed item can have the following optional attributes:
-
‘feed_url` - 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 new item and make sure that it is filtered with ‘:erb` or `:erubis`; it should not be laid out. Ensure that it is routed to the proper path, e.g. `/blog.xml`. It may also be useful to set the `is_hidden` attribute to true, so that helpers such as the sitemap helper will ignore the item. The content of the feed item should be `<%= atom_feed %>`.
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 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/nanoc3/helpers/blogging.rb', line 145 def atom_feed(params={}) require 'builder' # Extract parameters limit = params[:limit] || 5 relevant_articles = params[:articles] || articles || [] content_proc = params[:content_proc] || lambda { |a| a.compiled_content(: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 title = params[:title] || @item[:title] || @site.config[:title] if title.nil? raise RuntimeError.new('Cannot build Atom feed: no title in params, item or site config') end = params[:author_name] || @item[:author_name] || @site.config[:author_name] if .nil? raise RuntimeError.new('Cannot build Atom feed: no author_name in params, item or site config') end = params[:author_uri] || @item[:author_uri] || @site.config[:author_uri] if .nil? raise RuntimeError.new('Cannot build Atom feed: no author_uri in params, item or site config') 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 do |a| attribute_to_time(a[:created_at]) end.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 root_url = @site.config[:base_url] + '/' # Add primary attributes xml.id root_url xml.title title # Add date xml.updated(attribute_to_time(last_article[:created_at]).to_iso8601_time) # Add links xml.link(:rel => 'alternate', :href => root_url) xml.link(:rel => 'self', :href => feed_url) # Add author information xml. do xml.name xml.uri end # Add articles sorted_relevant_articles.each do |a| # Get URL url = url_for(a) next if url.nil? xml.entry do # Add primary attributes xml.id atom_tag_for(a) xml.title a[:title], :type => 'html' # Add dates xml.published attribute_to_time(a[:created_at]).to_iso8601_time xml.updated attribute_to_time(a[:updated_at] || a[:created_at]).to_iso8601_time # Add specific author information if a[:author_name] || a[:author_uri] xml. do xml.name a[:author_name] || xml.uri a[:author_uri] || end end # Add link xml.link(:rel => 'alternate', :href => url) # 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(item) ⇒ String
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 and described in his
- “How to make a good ID in Atom” blog post
296 297 298 299 300 301 302 |
# File 'lib/nanoc3/helpers/blogging.rb', line 296 def atom_tag_for(item) hostname, base_dir = %r{^.+?://([^/]+)(.*)$}.match(@site.config[:base_url])[1..2] formatted_date = attribute_to_time(item[:created_at]).to_iso8601_date 'tag:' + hostname + ',' + formatted_date + ':' + base_dir + (item.path || item.identifier) end |
#attribute_to_time(time) ⇒ Time
Converts the given attribute (which can be a string, a Time or a Date) into a Time.
311 312 313 314 315 |
# File 'lib/nanoc3/helpers/blogging.rb', line 311 def attribute_to_time(time) time = Time.local(time.year, time.month, time.day) if time.is_a?(Date) time = Time.parse(time) if time.is_a?(String) time end |
#feed_url ⇒ String
Returns the URL of the feed. It will return the custom feed URL if set, or otherwise the normal feed URL.
278 279 280 281 282 283 284 285 |
# File 'lib/nanoc3/helpers/blogging.rb', line 278 def feed_url # Check attributes if @site.config[:base_url].nil? raise RuntimeError.new('Cannot build Atom feed: site configuration has no base_url') end @item[:feed_url] || @site.config[:base_url] + @item.path end |
#sorted_articles ⇒ Array
Returns a sorted list of articles, i.e. items where the ‘kind` attribute is set to `“article”`. Articles are sorted by descending creation date, so newer articles appear before older articles.
39 40 41 42 43 |
# File 'lib/nanoc3/helpers/blogging.rb', line 39 def sorted_articles articles.sort_by do |a| attribute_to_time(a[:created_at]) end.reverse end |
#url_for(item) ⇒ String
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.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/nanoc3/helpers/blogging.rb', line 258 def url_for(item) # Check attributes if @site.config[:base_url].nil? raise RuntimeError.new('Cannot build Atom feed: site configuration has no base_url') end # Build URL if item[:custom_url_in_feed] item[:custom_url_in_feed] elsif item[:custom_path_in_feed] @site.config[:base_url] + item[:custom_path_in_feed] elsif item.path @site.config[:base_url] + item.path end end |