flatrack 1.3.3 → 1.4.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +3 -6
- data/flatrack.gemspec +4 -3
- data/lib/custom-extensions/sprockets-sass.rb +32 -0
- data/lib/flatrack.rb +123 -11
- data/lib/flatrack/asset_extensions.rb +7 -1
- data/lib/flatrack/cli.rb +9 -1
- data/lib/flatrack/domain_parser.rb +13 -0
- data/lib/flatrack/middleware.rb +32 -0
- data/lib/flatrack/redirector.rb +63 -0
- data/lib/flatrack/request.rb +16 -2
- data/lib/flatrack/response.rb +7 -8
- data/lib/flatrack/rewriter.rb +32 -0
- data/lib/flatrack/sass/functions.rb +6 -6
- data/lib/flatrack/sass/importer.rb +7 -7
- data/lib/flatrack/sass/sass_template.rb +6 -6
- data/lib/flatrack/site.rb +2 -27
- data/lib/flatrack/template.rb +27 -8
- data/lib/flatrack/template/erubis.rb +2 -2
- data/lib/flatrack/template/html.rb +2 -2
- data/lib/flatrack/template/rb.rb +2 -2
- data/lib/flatrack/version.rb +1 -1
- data/lib/flatrack/view.rb +1 -1
- data/lib/flatrack/view/capture_helper.rb +1 -2
- data/lib/flatrack/view/link_helper.rb +8 -1
- data/lib/flatrack/view/render_helper.rb +1 -1
- data/lib/flatrack/view/request_helper.rb +23 -2
- data/lib/flatrack/view/tag_helper.rb +19 -11
- data/spec/lib/flatrack/cli_spec.rb +28 -2
- data/spec/lib/flatrack/middleware_spec.rb +55 -0
- data/spec/lib/flatrack/site_spec.rb +3 -5
- data/spec/lib/flatrack/view/render_helper_spec.rb +4 -0
- data/spec/lib/flatrack/view/set_layout_spec.rb +1 -1
- data/spec/lib/flatrack/view/tag_helper_spec.rb +9 -0
- data/spec/lib/flatrack/view_spec.rb +1 -1
- data/spec/lib/flatrack_spec.rb +73 -0
- data/spec/lib/rake/asset_tasks_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/support/fixture_helper.rb +1 -1
- data/spec/support/site_helper.rb +3 -1
- metadata +32 -9
data/lib/flatrack/request.rb
CHANGED
@@ -13,6 +13,10 @@ class Flatrack
|
|
13
13
|
|
14
14
|
# the path of the incoming request
|
15
15
|
def path
|
16
|
+
env['ORIGINAL_PATH_INFO'] || env['PATH_INFO']
|
17
|
+
end
|
18
|
+
|
19
|
+
def page
|
16
20
|
env['PATH_INFO']
|
17
21
|
end
|
18
22
|
|
@@ -33,12 +37,22 @@ class Flatrack
|
|
33
37
|
# the processed response for an inbound request
|
34
38
|
def response
|
35
39
|
Response.new(self).render
|
36
|
-
rescue TemplateNotFound
|
40
|
+
rescue TemplateNotFound => e
|
41
|
+
raise e if config.raise_errors
|
37
42
|
respond_with_error(500)
|
38
|
-
rescue FileNotFound
|
43
|
+
rescue FileNotFound => e
|
44
|
+
raise e if config.raise_errors
|
39
45
|
respond_with_error(404)
|
40
46
|
end
|
41
47
|
|
48
|
+
def config
|
49
|
+
env['flatrack.config']
|
50
|
+
end
|
51
|
+
|
52
|
+
def mount_path
|
53
|
+
env['SCRIPT_NAME'].present? ? env['SCRIPT_NAME'] : '/'
|
54
|
+
end
|
55
|
+
|
42
56
|
private
|
43
57
|
|
44
58
|
def respond_with_error(code)
|
data/lib/flatrack/response.rb
CHANGED
@@ -6,7 +6,7 @@ class Flatrack
|
|
6
6
|
|
7
7
|
attr_accessor :layout
|
8
8
|
attr_reader :request
|
9
|
-
delegate :format, to: :request
|
9
|
+
delegate :mount_path, :config, :format, to: :request
|
10
10
|
|
11
11
|
# Initializes a response
|
12
12
|
# @param request [Flatrack::Request]
|
@@ -20,7 +20,7 @@ class Flatrack
|
|
20
20
|
# @option opts [Fixnum] :status
|
21
21
|
# @option opts [Symbol] :layout
|
22
22
|
# @return [Array] the rack response
|
23
|
-
def render(file: file_for(request.
|
23
|
+
def render(file: file_for(request.page), status: 200, layout: :layout)
|
24
24
|
@file, @status, @layout = file, status, layout
|
25
25
|
page_content = pre_render_page
|
26
26
|
body << begin
|
@@ -57,19 +57,18 @@ class Flatrack
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def file_for(path)
|
60
|
-
if File.directory?(File.join 'pages', path)
|
61
|
-
File.join(path, DEFAULT_FILE)
|
62
|
-
else
|
63
|
-
path
|
60
|
+
if File.directory?(File.join config.site_root, 'pages', path)
|
61
|
+
path = File.join(path, DEFAULT_FILE)
|
64
62
|
end
|
63
|
+
path
|
65
64
|
end
|
66
65
|
|
67
66
|
def renderer_for_page(file)
|
68
|
-
Template.find :page, format, file
|
67
|
+
Template.find config.site_root, :page, format, file
|
69
68
|
end
|
70
69
|
|
71
70
|
def renderer_for_layout(file)
|
72
|
-
Template.find :layout, format, file
|
71
|
+
Template.find config.site_root, :layout, format, file
|
73
72
|
end
|
74
73
|
|
75
74
|
def view
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Flatrack
|
2
|
+
def Rewriter(source, opts={})
|
3
|
+
to = opts.delete(:to)
|
4
|
+
klass = Class.new(Rewriter)
|
5
|
+
klass.send(:define_method, :initialize) do |app, mw_opts|
|
6
|
+
mapping = { source => to }
|
7
|
+
super app, mapping, mw_opts
|
8
|
+
end
|
9
|
+
klass
|
10
|
+
end
|
11
|
+
|
12
|
+
class Rewriter
|
13
|
+
|
14
|
+
def initialize(app, mapping = {}, opts = {})
|
15
|
+
@if = opts[:if] || Proc.new { true }
|
16
|
+
@unless = opts[:unless] || Proc.new { false }
|
17
|
+
@app = app
|
18
|
+
@mapping =
|
19
|
+
Hash[mapping.map { |paths| paths.map { |p| File.join '', p } }]
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
allow = @if.call(env) && !@unless.call(env)
|
24
|
+
if allow && @mapping.keys.include?(env['PATH_INFO'])
|
25
|
+
env['ORIGINAL_PATH_INFO'] = env['PATH_INFO']
|
26
|
+
env['PATH_INFO'] = @mapping[env['PATH_INFO']]
|
27
|
+
end
|
28
|
+
@app.call env
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -148,16 +148,16 @@ module Sass::Script::Functions
|
|
148
148
|
defined?(@signatures) && @signatures.delete(method)
|
149
149
|
end
|
150
150
|
|
151
|
-
declare :asset_path, [:source], :
|
151
|
+
declare :asset_path, [:source], var_kwargs: true
|
152
152
|
declare :asset_path, [:source, :kind]
|
153
|
-
declare :asset_url, [:source], :
|
153
|
+
declare :asset_url, [:source], var_kwargs: true
|
154
154
|
declare :asset_url, [:source, :kind]
|
155
|
-
declare :image_path, [:source], :
|
156
|
-
declare :image_url, [:source], :
|
155
|
+
declare :image_path, [:source], var_kwargs: true
|
156
|
+
declare :image_url, [:source], var_kwargs: true
|
157
157
|
declare :image_url, [:source, :only_path]
|
158
158
|
declare :image_url, [:source, :only_path, :cache_buster]
|
159
|
-
declare :font_path, [:source], :
|
160
|
-
declare :font_url, [:source], :
|
159
|
+
declare :font_path, [:source], var_kwargs: true
|
160
|
+
declare :font_url, [:source], var_kwargs: true
|
161
161
|
declare :font_url, [:source, :only_path]
|
162
162
|
declare :asset_data_uri, [:source]
|
163
163
|
end
|
@@ -48,9 +48,9 @@ class Flatrack
|
|
48
48
|
pathname = resolve(context, path, base_path) or return nil
|
49
49
|
context.depend_on pathname
|
50
50
|
::Sass::Engine.new evaluate(context, pathname), options.merge(
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
51
|
+
filename: pathname.to_s,
|
52
|
+
syntax: syntax(pathname),
|
53
|
+
importer: self
|
54
54
|
)
|
55
55
|
end
|
56
56
|
|
@@ -65,9 +65,9 @@ class Flatrack
|
|
65
65
|
end
|
66
66
|
return nil if imports.empty?
|
67
67
|
::Sass::Engine.new imports, options.merge(
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
68
|
+
filename: base_path.to_s,
|
69
|
+
syntax: :scss,
|
70
|
+
importer: self
|
71
71
|
)
|
72
72
|
end
|
73
73
|
|
@@ -135,7 +135,7 @@ class Flatrack
|
|
135
135
|
attributes = context.environment.attributes_for(path)
|
136
136
|
processors = context.environment.preprocessors(attributes.content_type) + attributes.engines.reverse
|
137
137
|
processors.delete_if { |processor| processor < Tilt::SassTemplate }
|
138
|
-
context.evaluate(path, :
|
138
|
+
context.evaluate(path, processors: processors)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
end
|
@@ -66,12 +66,12 @@ class Flatrack
|
|
66
66
|
# Assemble the options for the `Sass::Engine`
|
67
67
|
def sass_options
|
68
68
|
merge_sass_options(default_sass_options, options).merge(
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
69
|
+
filename: eval_file,
|
70
|
+
line: line,
|
71
|
+
syntax: syntax,
|
72
|
+
cache_store: cache_store,
|
73
|
+
importer: Importer.new,
|
74
|
+
custom: { sprockets_context: context }
|
75
75
|
)
|
76
76
|
end
|
77
77
|
|
data/lib/flatrack/site.rb
CHANGED
@@ -3,32 +3,7 @@ require 'rack/server'
|
|
3
3
|
class Flatrack
|
4
4
|
# Provides a rake wrapper for encapsulating a flatrack site
|
5
5
|
module Site
|
6
|
-
|
7
|
-
|
8
|
-
def self.call(env)
|
9
|
-
builder.call(env)
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def self.builder
|
15
|
-
mapping = self.mapping
|
16
|
-
Rack::Builder.app do
|
17
|
-
use Rack::Static, urls: ['/favicon.ico', 'assets'], root: 'public'
|
18
|
-
Flatrack.middleware.each { |mw| use(*mw) }
|
19
|
-
mapping.each { |path, app| map(path) { run app } }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.site
|
24
|
-
->(env) { Request.new(env).response }
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.mapping
|
28
|
-
{
|
29
|
-
'/assets' => Flatrack.assets,
|
30
|
-
'/' => site
|
31
|
-
}
|
32
|
-
end
|
6
|
+
extend self
|
7
|
+
delegate :call, to: Flatrack
|
33
8
|
end
|
34
9
|
end
|
data/lib/flatrack/template.rb
CHANGED
@@ -9,32 +9,47 @@ class Flatrack
|
|
9
9
|
# @private
|
10
10
|
DEFAULT_FORMAT = 'html'
|
11
11
|
|
12
|
-
attr_reader :type, :file, :format
|
12
|
+
attr_reader :base_path, :type, :file, :format
|
13
13
|
delegate :render, to: :@renderer
|
14
14
|
|
15
|
+
def self.register_path(path)
|
16
|
+
classes.each do |klass|
|
17
|
+
files = Dir.glob File.join path, '**', "*.#{klass::RENDERS}"
|
18
|
+
Tilt.register klass, *files
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
15
22
|
# Creates a new template instance and invokes find
|
16
23
|
# @param type [Symbol] the type of template
|
17
24
|
# @param format [String] the format e.g. html
|
18
25
|
# @param file [String] the location of the file
|
19
|
-
def self.find(type, format, file)
|
20
|
-
new(type, format, file)
|
26
|
+
def self.find(base_path, type, format, file)
|
27
|
+
new(base_path, type, format, file)
|
21
28
|
end
|
22
29
|
|
23
30
|
# Creates a new template instance
|
24
31
|
# @param type [Symbol] the type of template
|
25
32
|
# @param format [String] the format e.g. html
|
26
33
|
# @param file [String] the location of the file
|
27
|
-
def initialize(type, format, file)
|
34
|
+
def initialize(base_path, type, format, file)
|
35
|
+
@base_path = base_path
|
28
36
|
@format = format || DEFAULT_FORMAT
|
29
37
|
@type, @file = type, file.to_s
|
30
|
-
@renderer
|
38
|
+
@renderer = find
|
31
39
|
end
|
32
40
|
|
33
41
|
private
|
34
42
|
|
43
|
+
def self.classes
|
44
|
+
constants.map { |k| const_get k }.select do |klass|
|
45
|
+
klass.is_a?(Class) && klass < Tilt::Template
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
35
49
|
def find
|
36
50
|
template = find_by_type
|
37
51
|
fail FileNotFound, "could not find #{file}" unless template
|
52
|
+
template = File.expand_path template
|
38
53
|
Tilt.new template, options
|
39
54
|
rescue RuntimeError
|
40
55
|
raise TemplateNotFound, "could not find a renderer for #{file}"
|
@@ -48,11 +63,15 @@ class Flatrack
|
|
48
63
|
end
|
49
64
|
|
50
65
|
def find_by_type
|
51
|
-
|
66
|
+
paths = [base_path, Flatrack.gem_root]
|
67
|
+
|
68
|
+
# To support direct html files
|
69
|
+
if paths.any? { |path| file.start_with? path } && File.exist?(file)
|
52
70
|
file
|
53
71
|
else
|
54
|
-
|
55
|
-
|
72
|
+
file_without_format = File.join(File.dirname(file), File.basename(file, ".#{format}"))
|
73
|
+
file_with_format = [file_without_format, format].compact.join('.')
|
74
|
+
Dir[File.join base_path, type.to_s.pluralize, "#{file_with_format}*"].first
|
56
75
|
end
|
57
76
|
end
|
58
77
|
end
|
@@ -2,6 +2,8 @@ class Flatrack
|
|
2
2
|
class Template
|
3
3
|
# The tilt template for rendering ERB in flatrack
|
4
4
|
class Erubis < Tilt::ErubisTemplate
|
5
|
+
RENDERS = 'erb'
|
6
|
+
|
5
7
|
extend ActiveSupport::Autoload
|
6
8
|
autoload :Handler
|
7
9
|
|
@@ -19,5 +21,3 @@ class Flatrack
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
22
|
-
|
23
|
-
Tilt.prefer Flatrack::Template::Erubis, 'erb'
|
@@ -2,6 +2,8 @@ class Flatrack
|
|
2
2
|
class Template
|
3
3
|
# The tilt template for rendering HTML in flatrack
|
4
4
|
class Html < Tilt::PlainTemplate
|
5
|
+
RENDERS = 'html'
|
6
|
+
|
5
7
|
private
|
6
8
|
|
7
9
|
def evaluate(scope, locals, &block)
|
@@ -10,5 +12,3 @@ class Flatrack
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
13
|
-
|
14
|
-
Tilt.prefer Flatrack::Template::Html, 'html'
|
data/lib/flatrack/template/rb.rb
CHANGED
@@ -4,6 +4,8 @@ class Flatrack
|
|
4
4
|
class Template
|
5
5
|
# The tilt template for rendering Ruby in flatrack
|
6
6
|
class Rb < Tilt::ErubisTemplate
|
7
|
+
RENDERS = 'rb'
|
8
|
+
|
7
9
|
private
|
8
10
|
|
9
11
|
def data
|
@@ -12,5 +14,3 @@ class Flatrack
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
15
|
-
|
16
|
-
Tilt.prefer Flatrack::Template::Rb, 'rb'
|
data/lib/flatrack/version.rb
CHANGED
data/lib/flatrack/view.rb
CHANGED
@@ -9,8 +9,7 @@ class Flatrack
|
|
9
9
|
def capture(*args)
|
10
10
|
value = nil
|
11
11
|
buffer = with_output_buffer { value = yield(*args) }
|
12
|
-
|
13
|
-
html_escape string if string.is_a?(String)
|
12
|
+
buffer.presence || value
|
14
13
|
end
|
15
14
|
|
16
15
|
# Use an alternate output buffer for the duration of the block.
|
@@ -32,7 +32,14 @@ class Flatrack
|
|
32
32
|
# @return [String]
|
33
33
|
def link_to(*args, &block)
|
34
34
|
href, options, block = link_to_options(*args, &block)
|
35
|
-
|
35
|
+
if href.start_with?('/') && !href.start_with?('//') && mount_path != '/'
|
36
|
+
href = File.join '', mount_path, href
|
37
|
+
end
|
38
|
+
tag_opts = link_to_tag_options(href, options || {})
|
39
|
+
if current_path == tag_opts[:href]
|
40
|
+
((tag_opts[:class] ||= '') << ' active').strip!
|
41
|
+
end
|
42
|
+
html_tag(:a, tag_opts, false, &block)
|
36
43
|
end
|
37
44
|
|
38
45
|
private
|
@@ -8,11 +8,32 @@ class Flatrack
|
|
8
8
|
@response.request.params
|
9
9
|
end
|
10
10
|
|
11
|
-
# Returns the path
|
11
|
+
# Returns the path before rewrites
|
12
12
|
# @return [String]
|
13
|
-
def
|
13
|
+
def current_path
|
14
14
|
@response.request.path
|
15
15
|
end
|
16
|
+
alias path current_path
|
17
|
+
|
18
|
+
# Returns the page being displayed
|
19
|
+
# @return [String]
|
20
|
+
def current_page
|
21
|
+
@response.request.page
|
22
|
+
end
|
23
|
+
alias page current_page
|
24
|
+
|
25
|
+
# Returns the IP address for the request
|
26
|
+
# @return [String]
|
27
|
+
def request_ip
|
28
|
+
@response.request.env['REMOTE_ADDR']
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the cookies
|
32
|
+
# @return [Hash]
|
33
|
+
def cookies
|
34
|
+
@response.request.env['rack.cookies']
|
35
|
+
end
|
36
|
+
|
16
37
|
end
|
17
38
|
end
|
18
39
|
end
|
@@ -7,11 +7,11 @@ class Flatrack
|
|
7
7
|
|
8
8
|
# @private
|
9
9
|
PRE_CONTENT_STRINGS = {
|
10
|
-
|
10
|
+
textarea: "\n"
|
11
11
|
}
|
12
12
|
|
13
13
|
# @private
|
14
|
-
BOOLEAN_ATTRIBUTES
|
14
|
+
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
|
15
15
|
autoplay controls loop selected hidden scoped
|
16
16
|
async defer reversed ismap seamless muted
|
17
17
|
required autofocus novalidate formnovalidate open
|
@@ -37,16 +37,17 @@ class Flatrack
|
|
37
37
|
# @param options [Hash] the html options for the tag
|
38
38
|
# @yield the tag content
|
39
39
|
# @return [String]
|
40
|
-
def html_tag(name,
|
41
|
-
escape =
|
40
|
+
def html_tag(name, *args, &block)
|
41
|
+
content, options, escape = args
|
42
42
|
if block_given?
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
html_tag_string(name, capture(&block), options, escape)
|
43
|
+
check_arguments [name, *args], 1..3
|
44
|
+
options, escape = content, options
|
45
|
+
content = capture(&block)
|
47
46
|
else
|
48
|
-
|
47
|
+
check_arguments [name, *args], 2..4
|
49
48
|
end
|
49
|
+
escape = true if escape.nil?
|
50
|
+
html_tag_string(name, content, options, escape)
|
50
51
|
end
|
51
52
|
|
52
53
|
# Returns an HTML image tag
|
@@ -77,6 +78,13 @@ class Flatrack
|
|
77
78
|
|
78
79
|
private
|
79
80
|
|
81
|
+
def check_arguments(args, number_or_range)
|
82
|
+
range = number_or_range.is_a?(Fixnum) ? [number_or_range] : number_or_range
|
83
|
+
unless range.include? args.size
|
84
|
+
raise ArgumentError, "wrong number of arguments (#{args.count} for #{number_or_range.inspect})"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
80
88
|
def html_tag_string(name, content, options, escape = true)
|
81
89
|
tag_options = tag_options(options, escape) if options
|
82
90
|
content = h(content) if escape && !content.nil?
|
@@ -115,8 +123,8 @@ class Flatrack
|
|
115
123
|
def data_tag_option(key, value, escape)
|
116
124
|
key = "data-#{key.to_s.dasherize}"
|
117
125
|
value = value.to_json unless value.is_a?(String) ||
|
118
|
-
|
119
|
-
|
126
|
+
value.is_a?(Symbol) ||
|
127
|
+
value.is_a?(BigDecimal)
|
120
128
|
tag_option(key, value, escape)
|
121
129
|
end
|
122
130
|
|