hydeweb 0.0.8.pre2 → 0.1.0

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 (151) hide show
  1. data/{CHANGELOG → HISTORY.md} +6 -0
  2. data/Rakefile +2 -52
  3. data/bin/hyde +3 -23
  4. data/bin/hyde01 +7 -0
  5. data/data/new_site/README.md +1 -1
  6. data/data/new_site/hyde.conf +9 -6
  7. data/lib/hyde/cli/helpers.rb +40 -0
  8. data/lib/hyde/cli.rb +86 -0
  9. data/lib/hyde/config.rb +37 -0
  10. data/lib/hyde/helpers.rb +6 -47
  11. data/lib/hyde/layout.rb +17 -9
  12. data/lib/hyde/meta.rb +5 -21
  13. data/lib/hyde/page.rb +207 -159
  14. data/lib/hyde/partial.rb +10 -5
  15. data/lib/hyde/project.rb +58 -208
  16. data/lib/hyde/server.rb +57 -0
  17. data/lib/hyde.rb +28 -51
  18. data/test/fixture/extensions/extensions/a/a.rb +1 -0
  19. data/test/fixture/extensions/hyde.conf +8 -0
  20. data/test/fixture/extensions/site/index.haml +1 -0
  21. data/test/fixture/fail_type/control/about/index.html +2 -0
  22. data/test/fixture/fail_type/control/about/us.html +2 -0
  23. data/test/fixture/fail_type/control/index.html +1 -0
  24. data/test/fixture/fail_type/hyde.conf +8 -0
  25. data/test/fixture/fail_type/site/index.haml +4 -0
  26. data/test/fixture/nested_layout/control/index.html +2 -0
  27. data/test/fixture/nested_layout/hyde.conf +8 -0
  28. data/test/fixture/nested_layout/layouts/default.haml +2 -0
  29. data/test/{fixtures/content_for/site/default.html.haml → fixture/nested_layout/layouts/post.haml} +1 -0
  30. data/test/fixture/nested_layout/site/index.haml +4 -0
  31. data/test/fixture/one/control/about/index.css +2 -0
  32. data/test/fixture/one/control/cheers.html +5 -0
  33. data/test/fixture/one/control/css/style.css +2 -0
  34. data/test/fixture/one/control/hello.html +5 -0
  35. data/test/fixture/one/control/hi.html +1 -0
  36. data/test/fixture/one/control/index.html +7 -0
  37. data/test/fixture/one/hyde.conf +9 -0
  38. data/test/fixture/one/layouts/default.haml +4 -0
  39. data/test/fixture/one/partials/menu.haml +3 -0
  40. data/test/fixture/one/site/about/index.scss +1 -0
  41. data/test/fixture/one/site/cheers.html.haml +1 -0
  42. data/test/fixture/one/site/css/style.scss +2 -0
  43. data/test/fixture/one/site/hello.haml +1 -0
  44. data/test/fixture/one/site/hi.html +1 -0
  45. data/test/fixture/one/site/index.haml +7 -0
  46. data/test/fixture/parent/control/about/index.html +2 -0
  47. data/test/fixture/parent/control/about/us.html +2 -0
  48. data/test/fixture/parent/control/index.html +1 -0
  49. data/test/fixture/parent/hyde.conf +8 -0
  50. data/test/fixture/parent/site/about/index.haml +3 -0
  51. data/test/fixture/parent/site/about/us.haml +3 -0
  52. data/test/fixture/parent/site/index.haml +3 -0
  53. data/test/fixture/sort/hyde.conf +8 -0
  54. data/test/fixture/sort/site/about/hardy.haml +4 -0
  55. data/test/fixture/sort/site/about/intrepid.haml +4 -0
  56. data/test/fixture/sort/site/about.haml +3 -0
  57. data/test/fixture/subclass/control/index.html +1 -0
  58. data/test/fixture/subclass/extensions/a/a.rb +12 -0
  59. data/test/fixture/subclass/hyde.conf +8 -0
  60. data/test/fixture/subclass/layouts/default.haml +1 -0
  61. data/test/fixture/subclass/layouts/post.haml +1 -0
  62. data/test/fixture/subclass/site/index.haml +4 -0
  63. data/test/helper.rb +15 -21
  64. data/test/unit/extensions_test.rb +16 -0
  65. data/test/unit/fixture_test.rb +77 -0
  66. data/test/unit/hyde_test.rb +30 -0
  67. metadata +107 -153
  68. data/.yardopts +0 -5
  69. data/LICENSE +0 -20
  70. data/VERSION +0 -1
  71. data/data/new_site/.gitignore +0 -24
  72. data/data/pages/404.html +0 -3
  73. data/hydeweb.gemspec +0 -159
  74. data/lib/hyde/clicommand.rb +0 -60
  75. data/lib/hyde/clicommands.rb +0 -128
  76. data/lib/hyde/ostruct.rb +0 -13
  77. data/lib/hyde/page_factory.rb +0 -90
  78. data/lib/hyde/renderer.rb +0 -133
  79. data/lib/hyde/renderers.rb +0 -100
  80. data/lib/hyde/sinatra/init.rb +0 -64
  81. data/lib/hyde/utils.rb +0 -43
  82. data/lib/hyde_misc/console.rb +0 -4
  83. data/manual/Extending/ExtendingHyde.md +0 -118
  84. data/manual/Hyde.md +0 -63
  85. data/manual/Introduction/Configuration.md +0 -70
  86. data/manual/Introduction/GettingStarted.md +0 -64
  87. data/manual/Introduction/Installation.md +0 -16
  88. data/manual/Introduction/Layouts.md +0 -14
  89. data/manual/Introduction/Metadata.md +0 -94
  90. data/manual/Introduction/Partials.md +0 -73
  91. data/manual/Introduction/TemplateLanguages.md +0 -59
  92. data/manual/Tips/Tips.md +0 -42
  93. data/test/fixtures/content_for/_config.yml +0 -8
  94. data/test/fixtures/content_for/layouts/cf-args.haml +0 -2
  95. data/test/fixtures/content_for/layouts/cf.haml +0 -14
  96. data/test/fixtures/content_for/layouts/default.haml +0 -4
  97. data/test/fixtures/content_for/layouts/shared/test.haml +0 -4
  98. data/test/fixtures/content_for/site/cf-args-default.haml +0 -2
  99. data/test/fixtures/content_for/site/cf-args.haml +0 -5
  100. data/test/fixtures/content_for/site/cf.haml +0 -6
  101. data/test/fixtures/content_for/site/cf2.haml +0 -3
  102. data/test/fixtures/content_for/site/index.html.haml +0 -9
  103. data/test/fixtures/content_for/site/var.html.haml +0 -5
  104. data/test/fixtures/content_for/www_control/cf-args-default.html +0 -1
  105. data/test/fixtures/content_for/www_control/cf-args.html +0 -2
  106. data/test/fixtures/content_for/www_control/cf.html +0 -17
  107. data/test/fixtures/content_for/www_control/cf2.html +0 -19
  108. data/test/fixtures/content_for/www_control/default.html +0 -2
  109. data/test/fixtures/content_for/www_control/index.html +0 -10
  110. data/test/fixtures/content_for/www_control/var.html +0 -2
  111. data/test/fixtures/custom/_config.yml +0 -8
  112. data/test/fixtures/custom/extensions/custom/custom.rb +0 -9
  113. data/test/fixtures/custom/layouts/default.haml +0 -8
  114. data/test/fixtures/custom/layouts/erbtest.erb +0 -2
  115. data/test/fixtures/custom/layouts/shared/sidebar.haml +0 -4
  116. data/test/fixtures/custom/site/about/index.html +0 -1
  117. data/test/fixtures/custom/site/assets/common.css.less +0 -1
  118. data/test/fixtures/custom/site/assets/style.css.less +0 -3
  119. data/test/fixtures/custom/site/foo.html.haml +0 -3
  120. data/test/fixtures/custom/site/index.html.haml +0 -6
  121. data/test/fixtures/custom/site/layout_test.html.haml +0 -6
  122. data/test/fixtures/custom/site/lol.html.erb +0 -7
  123. data/test/fixtures/custom/site/markdown.html.md +0 -8
  124. data/test/fixtures/custom/site/yes.html +0 -2
  125. data/test/fixtures/custom/www_control/about/index.html +0 -1
  126. data/test/fixtures/custom/www_control/assets/common.css +0 -1
  127. data/test/fixtures/custom/www_control/assets/style.css +0 -6
  128. data/test/fixtures/custom/www_control/foo.html +0 -1
  129. data/test/fixtures/custom/www_control/index.html +0 -16
  130. data/test/fixtures/custom/www_control/layout_test.html +0 -16
  131. data/test/fixtures/custom/www_control/lol.html +0 -5
  132. data/test/fixtures/custom/www_control/markdown.html +0 -17
  133. data/test/fixtures/custom/www_control/yes.html +0 -2
  134. data/test/fixtures/default/_config.yml +0 -8
  135. data/test/fixtures/default/extensions/custom/custom.rb +0 -2
  136. data/test/fixtures/default/layouts/default.haml +0 -5
  137. data/test/fixtures/default/site/about/index.html +0 -1
  138. data/test/fixtures/default/site/foo.html.haml +0 -3
  139. data/test/fixtures/default/site/index.html.haml +0 -6
  140. data/test/fixtures/default/site/layout_test.html.haml +0 -6
  141. data/test/fixtures/default/site/yes.html +0 -2
  142. data/test/fixtures/default/www_control/about/index.html +0 -1
  143. data/test/fixtures/default/www_control/foo.html +0 -1
  144. data/test/fixtures/default/www_control/index.html +0 -9
  145. data/test/fixtures/default/www_control/layout_test.html +0 -9
  146. data/test/fixtures/default/www_control/yes.html +0 -2
  147. data/test/test_all_fixtures.rb +0 -51
  148. data/test/test_build.rb +0 -20
  149. data/test/test_hyde.rb +0 -75
  150. data/test/test_page.rb +0 -26
  151. data/test/test_utils.rb +0 -22
data/lib/hyde/page.rb CHANGED
@@ -1,209 +1,257 @@
1
- module Hyde
2
- class Page
3
- include Hyde::Utils
1
+ class Hyde
2
+ class Page
3
+ attr_reader :project
4
+ attr_reader :file
5
+
6
+ # Returns the URL path for a page.
7
+ def path
8
+ path = @file.sub(root_path, '')
9
+
10
+ # if xx.haml (but not xx.html.haml),
11
+ if tilt?
12
+ path = path.sub(/\.[^\.]*$/, "")
13
+ path += ".#{default_ext}" unless File.basename(path).include?('.')
14
+ end
4
15
 
5
- attr :renderer
16
+ path
17
+ end
6
18
 
7
- # The filename of the source file.
8
- #
9
- # @example
10
- # puts page.name
11
- # puts page.filename
12
- #
13
- # # about/index.html
14
- # # about/index.html.haml
15
- #
16
- attr_accessor :filename
19
+ def title
20
+ (meta.title if tilt?) || path
21
+ end
17
22
 
18
- # Metadata hash
19
- attr_accessor :meta
23
+ alias to_s title
20
24
 
21
- # Path
22
- # @see {#filename} for an example
23
- attr_accessor :name
25
+ def <=>(other)
26
+ result = self.position <=> other.position
27
+ result ||= self.position.to_s <=> other.position.to_s
28
+ result
29
+ end
24
30
 
25
- # A reference to the parent {Project} instance
26
- attr_reader :project
31
+ def html?
32
+ mime_type == 'text/html'
33
+ end
27
34
 
28
- attr_accessor :referrer
35
+ def mime_type
36
+ return nil unless tilt?
29
37
 
30
- DEFAULT_LAYOUT = 'default'
38
+ mime = nil
39
+ mime = tilt_engine.default_mime_type if tilt_engine.respond_to?(:default_mime_type)
31
40
 
32
- # Factory
33
- #
34
- def self.[](path, project, def_page_class = Page)
35
- PageFactory.create path, project, def_page_class
41
+ mime ||= case tilt_engine.name
42
+ when 'Tilt::SassTemplate' then 'text/css'
43
+ when 'Tilt::ScssTemplate' then 'text/css'
44
+ when 'Tilt::LessTemplate' then 'text/css'
45
+ when 'Tilt::CoffeeScriptTemplate' then 'application/javascript'
46
+ when 'Tilt::NokogiriTemplate' then 'text/xml'
47
+ when 'Tilt::BuilderTemplate' then 'text/xml'
48
+ else 'text/html'
36
49
  end
50
+ end
37
51
 
38
- # Returns the rendered output.
39
- def render(data = {}, &block)
40
- output = content(data, &block)
41
- output = layout.render(get_data(data)) { output } unless layout.nil?
42
- output
52
+ def default_ext
53
+ case mime_type
54
+ when 'text/html' then 'html'
55
+ when 'text/css' then 'css'
56
+ when 'text/xml' then 'xml'
57
+ when 'application/javascript' then 'js'
43
58
  end
59
+ end
44
60
 
45
- # Returns the HTML content.
46
- def content(data = {}, &block)
47
- @renderer.render(get_data(data), &block)
48
- end
61
+ def self.[](id, project=$project)
62
+ site = lambda { |*x| File.join root_path(project), *(x.compact) }
63
+ try = lambda { |id| p = new(id, project); p if p.exists? }
49
64
 
50
- def layout=(val)
51
- @layout = val
65
+ # Account for:
66
+ # ~/mysite/site/about/us.html.haml
67
+ # about/us.html.haml => ~/mysite/site/about/us.html.haml
68
+ # about/us.html => ~/mysite/site/about/us.html.*
69
+ # about/us.html => ~/mysite/site/about/us.*
70
+ # about/us => ~/mysite/site/about/us/index.*
71
+ #
72
+ page = try[id]
73
+ page ||= try[site[id]]
74
+ page ||= try[Dir[site["#{id}.*"]].first]
75
+ page ||= try[Dir[site["#{id.to_s.sub(/\.[^\.]*/,'')}.*"]].first]
76
+ page ||= try[Dir[site[id, "index.*"]].first]
77
+
78
+ # Subclass
79
+ if page && page.tilt? && page.meta.type
80
+ klass = Page.get_type(page.meta.type)
81
+ raise Error, "Class for type '#{page.meta.type}' not found" unless klass
82
+ page = klass.new(id, project)
52
83
  end
84
+ page
85
+ end
53
86
 
54
- def layout
55
- begin
56
- @layout ||= project[DEFAULT_LAYOUT, :Layout] if !@renderer.nil? and @renderer.layoutable? and meta.layout != false
57
- @layout
58
- rescue NotFound
59
- nil
60
- end
61
- end
87
+ # Returns a page subtype.
88
+ # @example Page.get_type('post') => Hyde::Page::Post
89
+ def self.get_type(type)
90
+ klass = type[0].upcase + type[1..-1].downcase
91
+ klass = klass.to_sym
92
+ self.const_get(klass) if self.const_defined?(klass)
93
+ end
62
94
 
63
- def title
64
- @title ||= if meta.title
65
- meta.title
66
- elsif is_index?
67
- File.basename(File.dirname(filename))
68
- else
69
- File.basename(filename, '.*')
70
- end
71
- end
95
+ def initialize(file, project=$project)
96
+ @file = file
97
+ @project = project
98
+ raise Error if project.nil?
99
+ end
72
100
 
73
- # Returns the URL path for the page.
74
- def path
75
- @url ||= begin
76
- if renderer.is_a?(Renderer::Passthru)
77
- '/' + @name
78
- else
79
- url = [ File.dirname(@name), File.basename(@filename) ]
80
- url[1] = File.basename(url[1], '.*')
81
- url[1] = (url[1] + @renderer.default_ext) unless url[1].include?('.')
82
- '/' + url.join('/')
83
- end
84
- end
85
- end
101
+ def exists?
102
+ @file and File.file?(@file) and valid?
103
+ end
86
104
 
87
- def output_path
88
- File.join(project.config.output_path, path)
89
- end
105
+ # Make sure that it's in the right folder.
106
+ def valid?
107
+ prefix = File.expand_path(root_path)
108
+ prefix == File.expand_path(@file)[0...prefix.size]
109
+ end
90
110
 
91
- def get_binding #(&blk)
92
- binding
93
- end
111
+ def content(locals={}, &blk)
112
+ return markup unless tilt?
113
+ # Build scope
114
+ scope = self.dup
115
+ scope.extend Helpers
116
+ scope.meta.merge! locals
94
117
 
95
- def to_s
96
- name
97
- end
118
+ tilt.render(scope, &blk)
119
+ end
98
120
 
99
- def to_sym
100
- (filename).to_sym
101
- end
121
+ def to_html(locals={}, &blk)
122
+ html = content(locals, &blk)
123
+ html = layout.to_html(locals) { html } if layout?
124
+ html
125
+ end
102
126
 
103
- def <=>(other)
104
- result = self.position <=> other.position
105
- result ||= self.position.to_s <=> other.position.to_s
106
- result
107
- end
127
+ def layout
128
+ layout = meta.layout
129
+ layout ||= default_layout unless meta.layout == false
130
+ Layout[layout, page] if layout
131
+ end
108
132
 
109
- def position
110
- meta.position || title
111
- end
133
+ def page
134
+ self
135
+ end
112
136
 
113
- def parent
114
- folder = File.dirname(@name)
115
- folder = File.join(folder, '..') if is_index?
116
- folder = File.expand_path(folder)
137
+ def layout?
138
+ !! layout
139
+ end
117
140
 
118
- files = Dir[File.join(folder, 'index.*')]
119
- return nil if files.empty?
141
+ def meta
142
+ @meta ||= Meta.new(YAML::load(parts.first))
143
+ end
120
144
 
121
- page = PageFactory.create(files.first, @project)
122
- return nil if page === self
145
+ # Writes to the given output file.
146
+ def write(out=nil)
147
+ out ||= project.path(:output, path)
148
+ FileUtils.mkdir_p File.dirname(out)
123
149
 
124
- page
150
+ if tilt?
151
+ File.open(out, 'w') { |f| f.write to_html }
152
+ else
153
+ FileUtils.cp file, out
125
154
  end
155
+ end
126
156
 
127
- def children
128
- return [] unless is_index?
129
- folder = File.dirname(@name)
157
+ # Checks if the file is supported by tilt.
158
+ def tilt?
159
+ !! tilt_engine
160
+ end
130
161
 
131
- get_pages_from folder
132
- end
162
+ # Returns the Tilt engine (eg Tilt::HamlEngine).
163
+ def tilt_engine
164
+ Tilt[@file]
165
+ end
133
166
 
134
- def siblings
135
- folder = File.dirname(@name)
136
- folder = File.join(folder, '..') if is_index?
167
+ def tilt_engine_name
168
+ tilt_engine.name.match(/:([^:]*)(?:Template?)$/)[1]
169
+ end
137
170
 
138
- get_pages_from folder
171
+ # Returns the tilt layout.
172
+ def tilt
173
+ if tilt?
174
+ begin
175
+ # HAML options and such (like :escape_html)
176
+ options = project.config.tilt_options_for(@file)
177
+ offset = parts.first.count("\n") + 2
178
+ @tilt ||= Tilt.new(@file, offset, options) { markup }
179
+ rescue LoadError => e
180
+ gem = e.message.split(' ').last
181
+ ext = File.extname(@file)
182
+ raise NoGemError, "You need the '#{gem}' gem to parse #{ext} files."
183
+ end
139
184
  end
185
+ end
140
186
 
141
- def get_pages_from(folder)
142
- # Sanity check: don't go beyond the root
143
- return [] unless File.expand_path(folder).include?(File.expand_path(@project.root(:site)))
187
+ def markup
188
+ parts.last
189
+ end
144
190
 
145
- files = Dir[@project.root(:site, folder, '*')]
146
- files.inject([]) do |a, name|
147
- if File.directory?(name)
148
- name = Dir[File.join(name, 'index.*')].first
149
- a << PageFactory.create(name, @project) unless name.nil?
191
+ def method_missing(meth, *args, &blk)
192
+ super unless meta.instance_variable_get(:@table).keys.include?(meth.to_sym)
193
+ meta.send(meth)
194
+ end
150
195
 
151
- else
152
- page = PageFactory.create name, @project
153
- a << page unless page.is_index?
196
+ def parent
197
+ parts = path.split('/')
198
+ parent_path = index? ? parts[0...-2] : parts[0...-1]
199
+ self.class[parent_path.join('/'), project]
200
+ end
154
201
 
155
- end
156
- a
157
- end.sort
202
+ def children
203
+ files = if index?
204
+ # about/index.html => about/*
205
+ File.expand_path('../*', @file)
206
+ else
207
+ # products.html => products/*
208
+ base = File.basename(@file, '.*')
209
+ File.expand_path("../#{base}/*", @file)
158
210
  end
159
211
 
160
- # Returns an array of the page's ancestors, starting from the root page.
161
- def breadcrumbs
162
- @crumbs ||= parent.nil? ? [] : (parent.breadcrumbs + [parent])
163
- end
212
+ Dir[files].reject { |f| f == @file }.map { |f| self.class[f, project] }.compact.sort
213
+ end
164
214
 
165
- def ===(other)
166
- return false if other.nil?
167
- super || (File.expand_path(self.filename) === File.expand_path(other.filename))
168
- end
215
+ def siblings
216
+ p = parent and p.children
217
+ end
169
218
 
170
- def next
171
- siblings.each_cons(2) { |(i, other)| return other if i === self }
172
- end
219
+ def breadcrumbs
220
+ parent? ? (parent.breadcrumbs + [self]) : [self]
221
+ end
222
+
223
+ def index?
224
+ File.basename(path, '.*') == 'index'
225
+ end
173
226
 
174
- def previous
175
- siblings.each_cons(2) { |(other, i)| return other if i === self }
176
- end
227
+ def parent?
228
+ !parent.nil?
229
+ end
177
230
 
178
- def is_index?
179
- !@name.match(/(^|\/)index/).nil?
180
- end
231
+ def root?
232
+ parent.nil?
233
+ end
181
234
 
182
- protected
235
+ protected
236
+ def default_layout
237
+ 'default' if html?
238
+ end
183
239
 
184
- # Constructor.
185
- # The `page` argument is a page name
186
- # Don't use me: use {Project#[]}
187
- #
188
- def initialize(path, project, renderer, filename)
189
- @project = project
190
- @name ||= path
191
- @meta ||= Meta.new self
192
- @filename = filename
193
- @renderer = renderer.new(self, filename)
194
- end
195
-
196
- def self.get_filename(path, project)
197
- project.root(:site, path)
240
+ # Returns the two parts of the markup.
241
+ def parts
242
+ @parts ||= begin
243
+ t = File.open(@file).read.force_encoding('UTF-8')
244
+ m = t.match(/^(.*)--+\n(.*)$/m)
245
+ m.nil? ? ['', t] : [m[1], m[2]]
198
246
  end
247
+ end
199
248
 
200
- private
249
+ def self.root_path(project, *a)
250
+ project.path(:site, *a)
251
+ end
201
252
 
202
- # Data for rendering
203
- def get_data(data)
204
- data = @meta | data
205
- data[:page] ||= self
206
- data
207
- end
253
+ def root_path(*a)
254
+ self.class.root_path(project, *a)
208
255
  end
209
256
  end
257
+ end
data/lib/hyde/partial.rb CHANGED
@@ -1,7 +1,12 @@
1
- module Hyde
2
- class Partial < Layout
3
- def self.get_filename(path, project)
4
- project.root(:partials, path)
5
- end
1
+ class Hyde
2
+ class Partial < Layout
3
+ protected
4
+ def self.root_path(project, *a)
5
+ project.path(:partials, *a)
6
6
  end
7
+
8
+ def default_layout
9
+ nil
10
+ end
11
+ end
7
12
  end