curly-templates 0.8.0 → 0.9.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.
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ ### Unreleased
2
+
3
+ ### Curly 0.9.0 (June 4, 2013)
4
+
5
+ * Allow running setup code before rendering a Curly view. Simply add a `#setup!`
6
+ method to your presenter – it will be called by Curly just before the view is
7
+ rendered.
8
+
9
+ *Daniel Schierbeck*
data/README.md CHANGED
@@ -22,6 +22,24 @@ or [Handlebars](http://handlebarsjs.com/), Curly is different in some key ways:
22
22
  object methods that are in turn used by the template.
23
23
 
24
24
 
25
+
26
+ ### Is it ready to use in production?
27
+
28
+ Yes! While still a young project, it's being used in a rather large Rails app
29
+ at Zendesk, where it performs admirably.
30
+
31
+
32
+
33
+ ### Table of Contents
34
+
35
+ 1. [Installing](#installing)
36
+ 2. [How to use Curly](#how-to-use-curly)
37
+ 3. [Presenters](#presenters)
38
+ 1. [Layouts and Content Blocks](#layouts-and-content-blocks)
39
+ 1. [Examples](#examples)
40
+ 4. [Caching](#caching)
41
+
42
+
25
43
  Installing
26
44
  ----------
27
45
 
@@ -87,17 +105,114 @@ render collection: post.comments
87
105
  ```
88
106
 
89
107
 
90
- Is it ready to use in production?
91
- ---------------------------------
108
+ Presenters
109
+ ----------
92
110
 
93
- Yes! While still a young project, it's being used in a rather large Rails app
94
- at Zendesk, where it performs admirably.
111
+ Presenters are classes that inherit from `Curly::Presenter` – they're usually placed in
112
+ `app/presenters/`, but you can put them anywhere you'd like. The name of the presenter
113
+ classes match the virtual path of the view they're part of, so if your controller is
114
+ rendering `posts/show`, the `Posts::ShowPresenter` class will be used. Note that Curly
115
+ is only used to render a view if a template can be found – in this case, at
116
+ `app/views/posts/show.html.curly`.
117
+
118
+ Presenters can declare a list of accepted parameters using the `presents` method:
119
+
120
+ ```ruby
121
+ class Posts::ShowPresenter < Curly::Presenter
122
+ presents :post
123
+ end
124
+ ```
125
+
126
+ A parameter can have a default value:
127
+
128
+ ```ruby
129
+ class Posts::ShowPresenter < Curly::Presenter
130
+ presents :post
131
+ presents :comment, default: nil
132
+ end
133
+ ```
134
+
135
+ Any public method defined on the presenter is made available to the template:
136
+
137
+ ```ruby
138
+ class Posts::ShowPresenter < Curly::Presenter
139
+ presents :post
140
+
141
+ def title
142
+ @post.title
143
+ end
144
+
145
+ def author_link
146
+ # You can call any Rails helper from within a presenter instance:
147
+ link_to author.name, profile_path(author), rel: "author"
148
+ end
149
+
150
+ private
151
+
152
+ # Private methods are not available to the template, so they're safe to
153
+ # use.
154
+ def author
155
+ @post.author
156
+ end
157
+ end
158
+ ```
159
+
160
+ Presenter methods can even take an argument. Say your Curly template has the content
161
+ `{{t.welcome_message}}`, where `welcome_message` is an I18n key. The following presenter
162
+ method would make the lookup work:
163
+
164
+ ```ruby
165
+ def t(key)
166
+ translate(key)
167
+ end
168
+ ```
169
+
170
+ That way, simple ``functions'' can be added to the Curly language. Make sure these do not
171
+ have any side effects, though, as an important part of Curly is the idempotence of the
172
+ templates.
173
+
174
+
175
+ ### Layouts and Content Blocks
176
+
177
+ Both layouts and content blocks (see [`content_for`](http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-content_for))
178
+ use `yield` to signal that content can be inserted. Curly works just like ERB, so calling
179
+ `yield` with no arguments will make the view usable as a layout, while passing a Symbol
180
+ will make it try to read a content block with the given name:
181
+
182
+ ```ruby
183
+ # Given you have the following Curly template in app/views/layouts/application.html.curly
184
+ #
185
+ # <html>
186
+ # <head>
187
+ # <title>{{title}}</title>
188
+ # </head>
189
+ # <body>
190
+ # <div id="sidebar">{{sidebar}}</div>
191
+ # {{body}}
192
+ # </body>
193
+ # </html>
194
+ #
195
+ class ApplicationLayout < Curly::Presenter
196
+ def title
197
+ "You can use methods just like in any other presenter!"
198
+ end
199
+
200
+ def sidebar
201
+ # A view can call `content_for(:sidebar) { "some HTML here" }`
202
+ yield :sidebar
203
+ end
204
+
205
+ def body
206
+ # The view will be rendered and inserted here:
207
+ yield
208
+ end
209
+ end
210
+ ```
95
211
 
96
212
 
97
- Examples
98
- --------
213
+ ### Examples
99
214
 
100
- Here is a simple Curly template -- it will be looked up by Rails automatically.
215
+ Here is a simple Curly template it will be looked up by Rails automatically.
101
216
 
102
217
  ```html
103
218
  <!-- app/views/posts/show.html.curly -->
@@ -205,7 +320,7 @@ end
205
320
  ### Static Caching
206
321
 
207
322
  Static caching will only be enabled for presenters that define a non-nil `#cache_key`
208
- method (see "Dynamic Caching.")
323
+ method (see [Dynamic Caching.](#dynamic-caching))
209
324
 
210
325
  In order to make a deploy expire the cache for a specific view, set the version of the
211
326
  view to something new, usually by incrementing by one:
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'curly-templates'
7
- s.version = '0.8.0'
8
- s.date = '2013-05-22'
7
+ s.version = '0.9.0'
8
+ s.date = '2013-06-04'
9
9
 
10
10
  s.summary = "Free your views!"
11
11
  s.description = "A view layer for your Rails apps that separates structure and logic."
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
28
28
 
29
29
  # = MANIFEST =
30
30
  s.files = %w[
31
+ CHANGELOG.md
31
32
  Gemfile
32
33
  README.md
33
34
  Rakefile
@@ -43,6 +44,7 @@ Gem::Specification.new do |s|
43
44
  lib/generators/curly/controller/controller_generator.rb
44
45
  lib/generators/curly/controller/templates/presenter.rb.erb
45
46
  lib/generators/curly/controller/templates/view.html.curly.erb
47
+ lib/rails/projections.json
46
48
  spec/compiler_spec.rb
47
49
  spec/generators/controller_generator_spec.rb
48
50
  spec/presenter_spec.rb
data/lib/curly.rb CHANGED
@@ -26,7 +26,7 @@
26
26
  # See Curly::Presenter for more information on presenters.
27
27
  #
28
28
  module Curly
29
- VERSION = "0.8.0"
29
+ VERSION = "0.9.0"
30
30
 
31
31
  # Compiles a Curly template to Ruby code.
32
32
  #
@@ -55,6 +55,27 @@ module Curly
55
55
  end
56
56
  end
57
57
 
58
+ # Sets up the view.
59
+ #
60
+ # Override this method in your presenter in order to do setup before the
61
+ # template is rendered. One use case is to call `content_for` in order
62
+ # to inject content into other templates, e.g. a layout.
63
+ #
64
+ # Example
65
+ #
66
+ # class Posts::ShowPresenter < Curly::Presenter
67
+ # presents :post
68
+ #
69
+ # def setup!
70
+ # content_for :page_title, @post.title
71
+ # end
72
+ # end
73
+ #
74
+ # Returns nothing.
75
+ def setup!
76
+ # Does nothing.
77
+ end
78
+
58
79
  # The key that should be used to cache the view.
59
80
  #
60
81
  # Unless `#cache_key` returns nil, the result of rendering the template
@@ -42,6 +42,8 @@ class Curly::TemplateHandler
42
42
  #{source}
43
43
  end
44
44
 
45
+ presenter.setup!
46
+
45
47
  if key = presenter.cache_key
46
48
  @output_buffer = ActiveSupport::SafeBuffer.new
47
49
 
@@ -0,0 +1,16 @@
1
+ {
2
+ "app/presenters/*_presenter.rb": {
3
+ "affinity": "controller",
4
+ "command": "presenter",
5
+ "test": "spec/presenters/%s_presenter_spec.rb",
6
+ "related": "app/views/%s.html.curly",
7
+ "template": "class %SPresenter < Curly::Presenter\nend",
8
+ "keywords": "presents depends_on version"
9
+ },
10
+
11
+ "app/views/*.html.curly": {
12
+ "affinity": "controller",
13
+ "test": "spec/views/%s_spec.rb",
14
+ "related": "app/presenters/%s_presenter.rb"
15
+ }
16
+ }
@@ -9,6 +9,10 @@ describe Curly::TemplateHandler do
9
9
  @cache_duration = options.fetch(:cache_duration, nil)
10
10
  end
11
11
 
12
+ def setup!
13
+ @context.content_for(:foo, "bar")
14
+ end
15
+
12
16
  def foo
13
17
  "FOO"
14
18
  end
@@ -47,6 +51,12 @@ describe Curly::TemplateHandler do
47
51
  @clock += duration
48
52
  end
49
53
 
54
+ def content_for(key, value = nil)
55
+ @contents ||= {}
56
+ @contents[key] = value if value.present?
57
+ @contents[key]
58
+ end
59
+
50
60
  def cache(key, options = {})
51
61
  fragment, expired_at = @cache[key]
52
62
 
@@ -98,6 +108,12 @@ describe Curly::TemplateHandler do
98
108
  output.should be_html_safe
99
109
  end
100
110
 
111
+ it "calls the #setup! method before rendering the view" do
112
+ template.stub(:source) { "{{foo}}" }
113
+ output
114
+ context.content_for(:foo).should == "bar"
115
+ end
116
+
101
117
  context "caching" do
102
118
  before do
103
119
  template.stub(:source) { "{{bar}}" }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curly-templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-22 00:00:00.000000000 Z
12
+ date: 2013-06-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -109,6 +109,7 @@ executables: []
109
109
  extensions: []
110
110
  extra_rdoc_files: []
111
111
  files:
112
+ - CHANGELOG.md
112
113
  - Gemfile
113
114
  - README.md
114
115
  - Rakefile
@@ -124,6 +125,7 @@ files:
124
125
  - lib/generators/curly/controller/controller_generator.rb
125
126
  - lib/generators/curly/controller/templates/presenter.rb.erb
126
127
  - lib/generators/curly/controller/templates/view.html.curly.erb
128
+ - lib/rails/projections.json
127
129
  - spec/compiler_spec.rb
128
130
  - spec/generators/controller_generator_spec.rb
129
131
  - spec/presenter_spec.rb
@@ -145,7 +147,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
145
147
  version: '0'
146
148
  segments:
147
149
  - 0
148
- hash: 2436310145351861333
150
+ hash: 3268332445838018672
149
151
  required_rubygems_version: !ruby/object:Gem::Requirement
150
152
  none: false
151
153
  requirements: