-
Notifications
You must be signed in to change notification settings - Fork 2
Scope: Forms vs Views #4
Comments
To elaborate a little on the last bullet above, I have recently been prototyping code to render entire pages from SHACL. The important feature for me was to use web components and server-side rendering. This forced me to slightly rethink how any given shape declares the UI components to use so that declarative HTML composition is possible. The outcome is a deviation from the DASH as I understand it, where I allowed RDF List objects of For example, in my data I have a link of precomputed filter URLs to pages where the <brands> a schema:WebPage;
hydra:view [
a :AlphabeticalPager ;
:page <brands?i=a> , <brands?i=b>, <brands?i=c> ; # ...
] ;
.
<brands?i=a> rdfs:label "A" . # etc I wish to display each link in a pager component. By separating the logic of displaying a link from the pager component itself, I arrive at this markup <ex-pager>
<!-- for every :page, render a link -->
<a href="brands?i=a>A</a>
<a href="brands?i=b>B</a>
<a href="brands?i=c>C</a>
<ex-pager>
The problem was that I could not define this composition with the current toolkit (or so I think). Thus, the <BrandsPage>
a sh:NodeShape ;
sh:targetNode <brands> ;
sh:property [
sh:path hydra:view ;
sh:class :AlphabeticalPager ;
dash:viewer
(
ex:Pager # dash:MultiViewer, render the <ex-pager> wrapper component
dash:DetailsViewer # delegate the rendering of individual links to nested shape
) ;
sh:node [
sh:property [
sh:path :page ;
dash:viewer dash:LabelViewer ; # render <A> link
] ;
] ;
] ;
. |
I have used a similar concept to dash:Viewers but always used views of documents. I think using multiple documents in a composition view might become very complex.
|
A SHACL Shape which describes an entire page allows me to retrieve the exact data needed to populate it and then render. Both important for performance and Server-Side Rendering in some way.
Not exactly. Clearly, my focus is HTML pages and the viewers in the above example translate to composition of HTML elements but they are abstract and could be used to compose an interface in another technology which keeps a similar tree-like component structure. |
How much of this is already in SHACL? Isn't SHACL by default meant for a one to one relationship between a shape and a document? How do you fetch multiple documents with pagination for example? Or is that exactly what you would like to add with SHACL UI? |
Yes, some of what you bring up would ideally be part of SHACL-UI
Yes, but I suppose you could dynamically load resources (documents?). The root shape may include hints for that, etc |
I am quite interested in this topic. In TopBraid we render resource forms with a generic top-to-bottom list of property widgets, grouped into sh:PropertyGroups and sorted by sh:order. I believe it would be beneficial to be able to say, for example, that a Person's firstName and lastName should appear horizontally aligned instead of vertically. This suggests some sort of layout structure. Likewise there could be annotations on whether the label of a property widget should appear above or to the left. And there could be "static" areas such as descriptive text or other media that are placed somewhere on a form. The don't need to be completely "static" but could be computed using SHACL-AF node expressions or similar.
I am aware this is open-ended and we don't want to reinvent HTML here. But a box layout model with static parts may go a long way. And it should be declarative so that non-HTML engines can also use that information. @tpluscode do you have a draft vocabulary for such things that you would want to share as starting point? |
I agree. Good form generators out there do have some control over the layout which is more sophisticated than grouping and ordering. What I'm trying to say is that forms and views are likely to be represented differently in SHACL Shapes. I also prefer completely separate implementations because forms and views have a very different model for the internal state of what's being rendered.
In fact I don't have much. In more recent implementation I rely simply on element composition and both layout and styling fall out of scope of the shape itself. Similar to the example above, a top-level <> a sh:NodeShape ;
dash:viewer ex:SidebarLayout ;
sh:property [ sh:path schema:title ; sh:group <#header> ] ;
sh:property [
sh:path skos:related ;
sh:group <#sidebar> ;
dash:viewer ( ex:LinkList dash:LabelViewer ) ;
] ;
sh:property [
sh:path schema:articleBody ;
dash:viewer dash:HTMLViewer ;
] ;
.
<#header> html:slot "header" .
<#sidebar> html:slot "sidebar" . The final result could be similar to <ex-sidebar-layout>
<span slot="header">
<!-- render component for schema:title -->
</span>
<!--
Notice again the rdf:List used for dash:viewer,
where the first is a dash:MultiViewer to act as a container
-->
<ex-link-list slot="sidebar">
<a href></a>
<a href></a>
<a href></a>
</ex-link-list>
<!-- render component for schema:articleBody -->
</ex-sidebar-layout> As I said, there is no need for explicit layout or styling hints. Layout is defined in the implementation of |
I like the usage of rdf:List for dash:viewer It made me think.. do we want layouts that are portable? If we want them to be portable and be defined in rdf we could use something like css grid and grid regions. I think we could maybe grab a subset of the css grid rules that would be easy to use in native code. I am not sure if portability of layouts would be a must. I do see one use case.. a system with federation and open data types, such as mastodon. One app could define a media type (a recipe for example) and also give a reference for how to render those recipes. In that case simple layouts such as 'two column', or 'left sidebar' could be interesting. |
Very good point! Contrary to my remark on the last call, I am most certainly JS-only focused. That said, there is nothing other than the slot concept which is browser-specific but I surely do not consider other targets in my work.
CSS grid is a good suggestion. It has wide support in browsers and should be easily adoptible on other platforms too. Alternatively, we could devise a abstract grid addressing and have CSS grid an implementation detail. While I still keep the mental separations between views and forms, the CSS grid would very much work for forms, such as in the "placing first and last name next to each other" scenario above. On second thought, a similar mechanism could also work for views, where an individual group is laid out as a grid too. I think this is slightly unrelated to the "two column"/"left sidebar" which defines a layout on a different level Now, one potentially problem with css grids is responsiveness. If the solution was to arbitrarily assign rendered viewers and editors to specific cells in a grid, the layout would be very rigid. Compare with the approach shown in this tutorial, where the HTML elements have meaningful class and are positioned using a grid indirectly.
To complement the fine-grained layouting solution (css grid, or otherwise) we could still keep these abstract layouts and a new concept. A hypothetical |
In addition to the #2 I think we should define if the interest of this task force is only forms or also "views" or pages.
In my experience, the two are quite separate and while DASH vocab comes with a set of terms for editors and viewers, I find that it is not as simple as annotation properties with both to produce good UI.
I found that a form is usually based off a SHACL Shape, describing a single resource or a set of closely related resources which form a cohesive whole. This is at least the case in a client/server, resource-oriented scenario where a client retrieves the shape and a single resource to edit and then saves it back. That said, an approach which sits closer ot the data itself is not so much different in that any modifications and shapes are closely modeling the graph model with very similar semantics to how one would model a OWL ontology, etc.
On the other hand, specialised views will likely span multiple resources and combine their descriptions in a different way, aiming to provide a different projection of the actual data. View Shapes would likely use deep property paths, partial queries, aggregations, and richer components to provide the user with an interface to fulfil a very different role than a "form turned read-only". Some examples of what I have in mind could include:
skos:related
) in a side columnThus in practice, I have been maintaining a separate shape for editing and a separate for displaying.
I would consider keeping such a separation in the spec, where we'd have one spec describing how to use SHACL to build editable UI, and another one dedicated to building "pages" with SHACL.
The text was updated successfully, but these errors were encountered: