frank 0.2.6 → 0.3.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/Featurelist +6 -0
- data/README.md +44 -32
- data/Rakefile +3 -3
- data/frank.gemspec +51 -45
- data/lib/frank.rb +1 -0
- data/lib/frank/base.rb +144 -94
- data/lib/frank/lorem.rb +77 -36
- data/lib/frank/middleware/imager.rb +43 -0
- data/lib/frank/middleware/refresh.rb +42 -0
- data/lib/frank/middleware/statik.rb +41 -0
- data/lib/frank/output.rb +25 -37
- data/lib/frank/rescue.rb +13 -6
- data/lib/frank/template_helpers.rb +34 -3
- data/lib/frank/templates/404.haml +1 -0
- data/lib/frank/templates/500.haml +2 -0
- data/lib/frank/tilt.rb +389 -141
- data/lib/template/{dynamic/layout.haml → layouts/default.haml} +0 -0
- data/lib/template/settings.yml +15 -28
- data/spec/base_spec.rb +88 -0
- data/{test → spec}/helper.rb +0 -7
- data/spec/output_spec.rb +220 -0
- data/spec/render_spec.rb +106 -0
- data/spec/template/dynamic/500.haml +1 -0
- data/{test → spec}/template/dynamic/_partial.haml +0 -0
- data/{test → spec}/template/dynamic/builder.builder +0 -0
- data/{test → spec}/template/dynamic/coffee.coffee +0 -0
- data/{test → spec}/template/dynamic/erb.erb +0 -0
- data/{test → spec}/template/dynamic/helper_test.haml +0 -0
- data/spec/template/dynamic/index.haml +5 -0
- data/spec/template/dynamic/layout2_test.haml +4 -0
- data/{test → spec}/template/dynamic/liquid.liquid +0 -0
- data/spec/template/dynamic/lorem_test.haml +7 -0
- data/{test → spec}/template/dynamic/markdown.md +0 -0
- data/spec/template/dynamic/markdown_in_haml.md +4 -0
- data/{test → spec}/template/dynamic/mustache.mustache +0 -0
- data/spec/template/dynamic/nested/child.haml +1 -0
- data/spec/template/dynamic/nested/deeper/deep.haml +1 -0
- data/spec/template/dynamic/no_layout.haml +4 -0
- data/spec/template/dynamic/partial_test.haml +2 -0
- data/{test → spec}/template/dynamic/redcloth.textile +0 -0
- data/spec/template/dynamic/refresh.haml +1 -0
- data/{test → spec}/template/dynamic/sass.sass +0 -0
- data/{test → spec}/template/helpers.rb +0 -0
- data/spec/template/layouts/default.haml +3 -0
- data/{test/template/dynamic → spec/template/layouts/explicit}/layout2.haml +0 -0
- data/spec/template/layouts/nested/default.haml +2 -0
- data/spec/template/settings.yml +45 -0
- data/{test/template/static → spec/template/static/files}/static.html +0 -0
- data/spec/template_helpers_spec.rb +78 -0
- metadata +57 -49
- data/lib/frank/imager.rb +0 -39
- data/lib/frank/statik.rb +0 -39
- data/test/suite.rb +0 -4
- data/test/template/dynamic/index.haml +0 -2
- data/test/template/dynamic/layout.haml +0 -2
- data/test/template/dynamic/layout2_test.haml +0 -1
- data/test/template/dynamic/layout_test.haml +0 -1
- data/test/template/dynamic/lorem_test.haml +0 -7
- data/test/template/dynamic/partial_test.haml +0 -2
- data/test/template/settings.yml +0 -62
- data/test/test_base.rb +0 -81
- data/test/test_helpers.rb +0 -71
- data/test/test_output.rb +0 -160
- data/test/test_render.rb +0 -89
data/Featurelist
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
- DONE - support layouts of a different type than the rendered template
|
2
|
+
dynamically reload template changes using javascript and a slick url
|
3
|
+
dynamically reload helpers and settings
|
4
|
+
- DONE - support yaml variable definition at the top of templates
|
5
|
+
- DONE - add helper for "selected" css class, this should work with frankup and frankout
|
6
|
+
- DONE - add frankout replacement fields to lorem helpers
|
data/README.md
CHANGED
@@ -25,22 +25,21 @@ Then `cd <project_name>` and start up the server with:
|
|
25
25
|
Frank's holdin' it down...
|
26
26
|
0.0.0.0:3601
|
27
27
|
|
28
|
-
And you're ready to get to work. By default, dynamic templates are served from the `dynamic` folder
|
29
|
-
|
28
|
+
And you're ready to get to work. By default, dynamic templates are served from the `dynamic` folder,
|
29
|
+
static files are served from the `static` folder, and layouts are server from the `layouts` folder.
|
30
30
|
|
31
31
|
When you are finished:
|
32
|
-
|
33
|
-
$ frankout <dump_dir> # compile templates
|
32
|
+
`$ frankout <dump_dir> # compile templates`
|
34
33
|
|
35
34
|
or
|
36
35
|
|
37
|
-
|
36
|
+
`$ frankout --production <dump_dir> # compile and create folder structure suitable for serving from a production website`
|
38
37
|
|
39
|
-
Views &
|
38
|
+
Views & Meta Data
|
40
39
|
-------------------------
|
41
40
|
|
42
41
|
All of your templates, and less/sass/coffeescript go into `<project>/dynamic`,
|
43
|
-
by default. You
|
42
|
+
by default. You can organize them into subfolders if you've
|
44
43
|
got lots.
|
45
44
|
|
46
45
|
### Views
|
@@ -48,21 +47,36 @@ got lots.
|
|
48
47
|
Writing views is simple. Say you've got a `blog.haml`, in `<project>/dynamic` just browse to
|
49
48
|
`http://0.0.0.0:3601/blog` and your view will be parsed and returned as html.
|
50
49
|
|
51
|
-
###
|
50
|
+
### Meta Data
|
51
|
+
|
52
|
+
Frank doesn't have controllers and there are times you need to pass variables around between templates and layouts.
|
53
|
+
This can be done with template Meta data. Meta data is set using YAML.
|
54
|
+
|
55
|
+
You define your fields at the top a template
|
56
|
+
a separate it from the rest of your template using the Meta delimiter: `META--------`. The delimiter can contain as
|
57
|
+
many dashes, or hyphens as you wish.
|
58
|
+
|
59
|
+
You can access your fields as local variables in the template (if the template language supports it).
|
60
|
+
For example, you might have a template and define a field `title: My Rad Template`, then inside a haml layout,
|
61
|
+
you could create a title tag with the field: `%title= title`
|
52
62
|
|
53
|
-
Layouts
|
54
|
-
|
63
|
+
Layouts (updated in 0.3)
|
64
|
+
-----------------------------
|
65
|
+
|
66
|
+
Layouts are also simple with Frank. By default, just create a `default.haml`
|
67
|
+
(or another language), inside the `layouts` folder and include a `yield` statement. Any
|
55
68
|
views will be inserted into it at that point.
|
56
69
|
|
57
|
-
|
70
|
+
Layouts can be name spaced with folders:
|
71
|
+
|
72
|
+
a template: `dynamic_folder/blog/a-blog-post.haml`
|
73
|
+
would look for a layout: `layouts/blog/default.haml`
|
74
|
+
and if not found use the default: `layouts/default.haml`
|
75
|
+
|
76
|
+
Frank also supports defining layouts on an individual template basis using meta data
|
77
|
+
you can do this by defining a meta field `layout: my_layout.haml` You can disable layouts on a
|
78
|
+
template by using `layout: nil`
|
58
79
|
|
59
|
-
layouts:
|
60
|
-
- name: blog_layout
|
61
|
-
only: [blog]
|
62
|
-
- name: normal
|
63
|
-
not: [blog, ajax]
|
64
|
-
This tells Frank to use `blog_layout.haml` for `/blog`, and `normal.haml`
|
65
|
-
for everything but `/blog' and '/ajax`.
|
66
80
|
|
67
81
|
|
68
82
|
Partials & Helpers
|
@@ -93,7 +107,13 @@ to the `FrankHelpers` module; that's it. Use them just like `render_partial`.
|
|
93
107
|
Built-in Helpers
|
94
108
|
----------------
|
95
109
|
|
96
|
-
|
110
|
+
### Auto Refresh
|
111
|
+
|
112
|
+
Constantly refreshing your browser can become tedious while doing work. Frank has a handy refresh helper.
|
113
|
+
It will include a bit of javascript that refreshes the browser when you save the current template or it's layout.
|
114
|
+
You can include this in a haml template like this: `= refresh`. When you `frankout`,
|
115
|
+
the template will render an empty string instead of the script tag
|
116
|
+
|
97
117
|
|
98
118
|
### Placeholder Text
|
99
119
|
|
@@ -113,7 +133,7 @@ This will return 3 sentences of standard [Lorem Ipsum][11]. `lorem` also has all
|
|
113
133
|
lorem.first_name
|
114
134
|
lorem.last_name
|
115
135
|
lorem.email
|
116
|
-
|
136
|
+
|
117
137
|
|
118
138
|
### Placeholder Images
|
119
139
|
|
@@ -129,19 +149,11 @@ The `lorem.image` helper returns a special Frank image URL. In this case, the re
|
|
129
149
|
|
130
150
|
If you would like to use the placeholder images in a context where the helper methods are unavailable (e.g. in static CSS or JavaScript), you can access the URL directly with `/_img/500x400.jpg`, or for random images `/_img/500x400.jpg?random`.
|
131
151
|
|
152
|
+
### Replacement Text
|
132
153
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
Sometimes it's nice to include user input in your mock-ups. It's especially
|
138
|
-
handy when mocking-up Ajax-driven elements. For this reason, the `request`
|
139
|
-
and `params` are available in your templates.
|
140
|
-
|
141
|
-
For example, to use a person's name submitted through a form you might do:
|
142
|
-
|
143
|
-
%h1= "Hello, #{params.name}"
|
144
|
-
|
154
|
+
All of the lorem helpers accept an optional "replacement" argument. This will be the text rendered when you `frankout`.
|
155
|
+
For example `lorem.sentence("<%= page.content %>")` will generate a lorem sentence when you view the page using the `frankup` server.
|
156
|
+
However, when you `frankout` the template will render "<%= page.content %>".
|
145
157
|
|
146
158
|
|
147
159
|
Configuration
|
data/Rakefile
CHANGED
@@ -4,8 +4,8 @@ begin
|
|
4
4
|
require 'jeweler'
|
5
5
|
Jeweler::Tasks.new do |gemspec|
|
6
6
|
gemspec.name = "frank"
|
7
|
-
gemspec.summary = "
|
8
|
-
gemspec.description = "
|
7
|
+
gemspec.summary = "Static Site Non-Framework"
|
8
|
+
gemspec.description = "Rapidly develop static sites using any supported templating language"
|
9
9
|
gemspec.version = Frank::VERSION
|
10
10
|
gemspec.email = "travis.dunn@thisismedium.com"
|
11
11
|
gemspec.homepage = "http://github.com/blahed/frank"
|
@@ -13,7 +13,7 @@ begin
|
|
13
13
|
gemspec.add_dependency 'rack', '>=1.0'
|
14
14
|
gemspec.add_dependency 'mongrel', '>=1.0'
|
15
15
|
gemspec.add_dependency 'haml', '>=2.0'
|
16
|
-
gemspec.add_development_dependency '
|
16
|
+
gemspec.add_development_dependency 'rspec'
|
17
17
|
gemspec.add_development_dependency 'rack-test', '>=0.5'
|
18
18
|
|
19
19
|
end
|
data/frank.gemspec
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in
|
3
|
+
# Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{frank}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0.beta"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["blahed", "nwah"]
|
12
|
-
s.date = %q{2010-
|
13
|
-
s.description = %q{
|
12
|
+
s.date = %q{2010-06-12}
|
13
|
+
s.description = %q{Rapidly develop static sites using any supported templating language}
|
14
14
|
s.email = %q{travis.dunn@thisismedium.com}
|
15
15
|
s.executables = ["frank", "frankout", "frankup"]
|
16
16
|
s.extra_rdoc_files = [
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
]
|
20
20
|
s.files = [
|
21
21
|
".gitignore",
|
22
|
+
"Featurelist",
|
22
23
|
"LICENSE",
|
23
24
|
"README.md",
|
24
25
|
"Rakefile",
|
@@ -28,11 +29,12 @@ Gem::Specification.new do |s|
|
|
28
29
|
"frank.gemspec",
|
29
30
|
"lib/frank.rb",
|
30
31
|
"lib/frank/base.rb",
|
31
|
-
"lib/frank/imager.rb",
|
32
32
|
"lib/frank/lorem.rb",
|
33
|
+
"lib/frank/middleware/imager.rb",
|
34
|
+
"lib/frank/middleware/refresh.rb",
|
35
|
+
"lib/frank/middleware/statik.rb",
|
33
36
|
"lib/frank/output.rb",
|
34
37
|
"lib/frank/rescue.rb",
|
35
|
-
"lib/frank/statik.rb",
|
36
38
|
"lib/frank/template_helpers.rb",
|
37
39
|
"lib/frank/templates/404.haml",
|
38
40
|
"lib/frank/templates/500.haml",
|
@@ -51,51 +53,55 @@ Gem::Specification.new do |s|
|
|
51
53
|
"lib/frank/tilt.rb",
|
52
54
|
"lib/template/dynamic/css/frank.sass",
|
53
55
|
"lib/template/dynamic/index.haml",
|
54
|
-
"lib/template/dynamic/layout.haml",
|
55
56
|
"lib/template/helpers.rb",
|
57
|
+
"lib/template/layouts/default.haml",
|
56
58
|
"lib/template/settings.yml",
|
57
59
|
"lib/template/static/images/frank-med.png",
|
58
60
|
"lib/template/static/js/frank.js",
|
59
|
-
"
|
60
|
-
"
|
61
|
-
"
|
62
|
-
"
|
63
|
-
"
|
64
|
-
"
|
65
|
-
"
|
66
|
-
"
|
67
|
-
"
|
68
|
-
"
|
69
|
-
"
|
70
|
-
"
|
71
|
-
"
|
72
|
-
"
|
73
|
-
"
|
74
|
-
"
|
75
|
-
"
|
76
|
-
"
|
77
|
-
"
|
78
|
-
"
|
79
|
-
"
|
80
|
-
"
|
81
|
-
"
|
82
|
-
"
|
83
|
-
"
|
84
|
-
"
|
61
|
+
"spec/base_spec.rb",
|
62
|
+
"spec/helper.rb",
|
63
|
+
"spec/output_spec.rb",
|
64
|
+
"spec/render_spec.rb",
|
65
|
+
"spec/template/dynamic/500.haml",
|
66
|
+
"spec/template/dynamic/_partial.haml",
|
67
|
+
"spec/template/dynamic/builder.builder",
|
68
|
+
"spec/template/dynamic/coffee.coffee",
|
69
|
+
"spec/template/dynamic/erb.erb",
|
70
|
+
"spec/template/dynamic/helper_test.haml",
|
71
|
+
"spec/template/dynamic/index.haml",
|
72
|
+
"spec/template/dynamic/layout2_test.haml",
|
73
|
+
"spec/template/dynamic/liquid.liquid",
|
74
|
+
"spec/template/dynamic/lorem_test.haml",
|
75
|
+
"spec/template/dynamic/markdown.md",
|
76
|
+
"spec/template/dynamic/markdown_in_haml.md",
|
77
|
+
"spec/template/dynamic/mustache.mustache",
|
78
|
+
"spec/template/dynamic/nested/child.haml",
|
79
|
+
"spec/template/dynamic/nested/deeper/deep.haml",
|
80
|
+
"spec/template/dynamic/no_layout.haml",
|
81
|
+
"spec/template/dynamic/partial_test.haml",
|
82
|
+
"spec/template/dynamic/redcloth.textile",
|
83
|
+
"spec/template/dynamic/refresh.haml",
|
84
|
+
"spec/template/dynamic/sass.sass",
|
85
|
+
"spec/template/helpers.rb",
|
86
|
+
"spec/template/layouts/default.haml",
|
87
|
+
"spec/template/layouts/explicit/layout2.haml",
|
88
|
+
"spec/template/layouts/nested/default.haml",
|
89
|
+
"spec/template/settings.yml",
|
90
|
+
"spec/template/static/files/static.html",
|
91
|
+
"spec/template_helpers_spec.rb"
|
85
92
|
]
|
86
93
|
s.homepage = %q{http://github.com/blahed/frank}
|
87
94
|
s.rdoc_options = ["--charset=UTF-8"]
|
88
95
|
s.require_paths = ["lib"]
|
89
96
|
s.rubygems_version = %q{1.3.6}
|
90
|
-
s.summary = %q{
|
97
|
+
s.summary = %q{Static Site Non-Framework}
|
91
98
|
s.test_files = [
|
92
|
-
"
|
93
|
-
"
|
94
|
-
"
|
95
|
-
"
|
96
|
-
"
|
97
|
-
"
|
98
|
-
"test/test_render.rb"
|
99
|
+
"spec/base_spec.rb",
|
100
|
+
"spec/helper.rb",
|
101
|
+
"spec/output_spec.rb",
|
102
|
+
"spec/render_spec.rb",
|
103
|
+
"spec/template/helpers.rb",
|
104
|
+
"spec/template_helpers_spec.rb"
|
99
105
|
]
|
100
106
|
|
101
107
|
if s.respond_to? :specification_version then
|
@@ -106,20 +112,20 @@ Gem::Specification.new do |s|
|
|
106
112
|
s.add_runtime_dependency(%q<rack>, [">= 1.0"])
|
107
113
|
s.add_runtime_dependency(%q<mongrel>, [">= 1.0"])
|
108
114
|
s.add_runtime_dependency(%q<haml>, [">= 2.0"])
|
109
|
-
s.add_development_dependency(%q<
|
115
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
110
116
|
s.add_development_dependency(%q<rack-test>, [">= 0.5"])
|
111
117
|
else
|
112
118
|
s.add_dependency(%q<rack>, [">= 1.0"])
|
113
119
|
s.add_dependency(%q<mongrel>, [">= 1.0"])
|
114
120
|
s.add_dependency(%q<haml>, [">= 2.0"])
|
115
|
-
s.add_dependency(%q<
|
121
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
116
122
|
s.add_dependency(%q<rack-test>, [">= 0.5"])
|
117
123
|
end
|
118
124
|
else
|
119
125
|
s.add_dependency(%q<rack>, [">= 1.0"])
|
120
126
|
s.add_dependency(%q<mongrel>, [">= 1.0"])
|
121
127
|
s.add_dependency(%q<haml>, [">= 2.0"])
|
122
|
-
s.add_dependency(%q<
|
128
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
123
129
|
s.add_dependency(%q<rack-test>, [">= 0.5"])
|
124
130
|
end
|
125
131
|
end
|
data/lib/frank.rb
CHANGED
data/lib/frank/base.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'frank/tilt'
|
2
2
|
require 'frank/template_helpers'
|
3
3
|
require 'frank/rescue'
|
4
|
-
require 'frank/statik'
|
5
|
-
require 'frank/imager'
|
4
|
+
require 'frank/middleware/statik'
|
5
|
+
require 'frank/middleware/imager'
|
6
|
+
require 'frank/middleware/refresh'
|
6
7
|
|
7
8
|
module Frank
|
8
|
-
VERSION = '0.
|
9
|
+
VERSION = '0.3.0.beta'
|
9
10
|
|
10
11
|
module Render; end
|
11
12
|
|
@@ -15,7 +16,13 @@ module Frank
|
|
15
16
|
include Frank::TemplateHelpers
|
16
17
|
include Frank::Render
|
17
18
|
|
18
|
-
attr_accessor
|
19
|
+
attr_accessor :environment
|
20
|
+
attr_accessor :proj_dir
|
21
|
+
attr_accessor :server
|
22
|
+
attr_accessor :static_folder
|
23
|
+
attr_accessor :dynamic_folder
|
24
|
+
attr_accessor :layouts_folder
|
25
|
+
attr_accessor :templates
|
19
26
|
|
20
27
|
def initialize(&block)
|
21
28
|
instance_eval &block
|
@@ -46,9 +53,9 @@ module Frank
|
|
46
53
|
# attempt to render with the request path,
|
47
54
|
# if it cannot be found, render error page
|
48
55
|
def process
|
49
|
-
|
50
|
-
@response['Content-Type'] = Rack::Mime.mime_type(
|
51
|
-
@response.write
|
56
|
+
load_helpers
|
57
|
+
@response['Content-Type'] = Rack::Mime.mime_type(File.extname(@request.path), 'text/html')
|
58
|
+
@response.write render(@request.path)
|
52
59
|
rescue Frank::TemplateError
|
53
60
|
render_404
|
54
61
|
rescue Exception => e
|
@@ -57,115 +64,158 @@ module Frank
|
|
57
64
|
|
58
65
|
# prints requests and errors to STDOUT
|
59
66
|
def log_request(status, excp=nil)
|
60
|
-
out = "[#{Time.now.strftime('%Y-%m-%d %H:%M')}] (#{@request.request_method}) http://#{@request.host}:#{@request.port}#{@request.fullpath} - #{status}"
|
61
|
-
out
|
62
|
-
|
67
|
+
out = "\033[1m[#{Time.now.strftime('%Y-%m-%d %H:%M')}]\033[22m (#{@request.request_method}) http://#{@request.host}:#{@request.port}#{@request.fullpath} - #{status}"
|
68
|
+
out << "\n\n#{excp.message}\n\n#{excp.backtrace.join("\n")} " if excp
|
69
|
+
puts out
|
70
|
+
end
|
71
|
+
|
72
|
+
def load_helpers
|
73
|
+
helpers = File.join(@proj_dir, 'helpers.rb')
|
74
|
+
if File.exist? helpers
|
75
|
+
load helpers
|
76
|
+
Frank::TemplateHelpers.class_eval("include FrankHelpers")
|
77
|
+
end
|
63
78
|
end
|
64
79
|
|
65
80
|
end
|
66
81
|
|
67
82
|
module Render
|
68
83
|
|
69
|
-
|
70
|
-
|
71
|
-
|
84
|
+
TMPL_EXTS = {
|
85
|
+
:html => %w[haml erb rhtml builder liquid mustache textile md mkd markdown],
|
86
|
+
:css => %w[sass less],
|
87
|
+
:js => %w[coffee]
|
88
|
+
}
|
72
89
|
|
73
|
-
#
|
74
|
-
def
|
75
|
-
path
|
76
|
-
|
90
|
+
# render request path or template path
|
91
|
+
def render(path)
|
92
|
+
# normalize the path
|
93
|
+
path.sub!(/^\/?(.*)$/, '/\1')
|
94
|
+
path.sub!(/\/$/, '/index.html')
|
95
|
+
path.sub!(/(\/[\w-]+)$/, '\1.html')
|
96
|
+
path = to_file_path(path) if defined? @request
|
97
|
+
|
98
|
+
# regex for kinds that don't support meta
|
99
|
+
# and define the meta delimiter
|
100
|
+
nometa, delimiter = /\/_|\.(js|coffee|css|sass|less)$/, /^META-{3,}\n$/
|
77
101
|
|
78
|
-
|
79
|
-
|
80
|
-
|
102
|
+
# set the layout
|
103
|
+
layout = path.match(nometa) ? nil : layout_for(path)
|
104
|
+
|
105
|
+
template_path = File.join(@proj_dir, @dynamic_folder, path)
|
106
|
+
raise Frank::TemplateError, "Template not found #{template_path}" unless File.exist? template_path
|
107
|
+
|
108
|
+
# read in the template
|
109
|
+
# check for meta and parse it if it exists
|
110
|
+
template = File.read(template_path) << "\n"
|
111
|
+
ext = File.extname(path)
|
112
|
+
template, meta = template.split(delimiter).reverse
|
113
|
+
locals = parse_meta_and_set_locals(meta, path)
|
114
|
+
|
115
|
+
# use given layout if defined as a meta field
|
116
|
+
layout = locals[:layout] == 'nil' ? nil : locals[:layout] if locals.has_key?(:layout)
|
117
|
+
|
118
|
+
# let tilt determine the template handler
|
119
|
+
# and return some template markup
|
120
|
+
if layout.nil?
|
121
|
+
tilt(ext, template, locals)
|
81
122
|
else
|
82
|
-
|
123
|
+
layout_path = File.join(@proj_dir, @layouts_folder, layout)
|
124
|
+
# add layout_path to locals
|
125
|
+
raise Frank::TemplateError, "Layout not found #{layout_path}" unless File.exist? layout_path
|
126
|
+
|
127
|
+
tilt(File.extname(layout), layout_path, locals) do
|
128
|
+
tilt(ext, template, locals)
|
129
|
+
end
|
83
130
|
end
|
84
131
|
end
|
85
132
|
|
86
|
-
#
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
133
|
+
# converts a request path to a template path
|
134
|
+
def to_file_path(path)
|
135
|
+
file_name = File.basename(path, File.extname(path))
|
136
|
+
file_ext = File.extname(path).sub(/^\./, '')
|
137
|
+
folder = File.join(@proj_dir, @dynamic_folder)
|
138
|
+
engine = nil
|
139
|
+
|
140
|
+
TMPL_EXTS.each do |ext, engines|
|
141
|
+
if ext.to_s == file_ext
|
142
|
+
engine = engines.reject do |eng|
|
143
|
+
!File.exist? File.join(folder, path.sub(/\.[\w-]+$/, ".#{eng}"))
|
144
|
+
end.first
|
97
145
|
end
|
98
|
-
else
|
99
|
-
render_template tmpl
|
100
146
|
end
|
147
|
+
|
148
|
+
raise Frank::TemplateError, "Template not found #{path}" if engine.nil?
|
149
|
+
|
150
|
+
path.sub(/\.[\w-]+$/, ".#{engine}")
|
101
151
|
end
|
102
152
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
return kind.to_s if exts.index(ext)
|
153
|
+
# lookup the original ext for given template path
|
154
|
+
# TODO: make non-ugly
|
155
|
+
def ext_from_handler(extension)
|
156
|
+
orig_ext = nil
|
157
|
+
TMPL_EXTS.each do |ext, engines|
|
158
|
+
orig_ext = ext.to_s if engines.include? extension[1..-1]
|
110
159
|
end
|
111
|
-
|
160
|
+
orig_ext
|
112
161
|
end
|
162
|
+
|
113
163
|
|
114
|
-
#
|
115
|
-
#
|
116
|
-
def
|
117
|
-
|
118
|
-
|
164
|
+
# reverse walks the layouts folder until we find a layout
|
165
|
+
# returns nil if layout is not found
|
166
|
+
def layout_for(path)
|
167
|
+
default = "default#{File.extname(path)}"
|
168
|
+
path = path.sub /\/[\w-]+\.[\w-]+$/, ''
|
169
|
+
folders = path.split('/')
|
119
170
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
171
|
+
until File.exist? File.join(@proj_dir, @layouts_folder, folders, default)
|
172
|
+
break if folders.empty?
|
173
|
+
folders.pop
|
174
|
+
end
|
175
|
+
|
176
|
+
if File.exist? File.join(@proj_dir, @layouts_folder, folders, default)
|
177
|
+
File.join(folders, default)
|
178
|
+
else
|
179
|
+
nil
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# setup an object and extend it with TemplateHelpers and Render
|
184
|
+
# then send everything to tilt and get some template markup back
|
185
|
+
def tilt(ext, source, locals={}, &block)
|
186
|
+
obj = Object.new.extend(TemplateHelpers).extend(Render)
|
187
|
+
instance_variables.each do |var|
|
188
|
+
unless ['@response', '@env'].include? var
|
189
|
+
obj.instance_variable_set(var.intern, instance_variable_get(var))
|
130
190
|
end
|
131
191
|
end
|
132
|
-
|
133
|
-
tmpl_ext
|
192
|
+
Tilt[ext].new(source).render(obj, locals=locals, &block)
|
134
193
|
end
|
135
194
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
195
|
+
private
|
196
|
+
|
197
|
+
# parse the given meta string with yaml
|
198
|
+
# add current path
|
199
|
+
# and add instance variables
|
200
|
+
def parse_meta_and_set_locals(meta, path)
|
201
|
+
locals = {}
|
140
202
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
203
|
+
# parse yaml and symbolize keys
|
204
|
+
if meta.nil?
|
205
|
+
meta = {}
|
206
|
+
else
|
207
|
+
meta = YAML.load(meta).inject({}) do |options, (key, value)|
|
208
|
+
options[(key.to_sym rescue key) || key] = value
|
209
|
+
options
|
210
|
+
end
|
211
|
+
end
|
149
212
|
|
150
|
-
#
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# TODO: cleanup
|
158
|
-
def tilt(file, *args, &block)
|
159
|
-
locals = @request.nil? ? {} : { :request => @env, :params => @request.params }
|
160
|
-
obj = Object.new.extend(TemplateHelpers).extend(Render)
|
161
|
-
obj.instance_variable_set(:@proj_dir, @proj_dir)
|
162
|
-
obj.instance_variable_set(:@dynamic_folder, @dynamic_folder)
|
163
|
-
obj.instance_variable_set(:@templates, @templates)
|
164
|
-
Tilt.new(file, 1).render(obj, locals, &block)
|
165
|
-
end
|
166
|
-
|
167
|
-
def remove_ext(path)
|
168
|
-
path.gsub(File.extname(path), '')
|
213
|
+
# normalize current_path
|
214
|
+
# and add it to locals
|
215
|
+
current_path = path.sub(/\.[\w-]+$/, '').sub(/\/index/, '/')
|
216
|
+
locals[:current_path] = current_path
|
217
|
+
|
218
|
+
meta.merge(locals)
|
169
219
|
end
|
170
220
|
|
171
221
|
end
|
@@ -175,8 +225,9 @@ module Frank
|
|
175
225
|
base = Base.new(&block) if block_given?
|
176
226
|
|
177
227
|
builder = Rack::Builder.new do
|
178
|
-
use Frank::Statik, :root => base.static_folder
|
179
|
-
use Frank::Imager
|
228
|
+
use Frank::Middleware::Statik, :root => base.static_folder
|
229
|
+
use Frank::Middleware::Imager
|
230
|
+
use Frank::Middleware::Refresh, :watch => [ base.dynamic_folder, base.static_folder, base.layouts_folder ]
|
180
231
|
run base
|
181
232
|
end
|
182
233
|
|
@@ -201,8 +252,7 @@ module Frank
|
|
201
252
|
|
202
253
|
# copies over the generic project template
|
203
254
|
def self.stub(project)
|
204
|
-
puts "\nFrank is
|
205
|
-
puts " - \033[32mCreating\033[0m your project '#{project}'"
|
255
|
+
puts "\nFrank is...\n - \033[32mCreating\033[0m your project '#{project}'"
|
206
256
|
Dir.mkdir project
|
207
257
|
puts " - \033[32mCopying\033[0m Frank template"
|
208
258
|
FileUtils.cp_r( Dir.glob(File.join(LIBDIR, 'template/*')), project )
|