Language handler question

In the API docs:
In the introduction to LanguageHandler
http://www.sketchup.com/intl/en/developer/docs/ourdoc/languagehandler

the example given to get a localized string is
localizedStr = swiveldriver_langHandler.GetString(‘String 1’)

Yet the only method defined for getting a string is LanguageHandler.
localized_string = swiveldriver_langHandler[‘String 1’]

Is there a difference?

The GetString is an alias for the [] method. It seems it just misses from the documentation (but [] is shorter anyways where as the spelling of GetStringslightly violatesRuby style).

The link doesn’t work for me.

Try this: GitHub - rubocop/ruby-style-guide: A community-driven Ruby coding style guide

The LanguageHandler is an old class used by SketchUp’s extensions since the early beginning. The names had that quirky naming of capital letter because they where written by C++ programmers.
The examples stem from this time - before the LanguageHandler was made part of the API.

(That being said, I personally don’t like the LanguageHandler being made into the API as-is - it could have done with some improvements. Though that was before my time.)

Hi all!

LanguageHandler is making me crazy. I have followed the docs example but it never returns the string from the .strings file:

localized = LanguageHandler.new('my_words.strings')
localized_string = localized['String 1'] 

I have checked the path structure so many times :cry:

myscript.rb <- creates the SketchupExtension instance
myscript/
myscript/Resources/
myscript/Resources/en/my_words.strings 

Any ideas?

2 Likes

(1) The lookup keystring must be IN the strings file, exactly as you give in the method call.

  • Be aware that GetString() must be used for SketchUp versions prior to 2014, or you must create a singleton method alias for [].
require 'langhandler'
say = LanguageHandler.new('my_words.strings')
(def say.[](key); self.GetString(key); end) unless say.respond_to?(:[])
# Now use [] method call freely against the say object.
  • The GetString() method alias should be considered deprecated, and the more rubyish [] used for new projects. (The API docs should have said this as well.)

(2) The “Resources” sub-directories must follow the exact names of the language codes returned by the Sketchup.get_locale() method, because that is the method call that is used in the file that defines the LanguageHandler class.
(Look at the “langhandler.rb” file in the “Tools” sub-dir.)

  • The name of your English sub-directory is “en” instead of “en-US”.
3 Likes

Thanks Dan!

No luck yet. I’ve tried both en and en-US, Sketchup.get_locale() returned en-US, but I’ll try again and report.

Will always return the locale of the language version of SketchUp you installed. If you want to test your strings you can follow these instructions: Localized Strings · Issue #45 · SketchUp/sketchup-stl · GitHub
(We need to document that better.)

tt_su, Dan, Villares,
I have been trying to get LanguageHandler to work for a week now without success. Does it work at all?

here is my code:-
this file called Language.rb is in C:\Users\Francis\AppData\Roaming\SketchUp\SketchUp 2015\SketchUp\Plugins\

require 'sketchup.rb'
require 'extensions.rb'
require 'langhandler.rb'


	
	$tStrings = LanguageHandler.new('helloBonjourTag.strings')
	
	helloBonjourTagExtension = SketchupExtension.new(
  "helloBonjourTag Tools", "Language/helloBonjourTag.rb")
  helloBonjourTagExtension.description="Languagehandler test"
	helloBonjourTagExtension.version = "1"
	helloBonjourTagExtension.creator = "FMS"
	helloBonjourTagExtension.copyright = "FMS"
	Sketchup.register_extension helloBonjourTagExtension, Sketchup.is_pro?

This one called helloBonjourTag.rb  is in C:\Users\Francis\AppData\Roaming\SketchUp\SketchUp 2015\SketchUp\Plugins\Language\
def hello
	locale = Sketchup.get_locale
	localizedStr = $tStrings['Hello']
	UI.messagebox("$tStrings.strings is #{$tStrings.strings}")
	UI.messagebox("locale is  #{locale} and localised string is #{localizedStr}")
end
this one is in C:\Users\Francis\AppData\Roaming\SketchUp\SketchUp 2015\SketchUp\Plugins\Language\Resources\en-US\helloBonjourTag.strings
"Hello" = "Bon Tag";
"Goodbye" = "Goodbye";

any help appreciated

best Francis

(1) Your strings file is invalid.

"Hello" = "Bon Tag";
"Goodbye" = "Goodbye";

needs to be like:

"Hello"="Bon Tag";
"Goodbye"="Goodbye";

no spaces surrounding the = character.


(2) Do not use $ global variables (even if poorly written examples do use them.) Your use of the $tStrings global variable will clash with Trimble’s use for one of the common extensions.


(3) Do not define global methods. All of you code needs to be within a unique module namespace. Since it is likely that you will write multiple plugins, each plugin should be within it’s own sub-module of your toplevel module.


(4) Do not use common names for plugin folders. Prefix all your plugin folders with the name of your toplevel module, followed by an undescore, like: “Camlaman_SomePlugin”

1 Like

tt_su, Dan, Villares,
I meant to say that I then type in hello into the Ruby console and hope to see ‘Hello’ translated into ‘Bon Tag’. My little joke mixing French and German. I have the American English version of Sketchup so this is just to test if LanguageHandler returns anything.

The program produces 2 UI.messageboxes, the first says $tStrings.strings = {} and the second says locale is en-US and localised string is ‘Hello’. That is where I go ‘Ahrggg!’

Thanks for any help you can give.
Best,
Francis

Because you have spaces surrounding the = character in your strings file.

There is a bug in “langhandler.rb” which ignores lines that are not EXACTLY
"string"="string";
so it ignores your lines that are:
"string" = "string";

1 Like

It does not work like this. The LanguageHandler does not change Ruby string handling into another language. So you will not be able to just type English words at the console and expect them to be translated.

The LanguageHandler class is just a simple wrapper around a Hash object, whose members are loaded from a file. So, you need to access your strings via the [] method called upon your LanguageHandler object:

@say = LanguageHandler::new("Camlaman.strings")
puts @say["hello"]

Dan,
thanks for the tip about the spaces. I tried changing the file but got a system error about the file being used by another program when I tried to save it. Not sure why that is but I think if I turn the computer on and off that should fix it, though ultimately I do wonder why that is happening?
I’ll let you know how I get on,
Thanks again,
Francis

Dan,
worked fine! Thank you so much. I’m sorry I broke all those Ruby etiquette rules but I just wanted to learn how LanguageHandler worked. I won’t be publishing my dry runs. The fussiness of the .strings file really caught me off guard. Ruby is so forgiving but that is not the case for everything. I’ll try to avoid your points 2,3 and 4 in anything I publish.
Thanks again,
Francis

2 Likes

We’re to blame for all the old bad examples. It’s burning a hole in our TODO list to get this fixed.

Btw, I updated your post so that the block of code is formatted better:

Dan, Thomas,
sorry to be a pain but I still have a small problem with the translation files. I have managed to translate my extension into French without problem but LanguageHandler seems to be tripping up over the German characters ä, ö etc. The german extension.strings file works when I replace them with ae, oe etc but it just doesn’t look nice. Real Germans wouldn’t be happy about it. Any ideas what I am doing wrong. I thought marking the file as UTC-8 in Notepad++ and saving it would do the trick but although Notepad++ converted all the characters into odd looking codes LanguageHandler still wouldn’t load the file.
Thanks for all your help!
Francis

Dan, Thomas,
by the way I save the files in Notepad++ with the format being ANSI. The French file has French characters like é in it and nevertheless, works fine.
Thanks again,
Francis

The strings files need to be encoded as UTF-8 without Bit Order Mark. (Just plain UTF-8 in Notepad++, NOT the UTF-8-BOM choice.)

Your Ruby files should also be encoded the same, and have a “magic comment” as the first line, like this:

# encoding: UTF-8