nanoc 1.6.2 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +27 -0
- data/Rakefile +34 -27
- data/bin/nanoc +153 -49
- data/lib/nanoc.rb +15 -33
- data/lib/nanoc/base/auto_compiler.rb +124 -0
- data/lib/nanoc/base/compiler.rb +55 -0
- data/lib/nanoc/base/core_ext/hash.rb +34 -0
- data/lib/nanoc/base/data_source.rb +53 -0
- data/lib/nanoc/base/enhancements.rb +89 -0
- data/lib/nanoc/base/filter.rb +16 -0
- data/lib/nanoc/base/layout_processor.rb +33 -0
- data/lib/nanoc/base/page.rb +155 -0
- data/lib/nanoc/base/page_proxy.rb +31 -0
- data/lib/nanoc/base/plugin.rb +19 -0
- data/lib/nanoc/base/plugin_manager.rb +33 -0
- data/lib/nanoc/base/site.rb +143 -0
- data/lib/nanoc/data_sources/database.rb +259 -0
- data/lib/nanoc/data_sources/filesystem.rb +308 -0
- data/lib/nanoc/data_sources/trivial.rb +145 -0
- data/lib/nanoc/filters/erb.rb +34 -0
- data/lib/nanoc/filters/haml.rb +16 -0
- data/lib/nanoc/filters/markaby.rb +15 -0
- data/lib/nanoc/filters/markdown.rb +13 -0
- data/lib/nanoc/filters/rdoc.rb +14 -0
- data/lib/nanoc/filters/smartypants.rb +13 -0
- data/lib/nanoc/filters/textile.rb +13 -0
- data/lib/nanoc/layout_processors/erb.rb +35 -0
- data/lib/nanoc/layout_processors/haml.rb +18 -0
- data/lib/nanoc/layout_processors/markaby.rb +16 -0
- metadata +37 -30
- data/lib/nanoc/compiler.rb +0 -145
- data/lib/nanoc/core_ext.rb +0 -1
- data/lib/nanoc/core_ext/array.rb +0 -17
- data/lib/nanoc/core_ext/hash.rb +0 -43
- data/lib/nanoc/core_ext/string.rb +0 -13
- data/lib/nanoc/core_ext/yaml.rb +0 -10
- data/lib/nanoc/creator.rb +0 -180
- data/lib/nanoc/enhancements.rb +0 -101
- data/lib/nanoc/filters.rb +0 -7
- data/lib/nanoc/filters/eruby_filter.rb +0 -39
- data/lib/nanoc/filters/haml_filter.rb +0 -18
- data/lib/nanoc/filters/liquid_filter.rb +0 -47
- data/lib/nanoc/filters/markaby_filter.rb +0 -15
- data/lib/nanoc/filters/markdown_filter.rb +0 -13
- data/lib/nanoc/filters/rdoc_filter.rb +0 -15
- data/lib/nanoc/filters/sass_filter.rb +0 -13
- data/lib/nanoc/filters/smartypants_filter.rb +0 -13
- data/lib/nanoc/filters/textile_filter.rb +0 -13
- data/lib/nanoc/page.rb +0 -171
- data/lib/nanoc/page_drop.rb +0 -18
- data/lib/nanoc/page_proxy.rb +0 -30
data/ChangeLog
CHANGED
@@ -1,6 +1,33 @@
|
|
1
1
|
nanoc Release Notes
|
2
2
|
===================
|
3
3
|
|
4
|
+
2.0
|
5
|
+
---
|
6
|
+
|
7
|
+
New:
|
8
|
+
|
9
|
+
* Support for custom layout processors
|
10
|
+
* Support for custom data sources
|
11
|
+
* Database data source
|
12
|
+
* Auto-compiler
|
13
|
+
* Pages have `parent` and `children`
|
14
|
+
|
15
|
+
Changed:
|
16
|
+
|
17
|
+
* The source has been restructured and cleaned up a great deal
|
18
|
+
* Filters are defined in a different way now
|
19
|
+
* The 'eruby' filter now uses ERB instead of Erubis
|
20
|
+
|
21
|
+
Removed:
|
22
|
+
|
23
|
+
* The `filters` property; use `filters_pre` instead
|
24
|
+
* Support for Liquid
|
25
|
+
|
26
|
+
1.6.2
|
27
|
+
-----
|
28
|
+
|
29
|
+
* Fixed an issue which prevented the content capturing plugin from working
|
30
|
+
|
4
31
|
1.6.1
|
5
32
|
-----
|
6
33
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
##### Requirements
|
2
|
+
|
1
3
|
require 'rake'
|
2
4
|
|
3
5
|
require 'rake/clean'
|
@@ -6,50 +8,47 @@ require 'rake/testtask'
|
|
6
8
|
|
7
9
|
require File.dirname(__FILE__) + '/lib/nanoc.rb'
|
8
10
|
|
9
|
-
#####
|
11
|
+
##### General details
|
10
12
|
|
11
13
|
NAME = 'nanoc'
|
12
14
|
VERS = Nanoc::VERSION
|
13
|
-
SUMMARY = 'a
|
14
|
-
|
15
|
+
SUMMARY = 'a tool that runs on your local computer and compiles Markdown, ' +
|
16
|
+
'Textile, Haml, ... documents into static web pages'
|
15
17
|
HOMEPAGE = 'http://nanoc.stoneship.org/'
|
18
|
+
|
19
|
+
AUTHOR = 'Denis Defreyne'
|
16
20
|
EMAIL = 'denis.defreyne@stoneship.org'
|
17
21
|
|
18
|
-
#####
|
22
|
+
##### Cleaning
|
19
23
|
|
20
24
|
CLEAN.include [ 'tmp', 'test/fixtures/*/output/*', 'test/fixtures/*/tmp' ]
|
21
25
|
CLOBBER.include [ 'pkg' ]
|
22
26
|
|
27
|
+
##### Packaging
|
28
|
+
|
23
29
|
spec = Gem::Specification.new do |s|
|
24
|
-
s.name
|
25
|
-
s.version
|
26
|
-
s.platform
|
27
|
-
s.summary
|
28
|
-
s.description
|
29
|
-
s.homepage
|
30
|
-
s.email = EMAIL
|
30
|
+
s.name = NAME
|
31
|
+
s.version = VERS
|
32
|
+
s.platform = Gem::Platform::RUBY
|
33
|
+
s.summary = SUMMARY
|
34
|
+
s.description = s.summary
|
35
|
+
s.homepage = HOMEPAGE
|
31
36
|
|
32
|
-
s.
|
37
|
+
s.author = AUTHOR
|
38
|
+
s.email = EMAIL
|
33
39
|
|
34
|
-
s.
|
35
|
-
s.files = %w( README LICENSE ChangeLog Rakefile ) + Dir['{bin,lib}/**/*']
|
36
|
-
s.executables = [ 'nanoc' ]
|
37
|
-
s.require_path = 'lib'
|
38
|
-
s.bindir = 'bin'
|
39
|
-
end
|
40
|
+
s.rubyforge_project = 'nanoc'
|
40
41
|
|
41
|
-
|
42
|
-
task.need_tar = true
|
43
|
-
task.gem_spec = spec
|
44
|
-
end
|
42
|
+
s.required_ruby_version = '>= 1.8.2'
|
45
43
|
|
46
|
-
|
47
|
-
|
44
|
+
s.has_rdoc = false
|
45
|
+
s.files = %w( README LICENSE ChangeLog Rakefile ) + Dir['{bin,lib}/**/*']
|
46
|
+
s.executables = [ 'nanoc' ]
|
47
|
+
s.require_path = 'lib'
|
48
|
+
s.bindir = 'bin'
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
task :default => [ :test ]
|
51
|
+
Rake::GemPackageTask.new(spec) { |task| }
|
53
52
|
|
54
53
|
task :install_gem do
|
55
54
|
sh %{rake package}
|
@@ -59,3 +58,11 @@ end
|
|
59
58
|
task :uninstall_gem do
|
60
59
|
sh %{sudo gem uninstall #{NAME}}
|
61
60
|
end
|
61
|
+
|
62
|
+
### Testing
|
63
|
+
|
64
|
+
Rake::TestTask.new(:test) do |test|
|
65
|
+
test.test_files = Dir['test/test_*.rb']
|
66
|
+
end
|
67
|
+
|
68
|
+
task :default => [ :test ]
|
data/bin/nanoc
CHANGED
@@ -1,26 +1,35 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
3
|
+
# Get what we need
|
4
4
|
|
5
|
+
require File.dirname(__FILE__) + '/../lib/nanoc.rb'
|
5
6
|
require 'getoptlong'
|
6
7
|
|
7
|
-
|
8
|
+
# Helper functions
|
9
|
+
|
10
|
+
def usage(s)
|
11
|
+
error(s, 'Usage')
|
12
|
+
end
|
8
13
|
|
9
14
|
# Define some texts
|
15
|
+
|
10
16
|
version_text = "nanoc #{Nanoc::VERSION} (c) 2007 Denis Defreyne."
|
11
|
-
usage_text = "Usage: nanoc [options] [command] [parameters]"
|
12
17
|
help_text = <<EOT
|
13
|
-
Usage: nanoc [-
|
14
|
-
nanoc create_site <name>
|
15
|
-
nanoc create_page <name> [-t template]
|
16
|
-
nanoc create_template <name>
|
18
|
+
Usage: nanoc [-chvV]
|
17
19
|
nanoc compile
|
20
|
+
nanoc autocompile
|
21
|
+
nanoc create_layout [layout_name]
|
22
|
+
nanoc create_page [page_name] [-t template]
|
23
|
+
nanoc create_site [site_name]
|
24
|
+
nanoc create_template [template_name]
|
18
25
|
|
19
26
|
Options:
|
20
|
-
-h, --help
|
21
|
-
-
|
22
|
-
-t, --template
|
23
|
-
|
27
|
+
-h, --help Show this help message and quit.
|
28
|
+
-p, --port Port the autocompiler should be run on.
|
29
|
+
-t, --template Template that should be used when creating a page.
|
30
|
+
(can only be used with create_page)
|
31
|
+
-V, --verbose Display more verbose log messages.
|
32
|
+
-v, --version Show the nanoc version number and quit.
|
24
33
|
|
25
34
|
Description:
|
26
35
|
The 'nanoc' command is used for creating nanoc-powered sites, as well as
|
@@ -29,72 +38,167 @@ Description:
|
|
29
38
|
Read more about nanoc on the site: <http://nanoc.stoneship.org/>
|
30
39
|
EOT
|
31
40
|
|
41
|
+
# Create site
|
42
|
+
|
43
|
+
$nanoc_site = Nanoc::Site.from_cwd
|
44
|
+
|
32
45
|
# Parse options
|
46
|
+
|
33
47
|
opts = GetoptLong.new(
|
34
|
-
[ '--help',
|
35
|
-
[ '--
|
36
|
-
[ '--
|
48
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
49
|
+
[ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT ],
|
50
|
+
[ '--template', '-t', GetoptLong::REQUIRED_ARGUMENT ],
|
51
|
+
[ '--verbose', '-V', GetoptLong::NO_ARGUMENT ],
|
52
|
+
[ '--version', '-v', GetoptLong::NO_ARGUMENT ],
|
53
|
+
[ '--yes', '-y', GetoptLong::NO_ARGUMENT ]
|
37
54
|
)
|
38
|
-
unprocessed_opts = {}
|
55
|
+
$unprocessed_opts = {}
|
39
56
|
begin
|
40
57
|
opts.each do |opt, arg|
|
41
58
|
case opt
|
42
59
|
when '--help'
|
43
60
|
$stderr.puts help_text
|
44
61
|
exit
|
62
|
+
when '--verbose'
|
63
|
+
$log_level = :low
|
45
64
|
when '--version'
|
46
65
|
puts version_text
|
47
66
|
exit
|
48
67
|
else
|
49
|
-
unprocessed_opts[opt] = arg
|
68
|
+
$unprocessed_opts[opt] = arg
|
50
69
|
end
|
51
70
|
end
|
52
71
|
rescue GetoptLong::InvalidOption
|
53
72
|
$stderr.puts usage_text
|
54
|
-
exit
|
73
|
+
exit(1)
|
55
74
|
end
|
56
75
|
|
57
76
|
# Make sure we have at least one argument
|
58
|
-
|
59
|
-
|
60
|
-
|
77
|
+
|
78
|
+
usage 'nanoc [options] [command] [parameters]' if ARGV.size == 0
|
79
|
+
|
80
|
+
# Functions for handing commands
|
81
|
+
|
82
|
+
def setup
|
83
|
+
# Check syntax
|
84
|
+
usage 'Usage: nanoc setup' if ARGV.size != 1
|
85
|
+
|
86
|
+
# Make sure we are in a nanoc site directory
|
87
|
+
unless $nanoc_site
|
88
|
+
error 'The current working directory does not seem to ' +
|
89
|
+
'be a valid/complete nanoc site directory; aborting.'
|
90
|
+
end
|
91
|
+
|
92
|
+
# Check for -y switch
|
93
|
+
unless $unprocessed_opts.has_key?('--yes')
|
94
|
+
error 'Are you absolutely sure you want to set up the data source for ' +
|
95
|
+
'this site? Setting up the data source will remove existing ' +
|
96
|
+
'data. To continue, use the -y switch, like "nanoc setup -y".'
|
97
|
+
end
|
98
|
+
|
99
|
+
# Setup
|
100
|
+
$nanoc_site.setup
|
61
101
|
end
|
62
102
|
|
63
|
-
|
64
|
-
|
65
|
-
|
103
|
+
def create_site
|
104
|
+
# Check syntax
|
105
|
+
usage 'Usage: nanoc create_site [site_name] [options]' if ARGV.size != 2
|
106
|
+
|
66
107
|
# Create site
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
108
|
+
Nanoc::Site.create(ARGV[1])
|
109
|
+
end
|
110
|
+
|
111
|
+
def create_page
|
112
|
+
# Check syntax
|
113
|
+
usage 'Usage: nanoc create_page [page_name] [options]' if ARGV.size != 2
|
114
|
+
|
115
|
+
# Make sure we are in a nanoc site directory
|
116
|
+
unless $nanoc_site
|
117
|
+
error 'The current working directory does not seem to ' +
|
118
|
+
'be a valid/complete nanoc site directory; aborting.'
|
119
|
+
end
|
73
120
|
|
74
121
|
# Create page
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
122
|
+
if $unprocessed_opts['--template'].nil?
|
123
|
+
$nanoc_site.create_page(ARGV[1])
|
124
|
+
else
|
125
|
+
$nanoc_site.create_page(ARGV[1], $unprocessed_opts['--template'])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def create_layout
|
130
|
+
# Check syntax
|
131
|
+
usage 'nanoc create_layout [layout_name]' if ARGV.size != 2
|
132
|
+
|
133
|
+
# Make sure we are in a nanoc site directory
|
134
|
+
unless $nanoc_site
|
135
|
+
error 'The current working directory does not seem to ' +
|
136
|
+
'be a valid/complete nanoc site directory; aborting.'
|
137
|
+
end
|
81
138
|
|
82
139
|
# Create template
|
83
|
-
|
84
|
-
|
85
|
-
$stderr.puts 'Usage: nanoc create_template [template_name]'
|
86
|
-
exit
|
87
|
-
end
|
88
|
-
$nanoc_creator.create_template(ARGV[1])
|
140
|
+
$nanoc_site.create_layout(ARGV[1])
|
141
|
+
end
|
89
142
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
143
|
+
def create_template
|
144
|
+
# Check syntax
|
145
|
+
usage 'nanoc create_template [template_name]' if ARGV.size != 2
|
146
|
+
|
147
|
+
# Make sure we are in a nanoc site directory
|
148
|
+
unless $nanoc_site
|
149
|
+
error 'The current working directory does not seem to ' +
|
150
|
+
'be a valid/complete nanoc site directory; aborting.'
|
151
|
+
end
|
152
|
+
|
153
|
+
# Create template
|
154
|
+
$nanoc_site.create_template(ARGV[1])
|
155
|
+
end
|
97
156
|
|
157
|
+
def compile_site
|
158
|
+
# Check syntax
|
159
|
+
usage 'nanoc compile' if ARGV.size != 1
|
160
|
+
|
161
|
+
# Make sure we are in a nanoc site directory
|
162
|
+
unless $nanoc_site
|
163
|
+
error 'The current working directory does not seem to ' +
|
164
|
+
'be a valid/complete nanoc site directory; aborting.'
|
165
|
+
end
|
166
|
+
|
167
|
+
# Compile site
|
168
|
+
$nanoc_site.compile
|
169
|
+
end
|
170
|
+
|
171
|
+
def autocompile_site
|
172
|
+
# Check syntax
|
173
|
+
usage 'nanoc compile' if ARGV.size != 1
|
174
|
+
|
175
|
+
# Make sure we are in a nanoc site directory
|
176
|
+
unless $nanoc_site
|
177
|
+
error 'The current working directory does not seem to ' +
|
178
|
+
'be a valid/complete nanoc site directory; aborting.'
|
179
|
+
end
|
180
|
+
|
181
|
+
# Autocompile site
|
182
|
+
$nanoc_site.autocompile($unprocessed_opts['--port'])
|
183
|
+
end
|
184
|
+
|
185
|
+
# Handle command
|
186
|
+
|
187
|
+
case ARGV[0]
|
188
|
+
when 'autocompile_site', 'autocompile', 'aco'
|
189
|
+
autocompile_site
|
190
|
+
when 'create_site', 'cs'
|
191
|
+
create_site
|
192
|
+
when 'create_page', 'cp'
|
193
|
+
create_page
|
194
|
+
when 'create_layout', 'cl'
|
195
|
+
create_layout
|
196
|
+
when 'create_template', 'ct'
|
197
|
+
create_template
|
198
|
+
when 'compile_site', 'compile', 'co'
|
199
|
+
compile_site
|
200
|
+
when 'setup', 's'
|
201
|
+
setup
|
98
202
|
else
|
99
|
-
|
203
|
+
error 'Unrecognised command \'' + ARGV[0] + '\''
|
100
204
|
end
|
data/lib/nanoc.rb
CHANGED
@@ -1,42 +1,24 @@
|
|
1
1
|
module Nanoc
|
2
2
|
|
3
|
-
VERSION = '
|
3
|
+
VERSION = '2.0'
|
4
4
|
|
5
|
-
def self.
|
6
|
-
|
7
|
-
|
8
|
-
'be a valid/complete nanoc site directory; aborting.' unless $quiet
|
9
|
-
exit
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def self.in_site?
|
16
|
-
return false unless File.directory?('content')
|
17
|
-
return false unless File.directory?('layouts')
|
18
|
-
return false unless File.directory?('lib')
|
19
|
-
return false unless File.directory?('tasks')
|
20
|
-
return false unless File.directory?('templates')
|
21
|
-
return false unless File.exist?('config.yaml')
|
22
|
-
return false unless File.exist?('meta.yaml')
|
23
|
-
return false unless File.exist?('Rakefile')
|
24
|
-
|
25
|
-
true
|
5
|
+
def self.load_file(*path)
|
6
|
+
full_path = [ File.dirname(__FILE__), 'nanoc' ] + path
|
7
|
+
Dir[File.join(full_path)].each { |f| require f }
|
26
8
|
end
|
27
9
|
|
28
10
|
end
|
29
11
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
12
|
+
# Load base
|
13
|
+
Nanoc.load_file('base', 'enhancements.rb')
|
14
|
+
Nanoc.load_file('base', 'core_ext', '*.rb')
|
15
|
+
Nanoc.load_file('base', 'plugin.rb')
|
16
|
+
Nanoc.load_file('base', '*.rb')
|
34
17
|
|
35
|
-
|
36
|
-
|
18
|
+
# Load plugins
|
19
|
+
Nanoc.load_file('data_sources', '*.rb')
|
20
|
+
Nanoc.load_file('filters', '*.rb')
|
21
|
+
Nanoc.load_file('layout_processors', '*.rb')
|
37
22
|
|
38
|
-
|
39
|
-
|
40
|
-
require File.dirname(__FILE__) + '/nanoc/page.rb'
|
41
|
-
require File.dirname(__FILE__) + '/nanoc/page_drop.rb'
|
42
|
-
require File.dirname(__FILE__) + '/nanoc/page_proxy.rb'
|
23
|
+
# Get global binding
|
24
|
+
$nanoc_binding = binding
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
|
5
|
+
class AutoCompiler
|
6
|
+
|
7
|
+
ERROR_404 = <<END
|
8
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
9
|
+
<html>
|
10
|
+
<head>
|
11
|
+
<title>404 File Not Found</title>
|
12
|
+
<style type="text/css">
|
13
|
+
body { padding: 10px; border: 10px solid #f00; margin: 10px; font-family: Helvetica, Arial, sans-serif; }
|
14
|
+
</style>
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
<h1>404 File Not Found</h1>
|
18
|
+
<p>The file you requested, <i><%=h path %></i>, was not found on this server.</p>
|
19
|
+
</body>
|
20
|
+
</html>
|
21
|
+
END
|
22
|
+
|
23
|
+
ERROR_500 = <<END
|
24
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
25
|
+
<html>
|
26
|
+
<head>
|
27
|
+
<title>500 Server Error</title>
|
28
|
+
<style type="text/css">
|
29
|
+
body { padding: 10px; border: 10px solid #f00; margin: 10px; font-family: Helvetica, Arial, sans-serif; }
|
30
|
+
</style>
|
31
|
+
</head>
|
32
|
+
<body>
|
33
|
+
<h1>500 Server Error</h1>
|
34
|
+
<p>An error occurred while compiling the page you requested, <i><%=h path %></i>.</p>
|
35
|
+
<p>If you think this is a bug in nanoc, please do <a href="http://nanoc.stoneship.org/trac/newticket">report it</a>—thanks!</p>
|
36
|
+
<p>Message:</p>
|
37
|
+
<blockquote><p><%=h exception.message %></p></blockquote>
|
38
|
+
<p>Backtrace:</p>
|
39
|
+
<ol>
|
40
|
+
<% exception.backtrace.each do |line| %>
|
41
|
+
<li><%= line %></li>
|
42
|
+
<% end %>
|
43
|
+
</ol>
|
44
|
+
</body>
|
45
|
+
</html>
|
46
|
+
END
|
47
|
+
|
48
|
+
def initialize(site)
|
49
|
+
# Set site
|
50
|
+
@site = site
|
51
|
+
end
|
52
|
+
|
53
|
+
def start(port)
|
54
|
+
nanoc_require('mime/types', "'mime/types' is required to autocompile sites.")
|
55
|
+
|
56
|
+
# Create server
|
57
|
+
@server = WEBrick::HTTPServer.new(:Port => port || 3000)
|
58
|
+
@server.mount_proc("/") { |request, response| handle_request(request, response) }
|
59
|
+
|
60
|
+
# Start server
|
61
|
+
trap('INT') { @server.shutdown }
|
62
|
+
@server.start
|
63
|
+
end
|
64
|
+
|
65
|
+
def handle_request(request, response)
|
66
|
+
# Reload site data
|
67
|
+
@site.load_data(true)
|
68
|
+
|
69
|
+
# Get page or file
|
70
|
+
page = @site.pages.find { |page| page.path == request.path }
|
71
|
+
file_path = @site.config[:output_dir] + request.path
|
72
|
+
|
73
|
+
if page.nil?
|
74
|
+
# Serve file
|
75
|
+
if File.exist?(file_path)
|
76
|
+
serve_file(file_path, response)
|
77
|
+
else
|
78
|
+
serve_404(request.path, response)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
# Serve page
|
82
|
+
serve_page(page, response)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def h(s)
|
87
|
+
ERB::Util.html_escape(s)
|
88
|
+
end
|
89
|
+
|
90
|
+
def serve_404(path, response)
|
91
|
+
response.status = 404
|
92
|
+
response['Content-Type'] = 'text/html'
|
93
|
+
response.body = ERB.new(ERROR_404).result(binding)
|
94
|
+
end
|
95
|
+
|
96
|
+
def serve_500(path, exception, response)
|
97
|
+
response.status = 500
|
98
|
+
response['Content-Type'] = 'text/html'
|
99
|
+
response.body = ERB.new(ERROR_500).result(binding)
|
100
|
+
end
|
101
|
+
|
102
|
+
def serve_file(path, response)
|
103
|
+
response.status = 200
|
104
|
+
response['Content-Type'] = MIME::Types.of(path).first || 'application/octet-stream'
|
105
|
+
response.body = File.read(path)
|
106
|
+
end
|
107
|
+
|
108
|
+
def serve_page(page, response)
|
109
|
+
# Recompile page
|
110
|
+
begin
|
111
|
+
@site.compiler.run(page)
|
112
|
+
rescue => exception
|
113
|
+
serve_500(page.path, exception, response)
|
114
|
+
return
|
115
|
+
end
|
116
|
+
|
117
|
+
response.status = 200
|
118
|
+
response['Content-Type'] = 'text/html'
|
119
|
+
response.body = page.layouted_content
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|