Class: Jekyll::Post

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

Constant Summary collapse

MATCHER =
/^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Convertible

#content_type, #do_layout, #read_yaml, #to_s, #transform

Constructor Details

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

Initialize this Post instance. site is the Site base is the String path to the dir containing the post file name is the String filename of the post file categories is an Array of Strings for the categories for this post

Returns



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

def initialize(site, source, dir, name)
  @site = site
  @base = File.join(source, dir, '_posts')
  @name = name

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

  #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')
  end
end

Class Attribute Details

.lsiObject

Returns the value of attribute lsi.



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

def lsi
  @lsi
end

Instance Attribute Details

#categoriesObject

Returns the value of attribute categories.



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

def categories
  @categories
end

#contentObject

Returns the value of attribute content.



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

def content
  @content
end

#dataObject

Returns the value of attribute data.



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

def data
  @data
end

#dateObject

Returns the value of attribute date.



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

def date
  @date
end

#extObject

Returns the value of attribute ext.



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

def ext
  @ext
end

#outputObject

Returns the value of attribute output.



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

def output
  @output
end

#publishedObject

Returns the value of attribute published.



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

def published
  @published
end

#siteObject

Returns the value of attribute site.



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

def site
  @site
end

#slugObject

Returns the value of attribute slug.



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

def slug
  @slug
end

#tagsObject

Returns the value of attribute tags.



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

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



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

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

Instance Method Details

#<=>(other) ⇒ Object

Spaceship is based on Post#date, slug

Returns -1, 0, 1



64
65
66
67
68
69
70
# File 'lib/jekyll/post.rb', line 64

def <=>(other)
  cmp = self.date <=> other.date
  if 0 == cmp
   cmp = self.slug <=> other.slug
  end
  return cmp
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



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

def dir
  File.dirname(url)
end

#inspectObject



219
220
221
# File 'lib/jekyll/post.rb', line 219

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

#nextObject



223
224
225
226
227
228
229
230
231
# File 'lib/jekyll/post.rb', line 223

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



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

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

#previousObject



233
234
235
236
237
238
239
240
# File 'lib/jekyll/post.rb', line 233

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 is the String filename of the post file

Returns nothing



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

def process(name)
  m, cats, date, slug, ext = *name.match(MATCHER)
  self.date = Time.parse(date)
  self.slug = slug
  self.ext = ext
end

Calculate related posts.

Returns []



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/jekyll/post.rb', line 144

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

  if self.site.lsi
    self.class.lsi ||= begin
      puts "Running the classifier... this could take a while."
      lsi = Classifier::LSI.new
      posts.each { |x| $stdout.print(".");$stdout.flush;lsi.add_item(x) }
      puts ""
      lsi
    end

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

#render(layouts, site_payload) ⇒ Object

Add any necessary layouts to this post layouts is a Hash of => "layout" site_payload is the site payload hash

Returns nothing



168
169
170
171
172
173
174
175
176
177
178
# File 'lib/jekyll/post.rb', line 168

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

  do_layout(payload, layouts)
end

#templateObject



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/jekyll/post.rb', line 102

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"
  else
    self.site.permalink_style.to_s
  end
end

#titleObject



215
216
217
# File 'lib/jekyll/post.rb', line 215

def title
  data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' ')
end

#to_erbObject

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

Returns



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

def to_erb
  { "title"      => self.title,
    "url"        => self.url,
    "date"       => self.date,
    "id"         => self.uid,
    "categories" => self.categories,
    "next"       => self.next,
    "previous"   => self.previous,
    "tags"       => self.tags,
    "content"    => self.content }.deep_merge(self.data)
end

#uidObject

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

Returns



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

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

#urlObject

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

Returns



119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/jekyll/post.rb', line 119

def url
  return permalink if permalink

  @url ||= {
    "year"       => date.strftime("%Y"),
    "month"      => date.strftime("%m"),
    "day"        => date.strftime("%d"),
    "title"      => CGI.escape(slug),
    "categories" => categories.join('/')
  }.inject(template) { |result, token|
    result.gsub(/:#{token.first}/, token.last)
  }.gsub(/\/\//, "/")
end

#write(dest) ⇒ Object

Write the generated post file to the destination directory. dest is the String path to the destination dir

Returns nothing



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

def write(dest)
  FileUtils.mkdir_p(File.join(dest, dir))

  # The url needs to be unescaped in order to preserve the correct filename
  path = File.join(dest, CGI.unescape(self.url))

  if template[/\.html$/].nil?
    FileUtils.mkdir_p(path)
    path = File.join(path, "index.html")
  end

  File.open(path, 'w') do |f|
    f.write(self.output)
  end
end