| 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. |
| 4 | module veb |
| 5 | |
| 6 | import os |
| 7 | |
| 8 | const tr_map = load_tr_map() |
| 9 | |
| 10 | pub 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' |
| 16 | fn 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 | |
| 37 | fn fetch_lang_from_tr_path(path string) string { |
| 38 | return path.find_between(os.path_separator, '.') |
| 39 | } |
| 40 | |
| 41 | // Used by %key in templates |
| 42 | pub 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 | |
| 51 | pub 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 | |