Frequently asked questions
NOTE: The best way to get help now is on the MailingList.
Q: Do methods like truncate still work on translated/unicode strings?
A: Good question, I haven’t looked into this much, but it’s more of a Ruby thing. Ruby doesn’t seem to handle String#length correctly for unicode strings, although I believe there are libraries that correct this. Better Unicode support is also planned for future Ruby releases. —JH
Meanwhile Globalize code doesn’t care that String.length returns size of string in bytes.
E.g. there is no support for multibyte UTF8 chars in methods globalize/rails/active_record.rb:ActiveRecord::Errors#add_on_boundary_breaking,ActiveRecord::Validations#validates_length_of,
or globalize/models/language.rb
Globalize::Language#after_initialize:
if !pluralization.nil? && pluralization.size > 200 raise SecurityError, "Pluralization field for #{self.english_name} language " + "contains potentially harmful code. " + "Must be less than 200 characters in length. Was #{pluralization.size} characters." end
Be honest, say validates_bytes_length_of, “must be less then 200 bytes” or address this issue.
Q: The installation looks too easy. In fact, I tried it out.
I see this:
242:~/CD/railsdemos oracle$ rails globize
...
242:~/CD/railsdemos oracle$ cd globize
242:~/CD/railsdemos/globize oracle$ script/plugin install svn://www.diluvia.net/rails-plugins/globalize/trunk
/opt/local/lib/ruby/1.8/open-uri.rb:87:in `initialize': No such file or directory - svn://www.diluvia.net/rails-plugins/globalize/trunk (Errno::ENOENT)
from /opt/local/lib/ruby/1.8/open-uri.rb:87:in `open_uri_original_open'
...
from from script/plugin:3
What am I doing wrong?
A: Dan, do you have subversion installed? Is it in your path? Also, which version of Ruby are you running?
Q: I’ve also go a weird error, when using PostGreSQL 8.0. Everything works fine on my debian server (live box), but on my Ubuntu box (devel box) things are a little screwy.
Everytime I try to rake migrate I get the following error:
RuntimeError: ERROR C55000 Mcurrval of sequence "globalize_countries_id_seq" is not yet defined in this session Fsequence.c L598 Rcurrval: SELECT currval('public.globalize_countries_id_seq')
Anyone have any idea what I’m doing wrong ?
A: Which versions of Rails, Globalize and Postgresql do you have?—JH
I got the data to load by modifying the migration to ignore the row id. Here is a patch:
--- 002_globalize_migration.rb.orig 2005-12-30 17:38:33.000000000 +0800
+++ 002_globalize_migration.rb 2005-12-29 02:24:22.000000000 +0800
@@ -72,13 +72,20 @@
reader = CSV::Reader.create(data)
columns = reader.shift.map {|column_name| cnx.quote_column_name(column_name) }
+ columns.shift # added for PostgreSQL
column_clause = columns.join(', ')
reader.each do |row|
next if row.first.nil? # skip blank lines
raise "No table name defined" if !table_name
raise "No header defined" if !column_clause
- values_clause = row.map {|v| cnx.quote(v).gsub('
', "
").gsub('
', "
") }.join(', ')
+
+ # Changed for PostgreSQL
+ #values_clause = row.map {|v| cnx.quote(v).gsub('
', "
").gsub('
', "
") }.join(', ')
+ values = row.map {|v| cnx.quote(v).gsub('
', "
").gsub('
', "
") }
+ values.shift
+ values_clause = values.join(', ')
+
sql = "INSERT INTO #{table_name} (#{column_clause}) VALUES (#{values_clause})"
cnx.insert(sql)
end
—Jake Morrison
I had the same trouble with Postgres. The issue is that Postgres does not define currval() before the sequence is used. What I did was add a call to set the values on the sequences after the creation of the tables (around line 55):
# Added for PostgresSQL
tables = ['globalize_countries', 'globalize_translations', 'globalize_languages']
tables.each do |table|
sql = "SELECT setval('#{table}_id_seq', 1)"
ActiveRecord::Base.connection.execute(sql)
end
-Daniel Wiesmann
Why is :select not allowed in the replacement for ActiveRecord::find? (in Globalize::DbTranslate)
Because Globalize modifies the :select portion of the query, so overriding it would break the functionality. —JH
I can see that I’m to use “string”.t to translate strings in my app, but where do I actually put the translated strings? Am I just blind, or is this not covered anywhere?
The translated strings go in the globalize_translations table in the db. Use Globalize::Locale.set_translation(key, *translations) to write new translations to the db. —JH
rails validation error gives me a ’%d’ i.s.o a number
There were problems with the following fields:
* Desc short is too short (min is %d characters)
BTW is is an idea to have these validation errors also in the translation database?
_cies breijs.
Answer: Actually, I’ve been seeing that, too—I’m going to look into it. —JH
i think this is an error generating an other error.
when i get globalize out of the plugin-path and environment.rb i get to see a normal error.
ActionView::ActionViewError (No rhtml, rxml, or delegate template found for /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/templates/rescues/diagnostics.rhtml):
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_view/base.rb:281:in `pick_template_extension'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_view/base.rb:195:in `globalize_old_render_file'
/vendor/plugins/globalize/lib/globalize/rails/action_view.rb:15:in `render_file'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/rescue.rb:73:in `rescue_action_locally'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/rescue.rb:31:in `rescue_action'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/rescue.rb:108:in `perform_action'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:369:in `send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/base.rb:369:in `process_without_session_management_support'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/action_controller/session_management.rb:116:in `process'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/dispatcher.rb:38:in `dispatch'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:141:in `process_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:53:in `process!'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:52:in `each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:597:in `each'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:597:in `each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:52:in `process!'
/usr/local/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/fcgi_handler.rb:22:in `process!'
dispatch.fcgi:24
_cies breijs.
Is there a way to make globalization work with pagination? I’m getting an error about :select, which was explained, but any ways to get it to work?
Answer: Good question, I’m looking into it. —JH
Any plan to make this module install via rubygem?
—CC
Answer: Not at this point. Since it’s a per application modification, I’m not sure how that would work. —JH
I have installed globalize according to the instruction provided in the home page. I populated the development database and test database. When I test run the test_plugins, I got an error loading sqlite3 as the following.
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in `require__': no such file to load -- sqlite3 (MissingSourceFile)
Why do I have to have sqlite installed? I use mysql only. Any idea how to workaround this?
—CC
Answer: You don’t really have to have sqlite installed. That’s just the default so that it will work out of the box with no extra db setup. Just change the globalize/test/config/database.yml file to reflect your mysql globalize test db. —JH
Are translations by language or by locale? As far as I can see they are by language, i.e.,
Locale.set("en-CA")
Locale.set_translation("a test","Canadian test")
Locale.set("en-US")
Locale.set_translation("a test","American test")
ends up with only one translation, and
<% Locale.set("en-CA") %>
<%= "a test".t %><br/>
<% Locale.set("en-US") %>
<%= "a test".t %><br/>
prints out
American test American test
Am I missing something? Thanks,
Dave
Answer: Yes, translations are keyed by language, however a language can be a localized dialect, such as en-CA (this is standardized as RFC 3066, and the Language model has a column for it). All you have to do is add rows to the globalize_languages table for the dialects you need. Then, when you do something like Locale.set(‘en-CA’), the referenced language will be the new en-CA language you added. —JH
More: I have run into a problem with this. The translation
cacheing uses the language first, then the locale
RFC 3066 locale. That is, cache_key in
Globalize::DbViewTranslator
def cache_key(key, language, idx)
[ key, language.code, idx ].join(':')
end
uses language.code, which is defined like this:
def code; iso_639_1 || iso_639_3 || rfc_3066; end
So it seems that either code needs to try rfc_3066 first, or cache_key does, i.e.
def code; rfc_3066 || iso_639_1 || iso_639_3; end
Or you have to null out the iso_639_1 and iso_639_3 fields
if you are going to use rfc_3066. I have modified
code on my site. —Jake Morrison
I already have a small web app which is translated into a number of langs (about 7). It’s perl on top of mysql. I’m looking at maybe migrating to ROR in future.
My app is organised in a very simple way – I have a table called sitetext:
this handles the majority of small words and phrases used. I use substitution like $VAR to make things flexible. There are other tables too that work similarly.
- How is underlying content organised in globalize? How hard would it be to write a script to migrate my content?
- Also, suppose a pages content changes – the author changes the english text. Does globalise track the fact that other langs are out of date? This is the way I will definitely need to go in future.
thanks
Answer: I don’t understand how you’re currently doing it, but you should definitely be able to write a migration script. As for question 2, Globalize is not currently tracking that, but it’s in the works.
response
My current layout is just one col in a table per language, plus an id – that’s what I meant. How is the database laid out in your code? is it documented somewhere here (even just an sql script or something?) thanks for the answer.
Jan 05, 2006:
I’m using ubuntu “hoary”, ruby 1.83, rails 1.0, postgres 7.4.7, and globalize svn version 155. The first two steps in the installation worked fine, but the third, “rake migrate” failed, in the same way described by Jake Morrison in his post above. I also had success by changing my db/migrate/001_globalize_migration.rb script as Jake described, after dropping the tables created in the database on the first attempt of running “rake migrate”
It’d be nice to patch the file. I suspect that the patched file would run on mysql also – the generated sql is standard sql.
OK, off to testing out globalizing my app.
Thanks for writing Globalize!
2006-01-25:
The plugin seems to be very useful. Only I’m worried that storing both app-translations (interface) and user-translations (user data) in the same database/table might make development as well as deployment harder. How do you handle this?
I imagine there could be benefits of a YAML based (or similar) solution for the view translations, and maybe even the languages and countries tables. (Version control, separation of user data and app data and more.) (Note that this is ment as a question, not a flame.)
2006-01-31
I would like to feed all translation strings from external script in shell, but I have no idea how to make it… I can load those data only from controller and browser, but it is not efficient :(
class WelcomeController < ApplicationController
include Globalize
def load
Locale.set_base_language('en')
rows = [
{:key=>'title', :language=>'pl', :translations=>['Tytuł', 'Tytuły', 'Tytuły', 'Tytuły', 'Tytułów']},
{:key=>'title', :language=>'en', :translations=>['The title', 'The titles']},
{:key=>'title', :language=>'de', :translations=>['Der Titel']},
]
for row in rows
Locale.set(row[:language])
Locale.set_translation(row[:key], Locale.language, row[:translations])
end
end
end
There would be very usefull to have an option for extract all globalize strings into one place (like gettext). And, after translation, upgrade the database with one script.
2006-02-07
I have been trying using Globalize plugin from external Ruby script, but it I do not know how. I created folder ‘work’ in my RoR application and I try to use script from this place:
1st try:
require File.dirname(__FILE__) + '/../vendor/plugins/globalize/init.rb')
does not work:
undefined local variable or method `directory' for main:Object (NameError)
2nd try:
require 'active_record' def directory_binding directory = File.dirname(__FILE__)+"/../vendor/plugins/globalize/lib/" Dir.chdir(directory) binding end eval(IO.read(File.dirname(__FILE__) + '/../vendor/plugins/globalize/init.rb'), directory_binding)
also does not work:
./globalize/rails/action_view.rb:4:in `alias_method': undefined method `render_file' for class `ActionView::Base'
2006-02-21
I really need some help in using the Globalize plugin. I’m currently developing on OSX 10.4.4, RoR 1.0, Postgres 8.0, and Ruby 1.8.2_4. My problem is making Globalize work with my models. Here a sample of my code:
environment.rb:
include Globalize
controllers/application.rb:
class ApplicationController < ActionController::Base
Locale.set_base_language('en-US')
end
models/trial.rb:
class Trial < ActiveRecord::Base translates :name end
trial_controller.rb:
class TrialController < ApplicationController
def index
Locale.set('en-US')
Trial.create(:name => 'One')
Locale.set('es-ES')
trial = Trial.find(1)
trial.name = 'Uno'
if trial.save
render_text("#{trial.name")
end
end
end
When running the app I get this error:
RuntimeError: ERROR C42601 Msyntax error at or near "WHERE" P20 Fscan.l L639 Ryyerror: UPDATE trials SET WHERE id = 1
Looking at it closely, it seems that on the intiall save on the
database, no data is being saved on the globalize_translation table so
when I try to update the data from my trials table no value is being
passed.
I know that I have configured the app properly because data is being
passed to the globalized_translation folder when I do “foo”.t on the views but I
really can’t make it work with my models.
Q: How do i prevent the base language text from being displayed when there’s no translation available for the current language?
Q: How do i find out (at runtime) if a model has a translation in the current language?
A: Globalize adds the methods xxx_is_base? to ActiveRecord, where xxx stands for the attribute name. before using the attribute, first check if it’s translated.
Example:
I have lots of Page objects, the property content is translated into several languages. To display all the pages that still need to be translated, do the following:
# somewhere in the controller
include Globalize
Locale.set_base_language('en')
Locale.set('es')
@pages = Page.find(:all)
# in the view
<%
@pages.each do |page|
if page.content_is_base? %>
<%= puts 'Page still needs to be translated!' %>
<% end %>
(not tested, hope there's no bug.)
Q: When I do a rake migrate I get this error. How do I fix it?
rake migrate (in /home/brian/pken) rake aborted! undefined method `namespace' for #<Object:0x400b59c0>
A: You need to update rake to 0.7 which adds namespace support. `sudo gem update rake` will do that for you.
2006-05-15
Q How much effort would it be to implement Oracle support? What are the DB-depencies?
Q Is possible to implement a runtime URL name translation?
...
map.connect /:language/ “restaurant”.t ”/” + “parmesan”.t
...
So that /en/restaurant/parmesan and /it/ristorante/parmigiano are logically the same page?
—> that would be amazing!
or some other possibility to support localizing urls, too. how are you guys doing this?
http://rails.techno-weenie.net/question/2006/5/23/url_reverse_translation
revision 1 · 25.06.08 00:40 · by: Sven