Last active
November 28, 2023 01:08
-
-
Save tmedwards/1710c9bf7db551ea6e6436b97e31d897 to your computer and use it in GitHub Desktop.
SugarCube v2 basic internationalization (i18n) example using a switching method (in Twee notation)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:: StoryTitle | |
SugarCube i18n example | |
:: Language Switching [script] | |
;(function () { | |
/*********************************************************** | |
Set up a `i18n` object on SugarCube's `setup` object. | |
***********************************************************/ | |
setup.i18n = { | |
/* | |
Map of language tags to labels for all supported | |
languages go here. | |
NOTE: All language tags should follow the syntax described within | |
BCP 47 (currently: RFC 5646). | |
SEE: | |
- https://www.rfc-editor.org/info/rfc5646 | |
- https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang | |
*/ | |
languages : { | |
// NOTE: User customization required here. | |
'de' : 'Deutsche', | |
'en' : 'English', | |
'fr' : 'Français' | |
}, | |
/* | |
The active language. The initial value will be the | |
default. | |
*/ | |
lang : recall('lang', 'en'), | |
/* | |
Initializes the active language. | |
*/ | |
initLang : function () { | |
/* | |
Set the `l10nStrings` properties to the appropriate | |
values for each supported language. | |
English need not receive a case, unless you simply | |
want to alter the default values, as it is the | |
default language. | |
*/ | |
switch (this.lang) { | |
/* | |
NOTE 1: User customization required here. | |
NOTE 2: The `l10nStrings` properties shown in the cases below | |
are an abbreviated set for example purposes. There are many | |
more properties within the `l10nStrings` object which you'll | |
need to handle. | |
*/ | |
case 'de': | |
l10nStrings.settingsTitle = 'Einstellungen'; | |
l10nStrings.settingsOff = 'Deaktivieren'; | |
l10nStrings.settingsOn = 'Aktivieren'; | |
l10nStrings.settingsReset = 'Auf Standardeinstellung zurücksetzen'; | |
break; | |
case 'fr': | |
l10nStrings.settingsTitle = 'Paramètres'; | |
l10nStrings.settingsOff = 'Désactiver'; | |
l10nStrings.settingsOn = 'Activer'; | |
l10nStrings.settingsReset = 'Réinitialiser les paramètres par défaut'; | |
break; | |
} | |
/* | |
Set the `lang` attribute on the document element to | |
the appropriate value. This is mostly notational, | |
though it could also be used to enable localization | |
specific styling. | |
*/ | |
$('html').attr('lang', this.lang); | |
}, | |
/* | |
Sets the active language by tag—e.g. 'en'. | |
JavaScript example: | |
setup.i18n.setLang('de'); | |
Macro example: | |
<<run setup.i18n.setLang('de')>> | |
*/ | |
setLang : function (tag) { | |
if (!this.tags().includes(tag)) { | |
throw new Error('unknown language tag "' + tag + '"'); | |
} | |
/* | |
Memorize the given language tag. | |
*/ | |
memorize('lang', tag); | |
/* | |
Reload the application to ensure that the proper | |
localizations are loaded. | |
*/ | |
window.location.reload(); | |
}, | |
/* | |
Utility methods. You probably do not need to worry | |
about any of these. | |
*/ | |
tags : function () { | |
return Object.keys(this.languages); | |
}, | |
labels : function () { | |
return Object.keys(this.languages).map(function (tag) { | |
return this.languages[tag]; | |
}, this); | |
} | |
}; | |
/*********************************************************** | |
Set up a `:passagerender` event listener that renders | |
the appropriate language tag suffixed passage into each | |
non-suffixed passage. | |
***********************************************************/ | |
$(document).on(':passagerender', function (ev) { | |
var passage = State.passage + '_' + setup.i18n.lang; | |
$(ev.content).empty().wiki(Story.get(passage).processText()); | |
}); | |
/*********************************************************** | |
Initialize the selected language. | |
***********************************************************/ | |
setup.i18n.initLang(); | |
})(); | |
:: Start | |
/* | |
The non-suffixed passages are here to prevent Twine from | |
complaining endlessly about missing passages, SugarCube from | |
showing broken links, and to keep the story history free of | |
suffixed passage names so that changing languages on the fly | |
will work. | |
The actual passages are the language tag suffixed versions. | |
For example, for this starting passage the German version | |
would be Start_de, the French Start_fr, and English Start_en. | |
When creating links between passages, you must always link to | |
the non-suffixed versions and never to the suffixed versions. | |
The `:passagerender` event will handle displaying the correct | |
version based on the currently selected language. | |
NOTE: While nothing within non-suffixed passages will be shown | |
to the player, they will be rendered. Meaning that side-effects | |
from code within said passages will occur—e.g. modifications to | |
story variables. Thus, you should either leave them empty or | |
place all contents within comment blocks like this one. | |
*/ | |
:: Start_de | |
Deutsche. | |
[[Nächster|Next]] | |
:: Start_en | |
English. | |
[[Next]] | |
:: Start_fr | |
Français. | |
[[Prochain|Next]] | |
:: Next | |
/* This should be empty. */ | |
:: Next_de | |
Nächster | |
:: Next_en | |
Next | |
:: Next_fr | |
Prochain | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That is useful.