diff --git a/app/assets/javascripts/main_include.js b/app/assets/javascripts/application.js similarity index 100% rename from app/assets/javascripts/main_include.js rename to app/assets/javascripts/application.js diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb deleted file mode 100644 index 4b040e3bd65..00000000000 --- a/app/assets/javascripts/application.js.erb +++ /dev/null @@ -1,17 +0,0 @@ -<% - -require_asset ("./main_include.js") - -# Include plugin javascripts/handlebars templates -DiscoursePluginRegistry.javascripts.each { |js| require_asset(js) } -DiscoursePluginRegistry.handlebars.each { |hb| require_asset(hb) } - -DiscoursePluginRegistry.each_globbed_asset do |f, ext| - if File.directory?(f) - depend_on(f) - elsif f.to_s.end_with?(".#{ext}") - require_asset(f) - end -end - -%> diff --git a/app/assets/javascripts/plugin-third-party.js.erb b/app/assets/javascripts/plugin-third-party.js.erb new file mode 100644 index 00000000000..f5cd239d59a --- /dev/null +++ b/app/assets/javascripts/plugin-third-party.js.erb @@ -0,0 +1,15 @@ +<% +# Include plugin javascripts/handlebars templates +Discourse.unofficial_plugins.each do |plugin| + plugin.javascript_includes.each { |js| require_asset(js) } + plugin.handlebars_includes.each { |hb| require_asset(hb) } + + plugin.each_globbed_asset do |f, is_dir| + if is_dir + depend_on(f) + else + require_asset(f) + end + end +end +%> diff --git a/app/assets/javascripts/plugin.js.erb b/app/assets/javascripts/plugin.js.erb new file mode 100644 index 00000000000..19e879b2edd --- /dev/null +++ b/app/assets/javascripts/plugin.js.erb @@ -0,0 +1,16 @@ +<% +# Include plugin javascripts/handlebars templates +Discourse.official_plugins.each do |plugin| + plugin.javascript_includes.each { |js| require_asset(js) } + plugin.handlebars_includes.each { |hb| require_asset(hb) } + + plugin.each_globbed_asset do |f, is_dir| + if is_dir + depend_on(f) + else + require_asset(f) + end + end +end + +%> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 0a0d3546239..8cdb11cc514 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -28,6 +28,8 @@ <%= script "vendor" %> <%= script "pretty-text-bundle" %> <%= script "application" %> + <%= script "plugin" %> + <%= script "plugin-third-party" %> <%- if staff? %> diff --git a/config/application.rb b/config/application.rb index 70d4427f773..20fe3f04260 100644 --- a/config/application.rb +++ b/config/application.rb @@ -73,7 +73,7 @@ module Discourse 'admin.js', 'admin.css', 'shiny/shiny.css', 'preload-store.js.es6', 'browser-update.js', 'embed.css', 'break_string.js', 'ember_jquery.js', 'pretty-text-bundle.js', 'wizard.css', 'wizard-application.js', - 'wizard-vendor.js'] + 'wizard-vendor.js', 'plugin.js', 'plugin-third-party.js'] # Precompile all available locales Dir.glob("#{config.root}/app/assets/javascripts/locales/*.js.erb").each do |file| diff --git a/lib/discourse.rb b/lib/discourse.rb index 666c9292f7a..1ac6e1b00d1 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -97,6 +97,7 @@ module Discourse set end + def self.activate_plugins! all_plugins = Plugin::Instance.find_all("#{Rails.root}/plugins") @@ -138,6 +139,14 @@ module Discourse @plugins ||= [] end + def self.official_plugins + plugins.find_all{|p| p.metadata.official?} + end + + def self.unofficial_plugins + plugins.find_all{|p| !p.metadata.official?} + end + def self.assets_digest @assets_digest ||= begin digest = Digest::MD5.hexdigest(ActionView::Base.assets_manifest.assets.values.sort.join) diff --git a/lib/discourse_plugin_registry.rb b/lib/discourse_plugin_registry.rb index d4c82e1e283..1eee3fca072 100644 --- a/lib/discourse_plugin_registry.rb +++ b/lib/discourse_plugin_registry.rb @@ -16,6 +16,10 @@ class DiscoursePluginRegistry attr_accessor :custom_html + def plugins + @plugins ||= [] + end + # Default accessor values def javascripts @javascripts ||= Set.new @@ -93,8 +97,11 @@ class DiscoursePluginRegistry end end + JS_REGEX = /\.js$|\.js\.erb$|\.js\.es6$/ + HANDLEBARS_REGEX = /\.hbs$|\.js\.handlebars$/ + def self.register_asset(asset, opts=nil) - if asset =~ /\.js$|\.js\.erb$|\.js\.es6$/ + if asset =~ JS_REGEX if opts == :admin self.admin_javascripts << asset else @@ -111,9 +118,7 @@ class DiscoursePluginRegistry self.stylesheets << asset end - elsif asset =~ /\.hbs$/ - self.handlebars << asset - elsif asset =~ /\.js\.handlebars$/ + elsif asset =~ HANDLEBARS_REGEX self.handlebars << asset end end diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index c1f9660c37c..199c3af0359 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -393,6 +393,37 @@ JS end end + def handlebars_includes + assets.map do |asset, opts| + next if opts == :admin + next unless asset =~ DiscoursePluginRegistry::HANDLEBARS_REGEX + asset + end.compact + end + + def javascript_includes + assets.map do |asset, opts| + next if opts == :admin + next unless asset =~ DiscoursePluginRegistry::JS_REGEX + asset + end.compact + end + + def each_globbed_asset + if @path + # Automatically include all ES6 JS and hbs files + root_path = "#{File.dirname(@path)}/assets/javascripts" + + Dir.glob("#{root_path}/**/*") do |f| + if File.directory?(f) + yield [f,true] + elsif f.to_s.ends_with?(".js.es6") || f.to_s.ends_with?(".hbs") + yield [f,false] + end + end + end + end + protected def register_assets! diff --git a/lib/plugin/metadata.rb b/lib/plugin/metadata.rb index f154d2a2e27..bcf8954d2bd 100644 --- a/lib/plugin/metadata.rb +++ b/lib/plugin/metadata.rb @@ -2,8 +2,34 @@ module Plugin; end class Plugin::Metadata + + OFFICIAL_PLUGINS = Set.new([ + "customer-flair", + "discourse-adplugin", + "discourse-akismet", + "discourse-backup-uploads-to-s3", + "discourse-cakeday", + "Canned Replies", + "discourse-data-explorer", + "discourse-details", + "discourse-nginx-performance-report", + "discourse-push-notifications", + "discourse-slack-official", + "discourse-solved", + "Spoiler Alert!", + "staff-notes", + "GitHub badges", + "hosted-site", + "lazyYT", + "logster-rate-limit-checker", + "poll", + "discourse-plugin-linkedin-auth", + "discourse-plugin-office365-auth", + "discourse-oauth2-basic" + ]) + FIELDS ||= [:name, :about, :version, :authors, :url, :required_version] - attr_accessor *FIELDS + attr_accessor(*FIELDS) def self.parse(text) metadata = self.new @@ -13,6 +39,10 @@ class Plugin::Metadata metadata end + def official? + OFFICIAL_PLUGINS.include?(name) + end + def parse_line(line) line = line.strip diff --git a/spec/components/plugin/metadata_spec.rb b/spec/components/plugin/metadata_spec.rb index 4f8783b0d64..44b509a0b61 100644 --- a/spec/components/plugin/metadata_spec.rb +++ b/spec/components/plugin/metadata_spec.rb @@ -24,4 +24,31 @@ TEXT end end + def official(name) + metadata = Plugin::Metadata.parse <