FEATURE: allow customizing default timezone for email. (#32964)

1. Changes default email format to llll (eg: Tue, May 8, 2018 2:00 AM)
from 2018-05-08T00:00:00Z UTC which is not nice on the eyes
2. Adds `discourse_local_dates_email_timezone` which allows configuring
default timezone in emails
3. Improved help text on site settings (format / timezone)

---------

Co-authored-by: Gary Pendergast <gary@pento.net>
This commit is contained in:
Sam
2025-05-29 14:17:37 +10:00
committed by GitHub
parent 0142d352a8
commit 2261d3711b
6 changed files with 58 additions and 5 deletions

View File

@ -30,8 +30,10 @@ function addLocalDate(attributes, state, buffer, applyDataAttributes) {
const emailFormat =
state.md.options.discourse.datesEmailFormat || moment.defaultFormat;
const emailTimezone =
state.md.options.discourse.datesEmailTimezone || "Etc/UTC";
attributes.emailPreview = `${dateTime.utc().format(emailFormat)} UTC`;
attributes.emailPreview = `${dateTime.utc().tz(emailTimezone).format(emailFormat)}`;
let token = new state.Token("span_open", "span", 1);
token.attrs = [["class", "discourse-local-date"]];
@ -112,6 +114,7 @@ export function setup(helper) {
helper.registerOptions((opts, siteSettings) => {
opts.datesEmailFormat = siteSettings.discourse_local_dates_email_format;
opts.datesEmailTimezone = siteSettings.discourse_local_dates_email_timezone;
opts.features["discourse-local-dates"] =
!!siteSettings.discourse_local_dates_enabled;

View File

@ -3,4 +3,5 @@ en:
discourse_local_dates_enabled: "Enable the discourse-local-dates feature. This will add support to local timezone aware dates in posts using the [date] element"
discourse_local_dates_default_formats: "Frequently used date time formats, see: <a target='_blank' rel='noopener' href='https://momentjs.com/docs/#/parsing/string-format/'>momentjs string format</a>"
discourse_local_dates_default_timezones: "Default list of timezones, must be a valid <a target='_blank' rel='noopener' href='https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'>TZ</a>"
discourse_local_dates_email_format: "Format used to display a date in emails"
discourse_local_dates_email_format: "Format used to display a date in emails, examples: 'LLLL', 'llll' or 'YYYY-MM-DDTHH:mm:ss[Z]'. see: <a target='_blank' rel='noopener' href='https://momentjs.com/docs/#/parsing/string-format/'>momentjs string format</a>"
discourse_local_dates_email_timezone: "Timezone used to display dates in emails, must be a valid <a target='_blank' rel='noopener' href='https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'>TZ</a>"

View File

@ -1,6 +1,10 @@
plugins:
discourse_local_dates_email_timezone:
default: "Etc/UTC"
client: true
area: "localization"
discourse_local_dates_email_format:
default: "YYYY-MM-DDTHH:mm:ss[Z]"
default: "llll z"
client: true
discourse_local_dates_enabled:
default: true

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddUtcToSetting < ActiveRecord::Migration[7.2]
def up
# we changed the setting so UTC is no longer appended, we append it now in the format
execute <<~SQL
UPDATE site_settings
SET value = value || ' z'
WHERE name = 'discourse_local_dates_email_format'
SQL
end
def down
execute <<~SQL
UPDATE site_settings
SET value = REPLACE(value, ' z', '')
WHERE name = 'discourse_local_dates_email_format'
SQL
end
end

View File

@ -1,7 +1,10 @@
# frozen_string_literal: true
RSpec.describe "Local Dates" do
before { freeze_time DateTime.parse("2018-11-10 12:00") }
before do
SiteSetting.discourse_local_dates_email_format = "YYYY-MM-DDTHH:mm:ss[Z] z"
freeze_time DateTime.parse("2018-11-10 12:00")
end
it "should work without timezone" do
post = Fabricate(:post, raw: <<~MD)

View File

@ -19,6 +19,7 @@ RSpec.describe PrettyText do
describe "emails simplified rendering" do
it "works with default markup" do
SiteSetting.discourse_local_dates_email_format = "YYYY-MM-DDTHH:mm:ss[Z] z"
cooked = PrettyText.cook("[date=2018-05-08]")
cooked_mail =
generate_html(
@ -31,6 +32,7 @@ RSpec.describe PrettyText do
end
it "works with time" do
SiteSetting.discourse_local_dates_email_format = "YYYY-MM-DDTHH:mm:ss[Z] UTC"
cooked = PrettyText.cook("[date=2018-05-08 time=20:00:00]")
cooked_mail =
generate_html(
@ -44,6 +46,7 @@ RSpec.describe PrettyText do
end
it "works with multiple timezones" do
SiteSetting.discourse_local_dates_email_format = "YYYY-MM-DDTHH:mm:ss[Z] UTC"
cooked =
PrettyText.cook(
'[date=2023-05-08 timezone="Europe/Paris" timezones="America/Los_Angeles|Pacific/Auckland"]',
@ -60,8 +63,28 @@ RSpec.describe PrettyText do
expect(PrettyText.format_for_email(cooked)).to match_html(cooked_mail)
end
describe "discourse_local_dates_email_timezone" do
before do
SiteSetting.discourse_local_dates_email_timezone = "Europe/Paris"
SiteSetting.discourse_local_dates_email_format = "llll"
end
it "uses the site setting" do
cooked = PrettyText.cook("[date=2018-05-08]")
cooked_mail =
generate_html(
"Tue, May 8, 2018 2:00 AM",
date: "2018-05-08",
email_preview: "Tue, May 8, 2018 2:00 AM",
)
expect(PrettyText.format_for_email(cooked)).to match_html(cooked_mail)
end
end
describe "discourse_local_dates_email_format" do
before { SiteSetting.discourse_local_dates_email_format = "DD/MM" }
before { SiteSetting.discourse_local_dates_email_format = "DD/MM UTC" }
it "uses the site setting" do
cooked = PrettyText.cook("[date=2018-05-08]")