From 7d96c54070d4fbd20c011d5c68e49db576a72d05 Mon Sep 17 00:00:00 2001 From: filesite Date: Sat, 5 Jul 2025 08:33:55 +0800 Subject: [PATCH] add ga code --- conf/config.json | 4 + i18n.mjs | 325 ++++++++++++++++++++----------------- public/de/index.html | 10 ++ public/en-us/index.html | 10 ++ public/es/index.html | 10 ++ public/hi/index.html | 10 ++ public/index.html | 10 ++ public/ja/index.html | 10 ++ public/ru/index.html | 10 ++ public/template/index.html | 10 ++ public/zh-tw/index.html | 10 ++ public/zh/index.html | 10 ++ 12 files changed, 278 insertions(+), 151 deletions(-) diff --git a/conf/config.json b/conf/config.json index df5e873..f321415 100644 --- a/conf/config.json +++ b/conf/config.json @@ -26,5 +26,9 @@ "tokens": { "herounion_demo": "hello#world!" + }, + + "templateConfigs": { + "GTAG_ID": "G-DZRYEJF89T" } } \ No newline at end of file diff --git a/i18n.mjs b/i18n.mjs index 2ceaf86..fbb5853 100644 --- a/i18n.mjs +++ b/i18n.mjs @@ -12,12 +12,13 @@ import common from './common.mjs'; class I18N { - //构造函数,设置默认配置 - constructor(defaultLang, templateDir, langDir, buildDir) { - this.defaultLang = typeof(defaultLang) != 'undefined' && defaultLang ? defaultLang : 'en'; - this.templateDir = typeof(templateDir) != 'undefined' && templateDir ? templateDir : './public/template/'; - this.langDir = typeof(langDir) != 'undefined' && langDir ? langDir : './i18n/'; - this.buildDir = typeof(buildDir) != 'undefined' && buildDir ? buildDir : './public/'; + //构造函数,设置默认配置 + constructor(defaultLang, templateDir, langDir, buildDir, configFilename) { + this.defaultLang = typeof(defaultLang) != 'undefined' && defaultLang ? defaultLang : 'en'; + this.templateDir = typeof(templateDir) != 'undefined' && templateDir ? templateDir : './public/template/'; + this.langDir = typeof(langDir) != 'undefined' && langDir ? langDir : './i18n/'; + this.buildDir = typeof(buildDir) != 'undefined' && buildDir ? buildDir : './public/'; + this.configFile = typeof(configFilename) != 'undefined' && configFilename ? configFilename : 'config.json'; } //从模板文件中解析语言占位变量,并生成语言包文件 @@ -25,20 +26,20 @@ class I18N { const _self = this; try { - const files = await readdir(_self.templateDir); - let parseLangRes = null; - for (const file of files) { - parseLangRes = await _self.parseLangFromTemplate(_self.templateDir + file); - if (parseLangRes) { - console.log('Template file [%s] parse lang config done', file); - } - } - } catch (err) { - console.error('Read dir in function init failed', err); - return false; - } - - return true; + const files = await readdir(_self.templateDir); + let parseLangRes = null; + for (const file of files) { + parseLangRes = await _self.parseLangFromTemplate(_self.templateDir + file); + if (parseLangRes) { + console.log('Template file [%s] parse lang config done', file); + } + } + } catch (err) { + console.error('Read dir in function init failed', err); + return false; + } + + return true; } //根据语言包文件以及模板文件,生成对应语言的html文件 @@ -49,29 +50,30 @@ class I18N { console.log('Lang json files', langFiles); if (langFiles && langFiles.length > 0) { - try { - let langData = null; - let newHtml = '', saved = false; - for (const langFile of langFiles) { - const langJson = await readFile(_self.langDir + langFile, { encoding: 'utf8' }); - if (!langJson) { - continue; - } - langData = JSON.parse(langJson); - - const files = await readdir(_self.templateDir); - for (const file of files) { - newHtml = await _self.replaceLangToTemplate(_self.templateDir + file, langData); - if (newHtml) { - saved = await _self.saveBuildHtml(langFile.replace('.json', ''), file, newHtml); - console.log('Template file [%s] lang data replace with [%s] done, html build [%s].', file, langFile, (saved ? 'success' : 'failed')); - } - } - } - } catch (err) { - console.error('Read dir in function build failed', err); - return false; - } + try { + let langData = null; + let newHtml = '', saved = false; + for (const langFile of langFiles) { + const langJson = await readFile(_self.langDir + langFile, { encoding: 'utf8' }); + if (!langJson) { + continue; + } + langData = JSON.parse(langJson); + + const files = await readdir(_self.templateDir); + for (const file of files) { + newHtml = await _self.replaceLangToTemplate(_self.templateDir + file, langData); + if (newHtml) { + newHtml = await _self.replaceConfigToTemplate(newHtml); //replace configs + saved = await _self.saveBuildHtml(langFile.replace('.json', ''), file, newHtml); + console.log('Template file [%s] lang data replace with [%s] done, html build [%s].', file, langFile, (saved ? 'success' : 'failed')); + } + } + } + } catch (err) { + console.error('Read dir in function build failed', err); + return false; + } } return true; @@ -79,38 +81,38 @@ class I18N { //判断语言代码格式是否符合国际标准 isIosLangCode(lang) { - return /^[a-z]{2}(\-[a-z]{2})?$/i.test(lang); + return /^[a-z]{2}(\-[a-z]{2})?$/i.test(lang); } //判断是否是语言包文件 isIosLangFile(filename) { - return /^[a-z]{2}(\-[a-z]{2})?\.json$/i.test(filename); + return /^[a-z]{2}(\-[a-z]{2})?\.json$/i.test(filename); } //更新语言包文件内容,合并新的数据到已有内容中 async updateLangFile(langFile, langJson) { - const _self = this; - let updated = false; - - try { - let json = await readFile(langFile, { encoding: 'utf8'}); - if (json) { - let data = JSON.parse(json); - for (const key in langJson) { - data[key] = langJson[key]; - } - - await writeFile(langFile, JSON.stringify(data, null, 4)); - }else { - await writeFile(langFile, JSON.stringify(langJson, null, 4)); - } - - updated = true; - } catch (err) { - console.error('updateLangFile failed', err); - } - - return updated; + const _self = this; + let updated = false; + + try { + let json = await readFile(langFile, { encoding: 'utf8'}); + if (json) { + let data = JSON.parse(json); + for (const key in langJson) { + data[key] = langJson[key]; + } + + await writeFile(langFile, JSON.stringify(data, null, 4)); + }else { + await writeFile(langFile, JSON.stringify(langJson, null, 4)); + } + + updated = true; + } catch (err) { + console.error('updateLangFile failed', err); + } + + return updated; } //解析单个模板文件,并生成语言包文件 @@ -118,66 +120,66 @@ class I18N { const _self = this; let langJson = {}, - total = 0; + total = 0; try { - const html_template = await readFile(templateFilepath, { encoding: 'utf8' }); - - const regHtmlLang = /[\s\S]*[\s\S]*/i; - let htmlLang = html_template.replace(regHtmlLang, "$1"); - if (htmlLang == html_template || _self.isIosLangCode(htmlLang) == false) { - htmlLang = _self.defaultLang; - }else { - htmlLang = htmlLang.toLowerCase(); - } - - //模版语法不能包含:换行符、英文冒号、英文分号 - const regLang = /\{([^\}\r\n:;]+)\}/ig; - const matches = html_template.matchAll(regLang); - for (const match of matches) { - langJson[match[1]] = match[1]; - total ++; - } - - //更新语言包文件 - if (total > 0) { - let langFile = _self.langDir + `${htmlLang}.json`; - const saved = await _self.updateLangFile(langFile, langJson); - if (!saved) { - return false; - } - } - } catch (err) { - console.error('parseLangFromTemplate failed', err); - return false; - } - - return langJson; + const html_template = await readFile(templateFilepath, { encoding: 'utf8' }); + + const regHtmlLang = /[\s\S]*[\s\S]*/i; + let htmlLang = html_template.replace(regHtmlLang, "$1"); + if (htmlLang == html_template || _self.isIosLangCode(htmlLang) == false) { + htmlLang = _self.defaultLang; + }else { + htmlLang = htmlLang.toLowerCase(); + } + + //模版语法不能包含:换行符、英文冒号、英文分号 + const regLang = /\{([^\}\r\n:;]+)\}/ig; + const matches = html_template.matchAll(regLang); + for (const match of matches) { + langJson[match[1]] = match[1]; + total ++; + } + + //更新语言包文件 + if (total > 0) { + let langFile = _self.langDir + `${htmlLang}.json`; + const saved = await _self.updateLangFile(langFile, langJson); + if (!saved) { + return false; + } + } + } catch (err) { + console.error('parseLangFromTemplate failed', err); + return false; + } + + return langJson; } //获取所有语言包json文件 async getLangFiles(lang) { - const _self = this; - - let langFiles = []; - - try { - const files = await readdir(_self.langDir); - let parseLangRes = null; - for (const file of files) { - if (_self.isIosLangFile(file)) { - if (typeof(lang) == 'undefined') { - langFiles.push(file); - }else if (file.indexOf(lang) > -1) { - langFiles.push(file); - } - } - } - } catch (err) { - console.error('Read dir in function getLangFiles failed', err); - return false; - } - - return langFiles; + const _self = this; + + let langFiles = []; + + try { + const files = await readdir(_self.langDir); + let parseLangRes = null; + for (const file of files) { + if (_self.isIosLangFile(file)) { + if (typeof(lang) == 'undefined') { + langFiles.push(file); + }else if (file.indexOf(lang) > -1) { + langFiles.push(file); + } + } + } + } catch (err) { + console.error('Read dir in function getLangFiles failed', err); + return false; + } + + return langFiles; } //根据语言包替换单个模板文件,返回新的html代码 @@ -186,39 +188,60 @@ class I18N { let html = ''; try { - const html_template = await readFile(templateFilepath, { encoding: 'utf8' }); - - html = html_template; - for (let key in langData) { - html = html.replaceAll(`{${key}}`, langData[key]); - } - } catch (err) { - console.error('replaceLangToTemplate failed', err); - return false; - } - - return html; + const html_template = await readFile(templateFilepath, { encoding: 'utf8' }); + + html = html_template; + for (let key in langData) { + html = html.replaceAll(`{${key}}`, langData[key]); + } + } catch (err) { + console.error('replaceLangToTemplate failed', err); + return false; + } + + return html; + } + + //根据配置文件,替换配置项 + async replaceConfigToTemplate(html_template) { + const _self = this; + + let html = html_template; + try { + let config = await common.getConfigFromJsonFile(_self.configFile); + if (typeof(config['templateConfigs']) == 'undefined' || !config['templateConfigs']) {return html;} + + let tempConfigs = config['templateConfigs']; + for (let key in tempConfigs) { + html = html.replaceAll(`{config:${key}}`, tempConfigs[key]); + } + } catch (err) { + console.error('replaceConfigToTemplate failed', err); + return false; + } + + return html; } //保存替换了语言包的html文件 async saveBuildHtml(lang, htmlFilename, htmlContent) { - const _self = this; - let saved = false; - - try { - let langDir = _self.buildDir + lang; - if (!fs.existsSync(langDir)) { - fs.mkdirSync(langDir); - } - - let htmlFile = `${langDir}/${htmlFilename}`; - await writeFile(htmlFile, htmlContent); - saved = true; - } catch (err) { - console.error('saveBuildHtml failed', err); - } - - return saved; + const _self = this; + let saved = false; + + try { + let langDir = _self.buildDir + lang; + if (!fs.existsSync(langDir)) { + fs.mkdirSync(langDir); + } + + let htmlFile = `${langDir}/${htmlFilename}`; + await writeFile(htmlFile, htmlContent); + saved = true; + } catch (err) { + console.error('saveBuildHtml failed', err); + } + + return saved; } } diff --git a/public/de/index.html b/public/de/index.html index 5e0bc51..5450322 100644 --- a/public/de/index.html +++ b/public/de/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/en-us/index.html b/public/en-us/index.html index 25ea36a..49d4783 100644 --- a/public/en-us/index.html +++ b/public/en-us/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/es/index.html b/public/es/index.html index ded30c0..42904a1 100644 --- a/public/es/index.html +++ b/public/es/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/hi/index.html b/public/hi/index.html index 0bc3946..040c6c8 100644 --- a/public/hi/index.html +++ b/public/hi/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/index.html b/public/index.html index 25ea36a..49d4783 100644 --- a/public/index.html +++ b/public/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/ja/index.html b/public/ja/index.html index 214bf3a..f04bb43 100644 --- a/public/ja/index.html +++ b/public/ja/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/ru/index.html b/public/ru/index.html index de2627d..d24e20d 100644 --- a/public/ru/index.html +++ b/public/ru/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/template/index.html b/public/template/index.html index 77aa072..de54fe6 100644 --- a/public/template/index.html +++ b/public/template/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/zh-tw/index.html b/public/zh-tw/index.html index 76c0f24..27115ed 100644 --- a/public/zh-tw/index.html +++ b/public/zh-tw/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file diff --git a/public/zh/index.html b/public/zh/index.html index a4765fe..ad1f462 100644 --- a/public/zh/index.html +++ b/public/zh/index.html @@ -276,5 +276,15 @@ setInterval(loadUnionStats, 20000); + + + + \ No newline at end of file