Skip to content

Instantly share code, notes, and snippets.

@tmedwards
Last active March 13, 2024 06:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tmedwards/33f3b4b7ada317fc9cc70aa8580c03f0 to your computer and use it in GitHub Desktop.
Save tmedwards/33f3b4b7ada317fc9cc70aa8580c03f0 to your computer and use it in GitHub Desktop.
SugarCube v2 basic internationalization (i18n) example using the Settings menu (in Twee notation)
:: StoryTitle
SugarCube i18n example
:: Language Switching [script]
;(function () {
/***********************************************************
Set up a `i18n` object on SugarCube's `setup` object.
***********************************************************/
setup.i18n = {
/*
Map of language labels to tags 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
*/
langs : {
// NOTE: User customization required here.
'Deutsche' : 'de',
'English' : 'en',
'Français' : 'fr',
},
/*
Utility methods. You probably do not need to worry
about any of these.
*/
tags : function () {
return Object.keys(this.langs).map(function (label) {
return this.langs[label];
}, this);
},
labels : function () {
return Object.keys(this.langs);
},
labelFromTag : function (tag) {
var label = Object.keys(this.langs).find(function (label) {
return this.langs[label] === tag;
}, this);
if (!label) {
throw new Error('unknown language tag "' + tag + '"');
}
return label;
}
};
/***********************************************************
Language switching setting.
***********************************************************/
function initLanguage() {
/*
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 (setup.i18n.langs[settings.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', setup.i18n.langs[settings.lang]);
}
function changeLanguage() {
/*
Reload the application to ensure that the proper
localizations are loaded.
*/
window.location.reload();
}
Setting.addList('lang', {
label : 'Language.',
list : setup.i18n.labels(),
default : setup.i18n.labelFromTag('en'),
onInit : initLanguage,
onChange : changeLanguage
});
/***********************************************************
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.langs[settings.lang];
$(ev.content).empty().wiki(Story.get(passage).processText());
});
})();
:: 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 postrender task 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
@Okamich
Copy link

Okamich commented Jul 2, 2019

Hi, how can i change lable "Language" in settings?

@tmedwards
Copy link
Author

Assuming you mean that you want it to change based on the currently selected language, then you do not without dipping into undocumented internals. The Setting API in SugarCube v2 was never designed with language switching in mind, so the order that various operations happen in is not conducive to what you'd like to accomplish.

If something which does not integrate into the Setting dialog would be acceptable, then there's the alternative example sc-i18n-example-2.twee.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment