v2 / vlib / veb / tr.v
84 lines · 77 sloc · 2.04 KB · f252d3e2e0294a91940c0adc11a8041744c095c6
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module veb
5
6import os
7
8const tr_map = load_tr_map()
9
10pub fn raw(s string) RawHtml {
11 return RawHtml(s)
12}
13
14// This function is run once, on app startup. Setting the `tr_map` const.
15// m['en']['house'] == 'House'
16fn load_tr_map() map[string]map[string]string {
17 // Find all translation files to figure out how many languages we have and to load the translation map
18 files := os.walk_ext('translations', '.tr')
19 mut res := map[string]map[string]string{}
20 for tr_path in files {
21 lang := fetch_lang_from_tr_path(tr_path)
22 text := os.read_file(tr_path) or {
23 eprintln('translation file "${tr_path}" failed to laod')
24 return {}
25 }
26 x := text.split('-----\n')
27 for s in x {
28 nl_pos := s.index('\n') or { continue }
29 key := s[..nl_pos]
30 val := s[nl_pos + 1..]
31 res[lang][key] = val
32 }
33 }
34 return res
35}
36
37fn fetch_lang_from_tr_path(path string) string {
38 return path.find_between(os.path_separator, '.')
39}
40
41// Used by %key in templates
42pub fn tr(lang string, key string) string {
43 res := tr_map[lang][key]
44 if res == '' {
45 eprintln('NO TRANSLATION FOR KEY "${key}"')
46 return key
47 }
48 return RawHtml(res)
49}
50
51pub fn tr_plural(lang string, key string, amount int) string {
52 s := tr_map[lang][key]
53 if s == '' {
54 eprintln('NO TRANSLATION FOR KEY "${key}"')
55 return key
56 }
57 if s.contains('|') {
58 //-----
59 // goods
60 // товар|а|ов
61 vals := s.split('|')
62 if vals.len != 3 {
63 return s
64 }
65 amount_str := amount.str()
66 // 1, 21, 121 товар
67 ending := if amount % 10 == 1 && !amount_str.ends_with('11') { // vals[0]
68 ''
69 // 2, 3, 4, 22 товара
70 } else if amount % 10 == 2 && !amount_str.ends_with('12') {
71 vals[1]
72 } else if amount % 10 == 3 && !amount_str.ends_with('13') {
73 vals[1]
74 } else if amount % 10 == 4 && !amount_str.ends_with('14') {
75 vals[1]
76 } else {
77 // 5 товаров, 11 товаров etc
78 vals[2]
79 }
80 return vals[0] + ending
81 } else {
82 return s
83 }
84}
85