daaru00 / gridsome-plugin-i18n

Gridsome plugin for i18n
MIT License
53 stars 12 forks source link

Add link rewrite #2

Closed daaru00 closed 4 years ago

daaru00 commented 4 years ago

Will add a rewrite logic on Vue Router to add localized path prefix (if not already present)

daaru00 commented 4 years ago

Here the latest implementation of $tp helper function:


$tp

Is a function that accept a path as arguments and return a localized prefixed path version.

// this.$i18n.locale is "en-gp"
const localizedPath = this.$tp('/projects/')
// localizedPath is "/en/projects/"

If a localized path prefix is already set it will returns the same path:

// this.$i18n.locale is "en-gp"
const localizedPath = this.$tp('/it/projects/')
// localizedPath is "/it/projects/"

this in order to not create redirect loop.

This is useful for render a correct path for builded <g-link> directives:

<g-link :to="$tp('/projects/')">Projects</g-link>

after build become:

<a href="/en/projects/">Projects</a>

It's also possible to select which locale to use during translation passing to second string parameter:

const localizedPath = this.$tp('/projects/', 'fr-fr')
// localizedPath is "/fr/projects/"

this will not works when path is already translated:

const localizedPath = this.$tp('/it/projects/', 'fr-fr')
// localizedPath is "/it/projects/" <--- not changed

To force changing locale add a third boolean parameter:

const localizedPath = this.$tp('/it/projects/', 'fr-fr', true)
// localizedPath is "/fr/projects/"

useful to language selector implementation.

daaru00 commented 4 years ago

Here an example of a Vue component to switch locale:

<template>
  <select v-model="currentLocale" @change="localeChanged">
    <option v-for="locale in availableLocales" :key="locale" :value="locale">{{ locale }}</option>
  </select>
</template>

<script>
export default {
  name: "LocaleSwitcher",
  data: function () {
    return {
      currentLocale: this.$i18n.locale.toString(),
      availableLocales: this.$i18n.availableLocales
    }
  },
  methods: {
    localeChanged () {
      this.$router.push({
        path: this.$tp(this.$route.path, this.currentLocale, true)
      })
    }
  }
}
</script>
daaru00 commented 4 years ago

Really really thank you @cfecherolle for your checking :pray: Is a huge improvements and don't want to break something or not covered some cases.

I can take advantage of your kindness and ask you for an additional check? Can you confirm that after running gridsome build inside ./dist directory the generated HTML has correct links? (english pages with "/en/" prefix, french pages with "/fr/"..and so on)

cfecherolle commented 4 years ago

Really really thank you @cfecherolle for your checking Is a huge improvements and don't want to break something or not covered some cases.

I can take advantage of your kindness and ask you for an additional check? Can you confirm that after running gridsome build inside ./dist directory the generated HTML has correct links? (english pages with "/en/" prefix, french pages with "/fr/"..and so on)

Yes it does! I just did a gridsome build and the generated pages in dist do have the lang prefixes in href attribute! For me it's fr by default, and then en or fr depending on the page folder I'm checking.

daaru00 commented 4 years ago

awesome, let's merge it! :tada:

pmochine commented 4 years ago

Side question to the LocaleSwitcher. It works nice, however it forces me always to the default language prefix of /en. Is it possible to ignore it?

For example: http://localhost:8080/en/ (I just need http://localhost:8080, but when I visit http://localhost:8080 it redirects me directly to /en/ because of the event in select @change="localeChanged")

daaru00 commented 4 years ago

Hi @pmochine,

yes, is possible to disable that behaviour using enablePathRewrite option (true by default)

module.exports = {
  plugins: [
    {
      use: "gridsome-plugin-i18n",
      options: {
        enablePathRewrite: false,
        // ...
      }
    }
  ]
};