Monday, November 08, 2010 at 12:02 AM.


on getString (stringId, adrLanguageTable, adrReplacementTable=nil, defaultLanguageName=nil) {
		<<7/5/02; 3:51:37 AM by JES
			<<Call through Frontier.getLocalizedObject to get the address of the string.
		<<05/17/00; 7:45:29 PM by JES
			<<optimized string finding code for about a 10% execution speed increase
		<<05/01/00; 1:16:08 PM by JES
			<<This is the bottleneck and place for optimization of all localized string lookups in Frontier.
				<<stringId -- This is a partial address, dot-delimited, like "discuss.byLine" or whatever. (Strings are stored in a table hierarchy.)
				<<adrLanguageTable -- This is the actual Frontier address of the language table to use.
				<<adrReplacementTable -- This is the address of a replacement table. It contains name/value pairs, of course. The values are the localized strings.
				<<defaultLanguageName -- the name of the language to fall back to if the lookup fails
					<<For example, mainResponder has a default setting at config.mainResponder.globals.language, which is passed in if it exists.
	<<on findString (adrLanguageTable, stringId)
		<<gets a string, given the language table address and the stringId
		<<on dive (adrLanguageTable, stringId) // takes a partial address, returns the address of a string, or false if not found
			<<local (nomad = @adrLanguageTable^.strings, s)
				<<if not (stringId contains ".")
					<<nomad = @nomad^.[stringId]
				<<s = string.nthField (stringId, '.', 1)
				<<nomad = @nomad^.[s]
				<<if not defined (nomad^)
					<<return (false)
				<<stringId = string.delete (stringId, 1, sizeOf (s) + 1)
			<<if defined (nomad^)
				<<return (nomad)
			<<return (false)
		<<local (stringAdr = dive (adrLanguageTable, stringId))
		<<if stringAdr // found it.
			<<return (string (stringAdr^))
		<<Was there a default language passed in?
		<<local (adrLanguagesTable = parentOf (adrLanguageTable^), defaultLanguage)
		<<if defaultLanguageName // was there a default language passed in?
			<<defaultLanguage = defaultLanguageName
			<<if defined (adrLanguagesTable^.[defaultLanguage])
				<<adrLanguageTable = @adrLanguagesTable^.[defaultLanguage]
				<<stringAdr = dive (adrLanguageTable, stringId)
				<<if stringAdr // found it.
					<<return (string (stringAdr^))
		<<Is there a default language setting for Frontier that's different from the one passed in?
		<<if defined (user.prefs.language) and (string.lower (user.prefs.language) != defaultLanguageName)
			<<defaultLanguage = user.prefs.language
			<<if defined (adrLanguagesTable^.[defaultLanguage])
				<<adrLanguageTable = @adrLanguagesTable^.[defaultLanguage]
				<<stringAdr = dive (adrLanguageTable, stringId)
				<<if stringAdr // found it.
					<<return (string (stringAdr^))
		<<only check for the English string if the default setting was something other than English
		<<if string.lower (defaultLanguage) != "english"
			<<if defined (adrLanguagesTable^.english)
				<<adrLanguageTable = @adrLanguagesTable^.english
				<<stringAdr = dive (adrLanguageTable, stringId)
				<<if stringAdr // found it.
					<<return (string (stringAdr^))
		<<scriptError ("Could not find the translation string at '" + stringId + "'.")
	local (s);
	<<s = findString (adrLanguageTable, stringId)
	local (adrstring);
	if Frontier.getlocalizedObject ("strings." + stringId, adrLanguageTable, @adrstring, defaultLanguageName) {
		s = string (adrstring^)}
	else { //error
		scriptError ("Could not find the translation string at '" + stringId + "'.")};
	if adrReplacementTable != nil { // replace the bracketted items -- "[[name]]", "[[date]]", etc
		if date.versionLessThan (Frontier.version (), "7.1b18") {
			local (i = 1, adrReplacementItem);
			for adrReplacementItem in adrReplacementTable {
				s = string.replaceAll (s, "[[" + nameOf (adrReplacementItem^) + "]]", adrReplacementItem^, false)}}
		else { //PBS 11/02/01: use string.multipleReplaceAll
			s = string.multipleReplaceAll (s, adrReplacementTable, false, "[[", "]]")}};
	return (s)};
bundle { //test code
	bundle { //test
		dialog.notify (getString ("weblogPostForm.postButton",}}
	<<bundle //benchmark
		<<local (t = clock.ticks ())
		<<for i = 1 to 1000
			<<getString ("weblogPostForm.postButton",
		<<dialog.notify (clock.ticks () - t)

This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.