Apologies for this long post from a newbie. I was trying out Adrian
Lienhard's Mewa with Seaside and it seems Mewa has languished. I was curious what knowledgable Seasiders thought of the following. QUESTION: Can we build very smart Seaside components automatically from meta-data of the domain objects, and still require a very small amount of meta-data for customized components? What's different about these "Components"? ========================================= Nothing changes on the interface between the Component and sessions, browsers, etc. However, each component in that tree is connected to domain objects via a meta-layer. This meta-layer provides a uniform (structural) reflective interface to all domain objects, their attribute values, and their operations including parameters and calling constraints, so that generic view and editor components can operate through this interface. What is this meta-layer? ======================== Components in successive levels of the component tree are (STRICTLY) attached to either - (meta)objects or - (meta)attributes of those object, or - (meta)operations on those objects A meta-object (in this discussion) is NOT a class; rather, it is a proxy-like object carrying meta-information for a specific domain object (instance). (The "meta" terminology comes from Mewa). A meta-attribute is an object carrying meta-information for the value of a specific attribute of a specific object. A meta-operation is an object carrying meta-information for a specific operation that might be invoked on a specific object. In combination these three carry all the information needed to construct components. The attached pictures from the Mewa paper show the essential idea (but don't include the meta-attributes and meta-operations). None of these meta-things need db-level persistance, they might use session-level persistence. Below is pseudo-Ruby code (sorry, I am not yet fluent in Smalltalk): class MetaObject # mostly acts as a proxy to obj, adding meta-information has_one :obj, Object has_many :attributes, MetaAttribute has_many :operations, MetaOperation def renderHtmlOn: html # walk attributes to structure views # walk operations to structure buttons/anchors/editors/...even wizards end end class MetaAttribute # a slot value of a domain object i.e. obj + attr + value # or, a slot + value of an operation on an object (op + param + value) has_one :attribute, Symbol has_one :type, Class # or duck-type has_one :multiplicity, Symbol # :attribute, :type, :mult should be shared via class level Attribute # I've just stuffed them here, just easier to understand this way has_one :owner, Object # domain obj or a MetaOperation (below) def value owner.instance_variable_get attribute # or #send... end def replace (replacement_obj) # illustrative only owner.send "#{attribute.to_s}=", replacement_obj end def add (added_obj) # illustrative; only defined if attr is a collection owner.send "add_to_#{attribute.to_s}", added_obj end end class MetaOperation # an operation-to-be-called on an object # has_one :operation, Symbol has_many :params, MetaAttribute # tracks param name, type, multiplicity, etc. # Used to populate (d)html accordingly # including using the smarts below # :operation and :params could be shared via class level Operation has_one :owner, Object has_many :current_values, Hash # current user-selected param values, hashed by param_symbol # for populating of parameter candidates e.g. a drop-down list # may be used via Ajax, including current parameter selection def candidates_for (param) owner.candidates_for operation, param, curr_values end # for enabling of operations e.g. menu or button enabling # may be used via Ajax, including current parameter selection def invocable? owner.invocable? (operation, current_values) end def invoke owner.send operations, current_values end end Example meta-layer instance =========================== Assume there is a component tree consisting of nested viewers and editors. On demand, build metadata about domain objects that these viewers and editors connect to, including the attributes and relations of these domain objects. Make that metadata structure uniformly as follows: m_obj m_attr m_obj m_obj m_attr... m_op1 m_attr... m_attr... m_op2 So if I have objects joe=Person.new joe.name = "Joe" home=House.new(:address=>"123 hometown") joe.add_house home vacation_home = House.new joe.add_house vacation_home room1 = Room.new room2 = Room.new home.add_room room1 home.add_room room2 bob=Person.new joe.add_friend bob Then a view or editor *on joe* will create and use this metadata structure: joe -- meta-object joe#name -- meta-attribute joe#name= -- meta-operation joe#houses -- meta-attribute home -- meta-object home#address -- meta-attribute "123 hometown" -- metaobject, optimized away home#rooms -- meta-attribute room1 -- meta-object room2 vacation_home joe#friends bob Example Component Tree ====================== CLAIM: The component tree should exactly parallel this metaobject and metaattribute structure (by default). So here are the components in that tree, and the (meta)-things they connect to: person_viewer --> joe #houses_viewer --> joe#houses house_viewer --> home #address_viewer --> home#address address_viewer --> "123 hometown" #rooms_viewer --> home#rooms room_viewer --> room1 room_editor --> room2#modify new_size --> room2#modify.new_size house_viewer --> vacation_home #friends_viewer --> joe#friends person_viewer --> bob As always, some of the elements in the above tree might change dynamically with Ajax e.g. a viewer might be replaced by an editor when the little "edit" link is clicked; but the editor would still be attached to the same meta-instance. I believe all the components in this tree could be generic by default, all the meta-objects constructed automatically given a few meta-data hints. Not sure how Seaside deals with Ajax right now, but we might need some event machinery between the tree and domain objects so an (Ajax) operation that replaced one component might also update other parts of related components in the tree. Ajax-induced updates would propagate up to the tree root collecting component updates, before going back to the client. CSS === Seaside components can be reused wonderfully, including embedding them in others. But if CSS is only provided at the page level, would it make sense for a component to (somehow) compose the CSS of its parts? We could eliminate some CSS warts while at it http://lunchroom.lunchboxsoftware.com/articles/2005/08/19/rcss-anyone, and with a few restrictions still retain client caching etc. Far less important than the component ideas above, though. Thoughts? Am I talking nonsense? Thanks. _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Hi ItsYou,
> QUESTION: Can we build very smart Seaside components automatically from > meta-data of the domain objects, and still require a very small amount of > meta-data for customized components? Yes. Several people have done this for public and commercial projects. Another such project available in public is Magritte, see: http://www.lukas-renggli.ch/smalltalk/magritte http://www.iam.unibe.ch/~scg/Archive/Diploma/Reng06a.pdf > - (meta)operations on those objects Mewa doesn't support that. For Magritte this is only supported on a very basic level, such as for comparison operators, though it is definitely feasible on a more generic level. > A meta-object (in this discussion) is NOT a class; rather, it is a > proxy-like object carrying meta-information for a specific domain object > (instance). (The "meta" terminology comes from Mewa). I would not call that proxy, a proxy is something that is on the same meta level than the proxied object. A proxy represents the proxied object. It is rather a type object. > A meta-attribute is an object carrying meta-information for the value of a > specific attribute of a specific object. In Magritte attributes and objects are unified, since an attribute is an object again. I don't see why the separation of those would be a benefit, maybe there is a good reason? > A meta-operation is an object carrying meta-information for a specific > operation that might be invoked on a specific object. OMG provides such a model called EMOF. Especially your code looks a lot like EMOF. When I started with Magritte I didn't know about this model, however I will try adapt Magritte to bring it closer to EMOF with the next major version. So far the evolution of Magritte was solely driven by requirements we had when developing new Web applications. > In combination these three carry all the information needed to construct > components. I don't think so. My experience shows that this only works for very simple user interfaces and very simple domain models without much semantics and behvior, such as for an editor/viewer of a relational database. > Assume there is a component tree consisting of nested viewers and editors. Magritte builds such trees, but allows you to customize any aspect of the generation, this is to manually display or change the default behavior using Smalltalk code. I think the possibility to do this is key to a meta-level framework that should be usable in different contexts. > joe -- meta-object > joe#name -- meta-attribute > joe#name= -- meta-operation > joe#houses -- meta-attribute > home -- meta-object > home#address -- meta-attribute > "123 hometown" -- metaobject, optimized away > home#rooms -- meta-attribute > room1 -- meta-object > room2 > vacation_home > joe#friends > bob Both, Mewa and Magritte can do that. I am missing how the behavior fits in there you described at the beginning of your mail. > CLAIM: The component tree should exactly parallel this metaobject and > metaattribute structure (by default). So here are the components in that > tree, and the (meta)-things they connect to: The parallelity does not work in general as I explained above. > As always, some of the elements in the above tree might change dynamically > with Ajax e.g. a viewer might be replaced by an editor when the little > "edit" link is clicked; but the editor would still be attached to the same > meta-instance. I have such an extension for Magritte, though it is (currently) only used in a commercial project. > I believe all the components in this tree could be generic by default, all > the meta-objects constructed automatically given a few meta-data hints. This doesn't work either. People need custom components for custom projects. > Not sure how Seaside deals with Ajax right now, but we might need some event > machinery between the tree and domain objects so an (Ajax) operation that > replaced one component might also update other parts of related components > in the tree. Ajax-induced updates would propagate up to the tree root > collecting component updates, before going back to the client. http://scriptaculous.seasidehosting.st Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Hi Lukas,
> Hi ItsYou, er, that would be "itsme" :-) > Another such project available in public is Magritte, That looks great! >> - (meta)operations on those objects > > Mewa doesn't support that. For Magritte this is only supported on a > very basic level, such as for comparison operators, though it is > definitely feasible on a more generic level. OK. >> A meta-object (in this discussion) is NOT a class; rather, it is a >> proxy-like object carrying meta-information for a specific domain object >> (instance). (The "meta" terminology comes from Mewa). > > I would not call that proxy, a proxy is something that is on the same > meta level than the proxied object. A proxy represents the proxied > object. It is rather a type object. The usual multipicity of typeObject:object is 1:N. Not so for these meta-objects. I prefer to call them "objectReflections", see below. >> A meta-attribute is an object carrying meta-information for the value of >> a >> specific attribute of a specific object. > > In Magritte attributes and objects are unified, since an attribute is > an object again. I don't see why the separation of those would be a > benefit, maybe there is a good reason? But an attribute is NOT an object. The #value of an attribute, for a specific owner object, IS an object. This is a big difference. Suppose joe home = 111USA then joe metaAttributeFor: #home , or joe attributeReflectionFor: #home is an object that encapsulates owner = joe attr = #home value = 111USA e.g. the object 111USA would know nothing about the label "home", but the metaAttribute would. This can also provide a single context for creating objects. The Meta-properties of an attribute include "own / create: Boolean". This attribute should be orthogonal to the multiplicity property (a mistake in Mewa, imo). Every domain object is created in the context of such a meta-attribute, and is automatically owned by the owner of that attribute. There is no need for special treatment of the object collections of the top-level domain object, just give it some "own/create" attributes. This works cleaner and more uniformly than the current Mewa example. One can sometimes force this onto the object, but this is often a mistake. e.g. if I have a class Person, each person can play many different roles (e.g. referred via attributes of other objects): author, father, project manager, ... >> A meta-operation is an object carrying meta-information for a specific >> operation that might be invoked on a specific object. > > OMG provides such a model called EMOF. Especially your code looks a > lot like EMOF. If I have joe with operation >>walk, then I have as many instances of the meta-operation >>walk on joe, as I have components that might invoke >>walk on joe. EMOF does not have such a concept, afaik. Perhaps it is not sufficiently informed by Smalltalk-ish concepts like closures :-) I don't really like the use of the word 'meta' here either, just borrowed what Mewa used. I prefer something like: - objectReflection - attributeReflection - operationReflection > When I started with Magritte I didn't know about this > model, however I will try adapt Magritte to bring it closer to EMOF Good to know, there may be tools you can then leverage. >> In combination these three carry all the information needed to construct >> components. > > I don't think so. My experience shows that this only works for very > simple user interfaces and very simple domain models without much > semantics and behvior, such as for an editor/viewer of a relational > database. Don't you think using operationReflection (expanded, of course) more fully could improve this? The kinds of patterns that show up in these semantics and behaviors are amenable to this, imho. >> joe -- meta-object >> joe#name -- meta-attribute >> joe#name= -- meta-operation >> joe#houses -- meta-attribute >> home -- meta-object >> home#address -- meta-attribute >> "123 hometown" -- metaobject, optimized away >> home#rooms -- meta-attribute >> room1 -- meta-object >> room2 >> vacation_home >> joe#friends >> bob > > Both, Mewa and Magritte can do that. I am missing how the behavior > fits in there you described at the beginning of your mail. See joe#name=. I should have shown more operationReflection in the example. e.g. (joe houses at: 1) metaOperationFor: #sell could be another operationReflection. These operationReflections correctly encapsulate parameters required, currently chosen of parameter values, available selections of parameter values, enabling/disabling of the operation, etc. >> CLAIM: The component tree should exactly parallel this metaobject and >> metaattribute structure (by default). So here are the components in that >> tree, and the (meta)-things they connect to: > > The parallelity does not work in general as I explained above. Hmm. Why not? There is a DOM-tree in the browser, and a parallel component tree in the server. All I am suggesting is that every node of the component tree be one of: - objectNode -- attached to an objectReflection - attributeNode -- attached to an attributeReflection - operationNode -- attached to an operationReflection >> As always, some of the elements in the above tree might change >> dynamically >> with Ajax e.g. a viewer might be replaced by an editor when the little >> "edit" link is clicked; but the editor would still be attached to the >> same >> meta-instance. > > I have such an extension for Magritte, though it is (currently) only > used in a commercial project. Any plans to release it? Is Magritte very experimental, or tested and robust? >> I believe all the components in this tree could be generic by default, >> all >> the meta-objects constructed automatically given a few meta-data hints. > > This doesn't work either. People need custom components for custom > projects. True. Hopefully small, encapsulated deltas that can be composed. Once we work at the meta-level we need a set of operations to compose these meta-objects as objects and derive their resulting composite properties, including propagating defaults, overriding, adding/appending, etc. just like class inheritance is largely hard-coded today into class structure. >> Not sure how Seaside deals with Ajax right now, but we might need some >> event >> machinery between the tree and domain objects so an (Ajax) operation that >> replaced one component might also update other parts of related >> components >> in the tree. Ajax-induced updates would propagate up to the tree root >> collecting component updates, before going back to the client. > > http://scriptaculous.seasidehosting.st Looks nice! Cheers, Itsme :_) _______________________________________________ Seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Free forum by Nabble | Edit this page |