plate 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,4 +1,8 @@
1
- ## Plate 0.6.0 (Unreleased)
1
+ ## Plate 0.6.1
2
+
3
+ * Added basis support for asset partials with Sass and Less. When using watch mode, partials will reload any referencing files if they are modified.
4
+
5
+ ## Plate 0.6.0
2
6
 
3
7
  * Meta data can be read from the config file and used to store common site data such as title, description, author, etc.
4
8
  * Modified new site generator to use meta data structure
data/README.md CHANGED
@@ -8,6 +8,8 @@ In addition to basic formatting with Markdown, Plate also supports generating mo
8
8
 
9
9
  Plate is a command line utility installed as a Ruby Gem. Installation requires Ruby 1.8.7, 1.9.2 or 1.9.3. For additional processing, install CoffeeScript, Sass, Haml and other formatters.
10
10
 
11
+ Current version is **0.6.0**
12
+
11
13
  ## Installation
12
14
 
13
15
  gem install plate
data/lib/plate/builder.rb CHANGED
@@ -232,7 +232,24 @@ module Plate
232
232
  end
233
233
  end
234
234
  else
235
- log("Cannot render file, it doesn't exist. [#{relative_file_path}]")
235
+ # Check for partials, and run any files that reference it.
236
+ if File.basename(relative_file_path) =~ /^_/
237
+ partial_name = File.basename(relative_file_path, '.*').gsub(/^_/, '')
238
+
239
+ log("Partial modified. Reloading referencing files", :indent)
240
+
241
+ other_files = site.find_by_extension(File.extname(relative_file_path))
242
+
243
+ other_files.each do |file|
244
+ if Array === file.partials
245
+ if file.partials.include?(partial_name)
246
+ self.render_file!(file.relative_file)
247
+ end
248
+ end
249
+ end
250
+ else
251
+ log("Cannot render file, it doesn't exist. [#{relative_file_path}]")
252
+ end
236
253
  end
237
254
 
238
255
  true
@@ -1,24 +1,56 @@
1
1
  module Plate
2
- class DynamicPage < Page
3
- attr_accessor :file_path, :locals
4
-
2
+ # Allows the creation of one-off pages generated entirely from a dynamic source. The root
3
+ # content for a `DynamicPage` instance is not read from the source directory, as opposed
4
+ # to normal files. Instead, dynamic pages are typically used to create pages with dynamic
5
+ # data and content.
6
+ #
7
+ # Examples may include a blog archives page, list of tags, categories pages, etc.
8
+ #
9
+ # @example Generate a page with custom content
10
+ #
11
+ # # This callback creates a tag index page for each tag in your posts.
12
+ # callback :site, :after_render do |site|
13
+ # site.tags.each do |tag|
14
+ # tag_page = DynamicPage.new(site, "/tags/#{site.to_url(tag)}/index.html", :layout => 'tag')
15
+ # tag_page.locals = { :tag => tag }
16
+ # tag_page.write!
17
+ # end
18
+ # end
19
+ #
20
+ class DynamicPage < Page
21
+ # The full file system path of where this file will be written to. Set from the
22
+ # destination path on initialize.
23
+ attr_accessor :file_path
24
+
25
+ # Provides a hash to the page with variables that are accessible from with dynamic
26
+ # layouts or dynamic templates for this page.
27
+ attr_accessor :locals
28
+
29
+ # Set up a new instance of Dynamic Page
5
30
  def initialize(site, destination_path, meta = {})
6
31
  self.site = site
7
32
  self.file_path = destination_path
8
- self.meta = meta
33
+ self.meta = meta
9
34
  self.content = ""
10
35
  self.locals = {}
11
36
  end
12
-
37
+
38
+ # Set the full hash to be provided to the view. Hash keys are symbolized before
39
+ # sending to the view.
13
40
  def locals=(hash)
14
41
  @locals = hash.symbolize_keys!
15
42
  end
16
-
43
+
44
+ # Alias for the content that is provided
17
45
  def rendered_body
18
46
  self.content
19
47
  end
20
-
21
- # Check to see if a method called is in your locals.
48
+
49
+ # Check to see if a method called is in your locals. Allows the view to call variables in the locals
50
+ # hash directly without having to call `page.locals`.
51
+ #
52
+ # For example, in a view you can call `page.locals[:local_key]` `locals[:local_key]` or just `local_key`.
53
+ # They all will return the same value (provided :local_key exists in the locals of course)
22
54
  def method_missing(sym, *args)
23
55
  return locals[sym] if locals.has_key?(sym)
24
56
  super
data/lib/plate/errors.rb CHANGED
@@ -1,13 +1,17 @@
1
1
  module Plate
2
+ # Raised if a given file by name is not found within the source tree.
2
3
  class FileNotFound < StandardError
3
4
  end
4
5
 
6
+ # Raised when a blog post does not contain a date within the meta data or within the file name.
5
7
  class NoPostDateProvided < StandardError
6
8
  end
7
9
 
10
+ # Raised if Plate is unable to read a plugin file from the lib directory.
8
11
  class PluginNotReadable < StandardError
9
12
  end
10
13
 
14
+ # Raised if the site's source directory was not found.
11
15
  class SourceNotFound < StandardError
12
16
  end
13
17
  end
@@ -27,7 +27,9 @@ module Plate
27
27
  :paths => paths
28
28
  })
29
29
 
30
- parser = ::Less::Parser.new(less_options)
30
+ scope.partials = data.to_s.scan(/@import\s"_?(.*?)";/i).flatten
31
+
32
+ parser = ::Less::Parser.new(less_options)
31
33
  parser.parse(data).to_css
32
34
  end
33
35
  end
data/lib/plate/page.rb CHANGED
@@ -6,6 +6,12 @@ module Plate
6
6
 
7
7
  attr_accessor :body, :content, :file, :meta, :site, :layout
8
8
 
9
+ # If set, will return an array of partial names used within this page.
10
+ #
11
+ # In watch mode, this allows the current page to be reloaded when any
12
+ # of its partials are reloaded.
13
+ attr_accessor :partials
14
+
9
15
  def initialize(site, file = nil, load_on_initialize = true)
10
16
  self.site = site
11
17
  self.file = file
@@ -55,6 +61,12 @@ module Plate
55
61
  @engines ||= self.extensions.reverse.collect { |e| self.site.registered_page_engines[e.gsub(/\./, '').to_sym] }.reject { |e| !e }
56
62
  end
57
63
 
64
+ # the last file extension for this page
65
+ def extension
66
+ extensions.last.gsub(/^\./, '')
67
+ end
68
+
69
+ # List of all extensions for this page
58
70
  def extensions
59
71
  @extensions ||= self.basename.scan(/\.[^.]+/)
60
72
  end
@@ -37,6 +37,8 @@ module Plate
37
37
  options[:cache_location] = File.join(scope.site.cache_location, 'sass-cache')
38
38
  end
39
39
 
40
+ scope.partials = data.to_s.scan(/@import\s"(.*?)";/i).flatten
41
+
40
42
  ::Sass::Engine.new(data, options).render
41
43
  end
42
44
  end
data/lib/plate/site.rb CHANGED
@@ -1,136 +1,142 @@
1
1
  module Plate
2
2
  require 'tilt'
3
-
3
+
4
4
  # This class contains everything you'll want to know about a site. It contains all data
5
5
  # about the site, including blog posts, content pages, static files, assets and anything else.
6
6
  class Site
7
7
  include Callbacks
8
-
9
- attr_accessor :assets, :build_destination, :cache_location, :destination,
8
+
9
+ attr_accessor :assets, :build_destination, :cache_location, :destination,
10
10
  :layouts, :logger, :metadata, :options, :pages, :posts, :source
11
-
11
+
12
12
  def initialize(source, destination, options = {})
13
13
  # Setup source and destination for the site files
14
14
  self.source = source
15
15
  self.destination = destination
16
-
16
+
17
17
  # By default, the build goes into the destination folder.
18
18
  # Override this to output to a different folder by default
19
19
  self.build_destination = destination
20
-
20
+
21
21
  # Sanitize options
22
22
  self.options = Hash === options ? options.clone : {}
23
23
  self.options.symbolize_keys!
24
-
24
+
25
25
  clear
26
26
  end
27
-
27
+
28
28
  %w( assets layouts pages posts ).each do |group|
29
29
  class_eval "def #{group}; load!; @#{group}; end"
30
30
  end
31
-
31
+
32
32
  def all_files
33
33
  @all_files ||= self.assets + self.layouts + self.pages + self.posts.to_a
34
34
  end
35
-
35
+
36
36
  # All extensions that are registered, as strings.
37
37
  def asset_engine_extensions
38
38
  @asset_engine_extensions ||= self.registered_asset_engines.keys.collect { |e| ".#{e}" }
39
39
  end
40
-
40
+
41
41
  # Alphabetical list of all blog post categories used.
42
42
  def categories
43
43
  @categories ||= self.posts.collect(&:category).uniq.sort
44
44
  end
45
-
45
+
46
46
  # Clear out all data related to this site. Prepare for a reload, or first time load.
47
47
  def clear
48
48
  @loaded = false
49
49
  @tags_counts = nil
50
50
  @default_layout = nil
51
-
51
+
52
52
  self.assets = []
53
53
  self.layouts = []
54
54
  self.pages = []
55
55
  self.posts = PostCollection.new
56
-
56
+
57
57
  @metadata = {}
58
58
  end
59
-
59
+
60
60
  # The default blog post category
61
61
  def default_category
62
62
  options[:default_category] || 'Posts'
63
63
  end
64
-
64
+
65
65
  # The default layout for all pages that do not specifically name their own
66
66
  def default_layout
67
67
  return nil if self.layouts.size == 0
68
68
  return @default_layout if @default_layout
69
-
69
+
70
70
  layout ||= self.layouts.reject { |l| !l.default? }
71
71
  layout = self.layouts if layout.size == 0
72
-
72
+
73
73
  if Array === layout and layout.size > 0
74
74
  layout = layout[0]
75
75
  end
76
-
76
+
77
77
  @default_layout = layout
78
78
  end
79
-
79
+
80
80
  # Find a page, asset or layout by source relative file path
81
81
  def find(search_path)
82
82
  self.all_files.find { |file| file == search_path }
83
83
  end
84
-
84
+
85
+ # Find all registered files by the given file extension
86
+ def find_by_extension(extension)
87
+ extension = extension.to_s.downcase.gsub(/^\./, '')
88
+ self.all_files.select { |file| file.extension.to_s.downcase.gsub(/^\./, '') == extension }
89
+ end
90
+
85
91
  # Find all pages and posts with this layout
86
92
  def find_by_layout(layout_name)
87
93
  result = []
88
-
94
+
89
95
  result += self.pages.find_all { |page| page.layout == layout_name }
90
96
  result += self.posts.find_all { |post| post.layout == layout_name }
91
-
97
+
92
98
  result
93
99
  end
94
-
95
- # Find a specific layout by its file name. Any extensions are removed.
100
+
101
+ # Find a specific layout by its file name. Any extensions are removed.
96
102
  def find_layout(layout_name)
97
103
  search_name = layout_name.to_s.downcase.strip.split('.')[0]
98
104
  matches = self.layouts.reject { |l| l.name != search_name }
99
105
  matches.empty? ? self.default_layout : matches[0]
100
106
  end
101
-
107
+
102
108
  def inspect
103
109
  "#<#{self.class}:0x#{object_id.to_s(16)} source=#{source.to_s.inspect}>"
104
110
  end
105
-
111
+
106
112
  # Load all data from the various source directories.
107
113
  def load!
108
114
  return if @loaded
109
-
115
+
110
116
  log("Loading site from source [#{source}]")
111
-
117
+
112
118
  run_callback :before_load
113
-
119
+
114
120
  self.load_pages!
115
121
  self.load_layouts!
116
122
  self.load_posts!
117
-
123
+
118
124
  run_callback :after_load
119
-
125
+
120
126
  @loaded = true
121
127
  end
122
-
128
+
123
129
  # Returns true if the site has been loaded from the source directories.
124
130
  def loaded?
125
131
  !!@loaded
126
132
  end
127
-
133
+
128
134
  # Write to the log if enable_logging is enabled
129
135
  def log(message, style = :indent)
130
136
  logger.send(:log, message, style) if logger and logger.respond_to?(:log)
131
137
  end
132
-
133
- # Access to read all meta data for this site. Meta data can be set on the
138
+
139
+ # Access to read all meta data for this site. Meta data can be set on the
134
140
  # site instance by passing in the `metadata` hash, or it can be pulled
135
141
  # from the config file under the heading of `meta`.
136
142
  #
@@ -149,43 +155,43 @@ module Plate
149
155
  def meta
150
156
  @meta ||= HashProxy.new(self.metadata)
151
157
  end
152
-
158
+
153
159
  # Set the meta data hash object for this site.
154
160
  def meta=(hash)
155
161
  # Reset the meta hash proxy
156
162
  @meta = nil
157
-
158
- self.metadata = hash
163
+
164
+ self.metadata = hash
159
165
  end
160
-
166
+
161
167
  def page_engine_extensions
162
168
  @page_engine_extensions ||= self.registered_page_engines.keys.collect { |e| ".#{e}" }
163
169
  end
164
-
170
+
165
171
  def relative_path(file_or_directory)
166
172
  file_or_directory.to_s.gsub(/^#{Regexp.quote(source)}(.*)$/, '\1')
167
173
  end
168
-
174
+
169
175
  def reload!
170
176
  clear
171
177
  load!
172
178
  end
173
-
179
+
174
180
  # Returns the asset engines that are available for use.
175
181
  def registered_asset_engines
176
182
  Plate.asset_engines
177
183
  end
178
-
184
+
179
185
  # Returns the engines available for use in page and layout formatting.
180
186
  def registered_page_engines
181
- Plate.template_engines
187
+ Plate.template_engines
182
188
  end
183
-
189
+
184
190
  # All tags used on this site
185
191
  def tags
186
192
  @tags ||= self.posts.tag_list
187
193
  end
188
-
194
+
189
195
  def to_url(str)
190
196
  result = str.to_s.strip.downcase
191
197
  result = result.gsub(/[^-a-z0-9~\s\.:;+=_]/, '')
@@ -194,7 +200,7 @@ module Plate
194
200
  result
195
201
  end
196
202
  alias_method :sanitize_slug, :to_url
197
-
203
+
198
204
  # The base URL for this site. The url can be set using the config option named `:base_url`.
199
205
  #
200
206
  # The base URL will not have any trailing slashes.
@@ -202,28 +208,28 @@ module Plate
202
208
  return '' unless self.options[:base_url]
203
209
  @url ||= self.options[:base_url].to_s.gsub(/(.*?)\/?$/, '\1')
204
210
  end
205
-
211
+
206
212
  protected
207
213
  # Load all layouts from layouts/
208
214
  def load_layouts!(log = true)
209
215
  @layouts = []
210
-
216
+
211
217
  Dir.glob(File.join(source, "layouts/**/*")).each do |file|
212
218
  # If this 'file' is a directory, just skip it. We only care about files.
213
- unless File.directory?(file)
219
+ unless File.directory?(file)
214
220
  @layouts << Layout.new(self, file)
215
221
  end
216
222
  end
217
223
 
218
224
  log("#{@layouts.size} layouts loaded") if log
219
-
225
+
220
226
  @layouts
221
227
  end
222
-
228
+
223
229
  def load_pages!(log = true)
224
230
  @assets = []
225
231
  @pages = []
226
-
232
+
227
233
  # Load all pages, static pages and assets from content/
228
234
  Dir.glob(File.join(source, "content/**/*")).each do |file|
229
235
  # If this 'file' is a directory, just skip it. We only care about files.
@@ -252,14 +258,14 @@ module Plate
252
258
 
253
259
  log("#{@assets.size} assets loaded") if log
254
260
  log("#{@pages.size} pages and other files loaded") if log
255
-
261
+
256
262
  @pages
257
263
  end
258
-
264
+
259
265
  # Load blog posts from posts/
260
266
  def load_posts!(log = true)
261
267
  @posts = PostCollection.new
262
-
268
+
263
269
  Dir.glob(File.join(source, "posts/**/*")).each do |file|
264
270
  # If this 'file' is a directory, just skip it. We only care about files.
265
271
  unless File.directory?(file)
@@ -270,13 +276,13 @@ module Plate
270
276
  if intro == "---"
271
277
  @posts.add(Post.new(self, file))
272
278
  end
273
- end
279
+ end
274
280
  end
275
-
281
+
276
282
  @posts.sort!
277
-
278
- log("#{@posts.size} posts loaded") if log
279
-
283
+
284
+ log("#{@posts.size} posts loaded") if log
285
+
280
286
  @posts
281
287
  end
282
288
  end
data/lib/plate/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Plate
2
- VERSION = "0.6.0" unless defined?(::Plate::VERSION)
2
+ VERSION = "0.6.1" unless defined?(::Plate::VERSION)
3
3
  end
data/lib/plate.rb CHANGED
@@ -48,14 +48,14 @@ module Plate
48
48
  # https://github.com/sstephenson/sprockets
49
49
 
50
50
  # Assets
51
- register_asset_engine :coffee, Tilt::CoffeeScriptTemplate
52
- register_asset_engine :less, LessTemplate
53
- register_asset_engine :sass, SassTemplate
54
- register_asset_engine :scss, ScssTemplate
51
+ register_asset_engine :coffee, Tilt::CoffeeScriptTemplate
52
+ register_asset_engine :less, LessTemplate
53
+ register_asset_engine :sass, SassTemplate
54
+ register_asset_engine :scss, ScssTemplate
55
55
 
56
56
  # Layouts & Markup
57
- register_template_engine :erb, Tilt::ERBTemplate
58
- register_template_engine :haml, HamlTemplate
59
- register_template_engine :md, MarkdownTemplate
60
- register_template_engine :markdown, MarkdownTemplate
57
+ register_template_engine :erb, Tilt::ERBTemplate
58
+ register_template_engine :haml, HamlTemplate
59
+ register_template_engine :md, MarkdownTemplate
60
+ register_template_engine :markdown, MarkdownTemplate
61
61
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-10 00:00:00.000000000 Z
12
+ date: 2012-05-24 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: !ruby/object:Gem::Requirement
16
+ requirement: &70231552834360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,15 +21,10 @@ dependencies:
21
21
  version: '3.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: '3.2'
24
+ version_requirements: *70231552834360
30
25
  - !ruby/object:Gem::Dependency
31
26
  name: directory_watcher
32
- requirement: !ruby/object:Gem::Requirement
27
+ requirement: &70231552833980 !ruby/object:Gem::Requirement
33
28
  none: false
34
29
  requirements:
35
30
  - - ! '>='
@@ -37,15 +32,10 @@ dependencies:
37
32
  version: '0'
38
33
  type: :runtime
39
34
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
35
+ version_requirements: *70231552833980
46
36
  - !ruby/object:Gem::Dependency
47
37
  name: i18n
48
- requirement: !ruby/object:Gem::Requirement
38
+ requirement: &70231552833440 !ruby/object:Gem::Requirement
49
39
  none: false
50
40
  requirements:
51
41
  - - ~>
@@ -53,15 +43,10 @@ dependencies:
53
43
  version: '0.6'
54
44
  type: :runtime
55
45
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '0.6'
46
+ version_requirements: *70231552833440
62
47
  - !ruby/object:Gem::Dependency
63
48
  name: rake
64
- requirement: !ruby/object:Gem::Requirement
49
+ requirement: &70231552833020 !ruby/object:Gem::Requirement
65
50
  none: false
66
51
  requirements:
67
52
  - - ! '>='
@@ -69,15 +54,10 @@ dependencies:
69
54
  version: '0'
70
55
  type: :runtime
71
56
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
57
+ version_requirements: *70231552833020
78
58
  - !ruby/object:Gem::Dependency
79
59
  name: redcarpet
80
- requirement: !ruby/object:Gem::Requirement
60
+ requirement: &70231552832480 !ruby/object:Gem::Requirement
81
61
  none: false
82
62
  requirements:
83
63
  - - ~>
@@ -85,15 +65,10 @@ dependencies:
85
65
  version: '2'
86
66
  type: :runtime
87
67
  prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: '2'
68
+ version_requirements: *70231552832480
94
69
  - !ruby/object:Gem::Dependency
95
70
  name: tilt
96
- requirement: !ruby/object:Gem::Requirement
71
+ requirement: &70231552831980 !ruby/object:Gem::Requirement
97
72
  none: false
98
73
  requirements:
99
74
  - - ~>
@@ -101,12 +76,7 @@ dependencies:
101
76
  version: '1.3'
102
77
  type: :runtime
103
78
  prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ~>
108
- - !ruby/object:Gem::Version
109
- version: '1.3'
79
+ version_requirements: *70231552831980
110
80
  description: Plate is a simple, static site generator and blog engine.
111
81
  email:
112
82
  - john@johntornow.com
@@ -174,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
144
  version: 1.8.12
175
145
  requirements: []
176
146
  rubyforge_project:
177
- rubygems_version: 1.8.21
147
+ rubygems_version: 1.8.15
178
148
  signing_key:
179
149
  specification_version: 3
180
150
  summary: A static site generator and blog engine.