Can I make VueI18n fallback on a key path if not found the complete key path? - vue.js

Is it possible for VueI18n to fall back to shorter key if it didn't found it.
A example for this could be, I have following messages:
{
en: {
"hello": "This is the fallback message!",
"admin.hello": "This is some other message for another context"
}
}
The below code is a illustration of what the results should be:
{{ $t("does.not.exists.hello") }} // should fallback on hello, so the result will be "This is the fallback message!"
{{ $t("admin.hello") }} // Message exists so the result should be "This is some other message for another context"
{{ $t("hello") }} // Message exists so the result should be "This is the fallback message!"

Okay I was to fast, with this question. MissingHandler is useful for this.
and the code example became like this:
Vue.use(VueI18n)
// Create VueI18n instance with options
export default new VueI18n({
locale: 'en', // set locale
silentTranslationWarn: true,
missing: (locale: Locale, key: Path, vm?: Vue) => {
if(key.includes(".")) {
let newKey = /\.(.+)/.exec(key)[1];
console.log(newKey)
return vm.$t(newKey) as string
}
return key
},
//formatter: new CustomFormatter(),
fallbackLocale: 'en',
messages // set locale messages
})

Related

Did not attempt to load JSON data because the request Content-Type was not 'application/json'. Axios

I'm doing a get method, when i run the code i'm getting this Did not attempt to load JSON data because the request Content-Type was not 'application/json'.. I have tried to set headers. Here is my code.
<template>
<div class="container">
<button #click="SearchTown"> Search Town </button>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'SearchTown',
props: {
messege: String
},
data(){
return{
search: [],
}
},
methods :{
SearchTown() {
axios
.get('https://david.darwinist.io/proxy/5000/town/',{headers:{'content-type':'application/json'}})
.then((response) => {// checking response in the console
console.log(response.data)})
.catch((error)=>{
console.log(error)
})
}
}
}
</script>
I'm having 400 error code. I need help.
This is my backend code
def getTown(session, town_dict):
try:
town = (
session.query(Town)
.join(Town.county)
.join(County.nation)
.where(County.name == town_dict["county"])
.where(Town.name == town_dict["name"])
).one()
town_county = copy.copy(town).__dict__
del town_county["_sa_instance_state"]
town_county["county"] = town.county.name
town_county["nation"] = town.county.nation.name
return town_county
except MultipleResultsFound:
return "bad Gateway!", 502
except NoResultFound:
return "Results not found!", 404
I'm not really sure if i have to change my query. Kindly advice.
As commented in this GitHub issue:
https://github.com/axios/axios/issues/86#issuecomment-136505548
https://github.com/axios/axios/issues/86#issuecomment-139638284
Your GET request must have some data passed along it. data: {} should do the trick.
Some people find it kind of misleading. The explanation for this behaviour is here:
Content-Type describes what format the request data is in. If there is no request data, there is no need to specify the Content-Type.

How to Load Custom Language in Monaco using VueJS/Webpack

I've created a custom language using this tool here. I don't know what to do to load it to my VueJS app. I tried the following and get no errors, but it also doesn't show seem to work, because in the Monarch tool thing I get blue text on known functions etc, but in my editor I don't. Other languages work as expected.
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const path = require('path');
const main = path.resolve(__dirname, './src/test/test.ts');
module.exports = {
configureWebpack: {
plugins: [
new MonacoWebpackPlugin({
languages: ['javascript', 'typescript', 'python', 'java', 'python', 'json', 'vb'],
customLanguages: [
{
label: 'test',
entry: main
}
]
})
]
}
...
I made my .ts file essentially export a conf property with all the variables or whatever that are used in the tokenizer. I also exported a language property. I'm not totally sure that is the right format.
My .ts file essentially looks like:
export const conf = {...}
export const language = {...}
I'm not totally sure what to do here. Docs are sparse for custom languages and nothing seems to be working other than I think I at least have the first part of defining the language working.
That Webpack plugin isn't actually needed.
Based on the custom language example, you can register the language at runtime via monaco.languages.setMonarchTokensProvider(). The second function argument is an instance of IMonarchLanguage, which matches the language spec in the example you linked.
<script setup lang="ts">
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import { ref, onMounted } from 'vue'
/**
* `customLangMonarch` contains the language spec example from
* https://microsoft.github.io/monaco-editor/monarch.html
*/
// #ts-ignore
import customLangMonarch from '#/custom-lang-monarch'
monaco.languages.register({ id: 'custom' })
monaco.languages.setMonarchTokensProvider('custom', customLangMonarch)
const editor = ref()
onMounted(() => {
monaco.editor.create(editor.value, {
language: 'custom',
})
})
</script>
demo w/Vue CLI
demo w/Vite

How can i customize form error message from Yup/Vee-validate using Vue-i18n in Ionic VueJS

I would like to use vue-i18n to translate my form error messages.
I've code a "lang.ts" file which builds my i18n instance like this :
import { createI18n } from 'vue-i18n';
import french from './i18n/fr-FR.json';
import english from './i18n/en-US.json';
// push translations to list
const messages = {
'en-US': french,
'fr-FR': english
}
// Create VueI18n instance with options
export const i18n = createI18n({
locale:"en-US",
messages
});
and I initialize all of this in my "main.ts"
...
const app = createApp(App).use(router);
router.isReady().then(() => {
Device.getLanguageCode().then(function (lang) {
i18n.global.locale = lang.value; // changing locale using Capacitor locale getter
app.use(i18n)
.use(IonicVue)
app.mount('#app');
});
});
I'm using a yup custom schema to validate my form, and that's where i mention my custom error message, the problem is that my "global" locale value isn't being used in my schema and it always translates to default language (en-US here...)
here's my schema
export const LoginFormContentSchema = yup
.object({
login: yup.object({
email: yup.string().email(i18n.global.t('wrongMail')).required(i18n.global.t('emptyMail')), // translating my error messages to current global locale
password: yup.string().required(i18n.global.t('emptyPassword')),
url: yup
.string()
.required(i18n.global.t("urlEmpty")).lowercase()
.matches(/^(https:\/\/)?[a-z0-9._-]+(\.fr)/),
}),
})
.required();
Since i've changed my locale before mounting the app, i should have fr-FR as locale everywhere, but i'm getting "en-US" outputs when the error message pops out even thought my device is in French and my global.locale is fr-FR.

Use same resource for languages with different IETF language tag in i18next

I have the following code:
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import locales from 'locales'
const resources = {
en: locales.en,
no: locales.no,
de: locales.de,
se: locales.se
}
function getDefaultLocale() {
const preferredLanguage = localStorage.getItem('preferredLanguage')
const lng = locales.languages
.map(({ code }) => code)
.find(code =>
code === preferredLanguage || // The user has set a preferred language
code === '__DEFAULT_LOCALE__' || // Default locale set at build time.
code === navigator.language
)
return lng
}
i18n
.use(initReactI18next)
.init({
resources,
lng: getDefaultLocale(),
appendNamespaceToCIMode: true
})
export default i18n
My problem is, that let's say when the English language is detected with navigator.language, it may be en, en-US, en-GB, or for Norwegian, it may be nb, nb-NO, ny-NO etc.
We would like to serve the same translations for all English language codes, and the same for all the Norwegian language codes.
My current solution is to defined resources like so:
const resources = {
en: locales.en,
'en-US': locales.en,
'en-GB': locales.en,
no: locales.no,
'nb-NO': locales.no,
'ny-NO': locales.no,
de: locales.de,
se: locales.se
}
But there must be a better solution to this! Could someone help?
Default behaviour for locales containing region is to fallback to the primary language code.
For instance, we have detected en-GB, but there is not translation file assigned to this locale. Assuming that en translations are in place, expected behaviour would be to proceed with them, not causing any trouble.
This practically means you can remove duplicate declaration from your initialization code:
const resources = {
en: locales.en,
no: locales.no,
de: locales.de,
se: locales.se
}
If you prefer, it could be done in a more concise manner:
const resources = { ...locales }

Handle Vue render errors locally

I am using Vue (server side rendered) with mjml to generate emails.
So I have something (overly simplified) like:
<mjml><mj-body>Hello {{ User.Name }}</mj-body></mjml>
If the model doesn't define User then Vue throws an error and the whole output is lost.
What I want to the output to be along the lines:
<mjml><mj-body>Hello <error>'User' is undefined</error></mj-body></mjml>
I have implemented Vue.config.errorHandler but that just tells me about the error -- there is no rendered output.
Anyway to implement the equivalent of an error handler around each variable substitution?
If you are using Vue version >= 2.5, you can use errorCaptured to create an ErrorBoundary
const ErrorBoundary = {
name: 'ErrorBoundary',
data: () => ({
error: false,
msg: ''
}),
errorCaptured (err, vm, info) {
this.error = true
this.msg = `${err.stack}\n\nfound in ${info} of component`
},
render (h) {
return this.error
? h('pre', this.msg)
: this.$slots.default[0]
}
}
and use this in your component
<error-boundary>
<mjml><mj-body>Hello {{ User.Name }}</mj-body></mjml>
</error-boundary>
If the application has any javascript error, it will be displayed on UI
Example on codepen
If you want to have more user-friendly error, you can customize ErrorBoundary to have fallback to another component. You can find out in this tutorial
Another good example of using errorHandler