1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
14 \use_numerical_citations 0
15 \paperorientation portrait
18 \paragraph_separation indent
20 \quotes_language english
24 \paperpagestyle default
31 Drew Crapmsie, José Pablo Ezequiel
32 \begin_inset Quotes eld
36 \begin_inset Quotes erd
47 Protocol A Protocol for introspection on relational objects.
51 Presentations A Mewa-like
57 http://www.adrian-lienhard.ch/files/mewa.pdf
66 http://common-lisp.net/project/ucw/
75 LISP-ON-LINES (LOL) is a framework for rapid development of complex data-driven
86 First we start with the data model.
87 The Meta Model Protocol (MMP) is used to provide information on the data
88 objects and how they relate to one another.
89 Its is currently implemented as a layer over CLSQL
98 , although support is planned for other backends (CLOS, Elephant[4], whatever).
101 The MMP shares its definition syntax with CLSQL's Object Oriented Data Definitio
108 http://clsql.b9.com/manual/ref-ooddl.html
114 Shouldn't this footnote be a bibliographical entry ? or something like that
122 The macro to define view-classes is named DEF-VIEW-CLASS/META, and takes
123 the same arguments as DEF-VIEW-CLASS from CLSQL.
124 For the purposes of this simple example, we will only need two functions
125 from the MMP beyond what CLSQL provides : LIST-SLOTS and LIST-SLOT-TYPES[5].
128 We'll define a simple class to hold a user.
131 (def-view-class/meta user ()
134 ((userid :initarg :userid :accessor userid :type integer :db-kind :key)
137 (username :initarg :username :accessor username :type string :db-kind
141 (password :initarg :password :accessor password :type string :db-kind
145 and now we create a user:
148 (defparameter user (make-instance 'user :userid 1
154 :password "p@ssw0rd"))
157 We can see the slots of users running:
160 (lisp-on-lines::list-slots user)
166 (USERID USERNAME PASSWORD)
172 (lisp-on-lines::list-slot-types user)
178 ((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING))
184 (lisp-on-lines::default-attributes user)
190 ((userid integer :label "User ID" :slot-name 'userid)
193 (username string :label "User name" :slot-name 'username)
196 (password string :label "Password" :slot-name 'password))
202 (set-default-attributes user)
209 ((userid integer :label "User ID" :slot-name 'userid)
212 (username string :label "User name" :slot-name 'username)
215 (password string :label "Password" :slot-name 'password))
220 (find-class-attributes user)
223 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
226 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
229 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
235 LISP-ON-LINES> ;;;; note that the mewa functions (find-attribute, set-attribute
236 etc) can take either an instance, or a class-name as a symbol , ie :
242 LISP-ON-LINES> (find-class-attributes 'user)
245 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
248 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
251 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
257 LISP-ON-LINES> (find-class-attributes (make-instance 'user))
260 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
263 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
266 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
275 Using that information, we have enough to create an interface to the object.
276 UncommonWeb includes a powerful presentation system, but it is not quite
277 dynamic enough for our needs.
278 Mewa defines an approach to presentations that suits our purposes, but
279 the paper is written from a smalltalk point of view.
280 A mixture of the two , Mewa Presentations(MP), is described here.
283 MP introduces to UCW the concept of attributes.
284 an attribute is essentially a named version of the defpresentation slot-like
289 (defpresentation person-editor (object-presentation)
292 ((string :label "First Name" :slot-name 'first-name :max-length 30)))
295 the (string :label "First Name" ...) form is an attribute definiton.
296 Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run
297 time (where the current system is done at compile time) to display the
299 This allows a very flexible system of displaying objects which is reminiscent
301 I discovered this, rather than invent or design it, so there are some rough
302 edges, but its a good start.
305 Its much easier to show this then to tell.
306 Lets present our user class.
307 Currently in UCW, you'd define a presentation as such :
310 (defpresentation user-presentation (object-presentation)
313 ((INTEGER :LABEL "USERID" :SLOT-NAME USERID)
316 (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
319 (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)))
322 which could be presented using PRESENT-OBJECT :
325 (present-object user :using 'user-presentation)
328 The equiv approach using mewa presentations is actually longer and more
329 verbose(!) but it serves to demonstrate how the MP system works.
332 Mewa Presentations adds a set of attributes to a class, keyed off the class
334 Attributes are inherited, so if you define an attribute on T, you can use
338 MP stores named attributes keyed on a class name.
339 to achieve the same functionality as the above using mp would look like
343 LISP-ON-LINES> (setf (find-attribute 'user :viewer) '(mewa-object-presentation
344 :attributes (userid username password) :global-properties (:editablep nil)))
347 (:VIEWER MEWA-OBJECT-PRESENTATION
353 (USERID USERNAME PASSWORD)
362 LISP-ON-LINES> (setf (find-attribute 'user 'userid) '(INTEGER :LABEL "USERID"
366 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
369 LISP-ON-LINES> (setf (find-attribute 'user 'username) '(STRING :LABEL "USERNAME"
370 :SLOT-NAME USERNAME))
373 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
376 LISP-ON-LINES> (setf (find-attribute 'user 'password) '(STRING :LABEL "USERNAME"
377 :SLOT-NAME PASSWORD))
380 (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD)
383 LISP-ON-LINES> (find-class-attributes 'user)
386 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
389 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
392 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
395 (:VIEWER MEWA-OBJECT-PRESENTATION
401 (USERID USERNAME PASSWORD)
413 this is all turned into a UCW presentation at runtime using MAKE-PRESENTATION
417 (defmethod render-on ((res response) (e presentations-index))
423 As you'll see, nothing is exported from the LISP-ON-LINES package.
427 if you wish to use LOL in your own package (or in UCW-USER or whatever),
430 you simply need to use the MEWA and META-MODEL packages"
433 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
434 s::user :type :viewer)))
437 SET-ATTRIBUTE can be used in place of (setf (find-attribute)) when you want
438 to "inherit" the properties of an existing attribute definition :
441 LISP-ON-LINES> (set-attribute 'user 'password '(string :label "password:
442 (must be at leat 8 chars)"))
451 "password: (must be at leat 8 chars)"
460 Now we want to create a presentation with which to edit the username.
461 we will use the existing attributes on a subclass of mewa-object-presetation
465 LISP-ON-LINES> (defcomponent user-editor (mewa-object-presentation)
474 :attributes '((username :label "Enter your New Username") password)
477 :global-properties '(:editablep t)))
483 LISP-ON-LINES> (setf (find-attribute 'user :editor) '(user-editor))
486 (:EDITOR USER-EDITOR)
492 which we then can display below our earlier example :
495 (defmethod render-on ((res response) (e presentations-index))
501 As you'll see, nothing is exported from the LISP-ON-LINES package.
505 if you wish to use LOL in your own package (or in UCW-USER or whatever),
508 you simply need to use the MEWA and META-MODEL packages"
511 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
512 s::user :type :viewer))
515 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
516 s::user :type :editor)))
519 that should give you some idea on how it works ..
520 ask me when you get confused :)