actionpack 3.0.0.rc → 3.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (57) hide show
  1. data/CHANGELOG +11 -2
  2. data/README.rdoc +3 -3
  3. data/lib/abstract_controller/base.rb +13 -1
  4. data/lib/action_controller.rb +2 -1
  5. data/lib/action_controller/base.rb +1 -1
  6. data/lib/action_controller/deprecated/base.rb +11 -1
  7. data/lib/action_controller/deprecated/url_writer.rb +14 -0
  8. data/lib/action_controller/metal/http_authentication.rb +3 -3
  9. data/lib/action_controller/metal/responder.rb +2 -8
  10. data/lib/action_controller/middleware.rb +1 -1
  11. data/lib/action_controller/test_case.rb +1 -1
  12. data/lib/action_controller/vendor/html-scanner/html/document.rb +2 -2
  13. data/lib/action_controller/vendor/html-scanner/html/node.rb +29 -29
  14. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +25 -25
  15. data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
  16. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +8 -8
  17. data/lib/action_dispatch.rb +1 -0
  18. data/lib/action_dispatch/http/cache.rb +2 -2
  19. data/lib/action_dispatch/http/mime_type.rb +10 -10
  20. data/lib/action_dispatch/http/parameters.rb +2 -2
  21. data/lib/action_dispatch/http/request.rb +7 -0
  22. data/lib/action_dispatch/http/url.rb +10 -0
  23. data/lib/action_dispatch/middleware/best_standards_support.rb +22 -0
  24. data/lib/action_dispatch/middleware/cookies.rb +18 -8
  25. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -5
  26. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +1 -0
  27. data/lib/action_dispatch/middleware/show_exceptions.rb +2 -9
  28. data/lib/action_dispatch/middleware/stack.rb +1 -1
  29. data/lib/action_dispatch/railtie.rb +2 -1
  30. data/lib/action_dispatch/routing.rb +4 -4
  31. data/lib/action_dispatch/routing/deprecated_mapper.rb +1 -0
  32. data/lib/action_dispatch/routing/mapper.rb +34 -21
  33. data/lib/action_dispatch/routing/route_set.rb +8 -5
  34. data/lib/action_dispatch/routing/url_for.rb +1 -1
  35. data/lib/action_dispatch/testing/assertions/routing.rb +37 -14
  36. data/lib/action_dispatch/testing/integration.rb +1 -0
  37. data/lib/action_pack/version.rb +1 -1
  38. data/lib/action_view/base.rb +1 -0
  39. data/lib/action_view/helpers/asset_tag_helper.rb +12 -0
  40. data/lib/action_view/helpers/debug_helper.rb +1 -1
  41. data/lib/action_view/helpers/form_helper.rb +7 -6
  42. data/lib/action_view/helpers/form_options_helper.rb +21 -18
  43. data/lib/action_view/helpers/form_tag_helper.rb +9 -9
  44. data/lib/action_view/helpers/number_helper.rb +1 -1
  45. data/lib/action_view/helpers/raw_output_helper.rb +1 -1
  46. data/lib/action_view/helpers/sanitize_helper.rb +4 -2
  47. data/lib/action_view/helpers/text_helper.rb +5 -2
  48. data/lib/action_view/helpers/translation_helper.rb +9 -9
  49. data/lib/action_view/log_subscriber.rb +1 -1
  50. data/lib/action_view/render/layouts.rb +8 -4
  51. data/lib/action_view/render/partials.rb +1 -1
  52. data/lib/action_view/template/handler.rb +1 -1
  53. data/lib/action_view/template/handlers.rb +1 -1
  54. data/lib/action_view/template/resolver.rb +15 -0
  55. data/lib/action_view/test_case.rb +1 -1
  56. data/lib/action_view/testing/resolvers.rb +1 -1
  57. metadata +18 -16
@@ -392,10 +392,9 @@ module ActionDispatch
392
392
  end
393
393
 
394
394
  def generate
395
- error = ActionController::RoutingError.new("No route matches #{options.inspect}")
396
395
  path, params = @set.set.generate(:path_info, named_route, options, recall, opts)
397
396
 
398
- raise error unless path
397
+ raise_routing_error unless path
399
398
 
400
399
  params.reject! {|k,v| !v }
401
400
 
@@ -404,7 +403,7 @@ module ActionDispatch
404
403
  path << "?#{params.to_query}" if params.any?
405
404
  "#{script_name}#{path}"
406
405
  rescue Rack::Mount::RoutingError
407
- raise error
406
+ raise_routing_error
408
407
  end
409
408
 
410
409
  def opts
@@ -421,6 +420,10 @@ module ActionDispatch
421
420
  {:parameterize => parameterize}
422
421
  end
423
422
 
423
+ def raise_routing_error
424
+ raise ActionController::RoutingError.new("No route matches #{options.inspect}")
425
+ end
426
+
424
427
  def different_controller?
425
428
  return false unless current_controller
426
429
  controller.to_param != current_controller.to_param
@@ -491,7 +494,7 @@ module ActionDispatch
491
494
 
492
495
  def recognize_path(path, environment = {})
493
496
  method = (environment[:method] || "GET").to_s.upcase
494
- path = Rack::Mount::Utils.normalize_path(path)
497
+ path = Rack::Mount::Utils.normalize_path(path) unless path =~ %r{://}
495
498
 
496
499
  begin
497
500
  env = Rack::MockRequest.env_for(path, {:method => method})
@@ -499,7 +502,7 @@ module ActionDispatch
499
502
  raise ActionController::RoutingError, e.message
500
503
  end
501
504
 
502
- req = Rack::Request.new(env)
505
+ req = @request_class.new(env)
503
506
  @set.recognize(req) do |route, matches, params|
504
507
  params.each do |key, value|
505
508
  if value.is_a?(String)
@@ -20,7 +20,7 @@ module ActionDispatch
20
20
  # <%= link_to('Click here', :controller => 'users',
21
21
  # :action => 'new', :message => 'Welcome!') %>
22
22
  #
23
- # #=> Generates a link to: /users/new?message=Welcome%21
23
+ # # Generates a link to /users/new?message=Welcome%21
24
24
  #
25
25
  # link_to, and all other functions that require URL generation functionality,
26
26
  # actually use ActionController::UrlFor under the hood. And in particular,
@@ -1,3 +1,4 @@
1
+ require 'uri'
1
2
  require 'active_support/core_ext/hash/diff'
2
3
  require 'active_support/core_ext/hash/indifferent_access'
3
4
 
@@ -40,14 +41,7 @@ module ActionDispatch
40
41
  # # Check a Simply RESTful generated route
41
42
  # assert_recognizes list_items_url, 'items/list'
42
43
  def assert_recognizes(expected_options, path, extras={}, message=nil)
43
- if path.is_a? Hash
44
- request_method = path[:method]
45
- path = path[:path]
46
- else
47
- request_method = nil
48
- end
49
-
50
- request = recognized_request_for(path, request_method)
44
+ request = recognized_request_for(path)
51
45
 
52
46
  expected_options = expected_options.clone
53
47
  extras.each_key { |key| expected_options.delete key } unless extras.nil?
@@ -77,7 +71,16 @@ module ActionDispatch
77
71
  # # Asserts that the generated route gives us our custom route
78
72
  # assert_generates "changesets/12", { :controller => 'scm', :action => 'show_diff', :revision => "12" }
79
73
  def assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)
80
- expected_path = "/#{expected_path}" unless expected_path[0] == ?/
74
+ if expected_path =~ %r{://}
75
+ begin
76
+ uri = URI.parse(expected_path)
77
+ expected_path = uri.path.to_s.empty? ? "/" : uri.path
78
+ rescue URI::InvalidURIError => e
79
+ raise ActionController::RoutingError, e.message
80
+ end
81
+ else
82
+ expected_path = "/#{expected_path}" unless expected_path.first == '/'
83
+ end
81
84
  # Load routes.rb if it hasn't been loaded.
82
85
 
83
86
  generated_path, extra_keys = @routes.generate_extras(options, defaults)
@@ -177,15 +180,35 @@ module ActionDispatch
177
180
 
178
181
  private
179
182
  # Recognizes the route for a given path.
180
- def recognized_request_for(path, request_method = nil)
181
- path = "/#{path}" unless path.first == '/'
183
+ def recognized_request_for(path)
184
+ if path.is_a?(Hash)
185
+ method = path[:method]
186
+ path = path[:path]
187
+ else
188
+ method = :get
189
+ end
182
190
 
183
191
  # Assume given controller
184
192
  request = ActionController::TestRequest.new
185
- request.env["REQUEST_METHOD"] = request_method.to_s.upcase if request_method
186
- request.path = path
187
193
 
188
- params = @routes.recognize_path(path, { :method => request.method })
194
+ if path =~ %r{://}
195
+ begin
196
+ uri = URI.parse(path)
197
+ request.env["rack.url_scheme"] = uri.scheme || "http"
198
+ request.host = uri.host if uri.host
199
+ request.port = uri.port if uri.port
200
+ request.path = uri.path.to_s.empty? ? "/" : uri.path
201
+ rescue URI::InvalidURIError => e
202
+ raise ActionController::RoutingError, e.message
203
+ end
204
+ else
205
+ path = "/#{path}" unless path.first == "/"
206
+ request.path = path
207
+ end
208
+
209
+ request.request_method = method if method
210
+
211
+ params = @routes.recognize_path(path, { :method => method })
189
212
  request.path_parameters = params.with_indifferent_access
190
213
 
191
214
  request
@@ -1,6 +1,7 @@
1
1
  require 'stringio'
2
2
  require 'uri'
3
3
  require 'active_support/core_ext/kernel/singleton_class'
4
+ require 'active_support/core_ext/object/try'
4
5
  require 'rack/test'
5
6
  require 'test/unit/assertions'
6
7
 
@@ -3,7 +3,7 @@ module ActionPack
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
5
  TINY = 0
6
- BUILD = "rc"
6
+ BUILD = "rc2"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, BUILD].join('.')
9
9
  end
@@ -227,6 +227,7 @@ module ActionView #:nodoc:
227
227
  @lookup_context = lookup_context.is_a?(ActionView::LookupContext) ?
228
228
  lookup_context : ActionView::LookupContext.new(lookup_context)
229
229
  @lookup_context.formats = formats if formats
230
+ @controller = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :controller)
230
231
  end
231
232
 
232
233
  def controller_path
@@ -393,6 +393,18 @@ module ActionView
393
393
  @@stylesheet_expansions.merge!(expansions)
394
394
  end
395
395
 
396
+ def self.reset_javascript_include_default
397
+ ActiveSupport::Deprecation.warn "reset_javascript_include_default is deprecated. Please manipulate " \
398
+ "config.action_view.javascript_expansions[:defaults] directly", caller
399
+ self.javascript_expansions[:defaults] = ['prototype', 'effects', 'dragdrop', 'controls', 'rails']
400
+ end
401
+
402
+ def self.register_javascript_include_default(*args)
403
+ ActiveSupport::Deprecation.warn "register_javascript_include_default is deprecated. Please " \
404
+ "manipulate config.action_view.javascript_expansions[:defaults] directly", caller
405
+ self.javascript_expansions[:defaults].concat args
406
+ end
407
+
396
408
  # Computes the path to a stylesheet asset in the public stylesheets directory.
397
409
  # If the +source+ filename has no extension, <tt>.css</tt> will be appended (except for explicit URIs).
398
410
  # Full paths from the document root will be passed through.
@@ -1,6 +1,6 @@
1
1
  module ActionView
2
2
  # = Action View Debug Helper
3
- #
3
+ #
4
4
  # Provides a set of methods for making it easier to debug Rails objects.
5
5
  module Helpers
6
6
  module DebugHelper
@@ -215,7 +215,7 @@ module ActionView
215
215
  # ...
216
216
  # <% end %>
217
217
  #
218
- # If your resource has associations defined, for example, you want to add comments
218
+ # If your resource has associations defined, for example, you want to add comments
219
219
  # to the post given that the routes are set correctly:
220
220
  #
221
221
  # <%= form_for([@document, @comment]) do |f| %>
@@ -583,8 +583,9 @@ module ActionView
583
583
  # 'Accept <a href="/terms">Terms</a>.'
584
584
  # end
585
585
  def label(object_name, method, content_or_options = nil, options = nil, &block)
586
- if block_given?
587
- options = content_or_options if content_or_options.is_a?(Hash)
586
+ content_is_options = content_or_options.is_a?(Hash)
587
+ if content_is_options || block_given?
588
+ options = content_or_options if content_is_options
588
589
  text = nil
589
590
  else
590
591
  text = content_or_options
@@ -1005,9 +1006,9 @@ module ActionView
1005
1006
 
1006
1007
  def value_before_type_cast(object, method_name)
1007
1008
  unless object.nil?
1008
- object.respond_to?(method_name + "_before_type_cast") ?
1009
- object.send(method_name + "_before_type_cast") :
1010
- object.send(method_name)
1009
+ object.respond_to?(method_name) ?
1010
+ object.send(method_name) :
1011
+ object.send(method_name + "_before_type_cast")
1011
1012
  end
1012
1013
  end
1013
1014
 
@@ -53,16 +53,16 @@ module ActionView
53
53
  # <option value="2">Sam</option>
54
54
  # <option value="3">Tobias</option>
55
55
  # </select>
56
- #
57
- # Like the other form helpers, +select+ can accept an <tt>:index</tt> option to manually set the ID used in the resulting output. Unlike other helpers, +select+ expects this
56
+ #
57
+ # Like the other form helpers, +select+ can accept an <tt>:index</tt> option to manually set the ID used in the resulting output. Unlike other helpers, +select+ expects this
58
58
  # option to be in the +html_options+ parameter.
59
- #
60
- # Example:
61
- #
59
+ #
60
+ # Example:
61
+ #
62
62
  # select("album[]", "genre", %w[rap rock country], {}, { :index => nil })
63
- #
63
+ #
64
64
  # becomes:
65
- #
65
+ #
66
66
  # <select name="album[][genre]" id="album__genre">
67
67
  # <option value="rap">rap</option>
68
68
  # <option value="rock">rock</option>
@@ -140,7 +140,7 @@ module ActionView
140
140
  # The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are methods to be called on each member
141
141
  # of +collection+. The return values are used as the +value+ attribute and contents of each
142
142
  # <tt><option></tt> tag, respectively.
143
- #
143
+ #
144
144
  # Example object structure for use with this method:
145
145
  # class Post < ActiveRecord::Base
146
146
  # belongs_to :author
@@ -298,17 +298,18 @@ module ActionView
298
298
  return container if String === container
299
299
 
300
300
  container = container.to_a if Hash === container
301
- selected, disabled = extract_selected_and_disabled(selected)
301
+ selected, disabled = extract_selected_and_disabled(selected).map do | r |
302
+ Array.wrap(r).map(&:to_s)
303
+ end
302
304
 
303
- options_for_select = container.inject([]) do |options, element|
305
+ container.map do |element|
304
306
  html_attributes = option_html_attributes(element)
305
- text, value = option_text_and_value(element)
307
+ text, value = option_text_and_value(element).map(&:to_s)
306
308
  selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
307
309
  disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled)
308
- options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{html_escape(text.to_s)}</option>)
309
- end
310
+ %(<option value="#{html_escape(value)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{html_escape(text)}</option>)
311
+ end.join("\n").html_safe
310
312
 
311
- options_for_select.join("\n").html_safe
312
313
  end
313
314
 
314
315
  # Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the
@@ -493,7 +494,7 @@ module ActionView
493
494
  end
494
495
 
495
496
  zone_options += options_for_select(convert_zones[zones], selected)
496
- zone_options
497
+ zone_options.html_safe
497
498
  end
498
499
 
499
500
  private
@@ -528,10 +529,12 @@ module ActionView
528
529
  end
529
530
 
530
531
  def extract_selected_and_disabled(selected)
531
- if selected.is_a?(Hash)
532
- [selected[:selected], selected[:disabled]]
532
+ if selected.is_a?(Proc)
533
+ [ selected, nil ]
533
534
  else
534
- [selected, nil]
535
+ selected = Array.wrap(selected)
536
+ options = selected.extract_options!.symbolize_keys
537
+ [ options[:selected] || selected , options[:disabled] ]
535
538
  end
536
539
  end
537
540
 
@@ -25,7 +25,7 @@ module ActionView
25
25
  # If "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
26
26
  # is added to simulate the verb over post.
27
27
  # * A list of parameters to feed to the URL the form will be posted to.
28
- # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
28
+ # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
29
29
  # submit behaviour. By default this behaviour is an ajax submit.
30
30
  #
31
31
  # ==== Examples
@@ -42,10 +42,10 @@ module ActionView
42
42
  # <div><%= submit_tag 'Save' %></div>
43
43
  # <% end -%>
44
44
  # # => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
45
- #
45
+ #
46
46
  # <%= form_tag('/posts', :remote => true) %>
47
47
  # # => <form action="/posts" method="post" data-remote="true">
48
- #
48
+ #
49
49
  def form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)
50
50
  html_options = html_options_for_form(url_for_options, options, *parameters_for_url)
51
51
  if block_given?
@@ -351,12 +351,12 @@ module ActionView
351
351
  # Creates a submit button with the text <tt>value</tt> as the caption.
352
352
  #
353
353
  # ==== Options
354
- # * <tt>:confirm => 'question?'</tt> - If present the unobtrusive JavaScript
355
- # drivers will provide a prompt with the question specified. If the user accepts,
354
+ # * <tt>:confirm => 'question?'</tt> - If present the unobtrusive JavaScript
355
+ # drivers will provide a prompt with the question specified. If the user accepts,
356
356
  # the form is processed normally, otherwise no action is taken.
357
357
  # * <tt>:disabled</tt> - If true, the user will not be able to use this input.
358
- # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
359
- # disabled version of the submit button when the form is submitted. This feature is
358
+ # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
359
+ # disabled version of the submit button when the form is submitted. This feature is
360
360
  # provided by the unobtrusive JavaScript driver.
361
361
  # * Any other key creates standard HTML options for the tag.
362
362
  #
@@ -383,7 +383,7 @@ module ActionView
383
383
  # # name="commit" type="submit" value="Edit" />
384
384
  #
385
385
  # submit_tag "Save", :confirm => "Are you sure?"
386
- # # => <input name='commit' type='submit' value='Save'
386
+ # # => <input name='commit' type='submit' value='Save'
387
387
  # data-confirm="Are you sure?" />
388
388
  #
389
389
  def submit_tag(value = "Save changes", options = {})
@@ -538,7 +538,7 @@ module ActionView
538
538
 
539
539
  def extra_tags_for_form(html_options)
540
540
  snowman_tag = tag(:input, :type => "hidden",
541
- :name => "_snowman", :value => "&#9731;".html_safe)
541
+ :name => "utf8", :value => "&#x2713;".html_safe)
542
542
 
543
543
  method = html_options.delete("method").to_s
544
544
 
@@ -325,7 +325,7 @@ module ActionView
325
325
  defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
326
326
  human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
327
327
  defaults = defaults.merge(human)
328
-
328
+
329
329
  options = options.reverse_merge(defaults)
330
330
  #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
331
331
  options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
@@ -2,7 +2,7 @@ module ActionView #:nodoc:
2
2
  # = Action View Raw Output Helper
3
3
  module Helpers #:nodoc:
4
4
  module RawOutputHelper
5
- # This method outputs without escaping a string. Since escaping tags is
5
+ # This method outputs without escaping a string. Since escaping tags is
6
6
  # now default, this can be used when you don't want Rails to automatically
7
7
  # escape tags. This is not recommended if the data is coming from the user's
8
8
  # input.
@@ -1,3 +1,4 @@
1
+ require 'active_support/core_ext/object/try'
1
2
  require 'action_controller/vendor/html-scanner'
2
3
  require 'action_view/helpers/tag_helper'
3
4
 
@@ -7,7 +8,8 @@ module ActionView
7
8
  # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
8
9
  # These helper methods extend Action View making them callable within your template files.
9
10
  module SanitizeHelper
10
- # This +sanitize+ helper will html encode all tags and strip all attributes that
11
+ extend ActiveSupport::Concern
12
+ # This +sanitize+ helper will html encode all tags and strip all attributes that
11
13
  # aren't specifically allowed.
12
14
  #
13
15
  # It also strips href/src tags with invalid protocols, like javascript: especially.
@@ -19,7 +21,7 @@ module ActionView
19
21
  #
20
22
  # You can add or remove tags/attributes if you want to customize it a bit.
21
23
  # See ActionView::Base for full docs on the available options. You can add
22
- # tags/attributes for single uses of +sanitize+ by passing either the
24
+ # tags/attributes for single uses of +sanitize+ by passing either the
23
25
  # <tt>:attributes</tt> or <tt>:tags</tt> options:
24
26
  #
25
27
  # Normal Use
@@ -10,6 +10,9 @@ module ActionView
10
10
  # your views. These helper methods extend Action View making them callable
11
11
  # within your template files.
12
12
  module TextHelper
13
+ extend ActiveSupport::Concern
14
+
15
+ include SanitizeHelper
13
16
  # The preferred method of outputting text in your views is to use the
14
17
  # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods
15
18
  # do not operate as expected in an eRuby code block. If you absolutely must
@@ -459,7 +462,7 @@ module ActionView
459
462
  text.gsub(AUTO_LINK_RE) do
460
463
  scheme, href = $1, $&
461
464
  punctuation = []
462
-
465
+
463
466
  if auto_linked?($`, $')
464
467
  # do not change string; URL is already linked
465
468
  href
@@ -504,7 +507,7 @@ module ActionView
504
507
  end
505
508
  end
506
509
  end
507
-
510
+
508
511
  # Detects already linked context or position in the middle of a tag
509
512
  def auto_linked?(left, right)
510
513
  (left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
@@ -5,21 +5,21 @@ module ActionView
5
5
  module Helpers
6
6
  module TranslationHelper
7
7
  # Delegates to I18n#translate but also performs three additional functions.
8
- # First, it'll catch MissingTranslationData exceptions and turn them into
9
- # inline spans that contains the missing key, such that you can see in a
8
+ # First, it'll catch MissingTranslationData exceptions and turn them into
9
+ # inline spans that contains the missing key, such that you can see in a
10
10
  # view what is missing where.
11
11
  #
12
- # Second, it'll scope the key by the current partial if the key starts
13
- # with a period. So if you call <tt>translate(".foo")</tt> from the
14
- # <tt>people/index.html.erb</tt> template, you'll actually be calling
12
+ # Second, it'll scope the key by the current partial if the key starts
13
+ # with a period. So if you call <tt>translate(".foo")</tt> from the
14
+ # <tt>people/index.html.erb</tt> template, you'll actually be calling
15
15
  # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
16
16
  # to translate many keys within the same partials and gives you a simple framework
17
- # for scoping them consistently. If you don't prepend the key with a period,
17
+ # for scoping them consistently. If you don't prepend the key with a period,
18
18
  # nothing is converted.
19
19
  #
20
- # Third, it'll mark the translation as safe HTML if the key has the suffix
21
- # "_html" or the last element of the key is the word "html". For example,
22
- # calling translate("footer_html") or translate("footer.html") will return
20
+ # Third, it'll mark the translation as safe HTML if the key has the suffix
21
+ # "_html" or the last element of the key is the word "html". For example,
22
+ # calling translate("footer_html") or translate("footer.html") will return
23
23
  # a safe HTML string that won't be escaped by other HTML helper methods. This
24
24
  # naming convention helps to identify translations that include HTML tags so that
25
25
  # you know what kind of output to expect when you call translate in a template.