padrino-helpers 0.1.1 → 0.1.2
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/README.rdoc +355 -1
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/padrino-helpers/asset_tag_helpers.rb +14 -3
- data/padrino-helpers.gemspec +5 -2
- data/test/test_asset_tag_helpers.rb +28 -0
- metadata +12 -2
data/README.rdoc
CHANGED
@@ -1,6 +1,360 @@
|
|
1
1
|
= padrino-helpers
|
2
2
|
|
3
|
-
|
3
|
+
This component provides a great deal of view helpers related to html markup generation.
|
4
|
+
There are helpers for generating tags, forms, links, images, and more. Most of the basic
|
5
|
+
methods should be very familiar to anyone who has used rails view helpers.
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
To install the 'full-stack' padrino framework, simply grab the latest version from gemcutter:
|
10
|
+
|
11
|
+
$ sudo gem install padrino --source http://gemcutter.org
|
12
|
+
|
13
|
+
This will install the necessary padrino gems to get you started.
|
14
|
+
Now you are ready to use this gem to enhance your sinatra projects or to create new Padrino applications.
|
15
|
+
|
16
|
+
You can also install only the padrino-helpers gem for more fine-grained use:
|
17
|
+
|
18
|
+
$ sudo gem install padrino-helpers --source http://gemcutter.org
|
19
|
+
|
20
|
+
== Usage
|
21
|
+
|
22
|
+
=== Output Helpers
|
23
|
+
|
24
|
+
* <tt>content_for(key, &block)</tt>
|
25
|
+
* Capture a block of content to be rendered at a later time.
|
26
|
+
* <tt>content_for(:head) { ...content... }</tt>
|
27
|
+
* Also supports arguments passed to the content block
|
28
|
+
* <tt>content_for(:head) { |param1, param2| ...content... }</tt>
|
29
|
+
* <tt>yield_content(key, *args)</tt>
|
30
|
+
* Render the captured content blocks for a given key.
|
31
|
+
* <tt>yield_content :head</tt>
|
32
|
+
* Also supports arguments yielded to the content block
|
33
|
+
* <tt>yield_content :head, param1, param2</tt>
|
34
|
+
* <tt>capture_html(*args, &block)</tt>
|
35
|
+
* Captures the html from a block of template code for erb or haml
|
36
|
+
* <tt>capture_html(&block)</tt> => "...html..."
|
37
|
+
* <tt>concat_content(text="")</tt>
|
38
|
+
* Outputs the given text to the templates buffer directly in erb or haml
|
39
|
+
* <tt>concat_content("This will be output to the template buffer in erb or haml")</tt>
|
40
|
+
|
41
|
+
=== Tag Helpers
|
42
|
+
|
43
|
+
* <tt>tag(name, options={})</tt>
|
44
|
+
* Creates an html tag with the given name and options
|
45
|
+
* <tt>tag(:br, :style => 'clear:both')</tt> => <br style="clear:both" />
|
46
|
+
* <tt>tag(:p, :content => "demo", :class => 'large')</tt> => <p class="large">demo</p>
|
47
|
+
* <tt>content_tag(name, content, options={})</tt>
|
48
|
+
* Creates an html tag with given name, content and options
|
49
|
+
* <tt>content_tag(:p, "demo", :class => 'light')</tt> => <p class="light">demo</p>
|
50
|
+
* <tt>content_tag(:p, :class => 'dark') { ...content... }</tt> => <p class="dark">...content...</p>
|
51
|
+
* <tt>input_tag(type, options = {})</tt>
|
52
|
+
* Creates an html input field with given type and options
|
53
|
+
* <tt>input_tag :text, :class => "demo"</tt>
|
54
|
+
* <tt>input_tag :password, :value => "secret", :class => "demo"</tt>
|
55
|
+
|
56
|
+
=== Asset Helpers
|
57
|
+
|
58
|
+
* <tt>flash_tag(kind, options={})</tt>
|
59
|
+
* Creates a div to display the flash of given type if it exists
|
60
|
+
* <tt>flash_tag(:notice, :class => 'flash', :id => 'flash-notice')</tt>
|
61
|
+
* <tt>link_to(*args, &block)</tt>
|
62
|
+
* Creates a link element with given name, url and options
|
63
|
+
* <tt>link_to 'click me', '/dashboard', :class => 'linky'</tt>
|
64
|
+
* <tt>link_to('/dashboard', :class => 'blocky') { ...content... }</tt>
|
65
|
+
* <tt>mail_to(email, caption=nil, mail_options={})</tt>
|
66
|
+
* Creates a mailto link tag to the specified email_address
|
67
|
+
* <tt>mail_to "me@demo.com"</tt>
|
68
|
+
* <tt>mail_to "me@demo.com", "My Email", :subject => "Feedback", :cc => 'test@demo.com'</tt>
|
69
|
+
* <tt>image_tag(url, options={})</tt>
|
70
|
+
* Creates an image element with given url and options
|
71
|
+
* <tt>image_tag('icons/avatar.png')</tt>
|
72
|
+
* <tt>stylesheet_link_tag(*sources)</tt>
|
73
|
+
* Returns a stylesheet link tag for the sources specified as arguments
|
74
|
+
* <tt>stylesheet_link_tag 'style', 'application', 'layout'</tt>
|
75
|
+
* <tt>javascript_include_tag(*sources)</tt>
|
76
|
+
* Returns an html script tag for each of the sources provided.
|
77
|
+
* <tt>javascript_include_tag 'application', 'special'</tt>
|
78
|
+
|
79
|
+
=== Form Helpers
|
80
|
+
|
81
|
+
* <tt>form_tag(url, options={}, &block)</tt>
|
82
|
+
* Constructs a form without object based on options
|
83
|
+
* Supports form methods 'put' and 'delete' through hidden field
|
84
|
+
* <tt>form_tag('/register', :class => 'example') { ... }</tt>
|
85
|
+
* <tt>field_set_tag(*args, &block)</tt>
|
86
|
+
* Constructs a field_set to group fields with given options
|
87
|
+
* <tt>field_set_tag(:class => 'office-set') { }</tt>
|
88
|
+
* <tt>field_set_tag("Office", :class => 'office-set') { }</tt>
|
89
|
+
* <tt>error_messages_for(record, options={})</tt>
|
90
|
+
* Constructs list html for the errors for a given object
|
91
|
+
* <tt>error_messages_for @user</tt>
|
92
|
+
* <tt>label_tag(name, options={}, &block)</tt>
|
93
|
+
* Constructs a label tag from the given options
|
94
|
+
* <tt>label_tag :username, :class => 'long-label'</tt>
|
95
|
+
* <tt>label_tag(:username, :class => 'blocked-label') { ... }</tt>
|
96
|
+
* <tt>hidden_field_tag(name, options={})</tt>
|
97
|
+
* Constructs a hidden field input from the given options
|
98
|
+
* <tt>hidden_field_tag :session_key, :value => 'secret'</tt>
|
99
|
+
* <tt>text_field_tag(name, options={})</tt>
|
100
|
+
* Constructs a text field input from the given options
|
101
|
+
* <tt>text_field_tag :username, :class => 'long'</tt>
|
102
|
+
* <tt>text_area_tag(name, options={})</tt>
|
103
|
+
* Constructs a text area input from the given options
|
104
|
+
* <tt>text_area_tag :username, :class => 'long'</tt>
|
105
|
+
* <tt>password_field_tag(name, options={})</tt>
|
106
|
+
* Constructs a password field input from the given options
|
107
|
+
* <tt>password_field_tag :password, :class => 'long'</tt>
|
108
|
+
* <tt>check_box_tag(name, options={})</tt>
|
109
|
+
* Constructs a checkbox input from the given options
|
110
|
+
* <tt>check_box_tag :remember_me, :checked => true</tt>
|
111
|
+
* <tt>radio_button_tag(name, options={})</tt>
|
112
|
+
* Constructs a radio button input from the given options
|
113
|
+
* <tt>radio_button_tag :gender, :value => 'male'</tt>
|
114
|
+
* <tt>select_tag(name, settings={})</tt>
|
115
|
+
* Constructs a select tag with options from the given settings
|
116
|
+
* <tt>select_tag(:favorite_color, :options => ['1', '2', '3'], :selected => '1')</tt>
|
117
|
+
* <tt>select_tag(:more_color, :options => [['label', '1'], ['label2', '2']])</tt>
|
118
|
+
* <tt>select_tag(:multiple_color, :options => [...], :multiple => true)</tt>
|
119
|
+
* <tt>file_field_tag(name, options={})</tt>
|
120
|
+
* Constructs a file field input from the given options
|
121
|
+
* <tt>file_field_tag :photo, :class => 'long'</tt>
|
122
|
+
* <tt>submit_tag(caption, options={})</tt>
|
123
|
+
* Constructs a submit button from the given options
|
124
|
+
* <tt>submit_tag "Create", :class => 'success'</tt>
|
125
|
+
* <tt>button_tag(caption, options={})</tt>
|
126
|
+
* Constructs an input (type => 'button') from the given options
|
127
|
+
* <tt>button_tag "Cancel", :class => 'clear'</tt>
|
128
|
+
* <tt>image_submit_tag(source, options={})</tt>
|
129
|
+
* Constructs an image submit button from the given options
|
130
|
+
* <tt>image_submit_tag "submit.png", :class => 'success'</tt>
|
131
|
+
|
132
|
+
A form_tag might look like:
|
133
|
+
|
134
|
+
- form_tag '/destroy', :class => 'destroy-form', :method => 'delete' do
|
135
|
+
= flash_tag(:notice)
|
136
|
+
- field_set_tag do
|
137
|
+
%p
|
138
|
+
= label_tag :username, :class => 'first'
|
139
|
+
= text_field_tag :username, :value => params[:username]
|
140
|
+
%p
|
141
|
+
= label_tag :password, :class => 'first'
|
142
|
+
= password_field_tag :password, :value => params[:password]
|
143
|
+
%p
|
144
|
+
= label_tag :strategy
|
145
|
+
= select_tag :strategy, :options => ['delete', 'destroy'], :selected => 'delete'
|
146
|
+
%p
|
147
|
+
= check_box_tag :confirm_delete
|
148
|
+
- field_set_tag(:class => 'buttons') do
|
149
|
+
= submit_tag "Remove"
|
150
|
+
|
151
|
+
=== FormBuilders
|
152
|
+
|
153
|
+
* <tt>form_for(object, url, settings={}, &block)</tt>
|
154
|
+
* Constructs a form using given or default form_builder
|
155
|
+
* Supports form methods 'put' and 'delete' through hidden field
|
156
|
+
* Defaults to StandardFormBuilder but you can easily create your own!
|
157
|
+
* <tt>form_for(@user, '/register', :id => 'register') { |f| ...field-elements... }</tt>
|
158
|
+
* <tt>form_for(:user, '/register', :id => 'register') { |f| ...field-elements... }</tt>
|
159
|
+
* <tt>fields_for(object, settings={}, &block)</tt>
|
160
|
+
* Constructs fields for a given object for use in an existing form
|
161
|
+
* Defaults to StandardFormBuilder but you can easily create your own!
|
162
|
+
* <tt>fields_for @user.assignment do |assignment| ... end</tt>
|
163
|
+
* <tt>fields_for :assignment do |assigment| ... end</tt>
|
164
|
+
|
165
|
+
The following are fields provided by AbstractFormBuilder that can be used within a form_for or fields_for:
|
166
|
+
|
167
|
+
* <tt>error_messages(options={})</tt>
|
168
|
+
* Displays list html for the errors on form object
|
169
|
+
* <tt>f.errors_messages</tt>
|
170
|
+
* <tt>label(field, options={})</tt>
|
171
|
+
* <tt>f.label :name, :class => 'long'</tt>
|
172
|
+
* <tt>text_field(field, options={})</tt>
|
173
|
+
* <tt>f.text_field :username, :class => 'long'</tt>
|
174
|
+
* <tt>check_box(field, options={})</tt>
|
175
|
+
* Uses hidden field to provide a 'unchecked' value for field
|
176
|
+
* <tt>f.check_box :remember_me, :uncheck_value => 'false'</tt>
|
177
|
+
* <tt>radio_button(field, options={})</tt>
|
178
|
+
* <tt>f.radio_button :gender, :value => 'male'</tt>
|
179
|
+
* <tt>hidden_field(field, options={})</tt>
|
180
|
+
* <tt>f.hidden_field :session_id, :class => 'hidden'</tt>
|
181
|
+
* <tt>text_area(field, options={})</tt>
|
182
|
+
* <tt>f.text_area :summary, :class => 'long'</tt>
|
183
|
+
* <tt>password_field(field, options={})</tt>
|
184
|
+
* <tt>f.password_field :secret, :class => 'long'</tt>
|
185
|
+
* <tt>file_field(field, options={})</tt>
|
186
|
+
* <tt>f.file_field :photo, :class => 'long'</tt>
|
187
|
+
* <tt>select(field, options={})</tt>
|
188
|
+
* <tt>f.select(:state, :options => ['California', 'Texas', 'Wyoming'])</tt>
|
189
|
+
* <tt>f.select(:state, :collection => @states, :fields => [:name, :id])</tt>
|
190
|
+
* <tt>f.select(:state, :options => [...], :include_blank => true)</tt>
|
191
|
+
* <tt>submit(caption, options={})</tt>
|
192
|
+
* <tt>f.submit "Update", :class => 'long'</tt>
|
193
|
+
* <tt>image_submit(source, options={})</tt>
|
194
|
+
* <tt>f.image_submit "submit.png", :class => 'long'</tt>
|
195
|
+
|
196
|
+
A form_for using these basic fields might look like:
|
197
|
+
|
198
|
+
- form_for @user, '/register', :id => 'register' do |f|
|
199
|
+
= f.error_messages
|
200
|
+
%p
|
201
|
+
= f.label :username, :caption => "Nickname"
|
202
|
+
= f.text_field :username
|
203
|
+
%p
|
204
|
+
= f.label :email
|
205
|
+
= f.text_field :email
|
206
|
+
%p
|
207
|
+
= f.label :password
|
208
|
+
= f.password_field :password
|
209
|
+
%p
|
210
|
+
= f.label :is_admin, :caption => "Admin User?"
|
211
|
+
= f.check_box :is_admin
|
212
|
+
%p
|
213
|
+
= f.label :color, :caption => "Favorite Color?"
|
214
|
+
= f.select :color, :options => ['red', 'black']
|
215
|
+
%p
|
216
|
+
- fields_for @user.location do |location|
|
217
|
+
= location.text_field :street
|
218
|
+
= location.text_field :city
|
219
|
+
%p
|
220
|
+
= f.submit "Create", :class => 'button'
|
221
|
+
|
222
|
+
There is also a StandardFormBuilder which builds on the abstract fields that can be used within a form_for:
|
223
|
+
|
224
|
+
* <tt>text_field_block(field, options={}, label_options={})</tt>
|
225
|
+
* <tt>text_field_block(:nickname, :class => 'big', :caption => "Username")</tt>
|
226
|
+
* <tt>text_area_block(field, options={}, label_options={})</tt>
|
227
|
+
* <tt>text_area_block(:about, :class => 'big')</tt>
|
228
|
+
* <tt>password_field_block(field, options={}, label_options={})</tt>
|
229
|
+
* <tt>password_field_block(:code, :class => 'big')</tt>
|
230
|
+
* <tt>file_field_block(field, options={}, label_options={})</tt>
|
231
|
+
* <tt>file_field_block(:photo, :class => 'big')</tt>
|
232
|
+
* <tt>check_box_block(field, options={}, label_options={})</tt>
|
233
|
+
* <tt>check_box_block(:remember_me, :class => 'big')</tt>
|
234
|
+
* <tt>select_block(field, options={}, label_options={})</tt>
|
235
|
+
* <tt>select_block(:country, :option => ['USA', 'Canada'])</tt>
|
236
|
+
* <tt>submit_block(caption, options={})</tt>
|
237
|
+
* <tt>submit_block(:username, :class => 'big')</tt>
|
238
|
+
* <tt>image_submit_block(source, options={})</tt>
|
239
|
+
* <tt>image_submit_block('submit.png', :class => 'big')</tt>
|
240
|
+
|
241
|
+
A form_for using these standard fields might look like:
|
242
|
+
|
243
|
+
- form_for @user, '/register', :id => 'register' do |f|
|
244
|
+
= f.error_messages
|
245
|
+
= f.text_field_block :name, :caption => "Full name"
|
246
|
+
= f.text_field_block :email
|
247
|
+
= f.check_box_block :remember_me
|
248
|
+
= f.select_block :fav_color, :options => ['red', 'blue']
|
249
|
+
= f.password_field_block :password
|
250
|
+
= f.submit_block "Create", :class => 'button'
|
251
|
+
|
252
|
+
and would generate this html:
|
253
|
+
|
254
|
+
<form id="register" action="/register" method="post">
|
255
|
+
<p><label for="user_name">Full name: </label><input type="text" id="user_name" name="user[name]"></p>
|
256
|
+
...omitted...
|
257
|
+
<p><input type="submit" value="Create" class="button"></p>
|
258
|
+
</form>
|
259
|
+
|
260
|
+
You can also easily build your own FormBuilder which allows for customized fields:
|
261
|
+
|
262
|
+
class MyCustomFormBuilder < AbstractFormBuilder
|
263
|
+
# Here we have access to a number of useful variables
|
264
|
+
#
|
265
|
+
# * template (use this to invoke any helpers)(ex. template.hidden_field_tag(...))
|
266
|
+
# * object (the record for this form) (ex. object.valid?)
|
267
|
+
# * object_name (object's underscored type) (ex. object_name => 'admin_user')
|
268
|
+
#
|
269
|
+
# We also have access to self.field_types => [:text_field, :text_area, ...]
|
270
|
+
# In addition, we have access to all the existing field tag helpers (text_field, hidden_field, file_field, ...)
|
271
|
+
end
|
272
|
+
|
273
|
+
Once a custom builder is defined, any call to form_for can use the new builder:
|
274
|
+
|
275
|
+
- form_for @user, '/register', :builder => 'MyCustomFormBuilder', :id => 'register' do |f|
|
276
|
+
...fields here...
|
277
|
+
|
278
|
+
The form builder can even be made into the default builder when form_for is invoked:
|
279
|
+
|
280
|
+
# anywhere in the sinatra application
|
281
|
+
set :default_builder, 'MyCustomFormBuilder'
|
282
|
+
|
283
|
+
And there you have it, a fairly complete form builder solution for sinatra.
|
284
|
+
I hope to create or merge in an even better 'default' form_builder in the near future.
|
285
|
+
|
286
|
+
=== Format Helpers
|
287
|
+
|
288
|
+
* <tt>escape_html</tt> (alias <tt>h</tt> and <tt>h!</tt>)
|
289
|
+
* (from RackUtils) Escape ampersands, brackets and quotes to their HTML/XML entities.
|
290
|
+
* <tt>relative_time_ago(date)</tt>
|
291
|
+
* Returns relative time in words referencing the given date
|
292
|
+
* <tt>relative_time_ago(2.days.ago)</tt> => "2 days"
|
293
|
+
* <tt>relative_time_ago(5.minutes.ago)</tt> => "5 minutes"
|
294
|
+
* <tt>relative_time_ago(2800.days.ago)</tt> => "over 7 years"
|
295
|
+
* <tt>time_in_words(date)</tt>
|
296
|
+
* Returns relative time in the past or future using appropriate date format
|
297
|
+
* <tt>time_in_words(2.days.ago)</tt> => "2 days ago"
|
298
|
+
* <tt>time_in_words(100.days.ago)</tt> => "Tuesday, July 21"
|
299
|
+
* <tt>time_in_words(1.day.from_now)</tt> => "tomorrow"
|
300
|
+
* <tt>escape_javascript(html_content)</tt>
|
301
|
+
* Escapes html to allow passing information to javascript. Used for passing data inside an ajax .js.erb template
|
302
|
+
* <tt>escape_javascript("<h1>Hey</h1>")</tt>
|
303
|
+
|
304
|
+
See the wiki article for additional information: <...WIKI...>
|
305
|
+
|
306
|
+
=== Render Helpers
|
307
|
+
|
308
|
+
This component provides a number of rendering helpers for sinatra, making the process
|
309
|
+
of displaying templates far smoother. This plugin also has support for useful additions
|
310
|
+
such as partials (with support for :collection) into the templating system.
|
311
|
+
|
312
|
+
* <tt>erb_template(template_path, options={})</tt>
|
313
|
+
* Renders a erb template based on the given path
|
314
|
+
* <tt>erb_template 'users/new'</tt>
|
315
|
+
* <tt>haml_template(template_path, options={})</tt>
|
316
|
+
* Renders a haml template based on the given path
|
317
|
+
* <tt>haml_template 'users/new'</tt>
|
318
|
+
* <tt>render_template(template_path, options={})</tt>
|
319
|
+
* Renders the first detected template based on the given path
|
320
|
+
* <tt>render_template 'users/new'</tt>
|
321
|
+
* <tt>render_template 'users/index', :template_engine => 'haml'</tt>
|
322
|
+
* <tt>partial(template, *args)</tt>
|
323
|
+
* Renders the html related to the partial template for object or collection
|
324
|
+
* <tt>partial 'photo/_item', :object => @photo, :locals => { :foo => 'bar' }</tt>
|
325
|
+
* <tt>partial 'photo/_item', :collection => @photos</tt>
|
326
|
+
|
327
|
+
Using render plugin helpers is extremely simple. If you want to render an erb template in your view path:
|
328
|
+
|
329
|
+
erb_template 'path/to/my/template'
|
330
|
+
|
331
|
+
or using haml templates works just as well:
|
332
|
+
|
333
|
+
haml_template 'path/to/haml/template'
|
334
|
+
|
335
|
+
There is also a method which renders the first view matching the path and removes the need to define an engine:
|
336
|
+
|
337
|
+
render_template 'path/to/any/template'
|
338
|
+
|
339
|
+
It is worth noting these are mostly for convenience. When I had more complex view files in sinatra, I got tired of writing:
|
340
|
+
|
341
|
+
haml :"the/path/to/file"
|
342
|
+
erb "/path/to/file".to_sym
|
343
|
+
|
344
|
+
Finally, we have the all-important partials support for rendering mini-templates onto a page:
|
345
|
+
|
346
|
+
partial 'photo/_item', :object => @photo, :locals => { :foo => 'bar' }
|
347
|
+
partial 'photo/_item', :collection => @photos
|
348
|
+
|
349
|
+
This works as you would expect and also supports the collection counter inside the partial <tt>item_counter</tt>
|
350
|
+
|
351
|
+
# /views/photo/_item.haml
|
352
|
+
# Access to collection counter with <partial_name>_counter i.e item_counter
|
353
|
+
# Access the object with the partial_name i.e item
|
354
|
+
|
355
|
+
And that concludes the render plugin for now but I am open to adding more methods as time progresses.
|
356
|
+
|
357
|
+
See the wiki article for additional information: <...WIKI...>
|
4
358
|
|
5
359
|
== Copyright
|
6
360
|
|
data/Rakefile
CHANGED
@@ -11,6 +11,7 @@ begin
|
|
11
11
|
gem.homepage = "http://github.com/padrino/padrino-helpers"
|
12
12
|
gem.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"]
|
13
13
|
gem.add_runtime_dependency "sinatra", ">= 0.9.2"
|
14
|
+
gem.add_runtime_dependency "padrino-core", ">= 0.1.1"
|
14
15
|
gem.add_development_dependency "haml", ">= 2.2.1"
|
15
16
|
gem.add_development_dependency "shoulda", ">= 0"
|
16
17
|
gem.add_development_dependency "mocha", ">= 0.9.7"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
@@ -62,7 +62,7 @@ module Padrino
|
|
62
62
|
# Returns the path to the image, either relative or absolute
|
63
63
|
def image_path(src)
|
64
64
|
src.gsub!(/\s/, '')
|
65
|
-
src =~ %r{^\s*(/|http)} ? src :
|
65
|
+
src =~ %r{^\s*(/|http)} ? src : uri_root_path('images', src)
|
66
66
|
end
|
67
67
|
|
68
68
|
protected
|
@@ -79,19 +79,30 @@ module Padrino
|
|
79
79
|
tag(:script, options)
|
80
80
|
end
|
81
81
|
|
82
|
+
# Returns the javascript_path appending the default javascripts path if necessary
|
82
83
|
def javascript_path(source)
|
83
84
|
return source if source =~ /^http/
|
84
|
-
result_path = "
|
85
|
+
result_path = "#{source}.js" if source =~ %r{^/} # absolute path
|
86
|
+
result_path ||= uri_root_path("javascripts", "#{File.basename(source, '.js')}.js")
|
85
87
|
stamp = File.exist?(result_path) ? File.mtime(result_path) : Time.now.to_i
|
86
88
|
"#{result_path}?#{stamp}"
|
87
89
|
end
|
88
90
|
|
91
|
+
# Returns the stylesheet_path appending the default stylesheets path if necessary
|
89
92
|
def stylesheet_path(source)
|
90
93
|
return source if source =~ /^http/
|
91
|
-
result_path = "
|
94
|
+
result_path = "#{source}.css" if source =~ %r{^/} # absolute path
|
95
|
+
result_path ||= uri_root_path("stylesheets", "#{File.basename(source, '.css')}.css")
|
92
96
|
stamp = File.exist?(result_path) ? File.mtime(result_path) : Time.now.to_i
|
93
97
|
"#{result_path}?#{stamp}"
|
94
98
|
end
|
99
|
+
|
100
|
+
# Returns the uri root of the application, defaulting to '/'
|
101
|
+
# @example uri_root('javascripts')
|
102
|
+
def uri_root_path(*paths)
|
103
|
+
root_uri = self.class.uri_root if self.class.respond_to?(:uri_root)
|
104
|
+
File.join(root_uri || '/', *paths)
|
105
|
+
end
|
95
106
|
end
|
96
107
|
end
|
97
108
|
end
|
data/padrino-helpers.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{padrino-helpers}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-18}
|
13
13
|
s.description = %q{Tag helpers, asset helpers, form helpers, form builders and many more helpers for padrino}
|
14
14
|
s.email = %q{nesquena@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -80,6 +80,7 @@ Gem::Specification.new do |s|
|
|
80
80
|
|
81
81
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
82
82
|
s.add_runtime_dependency(%q<sinatra>, [">= 0.9.2"])
|
83
|
+
s.add_runtime_dependency(%q<padrino-core>, [">= 0.1.1"])
|
83
84
|
s.add_development_dependency(%q<haml>, [">= 2.2.1"])
|
84
85
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
85
86
|
s.add_development_dependency(%q<mocha>, [">= 0.9.7"])
|
@@ -87,6 +88,7 @@ Gem::Specification.new do |s|
|
|
87
88
|
s.add_development_dependency(%q<webrat>, [">= 0.5.1"])
|
88
89
|
else
|
89
90
|
s.add_dependency(%q<sinatra>, [">= 0.9.2"])
|
91
|
+
s.add_dependency(%q<padrino-core>, [">= 0.1.1"])
|
90
92
|
s.add_dependency(%q<haml>, [">= 2.2.1"])
|
91
93
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
92
94
|
s.add_dependency(%q<mocha>, [">= 0.9.7"])
|
@@ -95,6 +97,7 @@ Gem::Specification.new do |s|
|
|
95
97
|
end
|
96
98
|
else
|
97
99
|
s.add_dependency(%q<sinatra>, [">= 0.9.2"])
|
100
|
+
s.add_dependency(%q<padrino-core>, [">= 0.1.1"])
|
98
101
|
s.add_dependency(%q<haml>, [">= 2.2.1"])
|
99
102
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
100
103
|
s.add_dependency(%q<mocha>, [">= 0.9.7"])
|
@@ -82,6 +82,10 @@ class TestAssetTagHelpers < Test::Unit::TestCase
|
|
82
82
|
should "display image tag absolute link with no options" do
|
83
83
|
assert_has_tag('img', :src => "/absolute/pic.gif") { image_tag('/absolute/pic.gif') }
|
84
84
|
end
|
85
|
+
should "display image tag absolute link with specified uri root" do
|
86
|
+
self.class.stubs(:uri_root).returns("/blog")
|
87
|
+
assert_has_tag('img', :src => "/blog/images/relative/pic.gif") { image_tag('relative/pic.gif') }
|
88
|
+
end
|
85
89
|
should "display image tag relative link with options" do
|
86
90
|
assert_has_tag('img.photo', :src => "/images/relative/pic.gif") { image_tag('relative/pic.gif', :class => 'photo') }
|
87
91
|
end
|
@@ -99,6 +103,19 @@ class TestAssetTagHelpers < Test::Unit::TestCase
|
|
99
103
|
expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" }
|
100
104
|
assert_has_tag('link', expected_options.merge(:href => "/stylesheets/style.css?#{time.to_i}")) { stylesheet_link_tag('style') }
|
101
105
|
end
|
106
|
+
should "display stylesheet link item with absolute path" do
|
107
|
+
time = stop_time_for_test
|
108
|
+
expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" }
|
109
|
+
actual_html = stylesheet_link_tag('/css/style')
|
110
|
+
assert_has_tag('link', expected_options.merge(:href => "/css/style.css?#{time.to_i}")) { actual_html }
|
111
|
+
end
|
112
|
+
should "display stylesheet link item with uri root" do
|
113
|
+
self.class.stubs(:uri_root).returns("/blog")
|
114
|
+
time = stop_time_for_test
|
115
|
+
expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" }
|
116
|
+
actual_html = stylesheet_link_tag('style')
|
117
|
+
assert_has_tag('link', expected_options.merge(:href => "/blog/stylesheets/style.css?#{time.to_i}")) { actual_html }
|
118
|
+
end
|
102
119
|
should "display stylesheet link items" do
|
103
120
|
time = stop_time_for_test
|
104
121
|
actual_html = stylesheet_link_tag('style', 'layout.css', 'http://google.com/style.css')
|
@@ -115,6 +132,17 @@ class TestAssetTagHelpers < Test::Unit::TestCase
|
|
115
132
|
actual_html = javascript_include_tag('application')
|
116
133
|
assert_has_tag('script', :src => "/javascripts/application.js?#{time.to_i}", :type => "text/javascript") { actual_html }
|
117
134
|
end
|
135
|
+
should "display javascript item with absolute path" do
|
136
|
+
time = stop_time_for_test
|
137
|
+
actual_html = javascript_include_tag('/js/application')
|
138
|
+
assert_has_tag('script', :src => "/js/application.js?#{time.to_i}", :type => "text/javascript") { actual_html }
|
139
|
+
end
|
140
|
+
should "display javascript item with uri root" do
|
141
|
+
self.class.stubs(:uri_root).returns("/blog")
|
142
|
+
time = stop_time_for_test
|
143
|
+
actual_html = javascript_include_tag('application')
|
144
|
+
assert_has_tag('script', :src => "/blog/javascripts/application.js?#{time.to_i}", :type => "text/javascript") { actual_html }
|
145
|
+
end
|
118
146
|
should "display javascript items" do
|
119
147
|
time = stop_time_for_test
|
120
148
|
actual_html = javascript_include_tag('application', 'base.js', 'http://google.com/lib.js')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: padrino-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Padrino Team
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2009-11-
|
15
|
+
date: 2009-11-18 00:00:00 -08:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -25,6 +25,16 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.9.2
|
27
27
|
version:
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: padrino-core
|
30
|
+
type: :runtime
|
31
|
+
version_requirement:
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.1.1
|
37
|
+
version:
|
28
38
|
- !ruby/object:Gem::Dependency
|
29
39
|
name: haml
|
30
40
|
type: :development
|