Class: Jekyll::Post

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

Direct Known Subclasses

Draft

Constant Summary collapse

MATCHER =

Valid post name regex.

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

Attributes for Liquid templates

EXCERPT_ATTRIBUTES_FOR_LIQUID.concat(%w[
  content
  excerpt
])

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Convertible

#converter, #do_layout, #output_ext, #render_all_layouts, #render_liquid, #to_liquid, #to_s, #transform, #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.



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

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

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

  if self.data.has_key?('date')
    self.date = Time.parse(self.data["date"].to_s)
  end

  self.published = self.published?

  self.populate_categories
  self.populate_tags
end

Instance Attribute Details

#categoriesObject

Returns the value of attribute categories.



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

def categories
  @categories
end

#contentObject

Returns the value of attribute content.



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

def content
  @content
end

#dataObject

Returns the value of attribute data.



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

def data
  @data
end

#dateObject

Returns the value of attribute date.



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

def date
  @date
end

#extObject

Returns the value of attribute ext.



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

def ext
  @ext
end

#extracted_excerptObject

Returns the value of attribute extracted_excerpt.



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

def extracted_excerpt
  @extracted_excerpt
end

#nameObject (readonly)

Returns the value of attribute name.



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

def name
  @name
end

#outputObject

Returns the value of attribute output.



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

def output
  @output
end

#publishedObject

Returns the value of attribute published.



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

def published
  @published
end

#siteObject

Returns the value of attribute site.



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

def site
  @site
end

#slugObject

Returns the value of attribute slug.



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

def slug
  @slug
end

#tagsObject

Returns the value of attribute tags.



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

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)


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

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



144
145
146
147
148
149
150
# File 'lib/jekyll/post.rb', line 144

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

#containing_dir(source, dir) ⇒ Object

Get the full path to the directory containing the post files



88
89
90
# File 'lib/jekyll/post.rb', line 88

def containing_dir(source, dir)
  return File.join(source, dir, '_posts')
end

#destination(dest) ⇒ Object

Obtain destination path.

dest - The String path to the destination dir.

Returns destination file path String.



267
268
269
270
271
272
# File 'lib/jekyll/post.rb', line 267

def destination(dest)
  # The url needs to be unescaped in order to preserve the correct filename
  path = File.join(dest, CGI.unescape(self.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.



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

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.



107
108
109
# File 'lib/jekyll/post.rb', line 107

def excerpt
  self.data.fetch('excerpt', self.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.



231
232
233
# File 'lib/jekyll/post.rb', line 231

def id
  File.join(self.dir, self.slug)
end

#inspectObject

Returns the shorthand String identifier of this Post.



275
276
277
# File 'lib/jekyll/post.rb', line 275

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

#nextObject



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

def next
  pos = self.site.posts.index(self)

  if pos && pos < self.site.posts.length-1
    self.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



129
130
131
# File 'lib/jekyll/post.rb', line 129

def path
  self.data.fetch('path', self.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.



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

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

#populate_categoriesObject



76
77
78
79
80
81
# File 'lib/jekyll/post.rb', line 76

def populate_categories
  if self.categories.empty?
    self.categories = self.data.pluralized_array('category', 'categories').map {|c| c.to_s.downcase}
  end
  self.categories.flatten!
end

#populate_tagsObject



83
84
85
# File 'lib/jekyll/post.rb', line 83

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

#previousObject



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

def previous
  pos = self.site.posts.index(self)
  if pos && pos > 0
    self.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.



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

def process(name)
  m, cats, date, slug, ext = *name.match(MATCHER)
  self.date = Time.parse(date)
  self.slug = slug
  self.ext = ext
rescue ArgumentError
  raise FatalException.new("Post #{name} does not have a valid date.")
end

#published?Boolean

Returns:

  • (Boolean)


68
69
70
71
72
73
74
# File 'lib/jekyll/post.rb', line 68

def published?
  if self.data.has_key?('published') && self.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.



98
99
100
101
# File 'lib/jekyll/post.rb', line 98

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

Calculate related posts.

Returns an Array of related Posts.



238
239
240
# File 'lib/jekyll/post.rb', line 238

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

#relative_pathObject

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



134
135
136
# File 'lib/jekyll/post.rb', line 134

def relative_path
  File.join(@dir, '_posts', @name)
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.



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

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

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

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

#templateObject



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

def template
  case self.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
    self.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



114
115
116
# File 'lib/jekyll/post.rb', line 114

def title
  self.data.fetch("title", self.titleized_slug)
end

#titleized_slugObject

Turns the post slug into a suitable title



119
120
121
# File 'lib/jekyll/post.rb', line 119

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

#urlObject

The generated relative url of this post.

Returns the String url.



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

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”



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

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