Using the lingo macro for my own plugin translations

I’m wondering if there are established best practices around using the lingo macro and the $:/language/* internationalization technique for user wikis, in my case for a plugin/extension mechanism.

I have an external way to internationalize the main content, but I’m not happy with my current approach for internationalizing templates, procedures, functions, and the like. I was thinking of adopting something similar to how the core is internationalized, adding tiddlers like

title: $:/language/plugins/MyName/MyPlugin/Chapter

Chapter

for English

and

title: $:/language/plugins/MyName/MyPlugin/Chapter

Capítulo

for Spanish

I don’t have to worry about the language loading mechanism that the core uses. My version would simply have the language tiddlers overlay the default ones.

But I am worried about name-spacing. I haven’t seen any description of conventions here. The core uses 16 basic tiddlers, plus 39 namespaces, to hold slightly over 1000 language tiddlers.1 Would it make sense that I simply claim the $:/language/plugins namespace for this? That would mean it’s not available for the core. I think the core would likely use $:/language/Plugin if it ever needed something like this. But I don’t want to step on toes.

Would that be reasonable? Is there any objection to my starting a convention that $:/language/plugin/MyName/MyPlugin/* is to be used for plugin-specific language translation tiddlers?

Pinging @jeremyruston, @pmario, @saqimtiaz, @EricShulman




1 These:

Language Tiddlers

$:/language/ConfirmAction $:/language/DropMessage
$:/language/ConfirmCancelTiddler $:/language/LazyLoadingWarning
$:/language/ConfirmDeleteTiddler $:/language/LoginToTiddlySpace
$:/language/ConfirmDeleteTiddlers $:/language/No
$:/language/ConfirmEditShadowTiddler $:/language/OfficialPluginLibrary
$:/language/ConfirmOverwriteTiddler $:/language/PluginReloadWarning
$:/language/Count $:/language/UnsavedChangesWarning
$:/language/DefaultNewTiddlerTitle $:/language/Yes

Language Tiddler Namespaces

$:/language//* $:/language/Error/* $:/language/RecentChanges/*
$:/language/AboveStory/* $:/language/Exporters/* $:/language/RelativeDate/*
$:/language/BinaryWarning/* $:/language/Filters/* $:/language/Search/*
$:/language/Buttons/* $:/language/Help/* $:/language/Shortcuts/*
$:/language/ClassicWarning/* $:/language/Import/* $:/language/SideBar/*
$:/language/CloseAll/* $:/language/InternalJavaScriptError/* $:/language/Snippets/*
$:/language/ColourPicker/* $:/language/LayoutSwitcher/* $:/language/Switcher/*
$:/language/ControlPanel/* $:/language/Manager/* $:/language/SystemTiddler/*
$:/language/Date/* $:/language/MissingTiddler/* $:/language/SystemTiddlers/*
$:/language/Diffs/* $:/language/Modals/* $:/language/TagManager/*
$:/language/Docs/* $:/language/Notifications/* $:/language/ThemeTweaks/*
$:/language/EditTemplate/* $:/language/OfficialPluginLibrary/* $:/language/Tiddler/*
$:/language/Encryption/* $:/language/PageTemplate/* $:/language/TiddlerInfo/*

The main problem here is, that the core does not have any functionality to switch / extract your texts.

There has been a PR, which is now closed because @jeremyruston is developing an alternative approach: Introducing bundled sub plugins #8957 at the moment.

The structure in the “now closed” PR was as shown in the screenshot from OP

As you can see, the

  • active texts follow $:/plugins/<author>/<plugin-name>/language/...
  • available texts follow $:/plugins/<author>/<plugin-name>/languages/<language-code>/...

I do not know, how @jeremyruston’s approach is with the new plugin, but I think it needs to be similar, to avoid naming problems.

In my case, I don’t think that will be a problem. This is designed to allow the same codebase to be used across a number of wikis, with just a few language-specific tweaks. All the important content will be in just one language. There is no dynamic switching of language.

This is related to things I’ve discussed in three previous posts regarding Bible wikis.

Currently I handle the small bit of internationalization needed with lines like this:

  {
    "title": "${title}",
    "tags": "${TableOfContents}",
    "text": "<div class=\"tc-table-of-contents\" style=\"column-width:12em;\">\n\n<<toc-selective-expandable \"${Book}\" \"nsort[seq]\" >>\n\n</div>\n",
  },

(note the use of ${title}, ${TableOfContents}, and ${Book})

which uses lines like these from a translation file:

  "Chapter": "Capítulo",
  "Book": "Libro",
  "Books": "Libros",
  "Verse": "Versículo",
  "Contents": "Contenido",
  "TableOfContents": "Contenido",

and this bit of code:

const update = ({title, language: {Book, Books, Chapter, Verse, Contents, TableOfContents, books: {Psalms}}}) => (tiddler) => 
  Object.fromEntries(Object.entries(tiddler).map(([k, v]) => [
    k, 
    v.replaceAll('${title}', title)
      .replaceAll('${Book}', Book)
      .replaceAll('${Books}', Books)
      .replaceAll('${Chapter}', Chapter)
   // ...

to create a tiddler like

title: "La Biblia Reina Valera Gómez"
tags:"Contenido"

<div class="tc-table-of-contents" style="column-width:12em;">

  <<toc-selective-expandable "Libro" "nsort[seq]" >>

</div>

That works fine for creating the various Bible versions. But the idea of extensions for these wikis, created not just by me but by others means that I have to revisit this to handle that. Here’s where I thought of using <<lingo>>. I can add language tiddlers for each of those terms above, and the extension can use them with <<lingo>>. If the extension has other internationalization needs, it can define its own language file that extension translations can also implement.

Of course I can define my own macro in place of <<lingo>>, but using the $:/language namespace seems to make sense. I’m just hoping that it’s reasonable to use the namespace the way I suggested.

I think even if Jeremy will change something, we still need to have the possibilities to switch between languages. So IMO the linked namespaces still stand. So for active texts I would use: $:/plugins/<author>/<plugin-name>/language/... which should be compatible, if you set the lingo-base variable right.

Well, if I’m not going to use the $:/language namespace, there’s little reason to use the <<lingo>> macro. I can write my own more specific to the problem. But I thought it would be a good idea to keep all internationalization text in one place. Clearly you disagree, but I’m afraid I don’t quite understand your reason.

While one could certainly change the interface language in one of the wikis, it would seem an odd experience, with the content still all in the initial language:

My language tiddlers, under the $:/language/plugins/<author>/<plugin>/ namespace would not currently be replaced when the language changes; the core includes no tiddlers there. I was hoping that we might agree to keep it this way.