Skip to content

Commit

Permalink
DEV: Introduce experimental type: objects theme setting (discourse#…
Browse files Browse the repository at this point in the history
…25538)

Why this change?

This commit introduces an experimental `type: objects` theme setting
which will allow theme developers to store a collection of objects as
JSON in the database. Currently, the feature is still in development and
this commit is simply setting up the ground work for us to introduce the
feature in smaller pieces.

What does this change do?

1. Adds a `json_value` column as `jsonb` data type to the `theme_settings` table.
2. Adds a `experimental_objects_type_for_theme_settings` site setting to
   determine whether `ThemeSetting` records of with the `objects` data
   type can be created.
3. Updates `ThemeSettingsManager` to support read/write access from the
   `ThemeSettings#json_value` column.
  • Loading branch information
tgxworld authored Feb 8, 2024
1 parent 8eb4bf0 commit 9f884cd
Show file tree
Hide file tree
Showing 36 changed files with 132 additions and 30 deletions.
21 changes: 19 additions & 2 deletions app/models/theme_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ class ThemeSetting < ActiveRecord::Base

has_many :upload_references, as: :target, dependent: :destroy

TYPES_ENUM =
Enum.new(integer: 0, float: 1, string: 2, bool: 3, list: 4, enum: 5, upload: 6, objects: 7)

validates_presence_of :name, :theme
validates :data_type, numericality: { only_integer: true }
before_validation :objects_type_enabled
validates :data_type, inclusion: { in: TYPES_ENUM.values }
validates :name, length: { maximum: 255 }

after_save :clear_settings_cache
Expand All @@ -24,7 +28,7 @@ def clear_settings_cache
end

def self.types
@types ||= Enum.new(integer: 0, float: 1, string: 2, bool: 3, list: 4, enum: 5, upload: 6)
TYPES_ENUM
end

def self.acceptable_value_for_type?(value, type)
Expand All @@ -37,6 +41,9 @@ def self.acceptable_value_for_type?(value, type)
value.is_a?(TrueClass) || value.is_a?(FalseClass)
when self.types[:list]
value.is_a?(String)
when self.types[:objects]
# TODO: This is a simple check now but we want to validate the default objects agianst the schema as well.
value.is_a?(Array)
else
true
end
Expand All @@ -62,6 +69,15 @@ def self.guess_type(value)
types[:bool]
end
end

private

def objects_type_enabled
if self.data_type == ThemeSetting.types[:objects] &&
!SiteSetting.experimental_objects_type_for_theme_settings
self.data_type = nil
end
end
end

# == Schema Information
Expand All @@ -75,4 +91,5 @@ def self.guess_type(value)
# theme_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# json_value :jsonb
#
2 changes: 1 addition & 1 deletion config/locales/server.ar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ ar:
optimized_link: روابط الصور المحسَّنة سريعة الزوال ولا يجب تضمينها في الرمز البرمجي المصدري للسمة.
settings_errors:
invalid_yaml: "ملف YAML الذي أدخلته غير صالح."
data_type_not_a_number: "نوع الإعداد `%{name}` غير مدعوم. الأنواع المدعومة هي: `integer`، و`bool`، و`list`، و`enum` و`upload`"
data_type_inclusion: "نوع الإعداد `%{name}` غير مدعوم. الأنواع المدعومة هي: `integer`، و`bool`، و`list`، و`enum` و`upload`"
name_too_long: "يوجد إعداد باسم طويل جدًا. الحد الأقصى للطول هو 255"
default_value_missing: "لا توجد قيمة افتراضية للإعداد `%{name}`"
default_not_match_type: "لا تتطابق القيمة الافتراضية للإعداد `%{name}` مع نوعه."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.da.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ da:
optimized_link: Optimerede billedlinks er midlertidige og bør ikke indgå i tema kildekode.
settings_errors:
invalid_yaml: "Leveret YAML er ugyldig."
data_type_not_a_number: "Indstilling`%{name}` typen understøttes ikke. Understøttede typer er `integer`, `bool`, `list`, `enum` og `upload`"
data_type_inclusion: "Indstilling`%{name}` typen understøttes ikke. Understøttede typer er `integer`, `bool`, `list`, `enum` og `upload`"
name_too_long: "Der er en indstilling med et for langt navn. Maksimal længde er 255"
default_value_missing: "Indstilling af `%{name}` har ingen standard værdi"
default_not_match_type: "Indstilling af `%{name}`s standard værdi's type stemmer ikke overens med den type fundet i indstillingerne."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ de:
optimized_link: Optimierte Bildlinks sind flüchtig und sollten nicht in den Theme-Quellcode eingebunden werden.
settings_errors:
invalid_yaml: "Der YAML-Code ist ungültig."
data_type_not_a_number: "Typ der Einstellung `%{name}` wird nicht unterstützt. Unterstützte Typen sind `integer`, `bool`, `list`, `enum` und `upload`"
data_type_inclusion: "Typ der Einstellung `%{name}` wird nicht unterstützt. Unterstützte Typen sind `integer`, `bool`, `list`, `enum` und `upload`"
name_too_long: "Es gibt eine Einstellung mit einem zu langen Namen. Die maximale Länge beträgt 255 Zeichen."
default_value_missing: "Einstellung `%{name}` hat keinen Standardwert."
default_not_match_type: "Bei der Einstellung `%{name}` stimmt der Datentyp des Standardwerts nicht mit dem Datentyp der Einstellung überein."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ en:
optimized_link: Optimized image links are ephemeral and should not be included in theme source code.
settings_errors:
invalid_yaml: "Provided YAML is invalid."
data_type_not_a_number: "Setting `%{name}` type is unsupported. Supported types are `integer`, `bool`, `list`, `enum` and `upload`"
data_type_inclusion: "Setting `%{name}` type is unsupported. Supported types are `integer`, `bool`, `list`, `enum` and `upload`"
name_too_long: "There is a setting with a too long name. Maximum length is 255"
default_value_missing: "Setting `%{name}` has no default value"
default_not_match_type: "Setting `%{name}` default value's type doesn't match with the setting type."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ es:
optimized_link: Los enlaces de imagen optimizados son efímeros y no deben incluirse en el código fuente del tema.
settings_errors:
invalid_yaml: "El YAML provisto no es válido."
data_type_not_a_number: "Tipo de ajuste «%{name}» no soportado. Los tipos soportados son «integer», «bool», «list», «enum» y «upload»"
data_type_inclusion: "Tipo de ajuste «%{name}» no soportado. Los tipos soportados son «integer», «bool», «list», «enum» y «upload»"
name_too_long: "Hay un ajuste con un nombre muy largo. La cantidad máxima de caracteres es 255"
default_value_missing: "El ajuste «%{name}» no tiene valor por defecto"
default_not_match_type: "El tipo de valor por defecto para el ajuste «%{name}» no coincide con el tipo de ajuste."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.fi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ fi:
optimized_link: Optimoidut kuvalinkit ovat lyhytikäisiä, eikä niitä tulisi sisällyttää teeman lähdekoodiin.
settings_errors:
invalid_yaml: "Annettu YAML ei kelpaa"
data_type_not_a_number: "Tietotyypiksi ei ole mahdollista asettaa `%{name}`. Tuettuja tietotyyppejä ovat `integer`, `bool`, `list`, `enum` ja `upload`"
data_type_inclusion: "Tietotyypiksi ei ole mahdollista asettaa `%{name}`. Tuettuja tietotyyppejä ovat `integer`, `bool`, `list`, `enum` ja `upload`"
name_too_long: "Jollain asetuksella on liian pitkä nimi. Enimmäispituus on 255."
default_value_missing: "Asetuksella \"%{name}\" ei ole oletusarvoa"
default_not_match_type: "Asetuksen \"%{name}\" oletusarvo ei sovi asetuksen tyyppiin."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ fr:
optimized_link: Les liens optimisés d'images sont éphémères et ne devraient pas être inclus dans le code source d'un thème.
settings_errors:
invalid_yaml: "Le YAML est invalide"
data_type_not_a_number: "Le type « %{name} » n'est pas supporté. Les types supportés sont « integer », « bool », « list », « enum » et « upload »"
data_type_inclusion: "Le type « %{name} » n'est pas supporté. Les types supportés sont « integer », « bool », « list », « enum » et « upload »"
name_too_long: "Il y a un paramètre avec un nom trop long. Longueur maximum 255"
default_value_missing: "Le paramètre « %{name} » n'a pas de valeur par défaut"
default_not_match_type: "Le type de la valeur par défaut du paramètre « %{name} » ne correspond pas au type du paramètre."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.gl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ gl:
optimized_link: As ligazóns de imaxe optimizadas son efémeras e non deberían ser incluídas no código fonte do tema.
settings_errors:
invalid_yaml: "O YAML proporcionado non é válido."
data_type_not_a_number: "Tipo de axuste `%{name}` non compatible. Os tipos compatibles son `integer`, `bool`, `list`, `enum` e `upload`"
data_type_inclusion: "Tipo de axuste `%{name}` non compatible. Os tipos compatibles son `integer`, `bool`, `list`, `enum` e `upload`"
name_too_long: "Hai un axuste cun nome demasiado longo. A lonxitude máxima é de 255 caracteres"
default_value_missing: "O axuste '%{name}' non ten un valor predefinido"
default_not_match_type: "O tipo de valor predefinido para o axuste `%{name}` non coincide co tipo de axuste."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.he.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ he:
optimized_link: קישורים משופרים לתמונות הם בני חלוף ואין לכלול אותם בקוד המקור של ערכת העיצוב.
settings_errors:
invalid_yaml: "ה־YAML שסופק שגוי."
data_type_not_a_number: "סוג ההגדרה `%{name}` אינו נתמך. הסוגים הנתמכים הם: `integer`,‏ `bool`,‏ `list`,‏ `enum` ו־`upload`"
data_type_inclusion: "סוג ההגדרה `%{name}` אינו נתמך. הסוגים הנתמכים הם: `integer`,‏ `bool`,‏ `list`,‏ `enum` ו־`upload`"
name_too_long: "קיימת הגדרה עם שם ארוך מדי. האורך המרבי הוא 255"
default_value_missing: "להגדרה `%{name}` אין ערך בררת מחדל"
default_not_match_type: "סוג ערך בררת המחדל של ההגדרה `%{name}` אינו תואם לסוג ההגדרה."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.hr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ hr:
optimized_link: Optimizirane veze na slike su prolazne i ne bi trebale biti uključene u izvorni kod teme.
settings_errors:
invalid_yaml: "Zadani YAML je nevažeći"
data_type_not_a_number: "Vrsta postavke `%{name}` nije podržana. Podržane vrste su `integer`, `bool`, `list`, `enum` i `upload`"
data_type_inclusion: "Vrsta postavke `%{name}` nije podržana. Podržane vrste su `integer`, `bool`, `list`, `enum` i `upload`"
name_too_long: "Postoji postavka s predugim imenom. Najveća dopuštena duljina je 255"
default_value_missing: "Postavka `%{name}` nema podrazumijevanu vrijednost."
default_not_match_type: "Tip zadane vrijednosti postavke `%{name}` ne podudara se s postavljenom vrijednošću postavke."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.hu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ hu:
no_multilevels_components: "A gyermektémákat tartalmazó témák nem lehet maguk is gyermektémák"
settings_errors:
invalid_yaml: "A megadott YAML érvénytelen."
data_type_not_a_number: "A `%{name}` típus beállítása nem támogatott. Támogatott típusok: `integer`, `bool`, `list`, `enum` és `upload`."
data_type_inclusion: "A `%{name}` típus beállítása nem támogatott. Támogatott típusok: `integer`, `bool`, `list`, `enum` és `upload`."
name_too_long: "Az egyik beállítás neve túl hosszú. A legnagyobb hossz 255"
default_value_missing: "A(z) „%{name}” beállításnak nincs alapértelmezett értéke."
default_not_match_type: "A(z) „%{name}” beállítás alapértelmezett értékének típusa nem egyezik a beállítás típusával."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.id.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ id:
optimized_link: Tautan gambar yang dioptimalkan bersifat sementara dan tidak boleh disertakan dalam kode sumber tema.
settings_errors:
invalid_yaml: "YAML yang diberikan tidak valid."
data_type_not_a_number: "Pengaturan jenis `%{name}` tidak didukung. Jenis yang didukung adalah `integer`, `bool`, `list`, `enum` dan `upload`"
data_type_inclusion: "Pengaturan jenis `%{name}` tidak didukung. Jenis yang didukung adalah `integer`, `bool`, `list`, `enum` dan `upload`"
name_too_long: "Ada pengaturan dengan nama yang terlalu panjang. Panjang maksimum adalah 255"
default_value_missing: "Pengaturan `%{name}` tidak memiliki nilai bawaan"
default_not_match_type: "Pengaturan jenis nilai bawaan `%{name}` tidak cocok dengan jenis pengaturan."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ it:
optimized_link: I collegamenti ad immagini ottimizzate sono effimeri e non devono essere inclusi nel codice sorgente del tema.
settings_errors:
invalid_yaml: "Il codice YAML fornito non è valido."
data_type_not_a_number: "L'impostazione del tipo `%{name}` non è supportata. I tipi supportati sono `integer`,` bool`, `list`,` enum` e `upload`"
data_type_inclusion: "L'impostazione del tipo `%{name}` non è supportata. I tipi supportati sono `integer`,` bool`, `list`,` enum` e `upload`"
name_too_long: "Una delle impostazioni ha un nome troppo lungo. La lunghezza massima è 255 caratteri"
default_value_missing: "L'impostazione `%{name}` non ha alcun valore predefinito"
default_not_match_type: "L'impostazione del valore predefinito `%{name}` non corrisponde al tipo di impostazione."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ ja:
optimized_link: 最適化された画像のリンクは一時的なリンクであるため、テーマのソースコードに含めるべきではありません。
settings_errors:
invalid_yaml: "入力された YAML は無効です。"
data_type_not_a_number: "設定 `%{name}` の型はサポートされていません。サポートされている型は `integer`、`bool`、`list`、`enum`、`upload` です"
data_type_inclusion: "設定 `%{name}` の型はサポートされていません。サポートされている型は `integer`、`bool`、`list`、`enum`、`upload` です"
name_too_long: "名前が長すぎる設定があります。最大長は 255 です"
default_value_missing: "設定 `%{name}` にデフォルト値がありません"
default_not_match_type: "設定 `%{name}` のデフォルト値の型が設定の型に一致していません。"
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.ko.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ ko:
optimized_link: 최적화된 이미지 링크는 일시적이므로 테마 소스 코드에 포함하지 않아야 합니다.
settings_errors:
invalid_yaml: "제공된 YAML이 유효하지 않습니다."
data_type_not_a_number: "`%{name}` 유형 설정은 지원되지 않습니다. 지원되는 유형은 `integer` , `bool` , `list` , `enum` 및 `upload` 입니다."
data_type_inclusion: "`%{name}` 유형 설정은 지원되지 않습니다. 지원되는 유형은 `integer` , `bool` , `list` , `enum` 및 `upload` 입니다."
name_too_long: "이름이 너무 긴 설정이 있습니다. 최대 길이는 255입니다"
default_value_missing: "`%{name}` 설정에 디폴트값이 없습니다"
default_not_match_type: "`%{name}` 디폴트값 유형 설정이 설정 유형과 일치하지 않습니다."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.lt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ lt:
optimized_link: Optimizuotos vaizdo nuorodos yra trumpalaikės ir neturėtų būti įtrauktos į temos šaltinio kodą.
settings_errors:
invalid_yaml: "Nurodytas YAML negalimas."
data_type_not_a_number: "“%{name}” tipo nustatymas nepalaikomas. Palaikomi tipai yra `integer`, `bool`, `list`, `enum` ir `upload`"
data_type_inclusion: "“%{name}” tipo nustatymas nepalaikomas. Palaikomi tipai yra `integer`, `bool`, `list`, `enum` ir `upload`"
name_too_long: "Yra nustatymas su per ilgu pavadinimu. Maksimalus ilgis yra 255"
default_value_missing: "Nustatymas „%{name}“ neturi numatytosios vertės"
default_not_match_type: "Nustatymas „%{name}“ numatytosios vertės tipas neatitinka nustatymo tipo."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ nl:
optimized_link: Geoptimaliseerde afbeeldingskoppelingen zijn kortstondig en dienen niet in broncode van thema's te worden opgenomen.
settings_errors:
invalid_yaml: "Opgegeven YAML is ongeldig."
data_type_not_a_number: "Type van instelling `%{name}` wordt niet ondersteund. Ondersteunde typen zijn `integer`, `bool`, `list`, `enum` en `upload`."
data_type_inclusion: "Type van instelling `%{name}` wordt niet ondersteund. Ondersteunde typen zijn `integer`, `bool`, `list`, `enum` en `upload`."
name_too_long: "Er is een instelling met een te lange naam. Maximale lengte is 255."
default_value_missing: "Instelling `%{name}` heeft geen standaardwaarde."
default_not_match_type: "Type van standaardwaarde van instelling `%{name}` komt niet overeen met het type van de instelling."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.pl_PL.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pl_PL:
optimized_link: Zoptymalizowane łącza do obrazów są efemeryczne i nie powinny być zawarte w kodzie źródłowym motywu.
settings_errors:
invalid_yaml: "Wprowadzony YAML jest nieprawidłowy"
data_type_not_a_number: "Ustawienie typu `%{name}` nie jest obsługiwane. Poprawne typy to `integer`, `bool`, `list`, `enum` oraz `upload`"
data_type_inclusion: "Ustawienie typu `%{name}` nie jest obsługiwane. Poprawne typy to `integer`, `bool`, `list`, `enum` oraz `upload`"
name_too_long: "Jedno z ustawień ma zbyt długą nazwę. Maksymalna długość to 255 znaków"
default_value_missing: "Ustawienie `%{name}` nie ma domyślnej wartości"
default_not_match_type: "Typ domyślnej wartości ustawienia \"%{name}\" nie odpowiada typowi ustawienia."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.pt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pt:
optimized_link: Os links de imagens otimizadas são efémeros e não devem ser incluídos no código-fonte do tema.
settings_errors:
invalid_yaml: "O YAML fornecido é inválido"
data_type_not_a_number: "A opção `%{name}` tipo não é suportada. Os tipos suportados são `integer`, `bool`, `list`, `enum` e `upload`"
data_type_inclusion: "A opção `%{name}` tipo não é suportada. Os tipos suportados são `integer`, `bool`, `list`, `enum` e `upload`"
name_too_long: "Existe uma configuração com um nome demasiado longo. O tamanho máximo é 255"
default_value_missing: "A configuração `%{name}` não tem um valor predefinido"
default_not_match_type: "O tipo do valor predefinido para a configuração `%{name}` não é igual ao esperado pela configuração."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.pt_BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pt_BR:
optimized_link: Links otimizados de imagem são temporários e não devem ser incluídos no código-fonte do tema.
settings_errors:
invalid_yaml: "O YAML informado é inválido."
data_type_not_a_number: "A configuração do tipo \"%{name}\" não é compatível. Os tipos compatíveis são \"integer\", \"bool\", \"list\", \"enum\" e \"upload\""
data_type_inclusion: "A configuração do tipo \"%{name}\" não é compatível. Os tipos compatíveis são \"integer\", \"bool\", \"list\", \"enum\" e \"upload\""
name_too_long: "Esta é uma configuração com um nome muito longo. O comprimento máximo é de 255"
default_value_missing: "A configuração \"%{name}\" não tem valor padrão"
default_not_match_type: "O tipo de valor padrão da configuração \"%{name}\" não corresponde ao tipo de configuração."
Expand Down
2 changes: 1 addition & 1 deletion config/locales/server.ru.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ ru:
optimized_link: Оптимизированные ссылки на изображения являются эфемерными и не должны включаться в исходный код темы.
settings_errors:
invalid_yaml: "Неверный формат YAML-файла."
data_type_not_a_number: "Тип `%{name}` не поддерживается. Поддерживаются следующие типы: `integer`, `bool`, `list`, `enum` и `upload`."
data_type_inclusion: "Тип `%{name}` не поддерживается. Поддерживаются следующие типы: `integer`, `bool`, `list`, `enum` и `upload`."
name_too_long: "Есть настройка со слишком длинным названием. Максимальная длина — 255 символов."
default_value_missing: "Настройка `%{name}` не имеет значения по умолчанию"
default_not_match_type: "Стандартные значения настройки `%{name}` не соответствуют допустимым типам."
Expand Down
Loading

0 comments on commit 9f884cd

Please sign in to comment.