From 0b8d0a14d789b9a9fcd14e41e231546debf3a046 Mon Sep 17 00:00:00 2001 From: Martin Brennan Date: Fri, 28 Jan 2022 13:02:02 +1000 Subject: [PATCH] DEV: Add markdown_additional_options to Site (#15738) Sometimes plugins need to have additional data or options available when rendering custom markdown features/rules that are not available on the default opts.discourse object. These additional options should be namespaced to the plugin adding them. ``` Site.markdown_additional_options["chat"] = { limited_pretty_text_markdown_rules: [] } ``` These are passed down to markdown rules on opts.discourse.additionalOptions. The main motivation for adding this is the chat plugin, which currently stores chat_pretty_text_features and chat_pretty_text_markdown_rules on the Site object via additions to the serializer, and the Site object is not accessible to import via markdown rules (either through Site.current() or through container.lookup). So, to have this working for both front + backend code, we need to attach these additional options from the Site object onto the markdown options object. --- app/assets/javascripts/discourse/app/lib/text.js | 1 + .../javascripts/pretty-text/addon/pretty-text.js | 2 ++ app/models/site.rb | 14 ++++++++++++++ app/serializers/site_serializer.rb | 7 ++++++- lib/pretty_text.rb | 1 + spec/requests/api/schemas/json/site_response.json | 3 +++ 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/discourse/app/lib/text.js b/app/assets/javascripts/discourse/app/lib/text.js index 6e7def0ecdb..635a5c44b2a 100644 --- a/app/assets/javascripts/discourse/app/lib/text.js +++ b/app/assets/javascripts/discourse/app/lib/text.js @@ -23,6 +23,7 @@ function getOpts(opts) { formatUsername, watchedWordsReplace: context.site.watched_words_replace, watchedWordsLink: context.site.watched_words_link, + additionalOptions: context.site.markdown_additional_options, }, opts ); diff --git a/app/assets/javascripts/pretty-text/addon/pretty-text.js b/app/assets/javascripts/pretty-text/addon/pretty-text.js index 6654f9cc244..80138a7ab39 100644 --- a/app/assets/javascripts/pretty-text/addon/pretty-text.js +++ b/app/assets/javascripts/pretty-text/addon/pretty-text.js @@ -40,6 +40,7 @@ export function buildOptions(state) { watchedWordsLink, featuresOverride, markdownItRules, + additionalOptions, } = state; let features = {}; @@ -80,6 +81,7 @@ export function buildOptions(state) { watchedWordsLink, featuresOverride, markdownItRules, + additionalOptions, }; // note, this will mutate options due to the way the API is designed diff --git a/app/models/site.rb b/app/models/site.rb index d8ba6cf083c..4442a12e272 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -7,6 +7,20 @@ class Site cattr_accessor :preloaded_category_custom_fields self.preloaded_category_custom_fields = Set.new + ## + # Sometimes plugins need to have additional data or options available + # when rendering custom markdown features/rules that are not available + # on the default opts.discourse object. These additional options should + # be namespaced to the plugin adding them. + # + # ``` + # Site.markdown_additional_options["chat"] = { limited_pretty_text_markdown_rules: [] } + # ``` + # + # These are passed down to markdown rules on opts.discourse.additionalOptions. + cattr_accessor :markdown_additional_options + self.markdown_additional_options = {} + def self.add_categories_callbacks(&block) categories_callbacks << block end diff --git a/app/serializers/site_serializer.rb b/app/serializers/site_serializer.rb index c65628748f3..7b16d6f1a64 100644 --- a/app/serializers/site_serializer.rb +++ b/app/serializers/site_serializer.rb @@ -32,7 +32,8 @@ class SiteSerializer < ApplicationSerializer :custom_emoji_translation, :watched_words_replace, :watched_words_link, - :categories + :categories, + :markdown_additional_options ) has_many :archetypes, embed: :objects, serializer: ArchetypeSerializer @@ -203,6 +204,10 @@ class SiteSerializer < ApplicationSerializer object.categories.map { |c| c.to_h } end + def markdown_additional_options + Site.markdown_additional_options + end + private def ordered_flags(flags) diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index a5885ce22d6..558a1880ea6 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -201,6 +201,7 @@ module PrettyText __optInput.censoredRegexp = #{WordWatcher.word_matcher_regexp(:censor)&.source.to_json}; __optInput.watchedWordsReplace = #{WordWatcher.word_matcher_regexps(:replace).to_json}; __optInput.watchedWordsLink = #{WordWatcher.word_matcher_regexps(:link).to_json}; + __optInput.additionalOptions = #{Site.markdown_additional_options.to_json}; JS if opts[:topic_id] diff --git a/spec/requests/api/schemas/json/site_response.json b/spec/requests/api/schemas/json/site_response.json index b1a2a0c325b..a65eea3cf67 100644 --- a/spec/requests/api/schemas/json/site_response.json +++ b/spec/requests/api/schemas/json/site_response.json @@ -466,6 +466,9 @@ "null" ] }, + "markdown_additional_options" : { + "type": "object" + }, "categories": { "type": "array", "items": [