X-Git-Url: http://sru.miketaylor.org.uk/?a=blobdiff_plain;ds=sidebyside;f=doc%2Fmkws-developer.markdown;h=7f35917728516a4e7946db970a765125255afd67;hb=aa7d7d964ec372c8c58b106db46be7fdbf24e5a6;hp=a621a2b8c993c3f4a10f4157d6400c1ba3ada2d7;hpb=db9816d0aa1265e9ad9565d0531e0d274f249983;p=mkws-moved-to-github.git
diff --git a/doc/mkws-developer.markdown b/doc/mkws-developer.markdown
index a621a2b..7f35917 100644
--- a/doc/mkws-developer.markdown
+++ b/doc/mkws-developer.markdown
@@ -1,16 +1,28 @@
% The MasterKey Widget Set developer's guide
% Mike Taylor
-% 11 August 2014
+% November 2014
+
+
+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, as opposed to just using it, you
-will need the following Debian packages (or their equivalents on your
-operating system):
+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 pandoc yui-compressor libbsd-resource-perl
+ $ 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
@@ -19,42 +31,86 @@ 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`.
-To compile the default templates you'll need to install the stable
-version of Handlebars. Currently it's at 2.0.0 and available by npm:
- $ npm install handlebars@2.0.0 -g
+Concepts
+========
+Code structure
+--------------
-Overview
-========
+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.
-Core concepts
--------------
+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) {
@@ -76,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`).
@@ -89,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
@@ -105,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
@@ -124,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
@@ -132,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
@@ -141,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()` --
@@ -163,15 +221,8 @@ 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.
+ FIXME: either document this or remove it from the API.
* `subwidget(type, overrides, defaults)` --
Returns the HTML of a subwidget of the specified type, which
@@ -186,7 +237,7 @@ be used by the derived widget.
See for example the `Credo` widget defined in the example
area's `mkws-widget-credo.js` file. This uses several
invocations of `subwidget` to create a complex compound widget
- with numerous text, facet and image panes. TODO: rename this
+ with numerous text, facet and image panes. FIXME: rename this
widget and everything related to it.
In addition to these properties and methods of the bare widget object,
@@ -275,7 +326,7 @@ 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.
- - -