1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
11 \paperpackage widemarginsa4
15 \use_numerical_citations 0
16 \paperorientation portrait
19 \paragraph_separation indent
21 \quotes_language english
25 \paperpagestyle default
39 \begin_inset Quotes eld
43 \begin_inset Quotes erd
53 is a very useful module that works on top of the
57 framework to do rapid developing of complex data-driven web appilcations
72 was founded and developed and continues to be developed and mantained by
83 The conventions used in this manual are:
86 Lisp code is shown as a monospace font.
87 It is assumed that the user is working in an interactive environment and
88 what the user should type appears as bold, for example:
101 Names of people or products are show as small caps, like
116 require further revision.
121 ToDo: Add more conventions as they are needed, possible classes of text:
122 names of concepts, name of programming entities, like variables, functions,
123 etc (which are embedded in text, should they be shown monospaced ?).
131 Protocol A Protocol for introspection on relational objects.
135 Presentations A Mewa-like
141 http://www.adrian-lienhard.ch/files/mewa.pdf
144 layer for UncommonWeb
150 http://common-lisp.net/project/ucw/
159 First we start with the data model.
160 The Meta Model Protocol (MMP) is used to provide information on the data
161 objects and how they relate to one another.
162 Its is currently implemented as a layer over CLSQL
171 , although support is planned for other backends (
182 The MMP shares its definition syntax with
188 's Object Oriented Data Definition Language (OODDL)
194 http://clsql.b9.com/manual/ref-ooddl.html
200 Shouldn't this footnote be a bibliographical entry ? or something like that
208 The macro to define view-classes is named DEF-VIEW-CLASS/META, and takes
209 the same arguments as DEF-VIEW-CLASS from CLSQL.
210 For the purposes of this simple example, we will only need two functions
211 from the MMP beyond what CLSQL provides : LIST-SLOTS and LIST-SLOT-TYPES[5].
214 We'll define a simple class to hold a user.
219 (def-view-class/meta user ()
224 ((userid :initarg :userid :accessor userid :type integer :db-kind :key)
229 (username :initarg :username :accessor username :type string :db-kind
235 (password :initarg :password :accessor password :type string :db-kind
239 and now we create a user:
244 (defparameter user (make-instance 'user :userid 1
254 :password "p@ssw0rd"))
257 We can see the slots of users running:
262 (lisp-on-lines::list-slots user)
265 (USERID USERNAME PASSWORD)
273 (lisp-on-lines::list-slot-types user)
276 ((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING))
279 To see the default attributes of a class
280 \begin_inset Marginal
285 Is this correct ? Drew, please, check.
293 (lisp-on-lines::default-attributes user)
296 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
299 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
302 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
305 To set the attributes of a class to the default values we use:
310 (lisp-on-lines::set-default-attributes user)
313 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
316 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
319 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
322 which takes an object of the class we are working with.
323 This is going to be change so we can do this action directly on the class.
324 It is on the TODO file.
332 (lisp-on-lines::find-class-attributes user)
335 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
338 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
341 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
347 note that the mewa functions (find-attribute, set-attribute etc) can take
348 either an instance, or a class-name as a symbol:
353 (lisp-on-lines::find-class-attributes 'user)
356 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
359 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
362 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
370 (lisp-on-lines::find-class-attributes (make-instance 'user))
373 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
376 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
379 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
385 Using that information, we have enough to create an interface to the object.
390 includes a powerful presentation system
396 To see this system in action, we strongly recomend to study the presentations
397 example which comes with
402 Reading components/presentations.lisp can help understand a lot about how
403 presentations are built.
406 , but it is not dynamic enough for some of the most advanced applications.
407 Mewa defines an approach to presentations that solves that problem, but
408 the paper is written from a
413 A mixture of the two , Mewa Presentations(MP), is described here.
425 An attribute is essentially a named version of the DEFPRESENTATION slot-like
426 arguments, for example in :
431 (defpresentation person-editor (object-presentation)
436 ((string :label "First Name" :slot-name 'first-name :max-length 30)))
439 the (string :label "First Name" ...) form is an attribute definiton.
440 Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run
445 's presentation system is done at compile time) to display the object.
446 This allows a very flexible system of displaying objects which is reminiscent
461 discovered this, rather than invent or design it, so there are some rough
462 edges, but its a good start.
468 Its much easier to show this than to tell.
469 Lets present our user class.
474 , you'd define a presentation as such :
479 (defpresentation user-presentation (object-presentation)
482 ((INTEGER :LABEL "USERID" :SLOT-NAME USERID)
485 (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
488 (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)))
491 which could be presented using PRESENT-OBJECT :
496 (present-object user :using 'user-presentation)
499 The equivalent approach using mewa presentations is actually longer and
500 more verbose(!) but it serves to demonstrate how the MP system works.
503 Mewa Presentations adds a set of attributes to a class, keyed off the class
505 Attributes are inherited, so if you define an attribute on T, you can use
509 MP stores named attributes keyed on a class name.
510 To achieve the same functionality as the above using mp would look like
516 (setf (lisp-on-lines::find-attribute 'user :viewer)
517 \begin_inset Marginal
522 Isn't this too imperative (in contrast to functional, lispy).
530 '(lisp-on-lines::mewa-object-presentation
535 :attributes (userid username password)
540 :global-properties (:editablep nil)))
543 (:VIEWER MEWA-OBJECT-PRESENTATION
549 (USERID USERNAME PASSWORD)
560 (setf (lisp-on-lines::find-attribute 'user 'userid)
561 \begin_inset Marginal
566 Are this setfs to 'userid, 'username and 'password needed ? I (Pupeno) inspected
567 they contents at of this moment and they seem to already contain what they
576 '(integer :label "userid" :slot-name userid))
579 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
584 (setf (lisp-on-lines::find-attribute 'user 'username)
589 '(STRING :LABEL "USERNAME" :SLOT-NAME USERNAME))
592 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
597 (setf (lisp-on-lines::find-attribute 'user 'password)
602 '(STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD))
605 (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD)
610 (lisp-on-lines::find-class-attributes 'user)
616 (:VIEWER MEWA-OBJECT-PRESENTATION
622 (USERID USERNAME PASSWORD)
631 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
634 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
637 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
643 this is all turned into a
647 presentation at runtime using MAKE-PRESENTATION, for example, the following
648 code should be enough to show what's built so far attached to the examples
654 (defcomponent lol-example (window-component)
664 (defmethod render-on ((res response) (lol-example lol-example))
674 (<ucw:render-component :component (lisp-on-lines::make-presentation
675 user :type :viewer)))
680 (defentry-point "lol.ucw" (:application *example-application*) ()
685 (call 'products-presentation))
688 As you'll see, nothing is exported from the LISP-ON-LINES package.
689 If you wish to use LOL in your own package (or in UCW-USER or whatever),
690 you simply need to use the MEWA and META-MODEL packages.
693 SET-ATTRIBUTE can be used in place of (setf (find-attribute)) when you want
694 to "inherit" the properties of an existing attribute definition :
697 LISP-ON-LINES> (set-attribute 'user 'password '(string :label "password:
698 (must be at leat 8 chars)"))
707 "password: (must be at leat 8 chars)"
716 Now we want to create a presentation with which to edit the username.
717 we will use the existing attributes on a subclass of mewa-object-presetation
721 LISP-ON-LINES> (defcomponent user-editor (mewa-object-presentation)
730 :attributes '((username :label "Enter your New Username") password)
733 :global-properties '(:editablep t)))
739 LISP-ON-LINES> (setf (find-attribute 'user :editor) '(user-editor))
742 (:EDITOR USER-EDITOR)
748 which we then can display below our earlier example :
751 (defmethod render-on ((res response) (e presentations-index))
757 As you'll see, nothing is exported from the LISP-ON-LINES package.
761 if you wish to use LOL in your own package (or in UCW-USER or whatever),
764 you simply need to use the MEWA and META-MODEL packages"
767 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
768 s::user :type :viewer))
771 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line
772 s::user :type :editor)))
775 that should give you some idea on how it works ..
776 ask me when you get confused :)