Part of MKWS-330.
[mkws-moved-to-github.git] / doc / mkws-manual.markdown
1 % The MKWS manual: embedded metasearching with the MasterKey Widget Set
2 % Mike Taylor
3 % October 2014
4
5
6 Introduction
7 ============
8
9 There are lots of practical problems in building resource discovery
10 solutions. One of the biggest, and most ubiquitous is incorporating
11 metasearching functionality into existing web-sites -- for example,
12 content-management systems, library catalogues or intranets. In
13 general, even when access to core metasearching functionality is
14 provided by simple web-services such as
15 [Pazpar2](http://www.indexdata.com/pazpar2), integration work is seen
16 as a major part of most projects.
17
18 Index Data provides several different toolkits for communicating with
19 its metasearching middleware, trading off varying degrees of
20 flexibility against convenience:
21
22 * [pz2.js](http://www.indexdata.com/pazpar2/doc/ajaxdev.html) --
23   a low-level JavaScript library for interrogating the
24   [Service Proxy](http://www.indexdata.com/service-proxy/)
25   and
26   [Pazpar2](http://www.indexdata.com/pazpar2/).
27   It allows the HTML/JavaScript programmer
28   to create JavaScript applications to display facets, records,
29   etc. that are fetched from the metasearching middleware.
30
31 * masterkey-ui-core -- a higher-level, complex JavaScript library that
32   uses pz2.js to provide the pieces needed for building a
33   full-featured JavaScript application.
34
35 * MasterKey Demo UI -- an example of a searching application built on
36   top of masterkey-ui-core. Available as a public demo at
37   <http://mk2.indexdata.com/>
38
39 * [MKDru](http://www.indexdata.com/masterkey-drupal) --
40   a toolkit for embedding MasterKey-like searching into
41   [Drupal](https://www.drupal.org/)
42   sites.
43
44 All of these approaches require programming to a greater or lesser
45 extent. Against this backdrop, we introduced
46 [MKWS (the MasterKey Widget Set)](http://mkws.indexdata.com/)
47 -- a set of simple, very high-level HTML+CSS+JavaScript
48 components that can be incorporated into any web-site to provide
49 MasterKey searching facilities. By placing `<div>`s with well-known
50 MKWS classes in any HTML page, the various components of an application
51 can be embedded: search-boxes, results areas, target information, etc.
52
53
54 Simple example
55 ==============
56
57 The following is
58 [a complete MKWS-based searching application](//example.indexdata.com/simple.html):
59
60         <html>
61           <head>
62             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
63             <title>MKWS demo client</title>
64             <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
65             <link rel="stylesheet" href="//mkws.indexdata.com/mkws.css" />
66           </head>
67           <body>
68             <div class="mkws-search"></div>
69             <div class="mkws-results"></div>
70           </body>
71         </html>
72
73 Go ahead, try it! Simply put the above in a file (e.g index.html),
74 drop it into a folder accessible with an ordinary web-server (e.g
75 Apache) and load it in your web browser. Just like that, you have
76 working metasearching.
77
78 How the example works
79 ---------------------
80
81 If you know any HTML, the structure of the file will be familar to
82 you: the `<html>` element at the top level contains a `<head>` and a
83 `<body>`. In addition to whatever else you might want to put on your
84 page, you can add MKWS elements.
85
86 These fall into two categories. First, the prerequisites in the HTML
87 header, which are loaded from the tool site `mkws.indexdata.com`:
88
89 * `mkws-complete.js`
90   contains all the JavaScript needed by the widget-set, including a
91   copy of the jQuery library.
92
93 * `mkws.css`
94   provides the default CSS styling
95
96 Second, within the HTML body, `<div>` elements with special IDs that
97 begin `mkws-` can be provided. These are filled in by the MKWS code,
98 and provide the components of the searching UI. The very simple
99 application above has only two such widgets: a search box and a
100 results area. But more are supported.
101
102 Defining widget elements
103 ========================
104
105 Widget type
106 -----------
107
108 An HTML element is made an MKWS widget by including an MKWS
109 class-name. These names begin `mkws-`: what follows that prefix
110 specifies the type of the widget. The type can be any sequence of
111 alphanumeric characters and hyphens _except_ something beginning
112 `team` -- see below.
113
114 The main widgets are:
115
116 * `mkws-search` -- provides the search box and button.
117
118 * `mkws-results` -- provides the results area, including a list of
119    brief records (which open out into full versions when clicked),
120    paging for large results sets, facets for refining a search,
121    sorting facilities, etc.
122
123 * `mkws-progress` -- shows a progress bar indicating how many of the
124    targets have responded to the search request.
125
126 * `mkws-stat` -- provides a status line summarising the statistics of
127    the various targets.
128
129 * `mkws-switch` -- provides links to switch between a view of the
130    result records and of the targets that provide them. Only
131    meaningful when `mkws-targets` is also provided.
132
133 * `mkws-targets` -- the area where per-target information will appear
134    when selected by the link in the `mkws-switch` area. Of interest
135    mostly for fault diagnosis rather than for end-users.
136
137 * `mkws-lang` -- provides links to switch between one of several
138    different UI languages. By default, English, Danish and German are
139    provided.
140
141 To see all of these working together, just put them all into the HTML
142 `<body>` like so:
143
144         <div class="mkws-switch"></div>
145         <div class="mkws-lang"></div>
146         <div class="mkws-progress"></div>
147         <div class="mkws-search"></div>
148         <div class="mkws-results"></div>
149         <div class="mkws-targets"></div>
150         <div class="mkws-stat"></div>
151
152 The full set of supported widgets is described in the
153 reference guide
154 [below](#widgets).
155
156 Widget team
157 -----------
158
159 In general a set of widgets work together in a team: in the example
160 above, the search-term that the user enters in the `mkws-search`
161 widget is used to generate the set of records that are displayed in
162 the `mkws-results` widget.
163
164 Sometimes, it's desirable to have multiple teams in a single page. A
165 widget can be placed in a named team by giving it (in addition to its
166 main class) a class that begins with `mkws-team-`: what follows that
167 prefix specifies the team that the widget is part of. For example,
168 `<div class="mkws-search mkws-team-aux">` creates a search widget that
169 is part of the `aux` team.
170
171 Widgets that do not have a team specified (as in the examples above)
172 are placed in the team called `AUTO`.
173
174 Old and new-style class-names
175 -----------------------------
176
177 **NOTE.** Versions of MKWS before v1.0 used camel-case class-names:
178 without hyphens and with second and subsequent words capitalised. So
179 instead of `mkws-search`, it used to be `mkwsSearch`. And the classes
180 used to specify team names used an `mkwsTeam_` prefix (with an
181 underscore). So instead of `mkws-team-foo`, it used to be
182 `mkwsTeam_foo`.
183
184 The 1.x series of MKWS releases recognise these old-style class-names
185 as well as the canonical ones, as a facility for backwards
186 compatibility. However, **these old class-names are deprecated, and
187 support will be removed in v2.0**. Existing applications that use them
188 should be upgraded to the new-style class names as soon as convenient.
189
190 Configuring widgets
191 ===================
192
193 Global configuration
194 --------------------
195
196 Many aspects of the behaviour of MKWS can be modified by setting
197 parameters into the `mkws_config` object. So the HTML header looks
198 like this:
199
200         <script type="text/javascript">
201           var mkws_config = {
202             lang_options: [ "en", "da" ]
203             lang: "da",
204             sort_default: "title",
205           };
206         </script>
207         <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
208
209 This configuration restricts the set of available UI languages English
210 and Danish (omitting German), sets the default to Danish (rather than
211 the English), and initially sorts search results by title rather than
212 relevance (though as always this can be changed in the UI).
213
214 The full set of supported configuration settings is described in the
215 reference guide below.
216
217 Per-widget configuration
218 ------------------------
219
220 In addition to the global configuration provided by the `mkws_config`
221 object, individual widgets' behaviour can be configured by providing
222 configuration settings as attributes on their HTML elements. For example,
223 a `records` widget might be restricted to displaying no more than
224 three records by setting the `numrecs` parameter as follows:
225
226         <div class="mkws-records" maxrecs="3">
227
228 Although this works well, HTML validators will consider this element
229 acceptable, since the `maxrecs` attribute is not part of the HTML
230 schema. However, attributes beginning `data-` are always accepted as
231 HTML extensions, much like email headers beginning with
232 `X-`. Therefore, the widget set also recognises configuration
233 attributes prefixed with `data-mkws-`, so:
234
235         <div class="mkws-records" data-mkws-maxrecs="3">
236
237 For first form is more convenient; the second is more correct.
238
239 Because some configuration settings take structured values rather than
240 simple strings, they cannot be directly provided by inline
241 attributes. To allow for this, the special attribute
242 `data-mkws-config`, if provided, is parsed as JSON and its key-value
243 pairs used as configuration settings for the widget in question. For
244 example, the value of `lang_options` is an array of strings specifying
245 which of the supported UI languages should be made available. The
246 following invocation will limit this list to only English and Danish
247 (omitting German):
248
249         <div class="mkws-lang" data-mkws-config='{ "lang_options": [ "en", "da" ] }'></div>
250
251 (Note that, as JSON requires double quotes around all strings, single
252 quotes must be used to contain the entire attribute value.)
253
254
255 Control over HTML and CSS
256 =========================
257
258 More sophisticated applications will not simply place the widgets
259 together, but position them carefully within an existing page
260 framework -- such as a Drupal template, an OPAC or a SharePoint page.
261
262 While it's convenient for simple applications to use a monolithic
263 `mkws-results` area which contains record, facets, sorting options,
264 etc., customised layouts may wish to treat each of these components
265 separately. In this case, `mkws-results` can be omitted, and the
266 following lower-level widgets provided instead:
267
268 * `mkws-facets` -- provides the facets
269
270 * `mkws-ranking` -- provides the options for how records are sorted and
271    how many are included on each page of results.
272
273 * `mkws-pager` -- provides the links for navigating back and forth
274    through the pages of records.
275
276 * `mkws-navi` -- when a search result has been narrowed by one or more
277    facets, this area shows the names of those facets, and allows the
278    selected values to be clicked in order to remove them.
279
280 * `mkws-records` -- lists the actual result records.
281
282 Customisation of MKWS searching widgets can also be achieved by
283 overriding the styles set in the toolkit's CSS stylesheet. The default
284 styles can be inspected in [mkws.css](mkws.css)
285 and overridden in any
286 styles that appears later in the HTML than that file. At the simplest
287 level, this might just mean changing fonts, sizes and colours, but
288 more fundamental changes are also possible.
289
290 To properly apply styles, it's necessary to understand how the HTML is
291 structured, e.g. which elements are nested within which
292 containers. The structures used by the widget-set are described in the
293 reference guide below.
294
295
296 Customised display using Handlebars templates
297 =============================================
298
299 A lot can be done by styling widgets in CSS and changing basic MKWS config
300 options. For further customisation, MKWS allows you to change the markup it
301 outputs for any widget. This is done by overriding the
302 [Handlebars](http://handlebarsjs.com/) template used to generate it. In general
303 these consist of `{{things in double braces}}` that are replaced by values from
304 the system. For details of Handlebars template syntax, see [the online
305 documentation](http://handlebarsjs.com/).
306
307 The templates used by the core widgets can be viewed in [our git
308 repository](http://git.indexdata.com/?p=mkws.git;a=tree;f=src/templates;).
309 Parameters are documented in a comment at the top of each template so
310 you can see what's going where. If all you want to do is add a CSS class to
311 something or change a `span` to a `div` it's easy to just copy the existing
312 template and make your edits.
313
314 Overriding templates
315 --------------------
316
317 To override the template for a widget, include it inline in the document
318 as a `<script>` tag marked with a class of `mkws-template-foo` where foo is the
319 name of the template you want to override (typically the name of the widget).
320 Inline Handlebars templates are distinguished from Javascript via a
321 `type="text/x-handlebars-template"` attribute. For example, to override the
322 pager template you would include this in your document:
323
324         <script class="mkws-template-pager" type="text/x-handlebars-template">
325           ...new Pager template
326         </script>
327
328 The Facet template has a special feature where you can override it on
329 a per-facet basis by adding a dash and the facet name as a suffix eg.
330 `facet-subjects`. (So `class="mkws-template-facet-subjects"`.) When
331 rendering a facet for which no specific template is defined, the code
332 falls back to using the generic facet template, just called `facet`.
333
334 You can also explicitly specify a different template for a particular
335 instance of a widget by providing the name of your alternative
336 (eg. `special-pager`) as the value of the `template` key in the MKWS
337 config object for that widget: for example, `<div class="mkws-pager"
338 template="special-pager"/>`.
339
340 Templates for MKWS can also be
341 [precompiled](http://handlebarsjs.com/precompilation.html). If a precompiled
342 template of the same name is found in the `Handlebars.templates` object, it
343 will be used instead of the default.
344
345 Inspecting metadata for templating
346 ----------------------------------
347
348 MKWS makes requests to the Service Proxy or Pazpar2 that perform the
349 actual searching. Depending on how these are configured and what is
350 available from the targets you are searching there may be more data
351 available than what is presented by the default templates.
352
353 Handlebars offers a convenient log helper that will output the contents of a
354 variable for you to inspect. This lets you look at exactly what is being
355 returned by the back end without needing to use a Javascript debugger. For
356 example, you might prepend `{{log hits}}` to the Records template in order to
357 see what is being returned with each search result in the list. In order for
358 this to work you'll need to enable verbose output from Handlebars which is done
359 by including this line or similar:
360
361         <script>Handlebars.logger.level = 1;</script>
362
363 Internationalisation
364 --------------------
365
366 If you would like your template to use the built in translation functionality,
367 output locale specific text via the mkws-translate helper like so:
368 `{{{mkws-translate "a few words"}}}`.
369
370 Example
371 -------
372
373 Rather than use the toolkit's included AJAX helpers to render record
374 details inline, here's a summary template that will link directly to
375 the source via the address provided in the metadata as the first
376 element of `md-electronic-url`:
377
378         <script class="mkws-template-summary" type="text/x-handlebars-template">
379           <a href="{{md-electronic-url.[0]}}">
380             <b>{{md-title}}</b>
381           </a>
382           {{#if md-title-remainder}}
383             <span>{{md-title-remainder}}</span>
384           {{/if}}
385           {{#if md-title-responsibility}}
386             <span><i>{{md-title-responsibility}}</i></span>
387           {{/if}}
388         </script>
389
390 For a more involved example where markup for multiple widgets is decorated with
391 [Bootstrap](http://getbootstrap.com/) classes and a custom Handlebars helper is
392 employed, take a look at the source of
393 [topic.html](http://example.indexdata.com/topic.html?q=water).
394
395
396 Some Refinements
397 ================
398
399
400 Message of the day
401 ------------------
402
403 Some applications might like to open with content in the area that
404 will subsequently be filled with result-records -- a message of the
405 day, a welcome message or a help page. This can be done by placing an
406 `mkws-motd` division anywhere on the page. It will initially be moved
407 into the `mkws-results` area and displayed, but will be hidden as soon
408 as the first search is made.
409
410
411 Popup results with jQuery UI
412 ----------------------------
413
414 The [jQuery UI library](http://en.wikipedia.org/wiki/JQuery_UI)
415 can be used to construct MKWS applications in which the only widget
416 generally visible on the page is a search box, and the results appear
417 in a popup. The key part of such an application is this invocation of
418 the MKWS jQuery plugin:
419
420         <div class="mkws-search"></div>
421         <div class="mkws-popup" popup_width="1024" popup_height="650">
422           <div class="mkws-results"></div>
423         </div>
424
425 The necessary scaffolding can be seen in an example application,
426 [popup.html](http://example.indexdata.com/popup.html).
427
428 The relevant properties (`popup_width`, etc.) are documented
429 [below](#jquery-ui-popup-invocation)
430 in the reference section.
431
432
433 MKWS target selection
434 =====================
435
436 Introduction
437 ------------
438
439 MKWS accesses targets using the Pazpar2 metasearching engine. Although
440 Pazpar2 can be used directly, using a statically configured set of
441 targets, this usage is unusual. More often, Pazpar2 is fronted by the
442 Service Proxy (SP), which manages authentication, sessions, target
443 selection, etc. This document assumes the SP is used, and explains how
444 to go about making a set of targets (a "library") available, how to
445 connect your MKWS application to that library, and how to choose which
446 of the available targets to use.
447
448 By default MKWS configures itself to use an account on a service
449 hosted by `sp-mkws.indexdata.com`. By default, it sends no
450 authentication credentials, allowing the appropriate account to be
451 selected on the basis of referring URL or IP address.
452
453 If no account has been set up to recognise the referring URL of the
454 application or the IP address of the client, then a default "MKWS
455 Demo" account is used. This account (which can also be explicitly
456 chosen by using the username `mkws`, password `mkws`) provides access
457 to about a dozen free data sources.
458
459 In order to search in a customised set of targets, including
460 subscription resources, it's necessary to create an account with
461 Index Data's hosted Service Proxy, and protect that account with
462 authentication tokens (to prevent unauthorised use of subscription
463 resources).
464
465 Maintaining the library
466 -----------------------
467
468 The Service Proxy accesses sets of targets that are known as
469 "libraries". In general, each customer will have their own library,
470 though some standard libraries may be shared between many customers --
471 for example, a library containing all open-access academic journals.
472 A library can also contain other configuration information, including
473 the set of categories by which targets are classified for the library.
474
475 Libraries are maintained using MKAdmin (MasterKey
476 Admin). Specifically, those used by MKWS are generally maintained on
477 the "MKX Admin" installation at
478 <http://mkx-admin.indexdata.com/console/>
479 In general, Index Data will create a library for each customer, then
480 give the customer a username/password pair that they can use to enter
481 MKAdmin and administrate that library.
482
483 Once logged in, customers can select which targets to include (from
484 the list of several thousand that MKAdmin knows about), and make
485 customer-specific modifications to the target profiles --
486 e.g. overriding the titles of the targets.
487
488 Most importantly, customers' administrators can add authentication
489 credentials that the Service Proxy will use on their behalf when
490 accessing subscription resources -- username/password pairs or proxies
491 to use for IP-based authentication. Note that **it is then crucial to
492 secure the library from use by unauthorised clients**, otherwise the
493 customer's paid subscriptions will be exploited.
494
495 Access to libraries is managed by creating one or more "User Access"
496 records in MKAdmin, under the tab of that name. Each of these records
497 provides a combination of credentials and other data that allow an
498 incoming MKWS client to be identified as having legitimate access to
499 the library. The authentication process, described below, works by
500 searching for a matching User Access record.
501
502
503 Authenticating your MWKS application onto the library
504 -----------------------------------------------------
505
506 Some MKWS applications will be content to use the default library with
507 its selection of targets. Most, though, will want to define their own
508 library providing a different range of available targets. An important
509 case is that of applications that authenticate onto subscription
510 resources by means of back-end site credentials stored in MKAdmin:
511 precautions must be taken so that such library accounts do not allow
512 unauthorised access.
513
514 Setting up such a library is a process of several stages.
515
516 ### Create the User Access account
517
518 Log in to MKAdmin to add a User Access account for your library:
519
520 * Go to <http://mkx-admin.indexdata.com/console/>
521 * Enter the adminstrative username/password
522 * Go to the User Access tab
523 * Create an end-user account
524 * Depending on what authentication method it be used, set the
525   User Access account's username and password, or referring URL, or
526   IP-address range.
527
528 If your MWKS application runs at a well-known, permanent address --
529 <http://yourname.com/app.html>, say -- you can set the User Access
530 record so that this originating URL is recognised by setting it into
531 the "Referring URL" field. Then the application will always use that
532 library that this User Access record is associated with (unless it
533 sends a username/password pair to override this default).
534
535 Or if your application's users are coming from a well-known range of
536 IP-address space, you can enter the range in the "IP Ranges"
537 field. The format of this field is as follows: it can contain any
538 number of ranges, separated by commas; each range is either a single
539 IP address or two addresses separated by a hyphen; each IP address is
540 four small integers separated by periods. For example,
541 `80.229.143.255-80.229.143.255, 5.57.0.0-5.57.255.255, 127.0.0.1`.
542
543 Alternatively, your application can authenticate by username and
544 password credentials. This is a useful approach in several situations,
545 including when you need to specify the use of a different library from
546 usual one. To arrange for this, set the username and password as a
547 single string separated by a slash -- e.g. `mike/swordfish` -- into
548 the User Access record's Authentication field.
549
550 You can set multiple fields into a single User Access record; or
551 create multiple User Access records. For example, a single User Access
552 record can specify both a Referring URL and a username/password pair
553 that can be used when running an application from a different URL. But
554 if multiple Referring URLs are needed, then each must be specified in
555 its own User Access record.
556
557 ### (Optional): embed credentials for access to the library
558
559 When credential-based authentication is in use (username and
560 password), it's necessary to pass these credentials into the Service
561 Proxy when establishing the session. This is done 
562 by providing the `sp_auth_credentials` configuration setting as a string
563 containing the username and password separated by a slash:
564
565         mkws_config = { sp_auth_credentials: "mike/swordfish" };
566
567 ### (Optional): conceal credentials from HTML source
568
569 Using credential-based authentication settings such as those above
570 reveals the the credentials to public view -- to anyone who does View
571 Source on the MKWS application. This may be acceptable for some
572 libraries, but is intolerable for those which provide authenticated
573 access to subscription resources.
574
575 In these circumstances, a different approach is
576 necessary. Referer-based or IP-based authentication may be
577 appropriate. But if these are not possible, then a more elaborate
578 approach can be used to hide the credentials in a web-server
579 configuration that is not visible to users.
580
581 The idea is to make a Service Proxy authentication URL local to the
582 customer, hiding the credentials in a rewrite rule in the local
583 web-server's configuration. Then local mechanisms can be used to limit
584 access to that local authentication URL. Here is one way to do it when
585 Apache2 is the application's web-server, which we will call
586 yourname.com`:
587
588 Step 1: add a rewriting authentication alias to the configuration:
589
590         RewriteEngine on
591         RewriteRule /spauth/ http://sp-mkws.indexdata.com/service-proxy/\
592                 ?command=auth&action=check,login&username=U&password=PW [P]
593
594 Step 2: set the MKWS configuration setting `service_proxy_auth` to
595 `http://yourname.com/spauth/`.
596
597 Step 3: protect access to the local path `http://yourname.com/spauth/`
598 (e.g. using a `.htaccess` file).
599
600
601 Choosing targets from the library
602 ---------------------------------
603
604 MKWS applications can choose what subset of the library's targets to
605 use, by means of several alternative settings on individual widgets or
606 in the `mkws_config` structure:
607
608 * `targets` -- contains a Pazpar2 targets string, typically of the form
609   "pz:id=" or "pz:id~" followed by a pipe-separated list of low-level
610   target IDs.
611   At present, these IDs can take one of two forms, depending on the
612   configuration of the Service Proxy being used: they may be based on
613   ZURLs (so a typical value would be something like
614   `pz:id=josiah.brown.edu:210/innopac|lui.indexdata.com:8080/solr4/select?fq=database:4902`)
615   or they may be UDBs (so a typical value would be something like
616   `pz:id=brown|artstor`)
617
618 * `targetfilter` -- contains a CQL query which is used to find relevant
619   targets from the relvant library. For example,
620   `udb==Google_Images`
621   or
622   `categories=news`
623
624 * `target` -- contains a single UDB, that of the sole target to be
625   used. For example,
626   `Google_Images`.
627   This is merely syntactic sugar for "targetfilter" with the query
628   `udb==NAME`
629
630 For example, a `Records` widget can be limited to searching only in
631 targets that have been categorised as news sources by providing an
632 attribute as follows:
633
634         <div class="mkws-records" targetfilter='categories=news'/>
635
636
637 Reference guide
638 ===============
639
640 Widgets
641 -------
642
643 The following widgets are provided in the core set. (Others can be
644 added: see the [MKWS developers' guide](mkws-developer.html).)
645
646 ----
647 Name              Description
648 ----              -----------
649 `auth-name`       Initially empty, it updates itself to shows the name
650                   of the library that the application is logged in as
651                   when authentication is complete.
652
653 `builder`         A button which, when pressed, analyses the current
654                   settings of the team that it is a part of, and
655                   generates the HTML for an auto-searching element
656                   that will replicate the present search. This HTML is
657                   displayed in an alert box: it is intended that this
658                   widget be subclassed to store the generated widget
659                   definitions in more useful places.
660
661 `button`          The search button. Usually generated a `search`
662                   widget.
663
664 `categories`      Obtains from the Service Proxy a list of the target
665                   categories associated with the library in use, and
666                   displays them in a drop-down list. When a category
667                   is selected, searches are limited to the targets
668                   that are part of that category.
669
670 `config`          This widget has no functionality of its own, but its
671                   configuration is copied up into its team, allowing
672                   it to affect other widgets in the team. This is the
673                   only way to set configuration settings at the team
674                   level.
675
676 `console-builder` Like the `builder` widget, but emits the generated
677                   HTML on the JavaScript console. This exists to
678                   provide an example of how to subclass the `builder`
679                   widget.
680
681 `cover-art`       Displays cover art for a book by searching in
682                   Amazon. Often used with an `autosearch` attribute to
683                   indicate what book to display. For example,
684                   `<div class="mkws-cover-art" autosearch="isbn=1291177124"></div>`
685                   displays cover art for _All Yesterdays: Unique and
686                   Speculative Views of Dinosaurs and Other Prehistoric
687                   Animals_.
688                   For this widget to work, a library that includes the
689                   AmazonBooks target must be used. For example, the
690                   "DEMO AmazonBooks for MKWS" account, which can be
691                   selected with `sp_auth_credentials="mkws-amazon/mkws"`.
692
693 `details`         This widget is generated by the toolkit itself to
694                   hold the full details of records that are initially
695                   listed in summary form.
696
697 `done`            Initially empty, this widget is set to display
698                   "Search complete: found _n_ records" when all
699                   targets have completed their work, either returning
700                   a hit-count or an error. The message displayed can
701                   be changed by overriding the `done` template using
702                   `<script class="mkws-template-done" type="text/x-handlebars-template">`.
703
704 `facet`           A facet that displays the frequency with which a set
705                   of terms occur within a specific field. The specific
706                   field whose contents are analysed must be specified
707                   by the widget's `facet` configuration setting, which
708                   may conveniently be done by means of the
709                   `data-mkws-facet` attribute on the HTML
710                   element. The supported facets are "subject",
711                   "author" and "xtargets" -- the latter a special case
712                   which treats the target providing a record as a
713                   facet. Most often, `facet` widgets are generated
714                   by a `facets` widget, which knows which facets are
715                   required, but they can also be placed individually.
716
717 `facets`          An area that contains a "Facets" heading and several
718                   `facet` widgets. The set of facet widgets generated
719                   is specified by the `facets` configuration setting,
720                   which may be set globally or at the level of the
721                   widget or the team. The value of this configuration
722                   setting is an array of zero or more strings, each
723                   naming a facet.
724
725 `google-image`    A specialisation of the `images` widget which
726                   defaults to the `Google_Images` target.
727
728 `images`          A specialisation of the `records` widget which
729                   defaults to the `images` template. Unlike the default
730                   summary template, this displays an image from the
731                   URL specified by the `md-thumburl` field of each
732                   record.
733
734 `lang`            Provides a selection between the supported set of
735                   languages (which defaults to English, German and
736                   Danish, but can be configured by the `lang`
737                   configuration setting, whose value is an array of
738                   two-letter language codes).
739
740 `log`             Initially empty, this widget accumulates a log of
741                   messages generated by the widget set, similar to
742                   those emitted on the JavaScript console.
743
744 `lolcat`          A specialisation of the `google-image` widget which
745                   defaults to the search-term "kitteh" and
746                   auto-executes.
747
748 `motd-container`  An empty container which the `motd` widget, if any,
749                   is moved into for initial display. Usually generated
750                   as part of the `results` widget.
751
752 `motd`            May be provided, containing content to appear in the
753                   area where records will later appear. It is moved
754                   into this area (the `motd-container` widget) and
755                   initially displayed; then hidden when the first
756                   search is run. It can be used to provide a "message
757                   of the day".
758
759 `navi`            Shows a list of the facets that have been selected,
760                   and allows them to be deselected.
761
762 `pager`           Shows a list of the available pages of results, and
763                   allows the user to navigate to a selected page.
764
765 `per-page`        Provides a dropdown allowing the user to choose how
766                   many records should appear on each page. The
767                   available set of page-sizes can be specified as the
768                   `perpage_options` configuration setting, whose value is
769                   an array of integers. The initial selected value can
770                   be specified by the `perpage_default` configuration setting.
771
772 `progress`        Shows a progress bar which indicates how many of the
773                   targets have responded to the search.
774
775 `query`           The input area for a query. Usually generated a `search`
776                   widget.
777
778 `ranking`         The result-ranking area, consisting of a `sort`
779                   widget and a `per-page` widget. These may instead
780                   be specified separately if preferred.
781
782 `record`          A detailed display of a single record, usually
783                   appearing when the user clicks on a summary
784                   record. This is generated by the `records` widget.
785
786 `records`         The area in which summary records appear. (Clicking
787                   on a summary record make it pop up as a detailed
788                   record.)
789
790 `reference`       A short summary about a subject specified by the
791                   `autosearch` configuration setting. This is created by
792                   drawing a picture and a paragraph of text from
793                   Wikipedia. To work correctly, this widget must be
794                   used in a library that provides the
795                   `wikimedia_wikipedia_single_result` target.
796
797 `results`         A large compound widget used to provide the most
798                   important results-oriented widgets in a pre-packaged
799                   framework: `facets`, `ranking`, `pager`, `navi` and
800                   `records`.
801
802 `search-form`     The search form, containing the query area and the
803                   button. Usually generated a `search` widget.
804
805 `search`          The search box, consisting of a form containing a
806                   query area and a button.
807
808 `sort`            Provides a dropdown allowing the user to choose how
809                   the displayed records should be sorted. The
810                   available set of sort criteria can be specified as the
811                   `sort_options` configuration setting, whose value is
812                   an array of two-element arrays. The first item of
813                   each sub-array is a pazpar2 sort-expression such as
814                   `data:0` and the second is a human-readable label
815                   such as `newest`. The initial selected
816                   value can be specified by the `sort_default` configuration
817                   setting.
818
819 `stat`            A summary line stating how many targets remain
820                   active, how many records have been found, and how
821                   many of them have been retrieved for display. For
822                   most purposes, the `progress` widget may be
823                   preferable.
824
825 `summary`         A short record, included in the list shown when a
826                   search is run. When clicked, this generally pops up
827                   a detailed `record` widget. This widget is generated
828                   by the toolkit in response to search results.
829
830 `switch`          A pair of buttons allowing the user to switch
831                   between viewing the search results (the usual case)
832                   or the target list.
833
834 `targets`         A list of all targets in the present library,
835                   showing their ID, the number of records they have
836                   found for the current search, any diagnostics they
837                   have returned, the number of records that have been
838                   returned for display, and the connection state.
839 ----
840
841
842 Configuration settings
843 ----------------------
844
845 Configuration settings may be provided at the level of a indiviual widget, or a team, or globally. Per-widget configuration is
846 described above; per-team settings can be placed in a `config` widget belonging to the relevant team, and will be applied to that
847 team as a whole; and global settings are provided in the global variable `mkws_config`. This structure is a key-value lookup
848 table, and may specify the values of many settings.
849
850 Some settings apply only to specific widgets; others to the behaviour of the tookit as a whole. When a widget does not itself have
851 a value specified for a particular configuration setting, its team is consulted; and if that also does not have a value, the global
852 settings are consulted. Only if this, too, is unspecified, is the default value used.
853
854 The supported configuration settings are described in the table below. For those settings that apply only to particular widgets,
855 the relevant widgets are listed. All entries are optional, but if specified must be given values of the specified type. Long
856 default values are in footnotes to keep the table reasonably narrow.
857
858 ----
859 Element                   Widget    Type    Default   Description
860 --------                  ------    -----   --------- ------------
861 auth_hostname             _global_  string            If provided, overrides the `pp2_hostname` setting when constructing the
862                                                       Service Proxy authentication URL. This need only be used when authentication
863                                                       is performed on a different host from the remaining operations (search,
864                                                       retrieve, etc.)
865
866 autosearch                facet,    string            If provided, this setting contains a query which is immediately run on behalf
867                           facets,                     of the team. Often used with an [indirect setting](#indirect-settings).
868                           record,
869                           records,
870                           results
871
872 facet                     facet     string            For a `facet` widget, this setting is mandatory, and indicates which field to
873                                                       list terms for. Three fields are supported: `subject`, `author` and
874                                                       `xtargets` -- the latter a special case which treats the target providing a
875                                                       record as a facet. Any other field may also be used, but the default caption
876                                                       and maximum term-count may not be appropriate, needing to be overridden by
877                                                       `facet_caption_*` and `facet_max_*` settings.
878
879 facet_caption_*           facet     string            Specifies what on-screen caption is to be used for the named facet: for
880                                                       example, if a `date` facet is generated, then `facet_caption_date` can be
881                                                       used to set the caption to "Year".
882
883 facet_max_*               facet     int               Specifies how many terms are to be displayed for the named facet: for
884                                                       example, if a `publisher` facet is generated, then `facet_max_publisher` can
885                                                       be used to limit the list to the top six.
886
887 facets                    _team_    array   *Note 1*  Ordered list of names of facets to display.
888
889 lang                      _team_    string            Two-letter ISO code of the default language to display the UI in. Supported
890                                                       language codes are `en` = English, `de` = German, `da` = Danish, and whatever
891                                                       additional languages are configured using `language_*` entries (see below).
892
893 lang_options              lang      array   []        A list of the languages to offer as options. If empty (the default), then all
894                                                       configured languages are listed.
895
896 language_*                _global_  hash              Support for any number of languages can be added by providing entries whose
897                                                       name is `language_` followed by the code of the language. See the separate
898                                                       section below for details.
899
900 limit                     facet,    string            Allows a partial search to be included in the specification of an
901                           facets,                     auto-executing widget. This is ANDed with the submitted query, as though it
902                           record,                     had been selected from a facet. See the Search section in [the Protocol
903                           records,                    chapter of the Pazpar2 manual
904                           results                     ](http://www.indexdata.com/pazpar2/doc/pazpar2_protocol.html)
905
906 log_level                 _global_  int     1         Level of debugging output to emit. 0 = none, 1 = messages, 2 = messages with
907                                                       datestamps, 3 = messages with datestamps and stack-traces.
908
909 maxrecs                   facet,    int               Limits the metasearching middleware to retrieving no more than the specified
910                           facets,                     number of records from each target.
911                           record,
912                           records,
913                           results
914
915 paragraphs                reference int               Limits the number of paragraphs rendered to the specified number. If
916                                                       omitted, there is no limit.
917
918 pazpar2_url               _global_  string            If specified, this is the URL used to access the metasearch middleware. This
919                                                       service must be configured to provide search results, facets, etc. It may be
920                                                       either unmediated Pazpar2 or the MasterKey Service Proxy, which mediates
921                                                       access to an underlying Pazpar2 instance. When not specified, the URL is
922                                                       assembled from `pp2_hostname` and `pp2_path`. See the [Assembling Pazpar2
923                                                       URLs](#assembling-pazpar2-urls) section below.
924
925 perpage                   facet,    int               Specifies the number of records to show per page in an auto-executing
926                           facets,                     widget. Contrast with `perpage_default`, which is used to prime the dropdown
927                           record,                     with which a user chooses the page-size in an interactive session.
928                           records,
929                           results
930
931 perpage_default           _team_    string  20        The initial value for the number of records to show on each page.
932
933 perpage_options           ranking   array   *Note 2*  A list of candidate page sizes. Users can choose between these to determine
934                                                       how many records are displayed on each page of results.
935
936 pp2_hostname              _global_  string  *Note 3*  Unless overridden by the `pazpar2_url` setting, this is used together with
937                                                       `pp2_path` to construct the URL to the Pazpar2 service (or Service
938                                                       Proxy). Set this to connect to a service on a different host from the
939                                                       default.
940
941 pp2_path                  _global_  string  *Note 4*  Unless overridden by the `pazpar2_url` setting, this is used together with
942                                                       `pp2_hostname` to construct the URL to the Pazpar2 service (or Service
943                                                       Proxy). Set this to connect to a service on a different host from the
944                                                       default.
945
946 responsive_design_width   _global_  int               If defined, then the facets display moves between two locations as the
947                                                       screen-width varies. The specified number is the threshhold width, in
948                                                       pixels, at which the facets move between their two locations. The `switch`
949                                                       and `lang` widgets also disappear entirely below this threshhold.
950
951 scan_all_nodes            _global_  bool    false     An internal setting that changes how MKWS scans the HTML documen to discover
952                                                       widgets. If set to true, a different approach is used which may be faster
953                                                       under some circumstances.
954
955 sentences                 reference int               Limits the number of sentences rendered to the specified number. If
956                                                       omitted, there is no limit.
957
958 service_proxy_auth        _global_  url               If defined, this is the URL which, when `use_service_proxy` is true, is
959                                                       fetched once at the beginning of each session to authenticate the user and
960                                                       establish a session that encompasses a defined set of targets to search
961                                                       in. When not defined, the URL is assembled from `auth_hostname` or
962                                                       `pp2_hostname`, `sp_auth_path`, `sp_auth_query` and
963                                                       `sp_auth_credentials`. See the [Assembling Pazpar2
964                                                       URLs](#assembling-pazpar2-urls) section below.
965
966 service_proxy_auth_domain _global_  domain            When the server used for authentication -- e.g. the one identified by the
967                                                       `service_proxy_auth` URL -- proxies for different server, this can be set to
968                                                       the domain of the server that it proxies for, so that cookies are rewritten
969                                                       to appear to be from this domain.
970
971 show_lang                lang       bool    true      Indicates whether or not to display the language menu.
972
973 show_perpage             ranking    bool    true      Indicates whether or not to display the perpage menu.
974
975 show_sort                ranking    bool    true      Indicates whether or not to display the sort menu.
976
977 show_switch              switch     bool    true      Indicates whether or not to display the switch menu.
978
979 sort                      facet,    string            Specifies the order in which to sort the records retrieved by an
980                           facets,                     auto-executing widget. Must be one of those in the `sort_options`
981                           record,                     array. Contrast with `sort_default`, which is used to prime the dropdown
982                           records,                    with which a user chooses the sortorder in an interactive session.
983                           results
984
985 sort_default              _team_    string  relevance The default sort criterion to use. Must be one of those in the
986                                                       `sort_options` array.
987
988 sort_options              ranking   array   *Note 5*  List of supported sort criteria. Each element of the list is itself a
989                                                       two-element list: the first element of each sublist is a pazpar2
990                                                       sort-expression such as `data:0` and the second is a human-readable label
991                                                       such as `newest`.
992
993 sp_auth_credentials       _global_  string            If defined, this must be a slash-separated combination of username and
994                                                       password, which is sent as the authentication credentials on session
995                                                       initialisation. See the [Assembling Pazpar2 URLs](#assembling-pazpar2-urls)
996                                                       section below.
997
998 sp_auth_path              _global_  string  *Note 6*  Part of the URL used for authentication. See the [Assembling Pazpar2
999                                                       URLs](#assembling-pazpar2-urls) section below.
1000
1001 sp_auth_query             _global_  string  *Note 7*  Part of the URL used for authentication. See the [Assembling Pazpar2
1002                                                       URLs](#assembling-pazpar2-urls) section below.
1003
1004 target                    facet,    string            One of three ways to select which targets an auto-searching widgets uses. See
1005                           facets,                     the [Choosing targets from the library](#choosing-targets-from-the-library)
1006                           record,                     section above.
1007                           records,
1008                           results
1009
1010 targetfilter              facet,    string            One of three ways to select which targets an auto-searching widgets uses. See
1011                           facets,                     the [Choosing targets from the library](#choosing-targets-from-the-library)
1012                           record,                     section above.
1013                           records,
1014                           results
1015
1016 targets                   facet,    string            One of three ways to select which targets an auto-searching widgets uses. See
1017                           facets,                     the [Choosing targets from the library](#choosing-targets-from-the-library)
1018                           record,                     section above.
1019                           records,
1020                           results
1021
1022 template                  details,  string            Numerous widgets use Handlebars templates to render HTML. In general, each
1023                           done,                       of these by default uses a template with the same name as the widget
1024                           facet,                      itself. Individual widgets can be customised to use a template of a
1025                           facets,                     different name by means of their `template` setting. The `records` widget
1026                           images,                     (and `record`, an equivalent that shows only a single record) use the
1027                           lang,                       `summary` template as well as the `records` template.
1028                           navi,
1029                           pager,
1030                           progress,
1031                           ranking,
1032                           records,
1033                           reference,
1034                           results,
1035                           search,
1036                           stat,
1037                           switch,
1038                           targets
1039
1040 <!--- The widget called "record" is a special-case of "records"; both also use "summary" -->
1041
1042 text                      builder   string  "Build!"  Specifies what text to use for the Builder button.
1043
1044 use_service_proxy         _global_  bool    true      If true, then a Service Proxy is used to deliver searching services rather
1045                                                       than raw Pazpar2. An authentication phase is run during initialisation.
1046 ----
1047
1048 The `show_lang`, `show_perpage`, `show_sort` and `show_switch` configuration settings are technically redundant, as the relevant
1049 widgets, like all widgets, are displayed only when they are provided. But they are retained as an easier route to lightly
1050 customise the display than by providing a full HTML structure.
1051
1052 ### Notes
1053
1054 1. The default for `facets` is `["xtargets", "subject", "author"]`
1055
1056 2. The default for `perpage_options` is `[10, 20, 30, 50]`
1057
1058 3. The default for `pp2_hostname` is `"sp-mkws.indexdata.com"`
1059
1060 4. The default for `pp2_path` is `"service-proxy"`
1061
1062 5. The default for `sort_options` is `[["relevance"], ["title:1", "title"], ["date:0", "newest"], ["date:1", "oldest"]]`
1063
1064 6. The default for `sp_auth_path` is `"service-proxy/"`.
1065
1066 7. The default for `sp_auth_query` is `"command=auth&action=perconfig"`.
1067
1068 ### Indirect settings
1069
1070 The values of any setting are generally interpreted literally. However, it is possible to specify a value indirectly -- for
1071 example, by reference to a query parameter -- and this is often useful in contexts such as specifying an autosearch query. FIXME
1072 say more.
1073
1074 FIXME !query!q, !path!2, etc.
1075
1076 ### Assembling Pazpar2 URLs
1077
1078 FIXME describe how `pazpar2_url` is assembled from `pp2_hostname` and `pp2_path`; and how `service_proxy_auth` is assembled from
1079 `auth_hostname` or `pp2_hostname`, `sp_auth_path`, `sp_auth_query` and `sp_auth_credentials`.
1080
1081 Language specification
1082 ----------------------
1083
1084 Support for another UI language can be added by providing an entry in
1085 the `mkws_config` object whose name is `language_` followed by the
1086 name of the language: for example, `language_French` to support
1087 French. Then value of this entry must be a key-value lookup table,
1088 mapping the English-language strings of the UI into their equivalents
1089 in the specified language. For example:
1090
1091         var mkws_config = {
1092           language_French: {
1093             "Authors": "Auteurs",
1094             "Subjects": "Sujets",
1095             // ... and others ...
1096           }
1097         }
1098
1099 The following strings occurring in the UI can be translated:
1100 `Displaying`,
1101 `Next`,
1102 `Prev`,
1103 `Records`,
1104 `Search`,
1105 `Sort by`,
1106 `Targets`,
1107 `Facets`,
1108 `and show`,
1109 `found`,
1110 `of`,
1111 `per page`
1112 and
1113 `to`.
1114
1115 In addition, facet names can be translated:
1116 `Authors`,
1117 `Sources`
1118 and
1119 `Subjects`.
1120
1121 Finally, the names of fields in the full-record display can be
1122 translated. These include, but may not be limited to:
1123 `Author`,
1124 `Date`,
1125 `Location`,
1126 `Subject`
1127 and
1128 `Title`.
1129
1130
1131
1132 jQuery UI popup invocation
1133 --------------------------
1134
1135 The MasterKey Widget Set can be invoked in a popup window on top of the page.
1136
1137 Note that when using the `popup` layout, facilities from the jQuery UI
1138 toolkit are used, so it's necessary to include both CSS and JavaScript
1139 from that toolkit. The relevant lines are:
1140
1141         <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
1142         <link rel="stylesheet" type="text/css"
1143               href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
1144
1145         <div class="mkws-search"></div>
1146         <div class="mkws-popup" popup_width="1024" popup_height="650" popup_autoOpen="0">
1147           <div class="mkws-switch"></div>
1148           <div class="mkws-lang"></div>
1149           <div class="mkws-results"></div>
1150           <div class="mkws-targets"></div>
1151           <div class="mkws-stat"></div>
1152         </div>
1153
1154 ----
1155 Element         Type    Default             Description
1156 --------        -----   -------             ------------
1157 popup_width     string  880                 Width of the popup window (if used), in
1158                                             pixels.
1159
1160 popup_height    string  760                 Height of the popup window (if used), in
1161                                             pixels.
1162
1163 popup_button    string  `input.mkwsButton`  A click on this selector will trigger the
1164                                             popup to open
1165
1166 popup_modal     string  0                   Modal confirmation mode. Valid values are 0 or 1
1167
1168 popup_autoOpen  string  1                   Open popup window on load. Valid values are 0 or 1
1169
1170 ----
1171
1172 You can have more than one mkws-popup widgets on a page. Please use a different 
1173 popup_button value to address the right ones.
1174
1175 The structure of the HTML generated by the MKWS widgets
1176 -------------------------------------------------------
1177
1178 In order to override the default CSS styles provided by the MasterKey Widget
1179 Set, it's necessary to understand that structure of the HTML elements that are
1180 generated within the widgets. This knowledge make it possible, for example,
1181 to style each `<div>` with class `term` but only when it occurs inside an
1182 element with class `mkws-facets`, so as to avoid inadvertently styling other
1183 elements using the same class in the non-MKWS parts of the page.
1184
1185 The HTML structure is as follows. As in CSS, #ID indicates a unique identifier
1186 and .CLASS indicates an instance of a class.
1187
1188         #mkwsSwitch
1189           a*
1190         
1191         #mkwsLang
1192           ( a | span )*
1193         
1194         #mkwsSearch
1195           form
1196             input#mkwsQuery type=text
1197             input#mkwsButton type=submit
1198         
1199         #mkwsBlanket
1200           (no contents -- used only for masking)
1201         
1202         #mkwsResults
1203           table
1204             tbody
1205               tr
1206                 td
1207                   #mkwsTermlists
1208                     div.title
1209                     div.facet*
1210                       div.termtitle
1211                       ( a span br )*
1212                 td
1213                   div#mkwsRanking
1214                     form#mkwsSelect
1215                       select#mkwsSort
1216                       select#mkwsPerpage
1217                   #mkwsPager
1218                   #mkwsNavi
1219                   #mkwsRecords
1220                     div.record*
1221                       span (for sequence number)
1222                       a (for title)
1223                       span (for other information such as author)
1224                       div.details (sometimes)
1225                         table
1226                           tbody
1227                             tr*
1228                               th
1229                               td
1230         #mkwsTargets
1231           #mkwsBytarget
1232             table
1233               thead
1234                 tr*
1235                   td*
1236               tbody
1237                 tr*
1238                   td*
1239         
1240         #mkwsStat
1241           span.head
1242           span.clients
1243           span.records
1244
1245 - - -
1246
1247 Copyright (C) 2013-2014 Index Data ApS. <http://indexdata.com>