Plugins - NatLibFi/Skosmos GitHub Wiki
Besides changing Skosmos configuration, and modifying the code directly, another option to extend and customize Skosmos is through plugins written in JavaScript.
A plugin consists of a folder, with a unique name. The folder name is also used as the plugin name. Within the folder, there should be a file plugin.json
, which provides information about each plugin's resources. For example:
{
"js": ["widget.js"],
"css": ["stylesheet.css", "anotherfile.css"],
"templates": ["template.html", "anothertemplate.html"],
"callback": ["my_callback"]
}
The js resources are used in the Skosmos template file. These JavaScript files are loaded for every page, and are located near the bottom of the page (i.e. near the </body>
HTML end tag).
The css resources are loaded also for each page by Skosmos template file. The CSS stylesheet files are put within the HTML <head>
section.
The templates resources are loaded for JavaScript, using Handlebars, and the syntax looks like:
<script id="{{ id }}" type="text/x-handlebars-template">
{{ template|raw }}
</script>
The template ID is automatically generated, based on the plugin name, and on the template file name minus the extension. If your plugin name is "acrobata" and the template file name is "privacy.html", the template ID will be "acrobata-privacy".
This is important when you need to use the template in JavaScript. It is also important to note that the extension is extracted simply by creating a substring of the template file name from the position 0
until the first appearance of the .
symbol. So if your template file name contains multiple .
characters, you may have unwanted template ID's.
The callbacks resources are a called for each page loaded.
When you install Skosmos, there should be a folder in the root application folder, called "plugins". Inside this folder you can put your plugin folders. As explained in the previous section, the folder names are used as plugin names as well.
For each request, Skosmos loads the content of each enabled plugins' plugin.json
, and utilises its resources, as explained in the previous section.
Plugins are enabled in the configuration file, config.ttl
. There are two ways to activate plugins. This is explained in the next section.
The first way to activate plugins in Skosmos is globally. This is done via the skosmos:globalPlugins
property in the config.ttl
configuration file.
:config a skosmos:Configuration ;
# ...
skosmos:globalPlugins ( "plugin1" "plugin2" "plugin3" ) .
This will initialize the plugins "plugin1", "plugin2", and "plugin3" for all Skosmos.
The second way to activate plugins, is per vocabulary. This is done via the skosmos:usePlugin
property. This property is not from skosmos:Configuration
, but added to each skosmos:Vocabulary
, zero or multiple times.
:ysa a skosmos:Vocabulary, void:Dataset ;
dc:title "YSA - Yleinen suomalainen asiasanasto"@fi,
"YSA - Allmän tesaurus på finska"@sv,
"YSA - General Finnish thesaurus"@en ;
# ...
void:sparqlEndpoint <http://api.dev.finto.fi/sparql> ;
skosmos:usePlugin "plugin1" ;
skosmos:usePlugin "plugin2" ;
skosmos:sparqlGraph <http://www.yso.fi/onto/ysa/>
.
In the example we have the vocabulary ysa
, being configured in Skosmos to load the plugins plugin1
and plugin2
. These plugins will appear only on the pages of the vocabularies where they were enabled via the skosmos:usePlugin
.
The third way to activate plugins is to use the skosmos:useParamPlugin
property. This can be added to a vocabulary multiple times if needed, which then activates those plugins for the vocabulary and it's concept pages.
:ysa a skosmos:Vocabulary, void:Dataset ;
dc:title "YSA - Yleinen suomalainen asiasanasto"@fi,
"YSA - Allmän tesaurus på finska"@sv,
"YSA - General Finnish thesaurus"@en ;
# ...
void:sparqlEndpoint <http://api.dev.finto.fi/sparql> ;
skosmos:useParamPlugin :messageWidget ;
skosmos:sparqlGraph <http://www.yso.fi/onto/ysa/>
.
:messageWidget a skosmos:ParameterizedPlugin ;
skosmos:usePlugin "awesome-message-widget";
skosmos:parameters [
a schema:PropertyValue ;
schema:propertyID "msg";
Schema:value "Message in Finnish"@fi, "Message in Swedish"@sv, “Default message without language code”;
] ,
[
a schema:PropertyValue ;
schema:propertyID "color" ;
schema:value "#800000" ;
] ,
[
a schema:PropertyValue ;
schema:propertyID "imageUrl" ;
schema:value "http://example.com/media/unicorn.png" ;
] .
This way it is possible to pass parameters to a plugin. The plugin is identified by skosmos:usePlugin
determined for the :messageWidget
resource. Each parameter is identified by schema:propertyID
. It is up to the plugin to interperet these parameters. An example of this can be seen here.
The fourth way to activate plugins is skosmos:vocabularyPlugins
property. skosmos:vocabularyPlugins
can have a list of names of global and vocabulary specific plugins or references to plugin resources e. g. parameterized plugins. skosmos:vocabularyPlugins
orders the execution and rendering of vocabulary-specific and global plugins.
:ysa a skosmos:Vocabulary, void:Dataset ;
dc:title "YSA - Yleinen suomalainen asiasanasto"@fi,
"YSA - Allmän tesaurus på finska"@sv,
"YSA - General Finnish thesaurus"@en ;
# ...
void:sparqlEndpoint <http://api.dev.finto.fi/sparql> ;
skosmos:vocabularyPlugins ( "plugin2" :messageWidget "plugin1" ) ;
skosmos:sparqlGraph <http://www.yso.fi/onto/ysa/>
:messageWidget a skosmos:ParameterizedPlugin ;
If a vocabulary-specific plugin name or resource is listed in skosmos:vocabularyPlugins
, skosmos:usePlugin
is not needed in configuration.
It is recommended to prepare a backup of your installation before installing plugins (as well as updating, patching, etc), or to use a testbed server. You may also want to enable exceptions logging, as well as log to a file, and monitor both the Skosmos log file, as well as the web application and system logs for any unexpected error.
Finally, as some resources load JavaScript and CSS files, comparing the browser console before and after installing a plugin can also be very helpful.
In this simple example, we will display a message above the main area Skosmos, between the top menu, and the area where concepts and the hierarchy tree are displayed.
First, create a folder, for example "acrobata" under the Skosmos/plugins
folder. Also add the plugin.json
file, with the following content.
{
"js": ["widget.js"],
"css": ["stylesheet.css"],
"templates": ["template.html"],
"callback": ["acrobata_message"]
}
Now we will go through each resource file used in this plugin. First the JavaScript file "widget.js".
// declaring a namespace for the plugin
var ACROBATA = ACROBATA || {};
ACROBATA = {
// variables in this namespace won't conflict with other global variables
message_value: "This is an example message.",
// likewise, functoins here also won't conflict with other existing functions
render: function(date) {
var source = $("#acrobata-template").html();
var template = Handlebars.compile(source);
var data = {
message: this.message_value + ". The time is " + date
};
$("#content-top").append(template(data));
// if you want to place plugin below concept or vocabulary info use this instead:
// $('#content-bottom').append(template(data));
}
};
$(function() {
// call a function in the plugin namespace
ACROBATA.render(new Date());
// avoid polluting global namespace, or use meaningful and less likely to collide names
window.acrobata_message = function() {
console.log('This is executed for each page, once loaded');
};
});
This file contains a few best practices for JavaScript, such namespaces. But you are free to implement the code as necessary for your environment.
The code above also contains the callback definition. Right near the end, where we define the global acrobata_message
function. Note that it matches exactly the name of the callback declared. It will be executed for each page that is loaded.
The JavaScript code is also rendering a template, with Handlebars, a JavaScript library for templating. The template file looks as follows.
<h1 class='acrobata_message'>{{ message }}</h1>
The {{ message }}
is replaced by the variable message
passed in the data
map, when the template is eval'ed. Notice how the template ID is created, as explained in the previous sections.
Finally, the stylesheet file.
/*
* Be aware values here may impact other parts of the template. Use
* good names, that won't affect other plugins or the rest of Skosmos.
*/
.acrobata_message {
color: red;
}
Putting it all together, the plugin is complete. We just need to enable it. Modify the config.ttl
file, making sure the globalPlugins
property loads the plugin.
:config a skosmos:Configuration ;
# ...
skosmos:globalPlugins ( "acrobata" ) .
Load Skosmos, and you should now have a custom message being displayed, as well as the callback message in the browser console.
Search for Skosmos plugins created at NatLibFi (they are all named according to the pattern Skosmos-widget-*)