Introduce 'Plugins' plugin to embed external services

Change-Id: Iffc71635c27ceec91fc1beef248d79f56adcad17
diff --git a/.gitignore b/.gitignore
index aeb6634..53dd354 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,6 +33,7 @@
 *.sqlite
 *.log
 *.db
+*.plugins.json
 *.old
 .*
 /t/kalamar_user_client.t
diff --git a/Changes b/Changes
index db5a4d0..4e0950e 100755
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-0.39 2020-09-21
+0.39 2020-09-22
         - Add information on secret file to Readme.
         - Change default API endpoint to korap.ids-mannheim.de.
         - Fix label for toggle plugins.
@@ -15,6 +15,8 @@
         - Added query parameter API to plugin server.
         - Minor documentation fix in Koral.
         - Added banner style.
+        - Introduced early 'Plugins' plugin to embed external
+          services.
 
         WARNING: If you relied on the former default API endpoint
           being http://localhost:9999/, this will break your
diff --git a/lib/Kalamar/Plugin/Plugins.pm b/lib/Kalamar/Plugin/Plugins.pm
new file mode 100644
index 0000000..5e2e4a0
--- /dev/null
+++ b/lib/Kalamar/Plugin/Plugins.pm
@@ -0,0 +1,91 @@
+package Kalamar::Plugin::Plugins;
+use Mojo::Base 'Mojolicious::Plugin';
+
+# Register the plugin
+sub register {
+  my ($plugin, $app, $param) = @_;
+
+  # Load parameter from config file
+  if (my $config_param = $app->config('Kalamar-Plugins')) {
+    $param = { %$param, %$config_param };
+  };
+
+  # There are default plugins to be registered
+  if ($param->{default_plugins}) {
+
+    # Read default plugins file
+    my $default = Mojo::File->new($param->{default_plugins});
+    my $json_array = $default->slurp;
+
+    # If any scripts are defined
+    if ($json_array) {
+
+      # TODO:
+      #   Make this CSP (#72) compliant.
+
+      # Add default plugins, if exist
+      $app->content_block(
+        scripts => {
+          inline => "<script>//<![CDATA[\nKorAP.Plugins=" . $json_array . "\n//]]></script>"
+        }
+      );
+    };
+  };
+
+  # TODO:
+  #   Add user registered plugins as a path
+};
+
+
+1;
+
+
+__END__
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+Kalamar::Plugin::Plugins - Register plugins in the user interface
+
+=head1 DESCRIPTION
+
+L<Kalamar::Plugin::Plugins> is an interface to register embedded plugins
+in the Kalamar user interface.
+
+B<WARNING! This is early software and not ready to use!>
+
+=head1 CONFIGURATION
+
+L<Kalamar::Plugin::Plugins> supports the following parameter for the
+C<Kalamar-Plugins> configuration section in the Kalamar configuration:
+
+=over 2
+
+=item B<default_plugins>
+
+Path for default plugins (mandatory for all users) to register in the
+frontend.
+
+=back
+
+=head2 COPYRIGHT AND LICENSE
+
+Copyright (C) 2020, L<IDS Mannheim|http://www.ids-mannheim.de/>
+Author: L<Nils Diewald|http://nils-diewald.de/>
+
+Kalamar is developed as part of the L<KorAP|http://korap.ids-mannheim.de/>
+Corpus Analysis Platform at the
+L<Leibniz Institute for the German Language (IDS)|http://ids-mannheim.de/>,
+member of the
+L<Leibniz-Gemeinschaft|http://www.leibniz-gemeinschaft.de>
+and supported by the L<KobRA|http://www.kobra.tu-dortmund.de> project,
+funded by the
+L<Federal Ministry of Education and Research (BMBF)|http://www.bmbf.de/en/>.
+
+Kalamar is free software published under the
+L<BSD-2 License|https://raw.githubusercontent.com/KorAP/Kalamar/master/LICENSE>.
+
+=cut
diff --git a/package.json b/package.json
index 97bed86..d05776c 100755
--- a/package.json
+++ b/package.json
@@ -2,8 +2,8 @@
   "name": "Kalamar",
   "description": "Mojolicious-based Frontend for KorAP",
   "license": "BSD-2-Clause",
-  "version": "0.39.1",
-  "pluginVersion": "0.2",
+  "version": "0.39.2",
+  "pluginVersion": "0.2.1",
   "engines": {
     "node": ">=6.0.0"
   },
diff --git a/t/plugin/plugins.t b/t/plugin/plugins.t
new file mode 100644
index 0000000..fa5ae91
--- /dev/null
+++ b/t/plugin/plugins.t
@@ -0,0 +1,38 @@
+use Mojo::Base -strict;
+use Test::More;
+use Test::Mojo;
+use Mojo::File qw/tempfile/;
+
+# Test the documentation
+my $t = Test::Mojo->new('Kalamar');
+
+my $temp = tempfile();
+
+$temp->spurt(<<SCRIPT);
+[{
+  'name' : 'Export',
+  'desc' : 'Exports Kalamar results',
+  'embed' : [{
+    'panel' : 'result',
+    'title' : 'exports KWICs and snippets',
+    'icon' : "\uf019",
+    'classes' : ['button-icon','plugin'],
+    'onClick' : {
+      'action' : 'addWidget',
+      'template' : 'http://localhost:7777/res/export.html'
+    }
+  }]
+}]
+SCRIPT
+
+$t->app->plugin('Plugins' => {
+  default_plugins => $temp->to_string
+});
+
+$t->get_ok('/')
+  ->text_is('h1 span', 'KorAP - Corpus Analysis Platform')
+  ->content_like(qr!KorAP\.Plugins\s*=\s*\[!)
+  ->content_like(qr!<script>\/\/<\!\[CDATA\[!)
+  ;
+
+done_testing;