Class: Broadway::Post

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

Constant Summary collapse

SRC_MATCHER =
/^(.+\/)*(?:(\d+-\d+-\d+)-)?(.*)(\.[^.]+)$/
URL_MATCHER =
/^(.+\/)*(.*)$/

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(options = {}) ⇒ 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 <Post>



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/broadway/post.rb', line 32

def initialize(options = {})
  self.site = options[:site]
  self.path = options[:path] if options.has_key?(:path)
  self.data = {}
  
  n, cats, date, slug, ext = *path.match(SRC_MATCHER)
  n, cats, slug = *path.match(URL_MATCHER) unless slug
  self.date = Time.parse(date) if date
  self.slug = slug
  self.ext = ext
  self.dir = options.has_key?(:dir) ? options[:dir] : File.dirname(path.gsub(/#{site.config[:source]}\/?/, ""))

  self.categories = dir.split('/').reject { |x| x.empty? }

  process(options) unless options.has_key?(:process) and options[:process] == false
end

Instance Attribute Details

#assetObject

Returns the value of attribute asset.



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

def asset
  @asset
end

#basenameObject

where the file is



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

def basename
  @basename
end

#categoriesObject

Returns the value of attribute categories.



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

def categories
  @categories
end

#contentObject

Returns the value of attribute content.



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

def content
  @content
end

#dataObject

Returns the value of attribute data.



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

def data
  @data
end

#dateObject

Returns the value of attribute date.



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

def date
  @date
end

#dirObject

where the file is



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

def dir
  @dir
end

#extObject

where the file is



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

def ext
  @ext
end

#nameObject

where the file is



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

def name
  @name
end

#outputObject

Returns the value of attribute output.



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

def output
  @output
end

#pathObject

where the file is



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

def path
  @path
end

#publishedObject

Returns the value of attribute published.



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

def published
  @published
end

#siteObject

Returns the value of attribute site.



19
20
21
# File 'lib/broadway/post.rb', line 19

def site
  @site
end

#slugObject

Returns the value of attribute slug.



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

def slug
  @slug
end

#tagsObject

Returns the value of attribute tags.



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

def tags
  @tags
end

Class Method Details

.to_xml(site) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/broadway/api.rb', line 4

def Post.to_xml(site)
  xml = Nokogiri::XML::Builder.new { |xml| 
    xml.send("posts", :type => "array") {
      site.posts.each do |post|
        xml.post {
          xml.title post.data["title"]
          xml.url post.url
          xml.categories post.categories.join(",")
          xml.date(:type => "date") {
            xml.text post.date.to_s
          }
          xml.slug post.slug
          xml.published(:type => "boolean") {
            xml.text post.published.to_s
          }
          xml.tags post.tags.join(",")
        }
      end
    }
  }
  xml.to_xml
end

.valid?(name, site) ⇒ Boolean

Post name validator. Post filenames must be like:

2008-11-05-my-awesome-post.textile

Returns <Bool>

Returns:

  • (Boolean)


15
16
17
# File 'lib/broadway/post.rb', line 15

def self.valid?(name, site)
  site.config[:posts_include].include?(File.extname(name))
end

Instance Method Details

#<=>(other) ⇒ Object

Spaceship is based on Post#date, slug

Returns -1, 0, 1



78
79
80
# File 'lib/broadway/post.rb', line 78

def <=>(other)
  return self.url <=> other.url
end

#excerptObject



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

def excerpt
  self.data && self.data["excerpt"]
end

#idObject

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

Returns <String>



86
87
88
# File 'lib/broadway/post.rb', line 86

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

#inspectObject



191
192
193
# File 'lib/broadway/post.rb', line 191

def inspect
  "#<Broadway:Post @url=#{self.url.inspect} @categories=#{self.categories.inspect} @tags=#{self.tags.inspect} @data=#{self.data.inspect}>"
end

#parentObject



90
91
92
# File 'lib/broadway/post.rb', line 90

def parent
  url ? site.find_page_by_url(url[1..-1].split("/").first) : nil
end

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

Returns <String>



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

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

#process(options = {}) ⇒ Object

Extract information from the post filename

+name+ is the String filename of the post file

Returns nothing



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/broadway/post.rb', line 53

def process(options = {})
  self.read_yaml(path)
  
  # If we've added a date and time to the yaml, use that instead of the filename date
  # Means we'll sort correctly.
  self.date = Time.parse(self.data["date"].to_s) if self.data.has_key?('date')
  
  if self.data.has_key?('published') && self.data['published'] == false
    self.published = false
  else
    self.published = true
  end
  
  if self.data.has_key?("asset")
    data["asset"]["title"] ||= self.title
    self.asset = Asset.new(data["asset"])
  end
  
  self.tags = self.data.pluralized_array("tag", "tags")
  self.tags ||= []
end

#render(layouts, site_payload) ⇒ Object

Add any necessary layouts to this post

+layouts+ is a Hash of {"name" => "layout"}
+site_payload+ is the site payload hash

Returns nothing



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/broadway/post.rb', line 146

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

  do_layout(payload, layouts)
end

#templateObject



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/broadway/post.rb', line 111

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



103
104
105
# File 'lib/broadway/post.rb', line 103

def title
  self.data && (self.data['title'] || self.slug)
end

#to_liquidObject

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

Returns <Hash>



181
182
183
184
185
186
187
188
189
# File 'lib/broadway/post.rb', line 181

def to_liquid
  { "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,
    "tags"       => self.tags,
    "content"    => self.content }.deep_merge(self.data)
end

#urlObject

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

Returns <String>



128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/broadway/post.rb', line 128

def url
  return permalink if permalink
  @url ||= {
    "year"       => date ? date.strftime("%Y") : "",
    "month"      => date ? date.strftime("%m") : "",
    "day"        => date ? date.strftime("%d") : "",
    "title"      => CGI.escape(slug),
    "categories" => categories.join('/')
  }.inject(template) { |result, token|
    result.gsub(/:#{token.first}/, token.last)
  }.gsub(/#{site.config[:posts]}/, "").squeeze("/")
end

#write(dest) ⇒ Object

Write the generated post file to the destination directory.

+dest+ is the String path to the destination dir

Returns nothing



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/broadway/post.rb', line 162

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