Thanks Richard That is enormously helpful.. i had worked out some of that by diving and playing.. but great to see it laid out.
The list of properties that get inherited is really helpful, and the rationale behind viewClass. Rob On Thu, 12 Jul 2018, 20:17 Richard Cyganiak <[email protected]> wrote: > Hi Rob, > > On 12 Jul 2018, at 01:22, [email protected] wrote: > > BTW - still trying to get my head around why sometimes a viewClass is used > and sometimes an instance of such a class - both seem to co-exist in EDG - > but whats the reason for using instances - and do they just behave like > their parent classes? and what if there are multiple? > > the properties of an instance do not shed much light on why they exist. > You previously pointed to classView as a way to invoke a service. the docs > leave me no wiser: > > " > _view The URI of a specific view to display (instance of ui:Element). > _viewClass The URI or qname of a user-defined view class (subclass of > ui:Elements) to display. All other arguments that match the declared > arguments of the view class will be passed into the view, e.g. > uispin?_viewClass=ex:MyView&name=Test will be comparable to <ex:MyView > arg:name="Test" />." > > is this explained in more detail elsewhere? > > > Not really, but it should be, so I started to write up some stuff. See > below. > > Richard > > > > > == SWP views are nested blank node structures == > > SWP views are written in XML: > > <ex:MyView arg:name="Test"/> > > But internally, this is treated not as XML but as a structure of nested > blank nodes. The snippet above would be a blank node with rdf:type > ex:MyView, and a property arg:name with value “Test”. > > In the case of XML with child elements, the root will still look as above, > but there are further connected blank nodes for each child. An SWP > developer rarely needs to know the details beyond that. > > > == Associating SWP views with classes and resources == > > There are a number of ways how these blank node structures can be > associated with classes and resources: > > 1. ui:view associates an SWP view with a resource (an instance). The view > is supposed to render the resource. > > 2. ui:instanceView associates an SWP view with a class. The view is > supposed to render instances of the class. The instance to render is passed > to the executing view as variable ?this. > > ui:view and ui:instanceView are used to “dress up” domain models (a.k.a. > domain ontologies) with presentation information that indicates how to > display the entities in the model. > > 3. ui:prototype associates an SWP view with a class. The view is supposed > to accept arguments, and render a response based on these arguments. The > arguments are passed in as variables. The view itself does not need to be > concerned with the question where the arguments come from and who provides > them. Classes that have a ui:prototype become available for use as custom > XML elements in other views. The ex:MyView example given earlier assumes > that ex:MyView is itself a class that has a ui:prototype. When the SWP > engine renders the view example, it would call the ui:prototype and pass in > the argument ?name with value “Test”. It is worth noting that the instances > of a class with a ui:prototype are typically blank nodes that are SWP > views. So we can think of our <ex:MyView arg:name="Test"> example view as > an instance of ex:MyView that fills in the required arguments. > > 4. ui:errorPrototype, ui:headIncludes, and a few other properties are > typically used to associate helper views for specific purposes to class > hierarchies that use ui:prototype. They usually do not contain business > logic. > > ui:prototype and friends are used to package SWP views as reusable > building blocks, and to develop full interactive web applications. > > > == Rendering SWP views via the SWP servlet == > > The most important way to execute SWP views is the SWP servlet of > TBL/EVN/EDG. When calling the servlet, the view to execute can be specified > in a number of ways: > > 1. /tbl/swp?_view=xxx directly names the view to render. As stated above, > SWP views are structures of nested blank nodes, so this would need to name > the top-level blank node of the view. This option rarely needs to be used > directly by developers, but is used internally when a part of a view needs > to be rendered, e.g., with ui:loadable or ui:handle. > > 2. /tbl/swp?_resource=xxx names a resource to render. The SWP servlet will > check if the resource has a ui:view property, and if so render that view. > Or else, walk up the class hierarchy to find a ui:instanceView property, > and render that with the resource bound to ?this. There are additional > arguments to pick between multiple applicable views. This is also what the > “Browser” tab in TBCME does. > > 3. /tbl/swp?_viewClass=xxx names a class whose ui:prototype to render. Any > additional parameters to the HTTP request (e.g., ¶m1=yyy¶m2=zzz) > will be passed in as arguments. In applications written in SWP, most pages > are rendered in this way. It’s worth knowing that such calls actually > create a new view on the fly, and render that view. So, > ?_viewClass=ex:MyView&name=Test would generate our example view given above > (in its blank node form), and pass that to the SWP engine to render. > > (I am glossing over the _base parameter that is especially critical for 2 > to specify the graph that holds the resource to be rendered.) > > > == The SWP class hierarchy == > > Another thing worth talking about is the role of the subclass hierarchy > when working with classes that have ui:prototypes. Since SWP is a > programming language, and has subclasses, one might think of it as an > object-oriented language. There are indeed some object-oriented concepts in > SWP, but I personally found that thinking of SWP in object-oriented terms > does more harm than good. SWP is not a traditional object-oriented (or, for > that matter, prototype-oriented) language. It is its own thing and fairly > unique. > > So, here are the most important uses of subclassing in SWP: > > 1. As a simple grouping mechanism in TBCME. If I work on a bunch of > classes related to a certain feature, I might make them all subclasses of a > common abstract class such as ex:FeatureXyzElements. This makes them appear > together in the TBCME class tree, which is convenient for navigation in > TBCME, even though it has no effect on the program itself. > > 2. To avoid having to repeat argument declarations, error prototypes, and > head includes on multiple classes. A few select properties, including > spin:constraints, ui:errorPrototype and ui:headIncludes, are inherited by > subclasses for the purposes of the SWP engine. So, if I have many classes > that require a ?projectGraph argument, I might declare it only once on an > abstract class ex:ProjectGraphElements, and then make all other classes > subclasses of that one. Or, if I have many classes that require the same > ui:errorPrototype (e.g., a permission check or configuration check), then I > might put that ui:errorPrototype on an abstract class ex:AdminElements and > make the other ones subclasses of that one. Just to avoid having to say the > same thing in multiple places. > > There are other uses and patterns related to subclasses in SWP, but I find > them less important. > > > == The “other” class hierarchy: meta-classes == > > It is also important to point out that SWP has two parallel class > hierarchies. The “real” class hierarchy is rooted at ui:Element, and > includes built-in abstract classes such as ui:ViewElements, ui:Services and > ui:Operations. All your classes that have ui:prototypes live as subclasses > in this hierarchy. Typically, I create new SWP classes by right-clicking on > the appropriate class in that hierarchy and selecting “Create subclass”. > > The “other” class hierarchy is rooted at ui:NodeClass and contains > meta-classes. Your classes will be instances of those meta-classes. This > usually happens automatically, and the whole “other” hierarchy can be > ignored. But it is useful to know about in case one accidentally wanders > into it. > > The meta-classes mostly exist to make matters confusing. Apart from this, > they also have the secondary purpose of making TBCME behave nicely when > editing the “real” classes. For example, the ui:prototype field appears on > the TBCME form of your classes by virtue of some meta-class magic. It would > be nice if TBCME did a better job at hiding that magic! > > Often, the meta-classes and the “real” classes are distinguished by > singular vs. plural names, but this is inconsistent and cannot be relied > upon. > > -- > You received this message because you are subscribed to the Google Groups > "TopBraid Suite Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
