Merged I18N branch to head.
authorTom Hughes <tom@compton.nu>
Sun, 31 May 2009 17:26:41 +0000 (17:26 +0000)
committerTom Hughes <tom@compton.nu>
Sun, 31 May 2009 17:26:41 +0000 (17:26 +0000)
204 files changed:
app/controllers/application.rb
app/controllers/browse_controller.rb
app/controllers/changeset_controller.rb
app/controllers/changeset_tag_controller.rb
app/controllers/diary_entry_controller.rb
app/controllers/export_controller.rb
app/controllers/message_controller.rb
app/controllers/site_controller.rb
app/controllers/trace_controller.rb
app/controllers/user_controller.rb
app/models/diary_entry.rb
app/models/notifier.rb
app/models/user.rb
app/views/browse/_changeset_details.rhtml
app/views/browse/_common_details.rhtml
app/views/browse/_containing_relation.rhtml
app/views/browse/_map.rhtml
app/views/browse/_node_details.rhtml
app/views/browse/_paging_nav.rhtml
app/views/browse/_relation_details.rhtml
app/views/browse/_relation_member.rhtml
app/views/browse/_start.rhtml
app/views/browse/_tag_details.rhtml
app/views/browse/_way_details.rhtml
app/views/browse/changeset.rhtml
app/views/browse/node.rhtml
app/views/browse/node_history.rhtml
app/views/browse/not_found.rhtml
app/views/browse/relation.rhtml
app/views/browse/relation_history.rhtml
app/views/browse/start.rjs
app/views/browse/way.rhtml
app/views/browse/way_history.rhtml
app/views/changeset/_changeset.rhtml
app/views/changeset/_changeset_paging_nav.rhtml
app/views/changeset/_changesets.rhtml
app/views/changeset/list.rhtml
app/views/changeset/list_bbox.rhtml
app/views/changeset/list_user.rhtml
app/views/diary_entry/_diary_comment.rhtml
app/views/diary_entry/_diary_entry.rhtml
app/views/diary_entry/edit.rhtml
app/views/diary_entry/list.rhtml
app/views/diary_entry/no_such_entry.rhtml
app/views/diary_entry/no_such_user.rhtml
app/views/export/_start.rhtml
app/views/export/start.rjs
app/views/geocoder/_results.rhtml
app/views/layouts/site.rhtml
app/views/message/_message_summary.rhtml
app/views/message/_sent_message_summary.rhtml
app/views/message/inbox.rhtml
app/views/message/new.rhtml
app/views/message/no_such_user.rhtml
app/views/message/outbox.rhtml
app/views/message/read.rhtml
app/views/notifier/diary_comment_notification.rhtml
app/views/notifier/signup_confirm.text.html.rhtml
app/views/notifier/signup_confirm.text.plain.rhtml
app/views/site/_key.rhtml
app/views/site/_search.rhtml
app/views/site/_sidebar.rhtml
app/views/site/edit.rhtml
app/views/site/index.rhtml
app/views/site/offline.rhtml
app/views/trace/_trace.rhtml
app/views/trace/_trace_form.rhtml
app/views/trace/_trace_header.rhtml
app/views/trace/_trace_optionals.rhtml
app/views/trace/_trace_paging_nav.rhtml
app/views/trace/create.rhtml
app/views/trace/edit.rhtml
app/views/trace/no_such_user.rhtml
app/views/trace/view.rhtml
app/views/user/_friend_map.rhtml
app/views/user/account.rhtml
app/views/user/confirm.rhtml
app/views/user/confirm_email.rhtml
app/views/user/login.rhtml
app/views/user/lost_password.rhtml
app/views/user/new.rhtml
app/views/user/no_such_user.rhtml
app/views/user/view.rhtml
config/initializers/action_mailer.rb
config/initializers/i18n.rb [new file with mode: 0644]
config/locales/de.yml [new file with mode: 0644]
config/locales/en.yml [new file with mode: 0644]
config/locales/es.yml [new file with mode: 0644]
config/locales/fr.yml [new file with mode: 0644]
config/routes.rb
db/migrate/035_change_user_locale.rb [new file with mode: 0644]
lib/migrate.rb
test/fixtures/countries.yml
test/fixtures/diary_entries.yml
test/functional/diary_entry_controller_test.rb
test/test_helper.rb
test/unit/country_test.rb
test/unit/diary_entry_test.rb
vendor/plugins/globalize2/.gitignore [new file with mode: 0644]
vendor/plugins/globalize2/LICENSE [new file with mode: 0644]
vendor/plugins/globalize2/README.textile [new file with mode: 0644]
vendor/plugins/globalize2/generators/db_backend.rb [new file with mode: 0644]
vendor/plugins/globalize2/generators/templates/db_backend_migration.rb [new file with mode: 0644]
vendor/plugins/globalize2/init.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/backend/chain.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/backend/static.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_raise_handler.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/load_path.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/model/active_record.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/globalize/translation.rb [new file with mode: 0644]
vendor/plugins/globalize2/lib/locale/root.yml [new file with mode: 0644]
vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb [new file with mode: 0644]
vendor/plugins/globalize2/notes.textile [new file with mode: 0644]
vendor/plugins/globalize2/test/backends/chained_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/backends/pluralizing_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/backends/static_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/data/locale/all.yml [new file with mode: 0644]
vendor/plugins/globalize2/test/data/locale/de-DE.yml [new file with mode: 0644]
vendor/plugins/globalize2/test/data/locale/en-US.yml [new file with mode: 0644]
vendor/plugins/globalize2/test/data/locale/en-US/module.yml [new file with mode: 0644]
vendor/plugins/globalize2/test/data/locale/fi-FI/module.yml [new file with mode: 0644]
vendor/plugins/globalize2/test/data/locale/root.yml [new file with mode: 0644]
vendor/plugins/globalize2/test/data/no_globalize_schema.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/data/post.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/data/schema.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/i18n/missing_translations_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/load_path_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/locale/fallbacks_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/locale/language_tag_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/model/active_record/migration_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/model/active_record/sti_translated_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/model/active_record/translated_test.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/test_helper.rb [new file with mode: 0644]
vendor/plugins/globalize2/test/translation_test.rb [new file with mode: 0644]
vendor/plugins/http_accept_language/MIT-LICENSE [new file with mode: 0644]
vendor/plugins/http_accept_language/README.rdoc [new file with mode: 0644]
vendor/plugins/http_accept_language/Rakefile [new file with mode: 0644]
vendor/plugins/http_accept_language/init.rb [new file with mode: 0644]
vendor/plugins/http_accept_language/lib/http_accept_language.rb [new file with mode: 0644]
vendor/plugins/http_accept_language/tasks/http_accept_language_tasks.rake [new file with mode: 0644]
vendor/plugins/http_accept_language/test/http_accept_language_test.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/.gitignore [new file with mode: 0644]
vendor/plugins/rails-i18n/README.textile [new file with mode: 0644]
vendor/plugins/rails-i18n/init.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ar.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/bs.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/cz.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/da.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/de.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ee.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/el.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/es-AR.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/es-MX.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/es.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/fa.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/fi.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/fr-CH.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/fr.yml [new file with mode: 0755]
vendor/plugins/rails-i18n/locale/fun/en-AU.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/fun/gibberish.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/gl-ES.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/he.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/hu.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/id.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/it.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ja.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ko.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/lt.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/mk.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/nl.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/no-NB.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/no-NN.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/pl.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/pt-BR.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/pt-PT.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ro.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/ru.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/sr-Latn.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/sr.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/sv-SE.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/sw.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/th.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/tr.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/vi.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/zh-CN.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/locale/zh-TW.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/rails/action_view.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/rails/active_record.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/rails/active_support.yml [new file with mode: 0644]
vendor/plugins/rails-i18n/script/update.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/test/lib/key_structure.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/test/structure.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/tools/Rails I18n.tmbundle/Commands/Lookup Translation.tmCommand [new file with mode: 0644]
vendor/plugins/rails-i18n/tools/Rails I18n.tmbundle/Commands/extract translation.tmCommand [new file with mode: 0644]
vendor/plugins/rails-i18n/tools/Rails I18n.tmbundle/Support/lib/dictionary.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/tools/Rails I18n.tmbundle/Support/lib/rails_i18n.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/tools/Rails I18n.tmbundle/Support/lib/yaml_waml.rb [new file with mode: 0644]
vendor/plugins/rails-i18n/tools/Rails I18n.tmbundle/info.plist [new file with mode: 0644]

index 64eb2180f6d7f0807b1a4aef5987110185a98f0d..c5624db146b4cdbfb86d03f84308c2d6f721f96e 100644 (file)
@@ -100,6 +100,19 @@ class ApplicationController < ActionController::Base
     response.headers['Error'] = message
     render :text => message, :status => status
   end
+  
+  def set_locale
+    if @user
+      if !@user.languages.empty?
+        request.user_preferred_languages = @user.languages
+      elsif !request.user_preferred_languages.empty?
+        @user.languages = request.user_preferred_languages
+        @user.save
+      end
+    end
+
+    I18n.locale = request.compatible_language_from(I18n.available_locales)
+  end
 
   def api_call_handle_error
     begin
@@ -134,7 +147,6 @@ class ApplicationController < ActionController::Base
   end
 
 private 
-
   # extract authorisation credentials from headers, returns user = nil if none
   def get_auth_data 
     if request.env.has_key? 'X-HTTP_AUTHORIZATION'          # where mod_rewrite might have put it 
index d8399c19e4af410dd3c7f135c9d133054aa12395..d3af27217544831281ea4e08aba81538e8f4395f 100644 (file)
@@ -2,6 +2,7 @@ class BrowseController < ApplicationController
   layout 'site'
 
   before_filter :authorize_web  
+  before_filter :set_locale 
   before_filter { |c| c.check_database_readable(true) }
 
   def start 
@@ -63,7 +64,7 @@ class BrowseController < ApplicationController
     @way_pages, @ways = paginate(:old_ways, :conditions => {:changeset_id => @changeset.id}, :per_page => 20, :parameter => 'way_page')
     @relation_pages, @relations = paginate(:old_relations, :conditions => {:changeset_id => @changeset.id}, :per_page => 20, :parameter => 'relation_page')
       
-    @title = "Changeset | #{@changeset.id}"
+    @title = "#{I18n.t('browse.changeset.title')} | #{@changeset.id}"
     @next = Changeset.find(:first, :order => "id ASC", :conditions => [ "id > :id", { :id => @changeset.id }] ) 
     @prev = Changeset.find(:first, :order => "id DESC", :conditions => [ "id < :id", { :id => @changeset.id }] ) 
   rescue ActiveRecord::RecordNotFound
index 778bb73aed716c071c277752b74ee256465fcd52..704a2a0f634aaa90e3aee9816461c17d07bcd366 100644 (file)
@@ -6,6 +6,7 @@ class ChangesetController < ApplicationController
 
   session :off, :except => [:list, :list_user, :list_bbox]
   before_filter :authorize_web, :only => [:list, :list_user, :list_bbox]
+  before_filter :set_locale, :only => [:list, :list_user, :list_bbox]
   before_filter :authorize, :only => [:create, :update, :delete, :upload, :include, :close]
   before_filter :require_public_data, :only => [:create, :update, :delete, :upload, :include, :close]
   before_filter :check_api_writable, :only => [:create, :update, :delete, :upload, :include]
index 3e8db3fc24539839e7f915dcf922c4caf9407b2e..374e21ca1db174dbb2556814be5bf9e8a4c5f273 100644 (file)
@@ -5,5 +5,4 @@ class ChangesetTagController < ApplicationController
     @tags = ChangesetTag.find(:all, :limit => 11, :conditions => ["match(v) against (?)", params[:query][:query].to_s] )
   end
 
-
 end
index 3ee36af21a9fb53ac5777344ada62cc4a23bce9e..d5f6f59fc3ea6d99eefadb12d7c7e5578f961dbb 100644 (file)
@@ -2,12 +2,13 @@ class DiaryEntryController < ApplicationController
   layout 'site', :except => :rss
 
   before_filter :authorize_web
+  before_filter :set_locale
   before_filter :require_user, :only => [:new, :edit]
   before_filter :check_database_readable
   before_filter :check_database_writable, :only => [:new, :edit]
 
   def new
-    @title = 'New diary entry'
+    @title = I18n.t('diary_entry.list.new')
 
     if params[:diary_entry]     
       @diary_entry = DiaryEntry.new(params[:diary_entry])
@@ -19,23 +20,21 @@ class DiaryEntryController < ApplicationController
         render :action => 'edit'
       end
     else
+      @diary_entry = DiaryEntry.new(:language_code => @user.preferred_language)
       render :action => 'edit'
     end
   end
 
   def edit
-    @title= 'Edit diary entry'
+    @title= I18n.t('diary_entry.edit.title')
     @diary_entry = DiaryEntry.find(params[:id])
 
     if @user != @diary_entry.user
       redirect_to :controller => 'diary_entry', :action => 'view', :id => params[:id]
     elsif params[:diary_entry]
-      @diary_entry.title = params[:diary_entry][:title]
-      @diary_entry.body = params[:diary_entry][:body]
-      @diary_entry.latitude = params[:diary_entry][:latitude]
-      @diary_entry.longitude = params[:diary_entry][:longitude]
-
-      if @diary_entry.save
+      params[:diary_entry][:language] = Language.find_by_code(params[:diary_entry][:language])
+      params[:diary_entry][:language] = Language.find_by_code("en") if params[:diary_entry][:language].nil?
+      if @diary_entry.update_attributes(params[:diary_entry])
         redirect_to :controller => 'diary_entry', :action => 'view', :id => params[:id]
       end
     end
@@ -71,7 +70,7 @@ class DiaryEntryController < ApplicationController
         render :action => 'no_such_user', :status => :not_found
       end
     else
-      @title = "Users' diaries"
+      @title = I18n.t('diary_entry.list.title')
       @entry_pages, @entries = paginate(:diary_entries, :include => :user,
                                         :conditions => ["users.visible = ?", true],
                                         :order => 'created_at DESC',
@@ -93,6 +92,15 @@ class DiaryEntryController < ApplicationController
       else
         render :nothing => true, :status => :not_found
       end
+    elsif params[:language]
+      @entries = DiaryEntry.find(:all, :include => :user,
+        :conditions => ["users.visible = ? AND diary_entries.language = ?", true, params[:language]],
+        :order => 'created_at DESC', :limit => 20)
+      @title = "OpenStreetMap diary entries in #{params[:language]}"
+      @description = "Recent diary entries from users of OpenStreetMap"
+      @link = "http://#{SERVER_URL}/diary/#{params[:language]}"
+      
+      render :content_type => Mime::RSS
     else
       @entries = DiaryEntry.find(:all, :include => :user,
                                  :conditions => ["users.visible = ?", true],
@@ -110,7 +118,11 @@ class DiaryEntryController < ApplicationController
 
     if user
       @entry = DiaryEntry.find(:first, :conditions => ['user_id = ? AND id = ?', user.id, params[:id]])
-      @title = "Users' diaries | #{params[:display_name]}"
+      if @entry
+        @title = "Users' diaries | #{params[:display_name]}"
+      else
+        render :action => 'no_such_entry', :status => :not_found
+      end
     else
       @not_found_user = params[:display_name]
 
index ab25fcbc67a2ed407955953287d3550c99c46812..b75fb1bca44d45ec9c00bb272f9ebd4590b49a8f 100644 (file)
@@ -1,4 +1,8 @@
 class ExportController < ApplicationController
+
+  before_filter :authorize_web
+  before_filter :set_locale
+
   def start
   end
 
index 2f71107f4b39e35720b78193d549a6f716d74e83..183f8004a19ed1831c28e52ceab1a28dd9e99333 100644 (file)
@@ -2,6 +2,7 @@ class MessageController < ApplicationController
   layout 'site'
 
   before_filter :authorize_web
+  before_filter :set_locale
   before_filter :require_user
   before_filter :check_database_readable
   before_filter :check_database_writable, :only => [:new, :reply, :mark]
index 4b22e46fd4d0ac39c7c28e5a6e38003cd79b343a..daf8fead74ae0a62c4a1207848566938b2576211 100644 (file)
@@ -1,5 +1,6 @@
 class SiteController < ApplicationController
   before_filter :authorize_web
+  before_filter :set_locale
   before_filter :require_user, :only => [:edit]
 
   def export
index 47bc62be882021bfd8f4e305306774f9e9c9761b..1787bb196a162e225631e67d0e22c1db5e648de4 100644 (file)
@@ -2,6 +2,7 @@ class TraceController < ApplicationController
   layout 'site'
 
   before_filter :authorize_web
+  before_filter :set_locale
   before_filter :require_user, :only => [:mine, :create, :edit, :delete, :make_public]
   before_filter :authorize, :only => [:api_details, :api_data, :api_create]
   before_filter :check_database_readable, :except => [:api_details, :api_data, :api_create]
index eb1471b00f005769359f03afd1eb87ab04335ffc..9c2787cc84c6002359775c9dde2c0b198d65a9e8 100644 (file)
@@ -3,6 +3,7 @@ class UserController < ApplicationController
 
   before_filter :authorize, :only => [:api_details, :api_gpx_files]
   before_filter :authorize_web, :except => [:api_details, :api_gpx_files]
+  before_filter :set_locale, :except => [:api_details, :api_gpx_files]
   before_filter :require_user, :only => [:set_home, :account, :go_public, :make_friend, :remove_friend, :upload_image, :delete_image]
   before_filter :check_database_readable, :except => [:api_details, :api_gpx_files]
   before_filter :check_database_writable, :only => [:login, :new, :set_home, :account, :go_public, :make_friend, :remove_friend, :upload_image, :delete_image]
@@ -22,9 +23,10 @@ class UserController < ApplicationController
       @user.data_public = true
       @user.description = "" if @user.description.nil?
       @user.creation_ip = request.remote_ip
+      @user.languages = request.user_preferred_languages
 
       if @user.save
-        flash[:notice] = "User was successfully created. Check your email for a confirmation note, and you\'ll be mapping in no time :-)<br /><br />Please note that you won't be able to login until you've received and confirmed your email address.<br /><br />If you use an antispam system which sends confirmation requests then please make sure you whitelist webmaster@openstreetmap.org as we are unable to reply to any confirmation requests."
+        flash[:notice] = I18n.t('user.new.flash create success message')
         Notifier.deliver_signup_confirm(@user, @user.tokens.create)
         redirect_to :action => 'login'
       else
@@ -48,15 +50,18 @@ class UserController < ApplicationController
       end
 
       @user.description = params[:user][:description]
+      @user.languages = params[:user][:languages].split(",")
       @user.home_lat = params[:user][:home_lat]
       @user.home_lon = params[:user][:home_lon]
 
       if @user.save
+        set_locale
+
         if params[:user][:email] == @user.new_email
-          @notice = "User information updated successfully. Check your email for a note to confirm your new email address."
+          flash[:notice] = I18n.t('user.account.flash update success confirm needed')
           Notifier.deliver_email_confirm(@user, @user.tokens.create)
         else
-          @notice = "User information updated successfully."
+          flash[:notice] = I18n.t('user.account.flash update success')
         end
       end
     end
@@ -67,7 +72,7 @@ class UserController < ApplicationController
       @user.home_lat = params[:user][:home_lat].to_f
       @user.home_lon = params[:user][:home_lon].to_f
       if @user.save
-        flash[:notice] = "Home location saved successfully."
+        flash[:notice] = I18n.t('user.set_home.flash success')
         redirect_to :controller => 'user', :action => 'account'
       end
     end
@@ -76,27 +81,27 @@ class UserController < ApplicationController
   def go_public
     @user.data_public = true
     @user.save
-    flash[:notice] = 'All your edits are now public.'
+    flash[:notice] = I18n.t('user.go_public.flash success')
     redirect_to :controller => 'user', :action => 'account', :display_name => @user.display_name
   end
 
   def lost_password
-    @title = 'lost password'
+    @title = I18n.t('user.lost_password.title')
     if params[:user] and params[:user][:email]
       user = User.find_by_email(params[:user][:email], :conditions => {:visible => true})
 
       if user
         token = user.tokens.create
         Notifier.deliver_lost_password(user, token)
-        @notice = "Sorry you lost it :-( but an email is on its way so you can reset it soon."
+        flash[:notice] = I18n.t('user.lost_password.notice.email on way')
       else
-        @notice = "Couldn't find that email address, sorry."
+        flash[:notice] = I18n.t('user.lost_password.notice email cannot find')
       end
     end
   end
 
   def reset_password
-    @title = 'reset password'
+    @title = I18n.t('user.reset_password.title')
     if params['token']
       token = UserToken.find_by_token(params[:token])
       if token
@@ -109,9 +114,9 @@ class UserController < ApplicationController
         user.save!
         token.destroy
         Notifier.deliver_reset_password(user, pass)
-        flash[:notice] = "Your password has been changed and is on its way to your mailbox :-)"
+        flash[:notice] = I18n.t('user.reset_password.flash changed check mail')
       else
-        flash[:notice] = "Didn't find that token, check the URL maybe?"
+        flash[:notice] = I18n.t('user.reset_password.flash token bad')
       end
     end
 
index 46d96fec7d86fbf85b85bed3b6646d5784033c9d..705438213628fe9fbb001cc608f7500968280ed4 100644 (file)
@@ -1,15 +1,18 @@
 class DiaryEntry < ActiveRecord::Base
   belongs_to :user
+  belongs_to :language, :foreign_key => 'language_code'
+  
   has_many :diary_comments, :include => :user,
                             :conditions => ["users.visible = ?", true],
                             :order => "diary_comments.id"
 
   validates_presence_of :title, :body
   validates_length_of :title, :within => 1..255
-  validates_length_of :language, :within => 2..3, :allow_nil => true
+  #validates_length_of :language, :within => 2..5, :allow_nil => false
   validates_numericality_of :latitude, :allow_nil => true,
                             :greater_than_or_equal_to => -90, :less_than_or_equal_to => 90
   validates_numericality_of :longitude, :allow_nil => true,
                             :greater_than_or_equal_to => -180, :less_than_or_equal_to => 180
   validates_associated :user
+  validates_associated :language
 end
index c2ff4c53a740edef47fb067436120eaed14bd936..b291c2b57de027d6dbc3d89b5b5f06f24df5bf3a 100644 (file)
@@ -108,6 +108,7 @@ private
 
   def common_headers(recipient)
     recipients recipient.email
+    locale recipient.preferred_language_from(I18n.available_locales)
     from "webmaster@openstreetmap.org"
     headers "return-path" => "bounces@openstreetmap.org",
             "Auto-Submitted" => "auto-generated"
index 2adbbb9a19d729acdc5053f54171a1d2d96ee6f5..683fcc96baceea7cb6453212e7c9ac912b964971 100644 (file)
@@ -78,6 +78,22 @@ class User < ActiveRecord::Base
     return el1
   end
 
+  def languages
+    attribute_present?(:languages) ? read_attribute(:languages).split(",") : []
+  end
+
+  def languages=(languages)
+    write_attribute(:languages, languages.join(","))
+  end
+
+  def preferred_language
+    languages.find { |l| Language.find(:first, :conditions => { :code => l }) }
+  end
+
+  def preferred_language_from(array)
+    (languages & array.collect { |i| i.to_s }).first
+  end
+
   def nearby(radius = 50, num = 10)
     if self.home_lon and self.home_lat 
       gc = OSM::GreatCircle.new(self.home_lat, self.home_lon)
index 6408b489b2307ac6c3b6056b4cfaabdcb6d2f0bf..92002b6e30f7274c4cdc560b72c89d8010bd57c7 100644 (file)
@@ -1,18 +1,18 @@
 <table>
 
   <tr>
-    <th>Created at:</th>
-    <td><%= h(changeset_details.created_at) %></td>
+    <th><%= t 'browse.changeset_details.created_at' %></th>
+    <td><%= l changeset_details.created_at %></td>
   </tr>
   
   <tr>
-    <th>Closed at:</th>
-    <td><%= h(changeset_details.closed_at) %></td>
+    <th><%= t 'browse.changeset_details.closed_at' %></th>
+    <td><%= l changeset_details.closed_at %></td>
   </tr>
   
   <% if changeset_details.user.data_public? %>
     <tr>
-      <th>Belongs to:</th>
+      <th><%= t 'browse.changeset_details.belongs_to' %></th>
       <td><%= link_to h(changeset_details.user.display_name), :controller => "user", :action => "view", :display_name => changeset_details.user.display_name %></td>
     </tr>
   <% end %>
@@ -20,9 +20,9 @@
   <%= render :partial => "tag_details", :object => changeset_details %>
 
   <tr>
-    <th>Bounding box:</th>
+    <th><%= t 'browse.changeset_details.bounding_box' %></th>
     <% unless changeset_details.has_valid_bbox? %>
-      <td>No bounding box has been stored for this changeset.</td>
+      <td><%= t 'browse.changeset_details.no_bounding_box' %></td>
     <% else
           minlon = changeset_details.min_lon/GeoRecord::SCALE.to_f
           minlat = changeset_details.min_lat/GeoRecord::SCALE.to_f
@@ -36,7 +36,7 @@
           </tr>
           <tr>
             <td><%=minlon -%></td>
-            <td>(<a href='/?minlon=<%= minlon %>&minlat=<%= minlat %>&maxlon=<%= maxlon %>&maxlat=<%= maxlat %>&box=yes' title='show area box'>box</a>)</td>
+            <td>(<a href='/?minlon=<%= minlon %>&minlat=<%= minlat %>&maxlon=<%= maxlon %>&maxlat=<%= maxlat %>&box=yes' title='<%= t 'browse.changeset_details.show_area_box' %>'><%= t 'browse.changeset_details.box' %></a>)</td>
             <td><%=maxlon -%></td>
           </tr>
           <tr>
@@ -49,7 +49,7 @@
 
   <% unless @nodes.empty? %>
     <tr valign="top">
-      <th>Has the following <%= @node_pages.item_count %> nodes:</th>
+      <th><%= t 'browse.changeset_details.has_nodes', :node_count => @node_pages.item_count %></th>
       <td>
         <table cellpadding="0">
           <% @nodes.each do |node| %>
@@ -63,7 +63,7 @@
   
   <% unless @ways.empty? %>
     <tr valign="top">
-      <th>Has the following <%= @way_pages.item_count %> ways:</th>
+      <th><%= t 'browse.changeset_details.has_ways', :way_count => @way_pages.item_count %></th>
       <td>
         <table cellpadding="0">
           <% @ways.each do |way| %>
@@ -80,7 +80,7 @@
   
   <% unless @relations.empty? %>
     <tr valign="top">
-      <th>Has the following <%= @relation_pages.item_count %> relations:</th>
+      <th><%= t 'browse.changeset_details.has_relations', :relation_count => @relation_pages.item_count %></th>
       <td>
         <table cellpadding="0">
           <% @relations.each do |relation| %>
index 09cf4cf2da24cf66cc5b9d48aa879f92942a02b5..179b22f60813add46ec6a752d627e7bc404b46e9 100644 (file)
@@ -1,22 +1,22 @@
 <tr>
-  <th>Edited at:</th>
-  <td><%= h(common_details.timestamp) %></td>
+  <th><%= t 'browse.common_details.edited_at' %></th>
+  <td><%= l common_details.timestamp %></td>
 </tr>
 
 <% if common_details.changeset.user.data_public? %>
   <tr>
-    <th>Edited by:</th>
+    <th><%= t 'browse.common_details.edited_by' %></th>
     <td><%= link_to h(common_details.changeset.user.display_name), :controller => "user", :action => "view", :display_name => common_details.changeset.user.display_name %></td>
   </tr>
 <% end %>
 
 <tr>
-  <th>Version:</th>
+  <th><%= t 'browse.common_details.version' %></th>
   <td><%= h(common_details.version) %></td>
 </tr>
 
 <tr>
-  <th>In changeset:</th>
+  <th><%= t 'browse.common_details.in_changeset' %></th>
   <td><%= link_to common_details.changeset_id, :action => :changeset, :id => common_details.changeset_id %></td>
 </tr>
 
index f5317f0453f97f473c85719e56c92b1ad0fcb71e..ee704acc87cd52e48db190fc7cce453e5d5e295f 100644 (file)
@@ -1,8 +1,8 @@
 <tr>
   <td>
-    <%= link_to "Relation " + h(printable_name(containing_relation.relation)), :action => "relation", :id => containing_relation.relation.id.to_s %>
+    <%= link_to t('browse.containing_relation.relation', :relation_name => h(printable_name(containing_relation.relation))), :action => "relation", :id => containing_relation.relation.id.to_s %>
     <% unless containing_relation.member_role.blank? %>
-      (as <%= h(containing_relation.member_role) %>)
+      <%= t 'browse.containing_relation.relation_as', :relation_role => h(containing_relation.member_role) %>
     <% end %>
   </td>
 </tr>
index d972104ba9d9c40cf08f5928575ca2e72766d09b..6655afcc54db39a8d5c8ec2c528be6c7f85b9498 100644 (file)
@@ -5,10 +5,10 @@
   <% if map.instance_of? Changeset or map.visible %>
     <div id="small_map" style="width:250px; height: 300px; border: solid 1px black">
     </div>
-    <span id="loading">Loading...</span>
+    <span id="loading"><%= t 'browse.map.loading' %></span>
     <a id="larger_map" href=""></a>
   <% else %>
-    Deleted
+    <%= t 'browse.map.deleted' %>
   <% end %>
 </td>
 <script type="text/javascript">
@@ -30,7 +30,7 @@
     $("loading").innerHTML = "";
 
     $("larger_map").href = '/?minlon='+minlon+'&minlat='+minlat+'&maxlon='+maxlon+'&maxlat='+maxlat+'&box=yes';
-    $("larger_map").innerHTML = "View Larger Map";
+    $("larger_map").innerHTML = "<%= t 'browse.map.view_larger_map' %>";
     <% else %>
     var obj_type = "<%= map.class.name.downcase %>";
     var obj_id = <%= map.id %>;
@@ -63,7 +63,7 @@
 
        var center = getMapCenter();
         $("larger_map").href = '/?lat='+center.lat+'&lon='+center.lon+'&zoom='+this.map.getZoom();
-        $("larger_map").innerHTML = "View Larger Map";
+        $("larger_map").innerHTML = "<%= t 'browse.map.view_larger_map' %>";
       } else {
         $("small_map").style.display = "none";
       }
index bbfe2ead760d72f0ec3e77d867d48f67a7c4e34d..7982e68052b448a2d69cccaa73f8e90d8b5c617c 100644 (file)
@@ -3,13 +3,13 @@
   <%= render :partial => "common_details", :object => node_details %>
 
   <tr>
-    <th>Coordinates:</th>
-    <td><div class="geo"><a href="/?lat=<%= h(node_details.lat) %>&lon=<%= h(node_details.lon) %>&zoom=18"><span class="latitude"><%= h(node_details.lat) %></span>, <span class="longitude"><%= h(node_details.lon) %></span></a></div></td>
+    <th><%= t 'browse.node_details.coordinates' %></th>
+    <td><div class="geo"><%= link_to ("<span class='latitude'>#{number_with_delimiter(node_details.lat)}</span>, <span class='longitude'>#{number_with_delimiter(node_details.lon)}</span>"), {:controller => 'site', :action => 'index', :lat => h(node_details.lat), :lon => h(node_details.lon), :zoom => "18"} %></div></td>
   </tr>
 
   <% unless node_details.ways.empty? and node_details.containing_relation_members.empty? %>
     <tr valign="top">
-      <th>Part of:</th>
+      <th><%= t 'browse.node_details.part_of' %></th>
       <td>
         <table cellpadding="0">
           <% node_details.ways.each do |way| %>
index fcfbb05dc048b8193bf16efb3bc448aaee7f641c..30e23b7dd5ed6c01e953d85c6739dff3518e111e 100644 (file)
@@ -1,12 +1,12 @@
 <tr><td colspan='2'>
 <% current_page = pages.current_page %>
 
-Showing page 
+<%= t'browse.paging_nav.showing_page' %> 
 <%= current_page.number %> (<%= current_page.first_item %><% 
 if (current_page.first_item < current_page.last_item) # if more than 1 trace on page 
   %>-<%= current_page.last_item %><% 
 end %>
-of <%= pages.item_count %>)
+<%= t'browse.paging_nav.of'%> <%= pages.item_count %>)
 
 <% if pages.page_count > 1 %>
 | <%= pagination_links_each(pages, {}) { |n| link_to_page(n, page_param) } %>
index e2249e92fb753ffbd053d5d97ac45e654f798f4e..bb7d45e44b3fb37b379566ddfec418bf4c88f261 100644 (file)
@@ -4,7 +4,7 @@
 
   <% unless relation_details.relation_members.empty? %>
     <tr valign="top">
-      <th>Members:</th>
+      <th><%= t'browse.relation_details.members' %></th>
       <td>
         <table cellpadding="0">
           <%= render :partial => "relation_member", :collection => relation_details.relation_members %>
@@ -15,7 +15,7 @@
 
   <% unless relation_details.containing_relation_members.empty? %>
     <tr>
-      <th>Part of:</th>
+      <th><%= t'browse.relation_details.part_of' %></th>
       <td>
         <table cellpadding="0">
           <%= render :partial => "containing_relation", :collection => relation_details.containing_relation_members %>
index ce982e2db4cf12707986c94c0b7679ac1bc9946b..39b89bc0100681be236d477ec7df387bb325e580 100644 (file)
@@ -3,7 +3,7 @@
     <%= relation_member.member_type.capitalize %>
     <%= link_to h(printable_name(relation_member.member)), :action => relation_member.member_type.downcase, :id => relation_member.member_id.to_s %>
     <% unless relation_member.member_role.blank? %>
-      as
+      <%= t'browse.relation_member.as' %>
       <%= h(relation_member.member_role) %>
     <% end %>
   </td>
index 2e120c100e7024bef6392458eb3e675e2727c4a6..9a1d50a828c1a21e757db3be2db65a044f07ba77 100644 (file)
@@ -1,9 +1,9 @@
 <div>
   <div style="text-align: center">
     <p style="margin-top: 10px; margin-bottom: 20px">
-      <a id="browse_select_view" href="#">View data for current map view</a>
+      <a id="browse_select_view" href="#"><%= t'browse.start.view_data' %></a>
       <br />
-      <a id="browse_select_box" href="#">Manually select a different area</a>  
+      <a id="browse_select_box" href="#"><%= t'browse.start.manually_select' %></a>  
     </p>
   </div>
   <div id="browse_status" style="text-align: center; display: none">
index ac407a7d73b4623b1d225620316d9884dd929c35..b5f2d97e7520d1483a651988ebe3398788a80a08 100644 (file)
@@ -1,6 +1,6 @@
 <% unless tag_details.tags.empty? %>
   <tr valign="top">
-    <th>Tags:</th>
+    <th><%= t'browse.tag_details.tags' %></th>
     <td>
       <table cellpadding="0">
         <%= render :partial => "tag", :collection => tag_details.tags.sort %>
index ef80870db76bf34de328a3d3e8dd6c73a1376dfc..4dc7b2b2ee8948a86ecd25a834411b18f2e41e6f 100644 (file)
@@ -3,7 +3,7 @@
   <%= render :partial => "common_details", :object => way_details %>
 
   <tr valign="top">
-    <th>Nodes:</th>
+    <th><%= t'browse.way_details.nodes' %></th>
     <td>
       <table cellpadding="0">
         <% way_details.way_nodes.each do |wn| %>
@@ -20,7 +20,7 @@
 
   <% unless way_details.containing_relation_members.empty? %>
     <tr valign="top">
-      <th>Part of:</th>
+      <th><%= t'browse.way_details.part_of' %></th>
       <td>
         <table cellpadding="0">
           <%= render :partial => "containing_relation", :collection => way_details.containing_relation_members %>
index 95fc1b1ac91298bb9acfc155f379099c714e8c12..e5963c57f415dbd1d9a65773420016ae3c7f257b 100644 (file)
@@ -1,7 +1,7 @@
 <table width="100%">
   <tr>
     <td>
-      <h2>Changeset: <%= h(@changeset.id) %></h2>
+      <h2><%= t 'browse.changeset.changeset' %> <%= h(@changeset.id) %></h2>
     </td>
     <td>
       <%= render :partial => "navigation" %>
     <td>
     <%= render :partial => "changeset_details", :object => @changeset %>
     <hr />
-    Download 
-    <%= link_to "Changeset XML", :controller => "changeset", :action => "read" %>
-    or
-    <%= link_to "osmChange XML", :controller => "changeset", :action => "download" %>
+    <%= t 'browse.changeset.download', :changeset_xml_link => link_to(t('browse.changeset.changesetxml'), :controller => "changeset", :action => "read"), 
+                                       :osmchange_xml_link => link_to(t('browse.changeset.osmchangexml'), :controller => "changeset", :action => "download") %>
     </td>
     <% if @changeset.has_valid_bbox? %>
     <%= render :partial => "map", :object => @changeset %>
index f798526a893fba11ca5099dad873894e3cd79d65..19aeb7dcafbe6da89dfec232f7d5219870c5e9ed 100644 (file)
@@ -1,11 +1,11 @@
 <%
 @name = printable_name @node
-@title = 'Node | ' + @name
+@title = t('browse.node.node') + ' | ' + @name
 %>
 <table width="100%">
   <tr>
     <td>
-      <h2>Node: <%= h(@name) %></h2>
+      <h2><%= t'browse.node.node_title', :node_name => h(@name) %></h2>
     </td>
     <td>
       <%= render :partial => "navigation" %>
@@ -15,9 +15,8 @@
     <td>
       <%= render :partial => "node_details", :object => @node %>
       <hr />
-      <%= link_to "Download XML", :controller => "node", :action => "read" %>
-      or
-      <%= link_to "view history", :action => "node_history" %>
+      <%= t'browse.node.download', :download_xml_link => link_to(t('browse.node.download_xml'), :controller => "node", :action => "read"),
+                                   :view_history_link => link_to(t('browse.node.view_history'), :action => "node_history") %>
     </td>
     <%= render :partial => "map", :object => @node %>
   </tr>
index 918be42dc1593230597e7479948fb912a4c81a99..4a34e345231ca2fd02ade4b55e2b95ea5cfbb075 100644 (file)
@@ -1,6 +1,6 @@
 <%
 @name = printable_name @node
-@title = 'Node History | ' + @name
+@title = t('browse.node_history.node_history') + ' | ' + @name
 %>
 <h2>Node History: <%= h(@name) %></h2>
 
@@ -11,9 +11,8 @@
         <%= render :partial => "node_details", :object => node %>
         <hr />
       <% end %>
-      <%= link_to "Download XML", :controller => "old_node", :action => "history" %>
-      or
-      <%= link_to "view details", :action => "node" %>
+      <%= t 'browse.node_history.download', :download_xml_link => link_to(t('browse.node_history.download_xml'), :controller => "old_node", :action => "history"),
+                                            :view_details_link => link_to(t('browse.node_history.view_details'), :action => "node") %>
     </td>
     <%= render :partial => "map", :object => @node %>
   </tr>
index 1322a0a6fffea6afa08799337325e04d0dcbdafd..82a81afa5dddf3c83c91dbed29ed35b4cf12b537 100644 (file)
@@ -1 +1 @@
-<p>Sorry, the <%= @type -%> with the id <%= params[:id] -%>, could not be found.</p>
+<p><%= t'browse.not_found.sorry', :type=> @type , :id => params[:id] %></p>
index 89f826c17ed53b1dddca4b98b0199a29e836404e..e180da084377d05929c08380e088c501c79e8b2e 100644 (file)
@@ -1,11 +1,11 @@
 <%
 @name = printable_name @relation
-@title = 'Relation | ' + @name
+@title = t('browse.relation.relation') + ' | ' + @name
 %>
 <table width="100%">
   <tr>
     <td>
-      <h2>Relation: <%= h(@name) %></h2>
+      <h2><%= t'browse.relation.relation_title', :relation_name => h(@name) %></h2>
     </td>
     <td>
       <%= render :partial => "navigation" %>
@@ -15,9 +15,8 @@
     <td>
       <%= render :partial => "relation_details", :object => @relation %>
       <hr />
-      <%= link_to "Download XML", :controller => "relation", :action => "read" %>
-      or
-      <%= link_to "view history", :action => "relation_history" %>
+      <%= t'browse.relation.download', :download_xml_link => link_to(t('browse.relation.download_xml'), :controller => "relation", :action => "read"),
+                                       :view_history_link => link_to(t('browse.relation.view_history'), :action => "relation_history") %>
     </td>
     <%= render :partial => "map", :object => @relation %>
   </tr>
index f6a3811ab69fe59a5f83fd7dc08723c2b57fb9ce..45f3d14004c8daa508b1fc595021943ba20167dd 100644 (file)
@@ -1,8 +1,8 @@
 <%
 @name = printable_name @relation
-@title = 'Relation History | ' + @name
+@title = t('browse.relation_history.relation_history') + ' | ' + @name
 %>
-<h2>Relation History: <%= h(@name) %></h2>
+<h2><%= t'browse.relation_history.relation_history_title', :relation_name => h(@name) %></h2>
 
 <table width="100%">
   <tr valign="top">
index 1cf423163f7e2b08ef274e7d5572226348bfe3f5..ccb39e4ff3e2793f282e825688ff49d4fc595edb 100644 (file)
@@ -1,4 +1,4 @@
-page.replace_html :sidebar_title, 'Data'
+page.replace_html :sidebar_title, t('browse.start_rjs.data_frame_title')
 page.replace_html :sidebar_content, :partial => 'start'
 page << <<EOJ
   var browseBoxControl;
@@ -41,7 +41,7 @@ page << <<EOJ
       if (map.getZoom() >= 15) {
           useMap();
       } else {
-          setStatus("Zoom in or select an area of the map to view");
+          setStatus("#{I18n.t('browse.start_rjs.zoom_or_select')}");
       }    
     }
   }
@@ -76,7 +76,7 @@ page << <<EOJ
   }
 
   function startDrag() {
-    $("browse_select_box").innerHTML='Drag a box on the map to select an area';
+    $("browse_select_box").innerHTML='#{I18n.t('browse.start_rjs.drag_a_box')}';
 
     browseBoxControl.activate();
 
@@ -121,7 +121,7 @@ page << <<EOJ
 
     browseMode = "manual";  
 
-    $("browse_select_box").innerHTML = "Manually select a different area";
+    $("browse_select_box").innerHTML = "#{I18n.t('browse.start_rjs.manually_select')}";
     $("browse_select_view").style.display = "inline";
   }
 
@@ -131,12 +131,12 @@ page << <<EOJ
     var div = document.createElement("div");
 
     var p = document.createElement("p");
-    p.appendChild(document.createTextNode("You have loaded an area which contains " + browseFeatureList.length + " features. In general, some browsers may not cope well with displaying this quantity of data. Generally, browsers work best at displaying less than 100 features at a time: doing anything else may make your browser slow/unresponsive. If you are sure you want to display this data, you may do so by clicking the button below."));
+    p.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.loaded_an_area')} " + browseFeatureList.length + " #{I18n.t('browse.start_rjs.browsers')}"));
     div.appendChild(p);
 
     var input = document.createElement("input");
     input.type = "submit";
-    input.value = "Load Data";
+    input.value = "#{I18n.t('browse.start_rjs.load_data')}";
     input.onclick = loadFeatureList;
     div.appendChild(input); 
 
@@ -187,14 +187,14 @@ page << <<EOJ
     var size = projected.getWidth() * projected.getHeight();
 
     if (size > 0.25) {
-      setStatus("Unable to load: Bounding box size of " + size + " is too large (must be smaller than 0.25)");
+      setStatus("#{I18n.t('browse.start_rjs.unable_to_load')} " + size + " #{I18n.t('must_be_smaller')}");
     } else {
       loadGML("/api/#{API_VERSION}/map?bbox=" + projected.toBBOX());
     }
   }
 
   function loadGML(url) {
-    setStatus("Loading...");
+    setStatus("#{I18n.t('browse.start_rjs.loading')}");
     $("browse_content").innerHTML = "";
 
     if (!browseDataLayer) {
@@ -381,7 +381,7 @@ page << <<EOJ
         
     var link = document.createElement("a");   
     link.href =  "/browse/" + type + "/" + feature.osm_id + "/history";
-    link.appendChild(document.createTextNode("Show history"));
+    link.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.show_history')}"));
     link.onclick = OpenLayers.Function.bind(loadHistory, {
       type: type, feature: feature, link: link
     });
@@ -394,7 +394,7 @@ page << <<EOJ
 
   function loadHistory() {
     this.link.href = "";
-    this.link.innerHTML = "Wait...";
+    this.link.innerHTML = "#{I18n.t('browse.start_rjs.wait')}";
 
     new Ajax.Request("/api/#{API_VERSION}/" + this.type + "/" + this.feature.osm_id + "/history", {
       onComplete: OpenLayers.Function.bind(displayHistory, this)
@@ -421,7 +421,7 @@ page << <<EOJ
     table.appendChild(tr);
 
     var heading = document.createElement("td");
-    heading.appendChild(document.createTextNode("History for " + featureName(this.feature)));
+    heading.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.history_for')} " + featureName(this.feature)));
     tr.appendChild(heading);
 
     var td = document.createElement("td");
@@ -430,7 +430,7 @@ page << <<EOJ
 
     var link = document.createElement("a");   
     link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history";
-    link.appendChild(document.createTextNode("Details"));
+    link.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.details')}"));
     td.appendChild(link);
 
     var div = document.createElement("div");
@@ -439,10 +439,10 @@ page << <<EOJ
     var nodes = doc.getElementsByTagName(this.type);
     var history = document.createElement("ul");  
     for (var i = nodes.length - 1; i >= 0; i--) {
-      var user = nodes[i].getAttribute("user") || "private user";
+      var user = nodes[i].getAttribute("user") || "#{I18n.t('browse.start_rjs.private_user')}";
       var timestamp = nodes[i].getAttribute("timestamp");
       var item = document.createElement("li");
-      item.appendChild(document.createTextNode("Edited by " + user + " at " + timestamp));
+      item.appendChild(document.createTextNode("#{I18n.t('browse.start_rjs.edited_by')} " + user + " #{I18n.t('browse.start_rjs.at_timestamp')} " + timestamp));
       history.appendChild(item);
     }
     div.appendChild(history);
index 9a733bf9d2058e7c29e90e3575c9f2b974c7bf02..79c913a077346f3a7d45b9b37b3c21081cab145f 100644 (file)
@@ -1,11 +1,11 @@
 <%
 @name = printable_name @way
-@title = 'Way | ' + @name
+@title = t('browse.way.way') + ' | ' + @name
 %>
 <table width="100%">
   <tr>
     <td>
-      <h2>Way: <%= h(@name) %></h2>
+      <h2><%= t'browse.way.way_title', :way_name => h(@name) %></h2>
     </td>
     <td>
       <%= render :partial => "navigation" %>
@@ -15,9 +15,8 @@
     <td>
       <%= render :partial => "way_details", :object => @way %>
       <hr />
-      <%= link_to "Download XML", :controller => "way", :action => "read" %>
-      or
-      <%= link_to "view history", :action => "way_history" %>
+      <%= t'browse.way.download', :download_xml_link => link_to(t('browse.way.download_xml'), :controller => "way", :action => "read"), 
+                                  :view_history_link => link_to(t('browse.way.view_history'), :action => "way_history") %>
     </td>
     <%= render :partial => "map", :object => @way %>
   </tr>
index c39cad54d2da878a17415a280f94365bc09db35a..edb967e9ecb00a1548a994eed9986a9a59b2c82f 100644 (file)
@@ -1,8 +1,8 @@
 <%
 @name = printable_name @way
-@title = 'Way History | ' + @name
+@title = t('browse.way_history.way_history') + ' | ' + @name
 %>
-<h2>Way History: <%= h(@name) %></h2>
+<h2><%= t'browse.way_history.way_history_title', :way_name => h(@name) %></h2>
 
 <table width="100%">
   <tr valign="top">
@@ -11,9 +11,8 @@
         <%= render :partial => "way_details", :object => way %>
         <hr />
       <% end %>
-      <%= link_to "Download XML", :controller => "old_way", :action => "history" %>
-      or
-      <%= link_to "view details", :action => "way" %>
+      <%= t'browse.way_history.download', :download_xml_link => link_to(t('browse.way_history.download_xml'), :controller => "old_way", :action => "history"), 
+                                          :view_details_link => link_to(t('browse.way_history.view_details'), :action => "way") %>
     </td>
     <%= render :partial => "map", :object => @way %>
   </tr>
index 02107771d160991106c882a9ef9b8201fca85480..75b94b4eff2f38946a56d89826960eedc8defc20 100644 (file)
@@ -6,7 +6,7 @@
   </td>
 
   <td class="<%= cl %> date">
-    <% if changeset.closed_at > DateTime.now %> (still editing)
+    <% if changeset.closed_at > DateTime.now %> <%= t'changeset.changeset.still_editing' %>
     <% else %><%= changeset.closed_at.strftime("%d %b %Y %H:%M") %><% end %>
   </td>
 
@@ -16,7 +16,7 @@
     <% if changeset.user.data_public? %>
       <%= link_to h(changeset.user.display_name), :controller => "changeset", :action => "list_user", :display_name => changeset.user.display_name %>
     <% else %>
-      <i>Anonymous</i>
+      <i><%= t'changeset.changeset.anonymous' %></i>
     <% end %>
     </td>
   <% end %>
     <% if changeset.tags['comment'] %>
       <%= h(changeset.tags['comment']) %>
     <% else %>
-      (none)
+      <%= t'changeset.changeset.no_comment' %>
     <% end %>
   </td>
 
   <td class="<%= cl %> area">
     <% if changeset.min_lat.nil? %>
-      (no edits)
+      <%= t'changeset.changeset.no_edits' %>
     <% else 
       minlon = changeset.min_lon/GeoRecord::SCALE.to_f
       minlat = changeset.min_lat/GeoRecord::SCALE.to_f
       maxlon = changeset.max_lon/GeoRecord::SCALE.to_f
       maxlat = changeset.max_lat/GeoRecord::SCALE.to_f
     %>
-      <a href='/?minlon=<%= minlon %>&minlat=<%= minlat %>&maxlon=<%= maxlon %>&maxlat=<%= maxlat %>&box=yes' title='show area box'><%= format("%0.3f",minlon) -%>,<%= format("%0.3f",minlat) -%>,<%= format("%0.3f",maxlon) -%>,<%= format("%0.3f",maxlat) -%></a>
+      <a href='/?minlon=<%= minlon %>&minlat=<%= minlat %>&maxlon=<%= maxlon %>&maxlat=<%= maxlat %>&box=yes' title='<%= t'changeset.changset.show_area_box' %>'><%= format("%0.3f",minlon) -%>,<%= format("%0.3f",minlat) -%>,<%= format("%0.3f",maxlon) -%>,<%= format("%0.3f",maxlat) -%></a>
       <!--<%=changeset.area%>-->
     <%   if changeset.area > 1500000000000 %>
-      (big)
+      <% t'changeset.changeset.big_area' %>
     <%
          end
        end
@@ -49,7 +49,7 @@
   </td>
 
   <td class="<%= cl %>">
-    <%= link_to 'more', {:controller => 'browse', :action => 'changeset', :id => changeset.id}, {:title => 'View changeset details'} %> 
+    <%= link_to t('changeset.changeset.more'), {:controller => 'browse', :action => 'changeset', :id => changeset.id}, {:title => t('changeset.changeset.view_changeset_details')} %> 
   </td>
 
 </tr>
index 7be15305df77a462b992731bd8c1c973992ff459..b8ac1a65fca39f394c5aaf7762ed9e3013535437 100644 (file)
@@ -1,11 +1,11 @@
 <% current_page = @edit_pages.current_page %>
 
-Showing page 
+<%= t'changeset.changeset_paging_nav.showing_page' %> 
 <%= current_page.number %> (<%= current_page.first_item %><% 
 if (current_page.first_item < current_page.last_item) # if more than 1 changeset on page 
   %>-<%= current_page.last_item %><% 
 end %>
-of <%= @edit_pages.item_count %>)
+<%= t'changeset.changeset_paging_nav.of'%> <%= @edit_pages.item_count %>)
 
 <%
 if @edit_pages.page_count > 1 
index 67e09045dc3beaa7c3603f37efbd15388a44b927..d9e01235c215d419375c9c36fbca051fe304950b 100644 (file)
@@ -1,14 +1,14 @@
 <% showusername = true if showusername.nil? %>
 <table id="changeset_list" cellpadding="3">
   <tr>
-    <th>ID</th>
-    <th>Saved at</th>
+    <th><%= t'changeset.changesets.id' %></th>
+    <th><%= t'changeset.changesets.saved_at' %></th>
 <% if showusername %>
-    <th>User</th>
+    <th><%= t'changeset.changesets.user' %></th>
 <% end %>
-    <th>Comment</th>
-    <th>Area</th>
+    <th><%= t'changeset.changesets.comment' %></th>
+    <th><%= t'changeset.changesets.area' %></th>
     <th></th>
   </tr>
   <%= render :partial => 'changeset', :locals => {:showusername => showusername}, :collection => @edits unless @edits.nil? %>
-</table>
\ No newline at end of file
+</table>
index b78469ddfc8b2ab7cf4080fbd5765949071c1c94..cfe4afd3faa5d0d9de765505f5a797220a3202ec 100644 (file)
@@ -1,9 +1,7 @@
-<h1>Recent Changes</h1>
-<p>Recently edited changesets:</p>
+<h1><%= t'changeset.list.recent_changes' %></h1>
+<p><%= t'changeset.list.recently_edited_changesets' %></p>
 
 <%= render :partial => 'changesets' %>
 
-<p>
-For more changesets, select a user and view their edits, or see the editing 'history' of a specific area.
-</p>
+<p><%= t'changeset.list.for_more_changesets' %></p>
 <br>
index 34644e960b471ae55075c48578bd5d3acf5ff360..3905c4441e52232ba14b0bb17d87b0d35c496b70 100644 (file)
@@ -1,4 +1,4 @@
-<h1>History</h1>
+<h1><%= t'changeset.list_bbox.history' %></h1>
 <%
 if @bbox!=nil
        minlon = @bbox[0] 
@@ -8,20 +8,20 @@ if @bbox!=nil
 
        %>
 <p>
-Changesets within the area: 
-      (<a href='/?minlon=<%= minlon %>&minlat=<%= minlat %>&maxlon=<%= maxlon %>&maxlat=<%= maxlat %>&box=yes' title='show area box'><%= format("%0.3f",minlon) -%>,<%= format("%0.3f",minlat) -%>,<%= format("%0.3f",maxlon) -%>,<%= format("%0.3f",maxlat) -%></a>) 
+<%= t'changeset.list_bbox.changesets_within_the_area' %> 
+      (<a href='/?minlon=<%= minlon %>&minlat=<%= minlat %>&maxlon=<%= maxlon %>&maxlat=<%= maxlat %>&box=yes' title='<%= t'changeset.list_bbox.show_area_box' %>'><%= format("%0.3f",minlon) -%>,<%= format("%0.3f",minlat) -%>,<%= format("%0.3f",maxlon) -%>,<%= format("%0.3f",maxlat) -%></a>) 
 
 </p>
 
 <%     if @edits.nil? or @edits.empty? %>
-<p><b>No changesets</b></p>
+<p><b><%= t'changeset.list_bbox.no_changesets' %></b></p>
 <%     else %>
 
 <%= render :partial => 'changeset_paging_nav' %>
 <%= render :partial => 'changesets' %>
 <%= render :partial => 'changeset_paging_nav' %>
 
-<p>For all changes everywhere see <%=  link_to("Recent Changes", :controller => "browse", :action => "changesets") %> </p>
+<p><%= t'changeset.list_bbox.all_changes_everywhere' , :recent_changes_link => link_to(t('changest.list_bbox.recent_changes'), :controller => "browse", :action => "changesets") %> </p>
 
 <%
        end
@@ -30,9 +30,9 @@ else
        #bbox is nil. happens if the user surfs to this page directly.
 %>
 
-<p>No area specified</p>
-<p>First use the <a href="/" title="view the map">view tab</a> to pan and zoom to an area of interest, then click the history tab.</p>
-<p>Alternatively view all <%=  link_to("recent changes", :controller => "browse", :action => "changesets") %> </p>
+<p><%= t'changeset.list_bbox.no_area_specified' %></p>
+<p><%= t'changeset.list_bbox.first_use_view', :view_tab_link => '<a href="/" title="' + t('changeset.list_bbox.view_the_map') + '">' + t('changeset.list_bbox.view_tab') + '</a>' %></p>
+<p><%= t'changeset.list_bbox.alternatively_view', :recent_changes_link => link_to(t('changeset.list_bbox.recent_changes'), :controller => "browse", :action => "changesets") %></p>
 
 <%
 end
index cf99d7a48fafaa46d7648c4508b3100447166240..7240e60276412a27d073a822c12ce2876be99f0a 100644 (file)
@@ -1,13 +1,13 @@
-<h1>Edits by <%= link_to(h(@display_name), {:controller=>'user', :action=>'view', :display_name=>@display_name}) %></h1>
+<h1><%= t'changeset.list_user.edits_by_username', :username_link => link_to(h(@display_name), {:controller=>'user', :action=>'view', :display_name=>@display_name}) %></h1>
 
 <% if not @edits or @edits.empty? %>
-<p><b>No visible edits by <%= h(@display_name) %>.</b></p>
+<p><b><%= t'changeset.list_user.no_visible_edits_by', :name => h(@display_name) %>.</b></p>
 <% else %>
 <%= render :partial => 'changeset_paging_nav' %>
 <%= render :partial => 'changesets', :locals => {:showusername => false} %>
 <%= render :partial => 'changeset_paging_nav' %>
 <% end %>
 
-<p>For changes by all users see <%=  link_to("Recent Changes", :controller => "browse", :action => "changesets") %> </p>
+<p><%= t'changeset.list_user.for_all_changes', :recent_changes_link => link_to(t('changeset.list_user.recent_changes'), :controller => "browse", :action => "changesets") %></p>
 <br>
 
index 2aca51f545c89d2f4adc1b4aedf5d9e32e4fd6b7..45cce0b25326f32dd7a6fb1877ac6c5ea344d964 100644 (file)
@@ -1,3 +1,3 @@
-<h4 id="comment<%= diary_comment.id %>">Comment from <%= link_to h(diary_comment.user.display_name), :controller => 'user', :action => 'view', :display_name => diary_comment.user.display_name %>  at <%= diary_comment.created_at %></h4>
+<h4 id="comment<%= diary_comment.id %>"><%= t('diary_entry.comment_from', :link_user => (link_to h(diary_comment.user.display_name), :controller => 'user', :action => 'view', :display_name => diary_comment.user.display_name), :comment_created_at => l(diary_comment.created_at)) %></h4>
 <%= htmlize(diary_comment.body) %>
 <hr />
index fe73155aca85241d4f31a475fdf7849127321ffb..a83f7ba25395c20d63ab4ef03b6734e4068a9ada 100644 (file)
@@ -1,19 +1,19 @@
 <b><%= link_to h(diary_entry.title), :action => 'view', :display_name => diary_entry.user.display_name, :id => diary_entry.id %></b><br />
 <%= htmlize(diary_entry.body) %>
 <% if diary_entry.latitude and diary_entry.longitude %>
-Coordinates: <div class="geo" style="display: inline"><span class="latitude"><%= diary_entry.latitude %></span>; <span class="longitude"><%= diary_entry.longitude %></span></div> (<%=link_to 'map', :controller => 'site', :action => 'index', :lat => diary_entry.latitude, :lon => diary_entry.longitude, :zoom => 14 %> / <%=link_to 'edit', :controller => 'site', :action => 'edit', :lat => diary_entry.latitude, :lon => diary_entry.longitude, :zoom => 14 %>)<br/>
+<%= t 'map.coordinates' %> <div class="geo" style="display: inline"><span class="latitude"><%= diary_entry.latitude %></span>; <span class="longitude"><%= diary_entry.longitude %></span></div> (<%=link_to (t 'map.view'), :controller => 'site', :action => 'index', :lat => diary_entry.latitude, :lon => diary_entry.longitude, :zoom => 14 %> / <%=link_to (t 'map.edit'), :controller => 'site', :action => 'edit', :lat => diary_entry.latitude, :lon => diary_entry.longitude, :zoom => 14 %>)<br/>
 <% end %>
-Posted by <b><%= link_to h(diary_entry.user.display_name), :controller => 'user', :action => 'view', :display_name => diary_entry.user.display_name %></b> at <%= diary_entry.created_at %>
+<%= t 'diary_entry.posted_by', :link_user => (link_to h(diary_entry.user.display_name), :controller => 'user', :action => 'view', :display_name => diary_entry.user.display_name), :created => l(diary_entry.created_at), :language => diary_entry.language.name %>
 <% if params[:action] == 'list' %>
 <br />
-<%= link_to 'Comment on this entry', :action => 'view', :display_name => diary_entry.user.display_name, :id => diary_entry.id, :anchor => 'newcomment' %>
+<%= link_to t('diary_entry.comment_link'), :action => 'view', :display_name => diary_entry.user.display_name, :id => diary_entry.id, :anchor => 'newcomment' %>
 |
-<%= link_to 'Reply to this entry', :controller => 'message', :action => 'new', :user_id => diary_entry.user.id, :title => "Re: #{diary_entry.title}" %>
+<%= link_to t('diary_entry.reply_link'), :controller => 'message', :action => 'new', :user_id => diary_entry.user.id, :title => "Re: #{diary_entry.title}" %>
 |
-<%= link_to pluralize(diary_entry.diary_comments.count, "comment"), :action => 'view', :display_name => diary_entry.user.display_name, :id => diary_entry.id, :anchor => 'comments' %>
+<%= link_to t('diary_entry.comment_count', :count => diary_entry.diary_comments.count), :action => 'view', :display_name => diary_entry.user.display_name, :id => diary_entry.id, :anchor => 'comments' %>
 <% end %>
 <% if @user == diary_entry.user %> 
-| <%= link_to 'Edit this entry', :action => 'edit', :display_name => @user.display_name, :id => diary_entry.id %>
+| <%= link_to t('diary_entry.edit_link'), :action => 'edit', :display_name => @user.display_name, :id => diary_entry.id %>
 <% end %>
 <br />
 <hr />
index a69f4fd9c9240bc7a666099ac806678ade8032e9..553367756b3611ca4aea0928c4407c3eb00ce72e 100644 (file)
@@ -5,26 +5,30 @@
 <% form_for :diary_entry do |f| %>
   <table>
     <tr valign="top">
-      <td class="fieldName">Subject:</td>
+      <td class="fieldName"><%= t 'diary_entry.edit.subject' -%></td>
       <td><%= f.text_field :title, :size => 60 %></td>
     </tr>
     <tr valign="top">
-      <td class="fieldName">Body:</td>
+      <td class="fieldName"><%= t 'diary_entry.edit.body' -%></td>
       <td><%= f.text_area :body, :cols => 80 %></td>
     </tr>
     <tr valign="top">
-      <td class="fieldName">Location:</td>
+      <td class="fieldName"><%= t 'diary_entry.edit.language' -%></td>
+      <td><%= f.collection_select :language_code, Language.find(:all, :order => :english_name), :code, :name %></td>
+    </tr>
+    <tr valign="top">
+      <td class="fieldName"><%= t 'diary_entry.edit.location' -%></td>
       <td>
         <div id="map" style="border: 1px solid black; position: relative; width : 90%; height : 400px; display: none;"></div>
-        <span class="location">Latitude: <%= f.text_field :latitude, :size => 20, :id => "latitude" %> Longitude: <%= f.text_field :longitude, :size => 20, :id => "longitude" %></span>
-        <a href="javascript:openMap()" id="usemap">use map</a>
+        <span class="location"><%= t 'diary_entry.edit.latitude' -%> <%= f.text_field :latitude, :size => 20, :id => "latitude" %> <%= t 'diary_entry.edit.longitude' -%> <%= f.text_field :longitude, :size => 20, :id => "longitude" %></span>
+        <a href="javascript:openMap()" id="usemap"><%= t 'diary_entry.edit.use_map_link' -%></a>
         <br/><br/>
       </td>
     </tr>
     <tr>
       <td></td>
       <td>
-         <%= submit_tag 'Save' %>
+         <%= submit_tag t('diary_entry.edit.save_button') %>
          <%# TODO: button should say 'publish' or 'save changes' depending on new/edit state %>
       </td>
     </tr>
@@ -72,7 +76,7 @@
       removeMarkerFromMap(marker);
     }
 
-    marker = addMarkerToMap(lonlat, null, "Diary entry location");
+    marker = addMarkerToMap(lonlat, null, "<%= t 'diary_entry.edit.marker_text' -%>");
   }
 
   function openMap() {
index 38157b183b976883282d86ba2bdcca717ccf0857..00937d89e0001d9c765596ceb2cc0575dec7b5a2 100644 (file)
@@ -7,27 +7,27 @@
 
 <% if @this_user %>
   <% if @user == @this_user %>
-    <%= link_to image_tag("new.png", :border=>0) + 'New diary entry', {:controller => 'diary_entry', :action => 'new', :display_name => @user.display_name}, {:title => 'Compose a new entry in your user diary'} %>
+    <%= link_to image_tag("new.png", :border=>0) + t('diary_entry.list.new'), {:controller => 'diary_entry', :action => 'new', :display_name => @user.display_name}, {:title => t('diary_entry.list.new_title')} %>
   <% end %>
 <% else %>
   <% if @user %>
-    <%= link_to image_tag("new.png", :border=>0) + 'New diary entry', {:controller => 'diary_entry', :action => 'new', :display_name => @user.display_name}, {:title => 'Compose a new entry in your user diary'} %>
+    <%= link_to image_tag("new.png", :border=>0) + t('diary_entry.list.new'), {:controller => 'diary_entry', :action => 'new', :display_name => @user.display_name}, {:title => t('diary_entry.list.new_title')} %>
   <% end %>
 <% end %>
 
 
 <% if @entries.empty? %>
-  <p>No diary entries</p>
+  <p><%= t 'diary_entry.list.no_entries' %></p>
 <% else %>
-  <p>Recent diary entries:</p>
+  <p><%= t 'diary_entry.list.recent_entries' %></p>
 
   <hr />
 
   <%= render :partial => 'diary_entry', :collection => @entries %>
        
-  <%= link_to "Older Entries", { :page => @entry_pages.current.next } if @entry_pages.current.next %>
+  <%= link_to t('diary_entry.list.older_entries'), { :page => @entry_pages.current.next } if @entry_pages.current.next %>
   <% if @entry_pages.current.next and @entry_pages.current.previous %>|<% end %>
-  <%= link_to "Newer Entries", { :page => @entry_pages.current.previous } if @entry_pages.current.previous %>
+  <%= link_to t('diary_entry.list.newer_entries'), { :page => @entry_pages.current.previous } if @entry_pages.current.previous %>
 
   <br />
 <% end %>
index 1ebcf269c832febcf56afa5773b196d53a6fc959..eef0e47d2d73b284b5343cd107ea7ca0f364035a 100644 (file)
@@ -1,2 +1,2 @@
-<h2>No entry with the id: <%= h(params[:id]) %></h2>
-<p>Sorry, there is no diary entry or comment with the id <%=h params[:id] -%>, or no id was given. Please check your spelling, or maybe the link you clicked is wrong.</p>
+<h2><%= t 'diary_entry.no_such_entry.heading', :id => h(params[:id]) %></h2>
+<p><%= t 'diary_entry.no_such_entry.body', :id => h(params[:id]) %></p>
index 7820b4847c6d260a232005a0eda5bcda52a2a930..02f6a4df205dd79771a8adc9559f169929acbe0f 100644 (file)
@@ -1,2 +1,2 @@
 <h2><%= h(@not_found_user) %></h2>
-<p>Sorry, there is no user with the name <%= @not_found_user -%>. Please check your spelling, or maybe the link you clicked is wrong.</p>
+<p><%= t 'diary_entry.no_such_user.body', :user => @not_found_user %></p>
index 9776261ea3e9d356aa52321f4e2feeca940241ae..9e3d6478363a1246d0095180d90b75353eb0243f 100644 (file)
@@ -1,6 +1,6 @@
 <% form_tag :action => "finish" do %>
 
-  <p class="export_heading">Area to Export</p>
+  <p class="export_heading"><%= t'export.start.area_to_export' %></p>
 
   <div class="export_bounds">
     <%= text_field_tag('maxlat', nil, :size => 10, :class => "export_bound") %>
     <br/>
     <%= text_field_tag('minlat', nil, :size => 10, :class => "export_bound") %>
     <p class="export_hint">
-      <a id='drag_box' href="#" onclick="return startBox();">Manually select a different area</a>  
+      <a id='drag_box' href="#" onclick="return startBox();"><%= t'export.start.manually_select' %></a>  
     </p>
   </div>
 
-  <p class="export_heading">Format to Export</p>
+  <p class="export_heading"><%= t'export.start.format_to_export' %></p>
 
   <div class="export_details">
     <p>
-      <%= radio_button_tag("format", "osm") %> OpenStreetMap XML Data
+      <%= radio_button_tag("format", "osm") %> <%= t'export.start.osm_xml_data' %>
       <br/>
-      <%= radio_button_tag("format", "mapnik") %> Mapnik Image
+      <%= radio_button_tag("format", "mapnik") %> <%= t'export.start.mapnik_image' %>
       <br/>
-      <%= radio_button_tag("format", "osmarender") %> Osmarender Image
+      <%= radio_button_tag("format", "osmarender") %> <%= t'export.start.osmarender_image' %>
       <br/>
-      <%= radio_button_tag("format", "html") %> Embeddable HTML
+      <%= radio_button_tag("format", "html") %> <%= t'export.start.embeddable_html' %>
     </p>
   </div>
 
   <div id="export_osm">
-    <p class="export_heading">Licence</p>
+    <p class="export_heading"><%= t'export.start.licence' %></p>
 
     <div class="export_details">
-      <p>OpenStreetMap data is licensed under the <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons Attribution-ShareAlike 2.0 license</a>.</p>
+      <p><%= t'export.start.export_details' %></p>
     </div>
   </div>
 
   <div id="export_mapnik">
-    <p class="export_heading">Options</p>
+    <p class="export_heading"><%= t'export.start.options' %></p>
 
     <div class="export_details">
-      <p>Format <%= select_tag("mapnik_format", options_for_select([["PNG", "png"], ["JPEG", "jpeg"], ["SVG", "svg"], ["PDF", "pdf"], ["Postscript", "ps"]], "png")) %></p>
-      <p>Scale 1 : <%= text_field_tag("mapnik_scale", nil, :size => 8) %> <span class="export_hint">(max 1 : <span id="mapnik_max_scale"></span>)</span></p>
-      <p>Image Size <span id="mapnik_image_width"></span> x <span id="mapnik_image_height"></span></p>
+      <p><%= t'export.start.format' %> <%= select_tag("mapnik_format", options_for_select([["PNG", "png"], ["JPEG", "jpeg"], ["SVG", "svg"], ["PDF", "pdf"], ["Postscript", "ps"]], "png")) %></p>
+      <p><%= t'export.start.scale' %> 1 : <%= text_field_tag("mapnik_scale", nil, :size => 8) %> <span class="export_hint">(<%= t'export.start.max' %> 1 : <span id="mapnik_max_scale"></span>)</span></p>
+      <p><%= t'export.start.image_size' %> <span id="mapnik_image_width"></span> x <span id="mapnik_image_height"></span></p>
     </div>
   </div>
 
   <div id="export_osmarender">
-    <p class="export_heading">Options</p>
+    <p class="export_heading"><%= t'export.start.options' %></p>
 
     <div class="export_details">
-      <p>Format <%= select_tag("osmarender_format", options_for_select([["PNG", "png"], ["JPEG", "jpeg"]], "png")) %></p>
-      <p>Zoom <%= select_tag("osmarender_zoom", options_for_select([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])) %></p>
+      <p><%= t'export.start.format' %> <%= select_tag("osmarender_format", options_for_select([["PNG", "png"], ["JPEG", "jpeg"]], "png")) %></p>
+      <p><%= t'export.start.zoom' %> <%= select_tag("osmarender_zoom", options_for_select([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])) %></p>
     </div>
   </div>
   
   <div id="export_html">
-    <p class="export_heading">Options</p>
+    <p class="export_heading"><%= t'export.start.options' %></p>
     <div class="export_details">
-      <p><a id="add_marker" href="#">Add a marker to the map</a></p>
+      <p><a id="add_marker" href="#"><%= t'export.start.add_marker' %></a></p>
       <p id="marker_inputs" style="display:none">
-        Lat: <input type="text" id="marker_lat" size="9" />
-        Lon: <input type="text" id="marker_lon" size="9" />
+        <%= t'export.start.latitude' %> <input type="text" id="marker_lat" size="9" />
+        <%= t'export.start.longitude' %> <input type="text" id="marker_lon" size="9" />
       </p>
     </div>
 
-    <p class="export_heading">Output</p>
+    <p class="export_heading"><%= t'export.start.output' %></p>
     <div class="export_details">
       <p><input type="text" id="export_html_text" style="width:95%" /></p>
-      <p>Paste HTML to embed in website</p>
+      <p><%= t'export.start.paste_html' %></p>
     </div>
   </div>
 
   <div class="export_buttons">
-    <p><%= submit_tag "Export", :id => "export_commit" %></p>
+    <p><%= submit_tag t('export.start.export_button'), :id => "export_commit" %></p>
   </div>
 
 <% end %>
index 83db38002444d179027a582a7012f0dc12fc8176..dd879132a4b26f65370622a0c545a7d26d1ec978 100644 (file)
@@ -1,4 +1,4 @@
-page.replace_html :sidebar_title, 'Export'
+page.replace_html :sidebar_title, t('export.start_rjs.export')
 page.replace_html :sidebar_content, :partial => 'start'
 page << <<EOJ
   var vectors;
@@ -77,7 +77,7 @@ page << <<EOJ
   $("minlat").onchange = boundsChanged;
 
   function startDrag() {
-    $("drag_box").innerHTML='Drag a box on the map to select an area';
+    $("drag_box").innerHTML='#{I18n.t('export.start_rjs.drag_a_box')}';
 
     clearBox();
     box.activate();
@@ -94,11 +94,11 @@ page << <<EOJ
     box.deactivate();
     validateControls();
 
-    $("drag_box").innerHTML = "Manually select a different area";
+    $("drag_box").innerHTML = "#{I18n.t('export.start_rjs.manually_select')}";
   }
 
   function startMarker() {
-    $("add_marker").innerHTML='Click on the map to add a marker';
+    $("add_marker").innerHTML='#{I18n.t('export.start_rjs.click_add_marker')}';
 
     if (!markerLayer) {
       markerLayer = new OpenLayers.Layer.Vector("",{
@@ -130,7 +130,7 @@ page << <<EOJ
   function endMarker(event) {
     markerControl.deactivate();
 
-    $("add_marker").innerHTML = "Change marker position";
+    $("add_marker").innerHTML = "#{I18n.t('export.start_rjs.change_marker')}";
     $("marker_inputs").style.display = "block";
     
     var epsg4326 = new OpenLayers.Projection("EPSG:4326");
@@ -147,7 +147,7 @@ page << <<EOJ
     $("marker_lon").value = "";
     $("marker_lat").value = "";
     $("marker_inputs").style.display = "none";
-    $("add_marker").innerHTML = "Add a marker to the map";
+    $("add_marker").innerHTML = "#{I18n.t('export.start_rjs.add_marker')}";
 
     if (markerLayer) { 
       markerControl.destroy();
@@ -248,7 +248,7 @@ page << <<EOJ
     
     var layers = getMapLayers();
 
-    html += '<br /><small><a href="http://#{SERVER_URL}/?lat='+center.lat+'&lon='+center.lon+'&zoom='+zoom+'&layers='+layers+markerUrl+'">View Larger Map</a></small>';
+    html += '<br /><small><a href="http://#{SERVER_URL}/?lat='+center.lat+'&lon='+center.lon+'&zoom='+zoom+'&layers='+layers+markerUrl+'">#{I18n.t('export.start_rjs.view_larger_map')}</a></small>';
 
     $("export_html_text").value = html;
 
index 9bcc5d8ae67f6f93976f3b1366f3a09ae63dc275..bf42244f99ec8e3e7b357b1933fc64d23f0b8528 100644 (file)
@@ -1,9 +1,9 @@
 <% results.each do |source| %>
-<% type = source[:type] || "Results" %>
-<p class="search_results_heading"><%= type %> from <%= link_to source[:source], source[:url] %></p>
+<% type = source[:type] || t('geocoder.results.results') %>
+<p class="search_results_heading"><%= t'geocoder.results.type_from_source', :type => type, :source_link => link_to(source[:source], source[:url]) %></p>
 <% if source[:results] %>
 <% if source[:results].empty? %>
-<p class="search_results_entry">No results found</p>
+<p class="search_results_entry"><%= t'geocoder.results.no_results' %></p>
 <% else %>
 <% source[:results].each do |result| %>
 <p class="search_results_entry"><%= result_to_html(result) %></p>
index 75e4eb46c41e20af83f87f8428047211558e107b..0da605ee207709c77c2a6e5c249c9d48b828903a 100644 (file)
 
     <span id="greeting">
       <% if @user and @user.id %>
-        Welcome, <%= link_to h(@user.display_name), {:controller => 'user', :action => 'view', :display_name => @user.display_name}%> | 
+        <%= t 'layouts.welcome_user', :user_link => (link_to h(@user.display_name), {:controller => 'user', :action => 'view', :display_name => @user.display_name}) %> | 
         <% @inbox_weight = 'bold' if @user.new_messages.size > 0 %>
         <%= yield :greeting %>
-        <%= link_to "inbox (#{@user.new_messages.size})", {:controller => 'message', :action => 'inbox', :display_name => @user.display_name}, {:style => "font-weight: #{@inbox_weight};" } %> |
-        <%= link_to 'logout', {:controller => 'user', :action => 'logout', :referer => request.request_uri}, {:id => 'logoutanchor'}%>
-      <% else %>
-        <%= link_to 'log in', {:controller => 'user', :action => 'login', :referer => request.request_uri}, {:id => 'loginanchor'}%> |
-        <%= link_to 'sign up', {:controller => 'user', :action => 'new'}, {:id => 'registeranchor'} %>
+        <%= link_to t('layouts.inbox', :size => @user.new_messages.size), {:controller => 'message', :action => 'inbox', :display_name => @user.display_name}, {:style => "font-weight: #{@inbox_weight};" } %> |
+        <%= link_to t('layouts.logout'), {:controller => 'user', :action => 'logout', :referer => request.request_uri}, {:id => 'logoutanchor'}%>
+      <% else %>               
+        <%= link_to t('layouts.log_in'), {:controller => 'user', :action => 'login', :referer => request.request_uri}, {:id => 'loginanchor'}%> |
+        <%= link_to t('layouts.sign_up'), {:controller => 'user', :action => 'new'}, {:id => 'registeranchor'} %>
       <% end %>
     </span>
 
         traceclass = 'active' if params['controller'] == 'trace'
         diaryclass = 'active' if params['controller'] == 'diary_entry'
         %>
-        <li><%= link_to 'View', {:controller => 'site', :action => 'index'}, {:id => 'viewanchor', :title => 'view maps', :class => viewclass} %></li>
-        <li><%= link_to 'Edit', {:controller => 'site', :action => 'edit'}, {:id => 'editanchor', :title => 'edit maps', :class => editclass} %></li>
-        <li><%= link_to 'History', {:controller => 'changeset', :action => 'list_bbox' }, {:id => 'historyanchor', :title => 'changeset history', :class => historyclass} %></li>
+        <li><%= link_to t('layouts.view'), {:controller => 'site', :action => 'index'}, {:id => 'viewanchor', :title => 'view maps', :class => viewclass} %></li>
+        <li><%= link_to t('layouts.edit'), {:controller => 'site', :action => 'edit'}, {:id => 'editanchor', :title => 'edit maps', :class => editclass} %></li>
+        <li><%= link_to t('layouts.history'), {:controller => 'changeset', :action => 'list_bbox' }, {:id => 'historyanchor', :title => 'changeset history', :class => historyclass} %></li>
         <% if params['controller'] == 'site' and (params['action'] == 'index' or params['action'] == 'export') %>
-        <li><%= link_to_remote 'Export', {:url => {:controller => 'export', :action => 'start'}}, {:id => 'exportanchor', :title => 'export map data', :class => exportclass, :href => url_for(:controller => 'site', :action => 'export')} %></li>
+        <li><%= link_to_remote t('layouts.export'), {:url => {:controller => 'export', :action => 'start'}}, {:id => 'exportanchor', :title => 'export map data', :class => exportclass, :href => url_for(:controller => 'site', :action => 'export')} %></li>
         <% else %>
-        <li><%= link_to 'Export', {:controller => 'site', :action => 'export'}, {:id => 'exportanchor', :title => 'export map data', :class => exportclass} %></li>
+        <li><%= link_to t('layouts.export'), {:controller => 'site', :action => 'export'}, {:id => 'exportanchor', :title => 'export map data', :class => exportclass} %></li>
         <% end %>
-        <li><%= link_to 'GPS Traces', {:controller => 'trace', :action => 'list'}, {:id => 'traceanchor', :title => 'manage traces', :class => traceclass} %></li>
-        <li><%= link_to 'User Diaries', {:controller => 'diary_entry', :action => 'list', :display_name => nil}, {:id => 'diaryanchor', :title => 'view user diaries', :class => diaryclass} %></li>
+        <li><%= link_to t('layouts.gps_traces'), {:controller => 'trace', :action => 'list'}, {:id => 'traceanchor', :title => 'manage traces', :class => traceclass} %></li>
+        <li><%= link_to t('layouts.user_diaries'), {:controller => 'diary_entry', :action => 'list', :display_name => nil}, {:id => 'diaryanchor', :title => 'view user diaries', :class => diaryclass} %></li>
       </ul>
     </div>
 
         <center>
           <h1>OpenStreetMap</h1>
           <%= link_to(image_tag("osm_logo.png", :size => "120x120", :border => 0), :controller => 'site', :action => 'index') %><br/>
-          <h2 class="nowrap">The Free Wiki World Map</h2>
+          <h2 class="nowrap"><%= t('layouts.tag_line') %></h2>
         </center>
       </div>
 
       <% unless @user %>
       <div id="intro">
         <p>
-          OpenStreetMap is a free editable map of the whole world. It
-          is made by people like you.
+          <%= t 'layouts.intro_1' %>
         </p>
         <p>
-          OpenStreetMap allows you to view, edit and use geographical
-          data in a collaborative way from anywhere on Earth.
+          <%= t 'layouts.intro_2' %>.
         </p>
         <p>
-          OpenStreetMap's hosting is kindly supported by the
-          <a href="http://www.vr.ucl.ac.uk">UCL VR Centre</a> and
-          <a href="http://www.bytemark.co.uk">bytemark</a>.
+        <%= t 'layouts.intro_3', 
+              :ucl => '<a href="http://www.vr.ucl.ac.uk">UCL VR Centre</a>', 
+              :bytemark => '<a href="http://www.bytemark.co.uk">bytemark</a>' %>
         </p>
       </div>
       <% end %>
 
       <% if OSM_STATUS == :database_offline or OSM_STATUS == :api_offline %>
       <div id="alert">
-        The OpenStreetMap database is currently offline while
-        essential database maintenance work is carried out.
+        <%= t 'layouts.offline' %>
       </div>
       <% elsif OSM_STATUS == :database_readonly or OSM_STATUS == :api_readonly %>
       <div id="alert">
-        The OpenStreetMap database is currently in read-only mode while
-        essential database maintenance work is carried out.
-      </div>
+        <%= t 'layouts.read_only' %>
       <% end %>
 
       <% if false %>
       <div id="donate" class="notice">
-        Support OpenStreetMap by
-        <a href="http://donate.openstreetmap.org/">donating</a>
-        to the Hardware Upgrade Fund.
+        <%= t 'layouts.donate', :link => "<a href=\"http://donate.openstreetmap.org/\">#{t('layouts.donate_link_text')}</a>" %>
       </div>
       <% end %>
 
       <div id="left_menu" class="left_menu">
-        <a href="http://wiki.openstreetmap.org">Help &amp; Wiki</a><br />
-        <a href="http://www.opengeodata.org/">News blog</a><br />
-        <a href="http://wiki.openstreetmap.org/index.php/Merchandise">Shop</a><br />
+        <a href="http://wiki.openstreetmap.org"><%= t 'layouts.help_wiki' %></a><br />
+        <a href="http://www.opengeodata.org/"><%= t 'layouts.news_blog' %></a><br />
+        <a href="http://wiki.openstreetmap.org/index.php/Merchandise"><%= t 'layouts.shop' %></a><br />
         <%= yield :left_menu %>
       </div>
 
       <div id="sotm" class="notice">
-        <%= link_to image_tag("sotm.png", :alt => "State of the Map", :border => "0"), "http://www.stateofthemap.org/" %>
+        <%= link_to image_tag("sotm.png", :alt => t('layouts.sotm'), :title => t('layouts.sotm'), :border => "0"), "http://www.stateofthemap.org/" %>
       </div>
 
       <%= yield :optionals %>
 
       <center>
         <div class="button" style="width: 115px">
-          <a href="http://donate.openstreetmap.org/"><img src="/images/donate.png" border="0" alt="Make a Donation" /></a>
+          <a href="http://donate.openstreetmap.org/"><img src="/images/donate.png" border="0" alt="<%= t 'layouts.alt_donation' %>" title="<%= t 'layouts.alt_donation' %>" /></a>
         </div>
 
         <div id="cclogo" class="button" style="width: 88px">
index 263e30e64089d2b93e25bd29d89b8bdac848ae70..129204d2d845c111e93c8f190cc27bdd451660c3 100644 (file)
@@ -4,11 +4,11 @@
 <tr class="inbox-row<%= "-unread" if not message_summary.message_read? %>">
   <td class="inbox-sender" bgcolor="<%= this_colour %>"><%= link_to h(message_summary.sender.display_name), :controller => 'user', :action => message_summary.sender.display_name %></td>
   <td class="inbox-subject" bgcolor="<%= this_colour %>"><%= link_to h(message_summary.title), :controller => 'message', :action => 'read', :message_id => message_summary.id  %></td>
-  <td class="inbox-sent" bgcolor="<%= this_colour %>"><%= message_summary.sent_on %></td>
+  <td class="inbox-sent" bgcolor="<%= this_colour %>"><%= message_summary.sent_on %></td>
   <% if message_summary.message_read? %>
-    <td><%= button_to 'Mark as unread', :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'unread' %></td>
+    <td><%= button_to t('message.message_summary.unread_button'), :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'unread' %></td>
   <% else %>
-    <td><%= button_to 'Mark as read', :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'read' %></td>
+    <td><%= button_to t('message.message_summary.read_button'), :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'read' %></td>
   <% end %>
-  <td><%= button_to 'Reply', :controller => 'message', :action => 'reply', :message_id => message_summary.id %></td>
+  <td><%= button_to t('message.message_summary.reply_button'), :controller => 'message', :action => 'reply', :message_id => message_summary.id %></td>
 </tr>
index 91fafe901347fbb0aed847c2f328523a645e4ee4..a03074e0838fa9f93793cef8ac8606cf4a9dccd9 100644 (file)
@@ -4,5 +4,5 @@
 <tr class="inbox-row">
   <td class="inbox-sender" bgcolor="<%= this_colour %>"><%= link_to h(sent_message_summary.recipient.display_name), :controller => 'user', :action => sent_message_summary.recipient.display_name %></td>
   <td class="inbox-subject" bgcolor="<%= this_colour %>"><%= link_to h(sent_message_summary.title), :controller => 'message', :action => 'read', :message_id => sent_message_summary.id  %></td>
-  <td class="inbox-sent" bgcolor="<%= this_colour %>"><%= sent_message_summary.sent_on %></td>
+  <td class="inbox-sent" bgcolor="<%= this_colour %>"><%= sent_message_summary.sent_on %></td>
 </tr>
index 2a64f2774788d7b81b0bfd343d82413a23bd3dce..38fe8495b7aa89e7bca7aaf953316ca96087e6c7 100644 (file)
@@ -1,14 +1,14 @@
-<h2>My inbox/<%= link_to "outbox", url_for(:controller => "user", :action => "outbox", :id => @user.display_name) %></h2>
+<h2><%= t'message.inbox.my_inbox'%>/<%= link_to t('message.inbox.outbox'), url_for(:controller => "user", :action => "outbox", :id => @user.display_name) %></h2>
 
-<p>You have <%= @user.new_messages.size %> new messages and <%= @user.messages.size -  @user.new_messages.size %> old messages</p> 
+<p><%= t'message.inbox.you_have', :new_count => @user.new_messages.size, :old_count => (@user.messages.size -  @user.new_messages.size) %></p> 
 
 <% if @user.messages.size > 0 %>
   <div id="messages">
     <table class="messages">
       <tr>
-        <th>From</th>
-        <th>Subject</th>
-        <th>Date</th>
+        <th><%= t'message.inbox.from' %></th>
+        <th><%= t'message.inbox.subject' %></th>
+        <th><%= t'message.inbox.date' %></th>
         <th></th>
         <th></th>
       </tr>
@@ -16,5 +16,5 @@
     </table>
   </div>
 <% else %>
-         <div id="messages">You have no messages yet. Why not get in touch with some of the <%= link_to 'people mapping nearby', :controller => 'user', :action => 'view', :display_name => @user.display_name %>?</div>
+         <div id="messages"><%= t'message.inbox.no_messages_yet', :people_mapping_nearby_link => link_to(t('message.inbox.people_mapping_nearby'), :controller => 'user', :action => 'view', :display_name => @user.display_name) %></div>
 <% end %>
index 17f3588bb47b4b3a6668a0c06111066eea6674b5..a356692c8f000e3973c1a7890a74e1ac94bcb830 100644 (file)
@@ -1,29 +1,24 @@
-<h2>Send a new message to <%= h(@to_user.display_name) %></h2>
-
-<% if params[:display_name] %>
-<p>Writing a new message to <%= h(params[:display_name]) %></p>  
-<p>TODO: drop down box of your friends</p>
-<%end%>
+<h2><%= t'message.new.send_message_to', :name => h(@to_user.display_name) %></h2>
 
 <%= error_messages_for 'message' %>
 
 <% form_for :message, :url => { :action => "new", :user_id => @to_user.id } do |f| %>
   <table>
     <tr valign="top">
-      <th>Subject</th>
+      <th><%= t'message.new.subject' %></th>
       <td><%= f.text_field :title, :size => 60, :value => @title %></td>
     </tr>
     <tr valign="top">
-      <th>Body</th>
+      <th><%= t'message.new.body' %></th>
       <td><%= f.text_area :body, :cols => 80, :value => @body %></td>
     </tr>
     <tr>
       <th></th>
-      <td><%= submit_tag 'Send' %></td>
+      <td><%= submit_tag t('message.new.send_button') %></td>
     </tr>
   </table>
 <% end %>
 
 <br />
 
-<%= link_to 'Back to inbox', :controller => 'message', :action => 'inbox', :display_name => @user.display_name %>
+<%= link_to t('message.new.back_to_inbox'), :controller => 'message', :action => 'inbox', :display_name => @user.display_name %>
index c18733af6d48fd37dd41f88d6025f2e963c636b9..0d9ba66aae008353ab1a4c9022882cbac89f2971 100644 (file)
@@ -1,2 +1,2 @@
-<h1>No such user or message</h1>
-<p>Sorry there is no user or message with that name or id</p>
+<h1><%= t'message.no_such_user.no_such_user' %></h1>
+<p><%= t'message.no_such_user.sorry' %></p>
index 6fcbdfa2161d69fe0c596bd3ec970c3503c197f9..3e6346c9ab90398ba5485ad1ac550d14f460d07a 100644 (file)
@@ -1,18 +1,18 @@
-<h2>My <%= link_to "inbox", url_for(:controller => "user", :action => "inbox", :id => @user.display_name) %>/outbox</h2>
+<h2><%= t'message.outbox.my_inbox', :inbox_link => link_to(t('message.outbox.inbox'), url_for(:controller => "user", :action => "inbox", :id => @user.display_name)) %>/<%= t'message.outbox.outbox' %></h2>
 
-<p>You have <%= @user.sent_messages.size %> sent messages
+<p><%= t'message.outbox.you_have_sent_messages', :sent_count => @user.sent_messages.size %>
 
 <% if @user.sent_messages.size > 0 %>
   <div id="messages">
     <table class="messages">
       <tr>
-        <th>To</th>
-        <th>Subject</th>
-        <th>Date</th>
+        <th><%= t'message.outbox.to' %></th>
+        <th><%= t'message.outbox.subject' %></th>
+        <th><%= t'message.outbox.date' %></th>
       </tr>
       <%= render :partial => "sent_message_summary", :collection => @user.sent_messages %>
     </table>
   </div>
 <% else %>
-         <div id="messages">You have no sent messages yet. Why not get in touch with some of the <%= link_to 'people mapping nearby', :controller => 'user', :action => 'view', :display_name => @user.display_name %>?</div>
+         <div id="messages"><%= t'message.outbox.no_sent_messages', :people_mapping_nearby_link => link_to(t('message.outbox.people_mapping_nearby'), :controller => 'user', :action => 'view', :display_name => @user.display_name) %></div>
 <% end %>
index d44859029dea35f7cadda8002239b8120943d419..8a7b6b1563c235340f6969e42a320f5b53b3497e 100644 (file)
@@ -1,10 +1,10 @@
 <% if @user == @message.recipient %>
 
-<h2>Reading your messages</h2>
+<h2><%= t'message.read.reading_your_messages' %></h2>
 
 <table>
   <tr>
-    <th align="right">From</th>
+    <th align="right"><%= t'message.read.from' %></th>
     <td>
      <% if @message.sender.image %>
         <%= image_tag url_for_file_column(@message.sender, "image") %>
 <%= link_to h(@message.sender.display_name), :controller => 'user', :action => 'view', :display_name => @message.sender.display_name %></td>
   </tr>
   <tr>
-    <th align="right">Subject</th>
+    <th align="right"><%= t'message.read.subject' %></th>
     <td><%= h(@message.title) %></td>
   </tr>
   <tr>
-    <th align="right">Date</th>
-    <td><%= @message.sent_on %></td>
+    <th align="right"><%= t'message.read.date' %></th>
+    <td><%= @message.sent_on %></td>
   </tr>
   <tr>
     <th></th>
 
 <table>
   <tr>
-    <td><%= button_to 'Reply', :controller => 'message', :action => 'reply', :message_id => @message.id %></td>
-    <td><%= button_to 'Mark as unread', :controller => 'message', :action => 'mark', :message_id => @message.id, :mark => 'unread' %></td>
-    <td><%= link_to 'Back to inbox', :controller => 'message', :action => 'inbox', :display_name => @user.display_name %></td>
+    <td><%= button_to t('message.read.reply_button'), :controller => 'message', :action => 'reply', :message_id => @message.id %></td>
+    <td><%= button_to t('message.read.unread_button'), :controller => 'message', :action => 'mark', :message_id => @message.id, :mark => 'unread' %></td>
+    <td><%= link_to t('message.read.back_to_inbox'), :controller => 'message', :action => 'inbox', :display_name => @user.display_name %></td>
   </tr>
 </table>
 
 <% else %>
 
-<h2>Reading your sent messages</h2>
+<h2><%= t'message.read.reading_your_sent_messages' %></h2>
 
 <table>
   <tr>
-    <th align="right">To</th>
+    <th align="right"><%= t'message.read.to' %></th>
     <td><%= link_to h(@message.recipient.display_name), :controller => 'user', :action => 'view', :display_name => @message.recipient.display_name %></td>
   </tr>
   <tr>
-    <th align="right">Subject</th>
+    <th align="right"><%= t'message.read.subject' %></th>
     <td><%= h(@message.title) %></td>
   </tr>
   <tr>
-    <th align="right">Date</th>
-    <td><%= @message.sent_on %></td>
+    <th align="right"><%= t'message.read.date' %></th>
+    <td><%= @message.sent_on %></td>
   </tr>
   <tr>
     <th></th>
@@ -63,7 +63,7 @@
 
 <table>
   <tr>
-    <td><%= link_to 'Back to outbox', :controller => 'message', :action => 'outbox', :display_name => @user.display_name %></td>
+    <td><%= link_to t('message.read.back_to_outbox'), :controller => 'message', :action => 'outbox', :display_name => @user.display_name %></td>
   </tr>
 </table>
 
index 4d5cd1d156168c3415b1652794b7e01230678958..2202f57c370d6211c4a46a7a7065446cb8f6c6a5 100644 (file)
@@ -1,44 +1,25 @@
 ***************************************************************************
 *                                                                         *
-*                   Please do not reply to this email.                    *
-*                Use the OpenStreetMap web site to reply.                 *
-*                                                                         *
-*               Bitte antworten Sie nicht auf diese E-Mail.               *
-*          Verwenden Sie die OpenStreetMap Website zum Antworten.         *
-*                                                                         *
-*                 Por favor, no responda a este mensaje.                  *
-*           Utilice el OpenStreetMap sitio web para responder.            *
-*                                                                         *
-*            S’il vous plaît de ne pas répondre à ce message.             *
-*           Utilisez le OpenStreetMap site Web pour y répondre.           *
+<%= t'banner1' %>
+<%= t'banner2' %>
 *                                                                         *
 ***************************************************************************
 
-Hi <%= @to_user %>,
 
-<%= @from_user %> has commented on your recent OpenStreetMap diary entry
-with the subject "<%= @subject %>":
+<%= t'notifier.diary.hi', :to_user => @to_user %> 
+
+<%= t'notifier.diary.header', :from_user => @from_user, :subject => @subject %>
 
 ==
 <%= @body %>
 ==
 
-You can also read the comment at <%= @readurl %>
-and you can comment at <%= @commenturl %>
-or reply at <%= @replyurl %>
+<%= t'notifier.diary.header', :readurl => @readurl, :commenturl => @commenturl, :replyurl => @replyurl
+
 
 ***************************************************************************
 *                                                                         *
-*                   Please do not reply to this email.                    *
-*                Use the OpenStreetMap web site to reply.                 *
-*                                                                         *
-*               Bitte antworten Sie nicht auf diese E-Mail.               *
-*          Verwenden Sie die OpenStreetMap Website zum Antworten.         *
-*                                                                         *
-*                 Por favor, no responda a este mensaje.                  *
-*           Utilice el OpenStreetMap sitio web para responder.            *
-*                                                                         *
-*            S’il vous plaît de ne pas répondre à ce message.             *
-*           Utilisez le OpenStreetMap site Web pour y répondre.           *
+<%= t'banner1' %>
+<%= t'banner2' %>
 *                                                                         *
 ***************************************************************************
index 3831ab91b0dee0768ab256d101a2058b7596db5e..eaeb7dce83aa9b9b54b3a475fd4f11b79fa9f024 100644 (file)
@@ -1,18 +1,18 @@
-<p>Hi there!</p>
+<p><%= t'notifier.signup_confirm_html.greeting' %></p>
 
-<p>Someone (hopefully you) would like to create an account over at
+<p><%= t'notifier.signup_confirm_html.hopefully_you' %>
    <%= SERVER_URL %>.</p>
 
-<p>If this is you, welcome! Please click the link below to confirm that account and read on for more information about OpenStreetMap</p>
+<p><%= t'notifier.signup_confirm_html.click_the_link' %></p>
 
 <p><a href="<%= @url %>"><%= @url %></a></p>
 
-<p>You can watch an introductory video to OpenStreetMap <a href="http://showmedo.com/videos/video?name=1800000&fromSeriesID=180">video here</a>. There are more <a href="http://showmedo.com/videos/series?name=mS2P1ZqS6">videos here</a>.
+<p><%= t'notifier.signup_confirm_html.introductory_video', :introductory_video_link => ('<a href="http://showmedo.com/videos/video?name=1800000&fromSeriesID=180">' + t('notifier.signup_confirm_html.video_to_openstreetmap') + '</a>') %> <%= t'notifier.signup_confirm_html.more_videos', :more_videos_link => ('<a href="http://showmedo.com/videos/series?name=mS2P1ZqS6">' + t('notifier.signup_confirm_html.more_videos_here') + '</a>') %>
 
-Get reading about OpenStreetMap <a href="http://wiki.openstreetmap.org/wiki/Beginners%27_Guide">on the wiki</p> or <a href="http://www.opengeodata.org/">the opengeodata blog</a> which has <a href="http://www.opengeodata.org/?cat=13">podcasts to listen to</a> also!
+<p><%= t'notifier.signup_confirm_html.get_reading' %></p>
 
-<p>You may also want to <a href="http://wiki.openstreetmap.org/index.php?title=Special:Userlogin&type=signup&returnto=Main_Page">sign up to the OpenStreetMap wiki</a>.</p>
+<p><%= t'notifier.signup_confirm_html.wiki_signup' %></p>
 
-<p>It is recommended that you create a user wiki page, which includes category tags noting where you are, such as <a href="http://wiki.openstreetmap.org/index.php/Category:Users_in_London">[[Category:Users_in_London]]</a>.</p> 
+<p><%= t'notifier.signup_confirm_html.user_wiki_page' %></p> 
 
-<p>A list of current users in categories, based on where in the world they are, is available from <a href="http://wiki.openstreetmap.org/index.php/Category:Users_by_geographical_region">Category:Users_by_geographical_region</a>.</p>
+<p><%= t'notifier.signup_confirm_html.current_user' %></p>
index 444891d673fe4af0ebd8263330b338d7e8264ae8..661179909c36319ab557e0d48ff7fa68a359c8aa 100644 (file)
@@ -1,37 +1,37 @@
-Hi there!
+<%= t'notifier.signup_confirm_plain.greeting' %>
 
-Someone (hopefully you) would like to create an account over at
+<%= t'notifier.signup_confirm_plain.hopefully_you' %>
 <%= SERVER_URL %>
 
-If this is you, welcome! Please click the link below to confirm that
-account and read on for more information about OpenStreetMap.
+<%= t'notifier.signup_confirm_plain.click_the_link_1' %>
+<%= t'notifier.signup_confirm_plain.click_the_link_2' %>
 
 <%= @url %>
 
-You can watch an introductory video to OpenStreetMap here:
+<%= t'notifier.signup_confirm_plain.introductory_video' %>
 
        http://showmedo.com/videos/video?name=1800000&fromSeriesID=180  
 
-There are more videos here:
+<%= t'notifier.signup_confirm_plain.more_videos' %>
 
        http://showmedo.com/videos/series?name=mS2P1ZqS6        
 
-Get reading about OpenStreetMap on the wiki:
+<%= t'notifier.signup_confirm_plain.the_wiki' %>
 
        http://wiki.openstreetmap.org/wiki/Beginners%27_Guide
 
-OpenGeoData.org is OpenStreetMap's blog, and it has podcasts too:
+<%= t'notifier.signup_confirm_plain.opengeodata' %>
 
        http://www.opengeodata.org/
 
-You may also want to sign up to the OpenStreetMap wiki at:
+<%= t'notifier.signup_confirm_plain.wiki_signup' %>
 
        http://wiki.openstreetmap.org/index.php?title=Special:Userlogin&type=signup&returnto=Main_Page
 
-It is recommended that you create a user wiki page, which includes
-category tags noting where you are, such as [[Category:Users_in_London]].
+<%= t'notifier.signup_confirm_plain.user_wiki_1' %>
+<%= t'notifier.signup_confirm_plain.user_wiki_2' %>
 
-A list of current users in categories, based on where in the world
-they are, is available from:
+<%= t'notifier.signup_confirm_plain.current_user_1' %>
+<%= t'notifier.signup_confirm_plain.current_user_2' %>
 
 http://wiki.openstreetmap.org/index.php/Category:Users_by_geographical_region
index f800bbb9767cc29cc3266d87179956dba7c1fbf4..9782b4cc59ef6422229d173b68289563b40a960f 100644 (file)
@@ -1,5 +1,5 @@
 <% content_for :left_menu do %>
-<%= link_to_function "Map key", "showKey();" %>
+<%= link_to_function t('site.key.map_key'), "showKey();" %>
 <% end %>
 
 <script type="text/javascript">
index 6ddcc851cd640bab7ac4495d3d18f45013f49e81..b57a1f984f0381308322d9e78ccfb23119000cef 100644 (file)
 
 <% content_for "optionals" do %>
   <div class="optionalbox">
-    <span class="oboxheader">Search</span>
-    <span class="whereami"><a href="javascript:describeLocation()">Where am I?</a></span>
+    <span class="oboxheader"><%= t 'site.search.search' %></span>
+    <span class="whereami"><a href="javascript:describeLocation()"><%= t 'site.search.where_am_i' %></a></span>
     <div class="search_form">
     <div id="search_field">
     <% form_remote_tag(:loading => "startSearch()",
                        :complete => "endSearch()",
                        :url => { :controller => :geocoder, :action => :search }) do %>
       <%= text_field_tag :query, h(params[:query]) %>
-      <%= submit_tag "Go" %>
+      <%= submit_tag t('site.search.submit_text') %>
     <% end %>
     </div>
-    <p id="search_active">Searching...</p>
+    <p id="search_active"><%= t 'site.search.searching' %></p>
     </div>
     <p class="search_help">
-      examples: 'Alkmaar', 'Regent Street, Cambridge', 'CB2 5AQ',
-      or 'post offices near Lünen'
-      <a href="http://wiki.openstreetmap.org/index.php/Search">more examples...</a>
+      <%= t 'site.search.search_help' %>
     </p>
   </div>
 <% end %>
index ad2845ff47ed8a637f6079e9fbf3ff31017a2124..dd15ef7ba64b2e00ac17de7da3066d3a11c38f0f 100644 (file)
@@ -1,8 +1,8 @@
 <div id="sidebar">
   <table class="sidebar_title" width="100%">
     <tr>
-      <td align="left" id="sidebar_title">Search Results</td>
-      <td align="right"><a href="javascript:closeSidebar()">Close</a></td>
+      <td align="left" id="sidebar_title"><% t 'site.sidebar.search_results' %></td>
+      <td align="right"><a href="javascript:closeSidebar()"><%= t 'site.sidebar.close' %></a></td>
     </tr>
   </table>
   <div id="sidebar_content">
index 0080fa8d7a7ee1161788d7687ab7a28d49de7389..49e4e94f09554d9390b1417b6e5ae54f851c004e 100644 (file)
@@ -1,16 +1,14 @@
 <% if OSM_STATUS == :database_offline or OSM_STATUS == :api_offline %>
-<p>The OpenStreetMap database is currently offline while
-   essential database maintenance work is carried out.
+<p><%= t 'layouts.osm_offline' %>
 </p>
 <% elsif OSM_STATUS == :database_readonly or OSM_STATUS == :api_readonly %>
-<p>The OpenStreetMap database is currently in read-only mode while
-   essential database maintenance work is carried out.
+<p><%= t 'layouts.osm_read_only' %>
 </p>
 <% elsif !@user.data_public? %>
-<p>You haven't set your edits to be public.</p>
-<p>You can no longer edit the map unless you do so. You can set your edits as public from your 
-<%= link_to 'user page', {:controller => 'user', :action => 'account', :display_name => @user.display_name, :anchor => 'public'}%>.</p>
-<p>(<a href="http://wiki.openstreetmap.org/index.php/Disabling_anonymous_edits">Find out why this is the case.</a>)</p>
+<p><%= t 'site.edit.not_public' %></p>
+<p><%= t 'site.edit.not_public_description', 
+:user_page => (link_to t('site.edit.user_page_link'), {:controller => 'user', :action => 'account', :display_name => @user.display_name, :anchor => 'public'}) %></p>
+<p><%= t 'site.edit.anon_edits', :link => link_to(t('site.edit.anon_edit_link_text'), t('site.edit.anon_edits_link')) %> (<a href=""></a>)</p>
 <% else %>
 <% content_for :greeting do %>
 <% if @user and !@user.home_lon.nil? and !@user.home_lat.nil? %>
@@ -54,11 +52,7 @@ zoom='14' if zoom.nil?
 %>
 
 <div id="map">
-       You need a Flash player to use Potlatch, the
-    OpenStreetMap Flash editor. You can <a href="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">download Flash Player from Adobe.com</a>.
-
-    <a href="http://wiki.openstreetmap.org/index.php/Editing">Several other options</a> are also available
-    for editing OpenStreetMap.
+       <%= t 'site.edit.flash_player_required' %>
 </div>
 
 <%= javascript_include_tag 'swfobject.js' %>
@@ -71,7 +65,7 @@ zoom='14' if zoom.nil?
   
   window.onbeforeunload=function() {
        if (!changesaved && !winie) {
-           return "You have unsaved changes.";
+           return "<%= t 'site.edit.potlatch_unsaved_changes' %>";
        }
   }
 
index b8fcf579ee2c6071d78257eb204210052ad97456..53a4c9a07800aa27e44576fa278c46532942a4de 100644 (file)
 
 <noscript>
   <div id="noscript">
-    <p>You are either using a browser that doesn't support javascript, or you have disabled javascript.</p>
-    <p>OpenStreetMap uses javascript for its slippy map.</p>
-    <p>You may want to try the <a href="http://tah.openstreetmap.org/Browse/">Tiles@Home static tile browser</a> if you are unable to enable javascript.</p>
+    <p><%= t 'site.index.js_1' %></p>
+    <p><%= t 'site.index.js_2' %></p>
+    <p><%= t 'site.index.js_3' %></p>
   </div>
 </noscript>
 
 <div id="map">
-<div id="permalink"><a href="/" id="permalinkanchor">Permalink</a></div>
+<div id="permalink"><a href="/" id="permalinkanchor"><%= t 'site.index.permalink' %></a></div>
 </div> 
 
 <div id="attribution">
@@ -27,7 +27,7 @@
       <td align="right">http://openstreetmap.org/</td>
     </tr>
     <tr>
-      <td colspan="2" align="center">Licensed under the Creative Commons Attribution-Share Alike 2.0 license by the OpenStreetMap project and its contributors.</td>
+      <td colspan="2" align="center"><%= t 'site.index.license' %></td>
     </tr>
   </table>
 </div>
index 22cf37ca9b1e3e8979b86a123284aa67afafd081..b960ab66d05347aedb40bba23b6d4bdd351cbed3 100644 (file)
@@ -1,9 +1,7 @@
 <% if OSM_STATUS == :database_offline %>
-<p>The OpenStreetMap database is currently offline while
-   essential database maintenance work is carried out.
+<p><%= t 'layouts.osm_offline' %>
 </p>
 <% else %>
-<p>The OpenStreetMap database is currently in read-only mode while
-   essential database maintenance work is carried out.
+<p><%= t 'layouts.osm_read_only' %>
 </p>
 <% end  %>
index d54f77ab6d31bbbbdec0922bcc1c56025ac5643a..430d87344c5b120b5c443febe3dcb18feda3799e 100644 (file)
@@ -4,7 +4,7 @@
     <% if trace.inserted %>
       <a href="<%= url_for :controller => 'trace', :action => 'view', :id => trace.id, :display_name => trace.user.display_name %>"><img src="<%= url_for :controller => 'trace', :action => 'icon', :id => trace.id, :display_name => trace.user.display_name %>" border="0" alt="" /></a>
     <% else %>
-      <span style="color:red">PENDING</span>
+      <span style="color:red"><%= t'trace.trace.pending' %></span>
     <% end %>
   </td>
   <td class="<%= cl %>"><%= link_to trace.name, {:controller => 'trace', :action => 'view', :display_name => trace.user.display_name, :id => trace.id} %>
         (<%= trace.size.to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,') %> points)
       <% end %> 
       ... <%= time_ago_in_words( trace.timestamp ) %>  ago</span>
-      <%= link_to 'more', {:controller => 'trace', :action => 'view', :display_name => trace.user.display_name, :id => trace.id}, {:title => 'View Trace Details'} %> /
-      <%= link_to_if trace.inserted?, 'map', {:controller => 'site', :action => 'index', :lat => trace.latitude, :lon => trace.longitude, :zoom => 14}, {:title => 'View Map'} %> /
-      <%= link_to 'edit', {:controller => 'site', :action => 'edit', :gpx => trace.id }, {:title => 'Edit Map'} %>
+      <%= link_to t('trace.trace.more'), {:controller => 'trace', :action => 'view', :display_name => trace.user.display_name, :id => trace.id}, {:title => t('trace.trace.trace_details')} %> /
+      <%= link_to_if trace.inserted?, 'map', {:controller => 'site', :action => 'index', :lat => trace.latitude, :lon => trace.longitude, :zoom => 14}, {:title => t('trace.trace.view_map')} %> /
+      <%= link_to t('trace.trace.edit'), {:controller => 'site', :action => 'edit', :gpx => trace.id }, {:title => t('trace.trace.edit_map')} %>
       <% if trace.public? %>
-        <span style="color:green">PUBLIC</span>
+        <span style="color:green"><%= t'trace.trace.public' %></span>
       <% else %>
-        <span style="color:red">PRIVATE</span>
+        <span style="color:red"><%= t'trace.trace.private' %></span>
       <% end %>
       <br />
       <%= h(trace.description) %>
     <br />
-    by <%= link_to h(trace.user.display_name), {:controller => 'user', :action => 'view', :display_name => trace.user.display_name} %>
+    <%= t'trace.trace.by' %> <%=link_to h(trace.user.display_name), {:controller => 'user', :action => 'view', :display_name => trace.user.display_name} %>
     <% if !trace.tags.empty? %>
-      in 
+      <%= t'trace.trace.in' %> 
       <% trace.tags.each do |tag| %>
         <%= link_to_tag tag.tag %>
       <% end %>
index 299845015c564e15743e5835f2213e189bcb7c31..9d9dd146ab3df4c50fbdbef6298258b80609a267 100644 (file)
@@ -1,9 +1,9 @@
 <% form_for :trace, @trace, :url => { :action => "create" }, :html => { :multipart => true } do |f| %>
 <table>
-  <tr><td align="right">Upload GPX File</td><td><%= f.file_field :gpx_file, :size => 50, :maxlength => 255 %></td></tr>
-  <tr><td align="right">Description</td><td><%= f.text_field :description, :size => 50, :maxlength => 255 %></td></tr>
-  <tr><td align="right">Tags</td><td><%= f.text_field :tagstring, :size => 50, :maxlength => 255 %></td></tr>
-  <tr><td align="right">Public?</td><td><%= f.check_box :public %></td></tr>
-  <tr><td></td><td><%= submit_tag 'Upload' %> | <a href="http://wiki.openstreetmap.org/index.php/Upload">Help</a></td></tr>
+  <tr><td align="right"><%= t'trace.trace_form.upload_gpx' %></td><td><%= f.file_field :gpx_file, :size => 50, :maxlength => 255 %></td></tr>
+  <tr><td align="right"><%= t'trace.trace_form.description' %></td><td><%= f.text_field :description, :size => 50, :maxlength => 255 %></td></tr>
+  <tr><td align="right"><%= t'trace.trace_form.tags' %></td><td><%= f.text_field :tagstring, :size => 50, :maxlength => 255 %></td></tr>
+  <tr><td align="right"><%= t'trace.trace_form.public' %></td><td><%= f.check_box :public %></td></tr>
+  <tr><td></td><td><%= submit_tag t('trace.trace_form.upload_button') %> | <a href="http://wiki.openstreetmap.org/index.php/Upload"><%= t'trace.trace_form.help' %></a></td></tr>
 </table>
 <% end %>
index cab6f7124504320d1eb19b8920bac3971b980e5b..5be7269c2e0691d392e28c1ac355ff0f15cb7fca 100644 (file)
@@ -7,20 +7,16 @@
 <p>
   <%= rss_link_to :action => 'georss', :display_name => @display_name, :tag => @tag %>
   <% if @user.nil? or @display_name.nil? or @user.display_name != @display_name %>
-    | <%= link_to 'See just your traces, or upload a trace', :action => 'mine' %>
+    | <%= link_to t('trace.trace_header.see_just_your_traces'), :action => 'mine' %>
   <% end %>
   <% if @tag or @display_name %>
-    | <%= link_to 'See all traces', :controller => 'trace', :action => 'list' %>
+    | <%= link_to t('trace.trace_header.see_all_traces'), :controller => 'trace', :action => 'list' %>
   <% end %>
   <% if @tag and @user and @user.display_name == @display_name %>
-    | <%= link_to 'See all your traces', :controller => 'trace', :action => 'mine' %>
+    | <%= link_to t('trace.trace_header.see_your_traces'), :controller => 'trace', :action => 'mine' %>
   <% end %>
 </p>
 
 <% if @user and @user.traces.count(:conditions => ["inserted=?", false]) > 4 %>
-  <p>
-    You have <%= @user.traces.count(:conditions => ["inserted=?", false]) %> traces 
-    waiting for upload. Please consider waiting for these to finish before 
-    uploading any more, so as not to block the queue for other users.
-  </p>
+  <p><%= t'trace.trace_header.traces_waiting', :count => @user.traces.count(:conditions => ["inserted=?", false]) %></p>
 <% end %>
index b5b068fe60de4387287e30542cc7a479d6619b55..f166a779bb5b9b4ecaa68e81cb8530cee3f68002 100644 (file)
@@ -1,6 +1,6 @@
 <% content_for "optionals" do %>
   <div class="optionalbox">
-    <span class="oboxheader">Tags</span>
+    <span class="oboxheader"><%= t'trace.trace_optionals.tags' %></span>
     <br />
     <br />
     <% if @all_tags %>
index fec83e3dac5f24d1bf9d92d0d0906583968978a1..9ac80d4cd9a74678cd782e1648c0d9f548f588a6 100644 (file)
@@ -1,11 +1,11 @@
 <% current_page = @trace_pages.current_page %>
 
-Showing page 
+<%= t'trace.trace_paging_nav.showing' %> 
 <%= current_page.number %> (<%= current_page.first_item %><% 
 if (current_page.first_item < current_page.last_item) # if more than 1 trace on page 
   %>-<%= current_page.last_item %><% 
 end %>
-of <%= @trace_pages.item_count %>)
+<%= t'trace.trace_paging_nav.of' %> <%= @trace_pages.item_count %>)
 
 <% if @trace_pages.page_count > 1 %>
  | <%= pagination_links_each(@trace_pages, {}) { |n| link_to_page(n) } %>
index 94f4039516d7e3914bc88a6f9ac4acf4a29604ed..140b74918cd8027323ad38f729df668d3a182f85 100644 (file)
@@ -1,4 +1,4 @@
-<h1>Upload GPS Trace</h1>
+<h1><%= t'trace.create.upload_trace' %></h1>
 
 <%= error_messages_for 'trace' %>
 
index d7c04182dbcebc636798eaaff4b8abd72b20cbff..9d91dec2e35ed2757abc15591404ef2134fbbc26 100644 (file)
@@ -6,28 +6,28 @@
 
 <table border="0">
   <tr>
-    <td>Filename:</td>
+    <td><%= t'trace.edit.filename' %></td>
     <td><%= @trace.name %> (<%= link_to 'download', :controller => 'trace', :action => 'data', :id => @trace.id %>)</td>
   </tr> 
   <tr>
-    <td>Uploaded at:</td>
+    <td><%= t'trace.edit.uploaded_at' %></td>
     <td><%= @trace.timestamp %></td>
   </tr>
   <% if @trace.inserted? %>
   <tr>
-    <td>Points:</td>
+    <td><%= t'trace.edit.points' %></td>
     <td><%= @trace.size.to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,') %></td></tr>
   <tr>
-    <td>Start coordinate:</td>
-    <td><div class="geo" style="display: inline"><span class="latitude"><%= @trace.latitude %></span>; <span class="longitude"><%= @trace.longitude %></span></div> (<%=link_to 'map', :controller => 'site', :action => 'index', :lat => @trace.latitude, :lon => @trace.longitude, :zoom => 14 %> / <%=link_to 'edit', :controller => 'site', :action => 'edit', :lat => @trace.latitude, :lon => @trace.longitude, :gpx=> @trace.id, :zoom => 14 %>)</td>
+    <td><%= t'trace.edit.start_coord' %>Start coordinate:</td>
+    <td><div class="geo" style="display: inline"><span class="latitude"><%= @trace.latitude %></span>; <span class="longitude"><%= @trace.longitude %></span></div> (<%=link_to 'map', :controller => 'site', :action => 'index', :lat => @trace.latitude, :lon => @trace.longitude, :zoom => 14 %> / <%=link_to t('trace.edit.edit'), :controller => 'site', :action => 'edit', :lat => @trace.latitude, :lon => @trace.longitude, :gpx=> @trace.id, :zoom => 14 %>)</td>
   </tr>
   <% end %>
   <tr>
-    <td>Owner:</td>
+    <td><%= t'trace.edit.owner' %></td>
     <td><%= link_to h(@trace.user.display_name), {:controller => 'user', :action => 'view', :display_name => @trace.user.display_name} %></td>
   </tr>
   <tr>
-    <td>Description:</td>
+    <td><%= t'trace.edit.description' %></td>
     <td><%= f.text_field :description %></td>
   </tr>
   <tr>
index 7820b4847c6d260a232005a0eda5bcda52a2a930..46ff6c1b07e52f0654f4970f811519059952e736 100644 (file)
@@ -1,2 +1,2 @@
 <h2><%= h(@not_found_user) %></h2>
-<p>Sorry, there is no user with the name <%= @not_found_user -%>. Please check your spelling, or maybe the link you clicked is wrong.</p>
+<p><%= t'trace.no_such_user.no_such_user', :name => @not_found_user %></p>
index 585342c0224c6abc6c88f024d194ee40efbf6ee9..381a2fc973c2c7612c871f270e8e51e117d3e753 100644 (file)
@@ -3,44 +3,44 @@
   <% if @trace.inserted %>
     <img src="<%= url_for :controller => 'trace', :action => 'picture', :id => @trace.id, :display_name => @trace.user.display_name %>">
   <% else %>
-    <span style="color:red">PENDING</span>
+    <span style="color:red"><%= t'trace.view.pending' %></span>
   <% end %>
 
 <table border="0">
   <tr>
-    <td>Filename:</td>
-    <td><%= @trace.name %> (<%= link_to 'download', :controller => 'trace', :action => 'data', :id => @trace.id %>)</td>
+    <td><%= t'trace.view.filename' %></td>
+    <td><%= @trace.name %> (<%= link_to t('trace.view.download'), :controller => 'trace', :action => 'data', :id => @trace.id %>)</td>
   </tr> 
   <tr>
-    <td>Uploaded at:</td>
+    <td><%= t'trace.view.uploaded' %></td>
     <td><%= @trace.timestamp %></td>
   </tr>
   <% if @trace.inserted? %>
   <tr>
-    <td>Points:</td>
+    <td><%= t'trace.view.points' %></td>
     <td><%= @trace.size.to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,') %></td></tr>
   <tr>
-    <td>Start coordinate:</td>
-    <td><div class="geo" style="display: inline"><span class="latitude"><%= @trace.latitude %></span>; <span class="longitude"><%= @trace.longitude %></span></div> (<%=link_to 'map', :controller => 'site', :action => 'index', :lat => @trace.latitude, :lon => @trace.longitude, :zoom => 14 %> / <%=link_to 'edit', :controller => 'site', :action => 'edit', :lat => @trace.latitude, :lon => @trace.longitude, :gpx=> @trace.id, :zoom => 14 %>)</td>
+    <td><%= t'trace.view.start_coordinates' %></td>
+    <td><div class="geo" style="display: inline"><span class="latitude"><%= @trace.latitude %></span>; <span class="longitude"><%= @trace.longitude %></span></div> (<%=link_to t('trace.view.map'), :controller => 'site', :action => 'index', :lat => @trace.latitude, :lon => @trace.longitude, :zoom => 14 %> / <%=link_to t('trace.view.edit'), :controller => 'site', :action => 'edit', :lat => @trace.latitude, :lon => @trace.longitude, :gpx=> @trace.id, :zoom => 14 %>)</td>
   </tr>
   <% end %>
   <tr>
-    <td>Owner:</td>
+    <td><%= t'trace.view.owner' %></td>
     <td><%= link_to h(@trace.user.display_name), {:controller => 'user', :action => 'view', :display_name => @trace.user.display_name} %></td>
   </tr>
   <tr>
-    <td>Description:</td>
+    <td><%= t'trace.view.description' %></td>
     <td><%= h(@trace.description) %></td>
   </tr>
   <tr>
-    <td>Tags:</td>
+    <td><%= t'trace.view.tags' %></td>
     <td>
     <% if @trace.tags %>
       <% @trace.tags.each do |tag| %>
         <%= link_to tag.tag, { :controller => 'trace', :action => 'list', :tag => tag.tag, :id => nil } %>
       <% end %>
     <% else %>
-      None
+      <%= t'trace.view.none' %>
     <% end %>
     </td>
   </tr>
 <table>
   <tr>
     <% unless @trace.public? %>
-    <td><%= button_to 'Make this track public permanently', :controller => 'trace', :action => 'make_public', :id => @trace.id %></td>
+    <td><%= button_to t('trace.view.make_public'), :controller => 'trace', :action => 'make_public', :id => @trace.id %></td>
     <% end %>
     <% if @trace.user == @user %>
-    <td><%= button_to 'Edit this track', :controller => 'trace', :action => 'edit', :id => @trace.id %></td>
+    <td><%= button_to t('trace.view.edit_track'), :controller => 'trace', :action => 'edit', :id => @trace.id %></td>
     <% end %>
     <% if @trace.user == @user %>
-    <td><%= button_to 'Delete this track', :controller => 'trace', :action => 'delete', :id => @trace.id %></td>
+    <td><%= button_to t('trace.view.delete_track'), :controller => 'trace', :action => 'delete', :id => @trace.id %></td>
     <% end %>
   </tr>
 </table>
index 33d6e1f8566c1665c52b58a50bc2e8d98c438f3b..c6d5f8afe498c776857590c4deab81c67572434d 100644 (file)
     setMapCenter(centre, zoom);
 
     <% if marker %>
-    marker = addMarkerToMap(new OpenLayers.LonLat(<%= mlon %>, <%= mlat %>), null, "Your location");
+    marker = addMarkerToMap(new OpenLayers.LonLat(<%= mlon %>, <%= mlat %>), null, "<%= t 'user.friend_map.your location' %>");
     <% end %>
 
     var near_icon = OpenLayers.Marker.defaultIcon();
     near_icon.url = OpenLayers.Util.getImagesLocation() + "marker-green.png";;
     var i = nearest.length;
     while( i-- ) {
-      var description = 'Nearby mapper: <a href="/user/'+nearest[i].display_name+'">'+nearest[i].display_name+'</a>'
+      var description = '<%= t 'user.friend_map.nearby mapper'%><a href="/user/'+nearest[i].display_name+'">'+nearest[i].display_name+'</a>'
       var nearmarker = addMarkerToMap(new OpenLayers.LonLat(nearest[i].home_lon, nearest[i].home_lat), near_icon.clone(), description);
     }
 
@@ -75,7 +75,7 @@
         removeMarkerFromMap(marker);
       }
 
-      marker = addMarkerToMap(lonlat, null, "Your location");
+      marker = addMarkerToMap(lonlat, null, "<%= t 'user.friend_map.your location' %>");
     }
   }
 
index 1dd4bdca0dea067f7a477ce54e4a3d4f8a9c3951..e43612673a15d00fbfbbee9005adbbd405f4b8b6 100644 (file)
@@ -1,33 +1,35 @@
-<h2>My settings</h2>
+<h2><%= t 'user.account.my settings' %></h2>
 <%= error_messages_for 'user' %>
 <% form_for :user, @user do |f| %>
 <table id="accountForm">
-  <tr><td class="fieldName">Display Name : </td><td><%= f.text_field :display_name %></td></tr>
-  <tr><td class="fieldName">Email : </td><td><%= f.text_field :email, {:size => 50, :maxlength => 255} %> <span class="minorNote">(never displayed publicly)</span></td></tr>
-  <tr><td class="fieldName" style="padding-bottom:0px;">Password : </td><td style="padding-bottom:0px;"><%= f.password_field :pass_crypt, {:value => '', :size => 30, :maxlength => 255} %></td></tr>
-  <tr><td class="fieldName">Confirm Password : </td><td><%= f.password_field :pass_crypt_confirmation, {:value => '', :size => 30, :maxlength => 255} %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.display name' %></td><td><%= f.text_field :display_name %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.email address' %></td><td><%= f.text_field :email, {:size => 50, :maxlength => 255} %> <span class="minorNote"><%= t 'user.account.email never displayed publicly' %></span></td></tr>
+  <tr><td class="fieldName" style="padding-bottom:0px;"><%= t 'user.new.password' %></td><td style="padding-bottom:0px;"><%= f.password_field :pass_crypt, {:value => '', :size => 30, :maxlength => 255} %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.confirm password' %></td><td><%= f.password_field :pass_crypt_confirmation, {:value => '', :size => 30, :maxlength => 255} %></td></tr>
 
   <tr>
-  <td class="fieldName" valign="top">Public editing :</td>
+  <td class="fieldName" valign="top"><%= t 'user.account.public editing.heading' %></td>
   <td>
 <% if @user.data_public? %>
-  Enabled. Not anonymous <span class="minorNote">(<a href="http://wiki.openstreetmap.org/index.php/Disabling_anonymous_edits" target="_new">what's this?</a>)</span>
+  <%= t 'user.account.public editing.enabled' %> <span class="minorNote">(<a href="<%= t 'user.account.public editing.enabled link' %>" target="_new"><%= t 'user.account.public editing.enabled link text' %></a>)</span>
 <% else %>
-  Disabled and anonymous. <span class="minorNote">(<a href="#public">why's this bad?</a>)</span>
+  <%= t 'user.account.public editing.disabled' %><span class="minorNote">(<a href="#public"><%= t 'user.account.public editing.disabled link text' %></a>)</span>
 <% end %>
   </td>
   </tr>
 
-  <tr><td class="fieldName" valign="top">Profile Description : </td><td><%= f.text_area :description, :rows => '5', :cols => '60' %><br /><br /></td></tr>
+  <tr><td class="fieldName" valign="top"><%= t 'user.account.profile description' %></td><td><%= f.text_area :description, :rows => '5', :cols => '60' %></td></tr>
 
-  <tr id="homerow" <% unless @user.home_lat and @user.home_lon %> class="nohome" <%end%> ><td class="fieldName">Home Location : </td><td><em class="message">You have not entered your home location.</em><span class="location">Latitude: <%= f.text_field :home_lat, :size => 20, :id => "home_lat" %> Longitude <%= f.text_field :home_lon, :size => 20, :id => "home_lon" %></span></td></tr>
+  <tr><td class="fieldName" valign="top"><%= t 'user.account.preferred languages' %></td><td><%= f.text_field :languages %></td></tr>
+
+  <tr id="homerow" <% unless @user.home_lat and @user.home_lon %> class="nohome" <%end%> ><td class="fieldName"><%= t 'user.account.home location' %></td><td><em class="message"><%= t 'user.account.no home location' %></em><span class="location"><%= t 'user.account.latitude' %> <%= f.text_field :home_lat, :size => 20, :id => "home_lat" %><%= t 'user.account.longitude' %><%= f.text_field :home_lon, :size => 20, :id => "home_lon" %></span></td></tr>
 
   <tr><td></td><td>
-  <p>Update home location when I click on the map? <input type="checkbox" value="1" <% unless @user.home_lat and @user.home_lon %> checked="checked" <% end %> id="updatehome" /> </p>
+  <p><%= t 'user.account.update home location on click' %> <input type="checkbox" value="1" <% unless @user.home_lat and @user.home_lon %> checked="checked" <% end %> id="updatehome" /> </p>
   <div id="map" style="border:1px solid black; position:relative; width:500px; height:400px;"></div>
   </td></tr>
   
-  <tr><td></td><td align=right><br/></br><%= submit_tag 'Save Changes' %></td></tr>
+  <tr><td></td><td align=right><br/></br><%= submit_tag t('user.account.save changes button') %></td></tr>
 </table>
 <br/>
 
   Your email address will not be revealed by becoming public.<br />
   This action cannot be reversed and all new users are now public by default.<br />
   <br /><br />
-  <%= button_to "Make all my edits public", :action => :go_public %>
+  <%= button_to t('user.account.make all my edits public button'), :action => :go_public %>
 <% end %>
 <br/>
 <br/>
-<%= link_to 'return to profile', :controller => 'user', :action => @user.display_name %>
+<%= link_to t('user.account.return to profile'), :controller => 'user', :action => @user.display_name %>
 <br/>
 <br/>
index 7953ff8222eaf2837ee9b2cd646b1adf8c09a574..5a4106ee395d441efd59b6463f30d9e40a6e42ea 100644 (file)
@@ -1,10 +1,10 @@
-<h1>Confirm a user account</h1>
+<h1><%= t 'user.confirm.heading' %></h1>
 
-<p>Press the confirm button below to activate your account.</p>
+<p><%= t 'user.confirm.press confirm button' %></p>
 
 <form method="post">
 <input type="hidden" name="confirm_string" value="<%= params[:confirm_string] %>">
-<input type="submit" name="confirm_action" value="Confirm">
+<input type="submit" name="confirm_action" value="<%= t 'user.confirm.button' %>">
 </form>
 
 
index 4be2b19bab8c52209b002be7fd64a2128b2d8b75..154dbb7c278f225ce37b30218401461b725ed85e 100644 (file)
@@ -1,8 +1,8 @@
-<h1>Confirm a change of email address</h1>
+<h1><%= t 'user.confirm email.heading' %></h1>
 
-<p>Press the confirm button below to confirm your new email address.</p>
+<p><%= t 'user.confirm email. press confirm button' %></p>
 
 <form method="post">
 <input type="hidden" name="confirm_string" value="<%= params[:confirm_string] %>">
-<input type="submit" name="confirm_action" value="Confirm">
+<input type="submit" name="confirm_action" value="<%= t 'user.confirm email.button' %>">
 </form>
index 0422d213258f76539b5a15c24228b3e50a576a58..dc10011172a41a32598bff8a36852667ed3d3065 100644 (file)
@@ -1,13 +1,13 @@
-<h1>Login</h1>
+<h1><%= t 'user.login.heading' %></h1>
 
-<p>Please login or <%= link_to 'create an account', :controller => 'user', :action => 'new' %>.</p>
+<p><%= t 'user.login.please login', :create_user_link => link_to(t('user.login.create_account'), :controller => 'user', :action => 'new') %></p>
 
 <% form_tag :action => 'login' do %>
 <%= hidden_field_tag('referer', h(params[:referer])) %>
 <table>
-  <tr><td class="fieldName">Email Address or Username:</td><td><%= text_field('user', 'email',{:size => 50, :maxlength => 255, :tabindex => 1}) %></td></tr>
-  <tr><td class="fieldName">Password:</td><td><%= password_field('user', 'password',{:size => 28, :maxlength => 255, :tabindex => 2}) %> <span class="minorNote">(<%= link_to 'Lost your password?', :controller => 'user', :action => 'lost_password' %>)</span></td></tr>
+  <tr><td class="fieldName"><%= t 'user.login.email or username' %></td><td><%= text_field('user', 'email',{:size => 50, :maxlength => 255, :tabindex => 1}) %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.login.password' %></td><td><%= password_field('user', 'password',{:size => 28, :maxlength => 255, :tabindex => 2}) %> <span class="minorNote">(<%= link_to t('user.login.lost password link'), :controller => 'user', :action => 'lost_password' %>)</span></td></tr>
   <tr><td colspan=2>&nbsp;<!--vertical spacer--></td></tr>
-  <tr><td></td><td align="right"><%= submit_tag 'Login', :tabindex => 3 %></td></tr>
+  <tr><td></td><td align="right"><%= submit_tag t('user.login.login_button'), :tabindex => 3 %></td></tr>
 </table>
 <% end %>
index fa1bc57e2a79fa1ba972cd6ec210aed8e1580c90..cb844c67c23eed85da8092a647b8a02d506ef634 100644 (file)
@@ -1,9 +1,9 @@
-<h1>Forgotten Password?</h1><br>
+<h1><%= t 'user.lost_password.heading' %></h1><br>
 
 <% form_tag :action => 'lost_password' do %>
 <table>
-  <tr><td>Email Address:</td><td><%= text_field('user', 'email', {:size => 50, :maxlength => 255} ) %></td></tr>
+  <tr><td><%= t 'user.lost_password.email address' %></td><td><%= text_field('user', 'email', {:size => 50, :maxlength => 255} ) %></td></tr>
 </table>
 <br>
-<input type="submit" value="Send me a new password">
+<input type="submit" value="<%= t 'user.lost_password.new password button' %>">
 <% end %>
index 8b40a2920b7a9c098713588ef2de8046cf9505ea..6ac85560d3720b78fef0829d49c1574502b4c6fd 100644 (file)
@@ -1,44 +1,36 @@
-<h1>Create a User Account</h1>
+<h1><%= t 'user.new.heading' %></h1>
 
 <% if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"}) %>
 
-<p>Unfortunately we are not currently able to create an account for
-   you automatically.
+<p><%= t 'user.new.no_auto_account_create' %>
 </p>
 
-<p>Please contact the <a href="mailto:webmaster@openstreetmap.org">webmaster</a>
-   to arrange for an account to be created - we will try and deal with
-   the request as quickly as possible. 
+<p><%= t 'user.new.contact_webmaster' %>
 </p>
 
 <% else %>
 
-<p>Fill in the form and we'll send you a quick email to activate your
-   account.
+<p><%= t 'user.new.fill_form' %>
 </p>
 
-<p>By creating an account, you agree that all work uploaded to
-   openstreetmap.org and all data created by use of any tools which
-   connect to openstreetmap.org is to be (non-exclusively) licensed under
-   <a href="http://creativecommons.org/licenses/by-sa/2.0/">this Creative
-   Commons license (by-sa)</a>.
+<p><%= t 'user.new.license_agreement' %>
 </p>
 
 <%= error_messages_for 'user' %>
 
 <% form_tag :action => 'save' do %>
 <table id="loginForm">
-  <tr><td class="fieldName">Email Address : </td><td><%= text_field('user', 'email',{:size => 50, :maxlength => 255, :tabindex => 1}) %></td></tr>
-  <tr><td class="fieldName">Confirm Email Address : </td><td><%= text_field('user', 'email_confirmation',{:size => 50, :maxlength => 255, :tabindex => 2}) %></td></tr>
-  <tr><td></td><td><span class="minorNote">Not displayed publicly (see <a href="http://wiki.openstreetmap.org/index.php/Privacy_Policy" title="wiki privacy policy including section on email addresses">privacy policy</a>)</span></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.email address' %></td><td><%= text_field('user', 'email',{:size => 50, :maxlength => 255, :tabindex => 1}) %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.confirm email address' %></td><td><%= text_field('user', 'email_confirmation',{:size => 50, :maxlength => 255, :tabindex => 2}) %></td></tr>
+  <tr><td></td><td><span class="minorNote"><%= t 'user.new.not displayed publicly' %></span></td></tr>
   <tr><td colspan=2>&nbsp;<!--vertical spacer--></td></tr>
-  <tr><td class="fieldName">Display Name : </td><td><%= text_field('user', 'display_name',{:size => 30, :maxlength => 255, :tabindex => 3}) %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.display name' %></td><td><%= text_field('user', 'display_name',{:size => 30, :maxlength => 255, :tabindex => 3}) %></td></tr>
   <tr><td colspan=2>&nbsp;<!--vertical spacer--></td></tr>
-  <tr><td class="fieldName">Password : </td><td><%= password_field('user', 'pass_crypt',{:size => 30, :maxlength => 255, :tabindex => 4}) %></td></tr>
-  <tr><td class="fieldName">Confirm Password : </td><td><%= password_field('user', 'pass_crypt_confirmation',{:size => 30, :maxlength => 255, :tabindex => 5}) %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.password' %></td><td><%= password_field('user', 'pass_crypt',{:size => 30, :maxlength => 255, :tabindex => 4}) %></td></tr>
+  <tr><td class="fieldName"><%= t 'user.new.confirm password' %></td><td><%= password_field('user', 'pass_crypt_confirmation',{:size => 30, :maxlength => 255, :tabindex => 5}) %></td></tr>
   
   <tr><td colspan=2>&nbsp;<!--vertical spacer--></td></tr>
-  <tr><td></td><td align=right><input type="submit" value="Signup" tabindex="6"></td></tr>
+  <tr><td></td><td align=right><input type="submit" value="<%= t'user.new.signup' %>" tabindex="6"></td></tr>
 </table>
 <% end %>
 
index 7820b4847c6d260a232005a0eda5bcda52a2a930..f510daffaada97e64a309074a43421db45b049e3 100644 (file)
@@ -1,2 +1,2 @@
 <h2><%= h(@not_found_user) %></h2>
-<p>Sorry, there is no user with the name <%= @not_found_user -%>. Please check your spelling, or maybe the link you clicked is wrong.</p>
+<p><%= t 'user.no_such_user.body', :user => @not_found_user %></p>
index c76ca23ae620055bdbe1db9aca8569bfaf371468..5096306431635eb333757622c896c1285142197c 100644 (file)
@@ -1,66 +1,65 @@
-<% @this_user = User.find_by_display_name(@this_user.display_name) %>
 <h2><%= h(@this_user.display_name) %></h2>
 <div id="userinformation">
 <% if @user and @this_user.id == @user.id %>
 <!-- Displaying user's own profile page -->
-<%= link_to 'my diary', :controller => 'diary_entry', :action => 'list', :display_name => @user.display_name %>
-| <%= link_to 'new diary entry', :controller => 'diary_entry', :action => 'new', :display_name => @user.display_name %>
-| <%= link_to 'my edits', :controller => 'changeset', :action => 'list_user', :display_name => @user.display_name %>
-| <%= link_to 'my traces', :controller => 'trace', :action=>'mine' %>
-| <%= link_to 'my settings', :controller => 'user', :action => 'account', :display_name => @user.display_name %>
+<%= link_to t('user.view.my diary'), :controller => 'diary_entry', :action => 'list', :display_name => @user.display_name %>
+| <%= link_to t('user.view.new diary entry'), :controller => 'diary_entry', :action => 'new', :display_name => @user.display_name %>
+| <%= link_to t('user.view.my edits'), :controller => 'changeset', :action => 'list_user', :display_name => @user.display_name %>
+| <%= link_to t('user.view.my traces'), :controller => 'trace', :action=>'mine' %>
+| <%= link_to t('user.view.my settings'), :controller => 'user', :action => 'account', :display_name => @user.display_name %>
 <% else %>
 <!-- Displaying another user's profile page -->
-<%= link_to 'send message', :controller => 'message', :action => 'new', :user_id => @this_user.id %>
-| <%= link_to 'diary', :controller => 'diary_entry', :action => 'list', :display_name => @this_user.display_name %>
-| <%= link_to 'edits', :controller => 'changeset', :action => 'list_user', :display_name => @this_user.display_name %>
-| <%= link_to 'traces', :controller => 'trace', :action => 'view', :display_name => @this_user.display_name %>
+<%= link_to t('user.view.send message'), :controller => 'message', :action => 'new', :user_id => @this_user.id %>
+| <%= link_to t('user.view.diary'), :controller => 'diary_entry', :action => 'list', :display_name => @this_user.display_name %>
+| <%= link_to t('user.view.edits'), :controller => 'changeset', :action => 'list_user', :display_name => @this_user.display_name %>
+| <%= link_to t('user.view.traces'), :controller => 'trace', :action => 'view', :display_name => @this_user.display_name %>
 | <% if @user and @user.is_friends_with?(@this_user) %>
-  <%= link_to 'remove as friend', :controller => 'user', :action => 'remove_friend', :display_name => @this_user.display_name %>
+  <%= link_to t('user.view.remove as friend'), :controller => 'user', :action => 'remove_friend', :display_name => @this_user.display_name %>
 <% else %>
-  <%= link_to 'add as friend', :controller => 'user', :action => 'make_friend', :display_name => @this_user.display_name %>
+  <%= link_to t('user.view.add as friend'), :controller => 'user', :action => 'make_friend', :display_name => @this_user.display_name %>
 <% end %>
 <% end %>
 </div>
 
 <% if @this_user != nil %>
 <P>
-<b>Mapper since : </b><%= @this_user.creation_time %> (<%= time_ago_in_words(@this_user.creation_time) %> ago)
+<b><%= t 'user.view.mapper since' %></b><%= l @this_user.creation_time %> <%= t 'user.view.ago', :time_in_words_ago => time_ago_in_words(@this_user.creation_time) %>
 </P>
 <% end %>
   
-<h3>User image</h3>
+<h3><%= t 'user.view.user image heading' %></h3>
 <% if @this_user.image %>
   <%= image_tag url_for_file_column(@this_user, "image") %>
   <% if @user and @this_user.id == @user.id %>
-    <%= button_to 'Delete Image', :action => 'delete_image' %>
+    <%= button_to t('user.view.delete image'), :action => 'delete_image' %>
   <% end %>
 <% end %>
 <br />
 
 <% if @user and @this_user.id == @user.id %>
-  Upload an image<br />
+  <%= t 'user.view.upload an image' %><br />
   <%= form_tag({:action=>'upload_image'}, :multipart => true)%>
     <%= file_column_field 'user', 'image' %>
-    <%= submit_tag 'Add Image' %>
+    <%= submit_tag t('user.view.add image') %>
   </form>
 <% end %>
 
-<h3>Description</h3>
+<h3><%= t 'user.view.description' %></h3>
 <div id="description"><%= htmlize(@this_user.description) %></div>
 
 <% if @this_user.home_lat.nil? or @this_user.home_lon.nil? %>
-<h3>User location</h3>
+<h3><%= t 'user.view.user location' %></h3>
 
-  No home location has been set.
+  <%= t 'user.view.no home location' %>
   <% if @user and @this_user.id == @user.id %>
-  If you set your location, a pretty map and stuff will appear below. You can set your home location on your <%= link_to 'settings', :controller => 'user', :action => 'account', :display_name => @user.display_name %> page.
+  <%= t 'user.view.if set location', :settings_link => (link_to t('user.view.settings_link_text'), :controller => 'user', :action => 'account', :display_name => @user.display_name) %>
   <% end %>
 <% else %>
 
   <% if @user and @this_user.id == @user.id %>
-    <h3>Your friends</h3>
+    <h3><%= t 'user.view.your friends' %></h3>
     <% if @this_user.friends.empty? %>
-      You have not added any friends yet.
+      <%= t 'user.view.no friends' %>
     <% else %>
       <table id="friends">
       <% @this_user.friends.each do |friend| %>
@@ -72,8 +71,8 @@
       <% end %>
       </td>
       <td class="username"><%= link_to h(@friend.display_name), :controller => 'user', :action => 'view',  :display_name => @friend.display_name %></td>
-      <td><% if @friend.home_lon and @friend.home_lat %><%= @this_user.distance(@friend).round %>km away<% end %></td>
-      <td class="message">(<%= link_to 'send message', :controller => 'message', :action => 'new', :user_id => @friend.id %>)</td>
+      <td><% if @friend.home_lon and @friend.home_lat %><%= t 'user.view.km away', :distance => l(@this_user.distance(@friend).round) %><% end %></td>
+      <td class="message">(<%= link_to t('user.view.send message'), :controller => 'message', :action => 'new', :user_id => @friend.id %>)</td>
       </tr>
       <%end%>
       </table>
@@ -83,9 +82,9 @@
 
 
   <% if @user and @this_user.id == @user.id %>
-    <h3>Nearby users:</h3>
+    <h3><%= t 'user.view.nearby users' %></h3>
     <% if @this_user.nearby.empty? %>
-      There are no users who admit to mapping nearby yet.
+      <%= t 'user.view.no nearby users' %>
     <% else %>
 
     <div id="map" style="border: 1px solid black; position: relative; width : 90%; height : 400px;"></div>
@@ -94,8 +93,8 @@
       <% @this_user.nearby.each do |nearby| %>
       <tr>
       <td class="username"><%= link_to h(nearby.display_name), :controller => 'user', :action => 'view',  :display_name => nearby.display_name %></td>
-      <td><%= @this_user.distance(nearby).round %>km away</td>
-      <td class="message">(<%= link_to 'send message', :controller => 'message', :action => 'new', :user_id => nearby.id %>)</td>
+      <td><%= t 'user.view.no nearby users', :distance => l(@this_user.distance(nearby).round) %></td>
+      <td class="message">(<%= link_to t('user.view.send message'), :controller => 'message', :action => 'new', :user_id => nearby.id %>)</td>
       </tr>
       <% end %>
       </table>
 <br/>
 <br/>
 <% if @user and @this_user.id == @user.id %>
-<%= link_to 'change your settings', :controller => 'user', :action => 'account', :display_name => @user.display_name %>
+<%= link_to t('user.view.change your settings'), :controller => 'user', :action => 'account', :display_name => @user.display_name %>
 <% end %>
index db6c1b9b7bcff789595643063f35ede3941521a3..37510ac27890195411eca82643333c2552da7563 100644 (file)
@@ -14,3 +14,25 @@ module Net
     end
   end
 end
+
+# Monkey patch to allow sending of messages in specific locales
+module ActionMailer
+  class Base
+    adv_attr_accessor :locale
+  private
+    alias_method :old_render_message, :render_message
+
+    def render_message(method_name, body)
+      old_locale= I18n.locale
+
+      begin
+        I18n.locale = @locale
+        message = old_render_message(method_name, body)
+      ensure
+        I18n.locale = old_locale
+      end
+
+      message
+    end
+  end
+end
diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb
new file mode 100644 (file)
index 0000000..54a925e
--- /dev/null
@@ -0,0 +1,4 @@
+require 'globalize/i18n/missing_translations_log_handler'
+
+I18n.missing_translations_logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log")
+I18n.exception_handler = :missing_translations_log_handler
diff --git a/config/locales/de.yml b/config/locales/de.yml
new file mode 100644 (file)
index 0000000..ffe18a7
--- /dev/null
@@ -0,0 +1,271 @@
+de:\r
+  map:\r
+    view: Karte\r
+    edit: Bearbeiten\r
+    coordinates: "Koordinaten:"\r
+  browse:\r
+    changeset:\r
+      changeset: "Changeset:"\r
+      download: "Download {{changeset_xml_link}} oder {{osmchange_xml_link}}"\r
+      changesetxml: "Changeset XML"\r
+      osmchangexml: "osmChange XML"\r
+    changeset_details:\r
+      created_at: "Erstellt am:"\r
+      closed_at: "Geschlossen am:"\r
+      belongs_to: "Erstellt von:"\r
+      bounding_box: "Zeichen-Box:"\r
+      no_bounding_box: "Es wurde keine Zeichen-Box für dieses Changeset gespeichert."\r
+      show_area_box: "Zeige Gebiet"\r
+      box: "Box"\r
+      has_nodes: "Enthält folgende {{node_count}} Knoten:"\r
+      has_ways: "Enthält folgende {{way_count}} Wege:"\r
+      has_relations: "Enthält folgende {{relation_count}} Relationen:"\r
+    common_details: \r
+      edited_at: "Bearbeitet am:"\r
+      edited_by: "Bearbeitet von:"\r
+      version: "Version:"\r
+      in_changeset: "In Changeset:"\r
+    containing_relation:\r
+      relation: "Relation {{relation_name}}"\r
+      relation_as: "(als {{relation_role}})"\r
+    map:\r
+      loading: "Lädt..."\r
+      deleted: "Gelöscht"\r
+      view_larger_map: "Größere Karte"\r
+    node_details:\r
+      part_of: "Teil von:"\r
+    node_history:\r
+      node_history: "Knoten Vergangenheit"\r
+      download: "{{download_xml_link}} oder {{view_details_link}}"\r
+      download_xml: "Download XML"\r
+      view_details: "Details"\r
+    node:\r
+      node: "Knoten"\r
+      node_title: "Knoten: {{node_name}}"\r
+      download: "{{download_xml_link}} oder {{view_history_link}}"\r
+      download_xml: "Download XML"\r
+      view_history: "Verlauf"\r
+    not_found:\r
+      sorry: "Sorry, das {{type}} mit der Nummer {{id}} konnte nicht gefunden werden."\r
+    paging_nav:\r
+      showing_page: "Zeige Seite"\r
+      of: "von"\r
+    relation_details:\r
+      members: "Mitglieder:"\r
+      part_of: "Teil von:"\r
+    relation_history:\r
+      relation_history: "Relation Vergangenheit"\r
+      relation_history_title: "Relation Vergangenheit: {{relation_name}}"\r
+    relation_member:\r
+      as: "als"\r
+    relation:\r
+      relation: "Relation"\r
+      relation_title: "Relation: {{relation_name}}"\r
+      download: "{{download_xml_link}} oder {{view_history_link}}"\r
+      download_xml: "Download XML"\r
+      view_history: "Vergangenheit"\r
+    start:\r
+      view_data: "Daten des aktuellen Kartenausschnittes"\r
+      manually_select: "Manuell einen anderen Kartenausschnitt auswählen"\r
+    start_rjs:\r
+      data_frame_title: "Daten"\r
+      zoom_or_select: "Zoom in or select an area of the map to view"\r
+      drag_a_box: "Drag a box on the map to select an area"\r
+      manually_select: "Manuell einen anderen Kartenausschnitt auswählen"\r
+      loaded_an_area: "You have loaded an area which contains"\r
+      browsers: "features. In general, some browsers may not cope well with displaying this quanity of data. Generally, browsers work best at displaying less than 100 features at a time: doing anything else may make your browser slow/unresponsive. If you are sure you want to display this data, you may do so by clicking the button below."\r
+      load_data: "Lade Daten"\r
+      unable_to_load: "Unable to load: Bounding box size of"\r
+      must_be_smaller: "is too large (must be smaller than 0.25)"\r
+      loading: "Loading..."\r
+      show_history: "Vergangenheit"\r
+      wait: "Warten..."\r
+      history_for: "Vergangenheit für"\r
+      details: "Details"\r
+      private_user: "private user"\r
+      edited_by: "Bearbeitet von"\r
+      at_timestamp: "at"\r
+  diary_entry:\r
+    list:\r
+      new: Neuer Tagebucheintrag\r
+      new_title: Verfasse einen neuen Tagebucheintrag\r
+      no_entries: Keine Tagebucheinträge\r
+      recent_entries: "Letzte Tagebucheinträge: "\r
+      older_entries: Ältere Einträge\r
+      newer_entries: Neuere Einträge\r
+    edit:\r
+      subject: "Betreff: "\r
+      body: "Text: "\r
+      language: "Sprache: "\r
+      location: "Ort: "\r
+      latitude: "Breitengrad: "\r
+      longitude: "Längengrad: "\r
+      use_map_link: "Karte nutzen"\r
+      save_button: "Speichern"\r
+      marker_text: Ort des Tagebucheintrages\r
+    no_such_entry:\r
+      heading: "Kein Eintrag mit der Nummer: {{id}}"\r
+      body: "Leider gibt es keinen Eintrag oder Kommentar mit dieser Nummer {{id}}. Bitte überprüfe deine Schreibweise oder der Link war beschädigt."\r
+    no_such_user:\r
+      body: "Es gibt leider keinen Benutzer mit dem Namen {{user}}. Bitte überprüfe deine Schreibweise oder der Link war beschädigt."\r
+    posted_by: "Verfasst von {{link_user}} am {{created}} in {{language}}"\r
+    comment_link: Kommentar zu diesem Eintrag\r
+    reply_link: Antworte auf diesen Eintrag\r
+    comment_count:\r
+      one: 1 Kommentar\r
+      other: "{{count}} Kommentare"\r
+    edit_link: Bearbeite diesen Eintrag\r
+    comment_from: "Kommentar von {{link_user}}  um {{comment_created_at}}"\r
+  layouts:\r
+    welcome_user: "Willkommen, {{user_link}}"\r
+    inbox: "Posteingang ({{size}})"\r
+    logout: Abmelden\r
+    log_in: Anmelden\r
+    sign_up: Registrieren\r
+    view: Karte\r
+    edit: Bearbeiten\r
+    history: Verlauf\r
+    export: Export\r
+    gps_traces: GPS Tracks\r
+    user_diaries: Benutzer Tagebücher\r
+    tag_line: Die freie Wiki-Weltkarte\r
+    intro_1: "OpenStreetMap ist eine freie, editierbare Karte der gesamten Welt, die von Menschen wie dir erstellt wird." \r
+    intro_2: "OpenStreetMap ermöglicht es geographische Daten gemeinschaftlich von überall auf der Welt anzuschauen und zu bearbeiten."\r
+    intro_3: "Das Hosting der OpenStreetMap-Server wird freundlicherweise von  {{ucl}} und {{bytemark}} unterstützt."\r
+    osm_offline: "Die OpenStreetMap Datenbank ist im Moment wegen wichtiger Wartungsarbeiten nicht verfügbar."\r
+    osm_read_only: 'Die OpenStreetMap Datenbank ist im Moment wegen wichtiger Wartungsarbeiten im "Nur-Lesen-Modus".'\r
+    donate: "Unterstütze OpenStreetMap mit einer {{link}} für die Hardware Spendenaktion."\r
+    donate_link_text: Spende\r
+    sotm: 'Komme zur OpenStreetMap Konferenz 2009, <a href="http://www.stateofthemap.org">The State of the Map</a>, am 10.-12. Juli in Amsterdam!'\r
+    alt_donation: Spenden\r
+  notifier:\r
+    diary:\r
+      banner1: "*               Bitte antworte nicht auf diese E-Mail.               *"\r
+      banner2: "*          Verwende stattdessen die OpenStreetMap Website zum Antworten.         *"\r
+  site:\r
+    index:\r
+      js_1: "Dein Browser unterstützt kein Javascript oder du hast es deaktiviert."\r
+      js_2: "OpenStreetMap nutzt Javascript für die Kartendarstellung."\r
+      js_3: 'Du kannst den <a href="http://tah.openstreetmap.org/Browse/">Tiles@Home static tile browser</a> nutzen, wenn du kein Javascript nutzen kannst.'\r
+      permalink: Permalink\r
+      license: "Lizenziert unter Creative Commons Attribution-Share Alike 2.0 Lizenz durch das OpenStreetMap Projekt und seine Mitwirkenden."\r
+    edit:\r
+      not_public: "Deine Einstellungen sind auf anonymes Bearbeiten gestellt."\r
+      not_public_description: "Du musst deine Einstellungen auf öffentliches Bearbeiten umstellen. Dies kannst du auf deiner Benutzerseite tun {{user_page}}."\r
+      user_page_link: Benutzerseite\r
+      anon_edits: "({{link}})"\r
+      anon_edits_link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"\r
+      anon_edits_link_text: "Hier findest du mehr Infos dazu."\r
+      flash_player_required: 'Du benötigst den Flash Player um Potlatch, den OpenStreetMap Flash Editor zu benutzen. <a href="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">Lade den Flash Player von Adobe.com herunter</a>. <a href="http://wiki.openstreetmap.org/wiki/DE:Editing">Einige andere Möglichkeiten</a>, um OpenStreetMap zu editieren, sind hier beschrieben.'\r
+      potlatch_unsaved_changes: "Du hast deine Arbeit noch nicht gespeichert. (Um sie in Potlach zu speichern, klicke auf eine leere Fläche bzw. deselektiere den Weg oder Punkt, wenn du im Live Modus editierst, oder klicke auf Speichern, wenn ein Speicherbutton vorhanden ist.)"\r
+    sidebar:\r
+      search_results: Suchergebnisse\r
+      close: Schließen\r
+    search:\r
+      search: Suchen\r
+      where_am_i: "Wo bin ich?"\r
+      submit_text: "Los"\r
+      searching: "Sucht..."\r
+      search_help: "Beispiele: 'München', 'Heinestraße, Würzburg', 'CB2 5AQ', or 'post offices near Lünen' <a href='http://wiki.openstreetmap.org/wiki/Search'>mehr Beispiele...</a>"\r
+    key:\r
+      map_key: "Legende"\r
+  user:\r
+    login:\r
+      heading: Anmelden\r
+      please login: "Bitte melde dich an oder {{create_user_link}}."\r
+      create_account: erstelle ein Benutzerkonto\r
+      email or username: "E-Mail-Adresse oder Benutzername: "\r
+      password: "Passwort: "\r
+      lost password link: "Passwort vergessen?"\r
+      login_button: Anmelden\r
+    lost_password:\r
+      title: Passwort verloren\r
+      heading: "Passwort vergessen?"\r
+      email address: "E-Mail-Adresse:"\r
+      new password button: "Sende mir ein neues Passwort"\r
+      notice email on way: "Ärgerlich, dass du es verloren hast :-( aber eine E-Mail ist schon auf dem Weg, so dass du es bald zurücksetzen kannst."\r
+      notice email cannot find: "Konnte diese E-Mail-Adresse leider nicht finden."\r
+    reset_password:\r
+      title: Passwort zurücksetzen\r
+      flash changed check mail: "Dein Passwort wurde geändert und ist auf dem Weg in deinen E-Mail-Posteingang :-)"\r
+      flash token bad: "Konnte das Kürzel nicht finden, überprüfe bitte die URL?"\r
+    new:\r
+      heading: Erstelle ein Benutzerkonto\r
+      no_auto_account_create: "Leider ist das automatische Erstellen eines Benutzerkontos gerade nicht möglich."\r
+      contact_webmaster: 'Bitte kontaktiere den <a href="mailto:webmaster@openstreetmap.org">Webmaster</a> um ein Benutzerkonto erstellt zu bekommen - wir werden die Anfrage so schnell wie möglich bearbeiten. '\r
+      fill_form: "Fülle das Formular aus und dir wird eine kurze E-Mail zur Aktivierung deines Accounts geschickt."\r
+      license_agreement: 'Mit der Accounterstellung stimmst du zu, dass alle Daten, die du zu openstreetmap.org hochlädst und alle Daten, die du mit irgendeinem externem Programm, dass sich mit openstreetmap.org verbindet, erstellst, (nicht exklusiv) unter <a href="http://creativecommons.org/licenses/by-sa/2.0/">dieser Creative Commons Lizenz (by-sa)</a> lizenziert werden.'\r
+      email address: "E-Mail-Adresse: "\r
+      confirm email address: "Bestätige deine E-Mail-Adresse: "\r
+      not displayed publicly: 'Nicht öffentlich sichtbar (<a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="wiki privacy policy including section on email addresses">Datenschutzrichtlinie</a>)'\r
+      display name: "Benutzername: "\r
+      password: "Passwort: "\r
+      confirm password: "Passwort bestätigen: "\r
+      signup: Registieren\r
+      flash create success message: "Benutzer wurde erfolgreich erstellt. Ein Bestätigungscode wurde dier per E-Mail zugesendet, bitte bestätige diesen und du kannst mit dem Mappen beginnen<br /><br />Du kannst dich nicht einloggen bevor du deine E-Mail-Adresse mit dem Bestätigungscode bestätigt hast.<br /><br />Falls du ein Antispam System nutzt, dass Bestätigungsanfragen sendet, dann setze bitte webmaster@openstreetmap.org auf deine Whitelist, weil wir auf keine Bestätigungsanfrage antworten können."\r
+    no_such_user:\r
+      body: "Es gibt leider keinen Benutzer mit dem Namen {{user}}. Bitte überprüfe deine Schreibweise oder der Link war beschädigt."\r
+    view:\r
+      my diary: Mein Tagebuch\r
+      new diary entry: neuer Tagebucheintrag\r
+      my edits: Meine Bearbeitungen\r
+      my traces: Meine Tracks\r
+      my settings: Meine Einstellungen\r
+      send message: Sende Nachricht\r
+      diary: Tagebuch\r
+      edits: Bearbeitungen\r
+      traces: Tracks\r
+      remove as friend: Als Freund entfernen\r
+      add as friend: Als Freund hinzufügen\r
+      mapper since: "Mapper seit: "\r
+      user image heading: Benutzerbild\r
+      delete image: Lösche Bild\r
+      upload an image: Lade ein Bild hoch\r
+      add image: Füge ein Bild hinzu\r
+      description: Beschreibung\r
+      user location: Standort des Benutzers\r
+      no home location: "Es wurde kein Standort angegeben."\r
+      if set location: "Wenn du deinen Standort angegeben hast, erscheint eine Karte am Seitenende. Du kannst deinen Standort in deinen {{settings_link}} ändern."\r
+      settings_link_text: Einstellungen\r
+      your friends: Deine Freunde\r
+      no friends: Du hast bis jetzt keine Freunde hinzugefügt.\r
+      km away: "{{distance}}km entfernt"\r
+      nearby users: "Benutzer in der Nähe: "\r
+      no nearby users: "Es gibt bisher keine Benutzer, die einen Standort in deiner Nähe angegeben haben."\r
+      change your settings: Ändere deine Einstellungen\r
+    friend_map:\r
+      your location: Dein Standort\r
+      nearby mapper: "Mapper in der Nähe: "\r
+    account:\r
+      my settings: Meine Einstellungen\r
+      email never displayed publicly: "(nicht öffentlich sichtbar)"\r
+      public editing:\r
+        heading: "Öffentliches Bearbeiten: "\r
+        enabled: "Aktiviert. Nicht anonym, bearbeiten der Kartendaten möglich."\r
+        enabled link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"\r
+        enabled link text: "Was ist das?"\r
+        disabled: "Deaktiviert, bearbeiten von Daten nicht möglich, alle bisherigen Bearbeitungen sind anonym."\r
+        disabled link text: "Warum kann ich nichts bearbeiten?"\r
+      profile description: "Profil Beschreibung: "\r
+      home location: "Standort: "\r
+      no home location: "Du hast noch keinen Standort angegeben."\r
+      latitude: "Breitengrad: "\r
+      longitude: "Längengrad: "\r
+      update home location on click: "Standort bei Klick auf die Karte aktualisieren?"\r
+      save changes button: Speichere Änderungen\r
+      make edits public button: Mache alle meine Bearbeitungen öffentlich\r
+      return to profile: Zurück zum Profil\r
+      flash update success confirm needed: "Benutzerinformationen erfolgreich aktualisiert. Du erzählst eine E-Mail, um deine neue E-Mail-Adresse zu bestätigen."\r
+      flash update success: "Benutzerinformationen erfolgreich aktualisiert."\r
+    confirm:\r
+      heading: Bestätige das Benutzerkonto\r
+      press confirm button: "Aktiviere dein Account, indem du auf den Bestätigungsbutton klickst."\r
+      button: Bestätigen\r
+    confirm email:\r
+      heading: Bestätige die Änderung der E-Mail-Adresse\r
+      press confirm button: "Bestätige deine neue E-Mail-Adresse, indem du auf den Bestätigungsbutton klickst."\r
+      button: Bestätigen\r
+    set_home:\r
+      flash success: "Standort erfolgreich gespeichert"\r
+    go_public:\r
+      flash success: "Alle deine Bearbeitungen sind nun öffentlich und du kannst nun die Kartendaten bearbeiten."\r
diff --git a/config/locales/en.yml b/config/locales/en.yml
new file mode 100644 (file)
index 0000000..7b6b07b
--- /dev/null
@@ -0,0 +1,507 @@
+en:
+  map:
+    view: View
+    edit: Edit
+    coordinates: "Coordinates:"
+  browse:
+    changeset:
+      title: "Changeset"
+      changeset: "Changeset:"
+      download: "Download {{changeset_xml_link}} or {{osmchange_xml_link}}"
+      changesetxml: "Changeset XML"
+      osmchangexml: "osmChange XML"
+    changeset_details:
+      created_at: "Created at:"
+      closed_at: "Closed at:"
+      belongs_to: "Belongs to:"
+      bounding_box: "Bounding box:"
+      no_bounding_box: "No bounding box has been stored for this changeset."
+      show_area_box: "Show Area Box"
+      box: "box"
+      has_nodes: "Has the following {{node_count}} nodes:"
+      has_ways: "Has the following {{way_count}} ways:"
+      has_relations: "Has the following {{relation_count}} relations:"
+    common_details: 
+      edited_at: "Edited at:"
+      edited_by: "Edited by:"
+      version: "Version:"
+      in_changeset: "In changeset:"
+    containing_relation:
+      relation: "Relation {{relation_name}}"
+      relation_as: "(as {{relation_role}})"
+    map:
+      loading: "Loading..."
+      deleted: "Deleted"
+      view_larger_map: "View Larger Map"
+    node_details:
+      coordinates: "Coordinates: "
+      part_of: "Part of:"
+    node_history:
+      node_history: "Node History"
+      download: "{{download_xml_link}} or {{view_details_link}}"
+      download_xml: "Download XML"
+      view_details: "view details"
+    node:
+      node: "Node"
+      node_title: "Node: {{node_name}}"
+      download: "{{download_xml_link}} or {{view_history_link}}"
+      download_xml: "Download XML"
+      view_history: "view history"
+    not_found:
+      sorry: "Sorry, the {{type}} with the id {{id}}, could not be found."
+    paging_nav:
+      showing_page: "Showing page"
+      of: "of"
+    relation_details:
+      members: "Members:"
+      part_of: "Part of:"
+    relation_history:
+      relation_history: "Relation History"
+      relation_history_title: "Relation History: {{relation_name}}"
+    relation_member:
+      as: "as"
+    relation:
+      relation: "Relation"
+      relation_title: "Relation: {{relation_name}}"
+      download: "{{download_xml_link}} or {{view_history_link}}"
+      download_xml: "Download XML"
+      view_history: "view history"
+    start:
+      view_data: "View data for current map view"
+      manually_select: "Manually select a different area"
+    start_rjs:
+      data_frame_title: "Data"
+      zoom_or_select: "Zoom in or select an area of the map to view"
+      drag_a_box: "Drag a box on the map to select an area"
+      manually_select: "Manually select a different area"
+      loaded_an_area: "You have loaded an area which contains"
+      browsers: "features. In general, some browsers may not cope well with displaying this quanity of data. Generally, browsers work best at displaying less than 100 features at a time: doing anything else may make your browser slow/unresponsive. If you are sure you want to display this data, you may do so by clicking the button below."
+      load_data: "Load Data"
+      unable_to_load: "Unable to load: Bounding box size of"
+      must_be_smaller: "is too large (must be smaller than 0.25)"
+      loading: "Loading..."
+      show_history: "Show History"
+      wait: "Wait..."
+      history_for: "History for"
+      details: "Details"
+      private_user: "private user"
+      edited_by: "Edited by"
+      at_timestamp: "at"
+    tag_details:
+      tags: "Tags:"
+    way_details:
+      nodes: "Nodes:"
+      part_of: "Part of:"
+    way_history:
+      way_history: "Way History"
+      way_history_title: "Way History: {{way_name}}"
+      download: "{{download_xml_link}} or {{view_details_link}}"
+      download_xml: "Download XML"
+      view_details: "view details"
+    way:
+      way: "Way"
+      way_title: "Way: {{way_name}}"
+      download: "{{download_xml_link}} or {{view_history_link}}"
+      download_xml: "Download XML"
+      view_history: "view history"
+  changeset:
+    changeset_paging_nav: 
+      showing_page: "Showing page"
+      of: "of"
+    changeset:
+      still_editing: "(still editing)"
+      anonymous: "Anonymous"
+      no_comment: "(none)"
+      no_edits: "(no edits)"
+      show_area_box: "show area box"
+      big_area: "(big)"
+      view_changeset_details: "View changeset details"
+      more: "more"
+    changesets:
+      id: "ID"
+      saved_at: "Saved at"
+      user: "User"
+      comment: "Comment"
+      area: "Area"
+    list_bbox:
+      history: "History"
+      changesets_within_the_area: "Changesets within the area:"
+      show_area_box: "show area box"
+      no_changesets: "No changesets"
+      all_changes_everywhere: "For all changes everywhere see {{recent_changes_link}}"
+      recent_changes: "Recent Changes"
+      no_area_specified: "No area specified"
+      first_use_view: "First use the {{view_tab_link}} to pan and zoom to an area of interest, then click the history tab."
+      view_the_map: "view the map"
+      view_tab: "view tab"
+      alternatively_view: "Alternatively, view all {{recent_changes_link}}"
+    list:
+      recent_changes: "Recent Changes"
+      recently_edited_changesets: "Recently edited changesets:"
+      for_more_changesets: "For more changesets, select a user and view their edits, or see the editing 'history' of a specific area."
+    list_user:
+      edits_by_username: "Edits by {{username_link}}"
+      no_visible_edits_by: "No visible edits by {{name}}."
+      for_all_changes: "For changes by all users see {{recent_changes_link}}"
+      recent_changes: "Recent Changes"
+  diary_entry:
+    list:
+      title: "Users' diaries"
+      new: New Diary Entry
+      new_title: Compose a new entry in your user diary
+      no_entries: No diary entries
+      recent_entries: "Recent diary entries: "
+      older_entries: Older Entries
+      newer_entries: Newer Entries
+    edit:
+      title: "Edit diary entry"
+      subject: "Subject: "
+      body: "Body: "
+      language: "Language: "
+      location: "Location: "
+      latitude: "Latitude: "
+      longitude: "Longitude: "
+      use_map_link: "use map"
+      save_button: "Save"
+      marker_text: Diary entry location
+    no_such_entry:
+      heading: "No entry with the id: {{id}}"
+      body: "Sorry, there is no diary entry or comment with the id {{id}}. Please check your spelling, or maybe the link you clicked is wrong."
+    no_such_user:
+      body: "Sorry, there is no user with the name {{user}}. Please check your spelling, or maybe the link you clicked is wrong."
+    posted_by: "Posted by {{link_user}} at {{created}} in {{language}}"
+    comment_link: Comment on this entry
+    reply_link: Reply to this entry
+    comment_count:
+      one: 1 comment
+      other: "{{count}} comments"
+    edit_link: Edit this entry
+    comment_from: "Comment from {{link_user}}  at {{comment_created_at}}"
+  export:
+    start:
+      area_to_export: "Area to Export"
+      manually_select: "Manually select a different area"
+      format_to_export: "Format to Export"
+      osm_xml_data: "OpenStreetMap XML Data"
+      mapnik_image: "Mapnik Image"
+      osmarender_image: "Osmarender Image"
+      embeddable_html: "Embeddable HTML"
+      licence: "Licence"
+      export_details: 'OpenStreetMap data is licensed under the <a href="http://creativecommons.org/licenses/by-sa/2.0/">Creative Commons Attribution-ShareAlike 2.0 license</a>.'
+      options: "Options"
+      format: "Format"
+      scale: "Scale"
+      max: "max"
+      image_size: "Image Size"
+      zoom: "Zoom"
+      add_marker: "Add a marker to the map"
+      latitude: "Lat:"
+      longitude: "Lon:"
+      output: "Output"
+      paste_html: "Paste HTML to embed in website"
+      export_button: "Export"
+    start_rjs:
+      export: "Export"
+      drag_a_box: "Drag a box on the map to select an area"
+      manually_select: "Manually select a different area"
+      click_add_marker: "Click on the map to add a marker"
+      change_marker: "Change marker position"
+      add_marker: "Add a marker to the map"
+      view_larger_map: "View Larger Map"
+  geocoder:
+    results:
+      results: "Results"
+      type_from_source: "{{type}} from {{source_link}}"
+      no_results: "No results found"
+  layouts:
+    welcome_user: "Welcome, {{user_link}}"
+    inbox: "inbox ({{size}})"
+    logout: logout
+    log_in: log in
+    sign_up: sign up
+    view: View
+    edit: Edit
+    history: History
+    export: Export
+    gps_traces: GPS Traces
+    user_diaries: User Diaries
+    tag_line: The Free Wiki World Map
+    intro_1: "OpenStreetMap is a free editable map of the whole world. It is made by people like you."
+    intro_2: "OpenStreetMap allows you to view, edit and use geographical data in a collaborative way from anywhere on Earth."
+    intro_3: "OpenStreetMap's hosting is kindly supported by the {{ucl}} and {{bytemark}}."
+    osm_offline: "The OpenStreetMap database is currently offline while essential database maintenance work is carried out."
+    osm_read_only: "The OpenStreetMap database is currently in read-only mode while essential database maintenance work is carried out."
+    donate: "Support OpenStreetMap by {{link}} to the Hardware Upgrade Fund."
+    donate_link_text: donating
+    help_wiki: "Help &amp; Wiki"
+    news_blog: "News blog"
+    shop: Shop
+    sotm: 'Come to the 2009 OpenStreetMap Conference, The State of the Map, July 10-12 in Amsterdam!'
+    alt_donation: Make a Donation
+  notifier:
+    diary:
+      banner1: "*                   Please do not reply to this email.                    *"
+      banner2: "*                Use the OpenStreetMap web site to reply.                 *"
+      hi: "Hi {{to_user}},"
+      header: "{{from_user}} has commented on your recent OpenStreetMap diary entry with the subject {{subject}}:"
+      footer: "You can also read the comment at {{readurl}} and you can comment at {{commenturl}} or reply at {{replyurl}}"
+    signup_confirm_plain:
+      greeting: "Hi there!"
+      hopefully_you: "Someone (hopefully you) would like to create an account over at"
+      # next two translations run-on : please word wrap appropriately
+      click_the_link_1: "If this is you, welcome! Please click the link below to confirm your"
+      click_the_link_2: "account and read on for more information about OpenStreetMap."
+      introductory_video: "You can watch an introductory video to OpenStreetMap here:"
+      more_videos: "There are more videos here:"
+      the_wiki: "Get reading about OpenStreetMap on the wiki:"
+      opengeodata: "OpenGeoData.org is OpenStreetMap's blog, and it has podcasts too:"
+      wiki_signup: "You may also want to sign up to the OpenStreetMap wiki at:"
+      # next four translations are in pairs : please word wrap appropriately
+      user_wiki_1: "It is recommended that you create a user wiki page, which includes"
+      user_wiki_2: "category tags noting where you are, such as [[Category:Users_in_London]]."
+      current_user_1: "A list of current users in categories, based on where in the world"
+      current_user_2: "they are, is available from:"
+    signup_confirm_html:
+      greeting: "Hi there!"
+      hopefully_you: "Someone (hopefully you) would like to create an account over at"
+      click_the_link: "If this is you, welcome! Please click the link below to confirm that account and read on for more information about OpenStreetMap"
+      introductory_video: "You can watch an {{introductory_video_link}}."
+      video_to_openstreetmap: "introductory video to OpenStreetMap"
+      more_videos: "There are {{more_videos_link}}."
+      more_videos_here: "more videos here"
+      get_reading: 'Get reading about OpenStreetMap <a href="http://wiki.openstreetmap.org/wiki/Beginners%27_Guide">on the wiki</p> or  <a href="http://www.opengeodata.org/">the opengeodata blog</a> which has <a href="http://www.opengeodata.org/?cat=13">podcasts to listen to</a> also!'
+      wiki_signup: 'You may also want to <a href="http://wiki.openstreetmap.org/index.php?title=Special:Userlogin&type=signup&returnto=Main_Page">sign up to the OpenStreetMap wiki</a>.'
+      user_wiki_page: 'It is recommended that you create a user wiki page, which includes category tags noting where you are, such as <a href="http://wiki.openstreetmap.org/wiki/Category:Users_in_London">[[Category:Users_in_London]]</a>.'
+      current_user: 'A list of current users in categories, based on where in the world they are, is available from <a href="http://wiki.openstreetmap.org/wiki/Category:Users_by_geographical_region">Category:Users_by_geographical_region</a>.'
+  message:
+    inbox:
+      my_inbox: "My inbox"
+      outbox: "outbox"
+      you_have: "You have {{new_count}} new messages and {{old_count}} old messages"
+      from: "From"
+      subject: "Subject"
+      date: "Date"
+      no_messages_yet: "You have no messages yet. Why not get in touch with some of the {{people_mapping_nearby_link}}?"
+      people_mapping_nearby: "people mapping nearby" 
+    message_summary:
+      unread_button: "Mark as unread"
+      read_button: "Mark as read"
+      reply_button: "Reply"
+    new:
+      send_message_to: "Send a new message to {{name}}"
+      subject: "Subject"
+      body: "Body"
+      send_button: "Send"
+      back_to_inbox: "Back to inbox"
+    no_such_user:
+      no_such_user: "No such user or message"
+      sorry: "Sorry there is no user or message with that name or id"
+    outbox: 
+      my_inbox: "My {{inbox_link}}"
+      inbox: "inbox"
+      outbox: "outbox"
+      you_have_sent_messages: "You have {{sent_count}} sent messages"
+      to: "To"
+      subject: "Subject"
+      date: "Date"
+      no_sent_messages: "You have no sent messages yet. Why not get in touch with some of the {{people_mapping_nearby_link}}?"
+      people_mapping_nearby: "people mapping nearby"
+    read:
+      reading_your_messages: "Reading your messages"
+      from: "From"
+      subject: "Subject"
+      date: "Date"
+      reply_button: "Reply"
+      unread_button: "Mark as unread"
+      back_to_inbox: "Back to inbox"
+      reading_your_sent_messages: "Reading your sent messages"
+      to: "To"
+      back_to_outbox: "Back to outbox"
+  site:
+    index:
+      js_1: "You are either using a browser that doesn't support javascript, or you have disabled javascript."
+      js_2: "OpenStreetMap uses javascript for its slippy map."
+      js_3: 'You may want to try the <a href="http://tah.openstreetmap.org/Browse/">Tiles@Home static tile browser</a> if you are unable to enable javascript.'
+      permalink: Permalink
+      license: "Licensed under the Creative Commons Attribution-Share Alike 2.0 license by the OpenStreetMap project and its contributors."
+    edit:
+      not_public: "You haven't set your edits to be public."
+      not_public_description: "You can no longer edit the map unless you do so. You can set your edits as public from your {{user_page}}."
+      user_page_link: user page
+      anon_edits: "({{link}})"
+      anon_edits_link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"
+      anon_edits_link_text: "Find out why this is the case."
+      flash_player_required: 'You need a Flash player to use Potlatch, the OpenStreetMap Flash editor. You can <a href="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">download Flash Player from Adobe.com</a>. <a href="http://wiki.openstreetmap.org/wiki/Editing">Several other options</a> are also available for editing OpenStreetMap.'
+      potlatch_unsaved_changes: "You have unsaved changes. (To save in Potlatch, you should deselect the current way or point, if editing in list mode, or click save if you have a save button.)"
+    sidebar:
+      search_results: Search Results
+      close: Close
+    search:
+      search: Search
+      where_am_i: "Where am I?"
+      submit_text: "Go"
+      searching: "Searching..."
+      search_help: "examples: 'Alkmaar', 'Regent Street, Cambridge', 'CB2 5AQ', or 'post offices near Lünen' <a href='http://wiki.openstreetmap.org/wiki/Search'>more examples...</a>"
+    key:
+      map_key: "Map key"
+  trace:
+    create:
+      upload: "Upload GPS Trace"
+    edit:
+      filename: "Filename:"
+      uploaded_at: "Uploaded at:"
+      points: "Points:"
+      start_coord: "Start coordinate:"
+      edit: "edit"
+      owner: "Owner:"
+      description: "Description:"
+      tags: "Tags:"
+      save_button: "Save Changes"
+    no_such_user:
+      no_such_user: "Sorry, there is no user with the name {{name}}. Please check your spelling, or maybe the link you clicked is wrong."
+    trace_form:
+      upload_gpx: "Upload GPX File"
+      description: "Description"
+      tags: "Tags"
+      public: "Public?"
+      upload_button: "Upload"
+      help: "Help"
+    trace_header:
+      see_just_your_traces: "See just your traces, or upload a trace"
+      see_all_traces: "See all traces"
+      see_your_traces: "See all your traces"
+      traces_waiting: "You have {{count}} traces waiting for upload. Please consider waiting for these to finish before uploading any more, so as not to block the queue for other users."
+    trace_optionals:
+      tags: "Tags"
+    view:
+      pending: "PENDING"
+      filename: "Filename:"
+      download: "download"
+      uploaded: "Uploaded at:"
+      points: "Points:"
+      start_coordinates: "Start coordinate:"
+      map: "map"
+      edit: "edit"
+      owner: "Owner:"
+      description: "Description:"
+      tags: "Tags"
+      none: "None"
+      make_public: "Make this track public permanently"
+      edit_track: "Edit this track"
+      delete_track: "Delete this track"
+    trace_paging_nav:
+      showing: "Showing page"
+      of: "of"
+    trace:
+      pending: "PENDING"
+      more: "more"
+      trace_details: "View Trace Details"
+      view_map: "View Map"
+      edit: "edit"
+      edit_map: "Edit Map"
+      public: "PUBLIC"
+      pritate: "PRIVATE"
+      by: "by"
+      in: "in"
+  user:
+    login:
+      heading: "Login"
+      please login: "Please login or {{create_user_link}}."
+      create_account: "create an account"
+      email or username: "Email Address or Username: "
+      password: "Password: "
+      lost password link: "Lost your password?"
+      login_button: "Login"
+    lost_password:
+      title: "lost password"
+      heading: "Forgotten Password?"
+      email address: "Email Address:"
+      new password button: "Send me a new password"
+      notice email on way: "Sorry you lost it :-( but an email is on its way so you can reset it soon."
+      notice email cannot find: "Couldn't find that email address, sorry."
+    reset_password:
+      title: "reset password"
+      flash changed check mail: "Your password has been changed and is on its way to your mailbox :-)"
+      flash token bad: "Didn't find that token, check the URL maybe?"
+    new:
+      heading: "Create a User Account"
+      no_auto_account_create: "Unfortunately we are not currently able to create an account for you automatically."
+      contact_webmaster: 'Please contact the <a href="mailto:webmaster@openstreetmap.org">webmaster</a> to arrange for an account to be created - we will try and deal with the request as quickly as possible. '
+      fill_form: "Fill in the form and we'll send you a quick email to activate your account."
+      license_agreement: 'By creating an account, you agree that all work uploaded to openstreetmap.org and all data created by use of any tools which connect to openstreetmap.org is to be (non-exclusively) licensed under <a href="http://creativecommons.org/licenses/by-sa/2.0/">this Creative Commons license (by-sa)</a>.'
+      email address: "Email Address: "
+      confirm email address: "Confirm Email Address: "
+      not displayed publicly: 'Not displayed publicly (see <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="wiki privacy policy including section on email addresses">privacy policy</a>)'
+      display name: "Display Name: "
+      password: "Password: "
+      confirm password: "Confirm Password: "
+      signup: Signup
+      flash create success message: "User was successfully created. Check your email for a confirmation note, and you\'ll be mapping in no time :-)<br /><br />Please note that you won't be able to login until you've received and confirmed your email address.<br /><br />If you use an antispam system which sends confirmation requests then please make sure you whitelist webmaster@openstreetmap.org as we are unable to reply to any confirmation requests."
+    no_such_user:
+      body: "Sorry, there is no user with the name {{user}}. Please check your spelling, or maybe the link you clicked is wrong."
+    view:
+      my diary: my diary
+      new diary entry: new diary entry
+      my edits: my edits
+      my traces: my traces
+      my settings: my settings
+      send message: send message
+      diary: diary
+      edits: edits
+      traces: traces
+      remove as friend: remove as friend
+      add as friend: add as friend
+      mapper since: "Mapper since: "
+      ago: "({{time_in_words_ago}} ago)"
+      user image heading: User image
+      delete image: Delete Image
+      upload an image: Upload an image
+      add image: Add Image
+      description: Description
+      user location: User location
+      no home location: "No home location has been set."
+      if set location: "If you set your location, a pretty map and stuff will appear below. You can set your home location on your {{settings_link}} page."
+      settings_link_text: settings
+      your friends: Your friends
+      no friends: You have not added any friends yet.
+      km away: "{{distance}}km away"
+      nearby users: "Nearby users: "
+      no nearby users: "There are no users who admit to mapping nearby yet."
+      change your settings: change your settings
+    friend_map:
+      your location: Your location
+      nearby mapper: "Nearby mapper: "
+    account:
+      my settings: My settings
+      email never displayed publicly: "(never displayed publicly)"
+      public editing:
+        heading: "Public editing: "
+        enabled: "Enabled. Not anonymous and can edit data."
+        enabled link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"
+        enabled link text: "what's this?"
+        disabled: "Disabled and cannot edit data, all previous edits are anonymous."
+        disabled link text: "why can't I edit?"
+      profile description: "Profile Description: "
+      preferred languages: "Preferred Languages: "
+      home location: "Home Location: "
+      no home location: "You have not entered your home location."
+      latitude: "Latitude: "
+      longitude: "Longitude: "
+      update home location on click: "Update home location when I click on the map?"
+      save changes button: Save Changes
+      make edits public button: Make all my edits public
+      return to profile: Return to profile
+      flash update success confirm needed: "User information updated successfully. Check your email for a note to confirm your new email address."
+      flash update success: "User information updated successfully."
+    confirm:
+      heading: Confirm a user account
+      press confirm button: "Press the confirm button below to activate your account."
+      button: Confirm
+    confirm email:
+      heading: Confirm a change of email address
+      press confirm button: "Press the confirm button below to confirm your new email address."
+      button: Confirm
+    set_home:
+      flash success: "Home location saved successfully"
+    go_public:
+      flash success: "All your edits are now public, and you are now allowed to edit."
diff --git a/config/locales/es.yml b/config/locales/es.yml
new file mode 100644 (file)
index 0000000..b903bfa
--- /dev/null
@@ -0,0 +1,6 @@
+es:\r
+  notifier:\r
+    diary:\r
+      banner1: "*                 Por favor, no responda a este mensaje.                  *"\r
+      banner2: "*           Utilice el OpenStreetMap sitio web para responder.            *"\r
+\r
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
new file mode 100644 (file)
index 0000000..7e81f4e
--- /dev/null
@@ -0,0 +1,259 @@
+fr:
+  map:
+    view: "Voir"
+    edit: "Éditer"
+    coordinates: "Coordonnées"
+  browse:
+    changeset:
+      changeset: "Changeset:"
+      download: "Télécharger {{changeset_xml_link}} ou {{osmchange_xml_link}}"
+      changesetxml: "Changeset XML"
+      osmchangexml: "osmChange XML"
+    changeset_details:
+      created_at: "Créé le:"
+      closed_at: "Terminé le:"
+      belongs_to: "Appartient à:"
+      bounding_box: "Bounding box:"
+      no_bounding_box: "Aucune bounding box n'a été stockée pour ce changeset."
+      show_area_box: "Montrer la boite"
+      box: "boite"
+      has_nodes: "A les {{node_count}} points suivants:"
+      has_ways: "A les {{way_count}} ways suivants:"
+      has_relations: "A les {{relation_count}} relations suivantes:"
+    common_details:
+      edited_at: "Édité le:"
+      edited_by: "Édité par:"
+      version: "Version:"
+      in_changeset: "Dans le changeset:"
+    containing_relation:
+      relation: "Relation {{relation_name}}"
+      relation_as: "(en tant que {{relation_role}})"
+    map:
+      loading: "Chargement..."
+      deleted: "Effacé"
+      view_larger_map: "Agrandir la carte"
+    node_details:
+      part_of: "Faisant partie de:"
+    node_history:
+      node_history: "Historique des points"
+      download: "{{download_xml_link}} ou {{view_details_link}}"
+      download_xml: "Télécharger XML"
+      view_details: "voir détails"
+    node:
+      node: "Point"
+      node_title: "Point: {{node_name}}"
+      download: "{{download_xml_link}} ou {{view_history_link}}"
+      download_xml: "Télécharger XML"
+      view_history: "voir l'historique"
+    not_found:
+      sorry: "Désolé, le {{type}} avec l'id {{id}}, n'a pas pu être trouvé."
+    paging_nav:
+      showing_page: "Page en cours"
+      of: "de"
+    relation_details:
+      members: "Membres:"
+      part_of: "Faisant partie de:"
+    relation_history:
+      relation_history: "Historique des relations"
+      relation_history_title: "Historique des relations: {{relation_name}}"
+    start:
+      view_data: "Voir les données sur la carte actuelle"
+      manually_select: "Sélectionner manuellement une zone différente"
+    start_rjs:
+      data_frame_title: "Données"
+      zoom_or_select: "Zoomer ou sélectionner une zone de la carte pour la visualiser"
+      drag_a_box: "Dessiner une boite sur la carte pour sélectionner une zone"
+      manually_select: "Sélectionner manuellement une zone différente"
+      loaded_an_area: "Vous avez chargé une zone qui contient"
+      browsers: "un grand nombre d'éléments. En général, les navigateurs ne supportent pas bien l'affichage de tant de données, et travaillent mieux lorsqu'ils affichent moins de 100 éléments: accepter peut rendre votre navigateur lent ou non fonctionnel. Si vous etes sûr de vouloir afficher ces données, vous pouvez le faire en appuyant sur le bouton ci-dessous."
+      load_data: "Charger les données"
+      unable_to_load: "Impossible de charger les données: la Bounding box d'une taille de"
+      must_be_smaller: "est trop grande (elle doit être plus petite que 0.25)"
+      loading: "Chargement..."
+      show_history: "Montrer l'historique"
+      wait: "Patienter..."
+      history_for: "Historique pour"
+      details: "Détails"
+      private_user: "utilisateur privé"
+      edited_by: "Édité par"
+      at_timestamp: "le"
+  diary_entry:
+    list:
+      new: "Nouvelle entrée du journal"
+      new_title: "Ajouter une nouvelle entrée dans votre journal"
+      no_entries: "Aucune entrée dans votre journal"
+      recent_entries: "Entrées récentes:"
+      older_entries: "Entrées plus anciennes"
+      newer_entries: "Entrées plus récentes"
+    edit:
+      subject: "Sujet:"
+      body: "Message:"
+      language: "Langue:"
+      location: "Lieu:"
+      latitude: "Latitude:"
+      longitude: "Longitude:"
+      use_map_link: "Utiliser la carte"
+      save_button: "Sauvegarder"
+      marker_text: "Emplacement de l'entrée du journal"
+    no_such_entry:
+      heading: "Aucune entrée avec l'id: {{id}}"
+      body: "Desolé, il n'y a aucune entrée dans le journal ou commentaires avec l'id {{id}}. Veuillez vérifier l'orthographe, ou le lien que vous avez cliqué n'est pas valide."
+    no_such_user:
+      body: "Desolé, il n'y pas d'utilisateur avec le nom {{user}}. Veuillez vérifier l'orthographe, ou le lien que vous avez cliqué n'est pas valide."
+    posted_by: "Posté par {{link_user}} à {{created}} en {{language}}"
+    comment_link: "Commenter cette entrée"
+    reply_link: "Répondre a cette entrée"
+    comment_count:
+      one: "1 commentaire"
+      other: "{{count}} commentaires"
+    edit_link: "Éditer cette entrée"
+    comment_from: "Commentaire de {{link_user}} le {{comment_created_at}}"
+  layouts:
+    welcome_user: "Bienvenue, {{user_link}}"
+    inbox: "Boite aux lettres ({{size}})"
+    logout: "Déconnexion"
+    log_in: "Connexion"
+    sign_up: "S'inscrire"
+    view: "Voir"
+    edit: "Éditer"
+    history: "Historique"
+    export: "Exporter"
+    gps_traces: "Traces GPS"
+    user_diaries: "Journaux"
+    tag_line: La wiki carte du monde libre
+    intro_1: "OpenStreetMap est une carte du monde entier librement éditable, faite par des gens comme vous."
+    intro_2: "OpenStreetMap vous permet de voir, éditer et utiliser des données géographiques de n'importe quel endroit dans le monde."
+    intro_3: "OpenStreetMap est gracieusement hébergé par {{ucl}} et {{bytemark}}."
+    osm_offline: "La base de données de OpenStreetMap est actuellement hors ligne; une maintenance essentielle à son bon fonctionnement est en cours."
+    osm_read_only: "La base de données de OpenStreetMap est actuellement en mode lecture seule ; une maintenance essentielle à son bon fonctionnement est en cours."
+    donate: "Soutenez OpenStreetMap, {{link}} au fond pour améliorer le matériel."
+    donate_link_text: "participez"
+    help_wiki: "Aide &amp; Wiki"
+    news_blog: "Blog de nouvelles"
+    shop: "Boutique"
+    sotm: 'Venez a la conférence 2009 de OpenStreetMap, <a href="http://www.stateofthemap.org">The State of the Map</a>, 10-12 juillet à Amsterdam!'
+    alt_donation: "Faites une donation"
+  notifier:
+    diary:
+      banner1: "*            S’il vous plaît de ne pas répondre à ce message.             *"
+      banner2: "*           Utilisez le OpenStreetMap site Web pour y répondre.           *"
+  site:
+    index:
+      js_1: "Vous utilisez soit un navigateur qui ne supporte pas Javascript soit vous avez désactivé Javascript."
+      js_2: "OpenStreetMap utilise Javascript pour ses cartes glissantes."
+      js_3: "Si vous êtes dans l'incapacité d'utiliser Javascript, essayer d'utiliser le <a href='http://tah.openstreetmap.org/Browse/'>navigateur statique de Tiles@Home</a>."
+      permalink: "Permalink"
+      license: "Sous license Creative Commons Attribution-Share Alike 2.0 par le projet OpenStreetMap et ses contributeurs."
+    edit:
+      not_public: "Vous n'avez pas réglé vos éditions pour qu'elles soient publiques."
+      not_public_description: "Vous ne pouvez plus éditer la carte a moins que vous ne rendiez vos éditions publiques. Vous pouvez rendre vos éditions publiques à partir de votre {{user_page}}."
+      user_page_link: "page utilisateur"
+      anon_edits: "({{link}})"
+      anon_edits_link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"
+      anon_edits_link_text: "Trouvez pourquoi ici."
+      flash_player_required: "Vous avez besoin d''un lecteur Flash pour utiliser Potlatch, l'éditeur Flash de OpenStreetMap. Vous pouvez <a href='http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'>télécharger Flash Player sur le site d'Adobe</a>. <a href='http://wiki.openstreetmap.org/wiki/Editing'>D'autres options</a> sont également disponibles pour éditer OpenStreetMap."
+      potlatch_unsaved_changes: "Vous avez des modifications non sauvegardées. (Pour sauvegarder dans Potlatch, vous devez dé-sélectionner le way ou le node en cours si vous éditez en mode liste, ou cliquer sur sauvegarder si vous avez un bouton sauvegarder.)"
+    sidebar:
+      search_results: "Résultats de la recherche"
+      close: "Fermer"
+    search:
+      search: "Chercher"
+      where_am_i: "Où suis-je?"
+      submit_text: "Allez"
+      searching: "En cours de recherche..."
+      search_help: "exemples: 'Alkmaar', 'Regent Street, Cambridge', 'CB2 5AQ', ou 'bureaux de poste près de Lünen' <a href='http://wiki.openstreetmap.org/wiki/Search'>D'autres d'exemples...</a>"
+    key:
+      map_key: "Clé de la carte"
+  user:
+    login:
+      heading: "Connexion"
+      please login: "Veuillez vous connecter ou {{create_user_link}}."
+      create_account: "Créer un compte"
+      email or username: "Adresse e-mail ou nom d'utilisateur:"
+      password: "Mot de passe: "
+      lost password link: "Vous avez perdu votre mot de passe?"
+      login_button: "Se connecter"
+    lost_password:
+      heading: "Vous avez perdu votre mot de passe?"
+      email address: "Adresse e-mail:"
+      new password button: "Envoyer un nouveau mot de passe"
+    new:
+      heading: "Créer un compte utilisateur"
+      no_auto_account_create: "Malheureusement, nous sommes actuellement dans l'impossibilité de vous créer un compte automatiquement."
+      contact_webmaster: "Veuillez contacter le <a href='mailto:webmaster@openstreetmap.org'>webmaster</a> pour qu'il vous crée un compte - nous essaierons de traiter votre demande le plus rapidement possible."
+      fill_form: "Remplissez le formulaire et nous vous enverrons un e-mail pour activer votre compte."
+      license_agreement: "En créant un compte, vous acceptez que tout le travail envoyé sur Openstreetmap.org et toutes les données créées par l'utilisation d'outils qui se connectent à Openstreetmap.org soient sous la licence (non exclusive) <a href='http://creativecommons.org/licenses/by-sa/2.0/'>Creative Commons license (by-sa)</a>."
+      email address: "Adresse e-mail: "
+      confirm email address: "Confirmer l'adresse e-mail: "
+      not displayed publicly: 'Non affichée publiquement (voir <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="wiki privacy policy including section on email addresses">notre charte sur la confidentialité</a>)'
+      display name: "Nom affiché: "
+      password: "Mot de passe: "
+      confirm password: "Confirmer le Mot de passe: "
+      signup: "S'inscrire"
+      flash create success message: "L'utilisateur a été créé avec succès. Vérifier votre e-mail de confirmation, et vous serez prêt à mapper dans peu de temps :-)<br /><br />Veuillez noter que vous ne serez pas capable de vous connecter tant que vous n'aurez pas recu le mail de confirmation et confirmé votre e-mail. <br /><br />Si vous utilisez un logiciel anti-spam qui envoie des requêtes de confirmation, veuillez mettre dans votre liste blanche webmaster@openstreetmap.org car nous sommes incapables de répondre à ces e-mails."
+    no_such_user:
+      body: "Désolé, il n'y a pas d'utilisateur avec le nom {{user}}. Veuillez vérifier l'orthographe, ou le lien que vous avez cliqué n'est pas valide."
+    view:
+      my diary: "Mon journal"
+      new diary entry: "Nouvelle entrée dans le journal"
+      my edits: "Mes éditions"
+      my traces: "Mes traces"
+      my settings: "Mes options"
+      send message: "Envoyer un message"
+      diary: "journal"
+      edits: "éditions"
+      traces: "traces"
+      remove as friend: "enlever en tant qu'ami"
+      add as friend: "ajouter en tant qu'ami"
+      mapper since: "Mappeur depuis: "
+      user image heading: "Image utilisateur"
+      delete image: "Effacer l'image"
+      upload an image: "Envoyer une image"
+      add image: "Ajouter une image"
+      description: Description
+      user location: "Emplacement de l'utilisateur"
+      no home location: "Aucun lieu n'a été défini."
+      if set location: "Si vous définissez un lieu, une jolie carte va apparaître en dessous. Vous pouvez définir votre lieu sur votre page {{settings_link}}."
+      settings_link_text: "options"
+      your friends: "Vos amis"
+      no friends: "Vous n'avez pas encore ajouté d'ami"
+      km away: "{{distance}} km"
+      nearby users: "Utilisateurs proches: "
+      no nearby users: "Il n'y a pas encore d'utilisateur à proximité."
+      change your settings: "modifiez vos options"
+    friend_map:
+      your location: "Votre emplacement"
+      nearby mapper: "Mappeur dans les environs: "
+    account:
+      my settings: "Mes options"
+      email never displayed publicly: "(jamais affiché publiquement)"
+      public editing:
+        heading: "Édition publique: "
+        enabled: "Activé. Non anonyme et peut éditer les données."
+        enabled link: "http://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"
+        enabled link text: "qu'est-ce que c'est?"
+        disabled: "Désactivé et ne peut pas éditer les données; toutes les précédentes éditions sont anonymes."
+        disabled link text: "pourquoi ne puis-je pas éditer?"
+      profile description: "Description du profil: "
+      home location: "Emplacement du domicile: "
+      no home location: "Vous n'avez pas entré l'emplacement de votre domicile."
+      latitude: "Latitude: "
+      longitude: "Longitude: "
+      update home location on click: "Mettre a jour l'emplacement de votre domicile quand vous cliquez sur la carte?"
+      save changes button: "Sauvegarder les changements"
+      make edits public button: "Rendre toutes mes éditions publiques"
+      return to profile: "Retourner au profil"
+      flash update success confirm needed: "Informations sur l'utilisateur mises à jour avec succès. Vérifiez votre boite mail afin de valider la vérification de votre nouvelle adresse e-mail."
+      flash update success: "Informations sur l'utilisateur mises à jour avec succès."
+    confirm:
+      heading: "Confirmer un compte utilisateur"
+      press confirm button: "Appuyer le bouton confirmer ci-dessous pour activer votre compte."
+      button: "Confirmer"
+    confirm email:
+      heading: "Confirmer le changement de votre adresse e-mail"
+      press confirm button: "Appuyer sur le bouton confirmer pour confirmer votre nouvelle adresse e-mail."
+      button: "Confirmer"
+    set_home:
+      flash success: "Emplacement de mon domicile sauvegardé avec succès"
+    go_public:
+      flash success: "Tous vos éditions sont dorénavant publiques et vous n'êtes pas autorisé a éditer."
index f2d64471900dc3142beaa378240dce829ca8d4b5..4b11610122165f17fdd543272db0d6ed4bab6cea 100644 (file)
@@ -85,6 +85,7 @@ ActionController::Routing::Routes.draw do |map|
   map.connect '/browse/changesets', :controller => 'changeset', :action => 'list'
   
   # web site
+  map.root :controller => 'site', :action => 'index'
   map.connect '/', :controller => 'site', :action => 'index'
   map.connect '/edit', :controller => 'site', :action => 'edit'
   map.connect '/history', :controller => 'changeset', :action => 'list_bbox'
diff --git a/db/migrate/035_change_user_locale.rb b/db/migrate/035_change_user_locale.rb
new file mode 100644 (file)
index 0000000..7dc8054
--- /dev/null
@@ -0,0 +1,15 @@
+require 'lib/migrate'
+
+class ChangeUserLocale < ActiveRecord::Migration
+  def self.up
+    remove_foreign_key :users, [:locale], :languages, [:code]
+
+    rename_column :users, :locale, :languages
+  end
+
+  def self.down
+    rename_column :users, :languages, :locale
+
+    add_foreign_key :users, [:locale], :languages, [:code]
+  end
+end
index 05b3c90f24da86a9cf541ec9cf60c7e90c9c7520..50ba6321dc24ffea9e7388137433f1b370e51f4c 100644 (file)
@@ -21,6 +21,11 @@ module ActiveRecord
          "REFERENCES #{reftbl} (#{quote_column_names(refcol || column_name)})"
       end
 
+      def remove_foreign_key(table_name, column_name, reftbl, refcol = nil)
+        execute "ALTER TABLE #{table_name} DROP " +
+          "CONSTRAINT #{table_name}_#{column_name[0]}_fkey"
+      end
+
       alias_method :old_options_include_default?, :options_include_default?
 
       def options_include_default?(options)
index f68d7023a6ab3ab148cce911156f69daa3fb7311..fec13e2965ebabbd7722a0692ee8657c2e88577e 100644 (file)
@@ -1,13 +1,15 @@
 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
 
-one:
-  min_lat: 
-  max_lat: 
-  min_lon: 
-  max_lon: 
+gb:
+  code: gb
+  min_lat: 49.9061889648438
+  max_lat: 60.8458099365234
+  min_lon: -8.62355613708496
+  max_lon: 1.75900018215179
 
-two:
-  min_lat: 
-  max_lat: 
-  min_lon: 
-  max_lon: 
+de:
+  code: de
+  min_lat: 47.2757720947266
+  max_lat: 55.0556411743164
+  min_lon: 5.865638256073
+  max_lon: 15.0398902893066
index 3d089b94ffe1b18cbe636430211cac9ac30bb3c3..34fb552687e33d3ec4d3254393f14412a16aae9d 100644 (file)
@@ -7,7 +7,7 @@ normal_user_entry_1:
   updated_at: "2008-11-07 17:43:34"
   latitude: 
   longitude: 
-  language: en
+  language_code: en
   
 normal_user_geo_entry:
   id: 2
@@ -18,4 +18,4 @@ normal_user_geo_entry:
   updated_at: "2008-11-07 17:47:34"
   latitude: 51.50763
   longitude: -0.10781
-  language: de
+  language_code: de
index 10fb908e84505b9299d5b8fb7b2e3622be6ae253..6189df30290431a9d35d3e28cc15cdfe6a4d2f5b 100644 (file)
@@ -72,6 +72,7 @@ class DiaryEntryControllerTest < ActionController::TestCase
           assert_select "form[action='/diary_entry/#{diary_entries(:normal_user_entry_1).id}/edit'][method=post]", :count => 1 do
             assert_select "input#diary_entry_title[name='diary_entry[title]'][value='#{diary_entries(:normal_user_entry_1).title}']", :count => 1
             assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => diary_entries(:normal_user_entry_1).body, :count => 1
+            assert_select "select#diary_entry_language_code", :count => 1
             assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1
             assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1
             assert_select "input[name=commit][type=submit][value=Save]", :count => 1
@@ -86,8 +87,10 @@ class DiaryEntryControllerTest < ActionController::TestCase
     new_body = "This is a new body for the diary entry"
     new_latitude = "1.1"
     new_longitude = "2.2"
+    new_language_code = "en"
     post(:edit, {:id => diary_entries(:normal_user_entry_1).id, 'commit' => 'save', 
-      'diary_entry'=>{'title' => new_title, 'body' => new_body, 'latitude' => new_latitude, 'longitude' => new_longitude} },
+      'diary_entry'=>{'title' => new_title, 'body' => new_body, 'latitude' => new_latitude,
+      'longitude' => new_longitude, 'language_code' => new_language_code} },
          {'user' => users(:normal_user).id})
     assert_response :redirect
     assert_redirected_to :action => :view, :id => diary_entries(:normal_user_entry_1).id
@@ -142,21 +145,51 @@ class DiaryEntryControllerTest < ActionController::TestCase
     
   end
   
-  def test_editing_creating_diary_comment
+  def test_edit_diary_entry_i18n
+    I18n.available_locales.each do |locale|
+      set_locale locale
+      
+      get(:edit, {:id => diary_entries(:normal_user_entry_1).id}, {'user' => users(:normal_user).id})
+      assert_response :success
+      assert_select "span[class=translation_missing]", false, "Missing translation in edit diary entry"
+    end
+  end
+  
+  def test_create_diary_entry
+    #post :new
+  end
+  
+  def test_creating_diary_comment
     
   end
   
+  # Check that you can get the expected response and template for all available languages
+  # Should test that there are no <span class="translation_missing">
   def test_listing_diary_entries
+    I18n.available_locales.each do |locale|
+      set_locale locale
+      
+      get :list
+      assert_response :success, "Should be able to list the diary entries in #{locale}"
+      assert_template 'list', "Should use the list template in #{locale}"
+      assert_select "span[class=translation_missing]", false, "Missing translation in list of diary entries"
     
+      # Now try to find a specific user's diary entry
+      get :list, {:display_name => users(:normal_user).display_name}
+      assert_response :success, "Should be able to list the diary entries for a user in #{locale}"
+      assert_template 'list', "Should use the list template for a user in #{locale}"
+      assert_select "span[class=translation_missing]", false, "Missing translation in list of diary entries for user"
+    end
   end
   
   def test_rss
     get :rss
-    assert :success
-    
+    assert_response :success
   end
   
   def test_viewing_diary_entry
-    
+    get :view, {:display_name => users(:normal_user).display_name, :id => diary_entries(:normal_user_entry_1).id}
+    assert_response :success
+    assert_template 'view'
   end
 end
index 5dd319e02a05e1d1a40391b40f18f8b62b8febfc..95b6e7e6766ba669c6451c5da9e5397d765651fe 100644 (file)
@@ -123,6 +123,10 @@ class Test::Unit::TestCase
     @request.env["RAW_POST_DATA"] = c.to_s
   end
   
+  def set_locale(l)
+    @request.env["HTTP_ACCEPT_LANGUAGE"] = l.to_s
+  end
+  
   # Used to check that the error header and the forbidden responses are given
   # when the owner of the changset has their data not marked as public
   def assert_require_public_data(msg = "Shouldn't be able to use API when the user's data is not public")
index 2adc9477389709e017752a40ad145ed34cc77441..84bb2c4a18bb71aff1c411d0fc40f623c9d2067e 100644 (file)
@@ -1,8 +1,9 @@
-require 'test_helper'
+require File.dirname(__FILE__) + '/../test_helper'
 
 class CountryTest < ActiveSupport::TestCase
-  # Replace this with your real tests.
-  test "the truth" do
-    assert true
+  fixtures :countries
+  
+  test "country count" do
+    assert_equal 2, Country.count
   end
 end
index e28e03a105704fb6092ac4fdc79691cda1a7bd58..b28577b992263bd9395d5c245fae423f5a501d31 100644 (file)
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test_helper'
 
 class DiaryEntryTest < Test::Unit::TestCase
   api_fixtures
-  fixtures :diary_entries
+  fixtures :diary_entries, :languages
   
   def test_diary_entry_count
     assert_equal 2, DiaryEntry.count
@@ -27,7 +27,7 @@ class DiaryEntryTest < Test::Unit::TestCase
   def diary_entry_valid(attrs, result = true)
     entry = diary_entries(:normal_user_entry_1).clone
     entry.attributes = attrs
-    assert_equal result, entry.valid?
+    assert_equal result, entry.valid?, "Expected #{attrs.inspect} to be #{result}"
   end
   
 end
diff --git a/vendor/plugins/globalize2/.gitignore b/vendor/plugins/globalize2/.gitignore
new file mode 100644 (file)
index 0000000..24f36d5
--- /dev/null
@@ -0,0 +1,4 @@
+doc
+spec/spec/db/*
+vendor
+NOTES
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/LICENSE b/vendor/plugins/globalize2/LICENSE
new file mode 100644 (file)
index 0000000..94a6b81
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2008, 2009 Joshua Harvey
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/README.textile b/vendor/plugins/globalize2/README.textile
new file mode 100644 (file)
index 0000000..dbd7288
--- /dev/null
@@ -0,0 +1,202 @@
+h1. Globalize2
+
+Globalize2 is the successor of Globalize for Rails. 
+
+It is compatible with and builds on the new "I18n api in Ruby on Rails":http://rails-i18n.org. and adds model translations as well as a bunch of other useful features, such as Locale fallbacks (RFC4647 compliant) and automatic loading of Locale data from defined directory/file locations.
+
+Globalize2 is much more lightweight and modular than its predecessor was. Content translations in Globalize2 use default ActiveRecord features and do not limit any functionality any more. 
+
+All features and tools in Globalize2 are implemented in the most unobstrusive and loosely-coupled way possible, so you can pick whatever features or tools you need for your application and combine them with other tools from other libraries or plugins.
+
+h2. Requirements
+
+Rails 2.2 (currently Rails edge)
+
+h2. Installation
+
+To install Globalize2 with its default setup just use:
+
+<pre><code>
+script/plugin install git://github.com/joshmh/globalize2.git
+</code></pre>
+
+This will:
+
+* activate model translations
+* set I18n.load_path to an instance of Globalize::LoadPath
+* set I18n.backend to an instance of Globalize::Backend::Static
+
+h2. Configuration
+
+You might want to add additional configuration to an initializer, e.g. config/initializers/globalize.rb
+
+h2. Model translations
+
+Model translations (or content translations) allow you to translate your models' attribute values. E.g.
+
+<pre><code>
+class Post < ActiveRecord::Base
+  translates :title, :text
+end
+</code></pre>
+
+Allows you to values for the attributes :title and :text per locale:
+
+<pre><code>
+I18n.locale = :en
+post.title # Globalize2 rocks!
+
+I18n.locale = :he
+post.title # גלובאלייז2 שולט!
+</code></pre>
+
+In order to make this work, you'll need to add the appropriate translation tables. Globalize2 comes with a handy helper method to help you do this. It's called @create_translation_table!@. Here's an example:
+
+<pre><code>
+class CreatePosts < ActiveRecord::Migration
+  def self.up
+    create_table :posts do |t|
+      t.timestamps
+    end
+    Post.create_translation_table! :title => :string, :text => :text
+  end
+  def self.down
+    drop_table :posts
+    Post.drop_translation_table!
+  end
+end
+</code></pre>
+
+Note that the ActiveRecord model @Post@ must already exist and have a @translates@ directive listing the translated fields.
+
+h2. Globalize::Backend::Static
+
+Globalize2 ships with a Static backend that builds on the Simple backend from the I18n library (which is shipped with Rails) and adds the following features:
+
+* It uses locale fallbacks when looking up translation data.
+* It returns an instance of Globalize::Translation::Static instead of a plain Ruby String as a translation.
+* It allows to hook in custom pluralization logic as lambdas.
+
+h2. Custom pluralization logic
+
+The Simple backend has its pluralization algorithm baked in hardcoded. This algorithm is only suitable for English and other languages that have the same pluralization rules. It is not suitable for, e.g., Czech though.
+
+To add custom pluralization logic to Globalize' Static backend you can do something like this:
+
+<pre><code>
+@backend.add_pluralizer :cz, lambda{|c| 
+  c == 1 ? :one : (2..4).include?(c) ? :few : :other 
+}
+</code></pre>
+
+h2. Locale Fallbacks
+
+Globalize2 ships with a Locale fallback tool which extends the I18n module to hold a fallbacks instance which is set to an instance of Globalize::Locale::Fallbacks by default but can be swapped with a different implementation. 
+
+Globalize2 fallbacks will compute a number of other locales for a given locale. For example:
+
+<pre><code>
+I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :"en-US", :en]
+</code></pre>
+
+Globalize2 fallbacks always fall back to 
+
+* all parents of a given locale (e.g. :es for :"es-MX"), 
+* then to the fallbacks' default locales and all of their parents and 
+* finally to the :root locale. 
+
+The default locales are set to [:"en-US"] by default but can be set to something else. The root locale is a concept borrowed from "CLDR":http://unicode.org and makes sense for storing common locale data which works as a last default fallback (e.g. "ltr" for bidi directions).
+
+One can additionally add any number of additional fallback locales manually. These will be added before the default locales to the fallback chain. For example:
+
+<pre><code>
+fb = I18n.fallbacks
+
+fb.map :ca => :"es-ES"
+fb[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]
+
+fb.map :"ar-PS" => :"he-IL"
+fb[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]
+fb[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]
+
+fb.map :sms => [:"se-FI", :"fi-FI"]
+fb[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]
+</code></pre>
+
+h2. Globalize::LoadPath
+
+Globalize2 replaces the plain Ruby array that is set to I18n.load_path by default through an instance of Globalize::LoadPath.
+
+This object can be populated with both paths to files and directories. If a path to a directory is added to it it will look up all locale data files present in that directory enforcing the following convention:
+
+<pre><code>
+I18n.load_path << "#{RAILS_ROOT}/lib/locales"
+
+# will load all the following files if present:
+lib/locales/all.yml
+lib/locales/fr.yml
+lib/locales/fr/*.yaml
+lib/locales/ru.yml
+lib/locales/ru/*.yaml
+...
+</code></pre>
+
+One can also specify which locales are used. By default this is set to "*" meaning that files for all locales are added. To define that only files for the locale :es are added one can specify:
+
+<pre><code>
+I18n.load_path.locales = [:es]
+</code></pre>
+
+One can also specify which file extensions are used. By default this is set to ['rb', 'yml'] so plain Ruby and YAML files are added if found. To define that only *.sql files are added one can specify:
+
+<pre><code>
+I18n.load_path.extensions = ['sql']
+</code></pre>
+
+Note that Globalize::LoadPath "expands" a directory to its contained file paths immediately when you add it to the load_path. Thus, if you change the locales or extensions settings in the middle of your application the change won't be applied to already added file paths.
+
+
+h2. Globalize::Translation classes
+
+Globalize2's Static backend as well as Globalize2 model translations return instances of Globalize::Translation classes (instead of plain Ruby Strings). These are simple and lightweight value objects that carry some additional meta data about the translation and how it was looked up.
+
+Model translations return instances of Globalize::Translation::Attribute, the Static backend returns instances of Globalize::Translation::Static.
+
+For example:
+
+<pre><code>
+I18n.locale = :de
+
+# Translation::Attribute
+title = Post.first.title  # assuming that no translation can be found:
+title.locale              # => :en
+title.requested_locale    # => :de 
+title.fallback?           # => true
+
+# Translation::Static
+rails = I18n.t :rails     # assuming that no translation can be found:
+rails.locale              # => :en
+rails.requested_locale    # => :de 
+rails.fallback?           # => true
+rails.options             # returns the options passed to #t
+rails.plural_key          # returns the plural_key (e.g. :one, :other)
+rails.original            # returns the original translation with no values 
+                          # interpolated to it (e.g. "Hi {{name}}!")
+</code></pre>
+
+h2. Missing Translations Log Handler
+
+A simple exception handler that behaves like the default exception handler but additionally logs missing translations to a given log.
+
+Useful for identifying missing translations during testing.
+
+E.g. 
+
+  require 'globalize/i18n/missing_translations_log_handler
+  I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER
+  I18n.exception_handler = :missing_translations_log_handler
+
+To set up a different log file:
+
+  logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log")
+  I18n.missing_translations_logger = logger
diff --git a/vendor/plugins/globalize2/generators/db_backend.rb b/vendor/plugins/globalize2/generators/db_backend.rb
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb b/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb
new file mode 100644 (file)
index 0000000..d4513a5
--- /dev/null
@@ -0,0 +1,25 @@
+class ActsAsTaggableMigration < ActiveRecord::Migration
+  def self.up
+    create_table :globalize_translations do |t|
+      t.string :locale, :null => false
+      t.string :key, :null => false
+      t.string :translation
+      t.timestamps
+    end
+
+# TODO: FINISH DOING MIGRATION -- stopped in the middle
+    
+    create_table :globalize_translations_map do |t|
+      t.string  :key, :null => false
+      t.integer :translation_id, :null => false
+    end
+    
+    add_index :taggings, :tag_id
+    add_index :taggings, [:taggable_id, :taggable_type]
+  end
+  
+  def self.down
+    drop_table :globalize_translations
+    drop_table :tags
+  end
+end
diff --git a/vendor/plugins/globalize2/init.rb b/vendor/plugins/globalize2/init.rb
new file mode 100644 (file)
index 0000000..7b5428e
--- /dev/null
@@ -0,0 +1,10 @@
+require 'rails_edge_load_path_patch.rb' unless I18n.respond_to?(:load_path)
+
+ActiveRecord::Base.send :include, Globalize::Model::ActiveRecord::Translated
+
+I18n.backend = Globalize::Backend::Static.new
+
+I18n.load_path = Globalize::LoadPath.new I18n.load_path
+I18n.load_path << "#{File.dirname(__FILE__)}/lib/locale"
+I18n.load_path << "#{RAILS_ROOT}/lib/locale"
+
diff --git a/vendor/plugins/globalize2/lib/globalize/backend/chain.rb b/vendor/plugins/globalize2/lib/globalize/backend/chain.rb
new file mode 100644 (file)
index 0000000..bb8679e
--- /dev/null
@@ -0,0 +1,102 @@
+module I18n
+  class << self
+    def chain_backends(*args)
+      self.backend = Globalize::Backend::Chain.new(*args)
+    end
+  end
+end
+  
+module Globalize  
+  module Backend
+    class Chain      
+      def initialize(*args)
+        add(*args) unless args.empty?
+      end
+      
+      # Change this to a) accept any number of backends and b) accept classes.
+      # When classes are passed instantiate them and add the instances as backends.
+      # Return the added backends from #add.
+      #
+      # Add an initialize method that accepts the same arguments and passes them
+      # to #add, so we could:
+      #   I18n.backend = Globalize::Backend::Chain.new(Globalize::Backend::Foo, Globalize::Backend::Bar)
+      #   Globalize::Backend::Chain.new(:foo, :bar)
+      #   Globalize.chain_backends :foo, :bar
+      def add(*backends)
+        backends.each do |backend|
+          backend = Globalize::Backend.const_get(backend.to_s.capitalize) if backend.is_a? Symbol
+          backend = backend.new if backend.is_a? Class
+          self.backends << backend
+        end
+      end
+      
+      def load_translations(*args)
+        backends.each{|backend| backend.load_translations(*args) }
+      end
+    
+      # For defaults:
+      # Never pass any default option to the backends but instead implement our own default
+      # mechanism (e.g. symbols as defaults would need to be passed to the whole chain to
+      # be translated).
+      #
+      # For namespace lookup: 
+      # Only return if the result is not a hash OR count is not present, otherwise merge them.
+      # So in effect the count variable would control whether we have a namespace lookup or a 
+      # pluralization going on.
+      #
+      # Exceptions:
+      # Make sure that we catch MissingTranslationData exceptions and raise
+      # one in the end when no translation was found at all.
+      #
+      # For bulk translation:
+      # If the key is an array we need to call #translate for each of the
+      # keys and collect the results.
+      
+      def translate(locale, key, options = {})
+        raise I18n::InvalidLocale.new(locale) if locale.nil?
+        return key.map{|k| translate locale, k, options } if key.is_a? Array
+        
+        default = options.delete(:default)
+        result = backends.inject({}) do |namespace, backend|
+          begin
+            translation = backend.translate(locale.to_sym, key, options) 
+            if namespace_lookup?(translation, options)
+              namespace.merge! translation
+            elsif translation
+              return translation 
+            end
+          rescue I18n::MissingTranslationData
+          end
+        end
+        result || default(locale, default, options) || raise(I18n::MissingTranslationData.new(locale, key, options))
+      end
+      
+      def localize(locale, object, format = :default)
+        backends.each do |backend|
+          result = backend.localize(locale, object, format) and return result
+        end
+      end
+    
+      protected
+        def backends
+          @backends ||= []
+        end
+        
+        def default(locale, default, options = {})
+          case default
+            when String then default
+            when Symbol then translate locale, default, options
+            when Array  then default.each do |obj| 
+              result = default(locale, obj, options.dup) and return result
+            end and nil
+          end
+        rescue I18n::MissingTranslationData
+          nil
+        end
+        
+        def namespace_lookup?(result, options)
+          result.is_a?(Hash) and not options.has_key?(:count)
+        end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb b/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb
new file mode 100644 (file)
index 0000000..80016f2
--- /dev/null
@@ -0,0 +1,37 @@
+require 'i18n/backend/simple'
+
+module Globalize
+  module Backend
+    class Pluralizing < I18n::Backend::Simple
+      def pluralize(locale, entry, count)
+        return entry unless entry.is_a?(Hash) and count
+        key = :zero if count == 0 && entry.has_key?(:zero)
+        key ||= pluralizer(locale).call(count)
+        raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
+        translation entry[key], :plural_key => key
+      end
+
+      def add_pluralizer(locale, pluralizer)
+        pluralizers[locale.to_sym] = pluralizer
+      end
+
+      def pluralizer(locale)
+        pluralizers[locale.to_sym] || default_pluralizer
+      end
+
+      protected
+        def default_pluralizer
+          pluralizers[:en]
+        end
+
+        def pluralizers
+          @pluralizers ||= { :en => lambda{|n| n == 1 ? :one : :other } }
+        end
+
+        # Overwrite this method to return something other than a String
+        def translation(string, attributes)
+          string
+        end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/backend/static.rb b/vendor/plugins/globalize2/lib/globalize/backend/static.rb
new file mode 100644 (file)
index 0000000..fb9e1fe
--- /dev/null
@@ -0,0 +1,60 @@
+require 'globalize/backend/pluralizing'
+require 'globalize/locale/fallbacks'
+require 'globalize/translation'
+
+module Globalize
+  module Backend
+    class Static < Pluralizing
+      def initialize(*args)
+        add(*args) unless args.empty?
+      end
+
+      def translate(locale, key, options = {})
+        result, default, fallback = nil, options.delete(:default), nil
+        I18n.fallbacks[locale].each do |fallback|
+          begin
+            result = super(fallback, key, options) and break
+          rescue I18n::MissingTranslationData
+          end
+        end
+        result ||= default locale, default, options
+
+        attrs = {:requested_locale => locale, :locale => fallback, :key => key, :options => options}
+        translation(result, attrs) || raise(I18n::MissingTranslationData.new(locale, key, options))
+      end
+
+      protected
+
+        alias :orig_interpolate :interpolate unless method_defined? :orig_interpolate
+        def interpolate(locale, string, values = {})
+          result = orig_interpolate(locale, string, values)
+          translation = translation(string)
+          translation.nil? ? result : translation.replace(result)
+        end
+
+        def translation(result, meta = nil)
+          return unless result
+
+          case result
+          when Numeric
+            result
+          when String
+            result = Translation::Static.new(result) unless result.is_a? Translation::Static
+            result.set_meta meta
+            result
+          when Hash
+            Hash[*result.map do |key, value|
+              [key, translation(value, meta)]
+            end.flatten]
+          when Array
+            result.map do |value|
+              translation(value, meta)
+            end
+          else
+            result
+            # raise "unexpected translation type: #{result.inspect}"
+          end
+        end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb b/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb
new file mode 100644 (file)
index 0000000..3f06ac2
--- /dev/null
@@ -0,0 +1,41 @@
+# A simple exception handler that behaves like the default exception handler
+# but additionally logs missing translations to a given log.
+#
+# Useful for identifying missing translations during testing.
+# 
+# E.g. 
+#
+#   require 'globalize/i18n/missing_translations_log_handler
+#   I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER
+#   I18n.exception_handler = :missing_translations_log_handler
+#
+# To set up a different log file:
+#
+#   logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log")
+#   I18n.missing_translations_logger = logger
+
+module I18n
+  @@missing_translations_logger = nil
+  
+  class << self
+    def missing_translations_logger
+      @@missing_translations_logger ||= begin
+        require 'logger' unless defined?(Logger)
+        Logger.new(STDOUT)
+      end
+    end
+  
+    def missing_translations_logger=(logger)
+      @@missing_translations_logger = logger
+    end
+  
+    def missing_translations_log_handler(exception, locale, key, options)
+      if MissingTranslationData === exception
+        missing_translations_logger.warn(exception.message)
+        return exception.message 
+      else
+        raise exception
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_raise_handler.rb b/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_raise_handler.rb
new file mode 100644 (file)
index 0000000..e32be28
--- /dev/null
@@ -0,0 +1,27 @@
+# A simple exception handler that behaves like the default exception handler
+# but also raises on missing translations.
+#
+# Useful for identifying missing translations during testing.
+# 
+# E.g. 
+#
+#   require 'globalize/i18n/missing_translations_raise_handler
+#   I18n.exception_handler = :missing_translations_raise_handler
+module I18n
+  class << self
+    def missing_translations_raise_handler(exception, locale, key, options)
+      raise exception
+    end
+  end
+  
+#  self.exception_handler = :missing_translations_raise_handler
+end
+
+I18n.exception_handler = :missing_translations_raise_handler
+
+ActionView::Helpers::TranslationHelper.module_eval do
+  def translate(key, options = {})
+    I18n.translate(key, options)
+  end
+  alias :t :translate
+end
diff --git a/vendor/plugins/globalize2/lib/globalize/load_path.rb b/vendor/plugins/globalize2/lib/globalize/load_path.rb
new file mode 100644 (file)
index 0000000..a49825b
--- /dev/null
@@ -0,0 +1,63 @@
+# Locale load_path and Locale loading support.
+#
+# To use this include the Globalize::LoadPath::I18n module to I18n like this:
+#
+#   I18n.send :include, Globalize::LoadPath::I18n
+#
+# Clients can add load_paths using:
+#
+#   I18n.load_path.add load_path, 'rb', 'yml'   # pass any number of extensions like this
+#   I18n.load_path << 'path/to/dir'             # usage without an extension, defaults to 'yml'
+#
+# And load locale data using either of:
+#
+#   I18n.load_locales 'en-US', 'de-DE'
+#   I18n.load_locale 'en-US'
+# 
+# This will lookup all files named like:
+#
+#   'path/to/dir/all.yml'
+#   'path/to/dir/en-US.yml'
+#   'path/to/dir/en-US/*.yml'
+#
+# The filenames will be passed to I18n.load_translations which delegates to 
+# the backend. So the actual behaviour depends on the implementation of the
+# backend. I18n::Backend::Simple will be able to read YAML and plain Ruby 
+# files. See the documentation for I18n.load_translations for details.
+
+module Globalize
+  class LoadPath < Array
+    def extensions
+      @extensions ||= ['rb', 'yml']
+    end
+    attr_writer :extensions
+  
+    def locales
+      @locales ||= ['*']
+    end
+    attr_writer :locales
+  
+    def <<(path)
+      push path
+    end
+  
+    def push(*paths)
+      super(*paths.map{|path| filenames(path) }.flatten.uniq.sort)
+    end
+  
+    protected
+  
+      def filenames(path)
+        return [path] if File.file? path
+        patterns(path).map{|pattern| Dir[pattern] }
+      end
+  
+      def patterns(path)
+        locales.map do |locale|
+          extensions.map do |extension|
+            %W(#{path}/all.#{extension} #{path}/#{locale}.#{extension} #{path}/#{locale}/**/*.#{extension})
+          end
+        end.flatten.uniq
+      end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb b/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb
new file mode 100644 (file)
index 0000000..c4acd57
--- /dev/null
@@ -0,0 +1,63 @@
+require 'globalize/locale/language_tag'
+
+module I18n
+  @@fallbacks = nil
+    
+  class << self
+    # Returns the current fallbacks. Defaults to +Globalize::Locale::Fallbacks+.
+    def fallbacks
+      @@fallbacks ||= Globalize::Locale::Fallbacks.new
+    end
+    
+    # Sets the current fallbacks. Used to set a custom fallbacks instance.
+    def fallbacks=(fallbacks) 
+      @@fallbacks = fallbacks
+    end
+  end
+end
+
+module Globalize
+  module Locale
+    class Fallbacks < Hash
+      def initialize(*defaults)
+        @map = {}
+        map defaults.pop if defaults.last.is_a?(Hash)
+        
+        defaults = [I18n.default_locale.to_sym] if defaults.empty?
+        self.defaults = defaults 
+      end
+      
+      def defaults=(defaults)
+        @defaults = defaults.map{|default| compute(default, false) }.flatten << :root
+      end
+      attr_reader :defaults
+      
+      def [](tag)
+        tag = tag.to_sym
+        has_key?(tag) ? fetch(tag) : store(tag, compute(tag))
+      end
+    
+      def map(mappings)
+        mappings.each do |from, to|
+          from, to = from.to_sym, Array(to)
+          to.each do |to|
+            @map[from] ||= []
+            @map[from] << to.to_sym
+          end
+        end
+      end
+      
+      protected
+    
+      def compute(tags, include_defaults = true)
+        result = Array(tags).collect do |tag|
+          tags = LanguageTag::tag(tag.to_sym).parents(true).map! {|t| t.to_sym }
+          tags.each{|tag| tags += compute(@map[tag]) if @map[tag] }
+          tags
+        end.flatten
+        result.push *defaults if include_defaults
+        result.uniq
+      end
+    end
+  end
+end
diff --git a/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb b/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb
new file mode 100644 (file)
index 0000000..d9aae54
--- /dev/null
@@ -0,0 +1,81 @@
+# for specifications see http://en.wikipedia.org/wiki/IETF_language_tag
+#
+# SimpleParser does not implement advanced usages such as grandfathered tags
+
+module Globalize
+  module Locale
+    module Rfc4646
+      SUBTAGS = [:language, :script, :region, :variant, :extension, :privateuse, :grandfathered]
+      FORMATS = {:language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase}
+    end
+    
+    class LanguageTag < Struct.new(*Rfc4646::SUBTAGS)
+      class << self
+        def parser
+          @@parser ||= SimpleParser
+        end
+    
+        def parser=(parser)
+          @@parser = parser
+        end
+    
+        def tag(tag)
+          matches = parser.match(tag)
+          new *matches if matches
+        end
+      end
+  
+      Rfc4646::FORMATS.each do |name, format|
+        define_method(name) { self[name].send(format) unless self[name].nil? }
+      end
+      
+      def to_sym
+        to_s.to_sym
+      end
+      
+      def to_s
+        @tag ||= to_a.compact.join("-")
+      end
+  
+      def to_a
+        members.collect {|attr| self.send(attr) }
+      end
+  
+      def parent
+        segs = to_a.compact
+        segs.length < 2 ? nil : LanguageTag.tag(segs[0..(segs.length-2)].join('-'))
+      end
+      
+      def parents(include_self = true)
+        result, parent = [], self.dup
+        result << parent if include_self
+        while parent = parent.parent
+          result << parent
+        end
+        result
+      end
+  
+      module SimpleParser
+        PATTERN = %r{\A(?:
+          ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
+          (?:-([a-z]{4}))?                                        # script
+          (?:-([a-z]{2}|\d{3}))?                                  # region
+          (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))*                     # variant
+          (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))*                   # extension
+          (?:-(x(?:-[0-9a-z]{1,8})+))?|                           # privateuse subtag
+          (x(?:-[0-9a-z]{1,8})+)|                                 # privateuse tag
+          /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */               # grandfathered
+          )\z}xi 
+
+        class << self
+          def match(tag)
+            c = PATTERN.match(tag.to_s).captures
+            c[0..4] << (c[5].nil? ? c[6] : c[5])  << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
+          rescue
+            false
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record.rb
new file mode 100644 (file)
index 0000000..9645842
--- /dev/null
@@ -0,0 +1,38 @@
+require 'globalize/translation'
+require 'globalize/locale/fallbacks'
+require 'globalize/model/active_record/adapter'
+require 'globalize/model/active_record/translated'
+
+module Globalize
+  module Model
+    module ActiveRecord
+      class << self                
+        def create_proxy_class(klass)
+          Object.const_set "#{klass.name}Translation", Class.new(::ActiveRecord::Base){
+            belongs_to "#{klass.name.underscore}".intern
+            
+            def locale
+              read_attribute(:locale).to_sym
+            end
+            
+            def locale=(locale)
+              write_attribute(:locale, locale.to_s)
+            end
+          }
+        end
+
+        def define_accessors(klass, attr_names)
+          attr_names.each do |attr_name|
+            klass.send :define_method, attr_name, lambda {
+              globalize.fetch self.class.locale, attr_name
+            }
+            klass.send :define_method, "#{attr_name}=", lambda {|val|
+              globalize.stash self.class.locale, attr_name, val
+              self[attr_name] = val
+            }
+          end
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb
new file mode 100644 (file)
index 0000000..93355b8
--- /dev/null
@@ -0,0 +1,96 @@
+module Globalize
+  module Model
+    class AttributeStash < Hash
+      def contains?(locale, attr_name)
+        locale = locale.to_sym
+        self[locale] ||= {}
+        self[locale].has_key? attr_name        
+      end
+      
+      def read(locale, attr_name)
+        locale = locale.to_sym
+        self[locale] ||= {}
+        self[locale][attr_name]
+      end
+      
+      def write(locale, attr_name, value)
+        locale = locale.to_sym
+        self[locale] ||= {}
+        self[locale][attr_name] = value
+      end
+    end
+    
+    class Adapter
+      def initialize(record)
+        @record = record
+        
+        # TODO what exactly are the roles of cache and stash
+        @cache = AttributeStash.new
+        @stash = AttributeStash.new
+      end
+      
+      def fetch(locale, attr_name)
+        # locale = I18n.locale
+        is_cached = @cache.contains?(locale, attr_name)
+        is_cached ? @cache.read(locale, attr_name) : begin
+          value = fetch_attribute locale, attr_name
+          @cache.write locale, attr_name, value if value && value.locale == locale
+          value
+        end
+      end
+      
+      def stash(locale, attr_name, value)
+        @stash.write locale, attr_name, value
+        @cache.write locale, attr_name, value
+      end
+      
+      def update_translations!
+        @stash.each do |locale, attrs|
+          translation = @record.globalize_translations.find_or_initialize_by_locale(locale.to_s)
+          attrs.each{|attr_name, value| translation[attr_name] = value }
+          translation.save!
+        end
+        @stash.clear
+      end
+      
+      # Clears the cache
+      def clear
+        @cache.clear
+        @stash.clear
+      end
+      
+      private
+      
+      def fetch_attribute(locale, attr_name)
+        fallbacks = I18n.fallbacks[locale].map{|tag| tag.to_s}.map(&:to_sym)
+        
+        # If the translations were included with 
+        # :include => globalize_translations
+        # there is no need to query them again.
+        unless @record.globalize_translations.loaded?
+          translations = @record.globalize_translations.by_locales(fallbacks) 
+        else
+          translations = @record.globalize_translations
+        end
+        result, requested_locale = nil, locale
+
+        # Walk through the fallbacks, starting with the current locale itself, and moving
+        # to the next best choice, until we find a match.
+        # Check the @globalize_set_translations cache first to see if we've just changed the 
+        # attribute and not saved yet.
+        fallbacks.each do |fallback|
+          # TODO should we be checking stash or just cache?
+          result = @stash.read(fallback, attr_name) || begin
+            translation = translations.detect {|tr| tr.locale == fallback }
+            translation && translation.send(attr_name)
+          end
+          if result
+            locale = fallback
+            break
+          end
+        end
+        result && Translation::Attribute.new(result, :locale => locale, :requested_locale => requested_locale)
+      end
+    end
+  end
+end
diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb
new file mode 100644 (file)
index 0000000..f8fb230
--- /dev/null
@@ -0,0 +1,154 @@
+module Globalize
+  module Model
+  
+    class MigrationError < StandardError; end
+    class UntranslatedMigrationField < MigrationError; end
+    class MigrationMissingTranslatedField < MigrationError; end
+    class BadMigrationFieldType < MigrationError; end
+  
+    module ActiveRecord
+      module Translated
+        def self.included(base)
+          base.extend ActMethods
+        end
+
+        module ActMethods
+          def translates(*attr_names)
+            options = attr_names.extract_options!
+            options[:translated_attributes] = attr_names
+
+            # Only set up once per class
+            unless included_modules.include? InstanceMethods
+              class_inheritable_accessor :globalize_options, :globalize_proxy
+              
+              include InstanceMethods
+              extend  ClassMethods
+              
+              self.globalize_proxy = Globalize::Model::ActiveRecord.create_proxy_class(self)
+              has_many(
+                :globalize_translations,
+                :class_name   => globalize_proxy.name,
+                :extend       => Extensions,
+                :dependent    => :delete_all,
+                :foreign_key  => class_name.foreign_key
+              )
+
+              after_save :update_globalize_record              
+            end
+
+            self.globalize_options = options
+            Globalize::Model::ActiveRecord.define_accessors(self, attr_names)
+            
+            # Import any callbacks that have been defined by extensions to Globalize2
+            # and run them.
+            extend Callbacks
+            Callbacks.instance_methods.each {|cb| send cb }
+          end
+
+          def locale=(locale)
+            @@locale = locale
+          end
+          
+          def locale
+            (defined?(@@locale) && @@locale) || I18n.locale
+          end          
+        end
+
+        # Dummy Callbacks module. Extensions to Globalize2 can insert methods into here
+        # and they'll be called at the end of the translates class method.
+        module Callbacks
+        end
+        
+        # Extension to the has_many :globalize_translations association
+        module Extensions
+          def by_locales(locales)
+            find :all, :conditions => { :locale => locales.map(&:to_s) }
+          end
+        end
+        
+        module ClassMethods          
+          def method_missing(method, *args)
+            if method.to_s =~ /^find_by_(\w+)$/ && globalize_options[:translated_attributes].include?($1.to_sym)
+              find(:first, :joins => :globalize_translations,
+                   :conditions => [ "#{i18n_attr($1)} = ? AND #{i18n_attr('locale')} IN (?)",
+                                   args.first,I18n.fallbacks[I18n.locale].map{|tag| tag.to_s}])
+            else
+              super
+            end
+          end
+                    
+          def create_translation_table!(fields)
+            translated_fields = self.globalize_options[:translated_attributes]
+            translated_fields.each do |f|
+              raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f]
+            end
+            fields.each do |name, type|
+              unless translated_fields.member? name 
+                raise UntranslatedMigrationField, "Can't migrate untranslated field: #{name}"
+              end              
+              unless [ :string, :text ].member? type
+                raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text"
+              end 
+            end
+            translation_table_name = self.name.underscore + '_translations'
+            self.connection.create_table(translation_table_name) do |t|
+              t.references self.table_name.singularize
+              t.string :locale
+              fields.each do |name, type|
+                t.column name, type
+              end
+              t.timestamps              
+            end
+          end
+
+          def drop_translation_table!
+            translation_table_name = self.name.underscore + '_translations'
+            self.connection.drop_table translation_table_name
+          end
+          
+          private
+          
+          def i18n_attr(attribute_name)
+            self.base_class.name.underscore + "_translations.#{attribute_name}"
+          end          
+        end
+        
+        module InstanceMethods
+          def reload(options = nil)
+            globalize.clear
+            
+            # clear all globalized attributes
+            # TODO what's the best way to handle this?
+            self.class.globalize_options[:translated_attributes].each do |attr|
+              @attributes.delete attr.to_s
+            end
+            
+            super options
+          end
+          
+          def globalize
+            @globalize ||= Adapter.new self
+          end
+          
+          def update_globalize_record
+            globalize.update_translations!
+          end
+          
+          def translated_locales
+            globalize_translations.scoped(:select => 'DISTINCT locale').map {|gt| gt.locale.to_sym }
+          end
+          
+          def set_translations options
+            options.keys.each do |key|
+
+              translation = globalize_translations.find_by_locale(key.to_s) ||
+                globalize_translations.build(:locale => key.to_s)
+              translation.update_attributes!(options[key])
+            end
+          end
+          
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/translation.rb b/vendor/plugins/globalize2/lib/globalize/translation.rb
new file mode 100644 (file)
index 0000000..a80afcd
--- /dev/null
@@ -0,0 +1,32 @@
+module Globalize
+  # Translations are simple value objects that carry some context information
+  # alongside the actual translation string.
+
+  class Translation < String
+    class Attribute < Translation
+      attr_accessor :requested_locale, :locale, :key
+    end
+    
+    class Static < Translation
+      attr_accessor :requested_locale, :locale, :key, :options, :plural_key, :original
+      
+      def initialize(string, meta = nil)
+        self.original = string
+        super
+      end
+    end
+    
+    def initialize(string, meta = nil)
+      set_meta meta
+      super string
+    end
+  
+    def fallback?
+      locale.to_sym != requested_locale.to_sym
+    end
+    
+    def set_meta(meta)
+      meta.each {|name, value| send :"#{name}=", value } if meta
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/locale/root.yml b/vendor/plugins/globalize2/lib/locale/root.yml
new file mode 100644 (file)
index 0000000..2ec2b3b
--- /dev/null
@@ -0,0 +1,3 @@
+root:
+  bidi:
+    direction: left-to-right
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb b/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb
new file mode 100644 (file)
index 0000000..e6f90d8
--- /dev/null
@@ -0,0 +1,40 @@
+module I18n
+  @@load_path = nil
+  @@default_locale = :'en-US'
+  
+  class << self
+    def load_path
+      @@load_path ||= []
+    end
+    
+    def load_path=(load_path)
+      @@load_path = load_path
+    end
+  end
+end
+
+I18n::Backend::Simple.module_eval do
+  def initialized?
+    @initialized ||= false
+  end
+  
+  protected
+
+    def init_translations
+      load_translations(*I18n.load_path)
+      @initialized = true
+    end
+    
+    def lookup(locale, key, scope = [])
+      return unless key
+      init_translations unless initialized?
+      keys = I18n.send :normalize_translation_keys, locale, key, scope
+      keys.inject(translations){|result, k| result[k.to_sym] or return nil }
+    end
+end
+
+rails_dir = File.expand_path "#{File.dirname(__FILE__)}/../../../rails/"
+paths = %w(actionpack/lib/action_view/locale/en-US.yml 
+           activerecord/lib/active_record/locale/en-US.yml
+           activesupport/lib/active_support/locale/en-US.yml)
+paths.each{|path| I18n.load_path << "#{rails_dir}/#{path}" }
diff --git a/vendor/plugins/globalize2/notes.textile b/vendor/plugins/globalize2/notes.textile
new file mode 100644 (file)
index 0000000..b686f41
--- /dev/null
@@ -0,0 +1,51 @@
+Stopped DB Backend in the middle, here's where we left off:
+
+h1. Some Notes
+
+* Started doing the migration generator in generators/db_backend.rb
+* Translation keys will be in dotted string format
+* Question: Do we need a plural_key column, or can we build it in to the dotted key?
+* We will probably have to code the following methods from scratch, to optimize db calls:
+** translate
+** localize
+** pluralize
+* We should refactor @interpolation@ code so that it can be included into backend code without inheriting SimpleBackend
+** Rationale: interpolation is something done entirely after a string is fetched from the data store
+** Alternately, it could be done from within the I18n module
+
+h1. Schema
+
+There will be two db tables. 
+
+# globalize_translations will have: locale, key, translation, created_at, updated_at.
+# globalize_translations_map will have: key, translation_id.
+
+globalize_translations_map will let us easily fetch entire sub-trees of namespaces. 
+However, this table may not be necessary, as it may be feasible to just use key LIKE "some.namespace.%".
+
+h1. Caching
+
+We'll almost certainly want to implement caching in the backend. Should probably be a customized
+implementation based on the Rails caching mechanism, to support memcached, etc.
+
+h1. Queries
+
+We'll want to pull in lots of stuff at once and return a single translation based on some
+quick Ruby selection. The query will look something like this:
+
+<pre>
+<code>
+SELECT * FROM globalize_translations
+WHERE locale in (<fallbacks>) AND
+key IN (key, default_key)
+</code>
+</pre>
+
+The Ruby code would then pick the first translation that satisfies a fallback, in fallback order. 
+Of course, the records with the supplied key would take precedence of those with the default key.
+
+h1. Misc
+
+We should revisit the :zero plural code. On the one hand it's certainly useful for 
+many apps in many languages. On the other hand it's not mentioned in CLDR, and not a real
+concept in language pluralization. Right now, I'm feeling it's still a good idea to keep it in. 
diff --git a/vendor/plugins/globalize2/test/backends/chained_test.rb b/vendor/plugins/globalize2/test/backends/chained_test.rb
new file mode 100644 (file)
index 0000000..bb0b3e0
--- /dev/null
@@ -0,0 +1,175 @@
+require File.join( File.dirname(__FILE__), '..', 'test_helper' )
+require 'globalize/backend/chain'
+
+module Globalize
+  module Backend
+    class Dummy
+      def translate(locale, key, options = {})
+      end
+    end
+  end
+end
+
+class ChainedTest < ActiveSupport::TestCase
+  
+  test "instantiates a chained backend and sets test as backend" do
+    assert_nothing_raised { I18n.chain_backends }
+    assert_instance_of Globalize::Backend::Chain, I18n.backend
+  end
+  
+  test "passes all given arguments to the chained backends #initialize method" do
+    Globalize::Backend::Chain.expects(:new).with(:spec, :simple)
+    I18n.chain_backends :spec, :simple
+  end
+
+  test "passes all given arguments to #add assuming that they are backends" do
+    # no idea how to spec that
+  end
+end
+
+class AddChainedTest < ActiveSupport::TestCase
+  def setup
+    I18n.backend = Globalize::Backend::Chain.new  
+  end
+  
+  test "accepts an instance of a backend" do
+    assert_nothing_raised { I18n.backend.add Globalize::Backend::Dummy.new }
+    assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
+  end
+
+  test "accepts a class and instantiates the backend" do
+    assert_nothing_raised { I18n.backend.add Globalize::Backend::Dummy }
+    assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
+  end
+
+  test "accepts a symbol, constantizes test as a backend class and instantiates the backend" do
+    assert_nothing_raised { I18n.backend.add :dummy }
+    assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
+  end
+
+  test "accepts any number of backend instances, classes or symbols" do
+    assert_nothing_raised { I18n.backend.add Globalize::Backend::Dummy.new, Globalize::Backend::Dummy, :dummy }
+    assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
+    assert_equal [ Globalize::Backend::Dummy, Globalize::Backend::Dummy, Globalize::Backend::Dummy ], 
+      I18n.backend.send(:backends).map{|backend| backend.class }
+  end
+  
+end
+
+class TranslateChainedTest < ActiveSupport::TestCase
+  def setup
+    I18n.locale = :en
+    I18n.backend = Globalize::Backend::Chain.new
+    @first_backend = I18n::Backend::Simple.new
+    @last_backend = I18n::Backend::Simple.new
+    I18n.backend.add @first_backend
+    I18n.backend.add @last_backend
+  end
+
+  test "delegates #translate to all backends in the order they were added" do
+    @first_backend.expects(:translate).with(:en, :foo, {})
+    @last_backend.expects(:translate).with(:en, :foo, {})
+    I18n.translate :foo
+  end
+
+  test "returns the result from #translate from the first backend if test's not nil" do
+    @first_backend.store_translations :en, {:foo => 'foo from first backend'}
+    @last_backend.store_translations :en, {:foo => 'foo from last backend'}
+    result = I18n.translate :foo
+    assert_equal 'foo from first backend', result
+  end
+
+  test "returns the result from #translate from the second backend if the first one returned nil" do
+    @first_backend.store_translations :en, {}
+    @last_backend.store_translations :en, {:foo => 'foo from last backend'}
+    result = I18n.translate :foo
+    assert_equal 'foo from last backend', result
+  end
+
+  test "looks up a namespace from all backends and merges them (if a result is a hash and no count option is present)" do
+    @first_backend.store_translations :en, {:foo => {:bar => 'bar from first backend'}}
+    @last_backend.store_translations :en, {:foo => {:baz => 'baz from last backend'}}
+    result = I18n.translate :foo
+    assert_equal( {:bar => 'bar from first backend', :baz => 'baz from last backend'}, result )
+  end
+
+  test "raises a MissingTranslationData exception if no translation was found" do
+    assert_raise( I18n::MissingTranslationData ) { I18n.translate :not_here, :raise => true }
+  end
+
+  test "raises an InvalidLocale exception if the locale is nil" do
+    assert_raise( I18n::InvalidLocale ) { Globalize::Backend::Chain.new.translate nil, :foo }
+  end
+
+  test "bulk translates a number of keys from different backends" do
+    @first_backend.store_translations :en, {:foo => 'foo from first backend'}
+    @last_backend.store_translations :en, {:bar => 'bar from last backend'}
+    result = I18n.translate [:foo, :bar]
+    assert_equal( ['foo from first backend', 'bar from last backend'], result )
+  end
+
+  test "still calls #translate on all the backends" do
+    @last_backend.expects :translate
+    I18n.translate :not_here, :default => 'default'
+  end
+
+  test "returns a given default string when no backend returns a translation" do
+    result = I18n.translate :not_here, :default => 'default'
+    assert_equal 'default', result
+  end
+
+end
+
+class CustomLocalizeBackend < I18n::Backend::Simple
+  def localize(locale, object, format = :default)
+    "result from custom localize backend" if locale == 'custom'
+  end
+end
+
+class LocalizeChainedTest < ActiveSupport::TestCase
+  def setup
+    I18n.locale = :en
+    I18n.backend = Globalize::Backend::Chain.new
+    @first_backend = CustomLocalizeBackend.new
+    @last_backend = I18n::Backend::Simple.new
+    I18n.backend.add @first_backend
+    I18n.backend.add @last_backend
+    @time = Time.now
+  end
+
+  test "delegates #localize to all backends in the order they were added" do
+    @first_backend.expects(:localize).with(:en, @time, :default)
+    @last_backend.expects(:localize).with(:en, @time, :default)
+    I18n.localize @time
+  end
+
+  test "returns the result from #localize from the first backend if test's not nil" do
+    @last_backend.expects(:localize).never
+    result = I18n.localize @time, :locale => 'custom'
+    assert_equal 'result from custom localize backend', result
+  end
+
+  test "returns the result from #localize from the second backend if the first one returned nil" do
+    @last_backend.expects(:localize).returns "value from last backend"
+    result = I18n.localize @time
+    assert_equal 'value from last backend', result
+  end
+end
+
+class NamespaceChainedTest < ActiveSupport::TestCase
+  def setup
+    @backend = Globalize::Backend::Chain.new
+  end
+  
+  test "returns false if the given result is not a Hash" do
+    assert !@backend.send(:namespace_lookup?, 'foo', {})
+  end
+
+  test "returns false if a count option is present" do
+    assert !@backend.send(:namespace_lookup?, {:foo => 'foo'}, {:count => 1})
+  end
+
+  test "returns true if the given result is a Hash AND no count option is present" do
+    assert @backend.send(:namespace_lookup?, {:foo => 'foo'}, {})
+  end  
+end
diff --git a/vendor/plugins/globalize2/test/backends/pluralizing_test.rb b/vendor/plugins/globalize2/test/backends/pluralizing_test.rb
new file mode 100644 (file)
index 0000000..7445e3f
--- /dev/null
@@ -0,0 +1,63 @@
+require File.join( File.dirname(__FILE__), '..', 'test_helper' )
+require 'globalize/backend/pluralizing'
+
+class PluralizingTest < ActiveSupport::TestCase
+  def setup
+    @backend = Globalize::Backend::Pluralizing.new
+    @cz_pluralizer = lambda{|c| c == 1 ? :one : (2..4).include?(c) ? :few : :other }
+  end
+
+  test "#pluralizer returns the pluralizer for a given locale if defined" do
+    assert_instance_of Proc, @backend.pluralizer(:en)
+  end
+  
+  test "#pluralizer returns the default pluralizer if no pluralizer is defined for the given locale" do
+    assert_equal @backend.pluralizer(:en), @backend.pluralizer(:de) 
+  end
+  
+  test "#add_pluralizer allows to store a pluralizer per locale" do
+    assert_nothing_raised { @backend.add_pluralizer(:cz, @cz_pluralizer) }
+    assert_equal @cz_pluralizer, @backend.pluralizer(:cz) 
+  end
+
+end
+
+class PluralizePluralizingTest < ActiveSupport::TestCase
+  def setup
+    @backend = Globalize::Backend::Pluralizing.new
+    @cz_pluralizer = lambda{|c| c == 1 ? :one : (2..4).include?(c) ? :few : :other }
+    @backend.store_translations :en, :foo => {:one => 'one en foo', :other => 'many en foos'}
+    @backend.store_translations :cz, :foo => {:one => 'one cz foo', :few => 'few cz foos', :other => 'many cz foos'}
+  end
+
+  test "looks up the :one translation when count is 1" do
+    assert_equal 'one en foo', @backend.translate(:en, :foo, :count => 1) 
+  end
+
+  test "looks up the :other translation when count is 2" do
+    assert_equal 'many en foos', @backend.translate(:en, :foo, :count => 2) 
+  end
+end
+
+class CzPluralizingTest < ActiveSupport::TestCase
+  def setup
+    @backend = Globalize::Backend::Pluralizing.new
+    @cz_pluralizer = lambda{|c| c == 1 ? :one : (2..4).include?(c) ? :few : :other }
+    @backend.store_translations :en, :foo => {:one => 'one en foo', :other => 'many en foos'}
+    @backend.store_translations :cz, :foo => {:one => 'one cz foo', :few => 'few cz foos', :other => 'many cz foos'}
+    @backend.add_pluralizer(:cz, @cz_pluralizer)
+  end
+
+  test "looks up the :one translation when count is 1 (:cz)" do
+    assert_equal 'one cz foo', @backend.translate(:cz, :foo, :count => 1) 
+  end
+
+  test "looks up the :few translation when count is 2 (:cz)" do
+    assert_equal 'few cz foos', @backend.translate(:cz, :foo, :count => 2)
+  end
+
+  test "looks up the :other translation when count is 5 (:cz)" do
+    assert_equal 'many cz foos', @backend.translate(:cz, :foo, :count => 5)
+  end
+
+end
diff --git a/vendor/plugins/globalize2/test/backends/static_test.rb b/vendor/plugins/globalize2/test/backends/static_test.rb
new file mode 100644 (file)
index 0000000..133e547
--- /dev/null
@@ -0,0 +1,143 @@
+require File.join( File.dirname(__FILE__), '..', 'test_helper' )
+require 'globalize/backend/static'
+require 'globalize/translation'
+require 'action_view'
+include ActionView::Helpers::NumberHelper
+
+I18n.locale = :'en-US'    # Need to set this, since I18n defaults to 'en'
+
+class StaticTest < ActiveSupport::TestCase
+  def setup
+    I18n.backend = Globalize::Backend::Static.new
+    translations = {:"en-US" => {:foo => "foo in en-US", :boz => 'boz', :buz => {:bum => 'bum'}},
+                    :"en"    => {:bar => "bar in en"},
+                    :"de-DE" => {:baz => "baz in de-DE"},
+                    :"de"    => {:boo => "boo in de", :number => { :currency => { :format => { :unit => '€', :format => '%n %u'}}}}}
+    translations.each do |locale, data| 
+      I18n.backend.store_translations locale, data 
+    end
+    I18n.fallbacks.map :"de-DE" => :"en-US", :he => :en
+  end
+  
+  test "returns an instance of Translation:Static" do
+    translation = I18n.translate :foo
+    assert_instance_of Globalize::Translation::Static, translation
+  end
+    
+  test "returns the translation in en-US if present" do
+    assert_equal "foo in en-US", I18n.translate(:foo, :locale => :"en-US") 
+  end
+
+  test "returns the translation in en if en-US is not present" do
+    assert_equal "bar in en", I18n.translate(:bar, :locale => :"en-US") 
+  end
+  
+  test "returns the translation in de-DE if present" do
+    assert_equal "baz in de-DE", I18n.translate(:baz, :locale => :"de-DE") 
+  end
+  
+  test "returns the translation in de if de-DE is not present" do
+    assert_equal "boo in de", I18n.translate(:boo, :locale => :"de-DE") 
+  end
+  
+  test "returns the translation in en-US if none of de-DE and de are present" do
+    assert_equal "foo in en-US", I18n.translate(:foo, :locale => :"de-DE") 
+  end
+
+  test "returns the translation in en if none of de-DE, de and en-US are present" do
+    assert_equal "bar in en", I18n.translate(:bar, :locale => :"de-DE") 
+  end
+  
+  test "returns the translation in en if none in he is present" do
+    assert_equal "bar in en", I18n.translate(:bar, :locale => :he) 
+  end
+  
+  test "returns the given default String when the key is not present for any locale" do
+    assert_equal "default", I18n.translate(:missing, :default => "default") 
+  end
+
+  test "returns the fallback translation for the key if present for a fallback locale" do
+    I18n.backend.store_translations :de, :non_default => "non_default in de"
+    assert_equal "non_default in de", I18n.translate(:non_default, :default => "default", :locale => :"de-DE") 
+  end  
+
+  test "returns an array of translations" do
+    assert_instance_of Array, I18n.translate([:foo, :boz])
+  end
+  
+  test "returns an array of instances of Translation::Static" do
+    assert_equal [Globalize::Translation::Static], I18n.translate([:foo, :boz]).map(&:class).uniq
+  end
+  
+  test "returns a hash of translations" do
+    assert_instance_of Hash, I18n.translate(:"buz")
+  end
+  
+  test "returns an array of translations 2" do
+    assert_equal [Globalize::Translation::Static], I18n.translate(:"buz").values.map(&:class) 
+  end
+
+  test "returns currency properly formated" do
+    currency = number_to_currency(10)
+    assert_equal "$10.00", currency
+  end
+
+  test "returns currency properly formated for locale" do
+    currency = number_to_currency(10, :locale => :'de')
+    assert_equal "10.000 €", currency
+  end
+
+  test "returns currency properly formated from parameters" do
+    currency = number_to_currency(10, :format => "%n %u", :unit => '€')
+    assert_equal "10.00 €", currency
+  end
+
+  test "makes sure interpolation does not break even with False as string" do
+    assert_equal "translation missing: en, support, array, skip_last_comma", I18n.translate(:"support.array.skip_last_comma")
+  end
+end
+
+class TranslationStaticTest < ActiveSupport::TestCase
+  def setup
+    I18n.backend = Globalize::Backend::Static.new 
+    translations = {
+      :greeting => "Hi {{name}}",
+      :messages => { :one => "You have one message.", :other => "You have {{count}} messages."}
+    }
+    I18n.backend.store_translations :"en", translations
+  end
+
+  def greeting
+    I18n.translate :greeting, :locale => :"en-US", :name => "Joshua"
+  end
+  
+  test "stores the actual locale" do
+    assert_equal :en, greeting.locale
+  end
+  
+  test "stores the requested locale" do
+    assert_equal :'en-US', greeting.requested_locale
+  end
+  
+  test "stores the requested key" do
+    assert_equal :greeting, greeting.key
+  end
+  
+  test "stores the options given to #translate" do
+    assert_equal( {:name => "Joshua"}, greeting.options ) 
+  end
+  
+  test "stores the original translation before test was interpolated" do
+    assert_equal "Hi {{name}}", greeting.original 
+  end
+  
+  test "stores the plural_key :one if pluralized as such" do
+    message = I18n.translate :messages, :locale => :"en-US", :count => 1
+    assert_equal :one, message.plural_key
+  end
+  
+  test "stores the plural_key :other if pluralized as such" do
+    messages = I18n.translate :messages, :locale => :"en-US", :count => 2
+    assert_equal :other, messages.plural_key
+  end
+end
diff --git a/vendor/plugins/globalize2/test/data/locale/all.yml b/vendor/plugins/globalize2/test/data/locale/all.yml
new file mode 100644 (file)
index 0000000..ee4fb4a
--- /dev/null
@@ -0,0 +1,2 @@
+en-US:
+  from-all-file: From the "all" file.
diff --git a/vendor/plugins/globalize2/test/data/locale/de-DE.yml b/vendor/plugins/globalize2/test/data/locale/de-DE.yml
new file mode 100644 (file)
index 0000000..d4c468e
--- /dev/null
@@ -0,0 +1,2 @@
+de-DE:
+  from-locale-file: Aus der Locale Datei.
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/data/locale/en-US.yml b/vendor/plugins/globalize2/test/data/locale/en-US.yml
new file mode 100644 (file)
index 0000000..866b171
--- /dev/null
@@ -0,0 +1,2 @@
+en-US:
+  from-locale-file: From the locale file.
diff --git a/vendor/plugins/globalize2/test/data/locale/en-US/module.yml b/vendor/plugins/globalize2/test/data/locale/en-US/module.yml
new file mode 100644 (file)
index 0000000..6655e9b
--- /dev/null
@@ -0,0 +1,2 @@
+en-US:
+  from-locale-dir: From the locale directory.
diff --git a/vendor/plugins/globalize2/test/data/locale/fi-FI/module.yml b/vendor/plugins/globalize2/test/data/locale/fi-FI/module.yml
new file mode 100644 (file)
index 0000000..62d00b1
--- /dev/null
@@ -0,0 +1,2 @@
+fi-FI:
+  from-locale-dir: Locale hakemistosta.
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/data/locale/root.yml b/vendor/plugins/globalize2/test/data/locale/root.yml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/vendor/plugins/globalize2/test/data/no_globalize_schema.rb b/vendor/plugins/globalize2/test/data/no_globalize_schema.rb
new file mode 100644 (file)
index 0000000..7cfaf69
--- /dev/null
@@ -0,0 +1,11 @@
+# This schema creates tables without columns for the translated fields
+ActiveRecord::Schema.define do  
+  create_table :blogs, :force => true do |t|
+    t.string :name
+  end
+
+  create_table :posts, :force => true do |t|
+    t.references :blog
+  end
+end
+  
diff --git a/vendor/plugins/globalize2/test/data/post.rb b/vendor/plugins/globalize2/test/data/post.rb
new file mode 100644 (file)
index 0000000..6673dc4
--- /dev/null
@@ -0,0 +1,24 @@
+class Post < ActiveRecord::Base
+  translates :subject, :content
+  validates_presence_of :subject
+end
+
+class Blog < ActiveRecord::Base
+  has_many :posts, :order => 'id ASC'
+end
+
+class Parent < ActiveRecord::Base
+  translates :content
+end
+
+class Child < Parent
+end
+
+class Comment < ActiveRecord::Base
+  validates_presence_of :content
+  belongs_to :post
+end
+class TranslatedComment < Comment
+  translates :content
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/data/schema.rb b/vendor/plugins/globalize2/test/data/schema.rb
new file mode 100644 (file)
index 0000000..8d076ae
--- /dev/null
@@ -0,0 +1,39 @@
+ActiveRecord::Schema.define do
+  
+  create_table :blogs, :force => true do |t|
+    t.string      :description
+  end
+
+  create_table :posts, :force => true do |t|
+    t.references :blog
+  end
+
+  create_table :post_translations, :force => true do |t|
+    t.string     :locale
+    t.references :post
+    t.string     :subject
+    t.text       :content
+  end
+  
+  create_table :parents, :force => true do |t|
+  end
+
+  create_table :parent_translations, :force => true do |t|
+    t.string     :locale
+    t.references :parent
+    t.text       :content
+    t.string     :type
+  end
+  
+  create_table :comments, :force => true do |t|
+    t.references :post
+  end
+
+  create_table :translated_comment_translations, :force => true do |t|
+    t.string     :locale
+    t.references :comment
+    t.string     :subject
+    t.text       :content
+  end
+  
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb b/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb
new file mode 100644 (file)
index 0000000..8641d57
--- /dev/null
@@ -0,0 +1,36 @@
+require File.join( File.dirname(__FILE__), '..', 'test_helper' )
+require 'globalize/i18n/missing_translations_log_handler'
+
+class MissingTranslationsTest < ActiveSupport::TestCase
+  test "defines I18n.missing_translations_logger accessor" do
+    assert I18n.respond_to?(:missing_translations_logger)
+  end
+
+  test "defines I18n.missing_translations_logger= writer" do
+    assert I18n.respond_to?(:missing_translations_logger=)
+  end
+end
+
+class TestLogger < String
+  def warn(msg) self.concat msg; end
+end
+
+class LogMissingTranslationsTest < ActiveSupport::TestCase
+  def setup
+    @locale, @key, @options = :en, :foo, {}
+    @exception = I18n::MissingTranslationData.new(@locale, @key, @options)
+    
+    @logger = TestLogger.new
+    I18n.missing_translations_logger = @logger
+  end
+
+  test "still returns the exception message for MissingTranslationData exceptions" do
+    result = I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
+    assert_equal 'translation missing: en, foo', result 
+  end
+  
+  test "logs the missing translation to I18n.missing_translations_logger" do
+    I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
+    assert_equal 'translation missing: en, foo', @logger 
+  end
+end
diff --git a/vendor/plugins/globalize2/test/load_path_test.rb b/vendor/plugins/globalize2/test/load_path_test.rb
new file mode 100644 (file)
index 0000000..ff009b3
--- /dev/null
@@ -0,0 +1,49 @@
+require File.join( File.dirname(__FILE__), 'test_helper' )
+require 'globalize/load_path'
+
+class LoadPathTest < ActiveSupport::TestCase
+  def setup
+    @plugin_dir = "#{File.dirname(__FILE__)}/.."
+    @locale_dir = "#{File.dirname(__FILE__)}/data/locale"
+    @load_path = Globalize::LoadPath.new
+  end
+  
+  test "returns glob patterns for all locales and ruby + yaml files by default" do
+    patterns = %w(locales/all.rb
+                  locales/*.rb 
+                  locales/*/**/*.rb 
+                  locales/all.yml 
+                  locales/*.yml
+                  locales/*/**/*.yml)
+    assert_equal patterns, @load_path.send(:patterns, 'locales')
+  end
+
+  test "returns the glob patterns for registered locales and extensions" do
+    @load_path.locales = [:en, :de]
+    @load_path.extensions = [:sql]
+    patterns = %w(locales/all.sql
+                  locales/en.sql
+                  locales/en/**/*.sql 
+                  locales/de.sql
+                  locales/de/**/*.sql)
+    assert_equal patterns, @load_path.send(:patterns, 'locales')
+  end
+
+  test "expands paths using yml as a default file extension" do
+    @load_path << @locale_dir
+    expected = %w(all.yml de-DE.yml en-US.yml en-US/module.yml fi-FI/module.yml root.yml)
+    assert_equal expected, @load_path.map{|path| path.sub("#{@locale_dir}\/", '')}
+  end
+
+  test "appends new paths to the collection so earlier collected paths preceed later collected ones" do
+    @load_path.locales = [:root]
+    @load_path << "#{@plugin_dir}/lib/locale"
+    @load_path << @locale_dir
+    
+    expected = %W(#{@plugin_dir}/lib/locale/root.yml 
+                  #{@locale_dir}/all.yml
+                  #{@locale_dir}/root.yml)
+    assert_equal expected, @load_path
+  end
+
+end
diff --git a/vendor/plugins/globalize2/test/locale/fallbacks_test.rb b/vendor/plugins/globalize2/test/locale/fallbacks_test.rb
new file mode 100644 (file)
index 0000000..304d3da
--- /dev/null
@@ -0,0 +1,154 @@
+require File.join( File.dirname(__FILE__), '..', 'test_helper' )
+require 'globalize/locale/fallbacks'
+
+include Globalize::Locale
+I18n.default_locale = :'en-US'    # This has to be set explicitly, no longer default for I18n
+
+class FallbacksTest < ActiveSupport::TestCase
+  def setup
+    I18n.fallbacks = Fallbacks.new
+  end
+
+  def teardown
+    I18n.default_locale = :'en-US'
+  end
+
+  test "#[] caches computed results" do
+    I18n.fallbacks['en']
+    assert_equal( { :en => [:en, :"en-US", :root] }, I18n.fallbacks ) 
+  end
+
+  test "#defaults always reflect the I18n.default_locale if no default has been set manually" do
+    I18n.default_locale = :'en-US'
+    assert_equal( [:'en-US', :en, :root], I18n.fallbacks.defaults ) 
+  end
+
+  test "#defaults always reflect a manually passed default locale if any" do
+    I18n.fallbacks = Fallbacks.new(:'fi-FI')
+    assert_equal( [:'fi-FI', :fi, :root], I18n.fallbacks.defaults ) 
+    I18n.default_locale = :'de-DE'
+    assert_equal( [:'fi-FI', :fi, :root], I18n.fallbacks.defaults ) 
+  end
+
+  test "#defaults allows to set multiple defaults" do
+    I18n.fallbacks = Fallbacks.new(:'fi-FI', :'se-FI')
+    assert_equal( [:'fi-FI', :fi, :'se-FI', :se, :root], I18n.fallbacks.defaults ) 
+  end
+end
+
+class NoMappingFallbacksTest < ActiveSupport::TestCase
+  def setup
+    @fallbacks = Fallbacks.new(:'en-US')
+  end
+
+  test "returns [:es, :en-US, :root] for :es" do
+    assert_equal [:es, :"en-US", :en, :root], @fallbacks[:es] 
+  end
+
+  test "returns [:es-ES, :es, :en-US, :root] for :es-ES" do
+    assert_equal [:"es-ES", :es, :"en-US", :en, :root], @fallbacks[:"es-ES"] 
+  end
+
+  test "returns [:es-MX, :es, :en-US, :root] for :es-MX" do
+    assert_equal [:"es-MX", :es, :"en-US", :en, :root], @fallbacks[:"es-MX"] 
+  end
+
+  test "returns [:es-Latn-ES, :es-Latn, :es, :en-US, :root] for :es-Latn-ES" do
+    assert_equal [:"es-Latn-ES", :"es-Latn", :es, :"en-US", :en, :root], @fallbacks[:'es-Latn-ES'] 
+  end
+
+  test "returns [:en, :en-US, :root] for :en" do
+    assert_equal [:en, :"en-US", :root], @fallbacks[:en] 
+  end
+
+  test "returns [:en-US, :en, :root] for :en-US (special case: locale == default)" do
+    assert_equal [:"en-US", :en, :root], @fallbacks[:"en-US"] 
+  end
+end
+
+class CaMappingFallbacksTest < ActiveSupport::TestCase
+  # Most people who speak Catalan also live in Spain, so test is safe to assume
+  # that they also speak Spanish as spoken in Spain.
+  def setup
+    @fallbacks = Fallbacks.new(:'en-US')
+    @fallbacks.map :ca => :"es-ES"
+  end
+
+  test "returns [:ca, :es-ES, :es, :en-US, :root] for :ca" do
+    assert_equal [:ca, :"es-ES", :es, :"en-US", :en, :root], @fallbacks[:ca] 
+  end
+
+  test "returns [:ca-ES, :ca, :es-ES, :es, :en-US, :root] for :ca-ES" do
+    assert_equal [:"ca-ES", :ca, :"es-ES", :es, :"en-US", :en, :root], @fallbacks[:"ca-ES"] 
+  end
+end
+
+class ArMappingFallbacksTest < ActiveSupport::TestCase
+  # People who speak Arabic as spoken in Palestine often times also speak
+  # Hebrew as spoken in Israel. However test is in no way safe to assume that
+  # everybody who speaks Arabic also speaks Hebrew.
+  def setup
+    @fallbacks = Fallbacks.new(:'en-US')
+    @fallbacks.map :"ar-PS" => :"he-IL"
+  end
+
+  test "returns [:ar, :en-US, :root] for :ar" do
+    assert_equal [:ar, :"en-US", :en, :root], @fallbacks[:ar] 
+  end
+
+  test "returns [:ar-EG, :ar, :en-US, :root] for :ar-EG" do
+    assert_equal [:"ar-EG", :ar, :"en-US", :en, :root], @fallbacks[:"ar-EG"] 
+  end
+
+  test "returns [:ar-PS, :ar, :he-IL, :he, :en-US, :root] for :ar-PS" do
+    assert_equal [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en, :root], @fallbacks[:"ar-PS"] 
+  end
+end
+
+class SmsMappingFallbacksTest < ActiveSupport::TestCase
+  # Sami people live in several scandinavian countries. In Finnland many people
+  # know Swedish and Finnish. Thus, test can be assumed that Sami living in
+  # Finnland also speak Swedish and Finnish.
+  def setup
+    @fallbacks = Fallbacks.new(:'en-US')
+    @fallbacks.map :sms => [:"se-FI", :"fi-FI"]
+  end
+
+  test "returns [:sms-FI, :sms, :se-FI, :se, :fi-FI, :fi, :en-US, :root] for :sms-FI" do
+    assert_equal [:"sms-FI", :sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en, :root], @fallbacks[:"sms-FI"] 
+  end
+end
+
+class DeAtMappingFallbacksTest < ActiveSupport::TestCase
+  def setup
+    @fallbacks = Fallbacks.new(:'en-US')
+    @fallbacks.map :"de-AT" => :"de-DE"
+  end
+
+  test "returns [:de, :en-US, :root] for de" do
+    assert_equal [:de, :"en-US", :en, :root], @fallbacks[:"de"] 
+  end
+
+  test "returns [:de-DE, :de, :en-US, :root] for de-DE" do
+    assert_equal [:"de-DE", :de, :"en-US", :en, :root], @fallbacks[:"de-DE"] 
+  end
+
+  test "returns [:de-AT, :de, :de-DE, :en-US, :root] for de-AT" do
+    assert_equal [:"de-AT", :de, :"de-DE", :"en-US", :en, :root], @fallbacks[:"de-AT"] 
+  end
+end
+
+class DeMappingFallbacksTest < ActiveSupport::TestCase
+  def setup
+    @fallbacks = Fallbacks.new(:'en-US')
+    @fallbacks.map :de => :en, :he => :en
+  end
+  
+  test "returns [:de, :en, :root] for :de" do
+    assert_equal [:de, :en, :"en-US", :root], @fallbacks[:de] 
+  end
+  
+  test "returns [:he, :en, :root] for :de" do
+    assert_equal [:he, :en, :"en-US", :root], @fallbacks[:he] 
+  end
+end
diff --git a/vendor/plugins/globalize2/test/locale/language_tag_test.rb b/vendor/plugins/globalize2/test/locale/language_tag_test.rb
new file mode 100644 (file)
index 0000000..2448af1
--- /dev/null
@@ -0,0 +1,130 @@
+require File.join( File.dirname(__FILE__), '..', 'test_helper' )
+require 'globalize/locale/language_tag'
+
+include Globalize::Locale
+
+class LanguageTagTest < ActiveSupport::TestCase
+  test "given a valid tag 'de' returns an LanguageTag from #tag" do
+    assert_instance_of LanguageTag, LanguageTag.tag('de')
+  end
+
+  test "given a valid tag 'de' returns an array of subtags" do
+    assert_equal ['de', nil, nil, nil, nil, nil, nil], LanguageTag::SimpleParser.match('de') 
+  end
+  
+  test "given a valid tag 'de-DE' returns an array of subtags" do
+    assert_equal ['de', nil, 'DE', nil, nil, nil, nil], LanguageTag::SimpleParser.match('de-DE') 
+  end
+  
+  test "given a valid lowercase tag 'de-latn-de-variant-x-phonebk' returns an array of subtags" do
+    assert_equal ['de', 'latn', 'de', 'variant', nil, 'x-phonebk', nil], 
+      LanguageTag::SimpleParser.match('de-latn-de-variant-x-phonebk') 
+  end
+  
+  test "given a valid uppercase tag 'DE-LATN-DE-VARIANT-X-PHONEBK' returns an array of subtags" do
+    assert_equal ['DE', 'LATN', 'DE', 'VARIANT', nil, 'X-PHONEBK', nil], 
+      LanguageTag::SimpleParser.match('DE-LATN-DE-VARIANT-X-PHONEBK') 
+  end
+  
+  test "given an invalid tag 'a-DE' test returns false" do
+    assert !LanguageTag::SimpleParser.match('a-DE')
+  end
+  
+  test "given an invalid tag 'de-419-DE' test returns false" do
+    assert !LanguageTag::SimpleParser.match('de-419-DE')
+  end
+end
+
+class DeLatnLanguageTagTest < ActiveSupport::TestCase
+  def setup
+    subtags = %w(de Latn DE variant a-ext x-phonebk i-klingon)
+    @tag = LanguageTag.new *subtags
+  end
+
+  test "returns 'de' as the language subtag in lowercase" do
+    assert_equal 'de', @tag.language
+  end
+
+  test "returns 'Latn' as the script subtag in titlecase" do
+    assert_equal 'Latn', @tag.script 
+  end
+
+  test "returns 'DE' as the region subtag in uppercase" do
+    assert_equal 'DE', @tag.region
+  end
+
+  test "returns 'variant' as the variant subtag in lowercase" do
+    assert_equal 'variant', @tag.variant 
+  end
+
+  test "returns 'a-ext' as the extension subtag" do
+    assert_equal 'a-ext', @tag.extension 
+  end
+
+  test "returns 'x-phonebk' as the privateuse subtag" do
+    assert_equal 'x-phonebk', @tag.privateuse 
+  end
+
+  test "returns 'i-klingon' as the grandfathered subtag" do
+    assert_equal 'i-klingon', @tag.grandfathered 
+  end
+  
+  test "returns a formatted tag string from #to_s" do
+    assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon', @tag.to_s 
+  end
+  
+  test "returns an array containing the formatted subtags from #to_a" do
+    assert_equal %w(de Latn DE variant a-ext x-phonebk i-klingon), @tag.to_a 
+  end
+end
+
+class InheritanceLanguageTagTest < ActiveSupport::TestCase
+  test "returns 'de-Latn-DE-variant-a-ext-x-phonebk' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
+    tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
+    assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk', tag.parent.to_s 
+  end
+
+  test "returns 'de-Latn-DE-variant-a-ext' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk'" do
+    tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk)
+    assert_equal 'de-Latn-DE-variant-a-ext', tag.parent.to_s 
+  end
+
+  test "returns 'de-Latn-DE-variant' as the parent of 'de-Latn-DE-variant-a-ext'" do
+    tag = LanguageTag.new *%w(de Latn DE variant a-ext)
+    assert_equal 'de-Latn-DE-variant', tag.parent.to_s 
+  end
+
+  test "returns 'de-Latn-DE' as the parent of 'de-Latn-DE-variant'" do
+    tag = LanguageTag.new *%w(de Latn DE variant)
+    assert_equal 'de-Latn-DE', tag.parent.to_s 
+  end
+
+  test "returns 'de-Latn' as the parent of 'de-Latn-DE'" do
+    tag = LanguageTag.new *%w(de Latn DE)
+    assert_equal 'de-Latn', tag.parent.to_s 
+  end
+
+  test "returns 'de' as the parent of 'de-Latn'" do
+    tag = LanguageTag.new *%w(de Latn)
+    assert_equal 'de', tag.parent.to_s 
+  end
+  
+  # TODO RFC4647 says: "If no language tag matches the request, the "default" value is returned."
+  # where should we set the default language?
+  # test "returns '' as the parent of 'de'" do
+  #   tag = LanguageTag.new *%w(de)
+  #   assert_equal '', tag.parent.to_s
+  # end
+
+  test "returns an array of 5 parents for 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
+    parents = %w(de-Latn-DE-variant-a-ext-x-phonebk-i-klingon 
+                 de-Latn-DE-variant-a-ext-x-phonebk 
+                 de-Latn-DE-variant-a-ext 
+                 de-Latn-DE-variant 
+                 de-Latn-DE 
+                 de-Latn 
+                 de) 
+    tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
+    assert_equal parents, tag.parents.map{|tag| tag.to_s} 
+  end  
+end
diff --git a/vendor/plugins/globalize2/test/model/active_record/migration_test.rb b/vendor/plugins/globalize2/test/model/active_record/migration_test.rb
new file mode 100644 (file)
index 0000000..c539fb6
--- /dev/null
@@ -0,0 +1,73 @@
+require File.join( File.dirname(__FILE__), '..', '..', 'test_helper' )
+require 'active_record'
+require 'globalize/model/active_record'
+
+# Hook up model translation
+ActiveRecord::Base.send(:include, Globalize::Model::ActiveRecord::Translated)
+
+# Load Post model
+require File.join( File.dirname(__FILE__), '..', '..', 'data', 'post' )
+
+class MigrationTest < ActiveSupport::TestCase
+  def setup
+    reset_db! File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'no_globalize_schema.rb'))
+  end
+  
+  test 'globalize table added' do
+    assert !Post.connection.table_exists?( :post_translations )
+    Post.create_translation_table! :subject => :string, :content => :text
+    assert Post.connection.table_exists?( :post_translations )      
+    columns = Post.connection.columns( :post_translations )
+    assert locale = columns.detect {|c| c.name == 'locale' }
+    assert_equal :string, locale.type
+    assert subject = columns.detect {|c| c.name == 'subject' }
+    assert_equal :string, subject.type
+    assert content = columns.detect {|c| c.name == 'content' }
+    assert_equal :text, content.type
+    assert post_id = columns.detect {|c| c.name == 'post_id' }
+    assert_equal :integer, post_id.type
+    assert created_at = columns.detect {|c| c.name == 'created_at' }
+    assert_equal :datetime, created_at.type
+    assert updated_at = columns.detect {|c| c.name == 'updated_at' }
+    assert_equal :datetime, updated_at.type
+  end
+  
+  test 'globalize table dropped' do
+    assert !Post.connection.table_exists?( :post_translations )
+    Post.create_translation_table! :subject => :string, :content => :text
+    assert Post.connection.table_exists?( :post_translations )      
+    Post.drop_translation_table!
+    assert !Post.connection.table_exists?( :post_translations )
+  end
+
+  test 'exception on untranslated field inputs' do
+    assert_raise Globalize::Model::UntranslatedMigrationField do
+      Post.create_translation_table! :subject => :string, :content => :text, :bogus => :string
+    end
+  end
+  
+  test 'exception on missing field inputs' do
+    assert_raise Globalize::Model::MigrationMissingTranslatedField do
+      Post.create_translation_table! :content => :text
+    end
+  end
+  
+  test 'exception on bad input type' do
+    assert_raise Globalize::Model::BadMigrationFieldType do
+      Post.create_translation_table! :subject => :string, :content => :integer
+    end
+  end
+  
+  test 'create_translation_table! should not be called on non-translated models' do
+    assert_raise NoMethodError do
+      Blog.create_translation_table! :name => :string      
+    end
+  end
+
+  test 'drop_translation_table! should not be called on non-translated models' do
+    assert_raise NoMethodError do
+      Blog.drop_translation_table!      
+    end
+  end
+
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/model/active_record/sti_translated_test.rb b/vendor/plugins/globalize2/test/model/active_record/sti_translated_test.rb
new file mode 100644 (file)
index 0000000..14d7d0f
--- /dev/null
@@ -0,0 +1,75 @@
+require File.join( File.dirname(__FILE__), '..', '..', 'test_helper' )
+require 'active_record'
+require 'globalize/model/active_record'
+
+# Hook up model translation
+ActiveRecord::Base.send(:include, Globalize::Model::ActiveRecord::Translated)
+
+# Load Post model
+require File.join( File.dirname(__FILE__), '..', '..', 'data', 'post' )
+
+class StiTranslatedTest < ActiveSupport::TestCase
+  def setup
+    I18n.locale = :'en-US'
+    I18n.fallbacks.clear 
+    reset_db! File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'schema.rb'))
+  end
+  
+  def teardown
+    I18n.fallbacks.clear 
+  end
+
+  test "works with simple dynamic finders" do
+    foo = Child.create :content => 'foo'
+    Child.create :content => 'bar'
+    child = Child.find_by_content('foo')
+    assert_equal foo, child
+  end
+
+  test 'change attribute on globalized model' do
+    child = Child.create :content => 'foo'
+    assert_equal [], child.changed
+    child.content = 'bar'
+    assert_equal [ 'content' ], child.changed
+    child.content = 'baz'
+    assert_member 'content', child.changed
+  end
+  
+  test 'change attribute on globalized model after locale switching' do
+    child = Child.create :content => 'foo'
+    assert_equal [], child.changed
+    child.content = 'bar'
+    I18n.locale = :de
+    assert_equal [ 'content' ], child.changed
+  end
+
+  test 'fallbacks with lots of locale switching' do
+    I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
+    child = Child.create :content => 'foo'
+    
+    I18n.locale = :'de-DE'
+    assert_equal 'foo', child.content
+    
+    I18n.locale = :'en-US'
+    child.update_attribute :content, 'bar'
+    
+    I18n.locale = :'de-DE'
+    assert_equal 'bar', child.content
+  end
+  
+  test "saves all locales, even after locale switching" do
+    child = Child.new :content => 'foo'
+    I18n.locale = 'de-DE'
+    child.content = 'bar'
+    I18n.locale = 'he-IL'
+    child.content = 'baz'
+    child.save
+    I18n.locale = 'en-US'
+    child = Child.first
+    assert_equal 'foo', child.content 
+    I18n.locale = 'de-DE'
+    assert_equal 'bar', child.content 
+    I18n.locale = 'he-IL'
+    assert_equal 'baz', child.content 
+  end    
+end
\ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/model/active_record/translated_test.rb b/vendor/plugins/globalize2/test/model/active_record/translated_test.rb
new file mode 100644 (file)
index 0000000..3e9ea00
--- /dev/null
@@ -0,0 +1,458 @@
+require File.join( File.dirname(__FILE__), '..', '..', 'test_helper' )
+require 'active_record'
+require 'globalize/model/active_record'
+
+# Hook up model translation
+ActiveRecord::Base.send(:include, Globalize::Model::ActiveRecord::Translated)
+
+# Load Post model
+require File.join( File.dirname(__FILE__), '..', '..', 'data', 'post' )
+
+class TranslatedTest < ActiveSupport::TestCase
+  def setup
+    I18n.locale = :'en-US'
+    I18n.fallbacks.clear 
+    reset_db! File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'schema.rb'))
+    ActiveRecord::Base.locale = nil
+  end
+  
+  def teardown
+    I18n.fallbacks.clear 
+  end
+
+  test "modifiying translated fields" do
+    post = Post.create :subject => 'foo'
+    assert_equal 'foo', post.subject
+    post.subject = 'bar'
+    assert_equal 'bar', post.subject    
+  end
+
+  test "modifiying translated fields while switching locales" do
+    post = Post.create :subject => 'foo'
+    assert_equal 'foo', post.subject
+    I18n.locale = :'de-DE'
+    post.subject = 'bar'
+    assert_equal 'bar', post.subject
+    I18n.locale = :'en-US'
+    assert_equal 'foo', post.subject
+    I18n.locale = :'de-DE'
+    post.subject = 'bar'
+  end
+  
+  test "has post_translations" do
+    post = Post.create
+    assert_nothing_raised { post.globalize_translations }
+  end
+
+  test "has German post_translations" do
+    I18n.locale = :de
+    post = Post.create :subject => 'foo'
+    assert_equal 1, post.globalize_translations.size
+    I18n.locale = :en
+    assert_equal 1, post.globalize_translations.size    
+  end
+  
+  test "returns the value passed to :subject" do
+    post = Post.new
+    assert_equal 'foo', (post.subject = 'foo')
+  end
+
+  test "translates subject and content into en-US" do
+    post = Post.create :subject => 'foo', :content => 'bar'
+    assert_equal 'foo', post.subject 
+    assert_equal 'bar', post.content 
+    assert post.save
+    post.reload
+    assert_equal 'foo', post.subject 
+    assert_equal 'bar', post.content 
+  end
+
+  test "finds a German post" do
+    post = Post.create :subject => 'foo (en)', :content => 'bar'
+    I18n.locale = 'de-DE'
+    post = Post.first
+    post.subject = 'baz&n