Yerelleştirme

Pluginler bölümünde görüldüğü gibi, tüm uluslararasılaştırma desteği için Olobase Admin, Vue I18n'i kullanacaktır. Her yerel ayar için anahtar/değer tabanlı bir JSON dosyası kullanılır. Vue I18n aynı zamanda tekil/çoğul formatın yanı sıra sayılar, para birimleri ve tarihler gibi gelişmiş formatları da destekler.

Vue I18n

Vuei18n kütüphanesi mevcut projenizin altında aşağıdaki dosyadan yüklenir.

src/i18n/index.js

import { createI18n } from "vue-i18n";
import pluralRules from "./rules/pluralization";
import numberFormats from "./rules/numbers.js";
import datetimeFormats from "./rules/datetime.js";
/**
 * app messages
 */
import _en from "./locales/en.json" assert { type: "json" };
import _tr from "./locales/tr.json" assert { type: "json" };

const i18n = createI18n({
  locale: import.meta.env.VITE_DEFAULT_LOCALE,
  fallbackLocale: import.meta.env.VITE_FALLBACK_LOCALE,
  legacy: false,
  globalInjection: true,
  // forceStringify: false,
  messages: { tr: _tr, en: _en },
  runtimeOnly: false,
  pluralRules,
  numberFormats,
  datetimeFormats,
});
/**
 * import vuetify admin locales
 */
import { en, tr } from "olobase-admin/src/locales";
/**
 * build vuetify admin messages
 */
const vaMessages = { en, tr };
/**
 * load vuetify admin i18n locales
 */
Object.keys(vaMessages).forEach((locale) => {
  i18n.global.mergeLocaleMessage(locale, { va: vaMessages[locale] });
})
export default i18n

Varsayılan Yerel Dil

LanguageSwitcher bileşeni kullanıcının varsayılan dil değerini belirlemesini sağlar.

src/views/Login.vue

Switch Locale

Dil değiştirme bileşenini diğer sayfalarınızda da ekleyebilirsiniz. Takip eden örnekte LanguageSwitcher bileşeninin Login.vue sayfasındaki kullanımını gösteriliyor.

src/i18n/translation.js

import i18n from "@/i18n";
import { nextTick } from "vue";
import store from "../store";

const Trans = {
  /*
  * code shortened for readability
  */
  async switchLanguage(newLocale) {
    Trans.currentLocale = newLocale;
    store.commit('SET_LOCALE', newLocale);
    cookies.set("lang", newLocale); // we user cookies
    document.querySelector("html").setAttribute("lang", newLocale);
  },
  /*
  * code shortened for readability
  */
}

src/views/Login.vue

<template>
  <div>
    <LanguageSwitcher />
  </div>
</template>

src/views/Login.vue

import LanguageSwitcher from "@/components/LanguageSwitcher.vue";

export default {
  components: { LanguageSwitcher },
}

Varsayılan yerel dil kullanıcı giriş yaptıktan sonra tarayıcının çerezler adlı yerel deposuna kayıt edilir. Uygulamayı ziyaret eden kullanıcı eğer önceden bir yerel dil seçmiş ise bu değer çerezlerden, eğer çerezlerde de bulunamaz ise VITE_DEFAULT_LOCALE değerinden elde edilir.

src/i18n/index.js

const i18n = createI18n({
  locale: import.meta.env.VITE_DEFAULT_LOCALE,
  fallbackLocale: import.meta.env.VITE_FALLBACK_LOCALE,
  legacy: false,
  globalInjection: true,
  // forceStringify: false,
  messages: { tr: _tr, en: _en },
  runtimeOnly: false,
  pluralRules,
  numberFormats,
  datetimeFormats,
});
├── src
│   ├── i18n
│   │   ├── locales
│   │   │   ├── en.js
│   │   │   ├── tr.js

Desteklenen Diller

Desteklenen dillere yeni bir dil eklemek ya da çıkarmak istediğiniz de src/.env.dev, src/.env.prod dosyasınlarındaki VITE_SUPPORTED_LOCALES değişkenini de güncellemelisiniz.

VITE_DEFAULT_LOCALE=tr
VITE_FALLBACK_LOCALE=en
VITE_SUPPORTED_LOCALES=en,tr
VITE_API_URL=http://demo.local/api
VITE_LICENSE_KEY=

Vuetify

Tam kullanıcı arayüzü yerelleştirme desteği için Olobase Admin yerel ayarları tek başına yeterli değildir. Vuetify, Olobase Admin'de eklenti olarak kullanıldığından, Vuetify i18n içinde de yerelleştirme kuralları belirtmeniz gerekir.

src/plugins/vuetify.js

// Styles
import "vuetify/styles";

// Translations provided by Vuetify
import { en, tr } from "vuetify/locale";
import Trans from "@/i18n/translation";
const defaultLang = Trans.guessDefaultLocale();

// Composables
import { createVuetify } from "vuetify";

const defaultTheme = {
  dark: false,
  colors: {
    background: "#FFFFFF",
    surface: "#FFFFFF",
    primary: localStorage.getItem("themeColor")
      ? localStorage.getItem("themeColor")
      : "#0a7248",
    secondary: "#eeeeee",
    error: "#ed0505",
    info: "#00CAE3",
    // success: '#4CAF50',
    // warning: '#FB8C00',
  },
};
// Vuetify 
export default createVuetify({
  locale: {
    locale: Trans.supportedLocales.includes(defaultLang) ? defaultLang : import.meta.env.VITE_DEFAULT_LOCALE,
    fallback: "en",
    messages: { tr, en },
  },
  theme: {
    defaultTheme: "defaultTheme",
    themes: {
      defaultTheme,
    },
  },
});

Resources (Kaynaklar)

Olobase Admin'deki tüm varsayılan kullanıcı arayüzü etiketlerinin doğru şekilde yerelleştirilmesi gerekir. Ayrıca Vue I18n sayesinde kendi özel yerel ayarlarınızı herhangi bir özel sayfa üzerinde kullanabilirsiniz. Peki ya kaynakların adı ve tüm kaynak özellik etiketleri ne olacak ? Vue I18n'den gelen $t fonksiyonunu CRUD sayfalarının her yerinde, tüm bileşenlere etiketler atamak zorunda kalmak sıkıcı olabilir.

Bu kodu en aza indirmek için Olobase Admin, basit bir adlandırma kuralını izleyerek kaynak veya source adından hedef çeviri anahtarını tahmin etmeye çalışacaktır. Olobase Admin, seçim, radyo düğmesi vb. gibi tüm seçim tabanlı alan veya giriş bileşenleri için kullanılabilecek yerelleştirilmiş numaralandırmaları bile destekler. Yerelleştirilmiş kaynağa özel tüm etiketlerin, ana kaynaklar anahtarının altına varsayılan olarak src/locales/{locale}.json olan kendi i18n json yerel ayarınıza eklenmesi gerekir. Kaynaklar altındaki her çeviri anahtarı, src/resources/index.js dosyasında ayarlanan geçerli kaynak adlarıyla eşleşmelidir.

Daha sonra dil ayarlarınıza aşağıdaki desteklenen anahtarları koyabilirsiniz:

Anahtar Açıklama
name Kaynağın tekil ve çoğul biçimdeki adı, özellikle her sayfa başlığında ve bazı bağlam mesajlarında kullanılır.
titles Her CRUD eylemi için yerelleştirilmiş başlıklar. Geçerli alt anahtarlar list, show, create veya edit'tir.
fields Her kaynak özelliği için yerelleştirilmiş etiketler.
enums Kaynak özelliği için yerelleştirilmiş numaralandırmalar; her numaralandırma, anahtarın hedeflenen özelliğin geçerli bir değerine karşılık gelmesi gereken bir anahtar-değer çifti dizisidir.

Her kaynak etiketi türü için uymanız gereken adlandırma çeviri anahtarları formatı aşağıda verilmiştir:

Anahtar I18n anahtar yol biçimi users modülü için örnek
name resources.{resource}.name resources.users.name
titles resources.{resource}.titles resources.users.titles
fields resources.{resource}.fields.{source} resources.users.fields.name
enums resources.{resource}.enums.{source}.{value} resources.users.enums.roles

İşte bir users modülü ve en yereline ait bir örnek:

src/locales/en.json

{
  //...
  "resources": {
    "users": {
      "name": "User | Users",
      "titles": {
        "list": "List all users",
        "show": "Details of user {name}",
        "create": "Create new user",
        "edit": "Edit user {name}"
      },
      "fields": {
        "id": "ID",
        "name": "Name",
        "email": "Email",
        "password": "Password",
        "password_confirmation": "Password Confirmation",
        "active": "Active",
        "roles": "Roles",
        "createdAt": "Creation Date",
        "updatedAt": "Modification Date"
      },
      "enums": {
        "roles": {
          "admin": "Admin",
          "editor": "Editor",
          "author": "Author"
        }
      }
    }
  }
}

Tekil ve Çoğul

Varsayılan Olarak Uygulayın

Enumerik Değerler (enums)

Seçme veya radyo bileşenleri için işlevsel yerelleştirilmiş seçeneklere sahip olmak amacıyla, numaralandırma anahtarınızın bu bileşenin kaynak desteğiyle aynı şekilde adlandırılması gerekir.

Sayfa Başlıkları

Bu özel anahtar isteğe bağlıdır ve esas olarak tam kontrolle uç durum yerelleştirme yönetimi için kullanılır. Varsayılan olarak, Olobase Admin şu başlık biçimini oluşturacaktır: {action} {resource} (ör. Kullanıcı listesi), aksiyon, CRUD eyleminin yerelleştirilmiş adıdır ve resource, kaynağın yerelleştirilmiş adıdır.

Ancak bazen daha iyi tanımlama için gösterme ve düzenleme eylemine yönelik belirli bir kaynak özelliği ekleyerek daha fazlasını isteyebilirsiniz. Bu, yerelleştirilmiş etikette nitelik adınızı parantez içine ekleyerek kolayca yapılır. Örneğin, {name} #{id}, burada name yer tutucusu, kullanıcı kaynak özelliğinin adı ile değiştirilecektir.

Override (Ezmek)

Eğer bir bileşen içerisinde belirli bir özelliğin ezme davranışı sergilemesini istiyorsanız özellik adı ve değerini açıkça belirtmelisiniz. Örneğin label özelliğinin aşağıdaki gibi belirtmek varsayılan label değerinin ezilmesini ve yeni değerin etkin olmasını sağlar. Bunu her bileşen için uygulayabilirsiniz.

<va-select-input
  :label="$t('demo.currencyId')"
  reference="currencies"
  v-model="model.currencyId"
></va-select-input>

Tarih ve Sayı Biçimi Kuralları

Yerelleştirilmiş sayı ve tarih alanı kaynak değerleri için muhtemelen DateField ve NumberField'ı kullanacaksınız. Bu bileşenler, başlık altında belirli Vue I18n işlevlerini kullanacaktır:

├── src
│   ├── i18n
│   │   ├── rules
│   │   │   ├── datetime.js
│   │   │   ├── numbers.js

src/i18n/rules/datetime.js

export default {
  en: {
    year: {
      year: "numeric",
    },
    month: {
      month: "short",
    },
    shortFormat: {
      dateStyle: "short",
    },
    longFormat: {
      year: "numeric",
      month: "long",
      day: "numeric",
      weekday: "long",
      hour: "numeric",
      minute: "numeric",
      hour12: false,
    },
  },
  tr: {
    year: {
      year: "numeric",
    },
    month: {
      month: "short",
    },
    shortFormat: {
      dateStyle: "short",
    },
    longFormat: {
      year: "numeric",
      month: "long",
      day: "numeric",
      weekday: "long",
      hour: "numeric",
      minute: "numeric",
      hour12: false,
    },
  },
};

Örneğin yukarıdaki gibi tanımlanan bir tarih kuralı i18n/index.js içerisinde tanımlanır.

src/i18n/index.js

import { createI18n } from "vue-i18n";
import pluralRules from "./rules/pluralization";
import numberFormats from "./rules/numbers.js";
import datetimeFormats from "./rules/datetime.js";
import _en from "./locales/en.json";
import _tr from "./locales/tr.json";

const i18n = createI18n({
  locale: import.meta.env.VITE_DEFAULT_LOCALE,
  fallbackLocale: import.meta.env.VITE_FALLBACK_LOCALE,
  legacy: false,
  globalInjection: true,
  // forceStringify: false,
  messages: { tr: _tr, en: _en },
  runtimeOnly: false,
  pluralRules,
  numberFormats,
  datetimeFormats,
});

DateField

<date-field source="creationDate" format="short"></date-field>

NumberField

<number-field source="price" format="currency"></number-field>