Structure and Semantics

This section describes dokieli's practices, and offers some guidelines for developers and authors that would like to maintain uniformity in what they create. Consumers of dokieli should not treat the information here as a profile, or as a yet another super or subset of HTML+RDFa when they author or build new functionality. Creating articles, annotations, and notifications in dokieli is intended to be done through its UI, where it takes care of majority of the semantic content generation. The information here however can be useful for authors that would like to combine hand coding with the functionality that dokieli's UI provides. Takeaway what you find useful, there is no proprietary lock-in here.

dokieli adopts progressive enhancement strategy for the structural, presentational, and behavioural layers to allow content and base functionality to be accessible through different media and devices. The content in HTML+RDFa that dokieli produces is accessible (readable) without requiring any CSS or JavaScript, ie. text-browser safe. Breaking this "rule" in future development should be considered an anti-pattern (or a bug) in dokieli.

dokieli can serialise articles, annotations, and notifications in HTML+RDFa, Turtle, and JSON-LD, depending on server content-negotiation. Articles are represented in HTML+RDFa so that information is usable by both humans and machine consumers while maintaining lowest requirements for publishing, eg. a single URL with full payload in HTML+RDFa can be accessible from any HTTP server. No additional requirements necessary from clients (eg. JavaScript support and enabled) or servers (eg. additional RDF based content-negotiation). For annotations and notifications, dokieli first meets interoperability requirements (for protocols and vocabularies), and remains flexible about the serialisation that servers prefer. Similarly for consuming content, it can work with any of the serialisations as mentioned.

dokieli takes the approach of having all human-visible content in HTML, and all structured statements be made in context of their content in RDFa. This is optimal in avoiding data duplication in the same document which happens to be the case with the other serialisations in RDF. The approach also helps to avoid the creation and usage of multiple data islands, ie. separately for humans and machines. It is efficient in that it has no dependency on JavaScript in order to make the hidden machine-readable content be consumable from a human user interface. One exception to this rule is allowing authors to use the Embed Data feature to include Turtle, JSON-LD, or TriG data blocks for alternative reasons.

dokieli documents

Is there such thing as a "dokieli" document? Must there be?

Article

An article may contain RDF classes like schema:CreativeWork sioc:Post prov:Entity schema:Article, otherwise, there is no unique data that would indicate that it is a "dokieli" document. If the HTML+RDFa representation includes do.js and the DOM is ready, the DO: Object { C: {…}, U: {…} } will be available.

Annotation

An annotation has the oa:Annotation class. It is possible to know that the article was rendered by dokieli: ?s oa:renderedVia <https://dokie.li/>, and we can assume that the annotation was created by it as well. This is not strictly true since that property could have been put there by something else. Annotations represented in HTML+RDFa do not include do.js.

Notification

A notification may have one of the following classes: as:Announce, as:Like, as:Dislike, as:Relationship. Notifications represented in HTML+RDFa do not include do.js.

HTML patterns

One of the goals of dokieli is not to impose arbitrary restrictions on type of nodes as well as the order they should be in HTML+RDFa. It has its own design patterns. It is an ongoing work to make dokieli as flexible as it can be on what it can consume. Ultimately, well-formed and valid HTML - along with accompanying RDFa, Turtle, JSON-LD, TriG etc - is the only requirement here. Take what you like:

Markup syntax

HTML5 Polyglot Markup is used to ensure that when content is processed or served as HTML or XHTML (text/html, application/xhtml+xml), they can generally be used in both HTML and XML ecosystems without further intervention. See also getDocument (do.js) for details on DOM normalisation.

Identifiers

Unique identifiers (@id) may be placed on any element. Identifiers are auto-generated by normalising some input eg. sections use their heading's text content as input, tables from caption. Anything of importance should have an identifier, and aimed to be included for common patterns out of the box. @id values are reused in RDFa. See also generateAttributeId (do.js) and its application in different places.

Outline

title is used.

main > article (querySelector) is considered to be the location of the primary content.

h1 is typically the first element node after main > article

There is a resource type, eg. schema:Article that can be found in main > article which is about the article. body may contain broad classes.

Section

Sectioning is declared with section and typically have a heading, eg. h2 as its first child. Subsections may appear as a child of parent section, or as a child of div (which is a child of parent section), ie. section section or section div section. The headings of subsections are enumerated eg. section h2 would have a subsection with section h3. Sections ids and heading text are used to dynamically build the table of contents.

h2 and h3 are used for section titles, div as a typical wrapper (eg. for descriptions), as well as to contain further sub-sectioned content.

Aside

asides can technically appear anywhere, but tend to appear as the last element node in section, eg. for related content, footnotes. If the aside is introduced to the DOM via JavaScript for like annotations, they have a similar structure to section.

Division

divs within section are used to wrap a block of arbitrary markup and content. See also RDFa below.

Figure

figures typically have figcaptions for things like audio, canvas, iframe, img, object, pre, video, math. For code scripts, figure class="listing" is used, and pre for the code itself with code The listing class is intended to have a collection of figures, which could also have a unique presentation, for example with line numbers or have its caption be prefixed with Listing and counter.

For mathematical equations figure class="equation" can be used to hint at an equation display. MathML base equation with <math xmlns="http://www.w3.org/1998/Math/MathML"> root can be included here (see also source). Alternatively, if MathJax JavaScript is available in the document, (La)TeX, eg. \lim_{x \to \infty} \exp(-x) = 0 and ASCIIMath, eg. sum_(i=1)^n i^3=((n(n+1))/2)^2, syntaxes can be input within the authoring mode (via Edit).
limn→∞x=0

Embedding Turtle, JSON-LD, and TriG

Turtle, JSON-LD, and TriG syntaxes are placed within respective script blocks in head eg. <script id="meta-json-ld" type="application/ld+json" title="JSON-LD"></script>. Data is enclosed in CDATA sections. This pattern is detected, visible and editable from Embed Data in dokieli menu. See also showEmbedData (do.js).

CSS

Multiple stylesheets can be included with @media, and when accompanied with @title, some user-agents can provide options for the user to switch between them, as well as from the dokieli menu, eg.

To preserve the order of content, @inlist is used eg. <section inlist="", <dd id="Sarven-Capadisli" inlist="" rel="bibo:authorList" resource="http://csarven.ca/#i">.

A sections @id value is used as part of section's @resource as a fragment, eg. <section id="introduction" rel="schema:hasPart" resource="#introduction">. This allows the same identifier to be used for humans and machines, the value is derived from normalising its heading value as mentioned earlier.

Relating parts is done with rel="schema:hasPart", eg. sections with subsection:

divs are used to hold a block of HTML markup and types of content together eg. <div datatype="rdf:HTML" property="schema:description" resource="#introduction" typeof="deo:Introduction"> makes it possible to declare that it contains HTML markup, and describes an introductory text.

Some of the prefixes (@prefix) on the body element are defined in the RDFa Core Initial Context. These prefixes are defined in dokieli for the purpose of being compact, robust, and to minimise potential errors for consumers.

Note

There is a work in progress to have a distribution version of dokeli, requiring only do.css and do.js in templates.

Servers should use UTF-8 character encoding in their HTTP responses to articles, annotations, and notifications. <meta charset="utf-8" /> is used in HTML.

The subject of the following statements may be anywhere in a document. They tend to give some provenance level information and intended to bring more context and attract reuse of the document in different ways.

The owl:sameAs indirectly gives this article, ie. any copy, an identifier. The identifier is typically where an article was originally made accessible from, so having this by default for copy distribution helps to keep its connection to source.

ldp:inbox relation gives an article its own Inbox where it can receive notifications about eg. annotations or activities relevant to an article. The notifications can be consumed by applications to offer additional content and interactive possibilities. dokieli can both send and consume notifications by way of discovering an article's inbox. Notifications are created for activities like announcements, creating, (dis)liking, and consumed in order to be displayed in context of available content. The protocol to send and consume notifications in dokieli uses Linked Data Notifications.

Nice to declare a license or rights to signal under what conditions the document may be reused, reshared or remixed, eg. via Creative Commons license. Articles and notifications tend to use schema:license and annotations use dcterms:rights (given Web Annotation Vocabulary).

Annotation

Annotations have their own URL, fetched, parsed, and then introduced into the DOM. They are normally appended at the bottom of a node (section) in which the annotation has a reference to. It is not required to introduce all of the annotation content into the DOM, nor all of it has to be human-visible. This is a run-time inclusion and typically included within <aside class="note do"></aside>. Write operations like Save, Save As, Export will exclude this (class~="do") when it normalises the DOM to HTML.

oa:canonical refers to a canonical IRI that can be used to deduplicate the annotation. If an user chooses to store their annotation at their personal Webspace as well as when an annotation service (if offered), dokieli treats the resource at personal space as the canonical, and the resource at the annotation service as the copy where it refers to the personal space (oa:via).

If an annotation resource is introduced to the article's DOM as part of an aside, they have a structure similar to an article, and may be displayed in different ways, eg. in marginalia:

Note that the human-visible anchor hyperlinks (#461819979) to the annotation aside id="461819979".

Notification

Notifications are discovered from LDN Inboxes. An article (or a fragment within) may have an inbox relation (ldp:inbox) which helps dokieli to discover it, and then fetch the notifications.

Notifications are intended to be brief, giving sufficient information for consumers to decide if they want use to them. If the notifications are generated by dokieli, eg. via an annotation activity, they typically include some provenance level data like generation date, actor that triggered it, license, where the annotation can be found, what it annotated, and the motivation for it. Notifications will not include the annotation body, but consumers can fetch their URLs (as mentioned in the annotation section).

User interface

Document modes

There UI adapts to the document mode the user is in: author, review, social. By default the social mode is engaged. The dokieli menu allows the user to engage the author mode through the Edit operation, and the review mode with Review. See also setDocumentMode (do.js).

dokieli menu

Sign in

This is where the user can enter their WebID to let dokieli know about who they are. dokieli fetches their WebID and related information to further help with dokieli's operations. Authentication is not done at this stage.

Share

User can share the current article or a part of it with their contacts, automatically discovered via foaf:knows as well as traversing equivalent profiles (owl:sameAs). Notification can also be sent to specific targets by entering their IRIs. dokieli sends a notification to the selected targets with information like: who sent it, when, license, motivation.

This feature changes the document mode to Review and gives different context for annotations. When a user selects a span of text, a toolbar provides the following options to motivations:

Approve

General agreement with the selected text. Optional text should specify why it is a strong point or a convincing argument.

Disapprove

General disagreement with the selected text. Optional text should specify why it is a weak point, an error, or inaccurate.

Specificity

Request to increase specificity on selected text. Optional text should indicate that a citation or more specificity is needed.

New

This feature allows a new document to be created at specified location. The new document is constructed based on If the user is signed in with their WebID and their personal storage location is identifier, the default location for the new resource will have the storage URL (pim:storage) as its base. If the user does not have a WebID and a storage, and if the article refers to an annotation service (oa:annotationService), it will use that URL instead. The URL can be input directly, and otherwise a name will be autogenerated for the resource. This feature uses the resource browser to navigate HTTP URLs. See also generateAttributeId (do.js). On create, the resulting hyperlink will be shown and a new tab in the browser will be prompted.

Open

Documents can be opened from a local filesystem or by entering an HTTP URL. Both options read the resource's content, and if dokieli's CSS and JavaScript are not present, they are included before updating the DOM and initiating dokieli. This feature uses the resource browser to navigate HTTP URLs. See also openDocument (do.js).

Save

This feature makes a write operation (HTTP PUT) request to the current location of the document (window.location). The document is normalised in that dokieli related items are removed from the DOM before making the request.

Save As

The Save As operation is similar to New for normalising some of the URLs and same as Save operation for normalising the DOM before making the request to specified location. If Derivation data is checked for inclusion, derived from and on information is included in the created document. This feature uses the resource browser to navigate HTTP URLs.

Export

Provides options to 1) exports the article as HTML and save to filesystem, 2) Makes a request to the Internet Archive to crawl all resources references in this article.

Print

Requests to print the current document (window.print()).

Edit

Editor is one of the document modes a user can be in. The available features reflect the edit operation. Edits reside in the DOM until a Save or Save As is triggered. There are several editor features in following categories: content formatting and structuring (2, 3, 4, , , , , code, , , , , ), including interactive and embeddable objects (), inline semantic relations (), footnotes and citations (), and annotations ().

Source

Users can edit the current state of the article. Updating, only updates the DOM, and leave the saving to Save or Save As.

Embed Data

This feature allows hidden RDF data to be stored with the document. Turtle, JSON-LD, and TriG can all be edited and stored independently.

To determine the base URL, when new documents are created or saved as, media resources from head link, [src], object[data] (querySelector) will have their URLs normalised to use current document's base URL as its absolute URL (this is the Use references as is option). If Copy to your storage is selected, relative URLs will not be updated as the copy operation reuses the same file paths when resource are copied to destination. The copy operation does an HTTP GET for each source, then HTTP PUT to target.

The resource browser eg. available for New, Open, Save As operations can be used to navigate through a Webspace. It does this by using the Linked Data Platform's containment rules to retrieve and then display the container's index. If the user's personal storage location is known, it will be used as default location for the resource browser. Alternatively, if the article refers to an annotation service, it will be used as start location.

Users are given a choice to specify the rights and license for their annotations from a list of Creative Commons licenses, eg. CC BY 4.0. If applicable, the notification payload will use the CC0 1.0 Universal license.

Views

The dokieli menu will list primary and alternate stylesheets that are detected in HTML. Native is always available and it will essentially disable all other stylesheets, thereby user-agent's default stylesheets are gets applied. When a view is selected, eg. Basic (which happens to be the one that is used on this article as primary), it becomes the primary stylesheet, and the rest of the stylesheets become alternate and disabled.

Notifications are sent with HTTP POST. Save and Save As normalises the HTML before sending.

Request to send

HTTP method(s)

Content-Type

Article

PUT

text/html

Annotation

OPTIONS, POST

text/html, application/ld+json, text/turtle

Notification

OPTIONS, POST

text/html, application/ld+json, text/turtle

Article

Articles typically use text/html with embedded RDFa. Where a server implements GET with text/html, and allows PUT for writing, the assumption is that it can allow text/html. In the future, dokieli can check for the Accept-Put header with OPTIONS to determine a suitable type. At this time, HTML+RDFa is an important default for articles.

Annotation

Annotations use the POST method with Content-Type header value determined by type of location to write to: personal storage space eg. given a profile's pim:storage; made to an annotation service eg. an article's oa:annotationService; sent to profile's outbox's outbox: as:outbox. The Web Annotation Protocol requires application/ld+json by default. dokieli sends an OPTIONS request to check for the Accept-Post header and sends the payload in one of the serializations that the server prefers. If it is not set, it will fallback to application/ld+json as preferred by Wen Annotation and ActivityPub.

Notification

Notifications use OPTIONS to check the response's Accept-Post HTTP header. If it is set and matches one of the acceptable RDF mediatypes that dokieli can parse, it will use that mediatype to serialize the payload before POSTing. If it is not set, it will fallback to application/ld+json as required by the Linked Data Notifications specification.

Current reasons for using HTTP POST and PUT instead of PATCH:

Servers with XML Patch and mediatype application/xml-patch+xml (RFC 7351) capability in the Linked Data ecosystem are not well supported.

HTTP PATCH with SPARQL Update (using mediatype application/sparql-update) would not work for RDFa representations because it would require additional server-side knowledge: HTML+RDFa serializer. This also makes server implementations a dependency for dokieli which is an undesirable design pattern.

HTTP PATCH can help to optimise HTTP requests provided that the server processes the SPARQL query and eventually publishes the final state of the article. dokieli's use of HTTP POST and HTTP PUT on the other hand does not expect or impose operations other than to store and serve the article. If servers would like to do versioning and how, dokieli leaves it to the servers to decide.

Due to Mixed Content implementations in Web browsers, ie. fetching of content over unencrypted or unauthenticated connections in the context of an encrypted and authenticated document, is subject to being blocked by the Web browser. Hence, an https document (eg article at https) will not be able to use the contents of an http document (eg. an http WebID). As a workaround, dokieli uses a proxy endpoint by default in order to use the contents of an http resource. An https document fetching an https resource will not use the proxy.

Authentication

dokieli was originally intended to handle different authentication mechanisms. WebID-TLS is currently supported to authenticate with servers.

Storage

Personal storage

WebID's with pim:storage can get to use their personal online data storage with dokieli's read-write operations, eg all annotations, Reply, Review, New, Save As.

Local storage

There is a Local Storage feature which uses user-agent's window.localStorage, with default 1m autosave.

Web Extension

The dokieli Web Extension is a minimal package of dokieli which contains the core CSS and JavaScript that works as a browser add-on. When user triggers it from their browser toolbar, it provides the same functionality as a single-page application, ie. initialised and rendered in the browser DOM.

Currently the extension works with Firefox and Chrome/Chromium browsers. Two ways to do this: