The publisher is an optional component that runs inside the repository server. Its goal is to retrieve in one remote call the information you want to display on a page. The result is returned as an XML document. The requestable information consists of more than just XML dumps of repository entities, the publisher provides all sorts of extra functionality, such as 'prepared documents' for publishing and diffs between document versions.
A publisher-request takes the form of an XML document which describes the various stuff you want the publisher to return. The remainder of this document describes the format of these XML requests.
The publisher was developed to support the needs of the Daisy Wiki, but can be useful for other applications as well.
This section describes the format of the publisher requests. The responses are not described in much detail, they are easily viewable by trying the requests out on a live Daisy instance. This can, for example, be done by creating a file containing a publisher request and using a tool like wget to send it to the HTTP interface of the publisher, thus like this:
wget --post-file=pubreq.xml --http-user=testuser@1
--http-passwd=testuser http://localhost:9263/publisher/request
A basic, empty publisher request is structured as follows:
<p:publisherRequest
xmlns:p="http://outerx.org/daisy/1.0#publisher"
locale="en-US"
versionMode="live"
exceptions="throw">
[... various publisher requests ...]
</p:publisherRequest>
The reponse of a publisher request is structured as follows:
<p:publisherResponse
xmlns:p="http://outerx.org/daisy/1.0#publisher">
[... responses to the various requests ...]
</p:publisherResponse>
About the attributes on the p:publisherRequest element:
The locale attribute is optional, by default the en-US locale will be used. If the publisher request is executed as part of another publisher request (see p:preparedDocuments), the locale will default to the locale of the 'parent' publisher request.
The versionMode attribute is optional, valid values are live (the default) or last. This attribute indicates which version of a document should be used by default if no explicit version is indicated. If its value is 'last', it will also cause the option 'search_last_version' to be set for various queries (those embedded in documents when requesting a preparedDocument, those executed by p:performQuery or p:forEach). It will also influence the version mode of the navigation tree when using p:navigationTree.
The exceptions attribute is also optional, throw is its default value. Basically this means that if an exception occurs during the processing of the publisher request, it will be thrown. It is also possible to specify inline, in which case the error description will be embedded in the p:publisherResponse element, but no exception will be thrown.
The styleHint attribute (optional, not shown above) will simply be replicated on the p:publisherResponse element. The publisher itself does not interpret the value of this attribute, it can be used by the caller of the publisher to influence the styling process. In the case of the Daisy Wiki, the styleHint attribute can contain the name of an alternative document-styling XSL to use (instead of the default doctype-name.xsl).
A p:document request is used to change the context document. The context document is the document on which the document related requests listed in the next section apply.
Any publisher request element can be nested within p:document.
The p:document request can work in three ways
Using the attributes id, branch (optional), language (optional) and version (optional) the new context document is specified.
The branch and language can be specified either by name or ID. If not specified, they default to the main branch and default language.
The version can be specified as "live" (the default), "last" or an explicit version number.
When this p:document is used in a location where there is already a context document (e.g. from a parent p:document), it is possible to use an attribute called field. The value of this attribute should be the name of a link-type field. This p:document request will then change the context document to the document specified in that link-type field in the current context document. If the current context document does not have such a field, the p:document request will be silently skipped. If the link-type field is a multivalue field, the p:document request will be executed once for each value of the multivalue field. This will then lead to multiple sibling p:document elements in the publisher response.
If you have selected a hierarchical field in the field attribute then you can choose which element of the hierarchical path you wish to use as the new context document. This is done using the hierarchyElement attribute. This attribute accepts integer values and 'all'. If you do not specify the hierarchy element attribute then 'all' will be used by default.
An illustration. Consider the following hierarchy: /domain/kingdom/subkingdom/branch/infrakingdom. Using 2 as hierarchyElement will get you documents at the level of kingdom. Using -2 will get you documents at the level of branch. As you can see the hierarchyElement specification is 1-based. Choosing level 12 will get you absolutely nothing since the hierarchy does not have 12 levels.
When the p:document request is used as child of the p:forEach request (see later), the context document is determined by the current document of the for-each loop.
The p:document request will output a p:document element in the publisherResponse. This element will have attributes describing the exact document variant and version that the context document was changed to.
Evaluates the document against the ACL and returns the result. This request requires no attributes.
Returns whether the user is subscribed for email notifications for this document, the result is a tag like this:
<p:subscriptionInfo subscribed="true|false"/>
This request requires no attributes.
Returns the comments for the current document. Newlines in the comments are replaced with <br/> tags. This request requires no attributes.
Returns the available variants for this document. This request requires no attributes.
p:preparedDocuments is the most important of all publisher requests. It returns the content of the document prepared for publishing. The preparation consists of all sorts of things such as:
The full format of the request is:
<p:preparedDocuments applyDocumentTypeStyling="true|false" publisherRequestSet="..."> <p:navigationDocument id="..." branch="..." language="..."/> </p:preparedDocuments>
The applyDocumentTypeStyling attribute isn't used by the publisher, but is simply replicated in the result. In the Daisy Wiki, its purpose is to indicate whether document type specific styling should be automatically applied.
The publisherRequestSet attribute: see below.
The p:navigationDocument element is optional. If supplied, it enables to annotate "daisy:" links with the target path in the navigation tree.
p:preparedDocuments looks up a new publisher request to be performed on the context document. The publisher request to be used can be determined dynamically (described further on), but by default it is this one:
<p:publisherRequest xmlns:p="http://outerx.org/daisy/1.0#publisher"> <p:prepareDocument/> <p:aclInfo/> <p:subscriptionInfo/> </p:publisherRequest>
This publisher request should (usually) contain a <p:prepareDocument/> element. The p:prepareDocument will be replaced by the Daisy document as XML (d:document), in which the HTML content is inlined and processed (i.e. the things mentioned in the enumeration above). If the content contains an include of another document, then for this included document the publisher will again determine a publisher request to be performed upon it, and execute it. The same happens for each include (recursively). The results of all these publisher requests are inserted in the publisher response in a structure like this:
<p:preparedDocuments applyDocumentTypeSpecificStyling="true|false">
<p:preparedDocument id="1">
<p:publisherResponse>
<d:document ...
</p:publisherResponse>
</p:preparedDocument>
<p:preparedDocument id="2">
<p:publisherResponse>
<d:document ...
</p:publisherResponse>
</p:preparedDocument>
</p:preparedDocuments>
The publisher response of the context document will always end up in the p:preparedDocument element with attribute id="1". If the document includes no other documents, this will be the only p:preparedDocument. Otherwise, for each included document (directly or indirectly), an additional p:preparedDocument element will be present.
So the included documents are not returned in a nested structure, but as a flat list. This allows to perform custom styling on each separate document before nesting them.
On the actual location of an include, a p:daisyPreparedInclude element is inserted, with an id attribute referencing the related p:preparedDocument element.
The content of a p:preparedDocument element is thus a single p:publisherResponse element, which in turns contains a single d:document element (as result of the p:prepareDocument in the publisher request). This d:document element follows the standard form of XML as is otherwise retrieved via the HTTP interface or by using the getXml() method on a document object, but with lots of additions such as inlined content for Daisy-HTML parts and non-string attribute values formatted according to the specified locale.
If you requested the live version of the document, but the document does not have a live version, there will simply be no p:preparedDocuments element in the response.
If instead of the default publisher request mentioned above, you want to execute some custom publisher request (which can be used to retrieve information related to the document being published), then this is possible by defining a publisher request set.
In the data directory of the repository server, you will find a subdirectory called 'pubreqs'. In this directory, each subdirectory specifies a publisher request set. Each such subdirectory should contain a file called mapping.xml and one or more other files containing publisher requests.
The mapping.xml file looks like this:
<m:publisherMapping xmlns:m="http://outerx.org/daisy/1.0#publishermapping"> <m:when test="documentType = 'mydoctype'" use="myrequest.xml"/> <m:when test="true" use="default.xml"/> </m:publisherMapping>
The publisher will run over each of the when rules, and if the expression in the test attribute matches, it will use the publisher request specified in the use attribute. The expressions are the same as used in the query language, and thus also the same as used in the ACL definition.
To make use of such a specific set of publisher requests, you use the publisherRequestSet attribute on the p:preparedDocuments element. The value of this attribute should correspond to the name of subdirectory of the pubreqs directory.
In the Daisy Wiki, the publisher request set to be used can be specified in the siteconf.xml
The p:prepareDocument can have an optional attribute called inlineParts. This attribute specifies a comma-separated list of part type names (or IDs) for which the content should be inlined. By default this only happens for parts for which the Daisy-HTML flag is set to true.
The inlining will only happen if the actual part has a mime-type that starts with "text/" or if the mime-type is recognized as an XML mime-type. Recognized XML mime-types are currently text/xml, application/xml or any mime type ending with "+xml".
If it is an XML mime-type, then the content will be parsed and inserted as XML. Otherwise, it will be inserted as character data (assuming UTF-8 encoding of the part text data). If the inlining actually happened, an attribute inlined="true" is added to the d:part element in question.
Returns the shallow version XML (this the version XML without field and part information in it), thus a "d:version" element. This request requires no attributes.
If you requested the live version of the document, but the document does not have a live version, there will simply be no d:version element in the response.
Returns the document XML with some slight annotations, thus a d:document element. This request requires no attributes.
In contrast with most other elements, if you request the live version of the document but the document doesn't have a live version, this element will automatically fallback to the last version, so there will always be a d:document element in the response.
The p:annoatedDocument element can have an optional attribute called inlineParts, which can have as value "#all" or "#daisyHtml". In case #daisyHtml is specified, the part content of all Daisy-HTML parts will be inlined (though without any processing applied to them). When #all is specified, the content of all parts whose mime-type starts with "text/" will be inline. If it is an XML mimetype, the content is inserted as XML. [in the future, this attribute could be expanded so that it takes a comma-separated list of part type names whose content needs to be inline]
Returns a list of all versions of the document (as a d:versions element). This request requires no attributes.
Returns a diff of the document version with another version of this document or another document.
The full form of this request is:
<p:diff> <p:otherDocument id="..." branch="..." language="..." version="..."/> </p:diff>
If no p:otherDocument element is specified, the diff will automatically be taken with the previous version of the document. If there is no such version (because the document has only one version yet), there will be no diff response.
If a p:otherDocument element is supplied, any combination of attributes is allowed, in other words all attributes are optional.
Returns the list of all values of the id attributes occuring in the Daisy-HTML parts of the current document. This can be useful in editors to show the user a list of possible fragment identifier values.
Syntax:
<p:ids/>
Returns a navigation tree. The full form of this request is:
<p:navigationTree> <p:navigationDocument id="..." branch="..." language="..."/> <p:activeDocument id="..." branch="..." language="..."/> <p:activePath>...</p:activePath> <p:contextualized>true|false</p:contextualized> <p:versionMode>live|last</p:versionMode> </p:navigationTree>
The activeDocument, activePath and versionMode elements are optional.
Returns a list of all private comments of the user.
Returns the result of executing a query. The full form of this request is:
<p:performQuery> <p:query>...</p:query> <p:extraConditions>...</p:extraConditions> </p:performQuery>
The p:extraConditions element is optional, and specifies additional conditions that will be AND-ed with those in the where clause of the query. This feature is not often needed. It can be useful when you let the user enter a free query but want to enforce some condition, e.g. limit the documents to a certain collection.
The result of a query is a d:searchResult element.
If there is a context document available (i.e. if this p:performQuery is used inside a p:document) then the ContextDoc function can be used in the query.
The p:forEach element allows to perform a p:document request for each document (actually, document variant) returned by query. The full form of this request is:
<p:forEach useLastVersion="true|false"> <p:query>...</p:query> <p:document .... /> </p:forEach>
If the useLastVersion attribute is false or not specified, the live version of each document will be used, otherwise the last version.
If there is a context document available (i.e. if this p:performQuery is used inside a p:document) then the ContextDoc function can be used in the query.
Allows to execute a part of the publisher request only if a certain test is satisfied. Syntax:
<p:if test="..."> [... any publisher request ...] </p:if>
The test attribute specifies a conditional expression (an expression evaluating to true or false) in the same format as used in the Daisy query language.
<p:choose>
<p:when test="...">
[... any publisher request ...]
</p:when>
[... more p:when's ...]
<p:otherwise>
[... any publisher request ...]
</p:otherwise>
</p:choose>
There should be at least one p:when, the p:otherwise is optional.
The p:group element acts as a container for other requests. It needs an id attribute:
<p:group id="..." catchErrors="true|false"> [... other requests here ...] </p:group>
It allows to distinguish between e.g. different queries or navigation tree results if you would have more then one of them.
The catchErrors attribute is optional. When this attribute has the value true, any errors that occur during the processing of the children of the p:group element will be catched. The result will then be a p:group element with an attribute error="true" and as child the stacktrace of the error. When catchErrors is true, the result of the execution of the children of the p:group element will need to be buffered temporarily, so only use this when you really needed.
This element allows to retrieve the names of a set of documents of which you have only the ID. The advantage compared to using simply the repository API is that this only requires one remote call for as many documents as you need (assuming you are using the remote API, otherwise it does not make a difference).
<p:resolveDocumentIds branch="..." language="..."> <p:document id="..." branch="..." language="..." version="..."/> </p:resolveDocumentIds>
The branch and language attributes on the p:resolveDocumentIds element specify the default branch and language to use if it is not specified on the individual documents. These attributes are optional, the main branch and default language is used as default when these attributes are not specified.
The branch, language and version attributes on the p:document element are optional. By default the live version is used, or the last version if the document does not have a live version.
The result has the following format:
<p:resolvedDocumentIds> <p:document id="..." branch="..." language="..." version="..." name="..."/> </p:resolvedDocumentIds>
The id, branch, language and version attributes are simply copied from the requesting document element. The name attribute is added. The p:document elements in the result corresponds to those in the request at the same position.
If there is some error (such as the document does not exist, or the specified branch or language does not exist), an error message is put in the name attribute.
This element allows to retrieve the selection list of a field type.
<p:selectionList fieldType="..." branch="..." language="..."/>
The fieldType attribute can contain either the name or ID of the field type.
The branch and language attributes are optional, if not present they default to those of the context document, if any, and otherwise to the main branch and default language. The branch and language only make a difference when the selection list implementation needs them, e.g. for query selection lists with "filter variants automatically" behaviour.
If the field type has no selection list, the output will contain nothing, otherwise a d:expSelectionList element will be present. The 'exp' prefix stands for 'expanded', this in contrast to the defintion of the selection list (which can e.g. be a query).