phlex-sinatra 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0e0c3d6038f57d3a01b5abb0172d1598a0edb08d46e455dede38da9ad708560
4
- data.tar.gz: 6e5025677940fc22ed1830405646c18d4d441f8125a4c37f3179d8c8e735a354
3
+ metadata.gz: a78afcc1302f4df83e718925f4dd189fd6270a83f6a0bd1a3fd14c480e15131e
4
+ data.tar.gz: 3337dfdb6dc398e901222b50c1b51fb480070204298b406c486238b4c0c8a58c
5
5
  SHA512:
6
- metadata.gz: e94e93fbb09a9b6043667f8139cc515a4d6b5302f3459b5216d4f900d471579b4621716e1734d4dd38ead39788074c6442ed3f0c46ce63e7aa9faa4868bb4cda
7
- data.tar.gz: 5026ea9e6f0af3ae2b064dc475d441e85b6753e49e37ef1e57f6aca00d3d7e15feb8a6eb188a6939eff70c0dae7ff1fa4db8447f3cd2a6c512a9212273ef4a4e
6
+ metadata.gz: ddc9255d6c867f6bd67c349df61e05c0bc79af68a3ede5be8217bee8ae42b6b6f08c40064f43d956eec2ab82007742608d948b071c3efe448c3ca1196c1a626a
7
+ data.tar.gz: 62e813a5c2523581b1eecc0fd3b02549d698454433f49618b5b3500684fc7fad8018b7a90d245b80711ce80bb98b4b8091cfdfe8ce8dc2c0fd26b7d2610fa6c6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## Version 0.4.0 - 2024-09-10
2
+
3
+ - Add support for wrapping a Phlex view in a layout. Pass `layout: true` to use Sinatra's default layout or specify the view by passing a symbol. Defaults to ERB and other Sinatra templating languages can be specified via the `layout_engine:` keyword.
4
+
5
+ ## Version 0.3.0 - 2023-12-13
6
+
7
+ - Add support for streaming a view. Pass `stream: true` to the `#phlex` helper so Phlex will use Sinatra's streaming capability.
8
+
1
9
  ## Version 0.2.0 - 2023-04-24
2
10
 
3
11
  - Allow passing a `content_type:` kwarg to the `#phlex` helper so it behaves like Sinatra's other template helpers (defaults to `:html` – or `:svg` for a `Phlex::SVG` instance).
data/Gemfile CHANGED
@@ -5,6 +5,9 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in phlex-sinatra.gemspec
6
6
  gemspec
7
7
 
8
+ gem 'capybara'
9
+ gem 'haml'
10
+ gem 'puma'
8
11
  gem 'rack-test'
9
12
  gem 'rake'
10
13
  gem 'rspec'
data/README.md CHANGED
@@ -24,7 +24,7 @@ You can now use Sinatra's `url()` helper method directly and its other methods (
24
24
 
25
25
  ```ruby
26
26
  class MyView < Phlex::HTML
27
- def template
27
+ def view_template
28
28
  h1 { 'Phlex / Sinatra integration' }
29
29
  p {
30
30
  a(href: url('/foo', false)) { 'link to foo' }
@@ -42,7 +42,92 @@ get '/foo' do
42
42
  end
43
43
  ```
44
44
 
45
- ## Why?
45
+ ## Layout
46
+
47
+ If your entire view layer uses Phlex then layout will be a part of your component structure but maybe you've got an existing non-Phlex layout or you don't want to use Phlex for _everything_, in which case standard Sinatra layouts are supported.
48
+
49
+ Pass `layout: true` to wrap the Phlex output with Sinatra's default layout -- a file named "layout.erb" in the configured views directory (ERB is the default) -- or pass a symbol to specify the file:
50
+
51
+ ```ruby
52
+ get '/foo' do
53
+ # This Phlex view will be wrapped by `views/my_layout.erb`.
54
+ phlex MyView.new, layout: :my_layout
55
+ end
56
+ ```
57
+
58
+ Other [Sinatra templating languages](https://sinatrarb.com/intro.html#available-template-languages) can be specified via the `layout_engine` keyword:
59
+
60
+ ```ruby
61
+ get '/foo' do
62
+ # This Phlex view will be wrapped by `views/layout.haml`.
63
+ phlex MyView.new, layout: true, layout_engine: :haml
64
+ end
65
+ ```
66
+
67
+ ## Using Phlex in other templates
68
+
69
+ It's also possible to call `phlex` from within other views, for instance an ERB template:
70
+
71
+ ```erb
72
+ <%= phlex MyView.new %>
73
+ ```
74
+
75
+ A `layout` can also be passed:
76
+
77
+ ```erb
78
+ <%= phlex MyView.new, layout: :wrapper %>
79
+ ```
80
+
81
+ ## Streaming
82
+
83
+ Streaming a Phlex view can be enabled by passing `stream: true` which will cause Phlex to automatically write to the response after the closing `</head>` and buffer the remaining content:
84
+
85
+ ```ruby
86
+ get '/foo' do
87
+ phlex MyView.new, stream: true
88
+ end
89
+ ```
90
+
91
+ Even with no further intervention this small change means that the browser will receive the complete `<head>` as quickly as possible and can start fetching and processing its external resources while waiting for the rest of the page to download.
92
+
93
+ You can also manually flush the contents of the buffer at any point using Phlex's `#flush` method:
94
+
95
+ ```ruby
96
+ class Layout < Phlex::HTML
97
+ def view_template(&block)
98
+ doctype
99
+ html {
100
+ head {
101
+ # All the usual stuff: links to external stylesheets and JavaScript etc.
102
+ }
103
+ # Phlex will automatically flush to the response at this point which will
104
+ # benefit all pages that opt in to streaming.
105
+ body {
106
+ # Standard site header and navigation.
107
+ render Header.new
108
+
109
+ yield_content(&block)
110
+ }
111
+ }
112
+ end
113
+ end
114
+
115
+ class MyView < Phlex::HTML
116
+ def view_template
117
+ render Layout.new {
118
+ # Knowing that this page can take a while to generate we can choose to
119
+ # flush here so the browser can render the site header while downloading
120
+ # the rest of the page - which should help minimise the First Contentful
121
+ # Paint metric.
122
+ flush
123
+
124
+ # The rest of the big long page...
125
+ }
126
+ end
127
+ end
128
+ ```
129
+
130
+ ## Why do I need Sinatra's `url()` helper?
46
131
 
47
132
  It might not seem obvious at first why you'd use `url()` at all given that you mostly just pass the string you want to output and then probably `false` so the scheme/host isn't included.
48
133
 
@@ -54,7 +139,7 @@ There are a couple of reasons:
54
139
 
55
140
  2. **Awareness that the app is being served from a subdirectory**
56
141
 
57
- This isn't something you encounter very often in a standard Sinatra app but you hit it quite quickly if you're using [Parklife](https://github.com/benpickles/parklife) to generate a static build which you host on GitHub Pages – which is exactly what prompted me to write this integration.
142
+ This isn't something you encounter very often in a standard Sinatra app but you hit it quite quickly if you're using [Parklife](https://github.com/benpickles/parklife) to generate a static build hosted on GitHub Pages – which is exactly what prompted me to write this integration.
58
143
 
59
144
  In this case by using the `url()` helper you won’t have to change anything when switching between serving the app from `/` in development and hosting it at `/my-repository/` in production – internal links to other pages/stylesheets/etc will always be correct regardless.
60
145
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlex
4
4
  module Sinatra
5
- VERSION = '0.2.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
data/lib/phlex-sinatra.rb CHANGED
@@ -6,6 +6,7 @@ require_relative 'phlex/sinatra/version'
6
6
  module Phlex
7
7
  module Sinatra
8
8
  Error = Class.new(StandardError)
9
+ IncompatibleOptionError = Class.new(Error)
9
10
 
10
11
  class TypeError < Error
11
12
  MAX_SIZE = 32
@@ -37,13 +38,39 @@ end
37
38
 
38
39
  module Sinatra
39
40
  module Templates
40
- def phlex(obj, content_type: nil)
41
+ def phlex(
42
+ obj,
43
+ content_type: nil,
44
+ layout: false,
45
+ layout_engine: :erb,
46
+ stream: false
47
+ )
41
48
  raise Phlex::Sinatra::TypeError.new(obj) unless obj.is_a?(Phlex::SGML)
42
49
 
43
- content_type ||= :svg if obj.is_a?(Phlex::SVG)
50
+ content_type ||= :svg if obj.is_a?(Phlex::SVG) && !layout
44
51
  self.content_type(content_type) if content_type
45
52
 
46
- obj.call(view_context: self)
53
+ # Copy Sinatra's behaviour and interpret layout=true as meaning "use the
54
+ # default layout" - uses an internal Sinatra instance variable :s
55
+ layout = @default_layout if layout == true
56
+
57
+ if stream
58
+ raise Phlex::Sinatra::IncompatibleOptionError.new(
59
+ 'streaming is not compatible with layout'
60
+ ) if layout
61
+
62
+ self.stream do |out|
63
+ obj.call(out, view_context: self)
64
+ end
65
+ else
66
+ output = obj.call(view_context: self)
67
+
68
+ if layout
69
+ render(layout_engine, layout, { layout: false }) { output }
70
+ else
71
+ output
72
+ end
73
+ end
47
74
  end
48
75
  end
49
76
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlex-sinatra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Pickles
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-24 00:00:00.000000000 Z
11
+ date: 2024-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 1.7.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 1.7.0
27
27
  description: A Phlex adapter for Sinatra
28
28
  email:
29
29
  - spideryoung@gmail.com
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
64
  - !ruby/object:Gem::Version
65
65
  version: '0'
66
66
  requirements: []
67
- rubygems_version: 3.4.6
67
+ rubygems_version: 3.5.17
68
68
  signing_key:
69
69
  specification_version: 4
70
70
  summary: A Phlex adapter for Sinatra