frank 0.2.6 → 0.3.0.beta
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.
- 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 )
|