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
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
layout 'site'
before_filter :authorize_web
+ before_filter :set_locale
before_filter { |c| c.check_database_readable(true) }
def start
@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
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]
@tags = ChangesetTag.find(:all, :limit => 11, :conditions => ["match(v) against (?)", params[:query][:query].to_s] )
end
-
end
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])
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
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',
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],
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]
class ExportController < ApplicationController
+
+ before_filter :authorize_web
+ before_filter :set_locale
+
def start
end
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]
class SiteController < ApplicationController
before_filter :authorize_web
+ before_filter :set_locale
before_filter :require_user, :only => [:edit]
def export
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]
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]
@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
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
@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
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
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
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
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"
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)
<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 %>
<%= 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
</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>
<% 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| %>
<% 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| %>
<% 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| %>
<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>
<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>
<% 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">
$("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 %>;
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";
}
<%= 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| %>
<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) } %>
<% 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 %>
<% 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 %>
<%= 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>
<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">
<% 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 %>
<%= 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| %>
<% 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 %>
<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 %>
<%
@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" %>
<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>
<%
@name = printable_name @node
-@title = 'Node History | ' + @name
+@title = t('browse.node_history.node_history') + ' | ' + @name
%>
<h2>Node History: <%= h(@name) %></h2>
<%= 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>
-<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>
<%
@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" %>
<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>
<%
@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">
-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;
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')}");
}
}
}
}
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();
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";
}
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);
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) {
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
});
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)
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");
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");
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);
<%
@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" %>
<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>
<%
@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">
<%= 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>
</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>
<% 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
</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>
<% 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
<% 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>
-<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>
-<h1>History</h1>
+<h1><%= t'changeset.list_bbox.history' %></h1>
<%
if @bbox!=nil
minlon = @bbox[0]
%>
<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
#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
-<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>
-<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 />
<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 />
<% 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>
removeMarkerFromMap(marker);
}
- marker = addMarkerToMap(lonlat, null, "Diary entry location");
+ marker = addMarkerToMap(lonlat, null, "<%= t 'diary_entry.edit.marker_text' -%>");
}
function openMap() {
<% 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 %>
-<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>
<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>
<% 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 %>
-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;
$("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();
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("",{
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");
$("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();
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;
<% 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>
<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 & 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">
<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 %>"><%= l 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>
<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 %>"><%= l sent_message_summary.sent_on %></td>
</tr>
-<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>
</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 %>
-<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 %>
-<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>
-<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 %>
<% 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><%= l @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><%= l @message.sent_on %></td>
</tr>
<tr>
<th></th>
<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>
***************************************************************************
* *
-* 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' %>
* *
***************************************************************************
-<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>
-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
<% 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">
<% 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 %>
<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">
<% 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? %>
%>
<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' %>
window.onbeforeunload=function() {
if (!changesaved && !winie) {
- return "You have unsaved changes.";
+ return "<%= t 'site.edit.potlatch_unsaved_changes' %>";
}
}
<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">
<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>
<% 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 %>
<% 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 %>
<% 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 %>
<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 %>
<% 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 %>
<% 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) } %>
-<h1>Upload GPS Trace</h1>
+<h1><%= t'trace.create.upload_trace' %></h1>
<%= error_messages_for 'trace' %>
<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>
<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>
<% 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>
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);
}
removeMarkerFromMap(marker);
}
- marker = addMarkerToMap(lonlat, null, "Your location");
+ marker = addMarkerToMap(lonlat, null, "<%= t 'user.friend_map.your location' %>");
}
}
-<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/>
-<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>
-<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>
-<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> <!--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 %>
-<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 %>
-<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> <!--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> <!--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> <!--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 %>
<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>
-<% @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| %>
<% 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>
<% 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>
<% @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 %>
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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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 & 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."
--- /dev/null
+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
--- /dev/null
+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 & 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."
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'
--- /dev/null
+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
"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)
# 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
updated_at: "2008-11-07 17:43:34"
latitude:
longitude:
- language: en
+ language_code: en
normal_user_geo_entry:
id: 2
updated_at: "2008-11-07 17:47:34"
latitude: 51.50763
longitude: -0.10781
- language: de
+ language_code: de
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
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
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
@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")
-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
class DiaryEntryTest < Test::Unit::TestCase
api_fixtures
- fixtures :diary_entries
+ fixtures :diary_entries, :languages
def test_diary_entry_count
assert_equal 2, DiaryEntry.count
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
--- /dev/null
+doc
+spec/spec/db/*
+vendor
+NOTES
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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"
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+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
--- /dev/null
+# 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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+root:
+ bidi:
+ direction: left-to-right
\ No newline at end of file
--- /dev/null
+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}" }
--- /dev/null
+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.
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+en-US:
+ from-all-file: From the "all" file.
--- /dev/null
+de-DE:
+ from-locale-file: Aus der Locale Datei.
\ No newline at end of file
--- /dev/null
+en-US:
+ from-locale-file: From the locale file.
--- /dev/null
+en-US:
+ from-locale-dir: From the locale directory.
--- /dev/null
+fi-FI:
+ from-locale-dir: Locale hakemistosta.
\ No newline at end of file
--- /dev/null
+# 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
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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 (de)'
+ post.save
+ assert_equal 'baz (de)', Post.first.subject
+ I18n.locale = :'en-US'
+ assert_equal 'foo (en)', Post.first.subject
+ end
+
+ test "saves an English post and loads test correctly" do
+ assert_nil Post.first
+ post = Post.create :subject => 'foo', :content => 'bar'
+ assert post.save
+ post = Post.first
+ assert_equal 'foo', post.subject
+ assert_equal 'bar', post.content
+ end
+
+ test "updates an attribute" do
+ post = Post.create :subject => 'foo', :content => 'bar'
+ post.update_attribute :subject, 'baz'
+ assert_equal 'baz', Post.first.subject
+ end
+
+ test "update_attributes failure" do
+ post = Post.create :subject => 'foo', :content => 'bar'
+ assert !post.update_attributes( { :subject => '' } )
+ assert_nil post.reload.attributes['subject']
+ assert_equal 'foo', post.subject
+ end
+
+ test "validates presence of :subject" do
+ post = Post.new
+ assert !post.save
+
+ post = Post.new :subject => 'foo'
+ assert post.save
+ end
+
+ test "returns the value for the correct locale, after locale switching" do
+ post = Post.create :subject => 'foo'
+ I18n.locale = 'de-DE'
+ post.subject = 'bar'
+ post.save
+ I18n.locale = 'en-US'
+ post = Post.first
+ assert_equal 'foo', post.subject
+ I18n.locale = 'de-DE'
+ assert_equal 'bar', post.subject
+ end
+
+ test "keeping one field in new locale when other field is changed" do
+ I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
+ post = Post.create :subject => 'foo'
+ I18n.locale = 'de-DE'
+ post.content = 'bar'
+ assert_equal 'foo', post.subject
+ end
+
+ test "modifying non-required field in a new locale" do
+ I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
+ post = Post.create :subject => 'foo'
+ I18n.locale = 'de-DE'
+ post.content = 'bar'
+ assert post.save
+ end
+
+ test "returns the value for the correct locale, after locale switching, without saving" do
+ post = Post.create :subject => 'foo'
+ I18n.locale = 'de-DE'
+ post.subject = 'bar'
+ I18n.locale = 'en-US'
+ assert_equal 'foo', post.subject
+ I18n.locale = 'de-DE'
+ assert_equal 'bar', post.subject
+ end
+
+ test "saves all locales, even after locale switching" do
+ post = Post.new :subject => 'foo'
+ I18n.locale = 'de-DE'
+ post.subject = 'bar'
+ I18n.locale = 'he-IL'
+ post.subject = 'baz'
+ post.save
+ I18n.locale = 'en-US'
+ post = Post.first
+ assert_equal 'foo', post.subject
+ I18n.locale = 'de-DE'
+ assert_equal 'bar', post.subject
+ I18n.locale = 'he-IL'
+ assert_equal 'baz', post.subject
+ end
+
+ test "resolves a simple fallback" do
+ I18n.locale = 'de-DE'
+ post = Post.create :subject => 'foo'
+ I18n.locale = 'de'
+ post.subject = 'baz'
+ post.content = 'bar'
+ post.save
+ I18n.locale = 'de-DE'
+ assert_equal 'foo', post.subject
+ assert_equal 'bar', post.content
+ end
+
+ test "resolves a simple fallback without reloading" do
+ I18n.locale = 'de-DE'
+ post = Post.new :subject => 'foo'
+ I18n.locale = 'de'
+ post.subject = 'baz'
+ post.content = 'bar'
+ I18n.locale = 'de-DE'
+ assert_equal 'foo', post.subject
+ assert_equal 'bar', post.content
+ end
+
+ test "resolves a complex fallback without reloading" do
+ I18n.fallbacks.map 'de' => %w(en he)
+ I18n.locale = 'de'
+ post = Post.new
+ I18n.locale = 'en'
+ post.subject = 'foo'
+ I18n.locale = 'he'
+ post.subject = 'baz'
+ post.content = 'bar'
+ I18n.locale = 'de'
+ assert_equal 'foo', post.subject
+ assert_equal 'bar', post.content
+ end
+
+ test "returns nil if no translations are found" do
+ post = Post.new :subject => 'foo'
+ assert_equal 'foo', post.subject
+ assert_nil post.content
+ end
+
+ test "returns nil if no translations are found; reloaded" do
+ post = Post.create :subject => 'foo'
+ post = Post.first
+ assert_equal 'foo', post.subject
+ assert_nil post.content
+ end
+
+ test "works with associations" do
+ blog = Blog.create
+ post1 = blog.posts.create :subject => 'foo'
+ I18n.locale = 'de-DE'
+ post2 = blog.posts.create :subject => 'bar'
+ assert_equal 2, blog.posts.size
+ I18n.locale = 'en-US'
+ assert_equal 'foo', blog.posts.first.subject
+ assert_nil blog.posts.last.subject
+ I18n.locale = 'de-DE'
+ assert_equal 'bar', blog.posts.last.subject
+ end
+
+ test "works with simple dynamic finders" do
+ foo = Post.create :subject => 'foo'
+ Post.create :subject => 'bar'
+ post = Post.find_by_subject('foo')
+ assert_equal foo, post
+ end
+
+ test 'change attribute on globalized model' do
+ post = Post.create :subject => 'foo', :content => 'bar'
+ assert_equal [], post.changed
+ post.subject = 'baz'
+ assert_equal [ 'subject' ], post.changed
+ post.content = 'quux'
+ assert_member 'subject', post.changed
+ assert_member 'content', post.changed
+ end
+
+ test 'change attribute on globalized model after locale switching' do
+ post = Post.create :subject => 'foo', :content => 'bar'
+ assert_equal [], post.changed
+ post.subject = 'baz'
+ I18n.locale = :de
+ assert_equal [ 'subject' ], post.changed
+ end
+
+ test 'fallbacks with lots of locale switching' do
+ I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
+ post = Post.create :subject => 'foo'
+
+ I18n.locale = :'de-DE'
+ assert_equal 'foo', post.subject
+
+ I18n.locale = :'en-US'
+ post.update_attribute :subject, 'bar'
+
+ I18n.locale = :'de-DE'
+ assert_equal 'bar', post.subject
+ end
+
+ test 'reload' do
+ post = Post.create :subject => 'foo', :content => 'bar'
+ post.subject = 'baz'
+ assert_equal 'foo', post.reload.subject
+ end
+
+ test 'complex writing and stashing' do
+ post = Post.create :subject => 'foo', :content => 'bar'
+ post.subject = nil
+ assert_nil post.subject
+ assert !post.valid?
+ end
+
+ test 'translated class locale setting' do
+ assert ActiveRecord::Base.respond_to?(:locale)
+ assert_equal :'en-US', I18n.locale
+ assert_equal :'en-US', ActiveRecord::Base.locale
+ I18n.locale = :de
+ assert_equal :de, I18n.locale
+ assert_equal :de, ActiveRecord::Base.locale
+ ActiveRecord::Base.locale = :es
+ assert_equal :de, I18n.locale
+ assert_equal :es, ActiveRecord::Base.locale
+ I18n.locale = :fr
+ assert_equal :fr, I18n.locale
+ assert_equal :es, ActiveRecord::Base.locale
+ end
+
+ test "untranslated class responds to locale" do
+ assert Blog.respond_to?(:locale)
+ end
+
+ test "to ensure locales in different classes are the same" do
+ ActiveRecord::Base.locale = :de
+ assert_equal :de, ActiveRecord::Base.locale
+ assert_equal :de, Parent.locale
+ Parent.locale = :es
+ assert_equal :es, ActiveRecord::Base.locale
+ assert_equal :es, Parent.locale
+ end
+
+ test "attribute saving goes by content locale and not global locale" do
+ ActiveRecord::Base.locale = :de
+ assert_equal :'en-US', I18n.locale
+ Post.create :subject => 'foo'
+ assert_equal :de, Post.first.globalize_translations.first.locale
+ end
+
+ test "attribute loading goes by content locale and not global locale" do
+ post = Post.create :subject => 'foo'
+ assert_equal :'en-US', ActiveRecord::Base.locale
+ ActiveRecord::Base.locale = :de
+ assert_equal :'en-US', I18n.locale
+ post.update_attribute :subject, 'foo [de]'
+ assert_equal 'foo [de]', Post.first.subject
+ ActiveRecord::Base.locale = :'en-US'
+ assert_equal 'foo', Post.first.subject
+ end
+
+ test "access content locale before setting" do
+ Globalize::Model::ActiveRecord::Translated::ActMethods.class_eval "remove_class_variable(:@@locale)"
+ assert_nothing_raised { ActiveRecord::Base.locale }
+ end
+
+ test "translated_locales" do
+ Post.locale = :de
+ post = Post.create :subject => 'foo'
+ Post.locale = :es
+ post.update_attribute :subject, 'bar'
+ Post.locale = :fr
+ post.update_attribute :subject, 'baz'
+ assert_equal [ :de, :es, :fr ], post.translated_locales
+ assert_equal [ :de, :es, :fr ], Post.first.translated_locales
+ end
+
+ test "including globalize_translations" do
+ I18n.locale = :de
+ Post.create :subject => "Foo1", :content => "Bar1"
+ Post.create :subject => "Foo2", :content => "Bar2"
+
+ class << Post
+ def tranlsations_included
+ self.all(:include => :globalize_translations)
+ end
+ end
+
+ default = Post.all.map {|x| [x.subject, x.content]}
+ with_include = Post.tranlsations_included.map {|x| [x.subject, x.content]}
+ assert_equal default, with_include
+ end
+
+ test "setting multiple translations at once with options hash" do
+ Post.locale = :de
+ post = Post.create :subject => "foo1", :content => "foo1"
+ Post.locale = :en
+ post.update_attributes( :subject => "bar1", :content => "bar1" )
+
+ options = { :de => {:subject => "foo2", :content => "foo2"},
+ :en => {:subject => "bar2", :content => "bar2"} }
+ post.set_translations options
+ post.reload
+
+ assert ["bar2", "bar2"], [post.subject, post.content]
+ Post.locale = :de
+ assert ["foo2", "foo2"], [post.subject, post.content]
+ end
+
+ test "setting only one translation with set_translations" do
+ Post.locale = :de
+ post = Post.create :subject => "foo1", :content => "foo1"
+ Post.locale = :en
+ post.update_attributes( :subject => "bar1", :content => "bar1" )
+
+ options = { :en => {:subject => "bar2", :content => "bar2"} }
+ post.set_translations options
+ post.reload
+
+ assert ["bar2", "bar2"], [post.subject, post.content]
+ Post.locale = :de
+ assert ["foo1", "foo1"], [post.subject, post.content]
+ end
+
+ test "setting only selected attributes with set_translations" do
+ Post.locale = :de
+ post = Post.create :subject => "foo1", :content => "foo1"
+ Post.locale = :en
+ post.update_attributes( :subject => "bar1", :content => "bar1" )
+
+ options = { :de => {:content => "foo2"}, :en => {:subject => "bar2"} }
+ post.set_translations options
+ post.reload
+
+ assert ["bar2", "bar1"], [post.subject, post.content]
+ Post.locale = :de
+ assert ["foo1", "foo2"], [post.subject, post.content]
+ end
+
+ test "setting invalid attributes raises ArgumentError" do
+ Post.locale = :de
+ post = Post.create :subject => "foo1", :content => "foo1"
+ Post.locale = :en
+ post.update_attributes( :subject => "bar1", :content => "bar1" )
+
+ options = { :de => {:fake => "foo2"} }
+ exception = assert_raise(ActiveRecord::UnknownAttributeError) do
+ post.set_translations options
+ end
+ assert_equal "unknown attribute: fake", exception.message
+ end
+
+ test "reload accepting find options" do
+ p = Post.create :subject => "Foo", :content => "Bar"
+ assert p.reload(:readonly => true, :lock => true)
+ assert_raise(ArgumentError) { p.reload(:foo => :bar) }
+ end
+
+ test "dependent destroy of translation" do
+ p = Post.create :subject => "Foo", :content => "Bar"
+ assert_equal 1, PostTranslation.count
+ p.destroy
+ assert_equal 0, PostTranslation.count
+ end
+
+ test "translating subclass of untranslated comment model" do
+ translated_comment = TranslatedComment.create(:post => @post)
+ assert_nothing_raised { translated_comment.globalize_translations }
+ end
+
+ test "modifiying translated comments works as expected" do
+ I18n.locale = :en
+ translated_comment = TranslatedComment.create(:post => @post, :content => 'foo')
+ assert_equal 'foo', translated_comment.content
+
+ I18n.locale = :de
+ translated_comment.content = 'bar'
+ assert translated_comment.save
+ assert_equal 'bar', translated_comment.content
+
+ I18n.locale = :en
+ assert_equal 'foo', translated_comment.content
+
+ assert_equal 2, translated_comment.globalize_translations.size
+ end
+end
+
+# TODO should validate_presence_of take fallbacks into account? maybe we need
+# an extra validation call, or more options for validate_presence_of.
+# TODO error checking for fields that exist in main table, don't exist in
+# proxy table, aren't strings or text
+#
+# TODO allow finding by translated attributes in conditions?
+# TODO generate advanced dynamic finders?
--- /dev/null
+require 'rubygems'
+require 'test/unit'
+require 'active_support'
+require 'active_support/test_case'
+require 'mocha'
+
+$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' )
+
+class ActiveSupport::TestCase
+ def reset_db!( schema_path )
+ ::ActiveRecord::Migration.verbose = false # Quiet down the migration engine
+ ::ActiveRecord::Base.establish_connection({
+ :adapter => 'sqlite3',
+ :dbfile => ':memory:'
+ })
+ ::ActiveRecord::Base.silence do
+ load schema_path
+ end
+ end
+
+ def assert_member(item, arr)
+ assert_block "Item #{item} is not in array #{arr}" do
+ arr.member? item
+ end
+ end
+end
\ No newline at end of file
--- /dev/null
+require File.join( File.dirname(__FILE__), 'test_helper' )
+require 'globalize/translation'
+
+class TranslationTest < ActiveSupport::TestCase
+ include Globalize
+
+ def setup
+ @translation = Translation::Static.new 'foo', :locale => :'en-US'
+ end
+
+ test "responds to fallback?" do
+ assert @translation.respond_to?( :fallback? )
+ end
+
+ test "returns true when :locale and :requested_locale are not equal" do
+ @translation.requested_locale = :'de-DE'
+ assert @translation.fallback?
+ end
+
+ test "returns false when :locale and :requested_locale are equal" do
+ @translation.requested_locale = :'en-US'
+ assert !@translation.fallback?
+ end
+
+ test "has the attribute :locale" do
+ assert @translation.respond_to?( :locale )
+ end
+
+ test "has the attribute :requested_locale" do
+ assert @translation.respond_to?( :requested_locale )
+ end
+
+ test "has the attribute :options" do
+ assert @translation.respond_to?( :options )
+ end
+
+ test "has the attribute :plural_key" do
+ assert @translation.respond_to?( :plural_key )
+ end
+
+ test "has the attribute :original" do
+ assert @translation.respond_to?( :original )
+ end
+
+ test "Translation::Attribute has the attribute :locale" do
+ translation = Translation::Attribute.new 'foo'
+ assert translation.respond_to?( :locale )
+ end
+
+ test "Translation::Attribute has the attribute :requested_locale" do
+ translation = Translation::Attribute.new 'foo'
+ assert translation.respond_to?( :requested_locale )
+ end
+end
--- /dev/null
+Copyright (c) 2008 [name of plugin creator]
+
+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.
--- /dev/null
+= HttpAcceptLanguage
+
+A small effort in making a plugin which helps you detect the users preferred language, as sent by the HTTP header.
+
+= Features
+
+* Splits the http-header into languages specified by the user
+* Returns empty array if header is illformed.
+* Corrects case to xx-XX
+* Sorted by priority given, as much as possible.
+* Gives you the most important language
+* Gives compatible languages
+See also: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+
+= Example
+
+ class SomeController < ApplicationController
+ def some_action
+
+ request.user_preferred_languages
+ # => [ 'nl-NL', 'nl-BE', 'nl', 'en-US', 'en' ]
+
+ available = %w{en en-US nl-BE}
+ request.preferred_language_from(available)
+ # => 'nl-BE'
+
+ request.user_preferred_language
+ # => [ 'en-GB']
+ available = %w{en-US}
+ request.compatible_language_from(available)
+ # => 'en-US'
+ end
+ end
+
+= Changenotes
+
+2009-03-12: Rails 2.3 compatible
+
+Copyright (c) 2008 Iain Hecker, released under the MIT license
--- /dev/null
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the http_accept_language plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the http_accept_language plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'HttpAcceptLanguage'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
--- /dev/null
+if defined?(ActionController::Request)
+ ActionController::Request.send :include, HttpAcceptLanguage
+elsif defined?(ActionController::AbstractRequest)
+ ActionController::AbstractRequest.send :include, HttpAcceptLanguage
+else
+ ActionController::CgiRequest.send :include, HttpAcceptLanguage
+end
--- /dev/null
+module HttpAcceptLanguage
+
+ # Returns a sorted array based on user preference in HTTP_ACCEPT_LANGUAGE.
+ # Browsers send this HTTP header, so don't think this is holy.
+ #
+ # Example:
+ #
+ # request.user_preferred_languages
+ # # => [ 'nl-NL', 'nl-BE', 'nl', 'en-US', 'en' ]
+ #
+ def user_preferred_languages
+ @user_preferred_languages ||= env['HTTP_ACCEPT_LANGUAGE'].split(',').collect do |l|
+ l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
+ l.split(';q=')
+ end.sort do |x,y|
+ raise "Not correctly formatted" unless x.first =~ /^[a-z\-]+$/i
+ y.last.to_f <=> x.last.to_f
+ end.collect do |l|
+ l.first.downcase.gsub(/-[a-z]+$/i) { |x| x.upcase }
+ end
+ rescue # Just rescue anything if the browser messed up badly.
+ []
+ end
+
+ # Sets the user languages preference, overiding the browser
+ #
+ def user_preferred_languages=(languages)
+ @user_preferred_languages = languages
+ end
+
+ # Finds the locale specifically requested by the browser.
+ #
+ # Example:
+ #
+ # request.preferred_language_from I18n.available_locales
+ # # => 'nl'
+ #
+ def preferred_language_from(array)
+ (user_preferred_languages & array.collect { |i| i.to_s }).first
+ end
+
+ # Returns the first of the user_preferred_languages that is compatible
+ # with the available locales. Ignores region.
+ #
+ # Example:
+ #
+ # request.compatible_language_from I18n.available_locales
+ #
+ def compatible_language_from(array)
+ user_preferred_languages.map do |x|
+ x = x.to_s.split("-")[0]
+ array.find do |y|
+ y.to_s.split("-")[0] == x
+ end
+ end.compact.first
+ end
+
+end
--- /dev/null
+# desc "Explaining what the task does"
+# task :http_accept_language do
+# # Task goes here
+# end
--- /dev/null
+$:.unshift(File.dirname(__FILE__) + '/../lib')
+require 'http_accept_language'
+require 'test/unit'
+
+class MockedCgiRequest
+ include HttpAcceptLanguage
+ def env
+ @env ||= {'HTTP_ACCEPT_LANGUAGE' => 'en-us,en-gb;q=0.8,en;q=0.6'}
+ end
+end
+
+class HttpAcceptLanguageTest < Test::Unit::TestCase
+ def test_should_return_empty_array
+ request.env['HTTP_ACCEPT_LANGUAGE'] = nil
+ assert_equal [], request.user_preferred_languages
+ end
+
+ def test_should_properly_split
+ assert_equal %w{en-US en-GB en}, request.user_preferred_languages
+ end
+
+ def test_should_ignore_jambled_header
+ request.env['HTTP_ACCEPT_LANGUAGE'] = 'odkhjf89fioma098jq .,.,'
+ assert_equal [], request.user_preferred_languages
+ end
+
+ def test_should_find_first_available_language
+ assert_equal 'en-GB', request.preferred_language_from(%w{en en-GB})
+ end
+
+ def test_should_find_first_compatible_language
+ assert_equal 'en-hk', request.compatible_language_from(%w{en-hk})
+ assert_equal 'en', request.compatible_language_from(%w{en})
+ end
+
+ def test_should_find_first_compatible_from_user_preferred
+ request.env['HTTP_ACCEPT_LANGUAGE'] = 'en-us,de-de'
+ assert_equal 'en', request.compatible_language_from(%w{de en})
+ end
+
+ private
+ def request
+ @request ||= MockedCgiRequest.new
+ end
+end
--- /dev/null
+.DS_Store
+Icon?
+._*
--- /dev/null
+h1. Rails Locale Data Repository
+
+Central point to collect locale data for use in Ruby on Rails.
+
+To contribute just send me a pull request, patch or plain text file.
+
+Please include a comment with the language/locale name and your name and email address (or other contact information like your github profile) to the locale file so people can come contact you and ask questions etc.
+
+Also, please pay attention to save your files as UTF-8.
+
+h2. Rails translations plugin
+
+To include the translations of this repository into your application, simply install it as a plugin:
+
+./script/plugin install git://github.com/zargony/rails-i18n.git
+
+The plugin will load Rails core translations of locales you are using in your app. (i.e. if you have en.yml, de.yml and fr.yml in config/locales, Rails core locales for :de and :fr are added). These translations are added to the I18n load path before application locales, so you can still override them in your application locales.
+
+h2. Rails translations
+
+Simple tool for testing the integrity of your key structure:
+
+Make sure you have the Ruby I18n gem installed. If you haven't already you can try:
+
+sudo gem install svenfuchs-i18n -s http://gems.github.com
+
+Then, standing in the root directory of this repository, do:
+
+ruby test/structure.rb [your-locale]
+
+Assuming that there is a file locale/[your-locale].{rb,yml} you will get a summary of missing and bogus keys as well as extra pluralization keys in your locale data.
+
+h2. Rails I18n Textmate bundle
+
+Still in a very experimental state but already helpful for me.
+
+The bundle adds a single command: extract translation (shift-cmd-e)
+
+# expects you to have a string selected (including single or double quotes)
+# prompts you for a dot-separated key
+# opens the file /log/translations.yml (creating it when not available)
+# adds the translation (mapping the dot-separated key to nested yaml keys)
+# replaces the selected string in your source-code with the dot-separated key wrapped into a call to t(your.key)
+
+It currently expects that you're working with English views, so it uses :en as a locale in translation.yml.
+
+Note that Textmate, while active, won't reload the translations.yml for you if it's already open. When you give the focus to another application and then go back to Textmate (e.g. with cmd-tab, cmd-tab) it will reload the file. I found it useful to have translations.yml open on a second monitor while extracting translations from my application.
+
+I still have to figure out how to automatically select the next string after this command has run. It works well to just use Textmate's "Find Next" though:
+
+# hit cmd-f and give it <code>("|').*(\1)</code> as a search expression, tell it to use this as a "Regular expression"
+# hit return and it will select the next string
+# use shift-cmd-e to extract that string
+# hit cmd-g to select the next string
+
--- /dev/null
+# Rails plugin initialization: add default locales to I18n.load_path
+# - only add locales that are actually used in the application
+# - prepend locales so that they can be overwritten by the application
+#
+# We do this after_initialize as the I18n.load_path might be modified
+# in a config/initializers/initializer.rb
+class Rails::Initializer #:nodoc:
+ def after_initialize_with_translations_import
+ after_initialize_without_translations_import
+ used_locales = I18n.load_path.map { |f| File.basename(f).gsub(/\.(rb|yml)$/, '') }.uniq
+ files_to_add = Dir[File.join(File.dirname(__FILE__), 'locale', "{#{used_locales.join(',')}}.{rb,yml}")]
+ I18n.load_path.unshift(*files_to_add)
+ end
+ alias_method_chain :after_initialize, :translations_import
+end
--- /dev/null
+# Arabic translations for Ruby on Rails
+# by Rida Al Barazi (me@rida.me)
+# updated by Ahmed Hazem (nardgo@gmail.com)
+
+ar:
+ date:
+ formats:
+ default: "%Y-%m-%d"
+ short: "%e %b"
+ long: "%B %e, %Y"
+
+ day_names: [الأحد, الإثنين, الثلاثاء, الأربعاء, الخميس, الجمعة, السبت]
+ abbr_day_names: [الأحد, الإثنين, الثلاثاء, الأربعاء, الخميس, الجمعة, السبت]
+ month_names: [~, يناير, فبراير, مارس, ابريل, مايو, يونيو, يوليو, اغسطس, سبتمبر, اكتوبر, نوفمبر, ديسمبر]
+ abbr_month_names: [~, يناير, فبراير, مارس, ابريل, مايو, يونيو, يوليو, اغسطس, سبتمبر, اكتوبر, نوفمبر, ديسمبر]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %b %d %H:%M:%S %Z %Y"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ only_second: "%S"
+
+ datetime:
+ formats:
+ default: "%Y-%m-%dT%H:%M:%S%Z"
+
+ am: 'صباحا'
+ pm: 'مساءا'
+
+ # Used in array.to_sentence.
+ support:
+ array:
+ sentence_connector: "و"
+ skip_last_comma: false
+
+ datetime:
+ distance_in_words:
+ half_a_minute: 'نصف دقيقة'
+ less_than_x_seconds:
+ one: 'أقل من ثانية'
+ other: '{{count}} ثوان'
+ x_seconds:
+ one: 'ثانية واحدة'
+ other: '{{count}} ثوان'
+ less_than_x_minutes:
+ one: 'أقل من دقيقة'
+ other: '{{count}} دقائق'
+ x_minutes:
+ one: 'دقيقة واحدة'
+ other: '{{count}} دقائق'
+ about_x_hours:
+ one: 'حوالي ساعة واحدة'
+ other: '{{count}} ساعات'
+ x_days:
+ one: 'يوم واحد'
+ other: '{{count}} أيام'
+ about_x_months:
+ one: 'حوالي شهر واحد'
+ other: '{{count}} أشهر'
+ x_months:
+ one: 'شهر واحد'
+ other: '{{count}} أشهر'
+ about_x_years:
+ one: 'حوالي سنة'
+ other: '{{count}} سنوات'
+ over_x_years:
+ one: 'أكثر من سنة'
+ other: '{{count}} سنوات'
+
+ number:
+ format:
+ separator: '.'
+ delimiter: ','
+ precision: 3
+ human:
+ format:
+ delimiter: ','
+ precision: 1
+ currency:
+ format:
+ separator: '.'
+ delimiter: ','
+ precision: 2
+ format: '%u %n'
+ unit: '$'
+ percentage:
+ format:
+ delimiter: ','
+ precision:
+ format:
+ delimiter: ','
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "ليس بالامكان حفظ {{model}}: خطأ واحد."
+ other: "ليس بالامكان حفظ {{model}}: {{count}} أخطاء."
+ body: "يرجى التحقق من الحقول التالية:"
+ messages:
+ inclusion: "ليس خيارا مقبولا"
+ exclusion: "محجوز"
+ invalid: "غير معرف أو محدد"
+ confirmation: "لا تتوافق مع التأكيد"
+ accepted: "يجب أن تقبل"
+ empty: "فارغ، يرجى ملء الحقل"
+ blank: "فارغ، يرجى ملء الحقل"
+ too_long: "أطول من اللازم (الحد الأقصى هو {{count}})"
+ too_short: "أقصر من اللازم (الحد الأدنى هو {{count}})"
+ wrong_length: "بطول غير مناسب (يجب أن يكون {{count}})"
+ taken: "غير متوفر (مستخدم)"
+ not_a_number: "ليس رقما"
+ greater_than: "يجب أن يكون أكبر من {{count}}"
+ greater_than_or_equal_to: "يجب أن يكون أكبر من أو يساوي {{count}}"
+ equal_to: "يجب أن يساوي {{count}}"
+ less_than: "يجب أن يكون أصغر من {{count}}"
+ less_than_or_equal_to: "يجب أن يكون أصغر من أو يساوي {{count}}"
+ odd: "يجب أن يكون فردي"
+ even: "يجب أن يكون زوجي"
--- /dev/null
+# bs [Bosnian] are the same as bs_BA [Bosnian (Bosnia and Herzegovina)]
+# translations for Ruby on Rails by Dejan Dimić (dejan.dimic@gmail.com)
+
+"bs":
+ date:
+ formats:
+ default: "%d/%m/%Y"
+ short: "%e %b"
+ long: "%B %e, %Y"
+ only_day: "%e"
+
+ day_names: [nedjelja, ponedjeljak, utorak, srijeda, četvrtak, petak, subota]
+ abbr_day_names: [ned, pon, uto, sri, čet, pet, sub]
+ month_names: [~, Januar, Februar, Mart, April, Maj, Јun, Јul, Аvgust, Septembar, Оktobar, Novembar, Decembar]
+ abbr_month_names: [~, Jan, Feb, Mar, Apr, Мaj, Jun, Јul, Avg, Sep, Okt, Nov, Dec]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %b %d %H:%M:%S %Z %Y"
+ time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ only_second: "%S"
+
+ am: 'АМ'
+ pm: 'PМ'
+
+ datetime:
+ formats:
+ default: "%Y-%m-%dT%H:%M:%S%Z"
+ distance_in_words:
+ half_a_minute: 'pola minute'
+ less_than_x_seconds:
+ zero: 'manje od 1 sekunde'
+ one: 'manje od 1 sekunde'
+ few: 'manje od {{count}} sekunde'
+ other: 'manje od {{count}} sekundi'
+ x_seconds:
+ one: '1 sekunda'
+ few: '{{count}} sekunde'
+ other: '{{count}} sekundi'
+ less_than_x_minutes:
+ zero: 'manje оd minuta'
+ one: 'manje od 1 minut'
+ other: 'manje od {{count}} minuta'
+ x_minutes:
+ one: '1 minut'
+ other: '{{count}} minuta'
+ about_x_hours:
+ one: 'oko 1 sat'
+ few: 'око {{count}} sata'
+ other: 'око {{count}} sati'
+ x_days:
+ one: '1 dan'
+ other: '{{count}} dana'
+ about_x_months:
+ one: 'око 1 mjesec'
+ few: 'око {{count}} mjeseca'
+ other: 'око {{count}} mjeseci'
+ x_months:
+ one: '1 mjesec'
+ few: '{{count}} mjeseca'
+ other: '{{count}} mjeseci'
+ about_x_years:
+ one: 'око 1 godine'
+ other: 'око {{count}} godine'
+ over_x_years:
+ one: 'preko 1 godine'
+ other: 'preko {{count}} godine'
+
+ number:
+ format:
+ precision: 3
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: 'KM'
+ precision: 2
+ format: '%n %u'
+
+ support:
+ array:
+ sentence_connector: "i"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: 'nisam uspio sačuvati {{model}}: 1 greška.'
+ few: 'nisam uspio sačuvati {{model}}: {{count}} greške.'
+ other: 'nisam uspio sačuvati {{model}}: {{count}} greški.'
+ body: "Molim Vas da provjerite slijedeća polja:"
+ messages:
+ inclusion: "nije u listi"
+ exclusion: "nije dostupno"
+ invalid: "nije ispravan"
+ confirmation: "se ne slaže sa svojom potvrdom"
+ accepted: "mora biti prihvaćeno"
+ empty: "mora biti dat"
+ blank: "mora biti dat"
+ too_long: "je predugačak (ne više od {{count}} karaktera)"
+ too_short: "је prekratak (ne manje od {{count}} karaktera)"
+ wrong_length: "nije odgovarajuće dužine (mora biti {{count}} karaktera)"
+ taken: "је zauzeto"
+ not_a_number: "nije broj"
+ greater_than: "mora biti veće od {{count}}"
+ greater_than_or_equal_to: "mora biti veće ili jednako {{count}}"
+ equal_to: "mora biti jednako {{count}}"
+ less_than: "mora biti manje od {{count}}"
+ less_than_or_equal_to: "mora biti manje ili jednako {{count}}"
+ odd: "mora biti neparno"
+ even: "mora biti parno"
--- /dev/null
+# Czech translations for Ruby on Rails
+# by Karel Minařík (karmi@karmi.cz)
+
+{ :'cz' => {
+
+ # ActiveSupport
+ :support => {
+ :array => {
+ :two_words_connector => ' a ',
+ :sentence_connector => 'a',
+ :skip_last_comma => true
+ }
+ },
+
+ # Date
+ :date => {
+ :formats => {
+ :default => "%d. %m. %Y",
+ :short => "%d %b",
+ :long => "%d. %B %Y",
+ },
+ :day_names => %w{Neděle Pondělí Úterý Středa Čtvrtek Pátek Sobota},
+ :abbr_day_names => %w{Ne Po Út St Čt Pá So},
+ :month_names => %w{~ Leden Únor Březen Duben Květen Červen Červenec Srpen Září Říjen Listopad Prosinec},
+ :abbr_month_names => %w{~ Led Úno Bře Dub Kvě Čvn Čvc Srp Zář Říj Lis Pro},
+ :order => [:day, :month, :year]
+ },
+
+ # Time
+ :time => {
+ :formats => {
+ :default => "%a %d. %B %Y %H:%M %z",
+ :short => "%d. %m. %H:%M",
+ :long => "%A %d. %B %Y %H:%M",
+ },
+ :am => 'am',
+ :pm => 'pm'
+ },
+
+ # Numbers
+ :number => {
+ :format => {
+ :precision => 3,
+ :separator => '.',
+ :delimiter => ','
+ },
+ :currency => {
+ :format => {
+ :unit => 'Kč',
+ :precision => 2,
+ :format => '%n %u',
+ :separator => ",",
+ :delimiter => " ",
+ }
+ },
+ :human => {
+ :format => {
+ :precision => 1,
+ :delimiter => ''
+ },
+ :storage_units => {
+ :format => "%n %u",
+ :units => {
+ :byte => "B",
+ :kb => "KB",
+ :mb => "MB",
+ :gb => "GB",
+ :tb => "TB",
+ }
+ }
+ },
+ :percentage => {
+ :format => {
+ :delimiter => ''
+ }
+ },
+ :precision => {
+ :format => {
+ :delimiter => ''
+ }
+ }
+ },
+
+ # Distance of time ... helper
+ # NOTE: In Czech language, these values are different for the past and for the future. Preference has been given to past here.
+ :datetime => {
+ :distance_in_words => {
+ :half_a_minute => 'půl minutou',
+ :less_than_x_seconds => {
+ :one => 'asi před sekundou',
+ :other => 'asi před {{count}} sekundami'
+ },
+ :x_seconds => {
+ :one => 'sekundou',
+ :other => '{{count}} sekundami'
+ },
+ :less_than_x_minutes => {
+ :one => 'před necelou minutou',
+ :other => 'před ani ne {{count}} minutami'
+ },
+ :x_minutes => {
+ :one => 'minutou',
+ :other => '{{count}} minutami'
+ },
+ :about_x_hours => {
+ :one => 'asi hodinou',
+ :other => 'asi {{count}} hodinami'
+ },
+ :x_days => {
+ :one => '24 hodinami',
+ :other => '{{count}} dny'
+ },
+ :about_x_months => {
+ :one => 'asi měsícem',
+ :other => 'asi {{count}} měsíci'
+ },
+ :x_months => {
+ :one => 'měsícem',
+ :other => '{{count}} měsíci'
+ },
+ :about_x_years => {
+ :one => 'asi rokem',
+ :other => 'asi {{count}} roky'
+ },
+ :over_x_years => {
+ :one => 'více než před rokem',
+ :other => 'více než {{count}} roky'
+ }
+ }
+ },
+
+ # ActiveRecord validation messages
+ :activerecord => {
+ :errors => {
+ :messages => {
+ :inclusion => "není v seznamu povolených hodnot",
+ :exclusion => "je vyhrazeno pro jiný účel",
+ :invalid => "není platná hodnota",
+ :confirmation => "nebylo potvrzeno",
+ :accepted => "musí být potvrzeno",
+ :empty => "nesmí být prázdný/é",
+ :blank => "je povinná položka", # alternate formulation: "is required"
+ :too_long => "je příliš dlouhá/ý (max. {{count}} znaků)",
+ :too_short => "je příliš krátký/á (min. {{count}} znaků)",
+ :wrong_length => "nemá správnou délku (očekáváno {{count}} znaků)",
+ :taken => "již databáze obsahuje",
+ :not_a_number => "není číslo",
+ :greater_than => "musí být větší než {{count}}",
+ :greater_than_or_equal_to => "musí být větší nebo rovno {{count}}",
+ :equal_to => "musí být rovno {{count}}",
+ :less_than => "musí být méně než {{count}}",
+ :less_than_or_equal_to => "musí být méně nebo rovno {{count}}",
+ :odd => "musí být liché číslo",
+ :even => "musí být sudé číslo"
+ },
+ :template => {
+ :header => {
+ :one => "Při ukládání objektu {{model}} došlo k chybám a nebylo jej možné uložit",
+ :other => "Při ukládání objektu {{model}} došlo ke {{count}} chybám a nebylo možné jej uložit"
+ },
+ :body => "Následující pole obsahují chybně vyplněné údaje:"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+# Danish translation file for standard Ruby on Rails internationalization
+# by Lars Hoeg (larshoeg@gmail.com, http://www.lenio.dk/)
+
+da:
+ # active_support
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ short: "%e. %b %Y"
+ long: "%e. %B %Y"
+
+ day_names: [søndag, mandag, tirsdag, onsdag, torsdag, fredag, lørdag]
+ abbr_day_names: [sø, ma, ti, 'on', to, fr, lø]
+ month_names: [~, januar, februar, marts, april, maj, juni, juli, august, september, oktober, november, december]
+ abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%e. %B %Y, %H:%M"
+ short: "%e. %b %Y, %H:%M"
+ long: "%A, %e. %B %Y, %H:%M"
+ am: ""
+ pm: ""
+
+ support:
+ array:
+ # Rails 2.2
+ #sentence_connector: "og"
+ #skip_last_comma: true
+ # Rails 2.3
+ words_connector: ", "
+ two_words_connector: " og "
+ last_word_connector: " og "
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "et halvt minut"
+ less_than_x_seconds:
+ one: "mindre end et sekund"
+ other: "mindre end {{count}} sekunder"
+ x_seconds:
+ one: "et sekund"
+ other: "{{count}} sekunder"
+ less_than_x_minutes:
+ one: "mindre end et minut"
+ other: "mindre end {{count}} minutter"
+ x_minutes:
+ one: "et minut"
+ other: "{{count}} minutter"
+ about_x_hours:
+ one: "cirka en time"
+ other: "cirka {{count}} timer"
+ x_days:
+ one: "en dag"
+ other: "{{count}} dage"
+ about_x_months:
+ one: "cirka en måned"
+ other: "cirka {{count}} måneder"
+ x_months:
+ one: "en måned"
+ other: "{{count}} måneder"
+ about_x_years:
+ one: "cirka et år"
+ other: "cirka {{count}} år"
+ over_x_years:
+ one: "mere end et år"
+ other: "mere end {{count}} år"
+ prompts:
+ second: "Sekund"
+ minute: "Minut"
+ hour: "Time"
+ day: "Dag"
+ month: "Måned"
+ year: "År"
+
+ # action_view
+ number:
+ format:
+ separator: ","
+ delimiter: "."
+ precision: 3
+ currency:
+ format:
+ format: "%u %n"
+ unit: "DKK"
+ separator: ","
+ delimiter: "."
+ precision: 2
+ precision:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+ human:
+ format:
+ # separator:
+ delimiter: ""
+ precision: 1
+ # Rails 2.2
+ #storage_units: [Bytes, KB, MB, GB, TB]
+ # Rails 2.3
+ storage_units:
+ # Storage units output formatting.
+ # %u is the storage unit, %n is the number (default: 2 MB)
+ format: "%n %u"
+ units:
+ byte:
+ one: "Byte"
+ other: "Bytes"
+ kb: "KB"
+ mb: "MB"
+ gb: "GB"
+ tb: "TB"
+ percentage:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # active_record
+ activerecord:
+ errors:
+ messages:
+ inclusion: "er ikke i listen"
+ exclusion: "er reserveret"
+ invalid: "er ikke gyldig"
+ confirmation: "stemmer ikke overens"
+ accepted: "skal accepteres"
+ empty: "må ikke udelades"
+ blank: "skal udfyldes"
+ too_long: "er for lang (maksimum {{count}} tegn)"
+ too_short: "er for kort (minimum {{count}} tegn)"
+ wrong_length: "har forkert længde (skulle være {{count}} tegn)"
+ taken: "er allerede brugt"
+ not_a_number: "er ikke et tal"
+ greater_than: "skal være større end {{count}}"
+ greater_than_or_equal_to: "skal være større end eller lig med {{count}}"
+ equal_to: "skal være lig med {{count}}"
+ less_than: "skal være mindre end {{count}}"
+ less_than_or_equal_to: "skal være mindre end eller lig med {{count}}"
+ odd: "skal være ulige"
+ even: "skal være lige"
+
+ template:
+ header:
+ one: "En fejl forhindrede {{model}} i at blive gemt"
+ other: "{{count}} fejl forhindrede denne {{model}} i at blive gemt"
+ body: "Der var problemer med følgende felter:"
--- /dev/null
+# German translations for Ruby on Rails
+# by Clemens Kofler (clemens@railway.at)
+
+de:
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ short: "%e. %b"
+ long: "%e. %B %Y"
+ only_day: "%e"
+
+ day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
+ abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
+ month_names: [~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
+ abbr_month_names: [~, Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%A, %e. %B %Y, %H:%M Uhr"
+ short: "%e. %B, %H:%M Uhr"
+ long: "%A, %e. %B %Y, %H:%M Uhr"
+ time: "%H:%M"
+
+ am: "vormittags"
+ pm: "nachmittags"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: 'eine halbe Minute'
+ less_than_x_seconds:
+ zero: 'weniger als 1 Sekunde'
+ one: 'weniger als 1 Sekunde'
+ other: 'weniger als {{count}} Sekunden'
+ x_seconds:
+ one: '1 Sekunde'
+ other: '{{count}} Sekunden'
+ less_than_x_minutes:
+ zero: 'weniger als 1 Minute'
+ one: 'weniger als eine Minute'
+ other: 'weniger als {{count}} Minuten'
+ x_minutes:
+ one: '1 Minute'
+ other: '{{count}} Minuten'
+ about_x_hours:
+ one: 'etwa 1 Stunde'
+ other: 'etwa {{count}} Stunden'
+ x_days:
+ one: '1 Tag'
+ other: '{{count}} Tage'
+ about_x_months:
+ one: 'etwa 1 Monat'
+ other: 'etwa {{count}} Monate'
+ x_months:
+ one: '1 Monat'
+ other: '{{count}} Monate'
+ about_x_years:
+ one: 'etwa 1 Jahr'
+ other: 'etwa {{count}} Jahre'
+ over_x_years:
+ one: 'mehr als 1 Jahr'
+ other: 'mehr als {{count}} Jahre'
+
+ number:
+ format:
+ precision: 2
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: '€'
+ format: '%n%u'
+ separator:
+ delimiter:
+ precision:
+ percentage:
+ format:
+ delimiter: ""
+ precision:
+ format:
+ delimiter: ""
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+
+ support:
+ array:
+ sentence_connector: "und"
+ skip_last_comma: true
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Konnte dieses {{model}} Objekt nicht speichern: 1 Fehler."
+ other: "Konnte dieses {{model}} Objekt nicht speichern: {{count}} Fehler."
+ body: "Bitte überprüfen Sie die folgenden Felder:"
+
+ messages:
+ inclusion: "ist kein gültiger Wert"
+ exclusion: "ist nicht verfügbar"
+ invalid: "ist nicht gültig"
+ confirmation: "stimmt nicht mit der Bestätigung überein"
+ accepted: "muss akzeptiert werden"
+ empty: "muss ausgefüllt werden"
+ blank: "muss ausgefüllt werden"
+ too_long: "ist zu lang (nicht mehr als {{count}} Zeichen)"
+ too_short: "ist zu kurz (nicht weniger als {{count}} Zeichen)"
+ wrong_length: "hat die falsche Länge (muss genau {{count}} Zeichen haben)"
+ taken: "ist bereits vergeben"
+ not_a_number: "ist keine Zahl"
+ greater_than: "muss größer als {{count}} sein"
+ greater_than_or_equal_to: "muss größer oder gleich {{count}} sein"
+ equal_to: "muss genau {{count}} sein"
+ less_than: "muss kleiner als {{count}} sein"
+ less_than_or_equal_to: "muss kleiner oder gleich {{count}} sein"
+ odd: "muss ungerade sein"
+ even: "muss gerade sein"
+ models:
--- /dev/null
+# Estonian localization for Ruby on Rails 2.2+
+# by Zahhar Kirillov <zahhar@gmail.com>
+
+ee:
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ short: "%d.%m.%y"
+ long: "%d. %B %Y"
+
+ day_names: [pühapäev, esmaspäev, teisipäev, kolmapäev, neljapäev, reede, laupäev]
+ standalone_day_names: [Pühapäev, Esmaspäev, Teisipäev, Kolmapäev, Neljapäev, Reede, Laupäev]
+ abbr_day_names: [P, E, T, K, N, R, L]
+
+ month_names: [~, jaanuar, veebruar, märts, aprill, mai, juuni, juuli, august, september, oktoober, november, detsember]
+ standalone_month_names: [~, Jaanuar, Veebruar, Märts, Aprill, Mai, Juuni, Juuli, August, September, Oktoober, November, Detsember]
+ abbr_month_names: [~, jaan., veebr., märts, apr., mai, juuni, juuli, aug., sept., okt., nov., dets.]
+ standalone_abbr_month_names: [~, jaan., veebr., märts, apr., mai, juuni, juuli, aug., sept., okt., nov., dets.]
+
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%d. %B %Y, %H:%M"
+ short: "%d.%m.%y, %H:%M"
+ long: "%a, %d. %b %Y, %H:%M:%S %z"
+
+ am: "enne lõunat"
+ pm: "pärast lõunat"
+
+ number:
+ format:
+ separator: ","
+ delimiter: " "
+ precision: 2
+
+ currency:
+ format:
+ format: "%n %u"
+ unit: "kr"
+ separator: ","
+ delimiter: " "
+ precision: 2
+
+ percentage:
+ format:
+ delimiter: ""
+
+ precision:
+ format:
+ delimiter: ""
+
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [bait, KB, MB, GB, TB]
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "pool minutit"
+ less_than_x_seconds:
+ one: "vähem kui {{count}} sekund"
+ other: "vähem kui {{count}} sekundit"
+ x_seconds:
+ one: "{{count}} sekund"
+ other: "{{count}} sekundit"
+ less_than_x_minutes:
+ one: "vähem kui {{count}} minut"
+ other: "vähem kui {{count}} minutit"
+ x_minutes:
+ one: "{{count}} minut"
+ other: "{{count}} minutit"
+ about_x_hours:
+ one: "umbes {{count}} tund"
+ other: "umbes {{count}} tundi"
+ x_days:
+ one: "{{count}} päev"
+ other: "{{count}} päeva"
+ about_x_months:
+ one: "umbes {{count}} kuu"
+ other: "umbes {{count}} kuud"
+ x_months:
+ one: "{{count}} kuu"
+ other: "{{count}} kuud"
+ about_x_years:
+ one: "umbes {{count}} aasta"
+ other: "umbes {{count}} aastat"
+ over_x_years:
+ one: "üle {{count}} aasta"
+ other: "üle {{count}} aastat"
+ prompts:
+ year: "Aasta"
+ month: "Kuu"
+ day: "Päev"
+ hour: "Tunde"
+ minute: "Minutit"
+ second: "Sekundit"
+
+ support:
+ array:
+ # Rails 2.2
+ sentence_connector: "ja"
+ skip_last_comma: true
+
+ # Rails 2.3
+ words_connector: ", "
+ two_words_connector: " ja "
+ last_word_connector: " ja "
--- /dev/null
+# Greek translations for Ruby on Rails
+# by Nick Kokkos (nkokkos@gmail.com)
+
+el:
+ number:
+ # Used in number_with_delimiter()
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+ format:
+ # Sets the separator between the units, for more precision (e.g. 1,0 / 2,0 == 0,5)
+ separator: ","
+ # Delimets thousands (e.g. 1.000.000 is a million) (always in groups of three)
+ delimiter: "."
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1,00)
+ precision: 3
+
+ # Used in number_to_currency()
+ currency:
+ format:
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+ # in Greek currency values would be represented as (e.g €5,78:five euros and seventy eight cents or €1.012,45: one thousand twelve euros and 45 cents)
+ format: "%u%n"
+ unit: "€"
+ # These three are to override number.format and are optional
+ separator: ","
+ delimiter: "."
+ precision: 2
+
+ # Used in number_to_percentage()
+ percentage:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_precision()
+ precision:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_human_size()
+ human:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ precision: 1
+ storage_units: [Bytes, KB, MB, GB, TB]
+
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+ datetime:
+ distance_in_words:
+ half_a_minute: "μισό λεπτό"
+ less_than_x_seconds:
+ one: "λιγότερο απο ένα δευτερόλεπτο"
+ other: "λιγότερο απο {{count}} δευτερόλεπτα"
+ x_seconds:
+ one: "1 δευτερόλεπτο"
+ other: "{{count}} δευτερόλεπτα"
+ less_than_x_minutes:
+ one: "λιγότερο απο ένα λεπτό"
+ other: "λιγότερο απο {{count}} λεπτά"
+ x_minutes:
+ one: "ένα λεπτό"
+ other: "{{count}} λεπτά"
+ about_x_hours:
+ one: "1 ώρα περίπου"
+ other: "{{count}} hours περίπου"
+ x_days:
+ one: "1 μέρα"
+ other: "{{count}} μέρες"
+ about_x_months:
+ one: "1 μήνα περίπου"
+ other: "{{count}} μήνες περίπου"
+ x_months:
+ one: "1 μήνα"
+ other: "{{count}} μήνες"
+ about_x_years:
+ one: "ένα χρόνο περίπου"
+ other: "{{count}} χρόνια περίπου"
+ over_x_years:
+ one: "πάνω απο 1 χρόνο"
+ other: "πάνω απο {{count}} χρόνια"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "1 λάθος παρεμπόδισε αυτό το {{model}} να αποθηκευθεί"
+ other: "{{count}} λάθη εμπόδισαν αυτό το {{model}} να αποθηκευθεί"
+ # The variable :count is also available
+ body: "Υπήρξαν προβλήματα με τα ακόλουθα πεδία :"
+
+
+ activerecord:
+ errors:
+ # The values :model, :attribute and :value are always available for interpolation
+ # The value :count is available when applicable. Can be used for pluralization.
+ messages:
+ inclusion: "δεν συμπεριλαβάνεται στη λίστα"
+ exclusion: "είναι δεσμευμένο"
+ invalid: "είναι άκυρο"
+ confirmation: "δεν ταιριάζει με την επικύρωση"
+ accepted: "πρέπει να είναι αποδεκτό"
+ empty: "δεν πρέπει να είναι άδειο"
+ blank: "δεν πρέπει να είναι κενό"
+ too_long: "είναι πολύ μεγάλο (το μέγιστο μήκος είναι {{count}} χαρακτήρες)"
+ too_short: "είναι πολύ μικρό (το μικρότερο μήκος είναι {{count}} χαρακτήρες)"
+ wrong_length: "έχει λανθασμένο μήκος (πρέπει να είναι {{count}} χαρακτήρες)"
+ taken: "το έχουν ήδη χρησιμοποιήσει"
+ not_a_number: "δεν είναι ένας αριθμός"
+ greater_than: "πρέπει να είναι μεγαλύτερο απο {{count}}"
+ greater_than_or_equal_to: "πρέπει να είναι μεγαλύτερο ή ίσον με {{count}}"
+ equal_to: "πρέπει να είναι ίσον με {{count}}"
+ less_than: "πρέπει να είναι λιγότερο απο {{count}}"
+ less_than_or_equal_to: "πρέπει να είναι λιγότερο ή ίσον με {{count}}"
+ odd: "πρέπει να είναι περιττός"
+ even: "πρέπει να είναι άρτιος"
+ # Append your own errors here or at the model/attributes scope.
+
+ # You can define own errors for models or model attributes.
+ # The values :model, :attribute and :value are always available for interpolation.
+ #
+ # For example,
+ # models:
+ # user:
+ # blank: "This is a custom blank message for {{model}}: {{attribute}}"
+ # attributes:
+ # login:
+ # blank: "This is a custom blank message for User login"
+ # Will define custom blank validation message for User model and
+ # custom blank validation message for login attribute of User model.
+ # models:
+
+ # Translate model names. Used in Model.human_name().
+ #models:
+ # For example,
+ # user: "Dude"
+ # will translate User model name to "Dude"
+
+ # Translate model attribute names. Used in Model.human_attribute_name(attribute).
+ #attributes:
+ # For example,
+ # user:
+ # login: "Handle"
+ # will translate User attribute "login" as "Handle"
+
+
+ date:
+ formats:
+ # Use the strftime parameters for formats.
+ # When no format has been given, it uses default.
+ # You can provide other formats here if you like!
+ default: "%d-%m-%Y"
+ short: "%d %b"
+ long: "%d %B %Y"
+ only_day: "%e"
+
+ day_names: [Κυριακή, Δευτέρα, Τρίτη, Τετάρτη, Πέμπτη, Παρασκευή, Σάββατο]
+ abbr_day_names: [Κυρ, Δευ, Τρι, Τετ, Πεμ, Παρ, Σαβ]
+
+ # Don't forget the nil at the beginning; there's no such thing as a 0th month
+ month_names: [~, Ιανοάριος, Φεβρουάριος, Μάρτιος, Απρίλιος, Μάιος, Ιούνιος, Ιούλιος, Άυγουστος, Σεπτέμβριος, Οκτώβριος, Νοέμβριος, Δεκέμβριος]
+ abbr_month_names: [~, Ιαν, Φεβ, Μάρ, Απρ, Μαι, Ιουν, Ιούλ, Αυγ, Σεπ, Οκτ, Νοε, Δεκ]
+ # Used in date_select and datime_select.
+ # original was: order: [ :year, :month, :day ]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %d %b %Y, %H:%M:%S %z"
+ time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%d %B %Y %H:%M"
+ only_second: "%S"
+ am: "am"
+ pm: "pm"
+
+ datetime:
+ formats:
+ default: "%d-%m-%YT%H:%M:%S%Z"
+
+
+# Used in array.to_sentence.
+ support:
+ array:
+ sentence_connector: "και"
+ skip_last_comma: false
--- /dev/null
+{
+ :'es-AR' => {
+
+ :date => {
+ :formats => {
+ :default => "%e/%m/%Y",
+ :short => "%e %b",
+ :long => "%e de %B de %Y",
+ :only_day => "%e"
+ },
+ :day_names => %w(Domingo Lunes Martes Miércoles Jueves Viernes Sábado),
+ :abbr_day_names => %w(Dom Lun Mar Mie Jue Vie Sab),
+ :month_names => [nil] + %w(Enero Febrero Marzo Abril Mayo Junio Julio Agosto Setiembre Octubre Noviembre Diciembre),
+ :abbr_month_names => [nil] + %w(Ene Feb Mar Abr May Jun Jul Ago Set Oct Nov Dic),
+ :order => [:day, :month, :year]
+ },
+ :time => {
+ :formats => {
+ :default => "%A, %e de %B de %Y, %H:%M hs",
+ :time => "%H:%M hs",
+ :short => "%e/%m, %H:%M hs",
+ :long => "%A, %e de %B de %Y, %H:%M hs",
+ :only_second => "%S"
+ },
+ :datetime => {
+ :formats => {
+ :default => "%d/%m/%Y-%dT%H:%M:%S%Z"
+ }
+ },
+ :time_with_zone => {
+ :formats => {
+ :default => lambda { |time| "%Y-%m-%d %H:%M:%S #{time.formatted_offset(false, 'UTC')}" }
+ }
+ },
+ :am => 'am',
+ :pm => 'pm'
+ },
+ # date helper distancia en palabras
+ #NOTE: Pluralization rules have changed! Rather than simply submitting an array, i18n now allows for a hash with the keys:
+ # :zero, :one & :other - FUNKY (but a pain to find...)!
+ :datetime => {
+ :distance_in_words => {
+ :half_a_minute => 'medio minuto',
+ :less_than_x_seconds => {:zero => 'menos de 1 segundo', :one => 'menos de 1 segundo', :other => 'menos de {{count}} segundos'},
+ :x_seconds => {:one => '1 second', :other => '{{count}} seconds'},
+ :less_than_x_minutes => {:zero => 'menos de 1 minuto', :one => 'menos de 1 minuto', :other => 'menos de {{count}} minutos'},
+ :x_minutes => {:one => "1 minuto", :other => "{{count}} minutos"},
+ :about_x_hours => {:one => 'aproximadamente 1 hora', :other => 'aproximadamente {{count}} horas'},
+ :x_days => {:one => '1 día', :other => '{{count}} días'},
+ :about_x_months => {:one => 'aproximandamente 1 mes', :other => 'aproximadamente {{count}} mes'},
+ :x_months => {:one => '1 month', :other => '{{count}} mes'},
+ :about_x_years => {:one => 'aproximadamente 1 año', :other => 'aproximadamente {{count}} años'},
+ :over_x_years => {:one => 'más de 1 año', :other => 'más de {{count}} años'}
+ }
+ },
+
+ # numbers
+ :number => {
+ :format => {
+ :precision => 3,
+ :separator => ',',
+ :delimiter => '.'
+ },
+ :currency => {
+ :format => {
+ :unit => '$',
+ :precision => 2,
+ :format => '%u %n'
+ }
+ }
+ },
+
+ # Active Record
+ :activerecord => {
+ :errors => {
+ :template => {
+ :header => {
+ :one => "{{model}} no pudo guardarse: 1 error",
+ :other => "{{model}}: {{count}} errores."
+ },
+ :body => "Por favor revise los campos siguientes:"
+ },
+ :messages => {
+ :inclusion => "no está incluido en la lista",
+ :exclusion => "no está disponible",
+ :invalid => "no es válido",
+ :confirmation => "no coincide con la confirmación",
+ :accepted => "debe ser aceptado",
+ :empty => "no puede estar vacío",
+ :blank => "no puede estar en blanco",
+ :too_long => "es demasiado largo (no más de {{count}} caracteres)",
+ :too_short => "es demasiado corto (no menos de {{count}} caracteres)",
+ :wrong_length => "no tiene la longitud correcta (debe ser de {{count}} caracteres)",
+ :taken => "no está disponible",
+ :not_a_number => "no es un número",
+ :greater_than => "debe ser mayor a {{count}}",
+ :greater_than_or_equal_to => "debe ser mayor o igual a {{count}}",
+ :equal_to => "debe ser igual a {{count}}",
+ :less_than => "debe ser menor que {{count}}",
+ :less_than_or_equal_to => "debe ser menor o igual que {{count}}",
+ :odd => "debe ser par",
+ :even => "debe ser impar"
+ }
+ }
+ }
+ }
+}
--- /dev/null
+# Spanish as spoken in Mexico (es-MX) translations for Rails
+# by Edgar J. Suárez (edgar.js@gmail.com)
+
+es-MX:
+ number:
+ percentage:
+ format:
+ delimiter: ""
+ currency:
+ format: "%u%n"
+ delimiter: ","
+ unit: "$"
+ precision: 2
+ separator: "."
+ format:
+ delimiter: ","
+ precision: 3
+ separator: "."
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [Bytes, KB, MB, GB, TB]
+ precision:
+ format:
+ delimiter: ""
+
+ date:
+ order: [:day, :month, :year]
+ abbr_day_names: [Dom, Lun, Mar, Mie, Jue, Vie, Sab]
+ abbr_month_names: [~, Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dic]
+ day_names: [Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado]
+ month_names: [~, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre]
+ formats:
+ short: "%d de %b"
+ default: "%d/%m/%Y"
+ long: "%A, %d de %B de %Y"
+ time:
+ formats:
+ short: "%d de %b a las %H:%M hrs"
+ default: "%a, %d de %b de %Y a las %H:%M:%S %Z"
+ long: "%A, %d de %B de %Y a las %I:%M %p"
+ am: "am"
+ pm: "pm"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "medio minuto"
+ less_than_x_seconds:
+ one: "menos de 1 segundo"
+ other: "menos de {{count}} segundos"
+ x_seconds:
+ one: "1 segundo"
+ other: "{{count}} segundos"
+ less_than_x_minutes:
+ one: "menos de 1 minuto"
+ other: "menos de {{count}} minutos"
+ x_minutes:
+ one: "1 minuto"
+ other: "{{count}} minutos"
+ about_x_hours:
+ one: "cerca de 1 hora"
+ other: "cerca de {{count}} horas"
+ x_days:
+ one: "1 día"
+ other: "{{count}} días"
+ about_x_months:
+ one: "cerca de 1 mes"
+ other: "cerca de {{count}} meses"
+ x_months:
+ one: "1 mes"
+ other: "{{count}} meses"
+ about_x_years:
+ other: "cerca de {{count}} años"
+ one: "cerca de 1 año"
+ over_x_years:
+ one: "más de 1 año"
+ other: "más de {{count}} años"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "{{model}} no pudo guardarse debido a 1 error"
+ other: "{{model}} no pudo guardarse debido a {{count}} errores"
+ body: "Revise que los siguientes campos sean válidos:"
+ messages:
+ inclusion: "no está incluído en la lista"
+ exclusion: "está reservado"
+ invalid: "es inválido"
+ invalid_date: "es una fecha inválida"
+ confirmation: "no coincide con la confirmación"
+ blank: "no puede estar en blanco"
+ empty: "no puede estar vacío"
+ not_a_number: "no es un número"
+ taken: "ya ha sido tomado"
+ less_than: "debe ser menor que {{count}}"
+ less_than_or_equal_to: "debe ser menor o igual que {{count}}"
+ greater_than: "debe ser mayor que {{count}}"
+ greater_than_or_equal_to: "debe ser mayor o igual que {{count}}"
+ too_short:
+ one: "es demasiado corto (mínimo 1 caracter)"
+ other: "es demasiado corto (mínimo {{count}} caracteres)"
+ too_long:
+ one: "es demasiado largo (máximo 1 caracter)"
+ other: "es demasiado largo (máximo {{count}} caracteres)"
+ equal_to: "debe ser igual a {{count}}"
+ wrong_length:
+ one: "longitud errónea (debe ser de 1 caracter)"
+ other: "longitud errónea (debe ser de {{count}} caracteres)"
+ accepted: "debe ser aceptado"
+ even: "debe ser un número par"
+ odd: "debe ser un número non"
--- /dev/null
+# Spanish translations for Rails
+# by Francisco Fernando García Nieto (ffgarcianieto@gmail.com)
+
+es:
+ number:
+ # Used in number_with_delimiter()
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+ format:
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+ separator: ","
+ # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+ delimiter: "."
+ # Number of decimals, behind the separator (1 with a precision of 2 gives: 1.00)
+ precision: 3
+
+ # Used in number_to_currency()
+ currency:
+ format:
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+ format: "%n %u"
+ unit: "€"
+ # These three are to override number.format and are optional
+ separator: ","
+ delimiter: "."
+ precision: 2
+
+ # Used in number_to_percentage()
+ percentage:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_precision()
+ precision:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_human_size()
+ human:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ precision: 1
+ # Rails <= v2.2.2
+ # storage_units: [Bytes, KB, MB, GB, TB]
+ # Rails >= v2.3
+ storage_units:
+ format: "%n %u"
+ units:
+ byte:
+ one: "Byte"
+ other: "Bytes"
+ kb: "KB"
+ mb: "MB"
+ gb: "GB"
+ tb: "TB"
+
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+ datetime:
+ distance_in_words:
+ half_a_minute: "medio minuto"
+ less_than_x_seconds:
+ one: "menos de 1 segundo"
+ other: "menos de {{count}} segundos"
+ x_seconds:
+ one: "1 segundo"
+ other: "{{count}} segundos"
+ less_than_x_minutes:
+ one: "menos de 1 minuto"
+ other: "menos de {{count}} minutos"
+ x_minutes:
+ one: "1 minuto"
+ other: "{{count}} minutos"
+ about_x_hours:
+ one: "alrededor de 1 hora"
+ other: "alrededor de {{count}} horas"
+ x_days:
+ one: "1 día"
+ other: "{{count}} días"
+ about_x_months:
+ one: "alrededor de 1 mes"
+ other: "alrededor de {{count}} meses"
+ x_months:
+ one: "1 mes"
+ other: "{{count}} meses"
+ about_x_years:
+ one: "alrededor de 1 año"
+ other: "alrededor de {{count}} años"
+ over_x_years:
+ one: "más de 1 año"
+ other: "más de {{count}} años"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "no se pudo guardar este {{model}} porque se encontró 1 error"
+ other: "no se pudo guardar este {{model}} porque se encontraron {{count}} errores"
+ # The variable :count is also available
+ body: "Se encontraron problemas con los siguientes campos:"
+
+ # The values :model, :attribute and :value are always available for interpolation
+ # The value :count is available when applicable. Can be used for pluralization.
+ messages:
+ inclusion: "no está incluido en la lista"
+ exclusion: "está reservado"
+ invalid: "no es válido"
+ confirmation: "no coincide con la confirmación"
+ accepted: "debe ser aceptado"
+ empty: "no puede estar vacío"
+ blank: "no puede estar en blanco"
+ too_long: "es demasiado largo ({{count}} caracteres máximo)"
+ too_short: "es demasiado corto ({{count}} caracteres mínimo)"
+ wrong_length: "no tiene la longitud correcta ({{count}} caracteres exactos)"
+ taken: "ya está en uso"
+ not_a_number: "no es un número"
+ greater_than: "debe ser mayor que {{count}}"
+ greater_than_or_equal_to: "debe ser mayor que o igual a {{count}}"
+ equal_to: "debe ser igual a {{count}}"
+ less_than: "debe ser menor que {{count}}"
+ less_than_or_equal_to: "debe ser menor que o igual a {{count}}"
+ odd: "debe ser impar"
+ even: "debe ser par"
+
+ # Append your own errors here or at the model/attributes scope.
+
+ models:
+ # Overrides default messages
+
+ attributes:
+ # Overrides model and default messages.
+
+ date:
+ formats:
+ # Use the strftime parameters for formats.
+ # When no format has been given, it uses default.
+ # You can provide other formats here if you like!
+ default: "%e/%m/%Y"
+ short: "%d de %b"
+ long: "%d de %B de %Y"
+
+ day_names: [Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado]
+ abbr_day_names: [Dom, Lun, Mar, Mie, Jue, Vie, Sab]
+
+ # Don't forget the nil at the beginning; there's no such thing as a 0th month
+ month_names: [~, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Setiembre, Octubre, Noviembre, Diciembre]
+ abbr_month_names: [~, Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Set, Oct, Nov, Dic]
+ # Used in date_select and datime_select.
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%A, %d de %B de %Y %H:%M:%S %z"
+ short: "%d de %b %H:%M"
+ long: "%d de %B de %Y %H:%M"
+ am: "am"
+ pm: "pm"
+
+# Used in array.to_sentence.
+ support:
+ array:
+ # Rails <= v.2.2.2
+ # sentence_connector: "y"
+ # Rails >= v.2.3
+ words_connector: ", "
+ two_words_connector: " y "
+ last_word_connector: " y "
\ No newline at end of file
--- /dev/null
+# Persian translations for Ruby on Rails
+# by Reza (reza@balatarin.com)
+
+fa:
+ number:
+ format:
+ precision: 2
+ separator: '٫'
+ delimiter: '٬'
+ currency:
+ format:
+ unit: 'ریال'
+ format: '%n %u'
+ separator: '٫'
+ delimiter: '٬'
+ precision: 0
+ percentage:
+ format:
+ delimiter: ""
+ precision:
+ format:
+ delimiter: ""
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [بایت, کیلوبایت, مگابایت, گیگابایت, ترابایت]
+
+ date:
+ formats:
+ default: "%Y/%m/%d"
+ short: "%m/%d"
+ long: "%e %B %Y"
+ only_day: "%e"
+
+ day_names: [یکشنبه, دوشنبه, سهشنبه, چهارشنبه, پنجشنبه, جمعه, شنبه]
+ abbr_day_names: [ی, د, س, چ, پ, ج]
+ month_names: [~, ژانویه, فوریه, مارس, آوریل, مه, ژوئن, ژوئیه, اوت, سپتامبر, اکتبر, نوامبر, دسامبر]
+ abbr_month_names: [~, ژانویه, فوریه, مارس, آوریل, مه, ژوئن, ژوئیه, اوت, سپتامبر, اکتبر, نوامبر, دسامبر]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%A، %e %B %Y، ساعت %H:%M:%S (%Z)"
+ short: "%e %B، ساعت %H:%M"
+ long: "%e %B %Y، ساعت %H:%M"
+ time: "%H:%M"
+ am: "قبل از ظهر"
+ pm: "بعد از ظهر"
+
+ support:
+ array:
+ sentence_connector: "و"
+ skip_last_comma: true
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "نیم دقیقه"
+ less_than_x_seconds:
+ zero: "کمتر از ۱ ثانیه"
+ one: "۱ ثانیه"
+ other: "کمتر از {{count}} ثانیه"
+ x_seconds:
+ one: "۱ ثانیه"
+ other: "{{count}} ثانیه"
+ less_than_x_minutes:
+ one: "کمتر از ۱ دقیقه"
+ other: "کمتر از {{count}} دقیقه"
+ x_minutes:
+ one: "۱ دقیقه"
+ other: "{{count}} دقیقه"
+ about_x_hours:
+ one: "حدود ۱ ساعت"
+ other: "حدود {{count}} ساعت"
+ x_days:
+ one: "۱ روز"
+ other: "{{count}} روز"
+ about_x_months:
+ one: "حدود ۱ ماه"
+ other: "حدود {{count}} ماه"
+ x_months:
+ one: "۱ ماه"
+ other: "{{count}} ماه"
+ about_x_years:
+ one: "حدود ۱ سال"
+ other: "حدود {{count}} سال"
+ over_x_years:
+ one: "بیش از ۱ سال"
+ other: "بیش از {{count}} سال"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "1 خطا جلوی ذخیره این {{model}} را گرفت"
+ other: "{{count}} خطا جلوی ذخیره این {{model}} را گرفت"
+ body: "موارد زیر مشکل داشت:"
+ messages:
+ inclusion: "در لیست موجود نیست"
+ exclusion: "رزرو است"
+ invalid: "نامعتبر است"
+ confirmation: "با تایید نمیخواند"
+ accepted: "باید پذیرفته شود"
+ empty: "نمیتواند خالی باشد"
+ blank: "نباید خالی باشد"
+ too_long: "بلند است (حداکثر {{count}} کاراکتر)"
+ too_short: "کوتاه است (حداقل {{count}} کاراکتر)"
+ wrong_length: "نااندازه است (باید {{count}} کاراکتر باشد)"
+ taken: "پیشتر گرفته شده"
+ not_a_number: "عدد نیست"
+ greater_than: "باید بزرگتر از {{count}} باشد"
+ greater_than_or_equal_to: "باید بزرگتر یا برابر {{count}} باشد"
+ equal_to: "باید برابر {{count}} باشد"
+ less_than: "باید کمتر از {{count}} باشد"
+ less_than_or_equal_to: "باید کمتر یا برابر {{count}} باشد"
+ odd: "باید فرد باشد"
+ even: "باید زوج باشد"
+ presence: "را فراموش کردهاید"
+ format: "فرمت مشکل دارد"
\ No newline at end of file
--- /dev/null
+# Finnish translations for Ruby on Rails
+# by Marko Seppä (marko.seppa@gmail.com)
+
+fi:
+ date:
+ formats:
+ default: "%e. %Bta %Y"
+ long: "%A%e. %Bta %Y"
+ short: "%e.%m.%Y"
+
+ day_names: [Sunnuntai, Maanantai, Tiistai, Keskiviikko, Torstai, Perjantai, Lauantai]
+ abbr_day_names: [Su, Ma, Ti, Ke, To, Pe, La]
+ month_names: [~, Tammikuu, Helmikuu, Maaliskuu, Huhtikuu, Toukokuu, Kesäkuu, Heinäkuu, Elokuu, Syyskuu, Lokakuu, Marraskuu, Joulukuu]
+ abbr_month_names: [~, Tammi, Helmi, Maalis, Huhti, Touko, Kesä, Heinä, Elo, Syys, Loka, Marras, Joulu]
+ order: [:day, :month, :year]
+
+ time:
+ formats:
+ default: "%a, %e. %b %Y %H:%M:%S %z"
+ short: "%e. %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ am: "aamupäivä"
+ pm: "iltapäivä"
+
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " ja "
+ last_word_connector: " ja "
+
+
+
+ number:
+ format:
+ separator: ","
+ delimiter: "."
+ precision: 3
+
+ currency:
+ format:
+ format: "%n %u"
+ unit: "€"
+ separator: ","
+ delimiter: "."
+ precision: 2
+
+ percentage:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ precision:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [Tavua, KB, MB, GB, TB]
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "puoli minuuttia"
+ less_than_x_seconds:
+ one: "aiemmin kuin sekunti"
+ other: "aiemmin kuin {{count}} sekuntia"
+ x_seconds:
+ one: "sekunti"
+ other: "{{count}} sekuntia"
+ less_than_x_minutes:
+ one: "aiemmin kuin minuutti"
+ other: "aiemmin kuin {{count}} minuuttia"
+ x_minutes:
+ one: "minuutti"
+ other: "{{count}} minuuttia"
+ about_x_hours:
+ one: "noin tunti"
+ other: "noin {{count}} tuntia"
+ x_days:
+ one: "päivä"
+ other: "{{count}} päivää"
+ about_x_months:
+ one: "noin kuukausi"
+ other: "noin {{count}} kuukautta"
+ x_months:
+ one: "kuukausi"
+ other: "{{count}} kuukautta"
+ about_x_years:
+ one: "vuosi"
+ other: "noin {{count}} vuotta"
+ over_x_years:
+ one: "yli vuosi"
+ other: "yli {{count}} vuotta"
+ prompts:
+ year: "Vuosi"
+ month: "Kuukausi"
+ day: "Päivä"
+ hour: "Tunti"
+ minute: "Minuutti"
+ second: "Sekuntia"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "1 virhe esti tämän {{model}} mallinteen tallentamisen"
+ other: "{{count}} virhettä esti tämän {{model}} mallinteen tallentamisen"
+ body: "Seuraavat kentät aiheuttivat ongelmia:"
+ messages:
+ inclusion: "ei löydy listauksesta"
+ exclusion: "on jo varattu"
+ invalid: "on kelvoton"
+ confirmation: "ei vastaa varmennusta"
+ accepted: "täytyy olla hyväksytty"
+ empty: "ei voi olla tyhjä"
+ blank: "ei voi olla sisällötön"
+ too_long: "on liian pitkä (maksimi on {{count}} merkkiä)"
+ too_short: "on liian lyhyt (minimi on {{count}} merkkiä)"
+ wrong_length: "on väärän pituinen (täytyy olla täsmälleen {{count}} merkkiä)"
+ taken: "on jo käytössä"
+ not_a_number: "ei ole numero"
+ greater_than: "täytyy olla suurempi kuin {{count}}"
+ greater_than_or_equal_to: "täytyy olla suurempi tai yhtä suuri kuin{{count}}"
+ equal_to: "täytyy olla yhtä suuri kuin {{count}}"
+ less_than: "täytyy olla pienempi kuin {{count}}"
+ less_than_or_equal_to: "täytyy olla pienempi tai yhtä suuri kuin {{count}}"
+ odd: "täytyy olla pariton"
+ even: "täytyy olla parillinen"
\ No newline at end of file
--- /dev/null
+# French (Switzerland) translations for Ruby on Rails
+# by Yann Lugrin (yann.lugrin@sans-savoir.net, http://github.com/yannlugrin)
+#
+# original translation into French by Christian Lescuyer
+# contributor: Sebastien Grosjean - ZenCocoon.com
+
+fr-CH:
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ short: "%e. %b"
+ long: "%e. %B %Y"
+ long_ordinal: "%e %B %Y"
+ only_day: "%e"
+
+ day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]
+ abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]
+ month_names: [~, janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre]
+ abbr_month_names: [~, jan., fév., mar., avr., mai, juin, juil., août, sept., oct., nov., déc.]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%d. %B %Y %H:%M"
+ time: "%H:%M"
+ short: "%d. %b %H:%M"
+ long: "%A, %d. %B %Y %H:%M:%S %Z"
+ long_ordinal: "%A %d %B %Y %H:%M:%S %Z"
+ only_second: "%S"
+ am: 'am'
+ pm: 'pm'
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "une demi-minute"
+ less_than_x_seconds:
+ one: "moins d'une seconde"
+ other: "moins de {{count}} secondes"
+ x_seconds:
+ one: "1 seconde"
+ other: "{{count}} secondes"
+ less_than_x_minutes:
+ one: "moins d'une minute"
+ other: "moins de {{count}} minutes"
+ x_minutes:
+ one: "1 minute"
+ other: "{{count}} minutes"
+ about_x_hours:
+ one: "environ une heure"
+ other: "environ {{count}} heures"
+ x_days:
+ one: "1 jour"
+ other: "{{count}} jours"
+ about_x_months:
+ one: "environ un mois"
+ other: "environ {{count}} mois"
+ x_months:
+ one: "1 mois"
+ other: "{{count}} mois"
+ about_x_years:
+ one: "environ un an"
+ other: "environ {{count}} ans"
+ over_x_years:
+ one: "plus d'un an"
+ other: "plus de {{count}} ans"
+ prompts:
+ year: "Année"
+ month: "Mois"
+ day: "Jour"
+ hour: "Heure"
+ minute: "Minute"
+ second: "Seconde"
+
+ number:
+ format:
+ precision: 3
+ separator: '.'
+ delimiter: "'"
+ currency:
+ format:
+ unit: 'CHF'
+ precision: 2
+ format: '%n %u'
+ human:
+ format:
+ precision: 2
+ storage_units: [ Octet, ko, Mo, Go, To ]
+
+ support:
+ array:
+ sentence_connector: 'et'
+ skip_last_comma: true
+ word_connector: ", "
+ two_words_connector: " et "
+ last_word_connector: " et "
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Impossible d'enregistrer {{model}}: 1 erreur"
+ other: "Impossible d'enregistrer {{model}}: {{count}} erreurs."
+ body: "Veuillez vérifier les champs suivants :"
+ messages:
+ inclusion: "n'est pas inclus(e) dans la liste"
+ exclusion: "n'est pas disponible"
+ invalid: "n'est pas valide"
+ confirmation: "ne concorde pas avec la confirmation"
+ accepted: "doit être accepté(e)"
+ empty: "doit être rempli(e)"
+ blank: "doit être rempli(e)"
+ too_long: "est trop long (pas plus de {{count}} caractères)"
+ too_short: "est trop court (au moins {{count}} caractères)"
+ wrong_length: "ne fait pas la bonne longueur (doit comporter {{count}} caractères)"
+ taken: "n'est pas disponible"
+ not_a_number: "n'est pas un nombre"
+ greater_than: "doit être supérieur à {{count}}"
+ greater_than_or_equal_to: "doit être supérieur ou égal à {{count}}"
+ equal_to: "doit être égal à {{count}}"
+ less_than: "doit être inférieur à {{count}}"
+ less_than_or_equal_to: "doit être inférieur ou égal à {{count}}"
+ odd: "doit être impair"
+ even: "doit être pair"
--- /dev/null
+# French translations for Ruby on Rails
+# by Christian Lescuyer (christian@flyingcoders.com)
+# contributor: Sebastien Grosjean - ZenCocoon.com
+
+fr:
+ date:
+ formats:
+ default: "%d/%m/%Y"
+ short: "%e %b"
+ long: "%e %B %Y"
+ long_ordinal: "%e %B %Y"
+ only_day: "%e"
+
+ day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]
+ abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]
+ month_names: [~, janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre]
+ abbr_month_names: [~, jan., fév., mar., avr., mai, juin, juil., août, sept., oct., nov., déc.]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%d %B %Y %H:%M"
+ time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%A %d %B %Y %H:%M:%S %Z"
+ long_ordinal: "%A %d %B %Y %H:%M:%S %Z"
+ only_second: "%S"
+ am: 'am'
+ pm: 'pm'
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "une demi-minute"
+ less_than_x_seconds:
+ zero: "moins d'une seconde"
+ one: "moins de 1 seconde"
+ other: "moins de {{count}} secondes"
+ x_seconds:
+ one: "1 seconde"
+ other: "{{count}} secondes"
+ less_than_x_minutes:
+ zero: "moins d'une minute"
+ one: "moins de 1 minute"
+ other: "moins de {{count}} minutes"
+ x_minutes:
+ one: "1 minute"
+ other: "{{count}} minutes"
+ about_x_hours:
+ one: "environ une heure"
+ other: "environ {{count}} heures"
+ x_days:
+ one: "1 jour"
+ other: "{{count}} jours"
+ about_x_months:
+ one: "environ un mois"
+ other: "environ {{count}} mois"
+ x_months:
+ one: "1 mois"
+ other: "{{count}} mois"
+ about_x_years:
+ one: "environ un an"
+ other: "environ {{count}} ans"
+ over_x_years:
+ one: "plus d'un an"
+ other: "plus de {{count}} ans"
+ prompts:
+ year: "Année"
+ month: "Mois"
+ day: "Jour"
+ hour: "Heure"
+ minute: "Minute"
+ second: "Seconde"
+
+ number:
+ format:
+ precision: 3
+ separator: ','
+ delimiter: ' '
+ currency:
+ format:
+ unit: '€'
+ precision: 2
+ format: '%n %u'
+ human:
+ format:
+ precision: 2
+ storage_units: [ Octet, ko, Mo, Go, To ]
+
+ support:
+ array:
+ sentence_connector: 'et'
+ skip_last_comma: true
+ word_connector: ", "
+ two_words_connector: " et "
+ last_word_connector: " et "
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Impossible d'enregistrer {{model}}: 1 erreur"
+ other: "Impossible d'enregistrer {{model}}: {{count}} erreurs."
+ body: "Veuillez vérifier les champs suivants :"
+ messages:
+ inclusion: "n'est pas inclus(e) dans la liste"
+ exclusion: "n'est pas disponible"
+ invalid: "n'est pas valide"
+ confirmation: "ne concorde pas avec la confirmation"
+ accepted: "doit être accepté(e)"
+ empty: "doit être rempli(e)"
+ blank: "doit être rempli(e)"
+ too_long: "est trop long (pas plus de {{count}} caractères)"
+ too_short: "est trop court (au moins {{count}} caractères)"
+ wrong_length: "ne fait pas la bonne longueur (doit comporter {{count}} caractères)"
+ taken: "n'est pas disponible"
+ not_a_number: "n'est pas un nombre"
+ greater_than: "doit être supérieur à {{count}}"
+ greater_than_or_equal_to: "doit être supérieur ou égal à {{count}}"
+ equal_to: "doit être égal à {{count}}"
+ less_than: "doit être inférieur à {{count}}"
+ less_than_or_equal_to: "doit être inférieur ou égal à {{count}}"
+ odd: "doit être impair"
+ even: "doit être pair"
--- /dev/null
+# original by Dr. Nic
+
+{
+ :'en-AU' => {
+ :date => {
+ :formats => {
+ :default => "%d/%m/%Y",
+ :short => "%e %b",
+ :long => "%e %B, %Y",
+ :long_ordinal => lambda { |date| "#{date.day.ordinalize} %B, %Y" },
+ :only_day => "%e"
+ },
+ :day_names => Date::DAYNAMES,
+ :abbr_day_names => Date::ABBR_DAYNAMES,
+ :month_names => Date::MONTHNAMES,
+ :abbr_month_names => Date::ABBR_MONTHNAMES,
+ :order => [:year, :month, :day]
+ },
+ :time => {
+ :formats => {
+ :default => "%a %b %d %H:%M:%S %Z %Y",
+ :time => "%H:%M",
+ :short => "%d %b %H:%M",
+ :long => "%d %B, %Y %H:%M",
+ :long_ordinal => lambda { |time| "#{time.day.ordinalize} %B, %Y %H:%M" },
+ :only_second => "%S"
+ },
+ :datetime => {
+ :formats => {
+ :default => "%Y-%m-%dT%H:%M:%S%Z"
+ }
+ },
+ :time_with_zone => {
+ :formats => {
+ :default => lambda { |time| "%Y-%m-%d %H:%M:%S #{time.formatted_offset(false, 'UTC')}" }
+ }
+ },
+ :am => 'am',
+ :pm => 'pm'
+ },
+ :datetime => {
+ :distance_in_words => {
+ :half_a_minute => 'half a minute',
+ :less_than_x_seconds => {:zero => 'less than a second', :one => 'less than a second', :other => 'less than {{count}} seconds'},
+ :x_seconds => {:one => '1 second', :other => '{{count}} seconds'},
+ :less_than_x_minutes => {:zero => 'less than a minute', :one => 'less than a minute', :other => 'less than {{count}} minutes'},
+ :x_minutes => {:one => "1 minute", :other => "{{count}} minutes"},
+ :about_x_hours => {:one => 'about 1 hour', :other => 'about {{count}} hours'},
+ :x_days => {:one => '1 day', :other => '{{count}} days'},
+ :about_x_months => {:one => 'about 1 month', :other => 'about {{count}} months'},
+ :x_months => {:one => '1 month', :other => '{{count}} months'},
+ :about_x_years => {:one => 'about 1 year', :other => 'about {{count}} years'},
+ :over_x_years => {:one => 'over 1 year', :other => 'over {{count}} years'}
+ }
+ },
+ :number => {
+ :format => {
+ :precision => 2,
+ :separator => ',',
+ :delimiter => '.'
+ },
+ :currency => {
+ :format => {
+ :unit => 'AUD',
+ :precision => 2,
+ :format => '%n %u'
+ }
+ }
+ },
+
+ # Active Record
+ :activerecord => {
+ :errors => {
+ :template => {
+ :header => {
+ :one => "Couldn't save this {{model}}: 1 error",
+ :other => "Couldn't save this {{model}}: {{count}} errors."
+ },
+ :body => "Please check the following fields, dude:"
+ },
+ :messages => {
+ :inclusion => "ain't included in the list",
+ :exclusion => "ain't available",
+ :invalid => "ain't valid",
+ :confirmation => "don't match its confirmation",
+ :accepted => "gotta be accepted",
+ :empty => "gotta be given",
+ :blank => "gotta be given",
+ :too_long => "is too long-ish (no more than {{count}} characters)",
+ :too_short => "is too short-ish (no less than {{count}} characters)",
+ :wrong_length => "ain't got the right length (gotta be {{count}} characters)",
+ :taken => "ain't available",
+ :not_a_number => "ain't a number",
+ :greater_than => "gotta be greater than {{count}}",
+ :greater_than_or_equal_to => "gotta be greater than or equal to {{count}}",
+ :equal_to => "gotta be equal to {{count}}",
+ :less_than => "gotta be less than {{count}}",
+ :less_than_or_equal_to => "gotta be less than or equal to {{count}}",
+ :odd => "gotta be odd",
+ :even => "gotta be even"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ :'gibberish' => {
+ # date and time formats
+ :date => {
+ :formats => {
+ :default => "%Y-%m-%d (ish)",
+ :short => "%e %b (ish)",
+ :long => "%B %e, %Y (ish)",
+ :long_ordinal => lambda { |date| "%B #{date.day}ish, %Y" },
+ :only_day => lambda { |date| "#{date.day}ish"}
+ },
+ :day_names => %w(Sunday-ish Monday-ish Tuesday-ish Wednesday-ish Thursday-ish Friday-ish Saturday-ish),
+ :abbr_day_names => %w(Sun-i Mon-i Tue-i Wed-i Thu-i Fri-i Sat-i),
+ :month_names => [nil] + %w(January-ish February-ish March-ish April-ish May-ish June-ish
+ July-ish August-ish September-ish October-ish November-rish December-ish),
+ :abbr_month_names => [nil] + %w(Jan-i Feb-i Mar-i Apr-i May-i Jun-i Jul-i Aug-i Sep-i Oct-i Nov-i Dec-i),
+ :order => [:day, :month, :year]
+ },
+ :time => {
+ :formats => {
+ :default => "%a %b %d %H:%M:%S %Z %Y (ish)",
+ :time => "%H:%M (ish)",
+ :short => "%d %b %H:%M (ish)",
+ :long => "%B %d, %Y %H:%M (ish)",
+ :long_ordinal => lambda { |time| "%B #{time.day}ish, %Y %H:%M" },
+ :only_second => "%S (ish)"
+ },
+ :datetime => {
+ :formats => {
+ :default => "%Y-%m-%dT%H:%M:%S%Z"
+ }
+ },
+ :time_with_zone => {
+ :formats => {
+ :default => lambda { |time| "%Y-%m-%d %H:%M:%S #{time.formatted_offset(false, 'UTC')}" }
+ }
+ },
+ :am => 'am-ish',
+ :pm => 'pm-ish'
+ },
+
+ # date helper distance in words
+ :datetime => {
+ :distance_in_words => {
+ :half_a_minute => 'a halfish minute',
+ :less_than_x_seconds => {:zero => 'less than 1 second', :one => ' less than 1 secondish', :other => 'less than{{count}}ish seconds'},
+ :x_seconds => {:one => '1 secondish', :other => '{{count}}ish seconds'},
+ :less_than_x_minutes => {:zero => 'less than a minuteish', :one => 'less than 1 minuteish', :other => 'less than {{count}}ish minutes'},
+ :x_minutes => {:one => "1ish minute", :other => "{{count}}ish minutes"},
+ :about_x_hours => {:one => 'about 1 hourish', :other => 'about {{count}}ish hours'},
+ :x_days => {:one => '1ish day', :other => '{{count}}ish days'},
+ :about_x_months => {:one => 'about 1ish month', :other => 'about {{count}}ish months'},
+ :x_months => {:one => '1ish month', :other => '{{count}}ish months'},
+ :about_x_years => {:one => 'about 1ish year', :other => 'about {{count}}ish years'},
+ :over_x_years => {:one => 'over 1ish year', :other => 'over {{count}}ish years'}
+ }
+ },
+
+ # numbers
+ :number => {
+ :format => {
+ :precision => 3,
+ :separator => ',',
+ :delimiter => '.'
+ },
+ :currency => {
+ :format => {
+ :unit => 'Gib-$',
+ :precision => 2,
+ :format => '%n %u'
+ }
+ }
+ },
+
+ # Active Record
+ :activerecord => {
+ :errors => {
+ :template => {
+ :header => {
+ :one => "Couldn't save this {{model}}: 1 error",
+ :other => "Couldn't save this {{model}}: {{count}} errors."
+ },
+ :body => "Please check the following fields, dude:"
+ },
+ :messages => {
+ :inclusion => "ain't included in the list",
+ :exclusion => "ain't available",
+ :invalid => "ain't valid",
+ :confirmation => "don't match its confirmation",
+ :accepted => "gotta be accepted",
+ :empty => "gotta be given",
+ :blank => "gotta be given",
+ :too_long => "is too long-ish (no more than {{count}} characters)",
+ :too_short => "is too short-ish (no less than {{count}} characters)",
+ :wrong_length => "ain't got the right length (gotta be {{count}} characters)",
+ :taken => "ain't available",
+ :not_a_number => "ain't a number",
+ :greater_than => "gotta be greater than {{count}}",
+ :greater_than_or_equal_to => "gotta be greater than or equal to {{count}}",
+ :equal_to => "gotta be equal to {{count}}",
+ :less_than => "gotta be less than {{count}}",
+ :less_than_or_equal_to => "gotta be less than or equal to {{count}}",
+ :odd => "gotta be odd",
+ :even => "gotta be even"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+# Galician (Spain) for Ruby on Rails
+# by Marcos Arias Pena (markus@agil-e.com)
+
+gl-ES:
+ # action_view
+ number:
+ # Usado en number_with_delimiter()
+ format:
+ separator: ","
+ delimiter: "."
+ precision: 2
+
+ # Usado en number_to_currency()
+ currency:
+ format:
+ # %u é a unidade monetaria, %n o número
+ # 1 euro sería 1.00 €
+ format: "%n %u"
+ unit: "€"
+ separator: ","
+ delimiter: "."
+ precision: 2
+
+ # Usado en number_to_percentage()
+ percentage:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Usado en number_to_precision()
+ precision:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Usado en number_to_human_size()
+ human:
+ format:
+ # separator:
+ delimiter: ""
+ precision: 1
+ # Se estás a usar Rails <= 2.2.2
+ # storage_units: [Bytes, KB, MB, GB, TB]
+ # Se estás a usar Rails >= 2.3
+ storage_units:
+ # Formato de saida de unidades de almacenamento
+ # %u é a unidade de almacenamento
+ # %n é o número (por defecto: 2 MB)
+ format: "%n %u"
+ units:
+ byte:
+ one: "Byte"
+ other: "Bytes"
+ kb: "KB"
+ mb: "MB"
+ gb: "GB"
+ tb: "TB"
+
+ # active_support
+ date:
+ formats:
+ default: "%e/%m/%Y"
+ short: "%e %b"
+ long: "%A %e de %B de %Y"
+ # Podes engadir máis formatos nesta lista ou cambiar os aquí definidos
+ day_names: [Domingo, Luns, Martes, Mércores, Xoves, Venres, Sábado]
+ abbr_day_names: [Dom, Lun, Mar, Mer, Xov, Ven, Sab]
+ month_names: [~, Xaneiro, Febreiro, Marzo, Abril, Maio, Xuño, Xullo, Agosto, Setembro, Outubro, Novembro, Decembro]
+ abbr_month_names: [~, Xan, Feb, Mar, Abr, Mai, Xuñ, Xul, Ago, Set, Out, Nov, Dec]
+ order: [:day, :month, :year]
+
+ time:
+ formats:
+ default: "%A, %e de %B de %Y ás %H:%M"
+ time: "%H:%M"
+ short: "%e/%m, %H:%M"
+ long: "%A %e de %B de %Y ás %H:%M"
+ # Podes engadir máis formatos nesta lista ou cambiar os aquí definidos
+ am: ''
+ pm: ''
+
+ # Usados en distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+ datetime:
+ distance_in_words:
+ half_a_minute: 'medio minuto'
+ less_than_x_seconds:
+ zero: 'menos dun segundo'
+ one: '1 segundo'
+ few: 'poucos segundos'
+ other: '{{count}} segundos'
+ x_seconds:
+ one: '1 segundo'
+ other: '{{count}} segundos'
+ less_than_x_minutes:
+ zero: 'menos dun minuto'
+ one: '1 minuto'
+ other: '{{count}} minutos'
+ x_minutes:
+ one: '1 minuto'
+ other: '{{count}} minuto'
+ about_x_hours:
+ one: 'aproximadamente unha hora'
+ other: '{{count}} horas'
+ x_days:
+ one: '1 día'
+ other: '{{count}} días'
+ x_weeks:
+ one: '1 semana'
+ other: '{{count}} semanas'
+ about_x_months:
+ one: 'aproximadamente 1 mes'
+ other: '{{count}} meses'
+ x_months:
+ one: '1 mes'
+ other: '{{count}} meses'
+ about_x_years:
+ one: 'aproximadamente 1 ano'
+ other: '{{count}} anos'
+ over_x_years:
+ one: 'máis dun ano'
+ other: '{{count}} anos'
+ now: 'agora'
+ today: 'hoxe'
+ tomorrow: 'mañá'
+ in: 'dentro de'
+
+ support:
+ array:
+ # Se estás a usar Rails <= 2.2.2
+ # sentence_connector: e
+ # Se estás a usar Rails >= 2.3
+ words_connector: ", "
+ two_words_connector: " e "
+ last_word_connector: " e "
+
+ # active_record
+ activerecord:
+ models:
+ # Traduce nomes de modelos. Usado en Model.human_name()
+ # Por exemplo
+ # model:
+ # user: "Nota"
+ # traducirá o modelo User como "Nota"
+
+ attributes:
+ # Traduce nomes de atributos de modelos. Usado en Model.human_attribute_name(attribute)
+ # Por exemplo
+ # attributes:
+ # user:
+ # login: "Aceso"
+ # traducirá o atribute login do modelo User como "Aceso"
+
+ errors:
+ template:
+ header:
+ one: "1 erro evitou que se poidese gardar o {{model}}"
+ other: "{{count}} erros evitaron que se poidese gardar o {{model}}"
+ # A variable :count tamén está dispoñible aquí
+ body: "Atopáronse os seguintes problemas:"
+ messages:
+ inclusion: "non está incluido na lista"
+ exclusion: "xa existe"
+ invalid: "non é válido"
+ confirmation: "non coincide coa confirmación"
+ accepted: "debe ser aceptado"
+ empty: "non pode estar valeiro"
+ blank: "non pode estar en blanco"
+ too_long: "é demasiado longo (non máis de {{count}} carácteres)"
+ too_short: "é demasiado curto (non menos de {{count}} carácteres)"
+ wrong_length: "non ten a lonxitude correcta (debe ser de {{count}} carácteres)"
+ taken: "non está dispoñible"
+ not_a_number: "non é un número"
+ greater_than: "debe ser maior que {{count}}"
+ greater_than_or_equal_to: "debe ser maior ou igual que {{count}}"
+ equal_to: "debe ser igual a {{count}}"
+ less_than: "debe ser menor que {{count}}"
+ less_than_or_equal_to: "debe ser menor ou igual que {{count}}"
+ odd: "debe ser par"
+ even: "debe ser impar"
+ # Engade aquí os teus propios mensaxes de erro ou no ámbito modelo/atributo
+
+ # Podes definir os teus propios erros para modelos ou para os atributos dun modelo
+ # Os valores :model, :attribute e :value están sempre dispoñibles para a interpolación
+ #
+ # Exemplos avanzados
+ # models:
+ # user:
+ # blank: "Esta é unha mensaxe personalizada para o modelo {{model}}: {{attribute}}"
+ # attributes:
+ # login:
+ # blank: "Esta é unha mensaxe personalidaza para o modelo Usuario: login"
--- /dev/null
+# Hebrew translations for Ruby on Rails
+# by Dotan Nahum (dipidi@gmail.com)
+
+"he-IL":
+ date:
+ formats:
+ default: "%Y-%m-%d"
+ short: "%e %b"
+ long: "%B %e, %Y"
+ only_day: "%e"
+
+ day_names: [ראשון, שני, שלישי, רביעי, חמישי, שישי, שבת]
+ abbr_day_names: [רא, שנ, של, רב, חמ, שי, שב]
+ month_names: [~, ינואר, פברואר, מרץ, אפריל, מאי, יוני, יולי, אוגוסט, ספטמבר, אוקטובר, נובמבר, דצמבר]
+ abbr_month_names: [~, יאנ, פב, מרץ, אפר, מאי, יונ, יול, אוג, ספט, אוק, נוב, דצ]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %b %d %H:%M:%S %Z %Y"
+ time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ only_second: "%S"
+
+ datetime:
+ formats:
+ default: "%d-%m-%YT%H:%M:%S%Z"
+
+ am: 'am'
+ pm: 'pm'
+
+ datetime:
+ distance_in_words:
+ half_a_minute: 'חצי דקה'
+ less_than_x_seconds:
+ zero: 'פחות משניה אחת'
+ one: 'פחות משניה אחת'
+ other: 'פחות מ- {{count}} שניות'
+ x_seconds:
+ one: 'שניה אחת'
+ other: '{{count}} שניות'
+ less_than_x_minutes:
+ zero: 'פחות מדקה אחת'
+ one: 'פחות מדקה אחת'
+ other: 'פחות מ- {{count}} דקות'
+ x_minutes:
+ one: 'דקה אחת'
+ other: '{{count}} דקות'
+ about_x_hours:
+ one: 'בערך שעה אחת'
+ other: 'בערך {{count}} שעות'
+ x_days:
+ one: 'יום אחד'
+ other: '{{count}} ימים'
+ about_x_months:
+ one: 'בערך חודש אחד'
+ other: 'בערך {{count}} חודשים'
+ x_months:
+ one: 'חודש אחד'
+ other: '{{count}} חודשים'
+ about_x_years:
+ one: 'בערך שנה אחת'
+ other: 'בערך {{count}} שנים'
+ over_x_years:
+ one: 'מעל שנה אחת'
+ other: 'מעל {{count}} שנים'
+
+ number:
+ format:
+ precision: 3
+ separator: '.'
+ delimiter: ','
+ currency:
+ format:
+ unit: 'שח'
+ precision: 2
+ format: '%u %n'
+
+ active_record:
+ error:
+ header_message: ["לא ניתן לשמור {{model}}: שגיאה אחת", "לא ניתן לשמור {{model}}: {{count}} שגיאות."]
+ message: "אנא בדוק את השדות הבאים:"
+ error_messages:
+ inclusion: "לא נכלל ברשימה"
+ exclusion: "לא זמין"
+ invalid: "לא ולידי"
+ confirmation: "לא תואם לאישורו"
+ accepted: "חייב באישור"
+ empty: "חייב להכלל"
+ blank: "חייב להכלל"
+ too_long: "יותר מדי ארוך (לא יותר מ- {{count}} תוים)"
+ too_short: "יותר מדי קצר (לא יותר מ- {{count}} תוים)"
+ wrong_length: "לא באורך הנכון (חייב להיות {{count}} תוים)"
+ taken: "לא זמין"
+ not_a_number: "הוא לא מספר"
+ greater_than: "חייב להיות גדול מ- {{count}}"
+ greater_than_or_equal_to: "חייב להיות גדול או שווה ל- {{count}}"
+ equal_to: "חייב להיות שווה ל- {{count}}"
+ less_than: "חייב להיות קטן מ- {{count}}"
+ less_than_or_equal_to: "חייב להיות קטן או שווה ל- {{count}}"
+ odd: "חייב להיות אי זוגי"
+ even: "חייב להיות זוגי"
\ No newline at end of file
--- /dev/null
+# Hungarian translations for Ruby on Rails
+# by Richard Abonyi (richard.abonyi@gmail.com)
+# thanks to KKata, replaced and #hup.hu
+# Cleaned up by László Bácsi (http://lackac.hu)
+# updated by kfl62 kfl62g@gmail.com
+
+"hu":
+ date:
+ formats:
+ default: "%Y.%m.%d."
+ short: "%b %e."
+ long: "%Y. %B %e."
+ day_names: [vasárnap, hétfő, kedd, szerda, csütörtök, péntek, szombat]
+ abbr_day_names: [v., h., k., sze., cs., p., szo.]
+ month_names: [~, január, február, március, április, május, június, július, augusztus, szeptember, október, november, december]
+ abbr_month_names: [~, jan., febr., márc., ápr., máj., jún., júl., aug., szept., okt., nov., dec.]
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%Y. %b %e., %H:%M"
+ short: "%b %e., %H:%M"
+ long: "%Y. %B %e., %A, %H:%M"
+ am: "de."
+ pm: "du."
+
+ datetime:
+ distance_in_words:
+ half_a_minute: 'fél perc'
+ less_than_x_seconds:
+# zero: 'kevesebb, mint 1 másodperc'
+ one: 'kevesebb, mint 1 másodperc'
+ other: 'kevesebb, mint {{count}} másodperc'
+ x_seconds:
+ one: '1 másodperc'
+ other: '{{count}} másodperc'
+ less_than_x_minutes:
+# zero: 'kevesebb, mint 1 perc'
+ one: 'kevesebb, mint 1 perc'
+ other: 'kevesebb, mint {{count}} perc'
+ x_minutes:
+ one: '1 perc'
+ other: '{{count}} perc'
+ about_x_hours:
+ one: 'majdnem 1 óra'
+ other: 'majdnem {{count}} óra'
+ x_days:
+ one: '1 nap'
+ other: '{{count}} nap'
+ about_x_months:
+ one: 'majdnem 1 hónap'
+ other: 'majdnem {{count}} hónap'
+ x_months:
+ one: '1 hónap'
+ other: '{{count}} hónap'
+ about_x_years:
+ one: 'majdnem 1 év'
+ other: 'majdnem {{count}} év'
+ over_x_years:
+ one: 'több, mint 1 év'
+ other: 'több, mint {{count}} év'
+ prompts:
+ year: "Év"
+ month: "Hónap"
+ day: "Nap"
+ hour: "Óra"
+ minute: "Perc"
+ second: "Másodperc"
+
+ number:
+ format:
+ precision: 2
+ separator: ','
+ delimiter: ' '
+ currency:
+ format:
+ unit: 'Ft'
+ precision: 0
+ format: '%n %u'
+ separator: ""
+ delimiter: ""
+ percentage:
+ format:
+ delimiter: ""
+ precision:
+ format:
+ delimiter: ""
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [bájt, KB, MB, GB, TB]
+
+ support:
+ array:
+# sentence_connector: "és"
+# skip_last_comma: true
+ words_connector: ", "
+ two_words_connector: " és "
+ last_word_connector: " és "
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "1 hiba miatt nem menthető a következő: {{model}}"
+ other: "{{count}} hiba miatt nem menthető a következő: {{model}}"
+ body: "Problémás mezők:"
+ messages:
+ inclusion: "nincs a listában"
+ exclusion: "nem elérhető"
+ invalid: "nem megfelelő"
+ confirmation: "nem egyezik"
+ accepted: "nincs elfogadva"
+ empty: "nincs megadva"
+ blank: "nincs megadva"
+ too_long: "túl hosszú (nem lehet több {{count}} karakternél)"
+ too_short: "túl rövid (legalább {{count}} karakter kell legyen)"
+ wrong_length: "nem megfelelő hosszúságú ({{count}} karakter szükséges)"
+ taken: "már foglalt"
+ not_a_number: "nem szám"
+ greater_than: "nagyobb kell legyen, mint {{count}}"
+ greater_than_or_equal_to: "legalább {{count}} kell legyen"
+ equal_to: "pontosan {{count}} kell legyen"
+ less_than: "kevesebb, mint {{count}} kell legyen"
+ less_than_or_equal_to: "legfeljebb {{count}} lehet"
+ odd: "páratlan kell legyen"
+ even: "páros kell legyen"
\ No newline at end of file
--- /dev/null
+# Bahasa Indonesia translations for Ruby on Rails
+# by wynst (wynst.uei@gmail.com)
+
+id:
+ date:
+ formats:
+ default: "%d %B %Y"
+ long: "%A, %d %B %Y"
+ short: "%d.%m.%Y"
+
+ day_names: [Minggu,Senin, Selasa, Rabu, Kamis, Jum'at, Sabtu]
+ abbr_day_names: [Minggu,Senin, Selasa, Rabu, Kamis, Jum'at, Sabtu]
+ month_names: [~, Januari, Februari, Maret, April, Mei, Juni, Juli, Agustus, September, Oktober, November, Desember]
+ abbr_month_names: [~, Jan, Feb, Mar, Apr, Mei, Jun, Jul, Agu, Sep, Okt, Nov, Des]
+ order: [:day, :month, :year]
+
+ time:
+ formats:
+ default: "%a, %d %b %Y %H.%M.%S %z"
+ short: "%d %b %H.%M"
+ long: "%d %B %Y %H.%M"
+ am: "am"
+ pm: "pm"
+
+ support:
+ array:
+ sentence_connector: "dan"
+ skip_last_comma: true
+
+ number:
+ format:
+ separator: ","
+ delimiter: "."
+ precision: 3
+
+ currency:
+ format:
+ format: "%n. %u"
+ unit: "Rp"
+ separator: ","
+ delimiter: "."
+ precision: 2
+
+ percentage:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ precision:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [Byte, KB, MB, GB, TB]
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "setengah menit"
+ less_than_x_seconds:
+ one: "kurang dari 1 detik"
+ other: "kurang dari {{count}} detik"
+ x_seconds:
+ one: "1 detik"
+ other: "{{count}} detik"
+ less_than_x_minutes:
+ one: "kurang dari 1 menit"
+ other: "kurang dari {{count}} menit"
+ x_minutes:
+ one: "menit"
+ other: "{{count}} menit"
+ about_x_hours:
+ one: "sekitar 1 jam"
+ other: "sekitar {{count}} jam"
+ x_days:
+ one: "sehari"
+ other: "{{count}} hari"
+ about_x_months:
+ one: "sekitar sebulan"
+ other: "sekitar {{count}} bulan"
+ x_months:
+ one: "sebulan"
+ other: "{{count}} bulan"
+ about_x_years:
+ one: "tahun"
+ other: "noin {{count}} tahun"
+ over_x_years:
+ one: "lebih dari setahun"
+ other: "lebih dari {{count}} tahun"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "1 kesalahan mengakibatkan {{model}} ini tidak bisa disimpan"
+ other: "{{count}} kesalahan mengakibatkan {{model}} ini tidak bisa disimpan"
+ body: "Ada persoalan dengan field berikut:"
+ messages:
+ inclusion: "tidak terikut di daftar"
+ exclusion: "sudah dipanjar"
+ invalid: "tidak valid"
+ confirmation: "tidak sesuai dengan konfirmasi"
+ accepted: "harus diterima"
+ empty: "tidak bisa kosong"
+ blank: "tidak bisa kosong"
+ too_long: "terlalu panjang (maksimum {{count}} karakter)"
+ too_short: "terlalu pendek (maksimum {{count}} karakter)"
+ wrong_length: "dengan panjang tidak sama (seharusnya {{count}} karakter)"
+ taken: "sudah dipanjar"
+ not_a_number: "bukan nomor"
+ greater_than: "harus lebih besar dari {{count}}"
+ greater_than_or_equal_to: "harus sama atau lebih besar dari {{count}}"
+ equal_to: "harus sama dengan {{count}}"
+ less_than: "harus lebih kecil dari {{count}}"
+ less_than_or_equal_to: "harus sama atau lebih kecil dari {{count}}"
+ odd: "harus ganjil"
+ even: "harus genap"
\ No newline at end of file
--- /dev/null
+# Italian translations for Ruby on Rails
+# by Claudio Poli (masterkain@gmail.com)
+# updated by Simone Carletti (weppos@weppos.net)
+
+it:
+ number:
+ format:
+ separator: ","
+ delimiter: "."
+ precision: 3
+
+ currency:
+ format:
+ format: "%n %u"
+ unit: "€"
+ separator: "."
+ delimiter: ","
+ precision: 2
+
+ percentage:
+ format:
+ delimiter: ""
+ # precision:
+
+ precision:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+
+ human:
+ format:
+ # separator:
+ delimiter: ""
+ precision: 1
+ storage_units: [Byte, Kb, Mb, Gb, Tb]
+
+ date:
+ formats:
+ default: "%d-%m-%Y"
+ short: "%d %b"
+ long: "%d %B %Y"
+ # Bogus?
+ only_day: "%e"
+
+ day_names: [Domenica, Lunedì, Martedì, Mercoledì, Giovedì, Venerdì, Sabato]
+ abbr_day_names: [Dom, Lun, Mar, Mer, Gio, Ven, Sab]
+
+ month_names: [~, Gennaio, Febbraio, Marzo, Aprile, Maggio, Giugno, Luglio, Agosto, Settembre, Ottobre, Novembre, Dicembre]
+ abbr_month_names: [~, Gen, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %d %b %Y, %H:%M:%S %z"
+ short: "%d %b %H:%M"
+ long: "%d %B %Y %H:%M"
+ # Bogus?
+ time: "%H:%M"
+ only_second: "%S"
+
+ # Bogus?
+ datetime:
+ formats:
+ default: "%d-%m-%YT%H:%M:%S%Z"
+
+ am: 'am'
+ pm: 'pm'
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "mezzo minuto"
+ less_than_x_seconds:
+ one: "meno di un secondo"
+ other: "meno di {{count}} secondi"
+ x_seconds:
+ one: "1 secondo"
+ other: "{{count}} secondi"
+ less_than_x_minutes:
+ one: "meno di un minuto"
+ other: "meno di {{count}} minuti"
+ x_minutes:
+ one: "1 minuto"
+ other: "{{count}} minuti"
+ about_x_hours:
+ one: "circa un'ora"
+ other: "circa {{count}} ore"
+ x_days:
+ one: "1 giorno"
+ other: "{{count}} giorni"
+ about_x_months:
+ one: "circa un mese"
+ other: "circa {{count}} mesi"
+ x_months:
+ one: "1 mese"
+ other: "{{count}} mesi"
+ about_x_years:
+ one: "circa un anno"
+ other: "circa {{count}} anni"
+ over_x_years:
+ one: "oltre un anno"
+ other: "oltre {{count}} anni"
+ prompts:
+ year: "Anno"
+ month: "Mese"
+ day: "Giorno"
+ hour: "Ora"
+ minute: "Minuto"
+ second: "Secondi"
+
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " e "
+ last_word_connector: ", e "
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Non posso salvare questo {{model}}: 1 errore"
+ other: "Non posso salvare questo {{model}}: {{count}} errori."
+ body: "Per favore ricontrolla i seguenti campi:"
+ messages:
+ inclusion: "non è incluso nella lista"
+ exclusion: "è riservato"
+ invalid: "non è valido"
+ confirmation: "non coincide con la conferma"
+ accepted: "deve essere accettata"
+ empty: "non può essere vuoto"
+ blank: "non può essere lasciato in bianco"
+ too_long: "è troppo lungo (il massimo è {{count}} lettere)"
+ too_short: "è troppo corto (il minimo è {{count}} lettere)"
+ wrong_length: "è della lunghezza sbagliata (deve essere di {{count}} lettere)"
+ taken: "è già in uso"
+ not_a_number: "non è un numero"
+ greater_than: "deve essere superiore a {{count}}"
+ greater_than_or_equal_to: "deve essere superiore o uguale a {{count}}"
+ equal_to: "deve essere uguale a {{count}}"
+ less_than: "deve essere meno di {{count}}"
+ less_than_or_equal_to: "deve essere meno o uguale a {{count}}"
+ odd: "deve essere dispari"
+ even: "deve essere pari"
\ No newline at end of file
--- /dev/null
+# Japanese translations for Ruby on Rails
+# by Akira Matsuda (ronnie@dio.jp)
+# AR error messages are basically taken from Ruby-GetText-Package. Thanks to Masao Mutoh.
+
+ja:
+ date:
+ formats:
+ default: "%Y/%m/%d"
+ short: "%m/%d"
+ long: "%Y年%m月%d日(%a)"
+
+ day_names: [日曜日, 月曜日, 火曜日, 水曜日, 木曜日, 金曜日, 土曜日]
+ abbr_day_names: [日, 月, 火, 水, 木, 金, 土]
+
+ month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
+ abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
+
+ order: [:year, :month, :day]
+
+ time:
+ formats:
+ default: "%Y/%m/%d %H:%M:%S"
+ short: "%y/%m/%d %H:%M"
+ long: "%Y年%m月%d日(%a) %H時%M分%S秒 %Z"
+ am: "午前"
+ pm: "午後"
+
+ support:
+ array:
+ sentence_connector: "と"
+ skip_last_comma: true
+ words_connector: "と"
+ two_words_connector: "と"
+ last_word_connector: "と"
+
+ number:
+ format:
+ separator: "."
+ delimiter: ","
+ precision: 3
+
+ currency:
+ format:
+ format: "%n%u"
+ unit: "円"
+ separator: "."
+ delimiter: ","
+ precision: 0
+
+ percentage:
+ format:
+ delimiter: ""
+
+ precision:
+ format:
+ delimiter: ""
+
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units:
+ format: "%n%u"
+ units:
+ byte: "バイト"
+ kb: "キロバイト"
+ mb: "メガバイト"
+ gb: "ギガバイト"
+ tb: "テラバイト"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "30秒前後"
+ less_than_x_seconds:
+ one: "1秒以下"
+ other: "{{count}}秒以下"
+ x_seconds:
+ one: "1秒"
+ other: "{{count}}秒"
+ less_than_x_minutes:
+ one: "1分以下"
+ other: "{{count}}分以下"
+ x_minutes:
+ one: "1分"
+ other: "{{count}}分"
+ about_x_hours:
+ one: "約1時間"
+ other: "約{{count}}時間"
+ x_days:
+ one: "1日"
+ other: "{{count}}日"
+ about_x_months:
+ one: "約1ヶ月"
+ other: "約{{count}}ヶ月"
+ x_months:
+ one: "1ヶ月"
+ other: "{{count}}ヶ月"
+ about_x_years:
+ one: "約{{count}}年以上"
+ other: "約{{count}}年以上"
+ over_x_years:
+ one: "{{count}}年以上"
+ other: "{{count}}年以上"
+
+ activerecord:
+ errors:
+ format:
+ separator: ""
+ template:
+ header:
+ one: "{{model}}にエラーが発生しました。"
+ other: "{{model}}に{{count}}つのエラーが発生しました。"
+ body: "次の項目を確認してください。"
+
+ messages:
+ inclusion: "は一覧にありません。"
+ exclusion: "は予約されています。"
+ invalid: "は不正な値です。"
+ confirmation: "が一致しません。"
+ accepted: "を受諾してください。"
+ empty: "を入力してください。"
+ blank: "を入力してください。"
+ too_long: "は{{count}}文字以内で入力してください。"
+ too_short: "は{{count}}文字以上で入力してください。"
+ wrong_length: "は{{count}}文字で入力してください。"
+ taken: "はすでに存在します。"
+ not_a_number: "は数値で入力してください。"
+ greater_than: "は{{count}}より大きい値にしてください。"
+ greater_than_or_equal_to: "は{{count}}以上の値にしてください。"
+ equal_to: "は{{count}}にしてください。"
+ less_than: "は{{count}}より小さい値にしてください。"
+ less_than_or_equal_to: "は{{count}}以下の値にしてください。"
+ odd: "は奇数にしてください。"
+ even: "は偶数にしてください。"
+
--- /dev/null
+# Korean (한글) translations for Ruby on Rails
+# by John Hwang (jhwang@tavon.org)
+# http://github.com/tavon
+
+ko:
+ date:
+ formats:
+ default: "%Y/%m/%d"
+ short: "%m/%d"
+ long: "%Y년 %m월 %d일 (%a)"
+
+ day_names: [일요일, 월요일, 화요일, 수요일, 목요일, 금요일, 토요일]
+ abbr_day_names: [일, 월, 화, 수, 목, 금, 토]
+
+ month_names: [~, 1월, 2월, 3월, 4월, 5월, 6월, 7월, 8월, 9월, 10월, 11월, 12월]
+ abbr_month_names: [~, 1월, 2월, 3월, 4월, 5월, 6월, 7월, 8월, 9월, 10월, 11월, 12월]
+
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%Y/%m/%d %H:%M:%S"
+ short: "%y/%m/%d %H:%M"
+ long: "%Y년 %B월 %d일, %H시 %M분 %S초 %Z"
+ am: "오전"
+ pm: "오후"
+
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+ datetime:
+ distance_in_words:
+ half_a_minute: "30초"
+ less_than_x_seconds:
+ one: "일초 이하"
+ other: "{{count}}초 이하"
+ x_seconds:
+ one: "일초"
+ other: "{{count}}초"
+ less_than_x_minutes:
+ one: "일분 이하"
+ other: "{{count}}분 이하"
+ x_minutes:
+ one: "일분"
+ other: "{{count}}분"
+ about_x_hours:
+ one: "약 한시간"
+ other: "약 {{count}}시간"
+ x_days:
+ one: "하루"
+ other: "{{count}}일"
+ about_x_months:
+ one: "약 한달"
+ other: "약 {{count}}달"
+ x_months:
+ one: "한달"
+ other: "{{count}}달"
+ about_x_years:
+ one: "약 일년"
+ other: "약 {{count}}년"
+ over_x_years:
+ one: "일년 이상"
+ other: "{{count}}년 이상"
+ prompts:
+ year: "년"
+ month: "월"
+ day: "일"
+ hour: "시"
+ minute: "분"
+ second: "초"
+
+ number:
+ # Used in number_with_delimiter()
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+ format:
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+ separator: "."
+ # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+ delimiter: ","
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
+ precision: 3
+
+ # Used in number_to_currency()
+ currency:
+ format:
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+ format: "%u%n"
+ unit: "₩"
+ # These three are to override number.format and are optional
+ separator: "."
+ delimiter: ","
+ precision: 0
+
+ # Used in number_to_percentage()
+ percentage:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_precision()
+ precision:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_human_size()
+ human:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ precision: 1
+ storage_units: [Bytes, KB, MB, GB, TB]
+
+# Used in array.to_sentence.
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: "과 "
+ last_word_connector: ", "
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "한개의 오류가 발생해 {{model}}를 저장 안았했습니다"
+ other: "{{count}}개의 오류가 발생해 {{model}}를 저장 안았했습니다"
+ # The variable :count is also available
+ body: "다음 항목에 문제가 발견했습니다:"
+
+ messages:
+ inclusion: "은 목록에 포함되어 있지 않습니다"
+ exclusion: "은 예약되어 있습니다"
+ invalid: "은 무효입니다"
+ confirmation: "은 확인이 되지 않았습니다"
+ accepted: "은 인정되어야 합니다"
+ empty: "은 비어두면 안 됩니다"
+ blank: "은 비어두면 안 됩니다"
+ too_long: "은 너무 깁니다 (최대 {{count}}자 까지)"
+ too_short: "은 너무 짧습니다 (최소 {{count}}자 까지)"
+ wrong_length: "은 길이가 틀렸습니다 ({{count}}자를 필요합니다)"
+ taken: "은 이미 선택된 겁니다"
+ not_a_number: "은 숫자가 아닙니다"
+ greater_than: "은 {{count}}이상을 요구합니다"
+ greater_than_or_equal_to: "은 {{count}}과 같거나 이상을 요구합니다"
+ equal_to: "은 {{count}}과 같아야 합니다"
+ less_than: "은 {{count}}과 같아야 합니다"
+ less_than_or_equal_to: "은 {{count}}과 같거나 이하을 요구합니다"
+ odd: "은 홀수을 요구합니다"
+ even: "은 짝수을 요구합니다"
+ # Append your own errors here or at the model/attributes scope.
--- /dev/null
+# Lithuanian translations for Ruby on Rails
+# by Laurynas Butkus (laurynas.butkus@gmail.com)
+
+lt:
+ number:
+ format:
+ separator: ","
+ delimiter: " "
+ precision: 3
+
+ currency:
+ format:
+ format: "%n %u"
+ unit: "Lt"
+ separator: ","
+ delimiter: " "
+ precision: 2
+
+ percentage:
+ format:
+ delimiter: ""
+
+ precision:
+ format:
+ delimiter: ""
+
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [baitai, KB, MB, GB, TB]
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "pusė minutės"
+ less_than_x_seconds:
+ one: "mažiau nei 1 sekundė"
+ other: "mažiau nei {{count}} sekundės"
+ x_seconds:
+ one: "1 sekundė"
+ other: "{{count}} sekundės"
+ less_than_x_minutes:
+ one: "mažiau nei minutė"
+ other: "mažiau nei {{count}} minutės"
+ x_minutes:
+ one: "1 minutė"
+ other: "{{count}} minutės"
+ about_x_hours:
+ one: "apie 1 valanda"
+ other: "apie {{count}} valandų"
+ x_days:
+ one: "1 diena"
+ other: "{{count}} dienų"
+ about_x_months:
+ one: "apie 1 mėnuo"
+ other: "apie {{count}} mėnesiai"
+ x_months:
+ one: "1 mėnuo"
+ other: "{{count}} mėnesiai"
+ about_x_years:
+ one: "apie 1 metai"
+ other: "apie {{count}} metų"
+ over_x_years:
+ one: "virš 1 metų"
+ other: "virš {{count}} metų"
+ prompts:
+ year: "Metai"
+ month: "Mėnuo"
+ day: "Diena"
+ hour: "Valanda"
+ minute: "Minutė"
+ second: "Sekundės"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Išsaugant objektą {{model}} rasta klaida"
+ other: "Išsaugant objektą {{model}} rastos {{count}} klaidos"
+ body: "Šiuose laukuose yra klaidų:"
+
+ messages:
+ inclusion: "nenumatyta reikšmė"
+ exclusion: "užimtas"
+ invalid: "neteisingas"
+ confirmation: "neteisingai pakartotas"
+ accepted: "turi būti patvirtintas"
+ empty: "negali būti tuščias"
+ blank: "negali būti tuščias"
+ too_long: "per ilgas (daugiausiai {{count}} simboliai)"
+ too_short: "per trumpas (mažiausiai {{count}} simboliai)"
+ wrong_length: "neteisingo ilgio (turi būti {{count}} simboliai)"
+ taken: "jau užimtas"
+ not_a_number: "ne skaičius"
+ greater_than: "turi būti didesnis už {{count}}"
+ greater_than_or_equal_to: "turi būti didesnis arba lygus {{count}}"
+ equal_to: "turi būti lygus {{count}}"
+ less_than: "turi būti mažesnis už {{count}}"
+ less_than_or_equal_to: "turi būti mažesnis arba lygus {{count}}"
+ odd: "turi būti nelyginis"
+ even: "turi būti lyginis"
+
+ models:
+
+ date:
+ formats:
+ default: "%Y-%m-%d"
+ short: "%b %d"
+ long: "%B %d, %Y"
+
+ day_names: [sekmadienis, pirmadienis, antradienis, trečiadienis, ketvirtadienis, penktadienis, šeštadienis]
+ abbr_day_names: [Sek, Pir, Ant, Tre, Ket, Pen, Šeš]
+
+ month_names: [~, sausio, vasario, kovo, balandžio, gegužės, birželio, liepos, rugpjūčio, rugsėjo, spalio, lapkričio, gruodžio]
+ abbr_month_names: [~, Sau, Vas, Kov, Bal, Geg, Bir, Lie, Rgp, Rgs, Spa, Lap, Grd]
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%a, %d %b %Y %H:%M:%S %z"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ am: "am"
+ pm: "pm"
+
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " ir "
+ last_word_connector: " ir "
--- /dev/null
+# Macedonian translations for Ruby on Rails
+# by Dejan Dimić (dejan.dimic@gmail.com)
+
+"mk":
+ date:
+ formats:
+ default: "%d/%m/%Y"
+ short: "%e %b"
+ long: "%B %e, %Y"
+ only_day: "%e"
+
+ day_names: [Недела, Понеделник, Вторник, Среда, Четврток, Петок, Сабота]
+ abbr_day_names: [Нед, Пон, Вто, Сре, Чет, Пет, Саб]
+ month_names: [~, Јануари, Февруари, Март, Април, Мај, Јуни, Јули, Август, Септември, Октомври, Ноември, Декември]
+ abbr_month_names: [~, Јан, Фев, Мар, Апр, Мај, Јун, Јул, Авг, Сеп, Окт, Ное, Дек]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %b %d %H:%M:%S %Z %Y"
+ time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ only_second: "%S"
+
+ am: 'АМ'
+ pm: 'ПМ'
+
+ datetime:
+ formats:
+ default: "%Y-%m-%dT%H:%M:%S%Z"
+ distance_in_words:
+ half_a_minute: 'пола минута'
+ less_than_x_seconds:
+ zero: 'помалку од секунда'
+ one: 'помалку од 1 секунда'
+ few: 'помалку од {{count}} секунди'
+ other: 'помалку од {{count}} секунди'
+ x_seconds:
+ one: '1 секунда'
+ few: '{{count}} секунди'
+ other: '{{count}} секунди'
+ less_than_x_minutes:
+ zero: 'помалку од минута'
+ one: 'помалку од 1 минута'
+ other: 'помалку од {{count}} минути'
+ x_minutes:
+ one: '1 минута'
+ other: '{{count}} минути'
+ about_x_hours:
+ one: 'околу 1 час'
+ few: 'околу {{count}} часа'
+ other: 'околу {{count}} часа'
+ x_days:
+ one: '1 ден'
+ other: '{{count}} денови'
+ about_x_months:
+ one: 'околу 1 месец'
+ few: 'околу {{count}} месеци'
+ other: 'околу {{count}} месеци'
+ x_months:
+ one: '1 месец'
+ few: '{{count}} месеци'
+ other: '{{count}} месеци'
+ about_x_years:
+ one: 'околу 1 година'
+ other: 'околу {{count}} години'
+ over_x_years:
+ one: 'над 1 година'
+ other: 'над {{count}} години'
+
+ number:
+ format:
+ precision: 3
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: 'MKD'
+ precision: 2
+ format: '%n %u'
+
+ support:
+ array:
+ sentence_connector: "и"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: 'Не успеав да го зачувам {{model}}: 1 грешка.'
+ few: 'Не успеав да го зачувам {{model}}: {{count}} грешки.'
+ other: 'Не успеав да го зачувам {{model}}: {{count}} грешки.'
+ body: "Ве молиме проверете ги следните полиња:"
+ messages:
+ inclusion: "не е во листата"
+ exclusion: "не е достапно"
+ invalid: "не е исправен"
+ confirmation: "не се совпаѓа со својата потврда"
+ accepted: "мора да биде прифатен"
+ empty: "мора да биде зададен"
+ blank: "мора да биде зададен"
+ too_long: "е предолг (не повеќе од {{count}} карактери)"
+ too_short: "е прекраток (не помалку од {{count}} карактери)"
+ wrong_length: "несоодветна должина (мора да имате {{count}} карактери)"
+ taken: "е зафатено"
+ not_a_number: "не е број "
+ greater_than: "мора да биде поголемо од {{count}}"
+ greater_than_or_equal_to: "мора да биде поголемо или еднакво на {{count}}"
+ equal_to: "мора да биде еднакво на {{count}}"
+ less_than: "мора да биде помало од {{count}}"
+ less_than_or_equal_to: "мора да биде помало или еднакво на {{count}}"
+ odd: "мора да биде непарно"
+ even: "мора да биде парно"
+
--- /dev/null
+{
+ :'nl' => {
+ :date => {
+ :formats => {
+ :default => "%d/%m/%Y",
+ :short => "%e %b",
+ :long => "%e %B %Y",
+ :long_ordinal => lambda { |date| "#{date.day}e van %B %Y" },
+ :only_day => "%e"
+ },
+ :day_names => %w(Zondag Maandag Dinsdag Woensdag Donderdag Vrijdag Zaterdag),
+ :abbr_day_names => %w(Zo Ma Di Wo Do Vr Za),
+ :month_names => [nil] + %w(Januari Februari Maart April Mei Juni Juli Augustus September Oktober November December),
+ :abbr_month_names => [nil] + %w(Jan Feb Mrt Apr Mei Jun Jul Aug Sep Okt Nov Dec),
+ :order => [:day, :month, :year]
+ },
+ :time => {
+ :formats => {
+ :default => "%a %b %d %H:%M:%S %Z %Y",
+ :time => "%H:%M",
+ :short => "%d %b %H:%M",
+ :long => "%d %B %Y %H:%M",
+ :long_ordinal => lambda { |time| "#{time.day}e van %B %Y %H:%M" },
+ :only_second => "%S"
+ },
+ :datetime => {
+ :formats => {
+ :default => "%Y-%m-%dT%H:%M:%S%Z"
+ }
+ },
+ :time_with_zone => {
+ :formats => {
+ :default => lambda { |time| "%Y-%m-%d %H:%M:%S #{time.formatted_offset(false, 'UTC')}" }
+ }
+ },
+ :am => %q('s ochtends),
+ :pm => %q('s middags)
+ },
+ :datetime => {
+ :distance_in_words => {
+ :half_a_minute => 'een halve minuut',
+ :less_than_x_seconds => {:zero => 'minder dan een seconde', :one => 'minder dan 1 seconde', :other => 'minder dan {{count}} secondes'},
+ :x_seconds => {:one => '1 seconde', :other => '{{count}} secondes'},
+ :less_than_x_minutes => {:zero => 'minder dan een minuut', :one => 'minder dan 1 minuut', :other => 'minder dan {{count}} minuten'},
+ :x_minutes => {:one => "1 minuut", :other => "{{count}} minuten"},
+ :about_x_hours => {:one => 'ongeveer 1 uur', :other => 'ongeveer {{count}} uren'},
+ :x_days => {:one => '1 dag', :other => '{{count}} dagen'},
+ :about_x_months => {:one => 'ongeveer 1 maand', :other => 'ongeveer {{count}} maanden'},
+ :x_months => {:one => '1 maand', :other => '{{count}} maanden'},
+ :about_x_years => {:one => 'ongeveer 1 jaar', :other => 'ongeveer {{count}} jaren'},
+ :over_x_years => {:one => 'langer dan 1 jaar', :other => 'langer dan {{count}} jaren'}
+ }
+ },
+ :number => {
+ :format => {
+ :precision => 2,
+ :separator => ',',
+ :delimiter => '.'
+ },
+ :currency => {
+ :format => {
+ :unit => '€',
+ :precision => 2,
+ :format => '%u %n'
+ }
+ }
+ },
+
+ # Active Record
+ :activerecord => {
+ :errors => {
+ :template => {
+ :header => {
+ :one => "Kon dit {{model}} object niet opslaan: 1 fout.",
+ :other => "Kon dit {{model}} niet opslaan: {{count}} fouten."
+ },
+ :body => "Controleer alstublieft de volgende velden:"
+ },
+ :messages => {
+ :inclusion => "is niet in de lijst opgenomen",
+ :exclusion => "is niet beschikbaar",
+ :invalid => "is ongeldig",
+ :confirmation => "komt niet met z'n bevestiging overeen",
+ :accepted => "moet worden geaccepteerd",
+ :empty => "moet opgegeven zijn",
+ :blank => "moet opgegeven zijn",
+ :too_long => "is te lang (niet meer dan {{count}} karakters)",
+ :too_short => "is te kort (niet minder dan {{count}} karakters)",
+ :wrong_length => "heeft niet de juiste lengte (moet precies {{count}} karakters zijn)",
+ :taken => "is niet beschikbaar",
+ :not_a_number => "is niet een getal",
+ :greater_than => "moet groter zijn dan {{count}}",
+ :greater_than_or_equal_to => "moet groter of gelijk zijn aan {{count}}",
+ :equal_to => "moet gelijk zijn aan {{count}}",
+ :less_than => "moet minder zijn dan {{count}}",
+ :less_than_or_equal_to => "moet minder of gelijk zijn aan {{count}}",
+ :odd => "moet oneven zijn",
+ :even => "moet even zijn"
+ }
+ }
+ }
+ }
+}
--- /dev/null
+# Norwegian, norsk bokmål, by irb.no
+"no-NB":
+ support:
+ array:
+ sentence_connector: "og"
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ short: "%e. %b"
+ long: "%e. %B %Y"
+ day_names: [søndag, mandag, tirsdag, onsdag, torsdag, fredag, lørdag]
+ abbr_day_names: [søn, man, tir, ons, tor, fre, lør]
+ month_names: [~, januar, februar, mars, april, mai, juni, juli, august, september, oktober, november, desember]
+ abbr_month_names: [~, jan, feb, mar, apr, mai, jun, jul, aug, sep, okt, nov, des]
+ order: [:day, :month, :year]
+ time:
+ formats:
+ default: "%A, %e. %B %Y, %H:%M"
+ time: "%H:%M"
+ short: "%e. %B, %H:%M"
+ long: "%A, %e. %B %Y, %H:%M"
+ am: ""
+ pm: ""
+ datetime:
+ distance_in_words:
+ half_a_minute: "et halvt minutt"
+ less_than_x_seconds:
+ one: "mindre enn 1 sekund"
+ other: "mindre enn {{count}} sekunder"
+ x_seconds:
+ one: "1 sekund"
+ other: "{{count}} sekunder"
+ less_than_x_minutes:
+ one: "mindre enn 1 minutt"
+ other: "mindre enn {{count}} minutter"
+ x_minutes:
+ one: "1 minutt"
+ other: "{{count}} minutter"
+ about_x_hours:
+ one: "rundt 1 time"
+ other: "rundt {{count}} timer"
+ x_days:
+ one: "1 dag"
+ other: "{{count}} dager"
+ about_x_months:
+ one: "rundt 1 måned"
+ other: "rundt {{count}} måneder"
+ x_months:
+ one: "1 måned"
+ other: "{{count}} måneder"
+ about_x_years:
+ one: "rundt 1 år"
+ other: "rundt {{count}} år"
+ over_x_years:
+ one: "over 1 år"
+ other: "over {{count}} år"
+ number:
+ format:
+ precision: 2
+ separator: "."
+ delimiter: ","
+ currency:
+ format:
+ unit: "kr"
+ format: "%n %u"
+ precision:
+ format:
+ delimiter: ""
+ precision: 4
+ activerecord:
+ errors:
+ template:
+ header: "kunne ikke lagre {{model}} på grunn av {{count}} feil."
+ body: "det oppstod problemer i følgende felt:"
+ messages:
+ inclusion: "er ikke inkludert i listen"
+ exclusion: "er reservert"
+ invalid: "er ugyldig"
+ confirmation: "passer ikke bekreftelsen"
+ accepted: "må være akseptert"
+ empty: "kan ikke være tom"
+ blank: "kan ikke være blank"
+ too_long: "er for lang (maksimum {{count}} tegn)"
+ too_short: "er for kort (minimum {{count}} tegn)"
+ wrong_length: "er av feil lengde (maksimum {{count}} tegn)"
+ taken: "er allerede i bruk"
+ not_a_number: "er ikke et tall"
+ greater_than: "må være større enn {{count}}"
+ greater_than_or_equal_to: "må være større enn eller lik {{count}}"
+ equal_to: "må være lik {{count}}"
+ less_than: "må være mindre enn {{count}}"
+ less_than_or_equal_to: "må være mindre enn eller lik {{count}}"
+ odd: "må være oddetall"
+ even: "må være partall"
+ # models:
+ # attributes:
--- /dev/null
+# Norwegian, nynorsk, by irb.no
+"no-NN":
+ support:
+ array:
+ sentence_connector: "og"
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ short: "%e. %b"
+ long: "%e. %B %Y"
+ day_names: [sundag, måndag, tysdag, onsdag, torsdag, fredag, laurdag]
+ abbr_day_names: [sun, mån, tys, ons, tor, fre, lau]
+ month_names: [~, januar, februar, mars, april, mai, juni, juli, august, september, oktober, november, desember]
+ abbr_month_names: [~, jan, feb, mar, apr, mai, jun, jul, aug, sep, okt, nov, des]
+ order: [:day, :month, :year]
+ time:
+ formats:
+ default: "%A, %e. %B %Y, %H:%M"
+ time: "%H:%M"
+ short: "%e. %B, %H:%M"
+ long: "%A, %e. %B %Y, %H:%M"
+ am: ""
+ pm: ""
+ datetime:
+ distance_in_words:
+ half_a_minute: "eit halvt minutt"
+ less_than_x_seconds:
+ one: "mindre enn 1 sekund"
+ other: "mindre enn {{count}} sekund"
+ x_seconds:
+ one: "1 sekund"
+ other: "{{count}} sekund"
+ less_than_x_minutes:
+ one: "mindre enn 1 minutt"
+ other: "mindre enn {{count}} minutt"
+ x_minutes:
+ one: "1 minutt"
+ other: "{{count}} minutt"
+ about_x_hours:
+ one: "rundt 1 time"
+ other: "rundt {{count}} timar"
+ x_days:
+ one: "1 dag"
+ other: "{{count}} dagar"
+ about_x_months:
+ one: "rundt 1 månad"
+ other: "rundt {{count}} månader"
+ x_months:
+ one: "1 månad"
+ other: "{{count}} månader"
+ about_x_years:
+ one: "rundt 1 år"
+ other: "rundt {{count}} år"
+ over_x_years:
+ one: "over 1 år"
+ other: "over {{count}} år"
+ number:
+ format:
+ precision: 2
+ separator: "."
+ delimiter: ","
+ currency:
+ format:
+ unit: "kr"
+ format: "%n %u"
+ precision:
+ format:
+ delimiter: ""
+ precision: 4
+ activerecord:
+ errors:
+ template:
+ header: "kunne ikkje lagra {{model}} grunna {{count}} feil."
+ body: "det oppstod problem i følgjande felt:"
+ messages:
+ inclusion: "er ikkje inkludert i lista"
+ exclusion: "er reservert"
+ invalid: "er ugyldig"
+ confirmation: "er ikkje stadfesta"
+ accepted: "må vera akseptert"
+ empty: "kan ikkje vera tom"
+ blank: "kan ikkje vera blank"
+ too_long: "er for lang (maksimum {{count}} teikn)"
+ too_short: "er for kort (minimum {{count}} teikn)"
+ wrong_length: "har feil lengde (maksimum {{count}} teikn)"
+ taken: "er allerie i bruk"
+ not_a_number: "er ikkje eit tal"
+ greater_than: "må vera større enn {{count}}"
+ greater_than_or_equal_to: "må vera større enn eller lik {{count}}"
+ equal_to: "må vera lik {{count}}"
+ less_than: "må vera mindre enn {{count}}"
+ less_than_or_equal_to: "må vera mindre enn eller lik {{count}}"
+ odd: "må vera oddetal"
+ even: "må vera partal"
+ # models:
+ # attributes:
\ No newline at end of file
--- /dev/null
+# Polish translations for Ruby on Rails
+# by Jacek Becela (jacek.becela@gmail.com, http://github.com/ncr)
+
+pl:
+ number:
+ format:
+ separator: ","
+ delimiter: " "
+ precision: 2
+ currency:
+ format:
+ format: "%n %u"
+ unit: "PLN"
+ percentage:
+ format:
+ delimiter: ""
+ precision:
+ format:
+ delimiter: ""
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [B, KB, MB, GB, TB]
+
+ date:
+ formats:
+ default: "%Y-%m-%d"
+ short: "%d %b"
+ long: "%d %B %Y"
+
+ day_names: [Niedziela, Poniedziałek, Wtorek, Środa, Czwartek, Piątek, Sobota]
+ abbr_day_names: [nie, pon, wto, śro, czw, pia, sob]
+
+ month_names: [~, Styczeń, Luty, Marzec, Kwiecień, Maj, Czerwiec, Lipiec, Sierpień, Wrzesień, Październik, Listopad, Grudzień]
+ abbr_month_names: [~, sty, lut, mar, kwi, maj, cze, lip, sie, wrz, paź, lis, gru]
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%a, %d %b %Y, %H:%M:%S %z"
+ short: "%d %b, %H:%M"
+ long: "%d %B %Y, %H:%M"
+ am: "przed południem"
+ pm: "po południu"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "pół minuty"
+ less_than_x_seconds:
+ one: "mniej niż sekundę"
+ few: "mniej niż {{count}} sekundy"
+ other: "mniej niż {{count}} sekund"
+ x_seconds:
+ one: "sekundę"
+ few: "{{count}} sekundy"
+ other: "{{count}} sekund"
+ less_than_x_minutes:
+ one: "mniej niż minutę"
+ few: "mniej niż {{count}} minuty"
+ other: "mniej niż {{count}} minut"
+ x_minutes:
+ one: "minutę"
+ few: "{{count}} minuty"
+ other: "{{count}} minut"
+ about_x_hours:
+ one: "około godziny"
+ other: "about {{count}} godzin"
+ x_days:
+ one: "1 dzień"
+ other: "{{count}} dni"
+ about_x_months:
+ one: "około miesiąca"
+ other: "około {{count}} miesięcy"
+ x_months:
+ one: "1 miesiąc"
+ few: "{{count}} miesiące"
+ other: "{{count}} miesięcy"
+ about_x_years:
+ one: "około roku"
+ other: "około {{count}} lat"
+ over_x_years:
+ one: "ponad rok"
+ few: "ponad {{count}} lata"
+ other: "ponad {{count}} lat"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "{{model}} nie został zachowany z powodu jednego błędu"
+ other: "{{model}} nie został zachowany z powodu {{count}} błędów"
+ body: "Błędy dotyczą następujących pól:"
+ messages:
+ inclusion: "nie znajduje się na liście dopuszczalnych wartości"
+ exclusion: "znajduje się na liście zabronionych wartości"
+ invalid: "jest nieprawidłowe"
+ confirmation: "nie zgadza się z potwierdzeniem"
+ accepted: "musi być zaakceptowane"
+ empty: "nie może być puste"
+ blank: "nie może być puste"
+ too_long: "jest za długie (maksymalnie {{count}} znaków)"
+ too_short: "jest za krótkie (minimalnie {{count}} znaków)"
+ wrong_length: "jest nieprawidłowej długości (powinna wynosić {{count}} znaków)"
+ taken: "zostało już zajęte"
+ not_a_number: "nie jest liczbą"
+ greater_than: "musi być większe niż {{count}}"
+ greater_than_or_equal_to: "musi być większe lub równe {{count}}"
+ equal_to: "musi być równe {{count}}"
+ less_than: "musie być mniejsze niż {{count}}"
+ less_than_or_equal_to: "musi być mniejsze lub równe {{count}}"
+ odd: "musi być nieparzyste"
+ even: "musi być parzyste"
+
+ support:
+ array:
+ sentence_connector: "i"
+ skip_last_comma: true
--- /dev/null
+pt-BR:
+ # formatos de data e hora
+ date:
+ formats:
+ default: "%d/%m/%Y"
+ short: "%d de %B"
+ long: "%d de %B de %Y"
+ only_day: "%d"
+
+ day_names: [Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sábado]
+ abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sáb]
+ month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
+ abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
+ order: [:day,:month,:year]
+
+ time:
+ formats:
+ default: "%A, %d de %B de %Y, %H:%M hs"
+ time: "%H:%M hs"
+ short: "%d/%m, %H:%M hs"
+ long: "%A, %d de %B de %Y, %H:%M hs"
+ only_second: "%S"
+ datetime:
+ formats:
+ default: "%Y-%m-%dT%H:%M:%S%Z"
+ am: ''
+ pm: ''
+
+ # date helper distanci em palavras
+ datetime:
+ distance_in_words:
+ half_a_minute: 'meio minuto'
+ less_than_x_seconds:
+ one: 'menos de 1 segundo'
+ other: 'menos de {{count}} segundos'
+
+ x_seconds:
+ one: '1 segundo'
+ other: '{{count}} segundos'
+
+ less_than_x_minutes:
+ one: 'menos de um minuto'
+ other: 'menos de {{count}} minutos'
+
+ x_minutes:
+ one: '1 minuto'
+ other: '{{count}} minutos'
+
+ about_x_hours:
+ one: 'aproximadamente 1 hora'
+ other: 'aproximadamente {{count}} horas'
+
+ x_days:
+ one: '1 dia'
+ other: '{{count}} dias'
+
+ about_x_months:
+ one: 'aproximadamente 1 mês'
+ other: 'aproximadamente {{count}} meses'
+
+ x_months:
+ one: '1 mês'
+ other: '{{count}} meses'
+
+ about_x_years:
+ one: 'aproximadamente 1 ano'
+ other: 'aproximadamente {{count}} anos'
+
+ over_x_years:
+ one: 'mais de 1 ano'
+ other: 'mais de {{count}} anos'
+
+ # numeros
+ number:
+ format:
+ precision: 3
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: 'R$'
+ precision: 2
+ format: '%u %n'
+ separator: ','
+ delimiter: '.'
+ percentage:
+ format:
+ delimiter: '.'
+ precision:
+ format:
+ delimiter: '.'
+ human:
+ format:
+ precision: 1
+ delimiter: '.'
+ support:
+ array:
+ sentence_connector: "e"
+ skip_last_comma: true
+
+ # Active Record
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "{{model}} não pôde ser salvo: 1 erro"
+ other: "{{model}} não pôde ser salvo: {{count}} erros."
+ body: "Por favor, cheque os seguintes campos:"
+ messages:
+ inclusion: "não está incluso na lista"
+ exclusion: "não está disponível"
+ invalid: "não é válido"
+ confirmation: "não bate com a confirmação"
+ accepted: "precisa ser aceito"
+ empty: "não pode ser vazio"
+ blank: "não pode ser vazio"
+ too_long: "é muito longo (não mais do que {{count}} caracteres)"
+ too_short: "é muito curto (não menos do que {{count}} caracteres)"
+ wrong_length: "não é do tamanho correto (precisa ter {{count}} caracteres)"
+ taken: "não está disponível"
+ not_a_number: "não é um número"
+ greater_than: "precisa ser maior do que {{count}}"
+ greater_than_or_equal_to: "precisa ser maior ou igual a {{count}}"
+ equal_to: "precisa ser igual a {{count}}"
+ less_than: "precisa ser menor do que {{count}}"
+ less_than_or_equal_to: "precisa ser menor ou igual a {{count}}"
+ odd: "precisa ser ímpar"
+ even: "precisa ser par"
\ No newline at end of file
--- /dev/null
+# Portuguese localization for Ruby on Rails
+# by Ricardo Otero <oterosantos@gmail.com>
+pt-PT:
+ support:
+ array:
+ sentence_connector: "e"
+ skip_last_comma: true
+
+ date:
+ formats:
+ default: "%d/%m/%Y"
+ short: "%d de %B"
+ long: "%d de %B de %Y"
+ only_day: "%d"
+ day_names: [Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sábado]
+ abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sáb]
+ month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
+ abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
+ order: [:day, :month, :year]
+
+ time:
+ formats:
+ default: "%A, %d de %B de %Y, %H:%Mh"
+ short: "%d/%m, %H:%M hs"
+ long: "%A, %d de %B de %Y, %H:%Mh"
+ am: ''
+ pm: ''
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "meio minuto"
+ less_than_x_seconds:
+ one: "menos de 1 segundo"
+ other: "menos de {{count}} segundos"
+ x_seconds:
+ one: "1 segundo"
+ other: "{{count}} segundos"
+ less_than_x_minutes:
+ one: "menos de um minuto"
+ other: "menos de {{count}} minutos"
+ x_minutes:
+ one: "1 minuto"
+ other: "{{count}} minutos"
+ about_x_hours:
+ one: "aproximadamente 1 hora"
+ other: "aproximadamente {{count}} horas"
+ x_days:
+ one: "1 dia"
+ other: "{{count}} dias"
+ about_x_months:
+ one: "aproximadamente 1 mês"
+ other: "aproximadamente {{count}} meses"
+ x_months:
+ one: "1 mês"
+ other: "{{count}} meses"
+ about_x_years:
+ one: "aproximadamente 1 ano"
+ other: "aproximadamente {{count}} anos"
+ over_x_years:
+ one: "mais de 1 ano"
+ other: "mais de {{count}} anos"
+
+ number:
+ format:
+ precision: 3
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: '€'
+ precision: 2
+ format: "%u %n"
+ separator: ','
+ delimiter: '.'
+ percentage:
+ format:
+ delimiter: ''
+ precision:
+ format:
+ delimiter: ''
+ human:
+ format:
+ precision: 1
+ delimiter: ''
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Não foi possível guardar {{model}}: 1 erro"
+ other: "Não foi possível guardar {{model}}: {{count}} erros"
+ body: "Por favor, verifique os seguintes campos:"
+ messages:
+ inclusion: "não está incluído na lista"
+ exclusion: "não está disponível"
+ invalid: "não é válido"
+ confirmation: "não está de acordo com a confirmação"
+ accepted: "precisa de ser aceite"
+ empty: "não pode estar em branco"
+ blank: "não pode estar em branco"
+ too_long: "tem demasiados caracteres (máximo: {{count}} caracteres)"
+ too_short: "tem poucos caracteres (mínimo: {{count}} caracteres)"
+ wrong_length: "não é do tamanho correcto (necessita de ter {{count}} caracteres)"
+ taken: "não está disponível"
+ not_a_number: "não é um número"
+ greater_than: "tem de ser maior do que {{count}}"
+ greater_than_or_equal_to: "tem de ser maior ou igual a {{count}}"
+ equal_to: "tem de ser igual a {{count}}"
+ less_than: "tem de ser menor do que {{count}}"
+ less_than_or_equal_to: "tem de ser menor ou igual a {{count}}"
+ odd: "tem de ser ímpar"
+ even: "tem de ser par"
\ No newline at end of file
--- /dev/null
+# Romanian translations for Ruby on Rails
+# by Catalin Ilinca (me@talin.ro)
+# updated by kfl62 (bogus keys are now commented)
+
+ro:
+ date:
+ formats:
+ default: "%d-%m-%Y"
+ short: "%d %b"
+ long: "%d %B %Y"
+# only_day: "%e"
+
+ day_names: [Duminică, Luni, Marți, Miercuri, Joi, Vineri, Sâmbată]
+ abbr_day_names: [Dum, Lun, Mar, Mie, Joi, Vin, Sâm]
+ month_names: [~, Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie]
+ abbr_month_names: [~, Ian, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %d %b %Y, %H:%M:%S %z"
+# time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%d %B %Y %H:%M"
+# only_second: "%S"
+
+# datetime:
+# formats:
+# default: "%d-%m-%YT%H:%M:%S%Z"
+
+ am: ''
+ pm: ''
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "jumătate de minut"
+ less_than_x_seconds:
+ one: "mai puțin de o secundă"
+ other: "mai puțin de {{count}} secunde"
+ x_seconds:
+ one: "1 secundă"
+ other: "{{count}} secunde"
+ less_than_x_minutes:
+ one: "mai puțin de un minut"
+ other: "mai puțin de {{count}} minute"
+ x_minutes:
+ one: "1 minut"
+ other: "{{count}} minute"
+ about_x_hours:
+ one: "aproximativ o oră"
+ other: "aproximativ {{count}} ore"
+ x_days:
+ one: "1 zi"
+ other: "{{count}} zile"
+ about_x_months:
+ one: "aproximativ o lună"
+ other: "aproximativ {{count}} luni"
+ x_months:
+ one: "1 lună"
+ other: "{{count}} luni"
+ about_x_years:
+ one: "aproximativ un an"
+ other: "aproximativ {{count}} ani"
+ over_x_years:
+ one: "mai mult de un an"
+ other: "mai mult de {{count}} ani"
+ prompts:
+ year: "Anul"
+ month: "Luna"
+ day: "Ziua"
+ hour: "Ora"
+ minute: "Minutul"
+ second: "Secunda"
+
+ number:
+ format:
+ precision: 3
+ separator: '.'
+ delimiter: ','
+ currency:
+ format:
+ unit: 'RON'
+ precision: 2
+ separator: '.'
+ delimiter: ','
+ format: '%n %u'
+ percentage:
+ format:
+ # separator:
+ delimiter: ","
+# precision: 2
+ precision:
+ format:
+ # separator:
+ delimiter: ""
+ # precision:
+ human:
+ format:
+# separator: "."
+ delimiter: ","
+ precision: 1
+ storage_units: [Bytes, KB, MB, GB, TB]
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Nu am putut salva acest model {{model}}: 1 eroare"
+ other: "Nu am putut salva acest {{model}}: {{count}} erori."
+ body: "Încearcă să corectezi urmatoarele câmpuri:"
+ messages:
+ inclusion: "nu este inclus în listă"
+ exclusion: "este rezervat"
+ invalid: "este invalid"
+ confirmation: "nu este confirmat"
+ accepted: "trebuie dat acceptul"
+ empty: "nu poate fi gol"
+ blank: "nu poate fi gol"
+ too_long: "este prea lung (se pot folosi maximum {{count}} caractere)"
+ too_short: "este pre scurt (minumim de caractere este {{count}})"
+ wrong_length: "nu are lungimea corectă (trebuie să aiba {{count}} caractere)"
+ taken: "este deja folosit"
+ not_a_number: "nu este un număr"
+ greater_than: "trebuie să fie mai mare decât {{count}}"
+ greater_than_or_equal_to: "trebuie să fie mai mare sau egal cu {{count}}"
+ equal_to: "trebuie să fie egal cu {{count}}"
+ less_than: "trebuie să fie mai mic decât {{count}}"
+ less_than_or_equal_to: "trebuie să fie mai mic sau egal cu {{count}}"
+ odd: "trebuie să fie par"
+ even: "trebuie să fie impar"
+ support:
+ array:
+# sentence_connector: "și"
+ words_connector: ", "
+ two_words_connector: " şi "
+ last_word_connector: " şi "
--- /dev/null
+# Russian localization for Ruby on Rails 2.2+
+# by Yaroslav Markin <yaroslav@markin.net>
+#
+# Be sure to check out "russian" gem (http://github.com/yaroslav/russian) for
+# full Russian language support in Rails (month names, pluralization, etc).
+# The following is an excerpt from that gem.
+#
+# Для полноценной поддержки русского языка (варианты названий месяцев,
+# плюрализация и так далее) в Rails 2.2 нужно использовать gem "russian"
+# (http://github.com/yaroslav/russian). Следующие данные -- выдержка их него, чтобы
+# была возможность минимальной локализации приложения на русский язык.
+
+ru:
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ short: "%d %b"
+ long: "%d %B %Y"
+
+ day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота]
+ standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
+ abbr_day_names: [Вс, Пн, Вт, Ср, Чт, Пт, Сб]
+
+ month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
+ # see russian gem for info on "standalone" day names
+ standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
+ abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.]
+ standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.]
+
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a, %d %b %Y, %H:%M:%S %z"
+ short: "%d %b, %H:%M"
+ long: "%d %B %Y, %H:%M"
+
+ am: "утра"
+ pm: "вечера"
+
+ number:
+ format:
+ separator: "."
+ delimiter: " "
+ precision: 3
+
+ currency:
+ format:
+ format: "%n %u"
+ unit: "руб."
+ separator: "."
+ delimiter: " "
+ precision: 2
+
+ percentage:
+ format:
+ delimiter: ""
+
+ precision:
+ format:
+ delimiter: ""
+
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ # Rails 2.2
+ # storage_units: [байт, КБ, МБ, ГБ, ТБ]
+
+ # Rails 2.3
+ storage_units:
+ # Storage units output formatting.
+ # %u is the storage unit, %n is the number (default: 2 MB)
+ format: "%n %u"
+ units:
+ byte:
+ one: "байт"
+ few: "байта"
+ many: "байт"
+ other: "байта"
+ kb: "КБ"
+ mb: "МБ"
+ gb: "ГБ"
+ tb: "ТБ"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "меньше минуты"
+ less_than_x_seconds:
+ one: "меньше {{count}} секунды"
+ few: "меньше {{count}} секунд"
+ many: "меньше {{count}} секунд"
+ other: "меньше {{count}} секунды"
+ x_seconds:
+ one: "{{count}} секунда"
+ few: "{{count}} секунды"
+ many: "{{count}} секунд"
+ other: "{{count}} секунды"
+ less_than_x_minutes:
+ one: "меньше {{count}} минуты"
+ few: "меньше {{count}} минут"
+ many: "меньше {{count}} минут"
+ other: "меньше {{count}} минуты"
+ x_minutes:
+ one: "{{count}} минуту"
+ few: "{{count}} минуты"
+ many: "{{count}} минут"
+ other: "{{count}} минуты"
+ about_x_hours:
+ one: "около {{count}} часа"
+ few: "около {{count}} часов"
+ many: "около {{count}} часов"
+ other: "около {{count}} часа"
+ x_days:
+ one: "{{count}} день"
+ few: "{{count}} дня"
+ many: "{{count}} дней"
+ other: "{{count}} дня"
+ about_x_months:
+ one: "около {{count}} месяца"
+ few: "около {{count}} месяцев"
+ many: "около {{count}} месяцев"
+ other: "около {{count}} месяца"
+ x_months:
+ one: "{{count}} месяц"
+ few: "{{count}} месяца"
+ many: "{{count}} месяцев"
+ other: "{{count}} месяца"
+ about_x_years:
+ one: "около {{count}} года"
+ few: "около {{count}} лет"
+ many: "около {{count}} лет"
+ other: "около {{count}} лет"
+ over_x_years:
+ one: "больше {{count}} года"
+ few: "больше {{count}} лет"
+ many: "больше {{count}} лет"
+ other: "больше {{count}} лет"
+ prompts:
+ year: "Год"
+ month: "Месяц"
+ day: "День"
+ hour: "Часов"
+ minute: "Минут"
+ second: "Секунд"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "{{model}}: сохранение не удалось из-за {{count}} ошибки"
+ few: "{{model}}: сохранение не удалось из-за {{count}} ошибок"
+ many: "{{model}}: сохранение не удалось из-за {{count}} ошибок"
+ other: "{{model}}: сохранение не удалось из-за {{count}} ошибки"
+
+ body: "Проблемы возникли со следующими полями:"
+
+ messages:
+ inclusion: "имеет непредусмотренное значение"
+ exclusion: "имеет зарезервированное значение"
+ invalid: "имеет неверное значение"
+ confirmation: "не совпадает с подтверждением"
+ accepted: "нужно подтвердить"
+ empty: "не может быть пустым"
+ blank: "не может быть пустым"
+ too_long:
+ one: "слишком большой длины (не может быть больше чем {{count}} символ)"
+ few: "слишком большой длины (не может быть больше чем {{count}} символа)"
+ many: "слишком большой длины (не может быть больше чем {{count}} символов)"
+ other: "слишком большой длины (не может быть больше чем {{count}} символа)"
+ too_short:
+ one: "недостаточной длины (не может быть меньше {{count}} символа)"
+ few: "недостаточной длины (не может быть меньше {{count}} символов)"
+ many: "недостаточной длины (не может быть меньше {{count}} символов)"
+ other: "недостаточной длины (не может быть меньше {{count}} символа)"
+ wrong_length:
+ one: "неверной длины (может быть длиной ровно {{count}} символ)"
+ few: "неверной длины (может быть длиной ровно {{count}} символа)"
+ many: "неверной длины (может быть длиной ровно {{count}} символов)"
+ other: "неверной длины (может быть длиной ровно {{count}} символа)"
+ taken: "уже существует"
+ not_a_number: "не является числом"
+ greater_than: "может иметь значение большее {{count}}"
+ greater_than_or_equal_to: "может иметь значение большее или равное {{count}}"
+ equal_to: "может иметь лишь значение, равное {{count}}"
+ less_than: "может иметь значение меньшее чем {{count}}"
+ less_than_or_equal_to: "может иметь значение меньшее или равное {{count}}"
+ odd: "может иметь лишь четное значение"
+ even: "может иметь лишь нечетное значение"
+
+ support:
+ array:
+ # Rails 2.2
+ sentence_connector: "и"
+ skip_last_comma: true
+
+ # Rails 2.3
+ words_connector: ", "
+ two_words_connector: " и "
+ last_word_connector: " и "
--- /dev/null
+# Serbian (Latin) translations for Ruby on Rails
+# by Dejan Dimić (dejan.dimic@gmail.com)
+
+"sr-Latn":
+ date:
+ formats:
+ default: "%d/%m/%Y"
+ short: "%e %b"
+ long: "%B %e, %Y"
+ only_day: "%e"
+
+ day_names: [Nedelja, Ponedeljak, Utorak, Sreda, Četvrtak, Petak, Subota]
+ abbr_day_names: [Ned, Pon, Uto, Sre, Čet, Pet, Sub]
+ month_names: [~, Januar, Februar, Mart, April, Maj, Jun, Jul, Avgust, Septembar, Oktobar, Novembar, Decembar]
+ abbr_month_names: [~, Jan, Feb, Mar, Apr, Maj, Jun, Jul, Avg, Sep, Okt, Nov, Dec]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %b %d %H:%M:%S %Z %Y"
+ time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ only_second: "%S"
+
+ datetime:
+ formats:
+ default: "%Y-%m-%dT%H:%M:%S%Z"
+
+ am: 'AM'
+ pm: 'PM'
+
+ datetime:
+ distance_in_words:
+ half_a_minute: 'pola minute'
+ less_than_x_seconds:
+ zero: 'manje od 1 sekunde'
+ one: 'manje od 1 sekund'
+ few: 'manje od {{count}} sekunde'
+ other: 'manje od {{count}} sekundi'
+ x_seconds:
+ one: '1 sekunda'
+ few: '{{count}} sekunde'
+ other: '{{count}} sekundi'
+ less_than_x_minutes:
+ zero: 'manje od minuta'
+ one: 'manje od 1 minut'
+ other: 'manje od {{count}} minuta'
+ x_minutes:
+ one: '1 minut'
+ other: '{{count}} minuta'
+ about_x_hours:
+ one: 'oko 1 sat'
+ few: 'oko {{count}} sata'
+ other: 'oko {{count}} sati'
+ x_days:
+ one: '1 dan'
+ other: '{{count}} dana'
+ about_x_months:
+ one: 'oko 1 mesec'
+ few: 'oko {{count}} meseca'
+ other: 'oko {{count}} meseci'
+ x_months:
+ one: '1 mesec'
+ few: '{{count}} meseca'
+ other: '{{count}} meseci'
+ about_x_years:
+ one: 'oko 1 godine'
+ other: 'oko {{count}} godine'
+ over_x_years:
+ one: 'preko 1 godine'
+ other: 'preko {{count}} godine'
+
+ number:
+ format:
+ precision: 3
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: 'DIN'
+ precision: 2
+ format: '%n %u'
+
+ support:
+ array:
+ sentence_connector: "i"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: 'Nisam uspeo sačuvati {{model}}: 1 greška'
+ few: 'Nisam uspeo sačuvati {{model}}: {{count}} greške.'
+ other: 'Nisam uspeo sačuvati {{model}}: {{count}} greški.'
+ body: "Molim Vas proverite sledeća polja:"
+ messages:
+ inclusion: "nije u listi"
+ exclusion: "nije dostupno"
+ invalid: "nije ispravan"
+ confirmation: "se ne slaže sa svojom potvrdom"
+ accepted: "mora biti prihvaćen"
+ empty: "mora biti dat"
+ blank: "mora biti dat"
+ too_long: "je predugačak (ne više od {{count}} karaktera)"
+ too_short: "je prekratak (ne manje od {{count}} karaktera)"
+ wrong_length: "nije odgovarajuće dužine (mora imati {{count}} karaktera)"
+ taken: "je zauzeto"
+ not_a_number: "nije broj"
+ greater_than: "mora biti veće od {{count}}"
+ greater_than_or_equal_to: "mora biti veće ili jednako {{count}}"
+ equal_to: "mora biti jednako {{count}}"
+ less_than: "mora biti manje od {{count}}"
+ less_than_or_equal_to: "mora biti manje ili jednako {{count}}"
+ odd: "mora biti neparno"
+ even: "mora biti parno"
--- /dev/null
+# Serbian default (Cyrillic) translations for Ruby on Rails
+# by Dejan Dimić (dejan.dimic@gmail.com)
+
+"sr":
+ date:
+ formats:
+ default: "%d/%m/%Y"
+ short: "%e %b"
+ long: "%B %e, %Y"
+ only_day: "%e"
+
+ day_names: [Недеља, Понедељак, Уторак, Среда, Четвртак, Петак, Субота]
+ abbr_day_names: [Нед, Пон, Уто, Сре, Чет, Пет, Суб]
+ month_names: [~, Јануар, Фабруар, Март, Април, Мај, Јун, Јул, Август, Септембар, Октобар, Новембар, Децембар]
+ abbr_month_names: [~, Јан, Феб, Мар, Апр, Мај, Јун, Јул, Авг, Сеп, Окт, Нов, Дец]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %b %d %H:%M:%S %Z %Y"
+ time: "%H:%M"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ only_second: "%S"
+
+ datetime:
+ formats:
+ default: "%Y-%m-%dT%H:%M:%S%Z"
+
+ am: 'АМ'
+ pm: 'ПМ'
+
+ datetime:
+ distance_in_words:
+ half_a_minute: 'пола минуте'
+ less_than_x_seconds:
+ zero: 'мање од 1 секунде'
+ one: 'мање од 1 секунд'
+ few: 'мање од {{count}} секунде'
+ other: 'мање од {{count}} секунди'
+ x_seconds:
+ one: '1 секунда'
+ few: '{{count}} секунде'
+ other: '{{count}} секунди'
+ less_than_x_minutes:
+ zero: 'мање од минута'
+ one: 'мање од 1 минут'
+ other: 'мање од {{count}} минута'
+ x_minutes:
+ one: '1 минут'
+ other: '{{count}} минута'
+ about_x_hours:
+ one: 'око 1 сат'
+ few: 'око {{count}} сата'
+ other: 'око {{count}} сати'
+ x_days:
+ one: '1 дан'
+ other: '{{count}} дана'
+ about_x_months:
+ one: 'око 1 месец'
+ few: 'око {{count}} месеца'
+ other: 'око {{count}} месеци'
+ x_months:
+ one: '1 месец'
+ few: '{{count}} месеца'
+ other: '{{count}} месеци'
+ about_x_years:
+ one: 'око 1 године'
+ other: 'око {{count}} године'
+ over_x_years:
+ one: 'преко 1 године'
+ other: 'преко {{count}} године'
+
+ number:
+ format:
+ precision: 3
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: 'ДИН'
+ precision: 2
+ format: '%n %u'
+
+ support:
+ array:
+ sentence_connector: "и"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: 'Нисам успео сачувати {{model}}: 1 грешка.'
+ few: 'Нисам успео сачувати {{model}}: {{count}} грешке.'
+ other: 'Нисам успео сачувати {{model}}: {{count}} грешки.'
+ body: "Молим Вас да проверите следећа поља:"
+ messages:
+ inclusion: "није у листи"
+ exclusion: "није доступно"
+ invalid: "није исправан"
+ confirmation: "се не слаже са својом потврдом"
+ accepted: "мора бити прихваћено"
+ empty: "мора бити дат"
+ blank: "мора бити дат"
+ too_long: "је предугачак (не више од {{count}} карактера)"
+ too_short: "је прекратак (не мање од {{count}} карактера)"
+ wrong_length: "није одговарајуће дужине (мора имати {{count}} карактера)"
+ taken: "је заузето"
+ not_a_number: "није број"
+ greater_than: "мора бити веће од {{count}}"
+ greater_than_or_equal_to: "мора бити веће или једнако {{count}}"
+ equal_to: "кора бити једнако {{count}}"
+ less_than: "мора бити мање од {{count}}"
+ less_than_or_equal_to: "мора бити мање или једнако {{count}}"
+ odd: "мора бити непарно"
+ even: "мора бити парно"
--- /dev/null
+# Swedish translation, by Johan Lundström (johanlunds@gmail.com), with parts taken
+# from http://github.com/daniel/swe_rails
+
+"sv-SE":
+ number:
+ # Used in number_with_delimiter()
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+ format:
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+ separator: ","
+ # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+ delimiter: "."
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
+ precision: 2
+
+ # Used in number_to_currency()
+ currency:
+ format:
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+ format: "%n %u"
+ unit: "kr"
+ # These three are to override number.format and are optional
+ # separator: "."
+ # delimiter: ","
+ # precision: 2
+
+ # Used in number_to_percentage()
+ percentage:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_precision()
+ precision:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_human_size()
+ human:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision: 1
+ storage_units:
+ # Storage units output formatting.
+ # %u is the storage unit, %n is the number (default: 2 MB)
+ format: "%n %u"
+ units:
+ byte:
+ one: "Byte"
+ other: "Bytes"
+ kb: "KB"
+ mb: "MB"
+ gb: "GB"
+ tb: "TB"
+
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+ datetime:
+ distance_in_words:
+ half_a_minute: "en halv minut"
+ less_than_x_seconds:
+ one: "mindre än en sekund"
+ other: "mindre än {{count}} sekunder"
+ x_seconds:
+ one: "en sekund"
+ other: "{{count}} sekunder"
+ less_than_x_minutes:
+ one: "mindre än en minut"
+ other: "mindre än {{count}} minuter"
+ x_minutes:
+ one: "en minut"
+ other: "{{count}} minuter"
+ about_x_hours:
+ one: "ungefär en timme"
+ other: "ungefär {{count}} timmar"
+ x_days:
+ one: "en dag"
+ other: "{{count}} dagar"
+ about_x_months:
+ one: "ungefär en månad"
+ other: "ungefär {{count}} månader"
+ x_months:
+ one: "en månad"
+ other: "{{count}} månader"
+ about_x_years:
+ one: "ungefär ett år"
+ other: "ungefär {{count}} år"
+ over_x_years:
+ one: "mer än ett år"
+ other: "mer än {{count}} år"
+ prompts:
+ year: "År"
+ month: "Månad"
+ day: "Dag"
+ hour: "Timme"
+ minute: "Minut"
+ second: "Sekund"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "Ett fel förhindrade denna {{model}} från att sparas"
+ other: "{{count}} fel förhindrade denna {{model}} från att sparas"
+ # The variable :count is also available
+ body: "Det var problem med följande fält:"
+ # The values :model, :attribute and :value are always available for interpolation
+ # The value :count is available when applicable. Can be used for pluralization.
+ messages:
+ inclusion: "finns inte i listan"
+ exclusion: "är reserverat"
+ invalid: "är ogiltigt"
+ confirmation: "stämmer inte överens"
+ accepted : "måste vara accepterad"
+ empty: "får ej vara tom"
+ blank: "måste anges"
+ too_long: "är för lång (maximum är {{count}} tecken)"
+ too_short: "är för kort (minimum är {{count}} tecken)"
+ wrong_length: "har fel längd (ska vara {{count}} tecken)"
+ taken: "har redan tagits"
+ not_a_number: "är inte ett nummer"
+ greater_than: "måste vara större än {{count}}"
+ greater_than_or_equal_to: "måste vara större än eller lika med {{count}}"
+ equal_to: "måste vara samma som"
+ less_than: "måste vara mindre än {{count}}"
+ less_than_or_equal_to: "måste vara mindre än eller lika med {{count}}"
+ odd: "måste vara udda"
+ even: "måste vara jämnt"
+ # Append your own errors here or at the model/attributes scope.
+
+ # You can define own errors for models or model attributes.
+ # The values :model, :attribute and :value are always available for interpolation.
+ #
+ # For example,
+ # models:
+ # user:
+ # blank: "This is a custom blank message for {{model}}: {{attribute}}"
+ # attributes:
+ # login:
+ # blank: "This is a custom blank message for User login"
+ # Will define custom blank validation message for User model and
+ # custom blank validation message for login attribute of User model.
+ # models:
+
+ # Translate model names. Used in Model.human_name().
+ #models:
+ # For example,
+ # user: "Dude"
+ # will translate User model name to "Dude"
+
+ # Translate model attribute names. Used in Model.human_attribute_name(attribute).
+ #attributes:
+ # For example,
+ # user:
+ # login: "Handle"
+ # will translate User attribute "login" as "Handle"
+
+ date:
+ formats:
+ # Use the strftime parameters for formats.
+ # When no format has been given, it uses default.
+ # You can provide other formats here if you like!
+ default: "%Y-%m-%d"
+ short: "%e %b"
+ long: "%e %B, %Y"
+
+ day_names: [söndag, måndag, tisdag, onsdag, torsdag, fredag, lördag]
+ abbr_day_names: [sön, mån, tis, ons, tor, fre, lör]
+
+ # Don't forget the nil at the beginning; there's no such thing as a 0th month
+ month_names: [~, januari, februari, mars, april, maj, juni, juli, augusti, september, oktober, november, december]
+ abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec]
+ # Used in date_select and datime_select.
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a, %d %b %Y %H:%M:%S %z"
+ short: "%d %b %H:%M"
+ long: "%d %B, %Y %H:%M"
+ am: ""
+ pm: ""
+
+# Used in array.to_sentence.
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " och "
+ last_word_connector: " och "
--- /dev/null
+# Swahili translations for Rails
+# by Joachim Mangilima (joachimm3@gmail.com) and Matthew Todd (http://matthewtodd.org)
+
+sw:
+ # date:
+ # formats:
+ # default: "%d.%m.%Y"
+ # short: "%e. %b"
+ # long: "%e. %B %Y"
+ # only_day: "%e"
+ #
+ # day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
+ # abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
+ # month_names: [~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
+ # abbr_month_names: [~, Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
+ # order: [ :day, :month, :year ]
+ #
+ # time:
+ # formats:
+ # default: "%A, %e. %B %Y, %H:%M Uhr"
+ # short: "%e. %B, %H:%M Uhr"
+ # long: "%A, %e. %B %Y, %H:%M Uhr"
+ # time: "%H:%M"
+ #
+ # am: "vormittags"
+ # pm: "nachmittags"
+ #
+ # datetime:
+ # distance_in_words:
+ # half_a_minute: 'eine halbe Minute'
+ # less_than_x_seconds:
+ # zero: 'weniger als 1 Sekunde'
+ # one: 'weniger als 1 Sekunde'
+ # other: 'weniger als {{count}} Sekunden'
+ # x_seconds:
+ # one: '1 Sekunde'
+ # other: '{{count}} Sekunden'
+ # less_than_x_minutes:
+ # zero: 'weniger als 1 Minute'
+ # one: 'weniger als eine Minute'
+ # other: 'weniger als {{count}} Minuten'
+ # x_minutes:
+ # one: '1 Minute'
+ # other: '{{count}} Minuten'
+ # about_x_hours:
+ # one: 'etwa 1 Stunde'
+ # other: 'etwa {{count}} Stunden'
+ # x_days:
+ # one: '1 Tag'
+ # other: '{{count}} Tage'
+ # about_x_months:
+ # one: 'etwa 1 Monat'
+ # other: 'etwa {{count}} Monate'
+ # x_months:
+ # one: '1 Monat'
+ # other: '{{count}} Monate'
+ # about_x_years:
+ # one: 'etwa 1 Jahr'
+ # other: 'etwa {{count}} Jahre'
+ # over_x_years:
+ # one: 'mehr als 1 Jahr'
+ # other: 'mehr als {{count}} Jahre'
+ #
+ # number:
+ # format:
+ # precision: 2
+ # separator: ','
+ # delimiter: '.'
+ # currency:
+ # format:
+ # unit: '€'
+ # format: '%n%u'
+ # separator:
+ # delimiter:
+ # precision:
+ # percentage:
+ # format:
+ # delimiter: ""
+ # precision:
+ # format:
+ # delimiter: ""
+ # human:
+ # format:
+ # delimiter: ""
+ # precision: 1
+ #
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " na "
+ last_word_connector: ", na "
+
+ activerecord:
+ errors:
+ # template:
+ # header:
+ # one: "Konnte dieses {{model}} Objekt nicht speichern: 1 Fehler."
+ # other: "Konnte dieses {{model}} Objekt nicht speichern: {{count}} Fehler."
+ # body: "Bitte überprüfen Sie die folgenden Felder:"
+
+ # The values :model, :attribute and :value are always available for interpolation
+ # The value :count is available when applicable. Can be used for pluralization.
+ messages:
+ # inclusion: "is not included in the list"
+ exclusion: "haiwezi kutumika"
+ invalid: "haifai"
+ confirmation: "haifanani na hapo chini"
+ # accepted: "must be accepted"
+ empty: "haitakiwi kuwa wazi"
+ blank: "haitakiwi kuwa wazi"
+ too_long: "ndefu sana (isizidi herufi {{count}})"
+ too_short: "fupi mno (isipungue herufi {{count}})"
+ # wrong_length: "is the wrong length (should be {{count}} characters)"
+ taken: "imeshachukuliwa"
+ not_a_number: "inaruhusiwa namba tu"
+ # greater_than: "must be greater than {{count}}"
+ # greater_than_or_equal_to: "must be greater than or equal to {{count}}"
+ # equal_to: "must be equal to {{count}}"
+ # less_than: "must be less than {{count}}"
+ # less_than_or_equal_to: "must be less than or equal to {{count}}"
+ # odd: "must be odd"
+ # even: "must be even"
--- /dev/null
+# Thai translation for Ruby on Rails
+# original by Prem Sichanugrist (s@sikachu.com/sikandsak@gmail.com)
+# activerecord keys fixed by Jittat Fakcharoenphol (jittat@gmail.com)
+
+{
+ :'th' => {
+ :date => {
+ :formats => {
+ :default => lambda { |date| "%d-%m-#{date.year+543}" },
+ :short => "%e %b",
+ :long => lambda { |date| "%e %B #{date.year+543}" },
+ :long_ordinal => lambda { |date| "%e %B #{date.year+543}" },
+ :only_day => "%e"
+ },
+ :day_names => %w(อาทิตย์ จันทร์ อังคาร พุธ พฤหัสบดี ศุกร์ เสาร์),
+ :abbr_day_names => %w(อา จ อ พ พฤ ศ ส),
+ :month_names => [nil] + %w(มกราคม กุมภาพันธ์ มีนาคม เมษายน พฤษภาคม มิถุนายน กรกฎาคม สิงหาคม กันยายน ตุลาคม พฤศจิกายน ธันวาคม),
+ :abbr_month_names => [nil] + %w(ม.ค. ก.พ. มี.ค. เม.ย. พ.ค. มิ.ย. ก.ค. ส.ค. ก.ย. ต.ค. พ.ย. ธ.ค.),
+ :order => [:day, :month, :year]
+ },
+ :time => {
+ :formats => {
+ :default => lambda { |time| "%a %d %b #{time.year+543} %H:%M:%S %Z" },
+ :time => "%H:%M น.",
+ :short => "%d %b %H:%M น.",
+ :long => lambda { |time| "%d %B #{time.year+543} %H:%M น." },
+ :long_ordinal => lambda { |time| "%d %B #{time.year+543} %H:%M น." },
+ :only_second => "%S"
+ },
+ :time_with_zone => {
+ :formats => {
+ :default => lambda { |time| "%Y-%m-%d %H:%M:%S #{time.formatted_offset(false, 'UTC')}" }
+ }
+ },
+ :am => '',
+ :pm => ''
+ },
+ :datetime => {
+ :formats => {
+ :default => "%Y-%m-%dT%H:%M:%S%Z"
+ },
+ :distance_in_words => {
+ :half_a_minute => 'ครึ่งนาทีที่ผ่านมา',
+ :less_than_x_seconds => 'น้อยกว่า {{count}} วินาที',
+ :x_seconds => '{{count}} วินาที',
+ :less_than_x_minutes => 'น้อยกว่า {{count}} วินาที',
+ :x_minutes => '{{count}} นาที',
+ :about_x_hours => 'ประมาณ {{count}} ชั่วโมง',
+ :x_hours => '{{count}} ชั่วโมง',
+ :about_x_days => 'ประมาณ {{count}} วัน',
+ :x_days => '{{count}} วัน',
+ :about_x_months => 'ประมาณ {{count}} เดือน',
+ :x_months => '{{count}} เดือน',
+ :about_x_years => 'ประมาณ {{count}} ปี',
+ :over_x_years => 'เกิน {{count}} ปี'
+ }
+ },
+
+ # numbers
+ :number => {
+ :format => {
+ :precision => 3,
+ :separator => '.',
+ :delimiter => ','
+ },
+ :currency => {
+ :format => {
+ :unit => 'Baht',
+ :precision => 2,
+ :format => '%n %u'
+ }
+ },
+ },
+
+ # Active Record
+ :activerecord => {
+ :errors => {
+ :template => {
+ :header => {
+ :one => "ไม่สามารถบันทึก {{model}} ได้เนื่องจากเกิดข้อผิดพลาด",
+ :other => "ไม่สามารถบันทึก {{model}} ได้เนื่องจากเกิด {{count}} ข้อผิดพลาด"
+ },
+ :body => "โปรดตรวจสอบข้อมูลที่คุณกรอกในช่องต่อไปนี้:"
+ },
+ :messages => {
+ :inclusion => "ไม่ได้อยู่ในลิสต์",
+ :exclusion => "ถูกจองเอาไว้แล้ว",
+ :invalid => "ไม่ถูกต้อง",
+ :confirmation => "ไม่ตรงกับการยืนยัน",
+ :accepted => "ต้องอยู่ในรูปแบบที่ยอมรับ",
+ :empty => "ต้องไม้เว้นว่างเอาไว้",
+ :blank => "ต้องไม่เว้นว่างเอาไว้",
+ :too_long => "ยาวเกินไป (ต้องไม่เกิน {{count}} ตัวอักษร)",
+ :too_short => "สั้นเกินไป (ต้องยาวกว่า {{count}} ตัวอักษร)",
+ :wrong_length => "มีความยาวไม่ถูกต้อง (ต้องมีความยาว {{count}} ตัวอักษร)",
+ :taken => "ถูกใช้ไปแล้ว",
+ :not_a_number => "ไม่ใช่ตัวเลข",
+ :greater_than => "ต้องมากกว่า {{count}}",
+ :greater_than_or_equal_to => "ต้องมากกว่าหรือเท่ากับ {{count}}",
+ :equal_to => "ต้องเท่ากับ {{count}}",
+ :less_than => "ต้องน้อยกว่า {{count}}",
+ :less_than_or_equal_to => "ต้องน้อยกว่าหรือเท่ากับ {{count}}",
+ :odd => "ต้องเป็นเลขคี่",
+ :even => "ต้องเป็นเลขคู่"
+ }
+ }
+ }
+ }
+}
+
--- /dev/null
+# Turkish translations for Ruby on Rails
+# by Ozgun Ataman (ozataman@gmail.com)
+
+tr:
+ locale:
+ native_name: Türkçe
+ address_separator: " "
+ date:
+ formats:
+ default: "%d.%m.%Y"
+ numeric: "%d.%m.%Y"
+ short: "%e %b"
+ long: "%e %B %Y, %A"
+ only_day: "%e"
+
+ day_names: [Pazar, Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi]
+ abbr_day_names: [Pzr, Pzt, Sal, Çrş, Prş, Cum, Cts]
+ month_names: [~, Ocak, Şubat, Mart, Nisan, Mayıs, Haziran, Temmuz, Ağustos, Eylül, Ekim, Kasım, Aralık]
+ abbr_month_names: [~, Oca, Şub, Mar, Nis, May, Haz, Tem, Ağu, Eyl, Eki, Kas, Ara]
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a %d.%b.%y %H:%M"
+ numeric: "%d.%b.%y %H:%M"
+ short: "%e %B, %H:%M"
+ long: "%e %B %Y, %A, %H:%M"
+ time: "%H:%M"
+
+ am: "öğleden önce"
+ pm: "öğleden sonra"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: 'yarım dakika'
+ less_than_x_seconds:
+ zero: '1 saniyeden az'
+ one: '1 saniyeden az'
+ other: '{{count}} saniyeden az'
+ x_seconds:
+ one: '1 saniye'
+ other: '{{count}} saniye'
+ less_than_x_minutes:
+ zero: '1 dakikadan az'
+ one: '1 dakikadan az'
+ other: '{{count}} dakikadan az'
+ x_minutes:
+ one: '1 dakika'
+ other: '{{count}} dakika'
+ about_x_hours:
+ one: '1 saat civarında'
+ other: '{{count}} saat civarında'
+ x_days:
+ one: '1 gün'
+ other: '{{count}} gün'
+ about_x_months:
+ one: '1 ay civarında'
+ other: '{{count}} ay civarında'
+ x_months:
+ one: '1 ay'
+ other: '{{count}} ay'
+ about_x_years:
+ one: '1 yıl civarında'
+ other: '{{count}} yıl civarında'
+ over_x_years:
+ one: '1 yıldan fazla'
+ other: '{{count}} yıldan fazla'
+
+ number:
+ format:
+ precision: 2
+ separator: ','
+ delimiter: '.'
+ currency:
+ format:
+ unit: 'TL'
+ format: '%n %u'
+ separator: ','
+ delimiter: '.'
+ precision: 2
+ percentage:
+ format:
+ delimiter: '.'
+ separator: ','
+ precision: 2
+ precision:
+ format:
+ delimiter: '.'
+ separator: ','
+ human:
+ format:
+ delimiter: '.'
+ separator: ','
+ precision: 2
+
+ support:
+ array:
+ sentence_connector: "ve"
+ skip_last_comma: true
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "{{model}} girişi kaydedilemedi: 1 hata."
+ other: "{{model}} girişi kadedilemedi: {{count}} hata."
+ body: "Lütfen aşağıdaki hataları düzeltiniz:"
+
+ messages:
+ inclusion: "kabul edilen bir kelime değil"
+ exclusion: "kullanılamaz"
+ invalid: "geçersiz"
+ confirmation: "teyidi uyuşmamakta"
+ accepted: "kabul edilmeli"
+ empty: "doldurulmalı"
+ blank: "doldurulmalı"
+ too_long: "çok uzun (en fazla {{count}} karakter)"
+ too_short: "çok kısa (en az {{count}} karakter)"
+ wrong_length: "yanlış uzunlukta (tam olarak {{count}} karakter olmalı)"
+ taken: "hali hazırda kullanılmakta"
+ not_a_number: "geçerli bir sayı değil"
+ greater_than: "{{count}} sayısından büyük olmalı"
+ greater_than_or_equal_to: "{{count}} sayısına eşit veya büyük olmalı"
+ equal_to: "tam olarak {{count}} olmalı"
+ less_than: "{{count}} sayısından küçük olmalı"
+ less_than_or_equal_to: "{{count}} sayısına eşit veya küçük olmalı"
+ odd: "tek olmalı"
+ even: "çift olmalı"
+ models:
--- /dev/null
+# Vietnamese translation for Ruby on Rails
+# by
+# Do Hai Bac (dohaibac@gmail.com)
+# Dao Thanh Ngoc (ngocdaothanh@gmail.com, http://github.com/ngocdaothanh/rails-i18n/tree/master)
+
+vi:
+ number:
+ # Used in number_with_delimiter()
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+ format:
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+ separator: ","
+ # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+ delimiter: "."
+ # Number of decimals, behind the separator (1 with a precision of 2 gives: 1.00)
+ precision: 3
+
+ # Used in number_to_currency()
+ currency:
+ format:
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+ format: "%n %u"
+ unit: "đồng"
+ # These three are to override number.format and are optional
+ separator: ","
+ delimiter: "."
+ precision: 2
+
+ # Used in number_to_percentage()
+ percentage:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_precision()
+ precision:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_human_size()
+ human:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ precision: 1
+ storage_units: [Bytes, KB, MB, GB, TB]
+
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+ datetime:
+ distance_in_words:
+ half_a_minute: "30 giây"
+ less_than_x_seconds:
+ one: "chưa tới 1 giây"
+ other: "chưa tới {{count}} giây"
+ x_seconds:
+ one: "1 giây"
+ other: "{{count}} giây"
+ less_than_x_minutes:
+ one: "chưa tới 1 phút"
+ other: "chưa tới {{count}} phút"
+ x_minutes:
+ one: "1 phút"
+ other: "{{count}} phút"
+ about_x_hours:
+ one: "khoảng 1 giờ"
+ other: "khoảng {{count}} giờ"
+ x_days:
+ one: "1 ngày"
+ other: "{{count}} ngày"
+ about_x_months:
+ one: "khoảng 1 tháng"
+ other: "khoảng {{count}} tháng"
+ x_months:
+ one: "1 tháng"
+ other: "{{count}} tháng"
+ about_x_years:
+ one: "khoảng 1 năm"
+ other: "khoảng {{count}} năm"
+ over_x_years:
+ one: "hơn 1 năm"
+ other: "hơn {{count}} năm"
+ prompts:
+ year: "Năm"
+ month: "Tháng"
+ day: "Ngày"
+ hour: "Giờ"
+ minute: "Phút"
+ second: "Giây"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "1 lỗi ngăn không cho lưu {{model}} này"
+ other: "{{count}} lỗi ngăn không cho lưu {{model}} này"
+ # The variable :count is also available
+ body: "Có lỗi với các mục sau:"
+
+ # The values :model, :attribute and :value are always available for interpolation
+ # The value :count is available when applicable. Can be used for pluralization.
+ messages:
+ inclusion: "không có trong danh sách"
+ exclusion: "đã được giành trước"
+ invalid: "không hợp lệ"
+ confirmation: "không khớp với xác nhận"
+ accepted: "phải được đồng ý"
+ empty: "không thể rỗng"
+ blank: "không thể để trắng"
+ too_long: "quá dài (tối đa {{count}} ký tự)"
+ too_short: "quá ngắn (tối thiểu {{count}} ký tự)"
+ wrong_length: "độ dài không đúng (phải là {{count}} ký tự)"
+ taken: "đã có"
+ not_a_number: "không phải là số"
+ greater_than: "phải lớn hơn {{count}}"
+ greater_than_or_equal_to: "phải lớn hơn hoặc bằng {{count}}"
+ equal_to: "phải bằng {{count}}"
+ less_than: "phải nhỏ hơn {{count}}"
+ less_than_or_equal_to: "phải nhỏ hơn hoặc bằng {{count}}"
+ odd: "phải là số chẵn"
+ even: "phải là số lẻ"
+ # Append your own errors here or at the model/attributes scope.
+
+ # You can define own errors for models or model attributes.
+ # The values :model, :attribute and :value are always available for interpolation.
+ #
+ # For example,
+ # models:
+ # user:
+ # blank: "This is a custom blank message for {{model}}: {{attribute}}"
+ # attributes:
+ # login:
+ # blank: "This is a custom blank message for User login"
+ # Will define custom blank validation message for User model and
+ # custom blank validation message for login attribute of User model.
+ # models:
+
+ # Translate model names. Used in Model.human_name().
+ #models:
+ # For example,
+ # user: "Dude"
+ # will translate User model name to "Dude"
+
+ # Translate model attribute names. Used in Model.human_attribute_name(attribute).
+ #attributes:
+ # For example,
+ # user:
+ # login: "Handle"
+ # will translate User attribute "login" as "Handle"
+
+ date:
+ formats:
+ # Use the strftime parameters for formats.
+ # When no format has been given, it uses default.
+ # You can provide other formats here if you like!
+ default: "%d-%m-%Y"
+ short: "%d %b"
+ long: "%d %B, %Y"
+
+ day_names: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"]
+ abbr_day_names: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"]
+
+ # Don't forget the nil at the beginning; there's no such thing as a 0th month
+ month_names: [~, "Tháng một", "Tháng hai", "Tháng ba", "Tháng tư", "Tháng năm", "Tháng sáu", "Tháng bảy", "Tháng tám", "Tháng chín", "Tháng mười", "Tháng mười một", "Tháng mười hai"]
+ abbr_month_names: [~, "Tháng một", "Tháng hai", "Tháng ba", "Tháng tư", "Tháng năm", "Tháng sáu", "Tháng bảy", "Tháng tám", "Tháng chín", "Tháng mười", "Tháng mười một", "Tháng mười hai"]
+ # Used in date_select and datime_select.
+ order: [ :day, :month, :year ]
+
+ time:
+ formats:
+ default: "%a, %d %b %Y %H:%M:%S %z"
+ short: "%d %b %H:%M"
+ long: "%d %B, %Y %H:%M"
+ am: "sáng"
+ pm: "chiều"
+
+ # Used in array.to_sentence.
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " và "
+ last_word_connector: ", và "
--- /dev/null
+# Chinese (China) translations for Ruby on Rails
+# by tsechingho (http://github.com/tsechingho)
+
+"zh-CN":
+ date:
+ formats:
+ default: "%Y-%m-%d"
+ short: "%b%d日"
+ long: "%Y年%b%d日"
+ day_names: [星期天, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]
+ abbr_day_names: [日, 一, 二, 三, 四, 五, 六]
+ month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
+ abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%Y年%b%d日 %A %H:%M:%S %Z"
+ short: "%b%d日 %H:%M"
+ long: "%Y年%b%d日 %H:%M"
+ am: "上午"
+ pm: "下午"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "半分钟"
+ less_than_x_seconds:
+ one: "一秒内"
+ other: "少于 {{count}} 秒"
+ x_seconds:
+ one: "一秒"
+ other: "{{count}} 秒"
+ less_than_x_minutes:
+ one: "一分钟内"
+ other: "少于 {{count}} 分钟"
+ x_minutes:
+ one: "一分钟"
+ other: "{{count}} 分钟"
+ about_x_hours:
+ one: "大约一小时"
+ other: "大约 {{count}} 小时"
+ x_days:
+ one: "一天"
+ other: "{{count}} 天"
+ about_x_months:
+ one: "大约一个月"
+ other: "大约 {{count}} 个月"
+ x_months:
+ one: "一个月"
+ other: "{{count}} 个月"
+ about_x_years:
+ one: "大约一年"
+ other: "大约 {{count}} 年"
+ over_x_years:
+ one: "一年以上"
+ other: "{{count}} 年以上"
+ prompts:
+ year: "年"
+ month: "月"
+ day: "日"
+ hour: "时"
+ minute: "分"
+ second: "秒"
+
+ number:
+ format:
+ separator: "."
+ delimiter: ","
+ precision: 3
+ currency:
+ format:
+ format: "%u %n"
+ unit: "CNY"
+ separator: "."
+ delimiter: ","
+ precision: 2
+ percentage:
+ format:
+ delimiter: ""
+ precision:
+ format:
+ delimiter: ""
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [Bytes, KB, MB, GB, TB]
+
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " 和 "
+ last_word_connector: ", 和 "
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "有 1 个错误发生导致「{{model}}」无法被保存。"
+ other: "有 {{count}} 个错误发生导致「{{model}}」无法被保存。"
+ body: "如下字段出现错误:"
+ messages:
+ inclusion: "不包含于列表中"
+ exclusion: "是保留关键字"
+ invalid: "是无效的"
+ confirmation: "与确认值不匹配"
+ accepted: "必须是可被接受的"
+ empty: "不能留空"
+ blank: "不能为空字符"
+ too_long: "过长(最长为 {{count}} 个字符)"
+ too_short: "過短(最短为 {{count}} 个字符)"
+ wrong_length: "长度非法(必须为 {{count}} 个字符)"
+ taken: "已经被使用"
+ not_a_number: "不是数字"
+ greater_than: "必须大于 {{count}}"
+ greater_than_or_equal_to: "必须大于或等于 {{count}}"
+ equal_to: "必须等于 {{count}}"
+ less_than: "必须小于 {{count}}"
+ less_than_or_equal_to: "必须小于或等于 {{count}}"
+ odd: "必须为单数"
+ even: "必须为双数"
+
+
+
\ No newline at end of file
--- /dev/null
+# Chinese (Taiwan) translations for Ruby on Rails
+# by tsechingho (http://github.com/tsechingho)
+
+"zh-TW":
+ date:
+ formats:
+ default: "%Y-%m-%d"
+ short: "%b%d日"
+ long: "%Y年%b%d日"
+ day_names: [星期天, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]
+ abbr_day_names: [日, 一, 二, 三, 四, 五, 六]
+ month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
+ abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%Y年%b%d日 %A %H:%M:%S %Z"
+ short: "%b%d日 %H:%M"
+ long: "%Y年%b%d日 %H:%M"
+ am: "上午"
+ pm: "下午"
+
+ datetime:
+ distance_in_words:
+ half_a_minute: "半分鐘"
+ less_than_x_seconds:
+ one: "一秒内"
+ other: "少於 {{count}} 秒"
+ x_seconds:
+ one: "一秒"
+ other: "{{count}} 秒"
+ less_than_x_minutes:
+ one: "一分鐘内"
+ other: "少於 {{count}} 分鐘"
+ x_minutes:
+ one: "一分鐘"
+ other: "{{count}} 分鐘"
+ about_x_hours:
+ one: "大約一小時"
+ other: "大約 {{count}} 小時"
+ x_days:
+ one: "一天"
+ other: "{{count}} 天"
+ about_x_months:
+ one: "大約一個月"
+ other: "大約 {{count}} 個月"
+ x_months:
+ one: "一個月"
+ other: "{{count}} 個月"
+ about_x_years:
+ one: "大約一年"
+ other: "大約 {{count}} 年"
+ over_x_years:
+ one: "一年以上"
+ other: "{{count}} 年以上"
+ prompts:
+ year: "年"
+ month: "月"
+ day: "日"
+ hour: "時"
+ minute: "分"
+ second: "秒"
+
+ number:
+ format:
+ separator: "."
+ delimiter: ","
+ precision: 3
+ currency:
+ format:
+ format: "%u %n"
+ unit: "NT$"
+ separator: "."
+ delimiter: ","
+ precision: 2
+ percentage:
+ format:
+ delimiter: ""
+ precision:
+ format:
+ delimiter: ""
+ human:
+ format:
+ delimiter: ""
+ precision: 1
+ storage_units: [Bytes, KB, MB, GB, TB]
+
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " 和 "
+ last_word_connector: ", 和 "
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "有 1 個錯誤發生使得「{{model}}」無法被儲存。"
+ other: "有 {{count}} 個錯誤發生使得「{{model}}」無法被儲存。"
+ body: "下面欄位有問題:"
+ messages:
+ inclusion: "沒有包含在列表中"
+ exclusion: "是被保留的"
+ invalid: "是無效的"
+ confirmation: "不符合確認值"
+ accepted: "必须是可被接受的"
+ empty: "不能留空"
+ blank: "不能是空白字元"
+ too_long: "過長(最長是 {{count}} 個字)"
+ too_short: "過短(最短是 {{count}} 個字)"
+ wrong_length: "字數錯誤(必須是 {{count}} 個字)"
+ taken: "已經被使用"
+ not_a_number: "不是數字"
+ greater_than: "必須大於 {{count}}"
+ greater_than_or_equal_to: "必須大於或等於 {{count}}"
+ equal_to: "必須等於 {{count}}"
+ less_than: "必須小於 {{count}}"
+ less_than_or_equal_to: "必須小於或等於 {{count}}"
+ odd: "必須是奇數"
+ even: "必須是偶數"
+
+
--- /dev/null
+"en":
+ number:
+ # Used in number_with_delimiter()
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+ format:
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+ separator: "."
+ # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+ delimiter: ","
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
+ precision: 3
+
+ # Used in number_to_currency()
+ currency:
+ format:
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+ format: "%u%n"
+ unit: "$"
+ # These three are to override number.format and are optional
+ separator: "."
+ delimiter: ","
+ precision: 2
+
+ # Used in number_to_percentage()
+ percentage:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_precision()
+ precision:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ # precision:
+
+ # Used in number_to_human_size()
+ human:
+ format:
+ # These three are to override number.format and are optional
+ # separator:
+ delimiter: ""
+ precision: 1
+ storage_units:
+ # Storage units output formatting.
+ # %u is the storage unit, %n is the number (default: 2 MB)
+ format: "%n %u"
+ units:
+ byte:
+ one: "Byte"
+ other: "Bytes"
+ kb: "KB"
+ mb: "MB"
+ gb: "GB"
+ tb: "TB"
+
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+ datetime:
+ distance_in_words:
+ half_a_minute: "half a minute"
+ less_than_x_seconds:
+ one: "less than 1 second"
+ other: "less than {{count}} seconds"
+ x_seconds:
+ one: "1 second"
+ other: "{{count}} seconds"
+ less_than_x_minutes:
+ one: "less than a minute"
+ other: "less than {{count}} minutes"
+ x_minutes:
+ one: "1 minute"
+ other: "{{count}} minutes"
+ about_x_hours:
+ one: "about 1 hour"
+ other: "about {{count}} hours"
+ x_days:
+ one: "1 day"
+ other: "{{count}} days"
+ about_x_months:
+ one: "about 1 month"
+ other: "about {{count}} months"
+ x_months:
+ one: "1 month"
+ other: "{{count}} months"
+ about_x_years:
+ one: "about 1 year"
+ other: "about {{count}} years"
+ over_x_years:
+ one: "over 1 year"
+ other: "over {{count}} years"
+ prompts:
+ year: "Year"
+ month: "Month"
+ day: "Day"
+ hour: "Hour"
+ minute: "Minute"
+ second: "Seconds"
+
+ activerecord:
+ errors:
+ template:
+ header:
+ one: "1 error prohibited this {{model}} from being saved"
+ other: "{{count}} errors prohibited this {{model}} from being saved"
+ # The variable :count is also available
+ body: "There were problems with the following fields:"
+
--- /dev/null
+en:
+ activerecord:
+ errors:
+ # The values :model, :attribute and :value are always available for interpolation
+ # The value :count is available when applicable. Can be used for pluralization.
+ messages:
+ inclusion: "is not included in the list"
+ exclusion: "is reserved"
+ invalid: "is invalid"
+ confirmation: "doesn't match confirmation"
+ accepted: "must be accepted"
+ empty: "can't be empty"
+ blank: "can't be blank"
+ too_long: "is too long (maximum is {{count}} characters)"
+ too_short: "is too short (minimum is {{count}} characters)"
+ wrong_length: "is the wrong length (should be {{count}} characters)"
+ taken: "has already been taken"
+ not_a_number: "is not a number"
+ greater_than: "must be greater than {{count}}"
+ greater_than_or_equal_to: "must be greater than or equal to {{count}}"
+ equal_to: "must be equal to {{count}}"
+ less_than: "must be less than {{count}}"
+ less_than_or_equal_to: "must be less than or equal to {{count}}"
+ odd: "must be odd"
+ even: "must be even"
+ # Append your own errors here or at the model/attributes scope.
+
+ # You can define own errors for models or model attributes.
+ # The values :model, :attribute and :value are always available for interpolation.
+ #
+ # For example,
+ # models:
+ # user:
+ # blank: "This is a custom blank message for {{model}}: {{attribute}}"
+ # attributes:
+ # login:
+ # blank: "This is a custom blank message for User login"
+ # Will define custom blank validation message for User model and
+ # custom blank validation message for login attribute of User model.
+ #models:
+
+ # Translate model names. Used in Model.human_name().
+ #models:
+ # For example,
+ # user: "Dude"
+ # will translate User model name to "Dude"
+
+ # Translate model attribute names. Used in Model.human_attribute_name(attribute).
+ #attributes:
+ # For example,
+ # user:
+ # login: "Handle"
+ # will translate User attribute "login" as "Handle"
+
--- /dev/null
+en:
+ date:
+ formats:
+ # Use the strftime parameters for formats.
+ # When no format has been given, it uses default.
+ # You can provide other formats here if you like!
+ default: "%Y-%m-%d"
+ short: "%b %d"
+ long: "%B %d, %Y"
+
+ day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+ abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+ # Don't forget the nil at the beginning; there's no such thing as a 0th month
+ month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+ abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+ # Used in date_select and datime_select.
+ order: [ :year, :month, :day ]
+
+ time:
+ formats:
+ default: "%a, %d %b %Y %H:%M:%S %z"
+ short: "%d %b %H:%M"
+ long: "%B %d, %Y %H:%M"
+ am: "am"
+ pm: "pm"
+
+# Used in array.to_sentence.
+ support:
+ array:
+ words_connector: ", "
+ two_words_connector: " and "
+ last_word_connector: ", and "
--- /dev/null
+curr_dir = File.expand_path(File.dirname(__FILE__))
+rails_locale_dir = File.expand_path(File.join(curr_dir, "..", "rails"))
+
+puts "Fetching latest Rails locale files to #{rails_locale_dir}"
+
+exec %(
+ curl -Lo '#{rails_locale_dir}/action_view.yml' http://github.com/rails/rails/tree/master/actionpack/lib/action_view/locale/en.yml?raw=true
+
+ curl -Lo '#{rails_locale_dir}/active_record.yml' http://github.com/rails/rails/tree/master/activerecord/lib/active_record/locale/en.yml?raw=true
+
+ curl -Lo '#{rails_locale_dir}/active_support.yml' http://github.com/rails/rails/tree/master/activesupport/lib/active_support/locale/en.yml?raw=true
+)
--- /dev/null
+$KCODE = 'u'
+
+require 'rubygems'
+require 'i18n'
+
+module I18n
+ module Backend
+ class Simple
+ public :translations, :init_translations
+ end
+ end
+end
+
+class KeyStructure
+ attr_reader :result
+
+ def initialize(locale)
+ @locale = locale.to_sym
+ init_backend
+
+ @reference = I18n.backend.translations[:'en']
+ @data = I18n.backend.translations[@locale]
+
+ @result = {:bogus => [], :missing => [], :pluralization => []}
+ @key_stack = []
+ end
+
+ def run
+ compare :missing, @reference, @data
+ compare :bogus, @data, @reference
+ end
+
+ def output
+ [:missing, :bogus, :pluralization].each do |direction|
+ next unless result[direction].size > 0
+ case direction
+ when :pluralization
+ puts "\nThe following pluralization keys seem to differ:"
+ else
+ puts "\nThe following keys seem to be #{direction} for #{@locale.inspect}:"
+ end
+ puts ' ' + result[direction].join("\n ")
+ end
+ if result.map{|k, v| v.size == 0}.uniq == [true]
+ puts "No inconsistencies found."
+ end
+ puts "\n"
+ end
+
+ protected
+
+ def compare(direction, reference, data)
+ reference.each do |key, value|
+ if data.has_key?(key)
+ @key_stack << key
+ if namespace?(value)
+ compare direction, value, (namespace?(data[key]) ? data[key] : {})
+ elsif pluralization?(value)
+ compare :pluralization, value, (pluralization?(data[key]) ? data[key] : {})
+ end
+ @key_stack.pop
+ else
+ @result[direction] << current_key(key)
+ end
+ end
+ end
+
+ def current_key(key)
+ (@key_stack.dup << key).join('.')
+ end
+
+ def namespace?(hash)
+ Hash === hash and !pluralization?(hash)
+ end
+
+ def pluralization?(hash)
+ Hash === hash and hash.has_key?(:one) and hash.has_key?(:other)
+ end
+
+ def init_backend
+ I18n.load_path = %W(
+ rails/action_view.yml
+ rails/active_record.yml
+ rails/active_support.yml
+ )
+ I18n.load_path += Dir["locale/#{@locale}.{rb,yml}"]
+ I18n.backend.init_translations
+ end
+end
--- /dev/null
+require File.dirname(__FILE__) + '/lib/key_structure.rb'
+
+locale = ARGV.first || raise("must give a locale as a command line argument")
+
+test = KeyStructure.new locale
+test.run
+test.output
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>beforeRunningCommand</key>
+ <string>nop</string>
+ <key>command</key>
+ <string>#!/usr/bin/ruby
+require 'rubygems'
+require 'i18n'
+I18n.locale = :en
+I18n.load_path << File.join(ENV['TM_PROJECT_DIRECTORY'], 'config', 'locales', 'en.yml')
+
+class << Object
+ def const_missing(const)
+ nil
+ end
+end
+
+def method_missing(method, *args)
+ "**#{method}**"
+end
+
+def t(*args)
+ I18n.t(*args)
+end
+
+def args_to_array(*args)
+ args
+end
+
+args = eval('args_to_array(' + ENV['TM_SELECTED_TEXT'] + ')')
+
+if args.last.is_a?(Hash)
+ args.last.each { |k, v| args.last[k] = "**#{k}**" if v.nil? }
+end
+
+print I18n.t(*args)
+</string>
+ <key>fallbackInput</key>
+ <string>none</string>
+ <key>input</key>
+ <string>selection</string>
+ <key>keyEquivalent</key>
+ <string>@I</string>
+ <key>name</key>
+ <string>Lookup Translation</string>
+ <key>output</key>
+ <string>showAsTooltip</string>
+ <key>uuid</key>
+ <string>7DAF30C3-0247-4E94-AA44-DD2E69A6E236</string>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>beforeRunningCommand</key>
+ <string>nop</string>
+ <key>command</key>
+ <string>#!/usr/bin/ruby
+
+require ENV['TM_SUPPORT_PATH'] + '/lib/ui.rb'
+require ENV['TM_BUNDLE_SUPPORT'] + '/lib/rails_i18n.rb'
+
+class Hash
+ def deep_merge(other)
+ # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
+ merge(other, &merger)
+ end
+
+ def set(keys, value)
+ key = keys.shift
+ if keys.empty?
+ self[key] = value
+ else
+ self[key] ||= {}
+ self[key].set keys, value
+ end
+ end
+end
+
+project_dir = ENV['TM_PROJECT_DIRECTORY']
+path = File.join(project_dir, 'log', 'translations')
+
+translation = ENV['TM_SELECTED_TEXT'].gsub(/^\s*("|')|("|')\s*$/, '')
+key = TextMate::UI.request_string :title => 'Key', :prompt => 'Key'
+keys = ['en'] + key.split('.')
+
+log_file = File.open(path, 'a+')
+log_file.puts "#{key}: #{translation}"
+
+data = { 'en' => {} }
+data.set keys, translation
+
+path = File.join(project_dir, 'log', 'translations.yml')
+data = data.deep_merge YAML.load(File.open(path, 'r') { |f| f.read }) if File.exists?(path)
+
+File.open(path, 'w+') { |f| f.write YAML.dump(data) }
+
+print "t(:'#{key}')"
+</string>
+ <key>fallbackInput</key>
+ <string>none</string>
+ <key>input</key>
+ <string>selection</string>
+ <key>keyEquivalent</key>
+ <string>@E</string>
+ <key>name</key>
+ <string>extract translation</string>
+ <key>output</key>
+ <string>replaceSelectedText</string>
+ <key>uuid</key>
+ <string>914BB49A-6809-425F-812E-7C3C5321D403</string>
+</dict>
+</plist>
--- /dev/null
+# = Dictionary
+#
+# The Dictionary class is a Hash that preserves order.
+# So it has some array-like extensions also. By defualt
+# a Dictionary object preserves insertion order, but any
+# order can be specified including alphabetical key order.
+#
+# == Usage
+#
+# Just require this file and use Dictionary instead of Hash.
+#
+# # You can do simply
+# hsh = Dictionary.new
+# hsh['z'] = 1
+# hsh['a'] = 2
+# hsh['c'] = 3
+# p hsh.keys #=> ['z','a','c']
+#
+# # or using Dictionary[] method
+# hsh = Dictionary['z', 1, 'a', 2, 'c', 3]
+# p hsh.keys #=> ['z','a','c']
+#
+# # but this don't preserve order
+# hsh = Dictionary['z'=>1, 'a'=>2, 'c'=>3]
+# p hsh.keys #=> ['a','c','z']
+#
+# # Dictionary has useful extensions: push, pop and unshift
+# p hsh.push('to_end', 15) #=> true, key added
+# p hsh.push('to_end', 30) #=> false, already - nothing happen
+# p hsh.unshift('to_begin', 50) #=> true, key added
+# p hsh.unshift('to_begin', 60) #=> false, already - nothing happen
+# p hsh.keys #=> ["to_begin", "a", "c", "z", "to_end"]
+# p hsh.pop #=> ["to_end", 15], if nothing remains, return nil
+# p hsh.keys #=> ["to_begin", "a", "c", "z"]
+# p hsh.shift #=> ["to_begin", 30], if nothing remains, return nil
+#
+# == Usage Notes
+#
+# * You can use #order_by to set internal sort order.
+# * #<< takes a two element [k,v] array and inserts.
+# * Use ::auto which creates Dictionay sub-entries as needed.
+# * And ::alpha which creates a new Dictionary sorted by key.
+#
+# == Authors
+#
+# * Jan Molic
+# * Thomas Sawyer
+#
+# == Acknowledgments
+#
+# * Andrew Johnson (merge, to_a, inspect, shift and Hash[])
+# * Jeff Sharpe (reverse and reverse!)
+# * Thomas Leitner (has_key? and key?)
+#
+# Originally ported from OrderHash 2.0, Copyright (c) 2005 jan molic
+#
+# == History
+#
+# * 2007.10.31 trans
+# ** Fixed initialize so the constructor blocks correctly effected dictionary rather then just the internal hash.
+#
+# == Copying
+#
+# Copyright (c) 2005 Jan Molic, Thomas Sawyer
+#
+# Ruby License
+#
+# This module is free software. You may use, modify, and/or redistribute this
+# software under the same terms as Ruby.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.
+
+
+# = Dictionary
+#
+# The Dictionary class is a Hash that preserves order.
+# So it has some array-like extensions also. By defualt
+# a Dictionary object preserves insertion order, but any
+# order can be specified including alphabetical key order.
+#
+# == Usage
+#
+# Just require this file and use Dictionary instead of Hash.
+#
+# # You can do simply
+# hsh = Dictionary.new
+# hsh['z'] = 1
+# hsh['a'] = 2
+# hsh['c'] = 3
+# p hsh.keys #=> ['z','a','c']
+#
+# # or using Dictionary[] method
+# hsh = Dictionary['z', 1, 'a', 2, 'c', 3]
+# p hsh.keys #=> ['z','a','c']
+#
+# # but this don't preserve order
+# hsh = Dictionary['z'=>1, 'a'=>2, 'c'=>3]
+# p hsh.keys #=> ['a','c','z']
+#
+# # Dictionary has useful extensions: push, pop and unshift
+# p hsh.push('to_end', 15) #=> true, key added
+# p hsh.push('to_end', 30) #=> false, already - nothing happen
+# p hsh.unshift('to_begin', 50) #=> true, key added
+# p hsh.unshift('to_begin', 60) #=> false, already - nothing happen
+# p hsh.keys #=> ["to_begin", "a", "c", "z", "to_end"]
+# p hsh.pop #=> ["to_end", 15], if nothing remains, return nil
+# p hsh.keys #=> ["to_begin", "a", "c", "z"]
+# p hsh.shift #=> ["to_begin", 30], if nothing remains, return nil
+#
+# == Usage Notes
+#
+# * You can use #order_by to set internal sort order.
+# * #<< takes a two element [k,v] array and inserts.
+# * Use ::auto which creates Dictionay sub-entries as needed.
+# * And ::alpha which creates a new Dictionary sorted by key.
+#
+class Dictionary
+
+ include Enumerable
+
+ class << self
+ #--
+ # TODO is this needed? Doesn't the super class do this?
+ #++
+
+ def [](*args)
+ hsh = new
+ if Hash === args[0]
+ hsh.replace(args[0])
+ elsif (args.size % 2) != 0
+ raise ArgumentError, "odd number of elements for Hash"
+ else
+ while !args.empty?
+ hsh[args.shift] = args.shift
+ end
+ end
+ hsh
+ end
+
+ # Like #new but the block sets the order.
+ #
+ def new_by(*args, &blk)
+ new(*args).order_by(&blk)
+ end
+
+ # Alternate to #new which creates a dictionary sorted by key.
+ #
+ # d = Dictionary.alpha
+ # d["z"] = 1
+ # d["y"] = 2
+ # d["x"] = 3
+ # d #=> {"x"=>3,"y"=>2,"z"=>2}
+ #
+ # This is equivalent to:
+ #
+ # Dictionary.new.order_by { |key,value| key }
+
+ def alpha(*args, &block)
+ new(*args, &block).order_by_key
+ end
+
+ # Alternate to #new which auto-creates sub-dictionaries as needed.
+ #
+ # d = Dictionary.auto
+ # d["a"]["b"]["c"] = "abc" #=> { "a"=>{"b"=>{"c"=>"abc"}}}
+ #
+ def auto(*args)
+ #AutoDictionary.new(*args)
+ leet = lambda { |hsh, key| hsh[key] = new(&leet) }
+ new(*args, &leet)
+ end
+ end
+
+ # New Dictiionary.
+
+ def initialize(*args, &blk)
+ @order = []
+ @order_by = nil
+ if blk
+ dict = self # This ensure autmatic key entry effect the
+ oblk = lambda{ |hsh, key| blk[dict,key] } # dictionary rather then just the interal hash.
+ @hash = Hash.new(*args, &oblk)
+ else
+ @hash = Hash.new(*args)
+ end
+ end
+
+ def order
+ reorder if @order_by
+ @order
+ end
+
+ # Keep dictionary sorted by a specific sort order.
+
+ def order_by( &block )
+ @order_by = block
+ order
+ self
+ end
+
+ # Keep dictionary sorted by key.
+ #
+ # d = Dictionary.new.order_by_key
+ # d["z"] = 1
+ # d["y"] = 2
+ # d["x"] = 3
+ # d #=> {"x"=>3,"y"=>2,"z"=>2}
+ #
+ # This is equivalent to:
+ #
+ # Dictionary.new.order_by { |key,value| key }
+ #
+ # The initializer Dictionary#alpha also provides this.
+
+ def order_by_key
+ @order_by = lambda { |k,v| k }
+ order
+ self
+ end
+
+ # Keep dictionary sorted by value.
+ #
+ # d = Dictionary.new.order_by_value
+ # d["z"] = 1
+ # d["y"] = 2
+ # d["x"] = 3
+ # d #=> {"x"=>3,"y"=>2,"z"=>2}
+ #
+ # This is equivalent to:
+ #
+ # Dictionary.new.order_by { |key,value| value }
+
+ def order_by_value
+ @order_by = lambda { |k,v| v }
+ order
+ self
+ end
+
+ #
+
+ def reorder
+ if @order_by
+ assoc = @order.collect{ |k| [k,@hash[k]] }.sort_by(&@order_by)
+ @order = assoc.collect{ |k,v| k }
+ end
+ @order
+ end
+
+ #def ==( hsh2 )
+ # return false if @order != hsh2.order
+ # super hsh2
+ #end
+
+ def ==(hsh2)
+ if hsh2.is_a?( Dictionary )
+ @order == hsh2.order &&
+ @hash == hsh2.instance_variable_get("@hash")
+ else
+ false
+ end
+ end
+
+ def [] k
+ @hash[ k ]
+ end
+
+ def fetch(k, *a, &b)
+ @hash.fetch(k, *a, &b)
+ end
+
+ # Store operator.
+ #
+ # h[key] = value
+ #
+ # Or with additional index.
+ #
+ # h[key,index] = value
+
+ def []=(k, i=nil, v=nil)
+ if v
+ insert(i,k,v)
+ else
+ store(k,i)
+ end
+ end
+
+ def insert( i,k,v )
+ @order.insert( i,k )
+ @hash.store( k,v )
+ end
+
+ def store( a,b )
+ @order.push( a ) unless @hash.has_key?( a )
+ @hash.store( a,b )
+ end
+
+ def clear
+ @order = []
+ @hash.clear
+ end
+
+ def delete( key )
+ @order.delete( key )
+ @hash.delete( key )
+ end
+
+ def each_key
+ order.each { |k| yield( k ) }
+ self
+ end
+
+ def each_value
+ order.each { |k| yield( @hash[k] ) }
+ self
+ end
+
+ def each
+ order.each { |k| yield( k,@hash[k] ) }
+ self
+ end
+ alias each_pair each
+
+ def delete_if
+ order.clone.each { |k| delete k if yield(k,@hash[k]) }
+ self
+ end
+
+ def values
+ ary = []
+ order.each { |k| ary.push @hash[k] }
+ ary
+ end
+
+ def keys
+ order
+ end
+
+ def invert
+ hsh2 = self.class.new
+ order.each { |k| hsh2[@hash[k]] = k }
+ hsh2
+ end
+
+ def reject(&block)
+ self.dup.delete_if(&block)
+ end
+
+ def reject!( &block )
+ hsh2 = reject(&block)
+ self == hsh2 ? nil : hsh2
+ end
+
+ def replace( hsh2 )
+ @order = hsh2.order
+ @hash = hsh2.hash
+ end
+
+ def shift
+ key = order.first
+ key ? [key,delete(key)] : super
+ end
+
+ def unshift( k,v )
+ unless @hash.include?( k )
+ @order.unshift( k )
+ @hash.store( k,v )
+ true
+ else
+ false
+ end
+ end
+
+ def <<(kv)
+ push(*kv)
+ end
+
+ def push( k,v )
+ unless @hash.include?( k )
+ @order.push( k )
+ @hash.store( k,v )
+ true
+ else
+ false
+ end
+ end
+
+ def pop
+ key = order.last
+ key ? [key,delete(key)] : nil
+ end
+
+ def inspect
+ ary = []
+ each {|k,v| ary << k.inspect + "=>" + v.inspect}
+ '{' + ary.join(", ") + '}'
+ end
+
+ def dup
+ a = []
+ each{ |k,v| a << k; a << v }
+ self.class[*a]
+ end
+
+ def update( hsh2 )
+ hsh2.each { |k,v| self[k] = v }
+ reorder
+ self
+ end
+ alias :merge! update
+
+ def merge( hsh2 )
+ self.dup.update(hsh2)
+ end
+
+ def select
+ ary = []
+ each { |k,v| ary << [k,v] if yield k,v }
+ ary
+ end
+
+ def reverse!
+ @order.reverse!
+ self
+ end
+
+ def reverse
+ dup.reverse!
+ end
+
+ #
+ def first(x=nil)
+ return @hash[order.first] unless x
+ order.first(x).collect { |k| @hash[k] }
+ end
+
+ #
+ def last(x=nil)
+ return @hash[order.last] unless x
+ order.last(x).collect { |k| @hash[k] }
+ end
+
+ def length
+ @order.length
+ end
+ alias :size :length
+
+ def empty?
+ @hash.empty?
+ end
+
+ def has_key?(key)
+ @hash.has_key?(key)
+ end
+
+ def key?(key)
+ @hash.key?(key)
+ end
+
+ def to_a
+ ary = []
+ each { |k,v| ary << [k,v] }
+ ary
+ end
+
+ def to_s
+ self.to_a.to_s
+ end
+
+ def to_hash
+ @hash.dup
+ end
+
+ def to_h
+ @hash.dup
+ end
+end
\ No newline at end of file
--- /dev/null
+require File.join(File.dirname(__FILE__), 'dictionary')
+require File.join(File.dirname(__FILE__), 'yaml_waml')
\ No newline at end of file
--- /dev/null
+# stolen from Kakutani Shintaro http://github.com/kakutani/yaml_waml
+
+require "yaml"
+
+class String
+ def is_binary_data?
+ false
+ end
+end
+
+module YamlWaml
+ def decode(orig_yamled)
+ yamled_str = case orig_yamled
+ when String then orig_yamled
+ when StringIO then orig_yamled.string
+ else return orig_yamled
+ end
+ yamled_str.gsub!(/\\x(\w{2})/){[$1].pack("H2")}
+ return yamled_str
+ end
+ module_function :decode
+end
+
+ObjectSpace.each_object(Class) do |klass|
+ klass.class_eval do
+ if method_defined?(:to_yaml) && !method_defined?(:to_yaml_with_decode)
+ def to_yaml_with_decode(*args)
+ io = args.shift if IO === args.first
+ yamled_str = YamlWaml.decode(to_yaml_without_decode(*args))
+ io.write(yamled_str) if io
+ return yamled_str
+ end
+ alias_method :to_yaml_without_decode, :to_yaml
+ alias_method :to_yaml, :to_yaml_with_decode
+ end
+ end
+end
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>name</key>
+ <string>Rails I18n</string>
+ <key>ordering</key>
+ <array>
+ <string>914BB49A-6809-425F-812E-7C3C5321D403</string>
+ <string>7DAF30C3-0247-4E94-AA44-DD2E69A6E236</string>
+ </array>
+ <key>uuid</key>
+ <string>F217218F-CCD3-45C0-8D67-DB761EA9CE61</string>
+</dict>
+</plist>