QOR-CMS(5):使用i18n进行国际化,汉化qor-admin的i18n配置文件yaml

本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/80765024

博主地址是:http://blog.csdn.net/freewebsys

前言


https://getqor.com/cn
QOR经过全新架构,以加速开发与部署内容管理系统(CMS)、电子商务系统和业务应用程序。QOR由这类系统中抽象出的通用功能模块构成,其中包含灵活可配置的后台、内容发布系统、媒体库等等。
文档:
https://doc.getqor.com/
代码:
https://github.com/golangpkg/qor-cms-demos
全部qor文章:
https://blog.csdn.net/freewebsys/article/category/7742598

1,i18n


qor 在设计的时候是支持 国际化的。
使用的i18n 开发的,所以只要汉化翻译下就行。
https://github.com/qor/i18n
在yaml 中进行配置。

en-US:
  qor_admin:
    actions:
      advanced_filter: " 高级过滤"

然后页面中使用 t 标签:

{{t "qor_admin.filter.advanced_filter" "Advanced Filter"}}

2,main代码


代码在:
https://github.com/golangpkg/qor-cms-demos/tree/master/demo06-i18n

package main

import (
    "fmt"
    "net/http"
    "github.com/qor/admin"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
    "github.com/qor/i18n"
    "github.com/qor/i18n/backends/yaml"
    "path/filepath"
    //"github.com/qor/l10n"
    "github.com/qor/l10n"
    "os"
)

// 用户
type User struct {
    gorm.Model
    Name string
}

func main() {
    // 注册数据库,可以是sqlite3 也可以是 mysql 换下驱动就可以了。
    DB, _ := gorm.Open("sqlite3", "demo.db")
    DB.AutoMigrate(&User{}, ) //自动创建表。

    i18nPath := os.Getenv("GOPATH") + "/src/github.com/golangpkg/qor-cms-demos/demo06-i18n"
    println("i18nPath: ", i18nPath)
    I18n := i18n.New(
        //database.New(DB),                                       // load translations from the database
        yaml.New(filepath.Join(i18nPath, "config/locales")), // load translations from the YAML files in directory `config/locales`
    )
    I18n.SaveTranslation(&i18n.Translation{Key: "qor_i18n.form.saved", Locale: "en-US", Value: "保存"})

    l10n.Global = "zh-CN"
    I18n.T("en-US", "demo.greeting") // Not exist at first
    I18n.T("en-US", "demo.hello")    // Exists in the yml file
    fmt.Println(I18n)

    // 初始化admin 还有其他的,比如API
    Admin := admin.New(&admin.AdminConfig{DB: DB, I18n: I18n})

    // 创建admin后台对象资源。
    Admin.AddResource(&User{})
    Admin.AddResource(I18n)

    // 启动服务
    mux := http.NewServeMux()
    Admin.MountTo("/admin", mux)
    fmt.Println("Listening on: 9000")
    http.ListenAndServe(":9000", mux)
}

yaml可以生效得加上 :

i18nPath := os.Getenv("GOPATH") + "/src/github.com/golangpkg/qor-cms-demos/demo06-i18n"
    println("i18nPath: ", i18nPath)
    I18n := i18n.New(
        //database.New(DB),                                       // load translations from the database
        yaml.New(filepath.Join(i18nPath, "config/locales")), // load translations from the YAML files in directory `config/locales`
    )
....
//在admin 配置中再指名i18n。
Admin := admin.New(&admin.AdminConfig{DB: DB, I18n: I18n})

其中yaml 中的中文:

demo06-i18n/config/locales/qor-admin.en-US.yml

en-US:
  qor_admin:
    actions:
      advanced_filter: " 高级过滤"
      bulk_edit: " 块编辑 "
      exit_bulk_edit: " 退出块编辑 "
      please_select_an_item: " 请选择一个 "
      search_bar_search: " 查询 "
    filter:
      advanced_filter: " 高级过滤"
      apply: " 应用 "
      checkbox:
        false: " 假 "
        is_blank: " 是否空 "
        is_present: " 是否在当前 "
        true: " 真 "
      number:
        eq: " 等于 "
        gt: " 大于 "
        lt: " 小于 "
      save_this_filter: " 保存这个过滤 "
      saved_filter: " 保存过滤 "
      strings:
        conts: " 包含 "
        end_with: " 结束于 "
        eq: " 等于 "
        start_with: " 开始于 "
    form:
      add: " 增加  "
      add_items: " 增加项 "
      are_you_sure: " 是否确定? "
      cancel: " 取消 "
      cancel_edit: " 取消编辑 "
      confirm:
        button:
          cancel: " 取消 "
          ok: " 确定 "
      crop_image: " 拷贝图片 "
      ok: " 确定 "
      save_changes: " 更新 "
      select_many_hint_button: " 完成 "
      submit: " 提交 "
    layout:
      header:
        actions: " 操作 "
      logo: "xxxx"
      skip_to_content: " 跳至内容 "
    pagination:
      first: " 首页 "
      next: " 下一页 "
      page_num: " {{.Pages}}页 "
      previous: " 上一页 "
      last: " 尾页 "
      20_entries: " 20条记录 "
      50_entries: " 50条记录 "
      100_entries: " 100条记录 "
      show_all: " 全部 "
    search_center:
      all: " 全部 "
      hint: " 查询… "
      view_all: " 显示全部 "
    showpage:
      inlineedit:
        button:
            cancel_edit: " 取消编辑 "
            save: " 保存 "

3,页面效果


修改页面

增加页面:

分页效果:

翻译,在yaml 配置里面的可以有个web界面

4,查询views下面templ模板


本来以为qor-admin当中还是有个默认的配置文件。
只要找过来,汉化下,就行呢。结果没有找到。
没有办法就想到扫描下views下面的模板文件,然后解析下。

{{t "qor_admin.filter.advanced_filter" "Advanced Filter"}}

模板,有一个默认的 字符串,没有配置,得文件一个一个解析。
使用golang 进行开发的时候,本来想使用一个python扫描下,但是用docker 环境中,
没有安装python,于是使用golang重写写一个扫描程序。
用起来和 python 一样,运行速度也快,和动态脚本一样。
代码:

package main

import (
    "testing"
    "log"
    "os"
    "io/ioutil"
    "strings"
    "sort"
)

var (
    i18nPath = os.Getenv("GOPATH") + "/src/github.com/qor/admin/views"
    i18nMap  = make(map[string]string)
)

func readDir(base, dir string) {
    files, err := ioutil.ReadDir(base + "/" + dir)
    if err != nil {
        log.Fatal(err)
    }
    for _, f := range files {
        mode := f.Mode()
        if mode.IsDir() {
            //递归循环,base目录,加上相对目录即可。
            readDir(base, dir+"/"+f.Name())
        } else if strings.Contains(f.Name(), ".tmpl") {
            //println(f.Name())
            ReadFile(base + "/" + dir + "/" + f.Name())
        }
    }
}

func Test_Find(t *testing.T) {
    println("i18nPath: ", i18nPath)
    readDir(i18nPath, "")
    var keys []string
    for k := range i18nMap {
        keys = append(keys, k)
    }
    sort.Strings(keys)
    for _, k := range keys {
        k2 := strings.Replace(k, ".", "\t", -1)
        println(k2, ": \"", i18nMap[k], "\"")
    }
}

func ReadFile(fileName string) {
    data, err := ioutil.ReadFile(fileName)
    println("read file :", fileName)
    if err == nil {
        content := string(data)
        print(len(content))
        result := GetStringInBetween(content, "{{", "}}")
        //println(result)
        //fmt.Print(string(data))
        for _, val := range result {
            val = strings.Replace(val, "\"", "", -1)
            //会有多个空格,只split 2 个。
            vals := strings.SplitN(val, " ", 2)
            println(val, "len:", len(vals))
            if len(vals) == 2 {
                //println(vals[0], ":", vals[1])
                i18nMap[vals[0]] = vals[1]
            }
        }
    }
}

// GetStringInBetween Returns empty string if no start string found
//https://stackoverflow.com/questions/26916952/go-retrieve-a-string-from-between-two-characters-or-other-strings
func GetStringInBetween(str string, start string, end string) (result []string) {
    s := 1
    for s > 0 {
        s = strings.Index(str, start)
        //println(s)
        if s == -1 {
            break
        }
        s += len(start)
        e := strings.Index(str, end)
        //println("start:", s, ",end:", e)
        if e <= s { //有可数组越界的可能。
            break
        }
        tmpStr := str[s:e]
        //判断里面是否存中 t 前缀。
        if strings.Contains(tmpStr, "qor_admin") && strings.HasPrefix(tmpStr, "t ") {
            //println(tmpStr)
            //println(tmpStr)
            //替换字符串。
            result = append(result, strings.Replace(tmpStr, "t ", "", -1))
        }
        str = strings.Replace(str, start+tmpStr+end, "", -1)
    }
    return
}

i18n_test.go 使用golang 的test 进行扫描。和main 在一起也可以执行。
然后就在将打印结果转换成yaml 就行了。
循环查询views下面的tmpl文件,然后再用GetStringInBetween循环返回一个字符串数组。
本来想用正则匹配的,但是实在是没有写出来。

strings.SplitN(val, " ", 2)
//split 按照空格拆分,发现里面有多个,其实只需要拆分成2个,所以用SplitN 参数2。

5,总结


i18n 还是非常方便的,研究了下使用配置文件yaml的方式,解决中文问题。
qor 在设计上是支持yaml但是,并没有一默认的配置文件。
还是自己检索了下views下面的模板文件,然后汇总出来了。
凑成了一个yaml文件,这样就不用修改代码了,并且qor-admin系统更新了,
yaml也不影响。

本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/80765024

博主地址是:http://blog.csdn.net/freewebsys

猜你喜欢

转载自blog.csdn.net/freewebsys/article/details/80765024