From c06eecfbc280da3295b73ef882e6a7c3b632c156 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 27 Jan 2009 15:12:21 +0000 Subject: Regenerate html --- railties/doc/guides/html/form_helpers.html | 74 ++++++++--------- railties/doc/guides/html/i18n.html | 126 ++++++++++++++++++++++++----- 2 files changed, 140 insertions(+), 60 deletions(-) diff --git a/railties/doc/guides/html/form_helpers.html b/railties/doc/guides/html/form_helpers.html index 5329d604b1..2693f29a9a 100644 --- a/railties/doc/guides/html/form_helpers.html +++ b/railties/doc/guides/html/form_helpers.html @@ -80,7 +80,7 @@
  • Common options
  • -
  • Individual Components
  • +
  • Individual components
  • @@ -670,16 +670,16 @@ Dates and times are not representable by a single input element. Instead you hav
  • -Other helpers use the _tag suffix to indicate whether a helper is a barebones helper or one that operates on model objects. With dates and times, select\_date, select\_time and select_datetime are the barebones helpers, date_select, time_select and datetime_select are the equivalent model object helpers. +Other helpers use the _tag suffix to indicate whether a helper is a barebones helper or one that operates on model objects. With dates and times, select_date, select_time and select_datetime are the barebones helpers, date_select, time_select and datetime_select are the equivalent model object helpers.

  • -

    Both of these families of helpers will create a series of select boxes for the different components (year, month, day etc...).

    +

    Both of these families of helpers will create a series of select boxes for the different components (year, month, day etc.).

    4.1. Barebones helpers

    The select_* family of helpers take as their first argument an instance of Date, Time or DateTime that is used as the currently selected value. You may omit this parameter, in which case the current date is used. For example

    -
    <%= select_date Date::today, :prefix => :start_date %>
    +
    <%= select_date Date.today, :prefix => :start_date %>

    outputs (with actual option values omitted for brevity)

    @@ -691,7 +691,7 @@ Other helpers use the _tag suffix to indicate whether a helper is a barebones he

    The above inputs would result in params[:start_date] being a hash with keys :year, :month, :day. To get an actual Time or Date object you would have to extract these values and pass them to the appropriate constructor, for example

    -
    Date::civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i)
    +
    Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i)

    The :prefix option is the key used to retrieve the hash of date components from the params hash. Here it was set to start_date, if omitted it will default to date.

    4.2. Model object helpers

    @@ -713,7 +713,7 @@ The model object helpers for dates and times submit parameters with special name
    {:person => {'birth_date(1i)' => '2008', 'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}}
    -

    When this is passed to Person.new (or update_attributes), Active Record spots that these parameters should all be used to construct the birth_date attribute and uses the suffixed information to determine in which order it should pass these parameters to functions such as Date::civil.

    +

    When this is passed to Person.new (or update_attributes), Active Record spots that these parameters should all be used to construct the birth_date attribute and uses the suffixed information to determine in which order it should pass these parameters to functions such as Date.civil.

    4.3. Common options

    Both families of helpers use the same core set of functions to generate the individual select tags and so both accept largely the same options. In particular, by default Rails will generate year options 5 years either side of the current year. If this is not an appropriate range, the :start_year and :end_year options override this. For an exhaustive list of the available options, refer to the API documentation.

    As a rule of thumb you should be using date_select when working with model objects and select_date in others cases, such as a search form which filters results by date.

    @@ -725,19 +725,19 @@ The model object helpers for dates and times submit parameters with special name In many cases the built in date pickers are clumsy as they do not aid the user in working out the relationship between the date and the day of the week. -

    4.4. Individual Components

    -

    Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component select_year, select_month, select_day, select_hour, select_minute, select_second. These helpers are fairly straightforward. By default they will generate a input named after the time component (for example "year" for select_year, "month" for select_month etc.) although this can be override with the :field_name option. The :prefix option works in the same way that it does for select_date and select_time and has the same default value.

    +

    4.4. Individual components

    +

    Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component select_year, select_month, select_day, select_hour, select_minute, select_second. These helpers are fairly straightforward. By default they will generate a input named after the time component (for example "year" for select_year, "month" for select_month etc.) although this can be overriden with the :field_name option. The :prefix option works in the same way that it does for select_date and select_time and has the same default value.

    The first parameter specifies which value should be selected and can either be an instance of a Date, Time or DateTime, in which case the relevant component will be extracted, or a numerical value. For example

    <%= select_year(2009) %>
     <%= select_year(Time.now) %>
    -

    Will produce the same output if the current year is 2009 and the value chosen by the user can be retrieved by params[:date][:year].

    +

    will produce the same output if the current year is 2009 and the value chosen by the user can be retrieved by params[:date][:year].

    5. Uploading Files

    -

    A common task is uploading some sort of file, whether it’s a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the form’s encoding MUST be set to multipart/form-data. If you forget to do this the file will not be uploaded. This can be done by passing :multi_part => true as an HTML option. This means that in the case of form_tag it must be passed in the second options hash and in the case of form_for inside the :html hash.

    +

    A common task is uploading some sort of file, whether it’s a picture of a person or a CSV file containing data to process. The most important thing to remember with file uploads is that the form’s encoding MUST be set to "multipart/form-data". If you forget to do this the file will not be uploaded. This can be done by passing :multi_part => true as an HTML option. This means that in the case of form_tag it must be passed in the second options hash and in the case of form_for inside the :html hash.

    The following two forms both upload a file.

    @@ -751,7 +751,7 @@ The model object helpers for dates and times submit parameters with special name

    Rails provides the usual pair of helpers: the barebones file_field_tag and the model oriented file_field. The only difference with other helpers is that you cannot set a default value for file inputs as this would have no meaning. As you would expect in the first case the uploaded file is in params[:picture] and in the second case in params[:person][:picture].

    5.1. What gets uploaded

    -

    The object in the params hash is an instance of a subclass of IO. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of File backed by a temporary file. In both cases the object will have an original_filename attribute containing the name the file had on the user’s computer and a content_type attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in #{RAILS_ROOT}/public/uploads under the same name as the original file (assuming the form was the one in the previous example).

    +

    The object in the params hash is an instance of a subclass of IO. Depending on the size of the uploaded file it may in fact be a StringIO or an instance of File backed by a temporary file. In both cases the object will have an original_filename attribute containing the name the file had on the user’s computer and a content_type attribute containing the MIME type of the uploaded file. The following snippet saves the uploaded content in #{Rails.root}/public/uploads under the same name as the original file (assuming the form was the one in the previous example).

    5.2. Dealing with Ajax

    -

    Unlike other forms making an asynchronous file upload form is not as simple as replacing form_for with remote_form_for. With an AJAX form the serialization is done by javascript running inside the browser and since javascript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.

    +

    Unlike other forms making an asynchronous file upload form is not as simple as replacing form_for with remote_form_for. With an Ajax form the serialization is done by JavaScript running inside the browser and since JavaScript cannot read files from your hard drive the file cannot be uploaded. The most common workaround is to use an invisible iframe that serves as the target for the form submission.

    6. Customising Form Builders

    -

    As mentioned previously the object yielded by form_for and fields_for is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example

    +

    As mentioned previously the object yielded by form_for and fields_for is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example

    -
    <% form_for @person  do |f| %>
    +
    <% form_for @person do |f| %>
       <%= text_field_with_label f, :first_name %>
     <% end %>
    @@ -798,7 +798,7 @@ by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite -->
    class LabellingFormBuilder < FormBuilder
    -  def text_field attribute, options={}
    +  def text_field(attribute, options={})
         label(attribute) + text_field(attribute, options)
       end
     end
    @@ -808,13 +808,13 @@ http://www.gnu.org/software/src-highlite -->
    <%= render :partial => f %>
    -

    If f is an instance of FormBuilder then this will render the form partial, setting the partial’s object to the form builder. If the form builder is of class LabellingFormBuilder then the labelling_form partial would be rendered instead.

    +

    If f is an instance of FormBuilder then this will render the form partial, setting the partial’s object to the form builder. If the form builder is of class LabellingFormBuilder then the labelling_form partial would be rendered instead.

    7. Understanding Parameter Naming Conventions

    -

    As you’ve seen in the previous sections, values from forms can be at the top level of the params hash or nested in another hash. For example in a standard create +

    As you’ve seen in the previous sections, values from forms can be at the top level of the params hash or nested in another hash. For example in a standard create action for a Person model, params[:model] would usually be a hash of all the attributes for the person to create. The params hash can also contain arrays, arrays of hashes and so on.

    -

    Fundamentally HTML forms don’t know about any sort of structured data, all they generate is name-value pairs. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.

    +

    Fundamentally HTML forms don’t know about any sort of structured data, all they generate is name-value pairs, where pairs are just plain strings. The arrays and hashes you see in your application are the result of some parameter naming conventions that Rails uses.

    @@ -824,8 +824,8 @@ action for a Person model, params[:model] would usually be a hash of al

    You may find you can try out examples in this section faster by using the console to directly invoke Rails' parameter parser. For example

    -
    ActionController::RequestParser.parse_query_parameters "name=fred&phone=0123456789"
    -#=> {"name"=>"fred", "phone"=>"0123456789"}
    +
    ActionController::UrlEncodedPairParser.parse_query_parameters "name=fred&phone=0123456789"
    +# => {"name"=>"fred", "phone"=>"0123456789"}
    @@ -838,11 +838,9 @@ action for a Person model, params[:model] would usually be a hash of al

    the params hash will contain

    -
    -
    {'person' => {'name' => 'Henry'}}
    +
    +
    {'person' => {'name' => 'Henry'}}
    +

    and params["name"] will retrieve the submitted value in the controller.

    Hashes can be nested as many levels as required, for example

    @@ -851,11 +849,9 @@ http://www.gnu.org/software/src-highlite -->

    will result in the params hash being

    -
    -
    {'person' => {'address' => {'city' => 'New York'}}}
    +
    +
    {'person' => {'address' => {'city' => 'New York'}}}
    +

    Normally Rails ignores duplicate parameter names. If the parameter name contains [] then they will be accumulated in an array. If you wanted people to be able to input multiple phone numbers, your could place this in the form:

    @@ -872,8 +868,8 @@ http://www.gnu.org/software/src-highlite --> <input name="addresses[][line2]" type="text"/> <input name="addresses[][city]" type="text"/>
    -

    This would result in params[:addresses] being an array of hashes with keys line1, line2 and city. Rails decides to start accumulating values in a new hash whenever it encounters a input name that already exists in the current hash.

    -

    The one restriction is that although hashes can be nested arbitrarily deep then can be only one level of "arrayness". Arrays can be usually replaced by hashes, for example instead of having an array of model objects one can have a hash of model objects keyed by their id, an array index or some other parameter.

    +

    This would result in params[:addresses] being an array of hashes with keys line1, line2 and city. Rails decides to start accumulating values in a new hash whenever it encounters an input name that already exists in the current hash.

    +

    There’s a restriction, however, while hashes can be nested arbitrarily, only one level of "arrayness" is allowed. Arrays can be usually replaced by hashes, for example instead of having an array of model objects one can have a hash of model objects keyed by their id, an array index or some other parameter.

    @@ -888,7 +884,7 @@ http://www.gnu.org/software/src-highlite -->
    <% form_for @person do |person_form| %>
    -  <%= person_form.text_field :name%>
    +  <%= person_form.text_field :name %>
       <% for address in @person.addresses %>
         <% person_form.fields_for address, :index => address do |address_form|%>
           <%= address_form.text_field :city %>
    @@ -907,12 +903,10 @@ http://www.gnu.org/software/src-highlite -->
     

    This will result in a params hash that looks like

    -
    -
    {'person' => {'name' => 'Bob', 'address' => { '23' => {'city' => 'Paris'}, '45' => {'city' => 'London'} }}}
    -

    Rails knows that all these inputs should be part of the person hash because you called fields_for on the first form builder. By specifying an :index option you’re telling rails that instead of naming the inputs person[address][city] it should insert that index surrounded by [] between the address and the city. If you pass an Active Record object as we did then Rails will call to_param on it, which by default returns the database id. This is often useful as it is then easy to locate which Address record should be modified. You can pass numbers with some other significance, strings or even nil (which will result in an array parameter being created).

    +
    +
    {'person' => {'name' => 'Bob', 'address' => {'23' => {'city' => 'Paris'}, '45' => {'city' => 'London'}}}}
    +
    +

    Rails knows that all these inputs should be part of the person hash because you called fields_for on the first form builder. By specifying an :index option you’re telling rails that instead of naming the inputs person[address][city] it should insert that index surrounded by [] between the address and the city. If you pass an Active Record object as we did then Rails will call to_param on it, which by default returns the database id. This is often useful as it is then easy to locate which Address record should be modified. You can pass numbers with some other significance, strings or even nil (which will result in an array parameter being created).

    To create more intricate nestings, you can specify the first part of the input name (person[address] in the previous example) explicitly, for example

    @@ -937,7 +931,7 @@ http://www.gnu.org/software/src-highlite -->

    8. Building Complex forms

    -

    Many apps grow beyond simple forms editing a single object. For example when creating a Person you might want to allow the user to (on the same form) create multiple address records (home, work etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary. While this guide has shown you all the pieces necessary to handle this, Rails does not yet have a standard end-to-end way of accomplishing this, but many have come up with viable approaches. These include:

    +

    Many apps grow beyond simple forms editing a single object. For example when creating a Person you might want to allow the user to (on the same form) create multiple address records (home, work, etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary. While this guide has shown you all the pieces necessary to handle this, Rails does not yet have a standard end-to-end way of accomplishing this, but many have come up with viable approaches. These include:

    • diff --git a/railties/doc/guides/html/i18n.html b/railties/doc/guides/html/i18n.html index 60253145de..b0d52c0ff5 100644 --- a/railties/doc/guides/html/i18n.html +++ b/railties/doc/guides/html/i18n.html @@ -59,13 +59,15 @@

  • - Internationalize your application + Internationalizing your application
  • @@ -128,7 +130,26 @@

    The Ruby I18n (shorthand for internationalization) gem which is shipped with Ruby on Rails (starting from Rails 2.2) provides an easy-to-use and extensible framework for translating your application to a single custom language other than English or for providing multi-language support in your application.

    -

    In the process of localizing your application you’ll probably want to do following two things:

    +

    The process of "internationalization" usually means to abstract all strings and other locale specific bits (such as date or currency formats) out of your application. The process of "localization" means to provide translations and localized formats for these bits. [1]

    +

    So, in the process of internationalizing your Rails application you have to:

    +
      +
    • +

      +Ensure you have support for i18n +

      +
    • +
    • +

      +Tell Rails where to find locale dictionaries +

      +
    • +
    • +

      +Tell Rails how to set, preserve and switch locale +

      +
    • +
    +

    In the process of localizing your application you’ll probably want to do following three things:

    • @@ -140,6 +161,11 @@ Replace or supplement Rail’s default locale — eg. date a Abstract texts in your application into keyed dictionaries — eg. flash messages, static texts in your views, etc

    • +
    • +

      +Store the resulting dictionaries somewhere +

      +

    This guide will walk you through the I18n API and contains a tutorial how to internationalize a Rails application from the start.

    @@ -237,6 +263,14 @@ http://www.gnu.org/software/src-highlite --> hello: "Hello world"

    This means, that in the :en locale, the key hello will map to Hello world string. Every string inside Rails is internationalized in this way, see for instance Active Record validation messages in the activerecord/lib/active_record/locale/en.yml file or time and date formats in the activesupport/lib/active_support/locale/en.yml file. You can use YAML or standard Ruby Hashes to store translations in the default (Simple) backend.

    The I18n library will use English as a default locale, ie. if you don’t set a different locale, :en will be used for looking up translations.

    +
    + + + +
    +Note +The i18n library takes pragmatic approach to locale keys (after some discussion), including only the locale ("language") part, like :en, :pl, not the region part, like :en-US or :en-UK, which are traditionally used for separating "languages" and "regional setting" or "dialects". (For instance, in the :en-US locale you would have $ as a currency symbol, while in :en-UK, you would have €. Also, insults would be different in American and British English :) Reason for this pragmatic approach is that most of the time, you usually care about making your application available in different "languages", and working with locales is much simpler this way. However, nothing stops you from separating regional and other settings in the traditional way. In this case, you could eg. inherit from the default en locale and then provide UK specific settings in a :en-UK dictionary.
    +

    The translations load path (I18n.load_path) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you.

    @@ -304,7 +338,7 @@ http://www.gnu.org/software/src-highlite -->
    Following examples rely on having locales loaded into your application available as an array of strings like ["en", "es", "gr"]. This is not inclued in current version of Rails 2.2 — forthcoming Rails version 2.3 will contain easy accesor available_locales. (See this commit and background at Rails I18n Wiki.)
    -

    We have to include support for getting available locales manually in an initializer like this:

    +

    So, for having available locales easily available in Rails 2.2, we have to include this support manually in an initializer, like this:

    end

    Every helper method dependent on url_for (eg. helpers for named routes like root_path or root_url, resource routes like books_path or books_url, etc.) will now automatically include the locale in the query string, like this: http://localhost:3001/?locale=ja.

    You may be satisfied with this. It does impact the readability of URLs, though, when the locale "hangs" at the end of every URL in your application. Moreover, from the architectural standpoint, locale is usually hierarchically above the other parts of application domain: and URLs should reflect this.

    -

    You probably want URLs look like this: www.example.com/en/books versus www.example.com/nl/books. This is achievable with the over-riding default_url_options strategy: you just have to set up your routes with path_prefix option in this way:

    +

    You probably want URLs look like this: www.example.com/en/books (which loads English locale) and www.example.com/nl/books (which loads Netherlands locale). This is achievable with the "over-riding default_url_options" strategy from above: you just have to set up your routes with path_prefix option in this way:

    # config/routes.rb
     map.resources :books, :path_prefix => '/:locale'
    -

    Now, when you call books_path method you should get "/en/books" (for the default locale). An URL like http://localhost:3001/nl/books should load the Netherlands locale, then, and so on.

    +

    Now, when you call books_path method you should get "/en/books" (for the default locale). An URL like http://localhost:3001/nl/books should load the Netherlands locale, then, and following calls to books_path should return "/nl/books" (because the locale changed).

    Of course, you need to take special care of root URL (usually "homepage" or "dashboard") of your application. An URL like http://localhost:3001/nl will not work automatically, because the map.root :controller => "dashboard" declaration in your routes.rb doesn’t take locale into account. (And rightly so. There’s only one "root" URL.)

    You would probably need to map URLs like these:

    @@ -452,13 +486,35 @@ map.dashboard '
  • 2.6. Setting locale from the client supplied information

    -

    # TODO: Accept-Language, GeoIP, etc. Explain why it is not such a good idea in most cases.

    -

    OK! Now you’ve initialized I18n support for your application and told it which locale should be used and how to preserve it between requests. With that in place you’re now ready for the really interesting stuff.

    +

    In specific cases, it would make sense to set locale from client supplied information, ie. not from URL. This information may come for example from users' preffered language (set in their browser), can be based on users' geographical location inferred from their IP, or users can provide it simply by choosing locale in your application interface and saving it to their profile. This approach is more suitable for web-based applications or services, not for websites — see the box about sessions, cookies and RESTful architecture above.

    +

    2.6.1. Using Accept-Language

    +

    One source of client supplied information would be an Accept-Language HTTP header. People may set this in their browser or other clients (such as curl).

    +

    A trivial implementation of using Accept-Language header would be:

    +
    +
    +
    def set_locale
    +  logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}"
    +  I18n.locale = extract_locale_from_accept_language_header
    +  logger.debug "* Locale set to '#{I18n.locale}'"
    +end
    +private
    +def extract_locale_from_accept_language_header
    +  request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
    +end
    +

    Of course, in production environment you would need much robust code, and could use a plugin such as Iaian Hecker’s http_accept_language.

    +

    2.6.2. Using GeoIP (or similar) database

    +

    Another way of choosing the locale from client’s information would be to use a database for mapping client IP to region, such as GeoIP Lite Country. The mechanics of the code would be very similar to the code above — you would need to query database for user’s IP, and lookup your preffered locale for the country/region/city returned.

    +

    2.6.3. User profile

    +

    You can also provide users of your application with means to set (and possibly over-ride) locale in your application interface, as well. Again, mechanics for this approach would be very similar to the code above — you’d probably let users choose a locale from a dropdown list and save it to their profile in database. Then you’d set the locale to this value.

    -

    3. Internationalize your application

    +

    3. Internationalizing your application

    -

    The process of "internationalization" usually means to abstract all strings and other locale specific bits out of your application. The process of "localization" means to then provide translations and localized formats for these bits. [1]

    -

    So, let’s internationalize something. You most probably have something like this in one of your applications:

    +

    OK! Now you’ve initialized I18n support for your Ruby on Rails application and told it which locale should be used and how to preserve it between requests. With that in place, you’re now ready for the really interesting stuff.

    +

    Let’s internationalize our application, ie. abstract every locale-specific parts, and that localize it, ie. provide neccessary translations for these abstracts.

    +

    You most probably have something like this in one of your applications:

    # app/views/home/index.html.erb <h1><%=t :hello_world %></h1> <p><%= flash[:notice] %></p>
    -

    When you now render this view it will show an error message that tells you that the translations for the keys :hello_world and :hello_flash are missing.

    +

    When you now render this view, it will show an error message which tells you that the translations for the keys :hello_world and :hello_flash are missing.

    rails i18n demo translation missing

    @@ -508,10 +564,10 @@ http://www.gnu.org/software/src-highlite --> Note -Rails adds a t (translate) helper method to your views so that you do not need to spell out I18n.t all the time. Additionally this helper will catch missing translations and wrap the resulting error message into a <span class="translation_missing">. +Rails adds a t (translate) helper method to your views so that you do not need to spell out I18n.t all the time. Additionally this helper will catch missing translations and wrap the resulting error message into a <span class="translation_missing">.
    -

    So let’s add the missing translations (i.e. do the "localization" part):

    +

    So let’s add the missing translations into the dictionary files (i.e. do the "localization" part):