Am using #ngx translator but I'm getting error. I need to use translator dropdown at footer and the translator should reflect in all pages
like this the services .. it works
loadTranslations(...args: Locale[]): void {
const locales = [...args];
locales.forEach(locale => {
this.translate.setTranslation(locale.lang, locale.data, true);
this.langIds.push(locale.lang);
});
// add new languages to the list
this.translate.addLangs(this.langIds);
}
setLanguage(lang) {
if (lang) {
this.translate.use(this.translate.getDefaultLang());
this.translate.use(lang);
localStorage.setItem('language', lang);
}
}
getSelectedLanguage(): any {
return localStorage.getItem('language') || this.translate.getDefaultLang();
}
and the constructor
import { locale as arLang } from './i18n/ar';
import { locale as frLang } from './i18n/fr';
constructor(private translationService: TranslationService,
) {
// register translations
this.translationService.loadTranslations(arLang, frLang);
}
For localization/internationalization of your app, angular has i18n. It handles all static text of your app and translates with any of your locale. For that you need to include equavalent translated text in $Yourlocale.xlf file.
For some reference:
Translate addition i18n
Addition in template
Add i18n tag :<div i18n>Some text</div>
Add i18n-x tag to component attribute :
<some-component i18n-titleProp="title" titleProp="some text""></some-component>
<input i18n-placeholder="placeholder"" placeholder="some text""></input>
Addition in ts file i18n-polyfill
Add i18n to class constructor :constructor(private i18n: I18n) {}
Add i18n tag to variable value :
any = [this.i18n('first value'), this.i18n('second value')]
some = this.i18n('some value')
Creation XLIFF translations files
run npm run i18n
See translation file /locales/messages.xlf
here you need to manually enter the equivalent translated text for transaltion.
Related
my name is DP, I have 2 years Vue2 experience, but I am new to Vue3. I am learning Vue3 recently, as I found the "setup(Composition API)" just like the "Controller(in MVC)" that I did in other language, so I am trying to build my test Vue3 project in MVC way, but I go some problem can anyone help? thx!
MVC Plan
M - use class
V - use <template> ... </template>
C - use setup
My Problem
working: using loadTopic_inSetup().then() in setup is working, because topicList_inSetup is defined in setup() too.
not working: using loadTopic_inModel() in setup is not working, I guess some kind data keep problem, because in console I can see the data already got from API
as u can see, I am not expert for js/ts, I am a backend developer, so if you know how to do it, plz help thx very much.
BTW, VUE is greet, I love it.
My Code
//APIBased.ts
import { ajax } from "#/lib/eeAxios"
export class APIBased {
//load data with given url and params
loadData(apiPath: string, params?: object): Promise<any> {
apiPath = '/v1/'+apiPath
return ajax.get(apiPath, params)
}
}
//Topic.ts
import { APIBased } from "./APIBased";
import { ref } from 'vue'
export class Topic extends APIBased {
//try keep data in model
topicList: any = ref([]);
constructor() {
super()
}
//direct return ajax.get, let setup do the then+catch
loadTopic_inSetup() {
return super.loadData('topics', { t_type_id: 1 })
}
//run ajax get set return data to this.topicList, keep data in model
loadTopic_inModel() {
super.loadData('topics', { t_type_id: 1 }).then((re) => {
console.log(re.data)
this.topicList = re.data
})
}
}
//EETest.vue
<template>
<EELayoutMainLayout>
<template v-slot:mainContent>
<h1>{{ "Hello Vue3 !!" }}</h1>
<hr/>
{{to.topicList}} //not working... just empty array
<hr/>
{{topicList_inSetup}} //working... topic list return from API show here.
</template>
</EELayoutMainLayout>
</template>
<script lang="ts">
import { defineComponent, getCurrentInstance, ref } from 'vue'
import EELayoutMainLayout from '#/components/eeLayout/EELayoutMainLayout.vue'
import { Topic } from "#/models/Topic";
export default defineComponent({
name: 'EETest',
props: {
},
setup() {
let topicList_inSetup = ref([])
const to = new Topic()
//try keep data in setup, it's working
to.loadTopic_inSetup().then((re) => {
topicList_inSetup.value = re.data
console.log(re.data)
})
//try keep data in model, the function is run, api return get, but data not show, even add ref in model
to.loadTopic_inModel()
return {
topicList,
to,
}
},
components: {
EELayoutMainLayout,
},
})
</script>
A few digressions before solving the problem. Maybe you are a java developer. I personally think it is inappropriate to write the front end with Java ideas. The design of vue3's setup is more inclined to combined functional programming
To fully understand why you need some pre knowledge, Proxy and the get and set method of Object
They correspond to the two core apis in vue, reactive and ref,
The former can only be applied to objects( because proxy can only proxy objects),The latter can be applied to any type(primary for basic javascript types, get and set can apply for any type)
You can modify the code to meet your expectations
loadTopic_inModel() {
super.loadData('topics', { t_type_id: 1 }).then((re) => {
console.log(re.data)
this.topicList.value = re.data
})
}
You cannot modify a ref object directly, a test case to explain what is reactive
when ref function is called, a will be like be wrapped in a class has value properties, and has get and set method
the effect function will call the arrow function, and in this time, the get method of a will be called and it will track as a dependence of the effect function, when a changed, the set method of a will be called, and it will trigger the arrow function,
so when you direct modify the a, the setter method will never trigger, the view will not update
const a = ref(1)
let dummy
let calls = 0
effect(() => {
calls++
dummy = a.value
})
expect(calls).toBe(1)
expect(dummy).toBe(1)
a.value = 2
expect(calls).toBe(2)
expect(dummy).toBe(2)
// same value should not trigger
a.value = 2
expect(calls).toBe(2)
We have a static site using Gatsby and contentful. Now we want to support multi-languages, with localized content from contentful. I am able to populate a graghql query:
query frontpageTeaser($lang: String) {
contentfulFrontpage(node_locale: { eq: "zh-CN" }) {
myArticalContent
...
}
}
This query is able to load the Chinese content from contentful, and English if changed to node_locale: { eq: "en-US" }.
Now the issue is: we want to support a language switch, so that when switching language, the graphql loads corresponding localized content.
We are using gatsby-plugin-react-i18next, which has this great feature:
Support multi-language url routes in a single page component. You don’t have to create separate pages such as pages/en/index.js or pages/es/index.js.
Pages like http://localhost:8000/zh-CN/ does load Chinese from local /locales/zh-CN/translation.json, but how to load localized content when switching language?
Graphql seems providing page query, so i added gatsby-node.js:
exports.createPages = async function ({ actions, graphql }) {
actions.createPage({
path: '/zh-CN/',
component: require.resolve(`./src/pages/index.js`),
context: { lang: 'zh-CN' },
})
}
And use this on page:
export const query = graphql`
query frontpageTeaser($lang: String) {
contentfulFrontpage(node_locale: { eq: $lang }) {
myArticalContent
}
}
`
But it always returns en. Please kindly help :). Thanks.
This can be a complex switch. There is an example project that has smoothly done it with another CMS + Gatsby, here.
Specific places to point out in the codebase:
Configuration of which locales you use, here
A dynamic link depending on the active locale, here
The context for your whole app to know what the active locale is, here
Actually implementing the locale context provider in the higher order component Layout, here
There is also some magic inside of the gatsby-node.js which updates what you've already been working on! You can find that, here.
Hope that helps :)
Before getting a better solution, this one works:
// #todo gatsby plugin https://www.gatsbyjs.org/packages/gatsby-plugin-react-i18next/
// this plugin provides current language `context.i18n.language`, which not know how to pass it to graphql page query.
// This snippet moves it one-level up to `context.locale`.
// #todo need to explore a better solution.
exports.onCreatePage = ({ page, actions }) => {
const { createPage, deletePage } = actions
if (!page.context.locale) {
const language = page.context.i18n.language
const locale = language === 'en' ? 'en-US' : language
deletePage(page)
createPage({
...page,
context: {
...page.context,
locale,
}
})
}
}
I am building a localized static website using Gatsby, with the help of gatsby-plugin-intl. This plugin adds a context variable named intl to pages (including template-based pages), which is an object: https://github.com/wiziple/gatsby-plugin-intl/blob/master/src/gatsby-node.js#L27-L34
I would like to access the intl.language variable from the context within a page query. This is my (failing) code at this stage:
query($slug: String!, $intl: String) {
contentfulPerson(slug: {eq: $slug}, node_locale: {eq: $intl.language}) {
name
}
}
Contentful is the headless CMS I use and from which I would like to fetch data in the correct locale.
Obviously this code has two problems: $intl is not a string, and $intl.language is not syntactically correct. But I don't know how to fix either problem.
I guess I could either fork the plugin or do something in my own gatsby-node.js to make the language available as a top-level variable in the context, but I'm interested to know if there is a way to do it directly.
The Gatsby docs say that query variables can be complex (https://www.gatsbyjs.org/docs/graphql-reference/#query-variables) but in the example they provide, they don't show how the types are defined or how to access a property within these variables.
EDIT : I tried moving the language to a top-level context variable in my gatsby-node.js using this code:
exports.onCreatePage = ({page, actions}) => {
const { createPage, deletePage } = actions
deletePage(page)
createPage({
...page,
context: {
...page.context,
language: page.context.intl.language
}
})
}
but the program runs out of memory (even when increasing max_old_space_size)
You can move the language field to a top-level context by doing this:
exports.onCreatePage = ({ page, actions }) => {
const { createPage, deletePage } = actions
const oldPage = Object.assign({}, page)
page.context.language = page.context.intl.language;
if (page.context.language !== oldPage.context.language) {
// Replace new page with old page
deletePage(oldPage)
createPage(page)
}
}
Checking if the field has changed avoids the infinity loop.
I am working under Aurelia Framework.I want to apply i18N on console messages .
I am using two languages "English" and "French"
Console.log("Hello World");
How i can print this message in french if user change language mode.
The docs for the plugin do contain exactly that example:
import {I18N} from 'aurelia-i18n';
export class MyDemoVM {
static inject = [I18N];
constructor(i18n) {
this.i18n = i18n;
console.log(this.i18n.tr('mykey'));
}
...
}
I would like to update my localization messages in vue-i18n dynamically.
I am building a webshop, where every item has descriptions in more languages. So what I’d like to achieve is when I get the webshop items from the REST API I want to put their names, descriptions etc. to the messages object in vue-i18n so it can work with them. Does the vue-i18n API have something to handle that? Also I am getting the data from the server (I get a Promise), so how can I make sure it gets updated in the browser view, when I finally get the response, and add the data to the localization?
What I did was write a mixin, and use it everywhere I need dynamic localization:
export default {
methods: {
$t: function (translate) {
if (typeof translate === 'string') {
return this.$i18n.t(translate)
} else if (translate === void 0) {
return this.$i18n.t('loading')
}
return translate[this.$i18n.locale]
}
}
}
This way when my texts look like the following, I can call $t(text) (NOT $t('text') of course):
data: function () {
return {text: {en:'Book', de:'Buch', hu:'Könyv'}}
}
So in your components you have to import this and add it as a mixin:
import dynamicLocalization from '#/components/mixins/dynamic-localization'
export default {
...
mixins:[dynamicLocalization]
...
}