TwP-webby 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. data/History.txt +11 -0
  2. data/Manifest.txt +45 -2
  3. data/Rakefile +1 -2
  4. data/examples/webby/content/css/site.css +1 -1
  5. data/examples/webby/content/learn/index.txt +1 -1
  6. data/examples/webby/content/release-notes/index.txt +21 -0
  7. data/examples/webby/content/release-notes/rel-0-9-0/index.txt +1 -0
  8. data/examples/webby/content/release-notes/rel-0-9-1/index.txt +93 -0
  9. data/examples/webby/content/tips_and_tricks/index.txt +14 -13
  10. data/examples/webby/content/tutorial/index.txt +13 -9
  11. data/examples/webby/content/user-manual/index.txt +8 -8
  12. data/examples/webby/layouts/default.txt +1 -1
  13. data/lib/webby/apps/main.rb +25 -13
  14. data/lib/webby/auto_builder.rb +2 -0
  15. data/lib/webby/builder.rb +2 -5
  16. data/lib/webby/filters.rb +5 -13
  17. data/lib/webby/renderer.rb +7 -5
  18. data/lib/webby/resources/db.rb +4 -4
  19. data/lib/webby/resources/layout.rb +14 -23
  20. data/lib/webby/resources/meta_file.rb +208 -0
  21. data/lib/webby/resources/page.rb +21 -58
  22. data/lib/webby/resources/partial.rb +10 -4
  23. data/lib/webby/resources/resource.rb +68 -27
  24. data/lib/webby/resources/static.rb +6 -22
  25. data/lib/webby/resources.rb +54 -14
  26. data/lib/webby/stelan/paginator.rb +17 -2
  27. data/lib/webby.rb +2 -1
  28. data/spec/data/Sitefile +9 -0
  29. data/spec/data/content/_partial.txt +10 -0
  30. data/spec/data/content/css/coderay.css +111 -0
  31. data/spec/data/content/css/site.css +67 -0
  32. data/spec/data/content/css/tumblog.css +308 -0
  33. data/spec/data/content/images/tumblog/permalink.gif +0 -0
  34. data/spec/data/content/images/tumblog/rss.gif +0 -0
  35. data/spec/data/content/index.txt +19 -0
  36. data/spec/data/content/photos.txt +21 -0
  37. data/spec/data/content/tumblog/200806/the-noble-chicken/index.txt +12 -0
  38. data/spec/data/content/tumblog/200807/historical-perspectives-on-the-classic-chicken-joke/index.txt +12 -0
  39. data/spec/data/content/tumblog/200807/mad-city-chickens/index.txt +10 -0
  40. data/spec/data/content/tumblog/200807/the-wisdom-of-the-dutch/index.txt +11 -0
  41. data/spec/data/content/tumblog/200807/up-a-tree/index.txt +13 -0
  42. data/spec/data/content/tumblog/index.txt +37 -0
  43. data/spec/data/content/tumblog/rss.txt +37 -0
  44. data/spec/data/hooligans/bad_meta_data_1.txt +34 -0
  45. data/spec/data/hooligans/bad_meta_data_2.txt +34 -0
  46. data/spec/data/layouts/default.txt +58 -0
  47. data/spec/data/layouts/tumblog/default.txt +44 -0
  48. data/spec/data/layouts/tumblog/post.txt +15 -0
  49. data/spec/data/lib/breadcrumbs.rb +28 -0
  50. data/spec/data/lib/tumblog_helper.rb +32 -0
  51. data/spec/data/tasks/tumblog.rake +30 -0
  52. data/spec/data/templates/_partial.erb +10 -0
  53. data/spec/data/templates/atom_feed.erb +40 -0
  54. data/spec/data/templates/page.erb +18 -0
  55. data/spec/data/templates/presentation.erb +40 -0
  56. data/spec/data/templates/tumblog/conversation.erb +12 -0
  57. data/spec/data/templates/tumblog/link.erb +10 -0
  58. data/spec/data/templates/tumblog/photo.erb +13 -0
  59. data/spec/data/templates/tumblog/post.erb +12 -0
  60. data/spec/data/templates/tumblog/quote.erb +11 -0
  61. data/spec/spec_helper.rb +37 -0
  62. data/spec/webby/apps/generator_spec.rb +4 -0
  63. data/spec/webby/apps/main_spec.rb +16 -3
  64. data/spec/webby/filters/textile_spec.rb +20 -0
  65. data/spec/webby/renderer_spec.rb +139 -0
  66. data/spec/webby/resources/db_spec.rb +250 -0
  67. data/spec/webby/resources/layout_spec.rb +83 -0
  68. data/spec/webby/resources/meta_file_spec.rb +157 -0
  69. data/spec/webby/resources/page_spec.rb +111 -0
  70. data/spec/webby/resources/partial_spec.rb +58 -0
  71. data/spec/webby/resources/resource_spec.rb +214 -0
  72. data/spec/webby/resources/static_spec.rb +49 -0
  73. data/spec/webby/resources_spec.rb +55 -3
  74. data/tasks/rubyforge.rake +1 -1
  75. metadata +64 -6
  76. data/lib/webby/resources/file.rb +0 -221
  77. data/spec/webby/resources/file_spec.rb +0 -104
@@ -120,6 +120,8 @@ class Renderer
120
120
  ::Webby::Renderer.new(resource)._render_page
121
121
  when Resources::Partial
122
122
  _render_partial(resource, opts)
123
+ when Resources::Static
124
+ resource._read
123
125
  else
124
126
  raise ::Webby::Error, "expecting a page or a partial but got '#{resource.class.name}'"
125
127
  end
@@ -189,7 +191,7 @@ class Renderer
189
191
  #
190
192
  def _render_page
191
193
  _track_rendering(@page.path) {
192
- Filters.process(self, @page, ::Webby::Resources::File.read(@page.path))
194
+ Filters.process(self, @page, @page._read)
193
195
  }
194
196
  end
195
197
 
@@ -203,7 +205,7 @@ class Renderer
203
205
  def _render_partial( part, opts = {} )
204
206
  _track_rendering(part.path) {
205
207
  _configure_locals(opts[:locals])
206
- Filters.process(self, part, ::Webby::Resources::File.read(part.path))
208
+ Filters.process(self, part, part._read)
207
209
  }
208
210
  end
209
211
 
@@ -248,8 +250,7 @@ class Renderer
248
250
  return if lyt.nil?
249
251
 
250
252
  _track_rendering(lyt.path) {
251
- @content = Filters.process(
252
- self, lyt, ::Webby::Resources::File.read(lyt.path))
253
+ @content = Filters.process(self, lyt, lyt._read)
253
254
  _render_layout_for(lyt)
254
255
  }
255
256
  end
@@ -270,7 +271,8 @@ class Renderer
270
271
  @_content_for.clear
271
272
  @_bindings.clear
272
273
  else
273
- @page.number = nil
274
+ @pager.pager.done
275
+ @pager = nil
274
276
  return false
275
277
  end
276
278
 
@@ -23,7 +23,7 @@ class DB
23
23
  # time if it already exists in the database.
24
24
  #
25
25
  def add( page )
26
- ary = @db[page.dir]
26
+ ary = @db[page.directory]
27
27
 
28
28
  # make sure we don't duplicate pages
29
29
  ary.delete page if ary.include? page
@@ -183,7 +183,7 @@ class DB
183
183
  # Reverse the order of the results
184
184
  #
185
185
  def siblings( page, opts = {} )
186
- ary = @db[page.dir].dup
186
+ ary = @db[page.directory].dup
187
187
  ary.delete page
188
188
  return ary unless opts.has_key? :sort_by
189
189
 
@@ -207,7 +207,7 @@ class DB
207
207
  # Reverse the order of the results
208
208
  #
209
209
  def children( page, opts = {} )
210
- rgxp = Regexp.new "\\A#{page.dir}/[^/]+"
210
+ rgxp = Regexp.new "\\A#{page.directory}/[^/]+"
211
211
 
212
212
  keys = @db.keys.find_all {|k| rgxp =~ k}
213
213
  ary = keys.map {|k| @db[k]}
@@ -229,7 +229,7 @@ class DB
229
229
  # of the current directory or the next directory up the chain.
230
230
  #
231
231
  def parent_of( page )
232
- dir = page.dir
232
+ dir = page.directory
233
233
 
234
234
  loop do
235
235
  if @db.has_key? dir
@@ -16,41 +16,32 @@ class Layout < Resource
16
16
  def initialize( fn )
17
17
  super
18
18
 
19
- @mdata = ::Webby::Resources::File.meta_data(@path)
20
- @mdata ||= {}
21
- @mdata.sanitize!
19
+ @_meta_data = MetaFile.meta_data(@path)
20
+ @_meta_data ||= {}
21
+ @_meta_data.sanitize!
22
22
  end
23
23
 
24
- # call-seq:
25
- # destination => string
26
- #
27
- # The output file destination for the layout. This is the ".cairn" file in
28
- # the output folder. It is used to determine if the layout is newer than
29
- # the build products.
30
- #
31
- def destination
32
- ::Webby.cairn
33
- end
34
-
35
- # call-seq:
36
- # extension => string or nil
37
- #
38
24
  # Returns the extension to be applied to output files rendered by the
39
25
  # layotut. This will either be a string or +nil+ if the layout does not
40
26
  # specify an extension to use.
41
27
  #
42
28
  def extension
43
- return @mdata['extension'] if @mdata.has_key? 'extension'
29
+ return _meta_data['extension'] if _meta_data.has_key? 'extension'
44
30
 
45
- if @mdata.has_key? 'layout'
46
- lyt = ::Webby::Resources.find_layout(@mdata['layout'])
47
- ext = lyt ? lyt.extension : nil
31
+ if _meta_data.has_key? 'layout'
32
+ lyt = ::Webby::Resources.find_layout(_meta_data['layout'])
33
+ lyt ? lyt.extension : nil
48
34
  end
49
35
  end
50
36
 
51
- # call-seq:
52
- # url => nil
37
+ # The output file destination for the layout. This is the ".cairn" file in
38
+ # the output folder. It is used to determine if the layout is newer than
39
+ # the build products.
53
40
  #
41
+ def destination
42
+ ::Webby.cairn
43
+ end
44
+
54
45
  # Layouts do not have a URL. This method will alwasy return +nil+.
55
46
  #
56
47
  def url
@@ -0,0 +1,208 @@
1
+ require 'yaml'
2
+
3
+ module Webby::Resources
4
+
5
+ # The MetaFile class is used to read meta-data and content from files. The
6
+ # meta-data is in a YAML block located at the top of the file. The content
7
+ # is the remainder of the file (everything after the YAML block).
8
+ #
9
+ # The meta-data data must be found between two YAML block separators "---",
10
+ # each on their own line.
11
+ #
12
+ # Example:
13
+ #
14
+ # ---
15
+ # layout: blog
16
+ # filter: markdown
17
+ # tags:
18
+ # - ruby
19
+ # - web development
20
+ # ---
21
+ # This is a blog entry formatted using MarkDown and tagged as "ruby" and
22
+ # "web development". The layout being used is the "blog" format.
23
+ #
24
+ class MetaFile
25
+
26
+ class Error < StandardError; end
27
+
28
+ META_SEP = %r/\A---\s*(?:\r\n|\n)?\z/ # :nodoc:
29
+ ERR_MSG = "corrupt meta-data (perhaps there is an errant YAML marker '---' in the file)" # :nodoc:
30
+
31
+ # call-seq:
32
+ # MetaFile.read( filename ) => string
33
+ #
34
+ # Opens the file identified by _filename_ and returns the contents of the
35
+ # file as a string. Any meta-data at the top of the file is skipped and
36
+ # is not included in the returned string. If the file contains no
37
+ # meta-data, then this method behaves the same as File#read.
38
+ #
39
+ def self.read( name )
40
+ ::File.open(name, 'r') {|fd| MetaFile.new(fd).read}
41
+ end
42
+
43
+ # call-seq:
44
+ # MetaFile.meta_data( filename ) => object or nil
45
+ #
46
+ # Opens the file identified by _filename_ and returns the meta-data
47
+ # located at the top of the file. If the file contains no meta-data, then
48
+ # +nil+ is returned.
49
+ #
50
+ def self.meta_data( name )
51
+ ::File.open(name, 'r') {|fd| MetaFile.new(fd).meta_data}
52
+ end
53
+
54
+ # call-seq:
55
+ # MetaFile.meta_data?( filename ) => true or false
56
+ #
57
+ # Opens the file identified by _filename_ and returns true if there is a
58
+ # meta-data block at the top of the file, and returns false if there is
59
+ # not a meta-data block at the top of the file.
60
+ #
61
+ def self.meta_data?( name )
62
+ ::File.open(name, 'r') {|fd| MetaFile.new(fd).meta_data?}
63
+ end
64
+
65
+ # Creates a new MetaFile parser that will read from the given _io_ stream.
66
+ #
67
+ def initialize( io )
68
+ raise ArgumentError, "expecting an IO stream" unless io.respond_to? :gets
69
+ @io = io
70
+ @meta_count = 0
71
+ end
72
+
73
+ # Returns the entire contents of the IO stream exluding any meta-data
74
+ # found at the beginning of the stream.
75
+ #
76
+ def read
77
+ @io.seek(meta_end || 0)
78
+ @io.read
79
+ end
80
+
81
+ # Reads in each meta-data section and yields it to the given block. The
82
+ # first meta-data section is yielded "as is", but subsequent meta-data
83
+ # sections are merged with this first section and then yielded. This
84
+ # allows the user to define common items in the first meta-data section
85
+ # and only include items that are different in the subsequent sections.
86
+ #
87
+ # Example:
88
+ #
89
+ # ---
90
+ # title: First Title
91
+ # author: me
92
+ # directory: foo/bar/baz
93
+ # ---
94
+ # title: Second Title
95
+ # author: you
96
+ # ---
97
+ # title: Third Title
98
+ # author: them
99
+ # ---
100
+ #
101
+ # and parsing the meta-data above yields ...
102
+ #
103
+ # meta_file.each do |hash|
104
+ # pp hash
105
+ # end
106
+ #
107
+ # the following output
108
+ #
109
+ # { 'title' => 'First Title',
110
+ # 'author' => 'me',
111
+ # 'directory' => 'foo/bar/baz' }
112
+ #
113
+ # { 'title' => 'Second Title',
114
+ # 'author' => 'you',
115
+ # 'directory' => 'foo/bar/baz' }
116
+ #
117
+ # { 'title' => 'Third Title',
118
+ # 'author' => 'them',
119
+ # 'directory' => 'foo/bar/baz' }
120
+ #
121
+ # Even though the "directory" item only appears in the first meta-data
122
+ # block, it is copied to all the subsequent blocks.
123
+ #
124
+ def each
125
+ return unless meta_data?
126
+
127
+ first, count = nil, 0
128
+ @io.seek 0
129
+
130
+ buffer = @io.gets
131
+ while count < @meta_count
132
+ while (line = @io.gets) !~ META_SEP
133
+ buffer << line
134
+ end
135
+
136
+ h = YAML.load(buffer)
137
+ raise Error, ERR_MSG unless h.instance_of?(Hash)
138
+
139
+ if first then h = first.merge(h)
140
+ else first = h.dup end
141
+
142
+ buffer = line
143
+ count += 1
144
+
145
+ yield h
146
+ end
147
+ rescue ArgumentError => err
148
+ msg = ERR_MSG.dup << "\n\t-- " << err.message
149
+ raise Error, msg
150
+ end
151
+
152
+ # Returns the meta-data defined at the top of the file. Returns +nil+ if
153
+ # no meta-data is defined. The meta-data is returned as Ruby objects
154
+ #
155
+ # Meta-data is stored in YAML format between two YAML separators "---" on
156
+ # their own lines.
157
+ #
158
+ def meta_data
159
+ return if meta_end.nil?
160
+
161
+ @io.seek 0
162
+ return YAML.load(@io)
163
+ end
164
+
165
+ # Returns true if the IO stream contains meta-data. Returns false if the
166
+ # IO stream does not contain meta-data.
167
+ #
168
+ def meta_data?
169
+ meta_end.nil? ? false : true
170
+ end
171
+
172
+ # Returns the number of meta-data blocks at the top of the file.
173
+ #
174
+ def meta_count
175
+ meta_end
176
+ @meta_count
177
+ end
178
+
179
+ # Returns the position in the IO stream where the meta-data ends and the
180
+ # regular data begins. If there is no meta-data in the stream, returns +nil+.
181
+ #
182
+ def meta_end
183
+ return @meta_end if defined? @meta_end
184
+ @meta_end = nil
185
+
186
+ @io.seek 0
187
+ line = @io.read(4)
188
+ return unless META_SEP =~ line
189
+
190
+ @io.seek 0
191
+ pos = nil
192
+ buffer = @io.gets.length
193
+ while line = @io.gets
194
+ buffer += line.length
195
+ if META_SEP =~ line
196
+ pos = buffer
197
+ @meta_count += 1
198
+ end
199
+ end
200
+ return if pos.nil?
201
+
202
+ @meta_end = pos
203
+ end
204
+
205
+ end # class MetaFile
206
+ end # module Webby::Resources
207
+
208
+ # EOF
@@ -9,22 +9,22 @@ module Webby::Resources
9
9
  #
10
10
  class Page < Resource
11
11
 
12
- # Resource page number (if needed)
13
- attr_reader :number
14
-
15
12
  # call-seq:
16
13
  # Resource.new( path )
17
14
  #
18
15
  # Creates a new page object from the full path to the page file.
19
16
  #
20
- def initialize( fn )
21
- super
22
- @number = nil
23
-
24
- @mdata = ::Webby::Resources::File.meta_data(@path)
25
- @mdata ||= {}
26
- @mdata = ::Webby.site.page_defaults.merge(@mdata)
27
- @mdata.sanitize!
17
+ def initialize( fn, meta_data = nil )
18
+ super(fn)
19
+
20
+ if meta_data.instance_of?(Hash)
21
+ @_meta_data = meta_data
22
+ else
23
+ @_meta_data = MetaFile.meta_data(@path)
24
+ @_meta_data ||= {}
25
+ end
26
+ @_meta_data = ::Webby.site.page_defaults.merge(@_meta_data)
27
+ @_meta_data.sanitize!
28
28
  end
29
29
 
30
30
  # call-seq:
@@ -46,51 +46,13 @@ class Page < Resource
46
46
  # is returned for layouts.
47
47
  #
48
48
  def url
49
- return @url if defined? @url and @url
49
+ return @url unless @url.nil?
50
50
 
51
- @url = destination.sub(::Webby.site.output_dir, '')
52
- @url = File.dirname(@url) if filename == 'index' and number.nil?
51
+ @url = super
52
+ @url = File.dirname(@url) if filename == 'index'
53
53
  @url
54
54
  end
55
55
 
56
- # call-seq:
57
- # page.number = Integer
58
- #
59
- # Sets the page number for the current resource to the given integer. This
60
- # number is used to modify the output destination for resources that
61
- # require pagination.
62
- #
63
- def number=( num )
64
- @number = num
65
- @url = @dest = nil
66
- end
67
-
68
- # call-seq:
69
- # destination => string
70
- #
71
- # Returns the path in the output directory where the rendered page should
72
- # be stored. This path is used to determine if the page is dirty and in
73
- # need of rendering.
74
- #
75
- # The destination for a page can be overridden by explicitly setting
76
- # the 'destination' property in the page's meta-data.
77
- #
78
- def destination
79
- return @dest if defined? @dest and @dest
80
-
81
- @dest = if @mdata.has_key? 'destination' then @mdata['destination']
82
- else ::File.join(dir, filename) end
83
-
84
- @dest = ::File.join(::Webby.site.output_dir, @dest)
85
- @dest << @number.to_s if @number
86
-
87
- ext = extension
88
- unless ext.nil? or ext.empty?
89
- @dest << '.' << ext
90
- end
91
- @dest
92
- end
93
-
94
56
  # call-seq:
95
57
  # extension => string
96
58
  #
@@ -102,14 +64,15 @@ class Page < Resource
102
64
  # * the extension of this page file
103
65
  #
104
66
  def extension
105
- return @mdata['extension'] if @mdata.has_key? 'extension'
67
+ return _meta_data['extension'] if _meta_data.has_key? 'extension'
106
68
 
107
- if @mdata.has_key? 'layout'
108
- lyt = ::Webby::Resources.find_layout(@mdata['layout'])
109
- ext = lyt ? lyt.extension : nil
110
- return ext if ext
69
+ if _meta_data.has_key? 'layout'
70
+ lyt = ::Webby::Resources.find_layout(_meta_data['layout'])
71
+ lyt_ext = lyt ? lyt.extension : nil
72
+ return lyt_ext if lyt_ext
111
73
  end
112
- @ext
74
+
75
+ ext
113
76
  end
114
77
 
115
78
  end # class Page
@@ -24,9 +24,9 @@ class Partial < Resource
24
24
  def initialize( fn )
25
25
  super
26
26
 
27
- @mdata = ::Webby::Resources::File.meta_data(@path)
28
- @mdata ||= {}
29
- @mdata.sanitize!
27
+ @_meta_data = MetaFile.meta_data(@path)
28
+ @_meta_data ||= {}
29
+ @_meta_data.sanitize!
30
30
  end
31
31
 
32
32
  # call-seq:
@@ -37,7 +37,7 @@ class Partial < Resource
37
37
  # copied (if a static file) to the output directory.
38
38
  #
39
39
  def dirty?
40
- return @mdata['dirty'] if @mdata.has_key? 'dirty'
40
+ return _meta_data['dirty'] if _meta_data.has_key? 'dirty'
41
41
 
42
42
  # if the destination file does not exist, then we are dirty
43
43
  return true unless test(?e, destination)
@@ -73,6 +73,12 @@ class Partial < Resource
73
73
  nil
74
74
  end
75
75
 
76
+ # :stopdoc:
77
+ def _read
78
+ MetaFile.read(@path)
79
+ end
80
+ # :startdoc:
81
+
76
82
  end # class Partial
77
83
  end # module Webby::Resources
78
84
 
@@ -16,31 +16,34 @@ class Resource
16
16
  # The full path to the resource file
17
17
  attr_reader :path
18
18
 
19
+ # The name of the file excluding the directory and extension
20
+ attr_reader :name
21
+
19
22
  # The directory of the resource excluding the content directory
20
23
  attr_reader :dir
21
24
 
22
- # The resource filename excluding path and extension
23
- attr_reader :filename
24
-
25
25
  # Extesion of the resource file
26
26
  attr_reader :ext
27
27
 
28
28
  # Resource file modification time
29
29
  attr_reader :mtime
30
30
 
31
+ attr_reader :_meta_data #:nodoc:
32
+
31
33
  # call-seq:
32
34
  # Resource.new( filename ) => resource
33
35
  #
34
36
  # Creates a new resource object given the _filename_.
35
37
  #
36
38
  def initialize( fn )
37
- @path = fn
38
- @dir = ::Webby::Resources::File.dirname(@path)
39
- @filename = ::Webby::Resources::File.basename(@path)
40
- @ext = ::Webby::Resources::File.extname(@path)
41
- @mtime = ::File.mtime @path
42
-
43
- @mdata = @@mdata ||= {}
39
+ @path = fn
40
+ @dir = ::Webby::Resources.dirname(@path)
41
+ @name = ::Webby::Resources.basename(@path)
42
+ @ext = ::Webby::Resources.extname(@path)
43
+ @mtime = ::File.mtime @path
44
+
45
+ @_meta_data = {}
46
+ self._reset
44
47
  end
45
48
 
46
49
  # call-seq:
@@ -51,7 +54,7 @@ class Resource
51
54
  #
52
55
  def equal?( other )
53
56
  return false unless other.kind_of? ::Webby::Resources::Resource
54
- @path == other.path
57
+ self.destination == other.destination
55
58
  end
56
59
  alias :== :equal?
57
60
  alias :eql? :equal?
@@ -65,7 +68,7 @@ class Resource
65
68
  #
66
69
  def <=>( other )
67
70
  return unless other.kind_of? ::Webby::Resources::Resource
68
- @path <=> other.path
71
+ self.destination <=> other.destination
69
72
  end
70
73
 
71
74
  # call-seq:
@@ -75,7 +78,7 @@ class Resource
75
78
  # converted into a string.
76
79
  #
77
80
  def []( key )
78
- @mdata[key.to_s]
81
+ _meta_data[key.to_s]
79
82
  end
80
83
 
81
84
  # call-seq:
@@ -85,7 +88,7 @@ class Resource
85
88
  # string.
86
89
  #
87
90
  def []=( key, value )
88
- @mdata[key.to_s] = value
91
+ _meta_data[key.to_s] = value
89
92
  end
90
93
 
91
94
  # call-seq:
@@ -97,7 +100,7 @@ class Resource
97
100
  # meta-data item is returned; otherwise, +nil+ is returned.
98
101
  #
99
102
  def method_missing( name, *a, &b )
100
- @mdata[name.to_s]
103
+ _meta_data[name.to_s]
101
104
  end
102
105
 
103
106
  # call-seq:
@@ -108,7 +111,7 @@ class Resource
108
111
  # copied (if a static file) to the output directory.
109
112
  #
110
113
  def dirty?
111
- return @mdata['dirty'] if @mdata.has_key? 'dirty'
114
+ return _meta_data['dirty'] if _meta_data.has_key? 'dirty'
112
115
 
113
116
  # if the destination file does not exist, then we are dirty
114
117
  return true unless test(?e, destination)
@@ -120,8 +123,8 @@ class Resource
120
123
 
121
124
  # check to see if the layout is dirty, and if it is then we
122
125
  # are dirty, too
123
- if @mdata.has_key? 'layout'
124
- lyt = ::Webby::Resources.find_layout(@mdata['layout'])
126
+ if _meta_data.has_key? 'layout'
127
+ lyt = ::Webby::Resources.find_layout(_meta_data['layout'])
125
128
  unless lyt.nil?
126
129
  return true if lyt.dirty?
127
130
  end
@@ -131,24 +134,62 @@ class Resource
131
134
  false
132
135
  end
133
136
 
134
- # call-seq
135
- # url => string or nil
137
+ # The resource filename excluding path and extension. This will either be
138
+ # the name of the file or the 'filename' attribute from the meta-data if
139
+ # present.
136
140
  #
137
- # Returns a string suitable for use as a URL linking to this page. Nil
138
- # is returned for layouts.
141
+ def filename
142
+ return _meta_data['filename'] if _meta_data.has_key? 'filename'
143
+ name
144
+ end
145
+
146
+ # The resource file extension. This will either be the extension of the
147
+ # file or the 'extension' attribute from the meta-data if present.
148
+ #
149
+ def extension
150
+ return _meta_data['extension'] if _meta_data.has_key? 'extension'
151
+ ext
152
+ end
153
+
154
+ # The location of this resource in the directory structure. This directory
155
+ # does not include the content folder or the output folder.
156
+ #
157
+ def directory
158
+ return _meta_data['directory'] if _meta_data.has_key? 'directory'
159
+ dir
160
+ end
161
+
162
+ # Returns the path in the output directory where the resource will be
163
+ # generated. This path is used to determine if the resource is dirty
164
+ # and in need of generating.
165
+ #
166
+ def destination
167
+ return @destination unless @destination.nil?
168
+
169
+ @destination = ::File.join(::Webby.site.output_dir, directory, filename)
170
+ ext = extension
171
+ unless ext.nil? or ext.empty?
172
+ @destination << '.' << ext
173
+ end
174
+ @destination
175
+ end
176
+
177
+ # Returns a string suitable for use as a URL linking to this resource.
139
178
  #
140
179
  def url
141
- return @url if defined? @url and @url
180
+ return @url unless @url.nil?
142
181
  @url = destination.sub(::Webby.site.output_dir, '')
143
182
  end
144
183
 
145
184
  # :stopdoc:
146
- def destination
147
- raise NotImplementedError
185
+ def _read
186
+ MetaFile.read(@path)
148
187
  end
149
188
 
150
- def extension
151
- raise NotImplementedError
189
+ def _reset( meta_data = nil )
190
+ _meta_data.replace(meta_data) if meta_data.instance_of?(Hash)
191
+ @url = nil
192
+ @destination = nil
152
193
  end
153
194
  # :startdoc:
154
195