class Moft::Post
Constants
- ATTRIBUTES_FOR_LIQUID
Attributes for Liquid templates
- MATCHER
Valid post name regex.
Attributes
Public Class Methods
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
.
# File lib/moft/post.rb, line 49 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
Public Instance Methods
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
# File lib/moft/post.rb, line 139 def <=>(other) cmp = self.date <=> other.date if 0 == cmp cmp = self.slug <=> other.slug end return cmp end
# File lib/moft/post.rb, line 258 def build_index # 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 end
Get the full path to the directory containing the post files
# File lib/moft/post.rb, line 89 def containing_dir(source, dir) return File.join(source, dir, '_posts') end
Obtain destination path.
dest - The String
path to the destination dir.
Returns destination file path String
.
# File lib/moft/post.rb, line 293 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
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.
# File lib/moft/post.rb, line 175 def dir File.dirname(url) end
The post excerpt. This is either a custom excerpt set in YAML front matter or the result of extract_excerpt.
Returns excerpt string.
# File lib/moft/post.rb, line 108 def excerpt if self.data.has_key? 'excerpt' self.data['excerpt'] else self.extracted_excerpt end end
The UID for this post (useful in feeds). e.g. /2008/11/05/my-awesome-post
Returns the String
UID.
# File lib/moft/post.rb, line 238 def id File.join(self.dir, self.slug) end
# File lib/moft/post.rb, line 315 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
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
# File lib/moft/post.rb, line 129 def path self.data['path'] || File.join(@dir, '_posts', @name).sub(/\A\//, '') end
The full path and filename of the post. Defined in the YAML of the post body (optional).
Returns the String
permalink.
# File lib/moft/post.rb, line 183 def permalink self.data && self.data['permalink'] end
# File lib/moft/post.rb, line 77 def populate_categories if self.categories.empty? self.categories = self.data.pluralized_array('category', 'categories').map {|c| c.downcase} end self.categories.flatten! end
# File lib/moft/post.rb, line 325 def previous pos = self.site.posts.index(self) if pos && pos > 0 self.site.posts[pos-1] else nil end end
Extract information from the post filename.
name - The String
filename of the post file.
Returns nothing.
# File lib/moft/post.rb, line 152 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
# File lib/moft/post.rb, line 69 def published? if self.data.has_key?('published') && self.data['published'] == false false else true end end
Read the YAML frontmatter.
base - The String
path to the dir containing the file. name - The String
filename of the file.
Returns nothing.
Moft::Convertible#read_yaml
# File lib/moft/post.rb, line 99 def read_yaml(base, name) super(base, name) self.extracted_excerpt = self.extract_excerpt end
Add any necessary layouts to this post.
layouts - A Hash
of {“name” => “layout”}. site_payload - The site payload hash.
Returns nothing.
# File lib/moft/post.rb, line 278 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
# File lib/moft/post.rb, line 187 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
Public: the Post
title, from the YAML Front-Matter or from the slug
Returns the post title
# File lib/moft/post.rb, line 119 def title self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' ') end
Transform the contents and excerpt based on the content type.
Returns nothing.
Moft::Convertible#transform
# File lib/moft/post.rb, line 164 def transform super self.extracted_excerpt = converter.convert(self.extracted_excerpt) end
The generated relative url of this post. e.g. /2008/11/05/my-awesome-post.html
Returns the String
URL.
# File lib/moft/post.rb, line 206 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
Protected Instance Methods
Internal: Extract excerpt from the content
By default excerpt is your first paragraph of a post: everything before the first two new lines:
--- title: Example --- First paragraph with [link][1]. Second paragraph. [1]: http://example.com/
This is fairly good option for Markdown and Textile files. But might cause problems for HTML posts (which is quite unusual for Moft
). If default excerpt delimiter is not good for you, you might want to set your own via configuration option ‘excerpt_separator`. For example, following is a good alternative for HTML posts:
# file: _config.yml excerpt_separator: "<!-- more -->"
Notice that all markdown-style link references will be appended to the excerpt. So the example post above will have this excerpt source:
First paragraph with [link][1]. [1]: http://example.com/
Excerpts are rendered same time as content is rendered.
Returns excerpt String
# File lib/moft/post.rb, line 370 def extract_excerpt separator = self.site.config['excerpt_separator'] head, _, tail = self.content.partition(separator) "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n") end