i18n wants to load an unspecified translation - internationalization

I'm currently working on an Aurelia project (web framework like Angular2).
I followed the guide on their github account but encountered a problem.
First, the browser returned me this error:
GET http://localhost:9000/src/locale/nl/translation.json?_=1450946571510 404 (Not Found)
Secondly, I'm using two languages in my application: Dutch (nl-BE) and French (fr-BE).
Here is how my folder structure looks like:
src (inside root)
.. locale
..... fr-BE
........ translation.json
..... nl-BE
........ translation.json
Here is what my full main.js file looks like:
import 'bootstrap';
import {I18N} from 'aurelia-i18n';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.globalResources('converters/dateFormat')
.plugin('components/index')
.plugin('plugins/index')
.plugin('aurelia-i18n', (instance) => {
instance.setup({
resGetPath: 'src/locale/__lng__/__ns__.json',
lng: 'nl-BE',
attributes: ['t', 'i18n'],
getAsync: true,
sendMissing: false,
fallbackLng: 'fr-BE',
debug: false
});
});
aurelia.start().then(a => a.setRoot());
}
I'm trying to setup a hello world where I have my view and viewmodel set like this:
import {inject} from 'aurelia-framework';
import {I18N} from 'aurelia-i18n';
#inject(I18N)
export class EntryDetails {
constructor(i18n){
this.i18n = i18n;
this.i18n.setLocale('nl-BE').then(() => console.log('test'));
}
}
And my view:
<template>
<span t="hello"></span> <span t="world"></span>
</template>
The problem is not that it's not working. The problem is that I'm getting an error that states my folder nl is missing in my locale folder. But I never specified that anywhere..

That is how i18next resolves translation files.
The lookup order for keys is always:
nl-BE language + country
nl language only
fallback thats defined in options.fallbackLng (en) (string or array of fallback language)
loaded resources:
locale/en/translation.json
locale/nl/translation.json
locale/nl-BE/translation.json
http://i18next.com/translate/#resolve
So you need to have nl/translation.json, even if it is not specified in config. It can be just empty but valid json file with content {}

Related

i18n camespace in SAP Commerce / Spartacus

I dont get how namespaces work in SAP Commerce. (https://sap.github.io/spartacus-docs/1.x/i18n/)
How i think it works is as follows:
Add the HTML {{ 'updatePasswordForm.oldPassword.placeholder' | cxTranslate }}
add that in your translation.ts
updatePasswordForm:{
oldPassword:{
placeholder: "Old password"
}
},
Config of chunks and namespaces mapping
with the last part i have my problem. I don't know where to put it and my project just uses the default one. How do do i find that?
I recommend using translation chunks as described there:
https://sap.github.io/spartacus-docs/i18n/#configuring-chunks-and-namespace-mapping
Working solution.
In app.module.ts in providers provide this config:
provideConfig({
i18n: {
backend: {
loadPath: 'assets/i18n-assets/{{lng}}/{{ns}}.json',
},
chunks: {
'forms': ['updatePasswordForm'],
},
},
}),
Afterwards, we can create a json file in src/assets/i18n-assets/en/forms.json and inside this file add the following lines:
{
"updatePasswordForm": {
"oldPassword": {
"placeholder": "Old password"
}
}
}
Explanation
loadPath defines the place where the translation chunks will be located.
{{lng}} defines a folder for translations language, e.g., en, de etc.
{{ns}} is placeholder for chunks.
In chunks we defined 'forms' field which corresponds to our translations file - forms.json.
Also, we have to map translations to namespaces - we have defined that our forms.json file contains namespaces ['updatePasswordForm'], so when translations will be needed for namespaces that starts with updatePasswordForm, the forms.json file will be loaded.

Laravel mix removes subfolder from image path

I've set up an alias for my public folder where I've placed my images.
So they are inside public/images. I have a subfolder for certain types of images - in this case, card brands.
They're in public/images/card-brands
Here is my alias config:
mix.webpackConfig({
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'#': __dirname + '/resources/js',
'#public' : __dirname + '/public'
},
},
})
I'm importing the images in my vue component file:
import amex from '#public/images/card-brands/amex.svg'
import discover from '#public/images/card-brands/discover.svg'
import visa from '#public/images/card-brands/visa.svg'
import mastercard from '#public/images/card-brands/mastercard.svg'
Then using it inside my components data like so:
export default {
name: 'PaymentMethod',
data() {
return {
...
visaSvg: visa,
mastercardSvg: mastercard,
discoverSvg: discover,
amexSvg: amex,
currentCardBrand: this.initialCurrentCardBrand
...
}
},
props: {
...
initialCurrentCardBrand: String,
...
}
computed: {
getCurrentCardBrandSvg() {
switch (this.currentCardBrand) {
case 'mastercard':
return this.mastercardSvg;
break;
case 'visa':
return this.visaSvg;
break;
case 'amex':
return this.amexSvg;
break;
case 'discover':
return this.discoverSvg;
break;
}
}
}
...
Finally, I'm using it on my template as and image src: <img class="w-10" :src="getCurrentCardBrandSvg">
Now, even though the images and my import path are using the card-brands subfolder, the URL that is generated ignores this and just looks for the images in the root images folder.
It should be:
/public/images/card-brands/visa.svg
but it's generating as
/public/images/visa.svg
How can I get it to keep my subfolder?
try this instead {{ asset('/images/card-brands/mastercard.svg')) }}
I faced a similar issue in laravel. I used the above format.Please correct me if Im wrong.
Edit: This could be slightly wrong. It works correctly for importing images via javascript, but I think grabbing images via laravel in blade templates still needs the images in the public folder.
The issue was not knowing that I was supposed to put my images folder inside the resources folder rather than public.
Laravel Mix will compile the images like it does the JS and SCSS and place it in public automatically.
So I created an images folder in resources, deleted my manually made images folder in public, and made an alias:
alias: {
'#images': __dirname + '/resources/images'
}
and now I can link to that inside my vue component.
import amex from '#images/card-brands/amex.svg'
import discover from '#images/card-brands/discover.svg'
import visa from '#images/card-brands/visa.svg'
import mastercard from '#images/card-brands/mastercard.svg'
The generated images will automatically be placed in public on the root level once I run npm run dev or npm run prod

how to access vue.js api key in laravel application

hello there i am trying to access my youtube api key located in the .env file from within this code:
<template>
<div class="YoutubeDash__wrapper">
<video-group :videos="videos"></video-group>
</div>
</template>
<script>
import VideoGroup from './VideoGroup.vue';
import Search from './Search';
export default {
components: {
VideoGroup
},
created(){
Search({
apiKey: process.env.VUE_APP_SECRET,
term: 'laravel repo'
}, response => this.videos = response);
},
data(){
return {
videos: null
}
}
}
</script>
According to the documentation using env variables with vue.js. Everything seems to be correct. In my .env file i say: VUE_APP_SECRET=xxxxxxxxxxxxxxx, what am i missing here ?
I get this error message:
app.js:37809 Error: YouTube search would require a key
Any tips are welcome! Thanks a lot!
We need to work with a small amount of information here so I am going to make a few assumptions (based on the tags) mostly that you are using laravel and laravel-mix to compile your resources.
For laravel(-mix) to make your .env variables accessible by JS you need to prefix them with MIX_ i.e. MIX_VUE_APP_SECRET. This will make your variable accessible as process.env.MIX_VUE_APP_SECRET.
I prefer excluding laravel-mix from this process.
Usually, in my blade entry-point I use meta tags:
<meta name="myVal" content="{{ config('<any-config-key>') }}">
<any-config-key> can be any laravel configuration key including those taken from .env.
Then, in my javascript I do something like:
const setVueGlobal = (metaHeaderName, vueGlobalName) => {
let value = document.head.querySelector('meta[name="' + metaHeaderName + '"]').content;
if (!value) {
console.error('some error msg');
return null;
}
Vue.prototype[vueGlobalName] = value;
return value;
};
setVueGlobal('myVal', '$myVal');
Finally, accessing using this.$myVal

Loading D3 with Nuxt/Vue

I am trying to implement D3 in an app I am building with Nuxt. I have successfully imported it into a view in the <script> section with import * as d3 from 'd3' however because the app is being rendered server-side D3's functionality doesn't work (i.e. d3.select(...)) due to the lack of browser. In the Nuxt plugin documentation it suggests a pattern for client-only external plugins:
module.exports = {
plugins: [
{ src: '~plugins/vue-notifications', ssr: false }
]
}
I attempted to implement the pattern in the nuxt.config.js of my project:
module.exports = {
head: {
title: 'My Demo App',
meta: [...],
link: [...]
},
loading: {...},
plugins: [
{ src: '~node_modules/d3/build/d3.js', ssr: false}
]
}
However D3 throws a ReferenceError while looking for document and Nuxt throws a SyntaxError in the console pointing to something in the plugins field of nuxt.config.js.
For reference, demo.vue:
<template>
<div class="demo-container"></div>
</template>
<script>
import * as d3 from 'd3';
d3.select('.demo-container');
</script>
Would someone be able to point to what I'm doing wrong?
For anyone coming to this page looking for a solution,
these suggestions from piyushchauhan2011 here on GitHub sent me in the right direction.
All I needed to do:
import d3 in my single-file component, and then
do any DOM manipulation with d3 only within mounted()
Before all this, I had to of course add d3 to my project with yarn add d3 (or npm install d3).
[Edit: removed link that no longer works. It wasn't that relevant anyway.]
I was getting an error:
Must use import to load ES Module: .../node_modules/d3/src/index.js require() of ES modules is not supported. require() of .../node_modules/d3/src/index.js from .../node_modules/vue-server-renderer/build.dev.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules. Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from .../node_modules/d3/package.json.
I solved it by reading this: https://github.com/nuxt/nuxt.js/issues/9223
which indicates you can add this to your nuxt.config.js file:
build: {
standalone: true,
}
This allowed the d3 import to work.
import * as d3 from "d3";
Here's a simple step-by-step tutorial:
Create a new NuxtJS project (Skip this step if you have an existing project)
npm init nuxt-app nuxtjs-d3js-example
Install D3JS
npm install d3
npm install #types/d3 --save-dev
Import D3JS and add a target
HTML:
<p id="d3-target"></p>
JavaScript:
import * as d3 from 'd3'
export default {
name: 'NuxtTutorial',
mounted: function() {
d3.select("#d3-target").text("This text is manipulated by d3.js")
},
}
Fix ES Module error (mentioned by #agm1984)
Error:
require() of ES Module /home/johnson/projects/nuxtjs-d3js-example/nuxtjs-d3js-example/node_modules/d3/src/index.js from /home/johnson/projects/nuxtjs-d3js-example/nuxtjs-d3js-example/node_modules/vue-server-renderer/build.dev.js not supported. Instead change the require of index.js in /home/johnson/projects/nuxtjs-d3js-example/nuxtjs-d3js-example/node_modules/vue-server-renderer/build.dev.js to a dynamic import() which is available in all CommonJS modules.
nuxt.config.js:
build: {
standalone: true,
}
A minimal project example can be found at: https://github.com/j3soon/nuxtjs-d3js-example, with each step detailed in the Git commit history.

Dojo Build with NLS - requireLocalization(..) fail?

My question, while at first somewhat similar to this one, seems to be a more basic question - and might be signaling a bug in the build system. I've created a custom build for my dojo application. I only build one layer right now, here's what the profile script/object looks like:
dependencies = {
stripConsole: "all",
action: "release",
optimize: "shrinksafe",
releaseName: "myProject",
// list of locales we want to expose
localeList: "en-gb,en-us,de-de",
layers: [
{
// Name: a relative path from the dojo.js in the desination directory.
name: "../../myProject.js",
dependencies: [
"myPackage.MyDataStore",
// MyWidget depends on a few other widgets, and has its own
// translation files.
"myPackage.MyWidget"
]
}
],
prefixes: [
// These paths are relative to the location of dojo.js
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ],
[ "myPackage", "../../../src/myPackage" ]
]
}
When I run a build with that description it outputs files in the following directory structure:
release/
release/myProject/
release/myProject/dijit/
... dijit ...
release/myProject/dojo/
... dojo ...
release/myProject/dojox/
... dojox ...
release/myProject/myPackage/
... my custom package ...
release/nls/
myProject_en-us.js
myProject_de.js
etc..
../myproject.js
../myProject.js.uncompressed.js
Finally, in my test HTML page - I've got the following:
<script type="text/javascript">
var djConfig = {
debug: true,
parseOnLoad: false,
modulePaths: { // paths to directories in relation to dojo's location.... hurr.
'myPackage': '../myPackage',
'dojox': '../dojox',
'dijit': '../dijit'
}
};
</script>
<script type="text/javascript" src="./release/myProject/dojo/dojo.js.uncompressed.js"></script>
<script type="text/javascript" src="./release/myProject.js.uncompressed.js"></script>
<script type="text/javascript">
dojo.addOnLoad(function(){
dojo.require('myPackage.MyDataStore');
dojo.require('myPackage.MyWidget');
var store = new myPackage.MyDataStore();
var widget = new myPackage.MyWidget({
store: store
}, dojo.byId('testWidget'));
widget.startup();
});
</script>
But unfortunately, Firebug spits this out at me:
Bundle not found: MyWidget in myPackage , locale=en-us
What I Think is Happening
I've traced through some of the code leading up to the above error and it seems like the dojo.i18n._preloadLocalizations() call at the end of the file doesn't actually load in the correct nls file from ./release/nls.
Any idea how to fix this without resorting to manually including the nls files with <script> tags?
It's a bug of dojo, you should not use '..' in your layers name in case it will generate a NLS package.
please refer to http://bugs.dojotoolkit.org/ticket/5225

Resources