Skip to content

Widget Development [WIP]

Bert Pareyn edited this page Mar 12, 2014 · 20 revisions

The basics

What is a widget

A widget is a modular, reusable piece of functionality that can be added to the page. It consists of an HTML fragment, JavaScript, CSS, i18n bundles and a configuration file.

Why use widgets?

Widgets are reusable, modular pieces of functionality that serve a specific function on the page. You can have multiple instances of a widget (e.g. embedding video). They are specialized which often keeps them small and easier to maintain.

How to use a widget?

Widgets can be used in 2 different ways:

  • Building the page (e.g. show top and left hand navigation, display a content item, ...)
  • Supporting the context of the page (e.g. edit permissions of content, add members to a research group, change your profile picture, ...)

The widget framework

Widget structure

manifest.js

manifest.js is the configuration file specific to the widget. It contains bundle definitions as well as triggers and a reference to the couple html page.

{
    "i18n": {
        "af_ZA": "bundles/af_ZA.properties",
        "ca_ES": "bundles/ca_ES.properties",
        "de_DE": "bundles/de_DE.properties",
        "default": "bundles/default.properties",
        "es_ES": "bundles/es_ES.properties",
        "fr_FR": "bundles/fr_FR.properties",
        "hi_IN": "bundles/hi_IN.properties",
        "nl_NL": "bundles/nl_NL.properties",
        "pl_PL": "bundles/pl_PL.properties",
        "pt_BR": "bundles/pt_BR.properties",
        "sv_SE": "bundles/sv_SE.properties",
        "tr_TR": "bundles/tr_TR.properties",
        "val_ES": "bundles/val_ES.properties",
        "zh_CN": "bundles/zh_CN.properties"
    },
    "trigger": {
        "selectors": [
            ".oae-trigger-upload"
        ],
        "events": [
            "oae.trigger.upload"
        ]
    },
    "src": "upload.html"
}

i18n

i18n specifies the translation files that are available inside of the widget's bundles folder relative to the manifest file. They are standard .properties files.

trigger

trigger defines how the widget can be triggered from within the page. This has as an added advantage that any widget can be lazy-loaded instead of included on page load. There are two different kinds of triggers:

  • selectors are standard classes put on elements inside of the DOM. The widget framework automatically registers the click on these elements and loads the widget. Inside of your widget you will need to bind to this click event (e.g. $(document).on('click', '.oae-trigger-upload', function(ev) {...});).
  • events are standard events that can be fired to trigger the widget. The widget framework automatically picks up on these events and loads the widget. Inside of your widget you will need to bind to this event (e.g. $(document).on('oae.trigger.upload', function(ev) {...});).

src

src is a reference to the widget HTML file relative to the manifest file.

widget.html

widget.html is the HTML file in the root of your widget directory. It is not a conventional HTML file as it does not have the usual html and body tags. They are not required as widgets will be loaded into an already existing HTML page. The widget HTML file contains the HTML that would normally be inserted into the body of the page and includes a link to the CSS and JavaScript included for the widget.

<!-- CSS -->
<link rel="stylesheet" type="text/css" href="css/todo.css" />

<div id="todo-container"><!-- --></div>
<div id="todo-template"><!-- --></div>

<!-- JAVASCRIPT -->
<script type="text/javascript" src="js/todo.js"></script>

widget.css

widget.css is a standard CSS file that contains the styles to be applied to the widget HTML elements. The CSS should always be scoped to the widget to avoid conflicts with other components or widgets in the OAE.

/*!
 * Copyright 2014 Apereo Foundation (AF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

.todo-widget {
    margin: 7px;
}

.todo-widget li.todo-finished {
    text-decoration: line-through;
}

widget.js

widget.js contains all the JavaScript for the widget. The JS file can listen for events to trigger the widget, send out it's own, fetch data through our APIs,... It is recommended that DOM manipulations are scoped to the widget to avoid conflicting with other components and widgets. The $rootel can be used to scope jQuery selectors to a specific container (the root element of the widget).

/*!
 * Copyright 2014 Apereo Foundation (AF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

define(['jquery', 'oae.core'], function($, oae) {

    return function(uid, showSettings, widgetData) {

        // The widget container
        var $rootel = $('#' + uid);

        /**
         * Initialize the todo widget
         */
        var initToDo = function() {

        };

        initToDo();
    };
});

bundles.properties

bundles.properties are standard properties files that list the available keys and their translation. The widget framework will pick up the translations and use them where needed. There are already a bunch of translations available in the global bundles. It is recommended that you check these global bundles (/ui/bundles) first before adding in a new translation in the widget bundle.