X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=doc%2Fmkws-developer.markdown;h=a299eeb79bd28cee3891093c52af189dbf6b62c0;hb=461e26cfa97d511db70fafb89c889dbb089ac7b2;hp=d4e81622d4d1a336fa13b2073e3ff103332d88c2;hpb=0f5159cbaf1ab368b62f2ac2c041d1f8792c6d13;p=mkws-moved-to-github.git diff --git a/doc/mkws-developer.markdown b/doc/mkws-developer.markdown index d4e8162..a299eeb 100644 --- a/doc/mkws-developer.markdown +++ b/doc/mkws-developer.markdown @@ -1,38 +1,116 @@ % The MasterKey Widget Set developer's guide % Mike Taylor -% 11 August 2014 +% November 2014 -Overview +Introduction +============ + +This manual is for people who want to build the widget set from +source, develop the widget set's core code, or (more likely) create +their own widgets as extensions to the main set. + +Those who want to use existing widgets should read +[The MKWS manual: embedded metasearching with the MasterKey Widget +Set](mkws-manual.html) instead. + + +Required development tools +========================== + +If you are building the widget set, you will need the following Debian +packages (or their equivalents on your operating system): + + $ sudo apt-get install curl git make unzip apache2 \ + pandoc yui-compressor libbsd-resource-perl + +You also need Node.js, but unfortunately the `node-js` package is not +available for Debian wheezy. You can either get it from +wheezy-backports or download the source from +http://nodejs.org/download/ and build it yourself. You need both Node +itself and its package manager NPM: `make install` puts them into +`/usr/local/bin`. + + +Concepts ======== -Core concepts -------------- +Code structure +-------------- + +The code of the widget set is in four main layers, described here from +the bottom up: + +1. The core code, which manages the set of widget teams, default +options, authentication onto the Service Proxy, and the creation of +widgets from HTML elements. +This code is in `mkws-core.js` + +2. The team code, which manages teams of widgets. This is responsible +for the collections of widgets that make up teams, event queues, and +handling search-and-retrieval events +This code is in `mkws-team.js` + +3. The generic widget code, which handles the creation of widget +objects, parsing configuration attributes from their HTML elements, +and firing off automatic searches. + +4. The code for individual widgets, which is specific to those +widgets. It often involves subscribing to events and responding to +them by setting the HTML of the widget element, but need not do +so. The code for many of the most important widgets is in +`mkws-widget-main.js`, but certain other widgets are defined in other +files beginning with the prefix `mkws-widget-`. + +In addition to this code, there are several source files containing +support code: + +* `mkws-filter.js` contains support routine implementing the +filter-set data structure, which contains information about which +filters (e.g. by target, or by facet) are in force. + +* `mkws-handlebars.js` contains Handlebars helpers which can be used +by the HTML templates. + +* `mkws-popup.js` defines a special widget for creating popup + windows. These may, but need not, contain other MKWS widgets, + forming a popup searching application. + +The final component of the source code is the set of Handlebars +templates, in the `templates` directory, which are used to emit the +HTML of the various widgets' contents. These are compiled into the +file `mkws-templates.js`. + + + +Defining new types of widget +---------------------------- Development with MKWS consists primarily of defining new types of -widgets. These can interact with the core functionality is several -defined ways. +widgets. This is done using exactly the same API as the the widgets +that come as part of the set: they have no privileged access. You create a new widget type by calling the `mkws.registerWidgetType` function, passing in the widget name and a function. The name is used to recognise HTML elements as being widgets of this type -- for -example, if you register a `Foo` widget, elements like -`
` will be widgets of this type. +example, if you register a `foo` widget, elements like +`
` will become widgets of this type. -The function promotes a bare widget object (passed as `this`) into a +The function promotes a bare widget object (which is created by the +core widget code and passed in as `this`) into a widget of the appropriate type. MKWS doesn't use classes or explicit prototypes: it just makes objects that have the necessary behaviours. There are _no_ behaviours that Widgets are obliged to provide: you can make a doesn't-do-anything-at-all widget if you like: - mkws.registerWidgetType('Sluggard', function() {}); + mkws.registerWidgetType('sluggard', function() {}); More commonly, widgets will subscribe to one or more events, so that they're notified when something interesting happens. For example, the -`Log` widget asks to be notified when a `log` event happens, and +`log` widget asks to be notified when a `log` event happens, and appends the logged message to its node, as follows: - mkws.registerWidgetType('Log', function() { + mkws.registerWidgetType('log', function() { var that = this; this.team.queue("log").subscribe(function(teamName, timestamp, message) { @@ -54,11 +132,11 @@ This simple widget illustrates several important points: * You can add functionality to a widget by subscribing it to an event's queue using `this.team.queue("EVENT").subscribe`. The argument is a function which is called whenever the event is - published. The arguments to the function are different for different - events. + published. The arguments to the event-callback function are + different for different events. * As with so much JavaScript programming, the value of the special - variable `this` is lost inside the `subscribez` callback function, + variable `this` is lost inside the `subscribe` callback function, so it must be saved if it's to be used inside that callback (typically as a local variable named `that`). @@ -67,13 +145,13 @@ Widget specialisation (inheritance) ----------------------------------- Many widgets are simple specialisations of existing widgets. For -example, the `Record` widget is the same as the `Records` widget -except that it defaults to displaying a single record. It's defined as -follows: +example, the `images` widget is the same as the `records` widget +except that it defaults to using the `images` template for displaying +its result list. It's defined as follows: - mkws.registerWidgetType('Record', function() { - mkws.promotionFunction('Records').call(this); - if (!this.config.maxrecs) this.config.maxrecs = 1; + mkws.registerWidgetType('images', function() { + mkws.promotionFunction('records').call(this); + if (!this.config.template) this.config.template = 'images'; }); Remember that when a promotion function is called, it's passed a base @@ -83,11 +161,11 @@ that you want to specialise from -- in this case, `Records` -- using the promotion function that's been registered for that type. Once this has been done, the specialisations can be introduced. In -this case, it's a very simple matter of changing the `maxrecs` -configuration setting to 1 unless it's already been given an explicit -value. (That would occur if the HTML used an element like `
`, though it's not obvious why anyone -would do that.) +this case, it's a very simple matter of changing the `template` +configuration setting to `'images'` unless it's already been given an +explicit value. (That would occur if the HTML used an element like +`
` to use a customised +template. Reference Guide @@ -102,7 +180,8 @@ that is passed into `registerWidgetType`'s callback function, and can be used by the derived widget. * `String this.type` -- - A string containing the type of the widget. + A string containing the type of the widget (`search`, + `switch`, etc.) * `Team this.team` -- The team object to which this widget belongs. The team has @@ -110,7 +189,8 @@ be used by the derived widget. below. * `DOMElement this.node` -- - The DOM element of the widget + The DOM element of the widget. Most often used for inserting + HTML into the widget element. * `Hash this.config` -- A table of configuration values for the widget. This table @@ -119,7 +199,7 @@ be used by the derived widget. inherits from the default configuration. Instances of widgets in HTML can set configuration items as HTML attributes: for example, the HTML element - `
`. + `
` creates a widget for which `this.config.maxrecs` is set to 10. * `String this.toString()` -- @@ -141,24 +221,23 @@ be used by the derived widget. widgets such as `Records` and `Facet` that display some part of a search result. -* `VOID hideWhenNarrow()` -- - Registers that this widget should hide itself when the page - becomes "narrow" -- that is, fewer pixels in width that the - threshhold value specified by the top-level configuration item - `responsive_design_width`. Should be used for "unimportant" - widgets that can be omitted from the mobile version of a site. - -* `expandValue()` -- - TODO: either document this or remove it from the API. - -* TODO subwidget() +* `subwidget(type, overrides, defaults)` -- + Returns the HTML of a subwidget of the specified type, which + can then be inserted into the widget using the + `this.node.html` function. The subwidget is given the same + attributes at the parent widget that invokes this function, + except where overrides are passed in. If defaults are also + provided, then these are used when the parent widget provides + no values. Both the `overrides` and `defaults` arguments are + hashes: the latter is optional. This can be used to assemble + compound widgets containing several subwidgets. In addition to these properties and methods of the bare widget object, some kinds of specific widget add other properties of their own. For -example, the `Builder` widget uses a `callback` property as the +example, the `builder` widget uses a `callback` property as the function that it use to publish the widget definition that it constructs. This defaults to the builtin function `alert`, but can be -overridden by derived widgets such as `ConsoleBuilder`. +overridden by derived widgets such as `console-builder`. Team methods @@ -239,9 +318,9 @@ API should get simpler. Events ------ -TODO: list of events that can be usefully subscribed to. +FIXME: list of events that can be usefully subscribed to. - - - -Copyright (C) 2013-2014 by IndexData ApS, +Copyright (C) 2013-2014 Index Data ApS.