|
47 | 47 | <p>One XSLT stylesheet can be specified per application. In order to reuse LinkedDataHub's built-in templates, it should import the <a href="https://github.com/AtomGraph/LinkedDataHub/blob/master/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/layout.xsl" target="_blank">system stylesheet <samp>layout.xsl</samp></a> and only override the necessary templates. That is however not a requirement, the stylesheet could also use its own independent transformation logic.</p> |
48 | 48 | <p>If there is no stylesheet specified for the application, the system stylesheet is used. It defines the overall layout and imports resource-level and container-specific stylesheets, as well as per-vocabulary stylesheets.</p> |
49 | 49 | <p>Note that LinkedDataHub itself imports stylesheets from <a href="https://github.com/AtomGraph/Web-Client" target="_blank">Web-Client</a>, which uses the same template modes but produces a much simpler layout.</p> |
50 | | - <p>There is also a special <a href="https://github.com/AtomGraph/LinkedDataHub/blob/master/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/client.xsl" target="_blank">client-side stylesheet</a> which is not used to render a full layout, but only manipulate DOM elements in the browser in response to user or system events. It is processed using <a href="http://www.saxonica.com/saxon-js/index.xml" target="_blank">Saxon-JS</a> which provides IXSL (<a href="https://www.saxonica.com/saxon-js/documentation/index.html#!ixsl-extension" target="_blank">client-side extensions for XSLT</a>). It imports and reuses some of the same sub-stylesheets as the server-side system stylesheet does, but avoids loading per-vocabulary stylesheets in order to improve page load time. Templates of the client-side stylesheet can also be overridden.</p> |
| 50 | + <p>The same XSLT 3.0 stylesheets run in two environments. On the server they are executed by Saxon-HE to produce the initial HTML response. In the browser they are executed by <a href="https://www.saxonica.com/saxon-js/index.xml" target="_blank">Saxon-JS 3</a>, which provides IXSL (<a href="https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension" target="_blank">Interactive XSLT extensions</a>) for reading and manipulating the browser DOM.</p> |
| 51 | + <p>There is a dedicated <a href="https://github.com/AtomGraph/LinkedDataHub/blob/master/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/client.xsl" target="_blank">client-side stylesheet <samp>client.xsl</samp></a> that drives the browser. After the server-rendered page loads, its <code>main</code> template renders the layout client-side — the left sidebar, navigation, document and tab panes, content blocks, forms and modal dialogs are injected into the DOM using IXSL (e.g. <code>ixsl:append-content</code>). It also handles all subsequent navigation, so following links and switching documents re-renders in place without a full page reload. It imports and reuses the same document-, resource- and property-level templates as the server-side system stylesheet, but avoids loading per-vocabulary stylesheets in order to improve page load time. Templates of the client-side stylesheet can also be overridden.</p> |
51 | 52 | </div> |
52 | 53 | <div> |
53 | 54 | <h3 id="namespaces">Namespaces</h3> |
|
137 | 138 | </tr> |
138 | 139 | </thead> |
139 | 140 | <tbody> |
140 | | - <tr> |
141 | | - <td><code>$ldt:base</code></td> |
142 | | - <td><code>xs:anyURI</code></td> |
143 | | - <td>Base URI of the current application</td> |
144 | | - </tr> |
145 | 141 | <tr> |
146 | 142 | <td><code>$lapp:Application</code></td> |
147 | 143 | <td><code>document-node()?</code></td> |
|
160 | 156 | <tr> |
161 | 157 | <td><code>$ac:endpoint</code></td> |
162 | 158 | <td><code>xs:anyURI</code></td> |
163 | | - <td>SPARQL query endpoint URI (defaults to <code>resolve-uri('sparql', $ldt:base)</code>)</td> |
| 159 | + <td>SPARQL query endpoint URI (defaults to <code>resolve-uri('sparql', ldt:base())</code>)</td> |
164 | 160 | </tr> |
165 | 161 | <tr> |
166 | 162 | <td><code>$sd:endpoint</code></td> |
|
182 | 178 | <td><code>xs:anyURI*</code></td> |
183 | 179 | <td>Current layout mode (derived: <code>ldh:ContentMode</code> if the document has content blocks, otherwise <code>ac:ReadMode</code>)</td> |
184 | 180 | </tr> |
185 | | - <tr> |
186 | | - <td><code>$lapp:origin</code></td> |
187 | | - <td><code>xs:anyURI</code></td> |
188 | | - <td>Origin URI of the current application</td> |
189 | | - </tr> |
190 | 181 | </tbody> |
191 | 182 | </table> |
192 | 183 | </div> |
|
223 | 214 | <td><code>xs:string?</code></td> |
224 | 215 | <td>Extracts the fragment identifier (the part after <code>#</code>)</td> |
225 | 216 | </tr> |
| 217 | + <tr> |
| 218 | + <td><code>lapp:origin()</code></td> |
| 219 | + <td><code>xs:anyURI</code></td> |
| 220 | + <td>Returns the origin (scheme, host and port) of the current application, e.g. <code>https://localhost:4443/</code>. Used to build absolute URIs for static resources and same-site requests</td> |
| 221 | + </tr> |
| 222 | + <tr> |
| 223 | + <td><code>ldt:base()</code></td> |
| 224 | + <td><code>xs:anyURI</code></td> |
| 225 | + <td>Returns the base URI of the current application. Replaces the former <code>$ldt:base</code> parameter</td> |
| 226 | + </tr> |
226 | 227 | <tr> |
227 | 228 | <td><code>ldh:request-uri()</code></td> |
228 | 229 | <td><code>xs:anyURI</code></td> |
|
238 | 239 | <td><code>xs:anyURI</code></td> |
239 | 240 | <td>Resolves a URI to a local href, proxying external URIs through the LinkedDataHub proxy. Overloads accept <code>$query-params as map(xs:string, xs:string*)</code> and <code>$fragment as xs:string?</code></td> |
240 | 241 | </tr> |
| 242 | + <tr> |
| 243 | + <td><code>ldh:parse-href($href as xs:anyURI)</code></td> |
| 244 | + <td><code>map(xs:string, item()?)</code></td> |
| 245 | + <td>Inverse of <code>ldh:href()</code> — parses a local href back into its target URI, query parameters and fragment. Shared by the client-side navigation handlers</td> |
| 246 | + </tr> |
241 | 247 | <tr> |
242 | 248 | <td><code>ldh:query-params($mode as xs:anyURI*)</code></td> |
243 | 249 | <td><code>map(xs:string, xs:string*)</code></td> |
|
386 | 392 | each LinkedDataHub instance. As a result, retrieving their descriptions by dereferencing their URIs using <code>document()</code> does not incur an HTTP request and is much faster. The URI-to-file mapping |
387 | 393 | is defined as Jena's <a href="https://jena.apache.org/documentation/io/rdf-input.html#configuring-a-locationmapper" target="_blank">location mapping</a> and can be found in |
388 | 394 | <a href="https://github.com/AtomGraph/LinkedDataHub/blob/master/src/main/resources/location-mapping.n3" target="_blank"><samp>location-mapping.n3</samp></a> and <a href="https://github.com/AtomGraph/LinkedDataHub/blob/master/src/main/resources/prefix-mapping.n3" target="_blank"><samp>prefix-mapping.n3</samp></a>.</p> |
389 | | - <p>Client-side stylesheets use <a href="https://www.saxonica.com/saxon-js/documentation/index.html#!ixsl-extension/instructions/schedule-action" target="_blank"><code><ixsl:schedule-action></code></a> (deprecated) and <a href="https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension/instructions/promise" target="_blank"><code><ixsl:promise></code></a> to load XML documents asynchronously.</p> |
| 395 | + <p>Client-side stylesheets use <a href="https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension/instructions/schedule-action" target="_blank"><code><ixsl:schedule-action></code></a> (deprecated) and <a href="https://www.saxonica.com/saxonjs/documentation3/index.html#!ixsl-extension/instructions/promise" target="_blank"><code><ixsl:promise></code></a> to load XML documents asynchronously. The metadata required to render forms — constructors, SHACL shapes, and property and object descriptions — is loaded client-side through chains of <code><ixsl:promise></code>, so the browser fetches it on demand rather than the server fetching everything up front.</p> |
390 | 396 | </div> |
391 | 397 | </div> |
392 | 398 | <div> |
|
0 commit comments