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+)-(.*)(\.[^.]+)$/

Class Attribute Summary (collapse)

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Convertible

#converter, #do_layout, #output_ext, #to_s, #write

Constructor Details

- (Post) initialize(site, source, dir, name)

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.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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 34

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)
  begin
    self.read_yaml(@base, name)
  rescue Exception => msg
    raise FatalException.new("#{msg} in #{@base}/#{name}")
  end

  # If we've added a date and time to the YAML, use that instead of the
  # filename date. Means we'll sort correctly.
  if self.data.has_key?('date')
    # ensure Time via to_s and reparse
    self.date = Time.parse(self.data["date"].to_s)
  end

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

  self.tags = self.data.pluralized_array("tag", "tags")

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

  self.tags.flatten!
  self.categories.flatten!
end

Class Attribute Details

+ (Object) lsi

Returns the value of attribute lsi



7
8
9
# File 'lib/jekyll/post.rb', line 7

def lsi
  @lsi
end

Instance Attribute Details

- (Object) categories

Returns the value of attribute categories



23
24
25
# File 'lib/jekyll/post.rb', line 23

def categories
  @categories
end

- (Object) content

Returns the value of attribute content



22
23
24
# File 'lib/jekyll/post.rb', line 22

def content
  @content
end

- (Object) data

Returns the value of attribute data



22
23
24
# File 'lib/jekyll/post.rb', line 22

def data
  @data
end

- (Object) date

Returns the value of attribute date



23
24
25
# File 'lib/jekyll/post.rb', line 23

def date
  @date
end

- (Object) ext

Returns the value of attribute ext



22
23
24
# File 'lib/jekyll/post.rb', line 22

def ext
  @ext
end

- (Object) extracted_excerpt

Returns the value of attribute extracted_excerpt



22
23
24
# File 'lib/jekyll/post.rb', line 22

def extracted_excerpt
  @extracted_excerpt
end

- (Object) name (readonly)

Returns the value of attribute name



25
26
27
# File 'lib/jekyll/post.rb', line 25

def name
  @name
end

- (Object) output

Returns the value of attribute output



22
23
24
# File 'lib/jekyll/post.rb', line 22

def output
  @output
end

- (Object) published

Returns the value of attribute published



23
24
25
# File 'lib/jekyll/post.rb', line 23

def published
  @published
end

- (Object) site

Returns the value of attribute site



21
22
23
# File 'lib/jekyll/post.rb', line 21

def site
  @site
end

- (Object) slug

Returns the value of attribute slug



23
24
25
# File 'lib/jekyll/post.rb', line 23

def slug
  @slug
end

- (Object) tags

Returns the value of attribute tags



23
24
25
# File 'lib/jekyll/post.rb', line 23

def tags
  @tags
end

Class Method Details

+ (Boolean) valid?(name)

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

Returns true if valid, false if not.

Returns:

  • (Boolean)


17
18
19
# File 'lib/jekyll/post.rb', line 17

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

Instance Method Details

- (Object) <=>(other)

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



105
106
107
108
109
110
111
# File 'lib/jekyll/post.rb', line 105

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

- (Object) containing_dir(source, dir)

Get the full path to the directory containing the post files



72
73
74
# File 'lib/jekyll/post.rb', line 72

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

- (Object) destination(dest)

Obtain destination path.

dest - The String path to the destination dir.

Returns destination file path String.



254
255
256
257
258
259
# File 'lib/jekyll/post.rb', line 254

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 template[/\.html$/].nil?
  path
end

- (Object) dir

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.



141
142
143
# File 'lib/jekyll/post.rb', line 141

def dir
  File.dirname(url)
end

- (Object) excerpt

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

Returns excerpt string.



91
92
93
94
95
96
97
# File 'lib/jekyll/post.rb', line 91

def excerpt
  if self.data.has_key? 'excerpt'
    self.data['excerpt']
  else
    self.extracted_excerpt
  end
end

- (Object) id

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

Returns the String UID.



204
205
206
# File 'lib/jekyll/post.rb', line 204

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

- (Object) inspect

Returns the shorthand String identifier of this Post.



280
281
282
# File 'lib/jekyll/post.rb', line 280

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

- (Object) next



284
285
286
287
288
289
290
291
292
# File 'lib/jekyll/post.rb', line 284

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

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

Returns the String permalink.



149
150
151
# File 'lib/jekyll/post.rb', line 149

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

- (Object) previous



294
295
296
297
298
299
300
301
# File 'lib/jekyll/post.rb', line 294

def previous
  pos = self.site.posts.index(self)
  if pos && pos > 0
    self.site.posts[pos-1]
  else
    nil
  end
end

- (Object) process(name)

Extract information from the post filename.

name - The String filename of the post file.

Returns nothing.



118
119
120
121
122
123
124
125
# File 'lib/jekyll/post.rb', line 118

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

- (Object) read_yaml(base, name)

Read the YAML frontmatter.

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

Returns nothing.



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

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

Calculate related posts.

Returns an Array of related Posts.



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

def related_posts(posts)
  return [] unless posts.size > 1

  if self.site.lsi
    self.class.lsi ||= begin
      puts "Starting the classifier..."
      lsi = Classifier::LSI.new(:auto_rebuild => false)
      $stdout.print("  Populating LSI... ");$stdout.flush
      posts.each { |x| $stdout.print(".");$stdout.flush;lsi.add_item(x) }
      $stdout.print("\n  Rebuilding LSI index... ")
      lsi.build_index
      puts ""
      lsi
    end

    related = self.class.lsi.find_related(self.content, 11)
    related - [self]
  else
    (posts - [self])[0..9]
  end
end

- (Object) render(layouts, site_payload)

Add any necessary layouts to this post.

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

Returns nothing.



239
240
241
242
243
244
245
246
247
# File 'lib/jekyll/post.rb', line 239

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

  do_layout(payload, layouts)
end

- (Object) template



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/jekyll/post.rb', line 153

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

- (Object) to_liquid

Convert this post into a Hash for use in Liquid templates.

Returns the representative Hash.



264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/jekyll/post.rb', line 264

def to_liquid
  self.data.deep_merge({
    "title"      => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '),
    "url"        => self.url,
    "date"       => self.date,
    "id"         => self.id,
    "categories" => self.categories,
    "next"       => self.next,
    "previous"   => self.previous,
    "tags"       => self.tags,
    "content"    => self.content,
    "excerpt"    => self.excerpt,
    "path"       => self.data['path'] || File.join(@dir, '_posts', @name).sub(/\A\//, '') })
end

- (Object) transform

Transform the contents and excerpt based on the content type.

Returns nothing.



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

def transform
  super
  self.extracted_excerpt = converter.convert(self.extracted_excerpt)
end

- (Object) url

The generated relative url of this post. e.g. /2008/11/05/my-awesome-post.html

Returns the String URL.



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
# File 'lib/jekyll/post.rb', line 172

def url
  return @url if @url

  url = if permalink
    permalink
  else
    {
      "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
    }.inject(template) { |result, token|
      result.gsub(/:#{Regexp.escape token.first}/, token.last)
    }.gsub(/\/\//, "/")
  end

  # sanitize url
  @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
  @url += "/" if url =~ /\/$/
  @url
end