module Plate # A model for each blog post class Post < Page # Returns the category for this blog post. If no category is given in the meta # information, then the value for config[:default_category] is used. # # If no default category has been given, this will default to "Posts" def category default = self.meta[:category] || self.site.default_category end # Category for this post, formatted to be URL-friendly def category_for_url self.category.to_s.dasherize.parameterize end # Returns the date for this post, either from the filename or meta hash. # If both are provided, the meta information takes precedence. def date result = nil if self.meta[:date] result = self.meta[:date].to_s elsif self.basename =~ /^(\d{4}-\d{2}-\d{2})-/ result = $1.to_s end begin return Time.parse(result) rescue Exception => e self.site.log(" ** Problem reading date for file #{relative_file} (#{e.message}). Post skipped.") end raise NoPostDateProvided end def day date.strftime('%d') end # The full file path of where this file will be written to. (Relative to site root) def file_path "#{permalink}/index.html" end def inspect "#<#{self.class}:0x#{object_id.to_s(16)} name=#{name.to_s.inspect} date=#{date.to_s}>" end def month date.strftime('%m') end # Return the [relative] path for this post. Uses the +permalink_template+ # variable as the method for converting post data into a URL. # # The permalink_template can be set in the global config named 'permalink'. # # Available options are: # # * `date` - The date of this post, formatted as YYYY-MM-DD # * `title` - The title of this post, formatted for URL # * `slug` - The filename slug # * `year` - The 4-digit year of this post # * `month` - The 2-digit month for this post # * `day` - The 2-digit day of month for this post # * `category` - The category for this post # # All values are formatted to be URL-safe. (No spaces, underscores or weird characters.) def permalink(cache_buster = false) return @permalink if @permalink and !cache_buster date = self.date # All of these variables can be put into a URL permalink_attributes = { "date" => date.strftime('%Y-%m-%d'), "slug" => slug, "title" => title_for_url, "year" => year, "month" => month, "day" => day, "category" => category_for_url } # Copy the permalink template as a starting point result = permalink_template.clone # Replace all variables from the attributes into the template permalink_attributes.each { |key, value| result.gsub!(/:#{Regexp.escape(key)}/, value) } # Remove any double slashes result.gsub!(/\/\//, '/') # Remove file extensions, and cleanup URL result = result.split('/').reject{ |segment| segment =~ /^\.+$/ }.join('/') @permalink = result end # The template to use when generating the permalink. def permalink_template self.site.options[:permalink] || '/:category/:year/:month/:slug' end # Returns the URL slug to use for this blog post. # # This will convert the file name from a format like: # # 2012-01-01-post-name.md # # To simply: # # post-name def slug name = self.basename.to_s.downcase.gsub(/^(\d{4}-\d{2}-\d{2})-/, '').split('.')[0] name.dasherize.parameterize end # Utility method to sanitize tags output. Tags are returned as an array. def tags @tags ||= (Array === self.meta[:tags] ? self.meta[:tags] : self.meta[:tags].to_s.strip.split(',')).collect(&:strip).sort end def year date.strftime('%Y') end # Compare two posts, by date. def <=>(other) self.date <=> other.date end end end