Custom Reports

Introduction

Custom Reports are compiled by invoking an invokable reporter, which contains a series of invocations of custom services (i.e. a service and arguments for its parameters, if any). The report is a hierarchical model (represented in JSON) and it can be rendered in a user-defined format (i.e. MIME type) and as a PDF document: the generation of the PDF is only supported for certain formats for which a dedicated conversion procedure is available. A common choice is to render a report as an HTML page (i.e. text/html).

Editing Invokable Reports

The screenshot below depicts the main user interface for editing the invokable reporters used to compile custom reports. The page can be accessed by authorized users through the Custom Services and Reports item under Tools menu.

The reports tab always contains (on the left) the list of invokable reporters: they are represented through their id, which is in fact the identifier of the configuration used to store the definition of the reporter in the configuration manager it.uniroma2.art.semanticturkey.config.invokablereporter.InvokableReporterStore. As expected, the plus and minus buttons in the header of the list are used to create a new reporter and delete the selected one, respectively.

Once a reporter is selected in the aforementioned list, its details are shown in the panel on the right. Firstly, global information:

The pencil button in the header of the section can be used to edit this information for an existing reporter.

The actual content of the report is generated through a series of service invocations listed in the bottom of the panel. The plus and minus buttons in the header of this list are used to add a new service invocation an delete the selected one, respectively.

Once a service invocation is selected in the aforementioned list, its details are shown in the panel on the right:

The screenshot below depicts the dialog for adding a new service invocation: it is possible to recognize the items above (e.g. label, description, etc.) and the parallel lists (in the bottom of the dialog) to select the service, then choose an operation withing that service and, lastly, the actual parameters. These should be serialized according to the format used in Semantic Turkey's property system: primitives and strings are given as literals, while RDF values are represented in N-Triples syntax (e.g. note <http://www.w3.org/2002/07/owl#Class> in the figure).

Compiling a custom report

The play button in the header of the details section for an invokable reporter allows for compiling a report. The report is displayed without applying the templates to render it, showing the result associated with each section as the JSON value returned by the corresponding service invocation.

The whole report is in fact as a JSON object, in which we can easily recognize the global information associated with the reporter (e.g. label, description, etc.) and an array of sections, each corresponding to a service invocation. These sections contain the information supplied in the service invocation plus the result obtained the actually doing this service invocation.

Rendering a report

The low-level representation discussed in the previous section is mainly useful for development purposes, while the actually consumed report is the rendered one.

The dropdown menu at the bottom allows to choose the rendering format, while the button on its right allows for downloading the rendered report (usually, in a new tab):

A report is rendered to the target mime type (associated with the invokable reporter) in a bottom-up manner:

The templates shall be expressed in the Mustache template language. In particular, ShowVoc uses JMustache, which provides some extensions for Mustache, such as some special variables that can be used in templates. Furthermore, the template engine is configured to consider null values and empty strings as false, for what concerns section enabling.

Without pretending to replace the documentation of Mustache, let us discuss its use with some examples.

Report-level template

Let us image that a report is associated with the following template, which has to be evaluated against a JSON object like the one in the picture above (representing the whole report without rendering) :

<!DOCTYPE html>
<html>
  <body>
    <h1>{{label}}</h1>
    <table>
      {{#sections}}
      <tr>
        <td><b>{{label}}</b></td><td>{{{rendering}}}</td>
      </tr>
      {{/sections}}
      </table>
  </body>
  </html>

The first occurrence of {{label}} is replace by the value of the property label of the root JSON object (in the example, Test Report).

The syntax

{{#sections}}
...
{{/sections}}
      

is used instead to iterate over the items of the value of the property sections, which is an array: the inner portion of the template (shortened as ...) will be evaluated repeatedly, using each item of the array as context object. If we consider the fragment <td><b>{{label}}</b></td><td>{{{rendering}}}</td>, the expressions {{label}} and {{{rendering}}} will be replaced by the values of the homonym properties stored in each section object. The triple braces around rendering (instead of two) are intended to disable HTML escaping (because we want to incorporate the HTML produced when rendering each section)

The end result should be something like the following:

<html>
  <body>
    <h1>Test Report</h1>
    <table>
      <tr>
        <td><b>number of classes</b></td><td>1</td>
      </tr>
    </table>
  </body>
</html>
  

Section-level template

The template associated with each service invocation is evaluated using the JSON object representing the corresponding section as context object.

If the return type of the invoked custom service is a primitive or a string, then a template like the following may suffice:

{{result}}
  

Alternatively, if the returned type is described by complex JSON object or an array, a more complex template is required.

Let us consider a return type like List<AnnotatedValue<IRI>>. The following figure focuses on the result in the section:

In this case, the template associated with the section might be something like the following:

<ul>
  {{#result}}
  <li>
    {{show}} ({{@id}}) - {{resCount}}
  </li>
  {{/result}}
</ul>
  

producing a rendering like the following:

<ul>
  <li>
  EuroVoc (en) (http://eurovoc.europa.eu/100141) - 539
  </li>
  <li>
  7231 economic geography (en) (http://eurovoc.europa.eu/100282) - 33
  </li>
  <li>
  7211 regions of EU Member States (en) (http://eurovoc.europa.eu/100278) - 25
  </li>
</ul>