padrino-helpers 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|