Browse Source

Added locale rtl support (e. g. for Persian or Hebrew).

Martin Edenhofer 7 years ago
parent
commit
3e92e4f9f4

+ 9 - 9
app/assets/javascripts/app/lib/app_post/i18n.coffee

@@ -96,12 +96,15 @@ class _i18nSingleton extends Spine.Module
 
     # prepare locale
     localeToSet = localeToSet.toLowerCase()
+    dirToSet = 'ltr'
 
     # check if locale exists
     localeFound = false
     locales     = App.Locale.all()
     for locale in locales
       if locale.locale is localeToSet
+        localeToSet = locale.locale
+        dirToSet = locale.dir
         localeFound = true
 
     # try aliases
@@ -109,6 +112,8 @@ class _i18nSingleton extends Spine.Module
       for locale in locales
         if locale.alias is localeToSet
           localeToSet = locale.locale
+          dirToSet = locale.dir
+          localeFound = true
 
     # if no locale and no alias was found, try to find correct one
     if !localeFound
@@ -118,15 +123,9 @@ class _i18nSingleton extends Spine.Module
       for locale in locales
         if locale.alias is localeToSet
           localeToSet = locale.locale
+          dirToSet = locale.dir
           localeFound = true
 
-      # try to find by locale
-      if !localeFound
-        for locale in locales
-          if locale.locale is localeToSet
-            localeToSet = locale.locale
-            localeFound = true
-
     # check if locale need to be changed
     return if localeToSet is @locale
 
@@ -136,8 +135,9 @@ class _i18nSingleton extends Spine.Module
     # set if not translated should be logged
     @_notTranslatedLog = @notTranslatedFeatureEnabled(@locale)
 
-    # set lang attribute of html tag
-    $('html').prop('lang', @locale.substr(0, 2) )
+    # set lang and dir attribute of html tag
+    $('html').prop('lang', localeToSet.substr(0, 2))
+    $('html').prop('dir', dirToSet)
 
     @mapString = {}
     App.Ajax.request(

+ 61 - 1
app/models/translation.rb

@@ -1,4 +1,5 @@
 # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
+require 'csv'
 
 class Translation < ApplicationModel
   before_create :set_initial
@@ -212,7 +213,7 @@ translate strings in ruby context, e. g. for notifications
 
 =begin
 
-load locales from local
+load translations from local
 
 all:
 
@@ -282,6 +283,65 @@ all:
     true
   end
 
+=begin
+
+load translations from csv file
+
+all:
+
+  Translation.load_from_csv
+
+  or
+
+  Translation.load_from_csv(locale, file_location, file_charset) # e. g. 'en-us' or 'de-de' and /path/to/translation_list.csv
+
+  e. g.
+
+  Translation.load_from_csv('he-il', '/Users/me/Downloads/Hebrew_translation_list-1.csv', 'Windows-1255')
+
+Get source file at https://i18n.zammad.com/api/v1/translations_empty_translation_list
+
+=end
+
+  def self.load_from_csv(locale_name, location, charset = 'UTF8')
+    locale = Locale.find_by(locale: locale_name)
+    if !locale
+      raise "No such locale: #{locale_name}"
+    end
+
+    if !::File.exist?(location)
+      raise "No such file: #{location}"
+    end
+
+    content = ::File.open(location, "r:#{charset}").read
+    params = {
+      col_sep: ',',
+    }
+    rows = ::CSV.parse(content, params)
+    header = rows.shift
+
+    translation_raw = []
+    rows.each { |row|
+      raise "Can't import translation, source is missing" if row[0].blank?
+      if row[1].blank?
+        warn "Skipped #{row[0]}, because translation is blank"
+        next
+      end
+      raise "Can't import translation, format is missing" if row[2].blank?
+      raise "Can't import translation, format is invalid (#{row[2]})" if row[2] !~ /^(time|string)$/
+      item = {
+        'locale'         => locale.locale,
+        'source'         => row[0],
+        'target'         => row[1],
+        'target_initial' => '',
+        'format'         => row[2],
+      }
+      translation_raw.push item
+    }
+    to_database(locale.name, translation_raw)
+    true
+  end
+
   private_class_method def self.to_database(locale, data)
     translations = Translation.where(locale: locale).all
     ActiveRecord::Base.transaction do

+ 1 - 0
db/migrate/20120101000001_create_base.rb

@@ -209,6 +209,7 @@ class CreateBase < ActiveRecord::Migration
       t.string  :locale,              limit: 20,  null: false
       t.string  :alias,               limit: 20,  null: true
       t.string  :name,                limit: 255, null: false
+      t.string  :dir,                 limit: 9,   null: false, default: 'ltr'
       t.boolean :active,                          null: false, default: true
       t.timestamps limit: 3, null: false
     end

+ 4 - 0
db/migrate/20170619000001_tree_select.rb

@@ -1,5 +1,9 @@
 class TreeSelect < ActiveRecord::Migration
   def up
+
+    # return if it's a new setup
+    return if !Setting.find_by(name: 'system_init_done')
+
     change_column :object_manager_attributes, :data_option, :text, limit: 800.kilobytes + 1, null: true
     change_column :object_manager_attributes, :data_option_new, :text, limit: 800.kilobytes + 1, null: true
   end

+ 9 - 0
db/migrate/20170626000001_locale_add_direction.rb

@@ -0,0 +1,9 @@
+class LocaleAddDirection < ActiveRecord::Migration
+  def up
+
+    # return if it's a new setup
+    return if !Setting.find_by(name: 'system_init_done')
+
+    add_column :locales, :dir, :string, limit: 9, null: false, default: 'ltr'
+  end
+end