syro-tilt 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c344875f1c37067ea3ede68552941eda515bf0d3e0b66e9b3335c5e5b15900f
4
- data.tar.gz: a2d4cec3221689f8b5f7c221c9e09f2e22f5c148266aacdb73c8cf41716e245d
3
+ metadata.gz: 1cfe3eed8f52da21ccc32308b4ec07c7992fb4a4cc378685a62760bb1d3e1496
4
+ data.tar.gz: 750a5807d161a85b49882fb2ada1ab1ce425688dd8346a7fd1724c98ff196a5e
5
5
  SHA512:
6
- metadata.gz: 67f316b8d950eb1fcf8409883c47a000c1959c1ab208593681012d70b74642d6bce3b7df77e10bf6ff87975f121cb632da015704104c35774582a67df494e211
7
- data.tar.gz: 03711476cdca8eb7867d3ab041e349f4d0cd57d464393753a46ab3319db766169054d97b4cefd694cca88f27a6e805b8747e8117724f987f78c27664a9ebbe7a
6
+ metadata.gz: 27d77ed0f98427523090cae24cf2e301adf305a27e78b4c41251eb0f4e8e9faa5d10a0f181df589312ada9cdd483cc8453e017e702f963677bc2e3af4f5e8bc4
7
+ data.tar.gz: 756805dbea57d98b914b755f8765ce5b55176917928698cf750cd566762c66489c36c0e1efbd94a1b0609baa432aea6f224086b96d13e452626ae7628be1ff16
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ AllCops:
4
4
  DisplayCopNames: true
5
5
  DisplayStyleGuide: true
6
6
  ExtraDetails: true
7
- TargetRubyVersion: 2.5
7
+ TargetRubyVersion: 2.3
8
8
 
9
9
 
10
10
  Performance:
@@ -57,4 +57,3 @@ Style/IfUnlessModifier:
57
57
 
58
58
  Style/Next:
59
59
  MinBodyLength: 8
60
-
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.6
4
+ - 2.5
5
+ - 2.4
6
+ - 2.3
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Syro::Tilt
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/syro-tilt.svg)](https://badge.fury.io/rb/syro-tilt)
4
+ [![Build Status](https://secure.travis-ci.org/evanleck/syro-tilt.svg)](https://travis-ci.org/evanleck/syro-tilt)
5
+
3
6
  Render [Tilt][tilt] templates in [Syro][syro] routes.
4
7
 
5
8
 
@@ -75,6 +78,38 @@ end
75
78
  `content_for`: capture content for use later.
76
79
 
77
80
 
81
+ ## Template File Naming
82
+
83
+ For templates that will be passed to `render`, it's important that you name your
84
+ templates following the pattern `#{ identifier }.#{ mime_type }.#{
85
+ template_engine }`. For example `home.html.erb` would be returned with the MIME
86
+ type `text/html` (derived from the `.html` extension) and rendered by Tilt using
87
+ the preferred mapping for `.erb` extensions.
88
+
89
+ Templates that are only ever used by the `partial` method do not require the
90
+ same naming because `partial` does not set the response's content type.
91
+
92
+
93
+ ## Caching
94
+
95
+ There's an optional in-memory cache included that will cache calls to `template`
96
+ and `template_path`. You probably don't want to use the cache during development
97
+ since you'll have to restart your server to see updated templates, but it will
98
+ likely be useful in production. To use it, require `syro/tilt/cache`.
99
+
100
+ ```ruby
101
+ require 'syro'
102
+ require 'syro/tilt'
103
+ require 'syro/tilt/cache'
104
+
105
+ app = Syro.new do
106
+ get do
107
+ render 'home'
108
+ end
109
+ end
110
+ ```
111
+
112
+
78
113
  ## Installation
79
114
 
80
115
  Add this line to your application's Gemfile:
data/lib/syro/tilt.rb CHANGED
@@ -51,23 +51,22 @@ class Syro # :nodoc:
51
51
  #
52
52
  # @return [String]
53
53
  # The path to the template file.
54
- def template_path(path, from = nil)
54
+ def template_path(path, from = nil, accept = nil)
55
55
  from ||= templates_directory
56
56
  path = File.join(from, path)
57
57
 
58
- accepts = env.fetch(HTTP_ACCEPT) { EMPTY }.to_s.then do |header|
59
- # Taken from Rack::Request#parse_http_accept_header (which is a private
60
- # method).
61
- header.split(ACCEPT_SPLIT_MULTIPLES).map do |part|
62
- attribute, parameters = part.split(ACCEPT_SPLIT_PARTS, 2)
63
- quality = 1.0
64
-
65
- if parameters && ACCEPT_CAPTURE_QUALITY.match?(parameters)
66
- quality = ACCEPT_CAPTURE_QUALITY.match(parameters)[1].to_f
58
+ # Taken from Rack::Request#parse_http_accept_header (which is a private
59
+ # method).
60
+ accepts = (accept || env.fetch(HTTP_ACCEPT) { EMPTY }).to_s.split(ACCEPT_SPLIT_MULTIPLES).map do |part|
61
+ attribute, parameters = part.split(ACCEPT_SPLIT_PARTS, 2)
62
+ quality =
63
+ if parameters =~ ACCEPT_CAPTURE_QUALITY
64
+ ACCEPT_CAPTURE_QUALITY.match(parameters)[1].to_f
65
+ else
66
+ 1.0
67
67
  end
68
68
 
69
- [attribute, quality]
70
- end
69
+ [attribute, quality]
71
70
  end
72
71
 
73
72
  # Reject "*/*" because it will always match the first thing it is compared
@@ -76,7 +75,7 @@ class Syro # :nodoc:
76
75
 
77
76
  # Find all potential templates e.g. ones with the same name but different
78
77
  # template engines or MIME types.
79
- potentials = Dir.glob(File.join(from, '**', '*')).filter do |potential|
78
+ potentials = Dir.glob(File.join(from, '**', '*')).select do |potential|
80
79
  potential.start_with?(path)
81
80
  end.sort
82
81
 
@@ -116,7 +115,10 @@ class Syro # :nodoc:
116
115
  #
117
116
  # @return [String]
118
117
  def partial(path, locals = {})
119
- template(template_path(path, locals.delete(:from))).render(self, locals) { yield if block_given? }
118
+ accept = env.fetch(HTTP_ACCEPT) { EMPTY }
119
+ from = locals.delete(:from) { templates_directory }
120
+
121
+ template(template_path(path, from, accept)).render(self, locals) { yield if block_given? }
120
122
  end
121
123
 
122
124
  # Set or get the current layout. A layout is just another template to wrap
@@ -141,10 +143,13 @@ class Syro # :nodoc:
141
143
  # @option locals [String] :from
142
144
  # The directory to look for templates within.
143
145
  def render(path, locals = {})
146
+ accept = env.fetch(HTTP_ACCEPT) { EMPTY }
147
+ from = locals.delete(:from) { templates_directory }
148
+
144
149
  content = partial(path, locals.dup) { yield if block_given? }
145
150
  content = partial(layout, locals.dup) { content } if layout
146
151
 
147
- res.headers[Rack::CONTENT_TYPE] = template_mime_type(template_path(path, locals[:from]))
152
+ res.headers[Rack::CONTENT_TYPE] = template_mime_type(template_path(path, from, accept))
148
153
  res.write content
149
154
  end
150
155
 
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../tilt'
3
+
4
+ class Syro # :nodoc:
5
+ module Tilt
6
+ # Add template and path caching to Syro::Tilt.
7
+ module Cache
8
+ # A very thin wrapper around Hash, with a Mutex.
9
+ class MemoryStore
10
+ def initialize
11
+ @cache = {}
12
+ @mutex = Mutex.new
13
+ end
14
+
15
+ def fetch(*key)
16
+ @mutex.synchronize do
17
+ @cache.fetch(key) do
18
+ @cache[key] = yield
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ @template_cache = MemoryStore.new
25
+ @template_path_cache = MemoryStore.new
26
+
27
+ # @return [MemoryStore]
28
+ def self.template_cache
29
+ @template_cache
30
+ end
31
+
32
+ # @return [MemoryStore]
33
+ def self.template_path_cache
34
+ @template_path_cache
35
+ end
36
+
37
+ # Cache calls to Syro::Tilt#template.
38
+ def template(path)
39
+ Cache.template_cache.fetch(path) do
40
+ super(path)
41
+ end
42
+ end
43
+
44
+ # Cache calls to Syro::Tilt#template_path.
45
+ def template_path(path, from, accept)
46
+ Cache.template_path_cache.fetch(path, from, accept) do
47
+ super(path, from, accept)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ Tilt.prepend(Tilt::Cache)
54
+ end
data/syro-tilt.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  Gem::Specification.new do |spec|
3
3
  spec.name = 'syro-tilt'
4
- spec.version = '0.1.0'
4
+ spec.version = '0.2.0'
5
5
  spec.authors = ['Evan Lecklider']
6
6
  spec.email = ['evan@lecklider.com']
7
7
  spec.summary = 'Render Tilt templates in Syro routes.'
@@ -9,12 +9,14 @@ Gem::Specification.new do |spec|
9
9
  spec.homepage = 'https://github.com/evanleck/syro-tilt'
10
10
  spec.license = 'MIT'
11
11
  spec.files = `git ls-files`.split("\n")
12
+ spec.required_ruby_version = '>= 2.3.0'
12
13
  spec.require_paths = ['lib']
13
14
 
14
15
  spec.add_dependency 'syro', '~> 3.0'
15
16
  spec.add_dependency 'tilt', '~> 2.0'
16
17
 
17
- spec.add_development_dependency 'bundler', '~> 2.0'
18
+ spec.add_development_dependency 'bundler', '>= 1.7'
19
+ spec.add_development_dependency 'erubi', '>= 1.8'
18
20
  spec.add_development_dependency 'minitest', '~> 5.0'
19
21
  spec.add_development_dependency 'rake', '~> 10.0'
20
22
  end
@@ -24,7 +24,7 @@ describe Syro::Tilt do
24
24
  end
25
25
 
26
26
  it 'finds the first match for an ambiguous file' do
27
- assert_equal 'test/views/plain.txt.erb', template_path('plain')
27
+ assert_equal 'test/views/plain.anope.erb', template_path('plain')
28
28
  end
29
29
 
30
30
  it "returns nil for files that don't exist" do
@@ -46,7 +46,7 @@ describe Syro::Tilt do
46
46
 
47
47
  describe '#partial' do
48
48
  it 'returns the contents of a template' do
49
- assert_equal "Plain text.\n", partial('plain')
49
+ assert_equal "First plain text.\n", partial('plain')
50
50
  end
51
51
 
52
52
  it 'accepts local variables' do
@@ -93,7 +93,7 @@ describe Syro::Tilt do
93
93
  render('plain')
94
94
 
95
95
  assert_equal 'text/plain', res.headers['Content-Type']
96
- assert_equal ["Plain text.\n"], res.body
96
+ assert_equal ["First plain text.\n"], res.body
97
97
  end
98
98
 
99
99
  it 'writes html text to the response' do
@@ -146,4 +146,34 @@ describe Syro::Tilt do
146
146
  refute content_for?(:notthere)
147
147
  end
148
148
  end
149
+
150
+ describe '#template' do
151
+ it 'returns a Tilt template' do
152
+ assert_instance_of Tilt::ErubiTemplate, template('test/views/typed.html.erb')
153
+ end
154
+
155
+ it "raises an error on missing files (Tilt's default behavior)" do
156
+ assert_raises(Errno::ENOENT) do
157
+ template('test/views/notthere.txt.erb')
158
+ end
159
+ end
160
+ end
161
+
162
+ describe 'Syro::Tilt::Cache' do
163
+ require_relative '../lib/syro/tilt/cache'
164
+
165
+ prepend Syro::Tilt::Cache
166
+
167
+ it 'caches templates' do
168
+ initial = template('test/views/typed.html.erb')
169
+
170
+ assert_equal initial, Syro::Tilt::Cache.template_cache.fetch('test/views/typed.html.erb')
171
+ end
172
+
173
+ it 'caches template paths' do
174
+ initial = template_path('typed.html', 'test/views', 'html')
175
+
176
+ assert_equal initial, Syro::Tilt::Cache.template_path_cache.fetch('typed.html', 'test/views', 'html')
177
+ end
178
+ end
149
179
  end
@@ -0,0 +1 @@
1
+ First plain text.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syro-tilt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Lecklider
@@ -42,16 +42,30 @@ dependencies:
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '2.0'
47
+ version: '1.7'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '2.0'
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: erubi
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: minitest
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -89,16 +103,19 @@ extra_rdoc_files: []
89
103
  files:
90
104
  - ".gitignore"
91
105
  - ".rubocop.yml"
106
+ - ".travis.yml"
92
107
  - Gemfile
93
108
  - LICENSE.txt
94
109
  - README.md
95
110
  - Rakefile
96
111
  - lib/syro/tilt.rb
112
+ - lib/syro/tilt/cache.rb
97
113
  - syro-tilt.gemspec
98
114
  - test/syro_tilt_test.rb
99
115
  - test/views/layout.erb
100
116
  - test/views/locals.erb
101
117
  - test/views/notsoplain.html.erb
118
+ - test/views/plain.anope.erb
102
119
  - test/views/plain.txt.erb
103
120
  - test/views/typed.anope.erb
104
121
  - test/views/typed.html.erb
@@ -115,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
132
  requirements:
116
133
  - - ">="
117
134
  - !ruby/object:Gem::Version
118
- version: '0'
135
+ version: 2.3.0
119
136
  required_rubygems_version: !ruby/object:Gem::Requirement
120
137
  requirements:
121
138
  - - ">="