Class: Jekyll::Post

Inherits:
Object
  • Object
show all
Includes:
Comparable, Convertible
Defined in:
lib/jekyll/post.rb

Direct Known Subclasses

Draft

Constant Summary

MATCHER =

Valid post name regex.

/^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
EXCERPT_ATTRIBUTES_FOR_LIQUID =
%w[
title
url
dir
date
id
categories
next
previous
tags
path
ATTRIBUTES_FOR_LIQUID =

Attributes for Liquid templates

EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[
content
excerpt

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Convertible

#[], #asset_file?, #coffeescript_file?, #converters, #do_layout, #invalid_layout?, #merged_file_read_opts, #output_ext, #place_in_layout?, #regenerate?, #render_all_layouts, #render_liquid, #render_with_liquid?, #sass_file?, #to_liquid, #to_s, #transform, #type, #write

Constructor Details

#initialize(site, source, dir, name) ⇒ Post

Initialize this Post instance.

site - The Site. base - The String path to the dir containing the post file. name - The String filename of the post file.

Returns the new Post.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/jekyll/post.rb', line 49

def initialize(site, source, dir, name)
  @site = site
  @dir = dir
  @base = containing_dir(dir)
  @name = name

  self.categories = dir.downcase.split('/').reject { |x| x.empty? }
  process(name)
  read_yaml(@base, name)

  data.default_proc = proc do |hash, key|
    site.frontmatter_defaults.find(File.join(dir, name), type, key)
  end

  if data.key?('date')
    self.date = Utils.parse_date(data["date"].to_s, "Post '#{relative_path}' does not have a valid date in the YAML front matter.")
  end

  populate_categories
  populate_tags
end

Instance Attribute Details

#categoriesObject

Returns the value of attribute categories



38
39
40
# File 'lib/jekyll/post.rb', line 38

def categories
  @categories
end

#contentObject

Returns the value of attribute content



37
38
39
# File 'lib/jekyll/post.rb', line 37

def content
  @content
end

#dataObject

Returns the value of attribute data



37
38
39
# File 'lib/jekyll/post.rb', line 37

def data
  @data
end

#dateObject

Returns the value of attribute date



38
39
40
# File 'lib/jekyll/post.rb', line 38

def date
  @date
end

#extObject

Returns the value of attribute ext



37
38
39
# File 'lib/jekyll/post.rb', line 37

def ext
  @ext
end

#extracted_excerptObject

Returns the value of attribute extracted_excerpt



37
38
39
# File 'lib/jekyll/post.rb', line 37

def extracted_excerpt
  @extracted_excerpt
end

#nameObject (readonly)

Returns the value of attribute name



40
41
42
# File 'lib/jekyll/post.rb', line 40

def name
  @name
end

#outputObject

Returns the value of attribute output



37
38
39
# File 'lib/jekyll/post.rb', line 37

def output
  @output
end

#siteObject

Returns the value of attribute site



36
37
38
# File 'lib/jekyll/post.rb', line 36

def site
  @site
end

#slugObject

Returns the value of attribute slug



38
39
40
# File 'lib/jekyll/post.rb', line 38

def slug
  @slug
end

#tagsObject

Returns the value of attribute tags



38
39
40
# File 'lib/jekyll/post.rb', line 38

def tags
  @tags
end

Class Method Details

.valid?(name) ⇒ Boolean

Post name validator. Post filenames must be like: 2008-11-05-my-awesome-post.textile

Returns true if valid, false if not.

Returns:

  • (Boolean)


32
33
34
# File 'lib/jekyll/post.rb', line 32

def self.valid?(name)
  name =~ MATCHER
end

Instance Method Details

#<=>(other) ⇒ Object

Compares Post objects. First compares the Post date. If the dates are equal, it compares the Post slugs.

other - The other Post we are comparing to.

Returns -1, 0, 1



147
148
149
150
151
152
153
# File 'lib/jekyll/post.rb', line 147

def <=>(other)
  cmp = self.date <=> other.date
  if 0 == cmp
   cmp = self.slug <=> other.slug
  end
  return cmp
end

#containing_dir(dir) ⇒ Object

Get the full path to the directory containing the post files



91
92
93
# File 'lib/jekyll/post.rb', line 91

def containing_dir(dir)
  site.in_source_dir(dir, '_posts')
end

#destination(dest) ⇒ Object

Obtain destination path.

dest - The String path to the destination dir.

Returns destination file path String.



269
270
271
272
273
274
# File 'lib/jekyll/post.rb', line 269

def destination(dest)
  # The url needs to be unescaped in order to preserve the correct filename
  path = site.in_dest_dir(dest, URL.unescape_path(url))
  path = File.join(path, "index.html") if path[/\.html?$/].nil?
  path
end

#dirObject

The generated directory into which the post will be placed upon generation. This is derived from the permalink or, if permalink is absent, set to the default date e.g. “/2008/11/05/” if the permalink style is :date, otherwise nothing.

Returns the String directory.



173
174
175
# File 'lib/jekyll/post.rb', line 173

def dir
  File.dirname(url)
end

#excerptObject

The post excerpt. This is either a custom excerpt set in YAML front matter or the result of extract_excerpt.

Returns excerpt string.



110
111
112
# File 'lib/jekyll/post.rb', line 110

def excerpt
  data.fetch('excerpt') { extracted_excerpt.to_s }
end

#idObject

The UID for this post (useful in feeds). e.g. /2008/11/05/my-awesome-post

Returns the String UID.



233
234
235
# File 'lib/jekyll/post.rb', line 233

def id
  File.join(dir, slug)
end

#inspectObject

Returns the shorthand String identifier of this Post.



277
278
279
# File 'lib/jekyll/post.rb', line 277

def inspect
  "<Post: #{id}>"
end

#nextObject



281
282
283
284
285
286
287
288
# File 'lib/jekyll/post.rb', line 281

def next
  pos = site.posts.index {|post| post.equal?(self) }
  if pos && pos < site.posts.length - 1
    site.posts[pos + 1]
  else
    nil
  end
end

#pathObject

Public: the path to the post relative to the site source,

from the YAML Front-Matter or from a combination of
the directory it's in, "_posts", and the name of the
post file

Returns the path to the file relative to the site source



132
133
134
# File 'lib/jekyll/post.rb', line 132

def path
  data.fetch('path') { relative_path.sub(/\A\//, '') }
end

The full path and filename of the post. Defined in the YAML of the post body (optional).

Returns the String permalink.



181
182
183
# File 'lib/jekyll/post.rb', line 181

def permalink
  data && data['permalink']
end

#populate_categoriesObject



79
80
81
82
83
84
# File 'lib/jekyll/post.rb', line 79

def populate_categories
  categories_from_data = Utils.pluralized_array_from_hash(data, 'category', 'categories')
  self.categories = (
    Array(categories) + categories_from_data
  ).map {|c| c.to_s.downcase}.flatten.uniq
end

#populate_tagsObject



86
87
88
# File 'lib/jekyll/post.rb', line 86

def populate_tags
  self.tags = Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
end

#previousObject



290
291
292
293
294
295
296
297
# File 'lib/jekyll/post.rb', line 290

def previous
  pos = site.posts.index {|post| post.equal?(self) }
  if pos && pos > 0
    site.posts[pos - 1]
  else
    nil
  end
end

#process(name) ⇒ Object

Extract information from the post filename.

name - The String filename of the post file.

Returns nothing.



160
161
162
163
164
165
# File 'lib/jekyll/post.rb', line 160

def process(name)
  m, cats, date, slug, ext = *name.match(MATCHER)
  self.date = Utils.parse_date(date, "Post '#{relative_path}' does not have a valid date in the filename.")
  self.slug = slug
  self.ext = ext
end

#published?Boolean

Returns:

  • (Boolean)


71
72
73
74
75
76
77
# File 'lib/jekyll/post.rb', line 71

def published?
  if data.key?('published') && data['published'] == false
    false
  else
    true
  end
end

#read_yaml(base, name) ⇒ Object

Read the YAML frontmatter.

base - The String path to the dir containing the file. name - The String filename of the file.

Returns nothing.



101
102
103
104
# File 'lib/jekyll/post.rb', line 101

def read_yaml(base, name)
  super(base, name)
  self.extracted_excerpt = extract_excerpt
end

Calculate related posts.

Returns an Array of related Posts.



240
241
242
# File 'lib/jekyll/post.rb', line 240

def related_posts(posts)
  Jekyll::RelatedPosts.new(self).build
end

#relative_pathObject

The path to the post source file, relative to the site source



137
138
139
# File 'lib/jekyll/post.rb', line 137

def relative_path
  File.join(*[@dir, "_posts", @name].map(&:to_s).reject(&:empty?))
end

#render(layouts, site_payload) ⇒ Object

Add any necessary layouts to this post.

layouts - A Hash of => “layout”. site_payload - The site payload hash.

Returns nothing.



250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/jekyll/post.rb', line 250

def render(layouts, site_payload)
  # construct payload
  payload = Utils.deep_merge_hashes({
    "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
    "page" => to_liquid(self.class::EXCERPT_ATTRIBUTES_FOR_LIQUID)
  }, site_payload)

  if generate_excerpt?
    extracted_excerpt.do_layout(payload, {})
  end

  do_layout(payload.merge({"page" => to_liquid}), layouts)
end

#templateObject



185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/jekyll/post.rb', line 185

def template
  case site.permalink_style
  when :pretty
    "/:categories/:year/:month/:day/:title/"
  when :none
    "/:categories/:title.html"
  when :date
    "/:categories/:year/:month/:day/:title.html"
  when :ordinal
    "/:categories/:year/:y_day/:title.html"
  else
    site.permalink_style.to_s
  end
end

#titleObject

Public: the Post title, from the YAML Front-Matter or from the slug

Returns the post title



117
118
119
# File 'lib/jekyll/post.rb', line 117

def title
  data.fetch('title') { titleized_slug }
end

#titleized_slugObject

Turns the post slug into a suitable title



122
123
124
# File 'lib/jekyll/post.rb', line 122

def titleized_slug
  slug.split('-').select {|w| w.capitalize! || w }.join(' ')
end

#urlObject

The generated relative url of this post.

Returns the String url.



203
204
205
206
207
208
209
# File 'lib/jekyll/post.rb', line 203

def url
  @url ||= URL.new({
    :template => template,
    :placeholders => url_placeholders,
    :permalink => permalink
  }).to_s
end

#url_placeholdersObject

Returns a hash of URL placeholder names (as symbols) mapping to the desired placeholder replacements. For details see “url.rb”



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/jekyll/post.rb', line 213

def url_placeholders
  {
    :year        => date.strftime("%Y"),
    :month       => date.strftime("%m"),
    :day         => date.strftime("%d"),
    :title       => slug,
    :i_day       => date.strftime("%-d"),
    :i_month     => date.strftime("%-m"),
    :categories  => (categories || []).map { |c| c.to_s }.join('/'),
    :short_month => date.strftime("%b"),
    :short_year  => date.strftime("%y"),
    :y_day       => date.strftime("%j"),
    :output_ext  => output_ext
  }
end