module Middleman::Blog::BlogArticle
A module that adds blog-article-specific methods to Resources. A {BlogArticle} can be retrieved via {Blog::Helpers#current_article} or methods on {BlogData} (like {BlogData#articles}).
@see rdoc.info/github/middleman/middleman/Middleman/Sitemap/Resource Middleman::Sitemap::Resource
Public Class Methods
# File lib/middleman-blog/blog_article.rb, line 20 def self.extended(base) base.class.send(:attr_accessor, :blog_controller) end
Public Instance Methods
The next (chronologically later) article after this one in the current locale or nil
if this is the most recent article.
@return [Middleman::Sitemap::Resource]
# File lib/middleman-blog/blog_article.rb, line 318 def article_locale_next blog_data.local_articles.reverse.find { |a| a.date > date } end
The previous (chronologically earlier) article before this one in the current locale, or nil
if this is the first article.
@return [BlogArticle]
# File lib/middleman-blog/blog_article.rb, line 308 def article_locale_previous blog_data.local_articles.find { |a| a.date < date } end
The next (chronologically later) article after this one or nil
if this is the most recent article.
@return [Middleman::Sitemap::Resource]
# File lib/middleman-blog/blog_article.rb, line 298 def article_next blog_data.articles.reverse.find { |a| a.date > date } end
The previous (chronologically earlier) article before this one or nil
if this is the first article.
@return [BlogArticle]
# File lib/middleman-blog/blog_article.rb, line 288 def article_previous blog_data.articles.find { |a| a.date < date } end
A reference to the {BlogData} for this article's blog.
@return [BlogData]
# File lib/middleman-blog/blog_article.rb, line 29 def blog_data blog_controller.data end
The options for this article's blog.
@return [ConfigurationManager]
# File lib/middleman-blog/blog_article.rb, line 38 def blog_options blog_controller.options end
The body of this article, in HTML (no layout). This is for things like RSS feeds or lists of articles - individual articles will automatically be rendered from their template.
@return [String]
# File lib/middleman-blog/blog_article.rb, line 96 def body render layout: false end
Attempt to figure out the date of the post. The date should be present in the source path, but users may also provide a date in the frontmatter in order to provide a time of day for sorting reasons.
@return [TimeWithZone]
# File lib/middleman-blog/blog_article.rb, line 200 def date return @_date if @_date frontmatter_date = data['date'] # First get the date from frontmatter @_date = if frontmatter_date.is_a? Time frontmatter_date.in_time_zone else Time.zone.parse(frontmatter_date.to_s) end # Next figure out the date from the filename source_vars = blog_data.source_template.variables if source_vars.include?('year') && source_vars.include?('month') && source_vars.include?('day') filename_date = Time.zone.local(path_part('year').to_i, path_part('month').to_i, path_part('day').to_i) if @_date raise "The date in #{path}'s filename doesn't match the date in its frontmatter" unless @_date.to_date == filename_date.to_date else @_date = filename_date.to_time.in_time_zone end end raise "Blog post #{path} needs a date in its filename or frontmatter" unless @_date @_date end
The default summary generator first tries to find the summary_separator
and take the text before it. If that doesn't work, it will truncate text without splitting the middle of an HTML tag, using a Nokogiri-based {TruncateHTML} utility.
@param [String] rendered The rendered blog article @param [Integer] length The length in characters to truncate to.
-1 or +nil+ will return the whole article.
@param [String] ellipsis The ellipsis string to use when content is trimmed.
# File lib/middleman-blog/blog_article.rb, line 136 def default_summary_generator(rendered, length, ellipsis) if blog_options.summary_separator && rendered.match(blog_options.summary_separator) require 'middleman-blog/truncate_html' TruncateHTML.truncate_at_separator(rendered, blog_options.summary_separator) elsif length && length >= 0 require 'middleman-blog/truncate_html' TruncateHTML.truncate_at_length(rendered, length, ellipsis) elsif blog_options.summary_length&.positive? require 'middleman-blog/truncate_html' TruncateHTML.truncate_at_length(rendered, blog_options.summary_length, ellipsis) else rendered end end
This is here to prevent out-of-memory on exceptions.
@private
# File lib/middleman-blog/blog_article.rb, line 327 def inspect "#<Middleman::Blog::BlogArticle: #{data.inspect}>" end
The language of the article. The language can be present in the frontmatter or in the source path. If both are present, they must match. If neither specifies a lang, I18n's default_locale will be used. If lang
is set to nil, or the :i18n
extension is not activated at all, nil
will be returned.
@return [Symbol] Language code (for example, :en
or :de
)
# File lib/middleman-blog/blog_article.rb, line 178 def locale frontmatter_locale = data['locale'] || data['lang'] filename_locale = path_part('locale') || path_part('lang') raise "The locale in #{path}'s filename (#{filename_locale.inspect}) doesn't match the lang in its frontmatter (#{frontmatter_locale.inspect})" if frontmatter_locale && filename_locale && frontmatter_locale != filename_locale default_locale = I18n.default_locale if defined? ::I18n found_locale = frontmatter_locale || filename_locale || default_locale found_locale&.to_sym end
The next (chronologically later) article after this one or nil
if this is the most recent article.
@deprecated Use {#article_next} instead.
@return [Middleman::Sitemap::Resource]
# File lib/middleman-blog/blog_article.rb, line 277 def next_article article_next end
The previous (chronologically earlier) article before this one or nil
if this is the first article.
@deprecated Use {#article_previous} instead.
@return [BlogArticle]
# File lib/middleman-blog/blog_article.rb, line 264 def previous_article article_previous end
Whether or not this article has been published. An article is considered published in the following scenarios:
-
Frontmatter does not set
published
to false and either -
The blog option
publish_future_dated
is true or -
The article's date is after the current time
@return [Boolean]
# File lib/middleman-blog/blog_article.rb, line 85 def published? data['published'] != false && (blog_options.publish_future_dated || date <= Time.current) end
Render this resource to a string with the appropriate layout. Called automatically by Middleman
.
@return [String]
# File lib/middleman-blog/blog_article.rb, line 48 def render(opts = {}, locs = {}, &block) unless opts.key?(:layout) opts[:layout] = metadata[:options][:layout] opts[:layout] = blog_options.layout if opts[:layout].nil? || opts[:layout] == :_auto_layout # Convert to a string unless it's a boolean opts[:layout] = opts[:layout].to_s if opts[:layout].is_a? Symbol end content = super(opts, locs, &block) content.sub!(blog_options.summary_separator, '') unless opts[:keep_separator] content end
The “slug” of the article that shows up in its URL. The article slug is a parametrized version of the {#title} (lowercase, spaces replaced with dashes, etc) and can be used in the blog permalink
as :title
.
@return [String]
# File lib/middleman-blog/blog_article.rb, line 240 def slug if data['slug'] Blog::UriTemplates.safe_parameterize(data['slug']) elsif blog_data.source_template.variables.include?('title') Blog::UriTemplates.safe_parameterize(path_part('title')) elsif title Blog::UriTemplates.safe_parameterize(title) else raise "Can't generate a slug for #{path} because it has no :title in its path pattern or title/slug in its frontmatter." end end
The summary for this article, in HTML.
The blog option summary_generator
can be set to a Proc
in order to provide custom summary generation. The Proc
is provided the rendered content of the article (without layout), the desired length to trim the summary to, and the ellipsis string to use. Otherwise the {#default_summary_generator} will be used, which returns either everything before the summary separator (set via the blog option summary_separator
and defaulting to “READMORE”) if it is found, or the first summary_length
characters of the post.
@param [Number] length How many characters to trim the summary to. @param [String] ellipsis The ellipsis string to use when content is trimmed. @return [String]
# File lib/middleman-blog/blog_article.rb, line 116 def summary(length = nil, ellipsis = '...') rendered = render layout: false, keep_separator: true if blog_options.summary_generator blog_options.summary_generator.call(self, rendered, length, ellipsis) else default_summary_generator(rendered, length, ellipsis) end end
The title of the article, set from frontmatter.
@return [String]
# File lib/middleman-blog/blog_article.rb, line 71 def title data['title'].to_s end
Private Instance Methods
Retrieve a section of the source path template.
@param [String] part The part of the path, e.g. “lang”, “year”, “month”, “day”, “title” @return [String]
# File lib/middleman-blog/blog_article.rb, line 339 def path_part(part) @_path_parts ||= Blog::UriTemplates.extract_params(blog_data.source_template, path) @_path_parts[part.to_s] end