How to implement localization with dialogs exported as libraries - node.js

I have packaged some of my dialogs as libraries by following the instructions from the basics-libraries example. Before, I had all dialogs in app.js and I used localization following the instructions from the documentation. For example, I used
var chatBot = new builder.UniversalBot(chatConnector, {
localizerSettings: {
botLocalePath: "./locale",
defaultLocale: "de"
}
});
and
session.preferredLocale("de");
to use German for all the prompt labels, and stored all the German translations in ./locale/de/index.json and ./locale/de/BotBuilder.json.
However, the localization doesn't work with the dialogs I have packaged into libraries. Instead of the localized strings only the message IDs are displayed.
It works if I use session.localizer.gettext(session.preferredLocale(), "message ID") on each string. However, that is very tedious, and I am wondering if there is a way to localize all strings inside a library at once.

In order to this to work, your locale file should have the same name as your library.
./my_bot_library.js
./locale/en/my_bot_library.json
Then, to get your localized text you can either use:
session.localizer.gettext(session.preferredLocale(), 'message ID', 'my_bot_library')
Please note that the the third parameter is the namespace that
represents the library name
or just the following which internally resolves the preferred Locale and current namespace/library name
session.gettext('message_id') or session.send('message_id')

Related

How do I use SharePlusLinuxPlugin?

I'm trying to open an image from memory with the default image viewer on Linux.
The class is part of the share_plus package. I can't figure out how to define the required UrlLauncherPlatform property.
I want to use it like this:
SharePlusLinuxPlugin(urlLauncher).shareXFiles([XFile.fromData(img)]);
I have googled this class, didn't find any usage examples.
From the source code on Github, it looks like shareXFiles() has not been implemented on Linux. To quote:
Future<ShareResult> shareXFiles(
List<XFile> files, {
String? subject,
String? text,
Rect? sharePositionOrigin,
}) {
throw UnimplementedError(
'shareXFiles() has not been implemented on Linux.',
);
}
The same is true for the shareFiles() method.
Aside from that, there is usually no need to call SharePlusLinuxPlugin directly. The Share class is configured in such a way that it automatically detects the platform that it is running on

How to set a List value with JScript

In FileNet, using FEM or ACCE, it is possible to use JScript in order to set attributes' values to an object. The official IBM guide provides this example (for Strings):
importClass(Packages.com.filenet.api.property.Properties);
importClass(Packages.com.filenet.api.constants.RefreshMode);
function OnCustomProcess (CEObject)
{
CEObject.refresh();
CEObject.getProperties().putValue("DocumentTitle", "Test1");
CEObject.save(RefreshMode.REFRESH);
}
But is it possible to do the same thing for more complex objects? I'm referring, in particular, to StringList type. There are no examples on the web, and defining a JS-like array doesn't work.
It is definitely possible to do this for more complex objects. Most of it is just following the path you would follow using Java, but changing the name of the variable types to var. Therefore the code for setting the value of a multivalue string property is as follows:
importClass(Packages.com.filenet.api.constants.RefreshMode);
importClass(Packages.com.filenet.api.core.Factory);
function OnCustomProcess (CEObject)
{
CEObject.refresh();
var list = Factory.StringList.createList();
list.add("Value 1");
list.add("Value 2");
CEObject.getProperties().putObjectValue("TestMultiValueProperty1", list);
CEObject.save(RefreshMode.REFRESH);
}
I often use the putObjectValue() method instead of the putValue() method because JavaScript sometimes has problems determining which type safe version of the putValue() it should use.
For a lot of examples you could go to the Global Configuration > Data Design > Add-ons section in the domain tab of the ACCE. The pre- and post-import scripts of the different Add-ons contain a lot of relevant JavaScript code.

Botbuilder how to use default locale strings in case namespace hasn't defined it

I am using the botbuilder framework. I have defined several namespaces for the dialogs I have created, such as help or default. For all of these I have also created json files in my locale/en/ directory, and all is well.
However, I have a few sentences that are very common, and I don't feel like copying those over to each of the individual namespaces. I have tried using index.json as a 'fallback' in case the namespace file doesn't define the string. But it doesn't work for me. Contrary to what the documentation seems to suggest.
/locale
/en
/help.json
/default.json
/index.json <-- Doesn't work
/dialogs
/help.js
/default.js
bot.js
Say I have the following library in help.js, that :
lib = new builder.Library('help')
lib.dialog('/', (session) => {
session.send('custom_cancel')
}
module.exports = lib
The library is used in bot.js:
bot.library(require('./dialogs/help'))
And index.json has this content:
{
"custom_cancel": "My custom cancel"
}
Whereas help.json is empty:
{}
Because help.json does not have custom_cancel, the bot will actually send custom_cancel as the string.
Again. I can copy paste the strings to both locations and there is no more problem. But that seems like an ugly solution to me.
I have tried the more explicit version, which seems to help in more cases, but I am not fully convinced yet.
session.localizer.gettext(session.preferredLocale(), 'custom_cancel')
You can use the third argument for the namespace. It seems that '' will point to the index.json file.

Getting Message from all resource files in different locale from a key

I have different locale file for messages to user in JSF based Project.
i want to retrieve messages from all locale available in my project using Key
I am using in managed bean
String message=ResourceBundle.getBundle("com.tech.resources.messages",
new Locale(loggedInUser.getLanguage())).getString("label.hostel.room.allocated");
Instead of one String i want all messages as a array or list assosiated with this key in all resource bundles like messages.properties, messages_hin.properties etc.
As you've already figured how to get a locale-specific bundle and then get its message by key and that part thus doesn't need to be answered, your sole question basically boils down to:
How can I get all supported locales of my JSF application?
You can get all supported locales by Application#getSupportedLocales().
Application application = FacesContext.getCurrentInstance().getApplication();
Iterator<Locale> supportedLocales = application.getSupportedLocales();
while (supportedLocales.hasNext()) {
Locale supportedLocale = supportedLocales.next();
// ...
}

Why in Mojito, renaming controller.server.js to controller.server-foo.js will have no effect?

In Mojito on top of Node.js, I followed the example on http://developer.yahoo.com/cocktails/mojito/docs/quickstart/
What I did was renaming controller.server.js to controller.server-foo.js, and created a new file controller.server.js to show "Hello World".
But when mojito is started, the old file controller.server-foo.js is being used and so the "Hello World" is not printed. How come Mojito will use the old file?
(I also tried renaming controller.server-foo.js to foo-controller.server.js and now the "Hello World" is printed, but why is controller.server-foo.js used?)
I found out that historically, the "affinity" of the controller can be two parts. The first part is common, server, or client, and the second part is optional, and it might be tests, or other words, so use other names such as controller-not-used-server.js to disable it.
#Charles, there are 3 registration processes in mojito (yes, it is confusing at first):
Affinity (server, client or common).
YUI.add when creating yui modules (controllers, models, binders, etc)
and the less common which is the registration by name (which includes soemthing that we call selectors)
In your case, by having two controllers, one of them with a custom selector named "foo", you are effectible putting in use the 3 registration at once. Here is what happen internally:
A controller is always detonated as "controller" filename from the mojit folder, which is part of the registration by name, and since you have "foo" selector for one of the controller, your mojit will have to modes, "default" and "foo". Which one of them will be use? depends on the application.json, where you can have some conditions to set the value of "selector", which by default is empty. If you set the value of selector to "foo" when, for example, device is an iphone, then that controller will be used when that condition matches.
Then the YUI.add plays an important role, it is the way we can identify which controller should be used, and its only requirement is that NO OTHER MODULE in the app can have the same YUI Module name, which means that your controllers can't be named the same when registering them thru YUI.add. And I'm sure this is what is happening in your case. If they both have the same name under YUI.add() one will always override the other, and you should probably see that in the logs as a warning, if not, feel free to open an issue thru github.
To summarize:
The names used when registering YUI modules have to be unique, in your case, you can use: YUI.add('MyMojit', function(){}) and YUI.add('MyMojitFoo', function(){}), for each controller.
Use the selector (e.g.: controller.server-mobile.js) to select which YUI module should be used for a particular request by setting selector to the proper value in application.json.

Resources