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
38 \begin_inset Quotes eld
42 \begin_inset Quotes erd
52 is a very useful module that works on top of the
56 framework to do rapid developing of complex data-driven web appilcations
70 The conventions used in this manual are:
73 Lisp code is shown as a monospace font.
74 It is assumed that the user is working in an interactive environment and
75 what the user should type appears as bold, for example:
88 Names of people or products are show as small caps, like
105 require further revision.
111 ToDo: Add more conventions as they are needed, possible classes of text:
112 names of concepts, name of programming entities, like variables, functions,
113 etc (which are embedded in text, should they be shown monospaced ?).
121 Protocol A Protocol for introspection on relational objects.
125 Presentations A Mewa-like
131 http://www.adrian-lienhard.ch/files/mewa.pdf
134 layer for UncommonWeb
140 http://common-lisp.net/project/ucw/
149 First we start with the data model.
150 The Meta Model Protocol (MMP) is used to provide information on the data
151 objects and how they relate to one another.
152 Its is currently implemented as a layer over CLSQL
161 , although support is planned for other backends (
172 The MMP shares its definition syntax with
178 's Object Oriented Data Definition Language (OODDL)
184 http://clsql.b9.com/manual/ref-ooddl.html
190 Shouldn't this footnote be a bibliographical entry ? or something like that
198 The macro to define view-classes is named DEF-VIEW-CLASS/META, and takes
199 the same arguments as DEF-VIEW-CLASS from CLSQL.
200 For the purposes of this simple example, we will only need two functions
201 from the MMP beyond what CLSQL provides : LIST-SLOTS and LIST-SLOT-TYPES[5].
204 We'll define a simple class to hold a user.
209 (def-view-class/meta user ()
214 ((userid :initarg :userid :accessor userid :type integer :db-kind :key)
219 (username :initarg :username :accessor username :type string :db-kind
225 (password :initarg :password :accessor password :type string :db-kind
229 and now we create a user:
234 (defparameter user (make-instance 'user :userid 1
244 :password "p@ssw0rd"))
247 We can see the slots of users running:
252 (lisp-on-lines::list-slots user)
255 (USERID USERNAME PASSWORD)
263 (lisp-on-lines::list-slot-types user)
266 ((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING))
274 (lisp-on-lines::default-attributes user)
277 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
280 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
283 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
291 (set-default-attributes user)
294 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
297 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
300 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
308 (lisp-on-lines::find-class-attributes user)
311 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
314 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
317 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
323 note that the mewa functions (find-attribute, set-attribute etc) can take
324 either an instance, or a class-name as a symbol:
329 (lisp-on-lines::find-class-attributes 'user)
332 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
335 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
338 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
346 (lisp-on-lines::find-class-attributes (make-instance 'user))
349 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
352 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
355 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
361 Using that information, we have enough to create an interface to the object.
362 UncommonWeb includes a powerful presentation system, but it is not quite
363 dynamic enough for our needs.
364 Mewa defines an approach to presentations that suits our purposes, but
365 the paper is written from a smalltalk point of view.
366 A mixture of the two , Mewa Presentations(MP), is described here.
369 MP introduces to UCW the concept of attributes.
370 an attribute is essentially a named version of the defpresentation slot-like
375 (defpresentation person-editor (object-presentation)
378 ((string :label "First Name" :slot-name 'first-name :max-length 30)))
381 the (string :label "First Name" ...) form is an attribute definiton.
382 Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run
383 time (where the current system is done at compile time) to display the
385 This allows a very flexible system of displaying objects which is reminiscent
387 I discovered this, rather than invent or design it, so there are some rough
388 edges, but its a good start.
391 Its much easier to show this then to tell.
392 Lets present our user class.
393 Currently in UCW, you'd define a presentation as such :
396 (defpresentation user-presentation (object-presentation)
399 ((INTEGER :LABEL "USERID" :SLOT-NAME USERID)
402 (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
405 (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)))
408 which could be presented using PRESENT-OBJECT :
411 (present-object user :using 'user-presentation)
414 The equiv approach using mewa presentations is actually longer and more
415 verbose(!) but it serves to demonstrate how the MP system works.
418 Mewa Presentations adds a set of attributes to a class, keyed off the class
420 Attributes are inherited, so if you define an attribute on T, you can use
424 MP stores named attributes keyed on a class name.
425 to achieve the same functionality as the above using mp would look like
429 LISP-ON-LINES> (setf (find-attribute 'user :viewer) '(mewa-object-presentation
430 :attributes (userid username password) :global-properties (:editablep nil)))
433 (:VIEWER MEWA-OBJECT-PRESENTATION
439 (USERID USERNAME PASSWORD)
448 LISP-ON-LINES> (setf (find-attribute 'user 'userid) '(INTEGER :LABEL "USERID"
452 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
455 LISP-ON-LINES> (setf (find-attribute 'user 'username) '(STRING :LABEL "USERNAME"
456 :SLOT-NAME USERNAME))
459 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
462 LISP-ON-LINES> (setf (find-attribute 'user 'password) '(STRING :LABEL "USERNAME"
463 :SLOT-NAME PASSWORD))
466 (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD)
469 LISP-ON-LINES> (find-class-attributes 'user)
472 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
475 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
478 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
481 (:VIEWER MEWA-OBJECT-PRESENTATION
487 (USERID USERNAME PASSWORD)
499 this is all turned into a UCW presentation at runtime using MAKE-PRESENTATION
503 (defmethod render-on ((res response) (e presentations-index))
509 As you'll see, nothing is exported from the LISP-ON-LINES package.
513 if you wish to use LOL in your own package (or in UCW-USER or whatever),
516 you simply need to use the MEWA and META-MODEL packages"
519 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
520 s::user :type :viewer)))
523 SET-ATTRIBUTE can be used in place of (setf (find-attribute)) when you want
524 to "inherit" the properties of an existing attribute definition :
527 LISP-ON-LINES> (set-attribute 'user 'password '(string :label "password:
528 (must be at leat 8 chars)"))
537 "password: (must be at leat 8 chars)"
546 Now we want to create a presentation with which to edit the username.
547 we will use the existing attributes on a subclass of mewa-object-presetation
551 LISP-ON-LINES> (defcomponent user-editor (mewa-object-presentation)
560 :attributes '((username :label "Enter your New Username") password)
563 :global-properties '(:editablep t)))
569 LISP-ON-LINES> (setf (find-attribute 'user :editor) '(user-editor))
572 (:EDITOR USER-EDITOR)
578 which we then can display below our earlier example :
581 (defmethod render-on ((res response) (e presentations-index))
587 As you'll see, nothing is exported from the LISP-ON-LINES package.
591 if you wish to use LOL in your own package (or in UCW-USER or whatever),
594 you simply need to use the MEWA and META-MODEL packages"
597 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
598 s::user :type :viewer))
601 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
602 s::user :type :editor)))
605 that should give you some idea on how it works ..
606 ask me when you get confused :)