Module: Middleman::Blog::BlogArticle

Extended by:
Gem::Deprecate
Defined in:
lib/middleman-blog/blog_article.rb

Overview

A module that adds blog-article-specific methods to Resources. A BlogArticle can be retrieved via Helpers#current_article or methods on BlogData (like Middleman::Blog::BlogData#articles).

Instance Method Summary collapse

Instance Method Details

#article_locale_nextMiddleman::Sitemap::Resource

The next (chronologically later) article after this one in the current locale or nil if this is the most recent article.

Returns:

  • (Middleman::Sitemap::Resource)


320
321
322
# File 'lib/middleman-blog/blog_article.rb', line 320

def article_locale_next
  blog_data.local_articles.reverse.find { |a| a.date > date }
end

#article_locale_previousBlogArticle

The previous (chronologically earlier) article before this one in the current locale, or nil if this is the first article.

Returns:



310
311
312
# File 'lib/middleman-blog/blog_article.rb', line 310

def article_locale_previous
  blog_data.local_articles.find { |a| a.date < date }
end

#article_nextMiddleman::Sitemap::Resource

The next (chronologically later) article after this one or nil if this is the most recent article.

Returns:

  • (Middleman::Sitemap::Resource)


300
301
302
# File 'lib/middleman-blog/blog_article.rb', line 300

def article_next
  blog_data.articles.reverse.find { |a| a.date > date }
end

#article_previousBlogArticle

The previous (chronologically earlier) article before this one or nil if this is the first article.

Returns:



290
291
292
# File 'lib/middleman-blog/blog_article.rb', line 290

def article_previous
  blog_data.articles.find { |a| a.date < date }
end

#blog_dataBlogData

A reference to the Middleman::Blog::BlogData for this article’s blog.

Returns:



31
32
33
# File 'lib/middleman-blog/blog_article.rb', line 31

def blog_data
  blog_controller.data
end

#blog_optionsConfigurationManager

The options for this article’s blog.

Returns:

  • (ConfigurationManager)


40
41
42
# File 'lib/middleman-blog/blog_article.rb', line 40

def blog_options
  blog_controller.options
end

#bodyString

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.

Returns:

  • (String)


98
99
100
# File 'lib/middleman-blog/blog_article.rb', line 98

def body
  render layout: false
end

#dateTimeWithZone

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.

Returns:

  • (TimeWithZone)


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
# File 'lib/middleman-blog/blog_article.rb', line 202

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

#default_summary_generator(rendered, length, ellipsis) ⇒ Object

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.

Parameters:

  • rendered (String)

    The rendered blog article

  • length (Integer)

    The length in characters to truncate to. -1 or nil will return the whole article.

  • ellipsis (String)

    The ellipsis string to use when content is trimmed.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/middleman-blog/blog_article.rb', line 138

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

#localeSymbol Also known as: lang

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.

Returns:

  • (Symbol)

    Language code (for example, :en or :de)



180
181
182
183
184
185
186
187
188
189
190
# File 'lib/middleman-blog/blog_article.rb', line 180

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

#next_articleMiddleman::Sitemap::Resource

Deprecated.

Use #article_next instead.

The next (chronologically later) article after this one or nil if this is the most recent article.

Returns:

  • (Middleman::Sitemap::Resource)


279
280
281
# File 'lib/middleman-blog/blog_article.rb', line 279

def next_article
  article_next
end

#previous_articleBlogArticle

Deprecated.

Use #article_previous instead.

The previous (chronologically earlier) article before this one or nil if this is the first article.

Returns:



266
267
268
# File 'lib/middleman-blog/blog_article.rb', line 266

def previous_article
  article_previous
end

#published?Boolean

Whether or not this article has been published. An article is considered published in the following scenarios:

  1. Frontmatter does not set published to false and either

  2. The blog option publish_future_dated is true or

  3. The article’s date is after the current time

Returns:

  • (Boolean)


87
88
89
# File 'lib/middleman-blog/blog_article.rb', line 87

def published?
  data['published'] != false && (blog_options.publish_future_dated || date <= Time.current)
end

#render(opts = {}, locs = {}, &block) ⇒ String

Render this resource to a string with the appropriate layout. Called automatically by Middleman.

Returns:

  • (String)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/middleman-blog/blog_article.rb', line 50

def render(opts = {}, locs = {}, &block)
  unless opts.key?(:layout)

    opts[:layout] = [: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

#slugString

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.

Returns:

  • (String)


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/middleman-blog/blog_article.rb', line 242

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

#summary(length = nil, ellipsis = '...') ⇒ String

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.

Parameters:

  • length (Number) (defaults to: nil)

    How many characters to trim the summary to.

  • ellipsis (String) (defaults to: '...')

    The ellipsis string to use when content is trimmed.

Returns:

  • (String)


118
119
120
121
122
123
124
125
126
# File 'lib/middleman-blog/blog_article.rb', line 118

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

#tagsArray<String>

A list of tags for this article, set from frontmatter.

Returns:

  • (Array<String>)

    (never nil)



161
162
163
164
165
166
167
168
169
# File 'lib/middleman-blog/blog_article.rb', line 161

def tags
   = data['tags']

  if .is_a? String
    .split(',').map(&:strip)
  else
    Array().map(&:to_s)
  end
end

#titleString

The title of the article, set from frontmatter.

Returns:

  • (String)


73
74
75
# File 'lib/middleman-blog/blog_article.rb', line 73

def title
  data['title'].to_s
end