i18next: fallback to [same language + different namespace] instead of [different language + same namespace] - node.js

This is about using i18next in a node.js backend.
This is the initialization:
i18next.init({
lng: 'de',
fallbackLng: ['de'],
ns: {
namespaces: ['formal', 'informal'],
defaultNs: 'formal'
},
fallbackToDefaultNS: true,
resStore: {
de: resourcesDE,
en: resourcesEN
}
});
where resourcesDE is an object with structure { formal: { }, informal: { }} and resourcesEN has the same structure but only 'formal', no 'informal' (but I have this problem even if there is 'informal' in resourcesEN).
Now, what I want to have is:
If I request the translation of 'informal:myKey' for English that the search route (== fallback) is:
(en)'informal:myKey' > (en)'myKey' > (de)'informal:myKey' > (de)'myKey'
or
(en)'informal:myKey' > (en)'myKey' > (de)'myKey'
but what actually happens is:
(en)'informal:myKey' > (de)'informal:myKey' > (de)'myKey'
meaning that the language changes before even trying to get a text of the same language from a different (the default) namespace.
How can I achieve this or something along those lines. I've also tried using a context instead of namespaces for these alternatives, but that seemed to behave the same. I'm glad to be proven wrong though.

The solution that worked out for me, in the end:
Instead of namespaces, I use special language flavors: 'de-INFORMAL' and 'en-INFORMAL'. If no label is found under 'en-INFORMAL', the lookup falls back to 'en', first and out of the box. If fallbackLng is set to 'de' it will fallback to that if the label in not found in 'en', either.

Related

Make mongo stop throwing errors related to unsupported text index language

I have a text index on a collection. I added a language field to my documents, and all of a sudden started receiving a bunch of "language override unsupported: <LANG>" errors. Apparently language is a magical field when you have a text index.
How do I make mongo not throw an error if the language is unsupported?
It doesn't matter to me if a language is unsupported. I want my insert operation to succeed, regardless if the language is supported or not.
The insert operation:
// This should succeed regardless if suggestion.language is an unsupported language
// I don't want to wrap this in a try/catch, and have to retry on error.
addSuggestion (suggestion) {
const suggCol = db.get().collection('suggestions')
return suggCol.insertOne(suggestion)
},
How I create my index
// Create a text index, on the "text" property.
// TODO: Mongo throws error if suggestion.language contains an
// unsupported language. Override the language for now.
db.collection('suggestions').createIndex({ text: 'text' }, { language_override: 'dummyVal' })
To avoid the error for now, I'm ignoring the text index by setting { language_override: 'dummyVal' }. In the future, I would like to use the language_override.
This is a feature and you seem to have already arrived at the correct solution - language_override.

ES6 Proxy wrapper

Modern ECMAScript-262 from 6 version supports Proxy object, which allows to intercept custom object invocations (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy )
By using Proxy-object, user can write something like obj.func1(123).func2('ABC').something, there nothing right to obj is not existing actually. Of course, by proper Proxy declaration, this chain can exist. The simplest way is return new Proxy on every property access and function invocation.
But is there way to automate this process, maybe some NPM library? The goal is transform custom free-form expression with Proxy to declarative string.
Upper example will transform to something like:
const result = obj.func1(123).func2('ABC').something;
result.__INVOCATION_VIEW__ === [
{ type: 'function', name: 'func1', args: [123] },
{ type: 'function', name: 'func2', args: ['ABC'] },
{ type: 'get', name: 'something' }
]
Pure theoretically, solution is possible anyway, because any entity in invocation chain is available as string in subsequent Proxy. But implementation is much complex. Maybe there is existing library for it?

Changing anyMatch default for Filter.JS in ExtJS for MultiSelect search

I have a multiselect bound to a store in which I implemented use of anyMatch: true to allow for True to allow any match - no regex start/end line anchors will be added (as per the comment in Filter.js). My problem is that I need to implement this as per the answer to multiselect-search-whole-string, in particular the solution provided in this fiddle https://fiddle.sencha.com/#fiddle/jf5
What I want to do is just set anyMatch: true, regardless, so I set it in Filter.js, but this has no effect on use of it. I searched the entire codebase for other instances of anyMatch: false and the only other one is in ext-all-debug.js. Why isn't setting these values having any effect? I don't see where else this default value could be set?
EDIT 1
I tried a different override, and while it is not exhibiting the right behavior, it is actually doing something this time. I figured that since the chunk of code that does work when embedded in the search attribute within the MultiSelector control was pretty much what was found in the MultiSelectorSearch's search method, that this was what I needed to focus on for the override. Any suggestions on tweaking this would be most welcome:
Ext.define('Ext.overrides.view.MultiSelectorSearch', {
override: 'Ext.view.MultiSelectorSearch',
search: function (text, me) {
var filter = me.searchFilter,
filters = me.getSearchStore().getFilters();
if (text) {
filters.beginUpdate();
if (filter) {
filter.setValue(text);
} else {
me.searchFilter = filter = new Ext.util.Filter({
id: 'search',
property: me.field,
value: text,
anyMatch: true
});
}
filters.add(filter);
filters.endUpdate();
} else if (filter) {
filters.remove(filter);
}
}
});
EDIT 2
Got it! The key was that originally, since this code was embedded in a singleton, I could reference the method by passing me from the calling form.panel. This did not work globally as an override, and required me to define the method as
search: function (text) {
var me = this,
I hope this helps someone out there!
Changing in ext-all-debug.js is not safe, when you do a production build this file will not get included.
Best way is to override the Filter class, here is how you can do it.
Ext.define('Ext.overrides.util.Filter', {
override: 'Ext.util.Filter',
anyMatch: true
});
And import this class in Application.js
Ext.require([
'Ext.overrides.util.Filter'
]);

i18next init on specific language

I'm using i18next-node for localization of my app.
I have two languages: en-CA and fr-CA
I'm using this to init the app:
i18next.init({
saveMissing: true,
sendMissingTo : 'all',
ignoreRoutes: ['img/','images/', 'public/', 'css/', 'js/'],
debug: true,
lng: 'en-CA'
});
The problem is, when I start the app, it gives me this error:
currentLng set to: en-US
[ { [Error: ENOENT, open 'locales/en-US/translation.json']
errno: 34,
code: 'ENOENT',
path: 'locales/en-US/translation.json' } ]
I don't want en-US, I want en-CA. Now, my app isn't showing either language. How do I set en-CA to be the default?
Turns out you can set fallbackLng : 'en-CA' and that will work. Kind of a hack though.
Try to read the detect language section under http://i18next.com/node/pages/doc_init.html
i18next detects during the request the language from your browser-settings (if not set by any other methode - cookie, querystring). That's why language is set to 'en-US'.
You can set the supported languages on init:
i18n.init({supportedLngs: ['en-CA', 'fr-CA']})
But you still need to set a fallbackLng -> eg. if someone requests your page with language set 'de' some fallback language should be displayed.

CouchApp design document and shared libraries

var ddoc = {
_id: '_design/app',
language: 'javascript',
views: {},
lists: {},
shows: {},
lib: {/* see below */}
};
I can't find good documentation about what to put into ddoc.lib, eg:
Can I put functions: ddoc.lib.myHelper = function () {}; ?
Can I reference JavaScript files (CommonJS module?): ddoc.lib.math = 'math.js';
In case of 2. where to store math.js?
As far as I know the best solution for today is to use couchapp. It can create a sceleton that could be edited easily.
The best couchapp manager I have seen is http://kan.so/ I would just use this, but ...
To roughly answer your questions.
yes you can put functions in lib, but they must be turned into escaped strings. You want to just put them in like you would a file though not an anonymous function.
yes you can require just structure as
"lib": {
"math.js":"escaped source"
}

Resources