From e4dd53427e27f3bb6688c12cdf383fd92a1d16ce Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Sun, 15 Jan 2023 16:58:28 +1100 Subject: [PATCH] Add language setting to global settings and board settings --- configs/template.js.example | 2 ++ controllers/forms/boardsettings.js | 4 +++- controllers/forms/globalsettings.js | 4 +++- migrations/1.0.0.js | 19 +++++++++++++++++++ models/forms/changeglobalsettings.js | 2 ++ models/pages/globalmanage/settings.js | 2 ++ models/pages/manage/settings.js | 2 ++ views/pages/globalmanagesettings.pug | 5 +++++ views/pages/managesettings.pug | 5 +++++ 9 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 migrations/1.0.0.js diff --git a/configs/template.js.example b/configs/template.js.example index 4ba7cba2..5cc7c5df 100644 --- a/configs/template.js.example +++ b/configs/template.js.example @@ -24,6 +24,8 @@ module.exports = { url: '' }, + language: 'en', + filters: [], strictFiltering: false, filterMode: 0, diff --git a/controllers/forms/boardsettings.js b/controllers/forms/boardsettings.js index 4283ac74..167f5675 100644 --- a/controllers/forms/boardsettings.js +++ b/controllers/forms/boardsettings.js @@ -7,6 +7,7 @@ const changeBoardSettings = require(__dirname+'/../../models/forms/changeboardse , dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js') , config = require(__dirname+'/../../lib/misc/config.js') , paramConverter = require(__dirname+'/../../lib/middleware/input/paramconverter.js') + , i18n = require(__dirname+'/../../lib/locale/locale.js') , { checkSchema, lengthBody, numberBody, minmaxBody, numberBodyVariable, inArrayBody, arrayInBody } = require(__dirname+'/../../lib/input/schema.js'); @@ -14,7 +15,7 @@ module.exports = { paramConverter: paramConverter({ timeFields: ['ban_duration', 'delete_protection_age'], - trimFields: ['filters', 'moderators', 'tags', 'announcement', 'description', 'name', 'custom_css'], + trimFields: ['filters', 'moderators', 'tags', 'announcement', 'description', 'name', 'custom_css', 'language'], allowedArrays: ['countries'], numberFields: ['lock_reset', 'captcha_reset', 'filter_mode', 'lock_mode', 'message_r9k_mode', 'file_r9k_mode', 'captcha_mode', 'tph_trigger', 'pph_trigger', 'pph_trigger_action', 'tph_trigger_action', 'bump_limit', 'reply_limit', 'max_files', 'thread_limit', 'max_thread_message_length', 'max_reply_message_length', 'min_thread_message_length', @@ -71,6 +72,7 @@ module.exports = { { result: numberBody(req.body.ban_duration, 0), expected: true, error: 'Invalid filter auto ban duration' }, { result: numberBody(req.body.delete_protection_age, 0), expected: true, error: 'Invalid OP thread age delete protection' }, { result: numberBody(req.body.delete_protection_count, 0), expected: true, error: 'Invalid OP thread reply count delete protection' }, + { result: inArrayBody(req.body.language, i18n.getLocales()), expected: true, error: 'Invalid language' }, { result: inArrayBody(req.body.theme, themes), expected: true, error: 'Invalid theme' }, { result: inArrayBody(req.body.code_theme, codeThemes), expected: true, error: 'Invalid code theme' }, ], res.locals.permissions); diff --git a/controllers/forms/globalsettings.js b/controllers/forms/globalsettings.js index 5daacd5e..4c4c6e1e 100644 --- a/controllers/forms/globalsettings.js +++ b/controllers/forms/globalsettings.js @@ -6,6 +6,7 @@ const changeGlobalSettings = require(__dirname+'/../../models/forms/changeglobal , config = require(__dirname+'/../../lib/misc/config.js') , { fontPaths } = require(__dirname+'/../../lib/misc/fonts.js') , paramConverter = require(__dirname+'/../../lib/middleware/input/paramconverter.js') + , i18n = require(__dirname+'/../../lib/locale/locale.js') , { checkSchema, lengthBody, numberBody, minmaxBody, numberBodyVariable, inArrayBody } = require(__dirname+'/../../lib/input/schema.js'); @@ -14,7 +15,7 @@ module.exports = { paramConverter: paramConverter({ timeFields: ['hot_threads_max_age', 'inactive_account_time', 'ban_duration', 'board_defaults_filter_ban_duration', 'default_ban_duration', 'block_bypass_expire_after_time', 'dnsbl_cache_time', 'board_defaults_delete_protection_age'], trimFields: ['captcha_options_grid_question', 'captcha_options_grid_trues', 'captcha_options_grid_falses', 'captcha_options_font', 'allowed_hosts', 'dnsbl_blacklists', 'other_mime_types', - 'highlight_options_language_subset', 'global_limits_custom_css_filters', 'board_defaults_filters', 'filters', 'archive_links', 'reverse_links'], + 'highlight_options_language_subset', 'global_limits_custom_css_filters', 'board_defaults_filters', 'filters', 'archive_links', 'reverse_links', 'language'], numberFields: ['inactive_account_action', 'abandoned_board_action', 'filter_mode', 'auth_level', 'captcha_options_text_wave', 'captcha_options_text_paint', 'captcha_options_text_noise', 'captcha_options_grid_noise', 'captcha_options_grid_edge', 'captcha_options_generate_limit', 'captcha_options_grid_size', 'captcha_options_grid_image_size', 'captcha_options_num_distorts_min', 'captcha_options_num_distorts_max', 'captcha_options_distortion', 'captcha_options_grid_icon_y_offset', 'flood_timers_same_content_same_ip', 'flood_timers_same_content_any_ip', @@ -82,6 +83,7 @@ module.exports = { { result: lengthBody(req.body.ip_header, 0, 100), expected: false, error: 'IP header length must not exceed 100 characters' }, { result: lengthBody(req.body.meta_site_name, 0, 100), expected: false, error: 'Meta site name must not exceed 100 characters' }, { result: lengthBody(req.body.meta_url, 0, 100), expected: false, error: 'Meta url must not exceed 100 characters' }, + { result: inArrayBody(req.body.language, i18n.getLocales()), expected: true, error: 'Invalid language' }, { result: inArrayBody(req.body.captcha_options_type, ['grid', 'grid2', 'text', 'google', 'hcaptcha']), expected: true, error: 'Invalid captcha options type' }, { result: numberBody(req.body.captcha_options_generate_limit, 1), expected: true, error: 'Captcha options generate limit must be a number > 0' }, { result: numberBody(req.body.captcha_options_grid_size, 2, 6), expected: true, error: 'Captcha options grid size must be a number from 2-6' }, diff --git a/migrations/1.0.0.js b/migrations/1.0.0.js new file mode 100644 index 00000000..079842f0 --- /dev/null +++ b/migrations/1.0.0.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = async(db, redis) => { + console.log('Updating db for language settings'); + await db.collection('globalsettings').updateOne({ _id: 'globalsettings' }, { + '$set': { + 'language': 'en', + }, + }); + await db.collection('boards').updateMany({}, { + '$set': { + 'settings.language': 'en', + }, + }); + console.log('Clearing globalsettings cache'); + await redis.deletePattern('globalsettings'); + console.log('Clearing boards cache'); + await redis.deletePattern('board:*'); +}; diff --git a/models/forms/changeglobalsettings.js b/models/forms/changeglobalsettings.js index 14e1fb54..91977d3b 100644 --- a/models/forms/changeglobalsettings.js +++ b/models/forms/changeglobalsettings.js @@ -29,6 +29,7 @@ const { Boards } = require(__dirname+'/../../db/') 'codeThemes': ['scripts'], 'globalLimits.postFiles.max': ['deletehtml', 'custompages'], 'globalLimits.postFilesSize.max': ['deletehtml', 'custompages'], + 'language': ['deletehtml', 'css', 'scripts', 'custompages'], //these will make it easier to keep updated and include objects where any/all property change needs tasks //basically, it expands to all of globalLimits.fieldLength.* or frontendScriptDefault.* //it could be calculated in compareSettings with *, but im just precompiling it now. probably a tiny bit faster not doing it each time @@ -65,6 +66,7 @@ module.exports = async (req, res) => { siteName: trimSetting(req.body.meta_site_name, oldSettings.meta.siteName), url: trimSetting(req.body.meta_url, oldSettings.meta.url), }, + language: trimSetting(req.body.language, oldSettings.language), captchaOptions: { type: trimSetting(req.body.captcha_options_type, oldSettings.captchaOptions.type), generateLimit: numberSetting(req.body.captcha_options_generate_limit, oldSettings.captchaOptions.generateLimit), diff --git a/models/pages/globalmanage/settings.js b/models/pages/globalmanage/settings.js index 3a1067b0..a50fcf27 100644 --- a/models/pages/globalmanage/settings.js +++ b/models/pages/globalmanage/settings.js @@ -3,6 +3,7 @@ const config = require(__dirname+'/../../../lib/misc/config.js') , { fontList } = require(__dirname+'/../../../lib/misc/fonts.js') , { themes, codeThemes } = require(__dirname+'/../../../lib/misc/themes.js') + , i18n = require(__dirname+'/../../../lib/locale/locale.js') , { countryNamesMap, countryCodes } = require(__dirname+'/../../../lib/misc/countries.js'); module.exports = async (req, res) => { @@ -18,6 +19,7 @@ module.exports = async (req, res) => { themes, codeThemes, fontList, + languages: i18n.getLocales(), }); }; diff --git a/models/pages/manage/settings.js b/models/pages/manage/settings.js index 8fffbb04..608926e3 100644 --- a/models/pages/manage/settings.js +++ b/models/pages/manage/settings.js @@ -1,6 +1,7 @@ 'use strict'; const { themes, codeThemes } = require(__dirname+'/../../../lib/misc/themes.js') + , i18n = require(__dirname+'/../../../lib/locale/locale.js') , { countryNamesMap, countryCodes } = require(__dirname+'/../../../lib/misc/countries.js'); module.exports = async (req, res) => { @@ -14,6 +15,7 @@ module.exports = async (req, res) => { countryCodes, themes, codeThemes, + languages: i18n.getLocales(), }); }; diff --git a/views/pages/globalmanagesettings.pug b/views/pages/globalmanagesettings.pug index df67aac5..056603ef 100644 --- a/views/pages/globalmanagesettings.pug +++ b/views/pages/globalmanagesettings.pug @@ -77,6 +77,11 @@ block content .row .label Meta URL input(type='text' name='meta_url' value=settings.meta.url) + .row + .label Language + select(name='language') + each language in languages + option(value=language selected=settings.language === lang) #{language} .row .label Disable Anonymizer File Posting label.postform-style.ph-5 diff --git a/views/pages/managesettings.pug b/views/pages/managesettings.pug index b37bd80b..ffee5196 100644 --- a/views/pages/managesettings.pug +++ b/views/pages/managesettings.pug @@ -71,6 +71,11 @@ block content .row .label Announcement textarea(name='announcement' placeholder='Supports post styling') #{board.settings.announcement.raw} + .row + .label Language + select(name='language') + each language in languages + option(value=language selected=settings.language === lang) #{language} .row .label Theme select(name='theme')