moved mewa package definition to packages.lisp and added the lisp-on-lines package
[clinton/lisp-on-lines.git] / lisp-on-lines.txt
1 LISP-ON-LINES 0.1
2
3
4 Components:
5
6 Meta Model Protocol - A Protocol for introspection on relational objects.
7 Mewa Presentations : A Mewa-like[1] layer for UncommonWeb[2] Presentations.
8
9 Description:
10
11 LISP-ON-LINES (LOL) is a framework for rapid development of complex data-driven web appilcations.
12 Introduction:
13
14
15 Example:
16
17 First we start with the data model. The Meta Model Protocol (MMP) is used to provide information on the data objects and how they relate to one another. Its is currently implemented as a layer over CLSQL[3], although support is planned for other backends (CLOS,Elephant[4], whatever).
18
19 The MMP shares its definition syntax with CLSQL's Object Oriented Data Definition Language (OODDL). The macro to define view-classes is named DEF-VIEW-CLASS/META, and takes the same arguments as DEF-VIEW-CLASS from CLSQL. For the purposes of this simple example, we will only need two functions from the MMP beyond what CLSQL provides : LIST-SLOTS and LIST-SLOT-TYPES[5].
20
21 We'll define a simple class to hold a user.
22 LISP-ON-LINES> (def-view-class/meta user ()
23 ((userid :initarg :userid :accessor userid :type integer :db-kind :key)
24 (username :initarg :username :accessor username :type string :db-kind :base)
25 (password :initarg :password :accessor password :type string :db-kind :base)))
26 STYLE-WARNING: redefining META-MODEL.METADATA (USER) in DEFMETHOD
27 #<CLSQL-SYS::STANDARD-DB-CLASS USER>
28 LISP-ON-LINES> (defparameter user (make-instance 'user :userid 1 :username "drewc" :password "p@ssw0rd"))
29 USER
30 LISP-ON-LINES> (list-slots user)
31 (USERID USERNAME PASSWORD)
32 LISP-ON-LINES> (list-slot-types user)
33 ((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING))
34 ; compiling file "/tmp/fileQQsHyN" (written 03 JUN 2005 03:20:06 PM):
35
36 ; /tmp/fileQQsHyN.fasl written
37 ; compilation finished in 0:00:00
38 LISP-ON-LINES> (default-attributes user)
39 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
40 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
41 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
42 LISP-ON-LINES> (set-default-attributes user)
43 ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
44 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
45 (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))
46 LISP-ON-LINES> (find-class-attributes user)
47 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
48 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
49 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
50 COMMON-LISP:NIL)
51 LISP-ON-LINES> ;;;; note that the mewa functions (find-attribute, set-attribute etc) can take either an instance, or a class-name as a symbol , ie :
52 ; No value
53 LISP-ON-LINES> (find-class-attributes 'user)
54 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
55 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
56 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
57 COMMON-LISP:NIL)
58 LISP-ON-LINES> (find-class-attributes (make-instance 'user))
59 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
60 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
61 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
62 COMMON-LISP:NIL)
63 LISP-ON-LINES>
64
65 Using that information, we have enough to create an interface to the object. UncommonWeb includes a powerful presentation system, but it is not quite dynamic enough for our needs. Mewa defines an approach to presentations that suits our purposes, but the paper is written from a smalltalk point of view. A mixture of the two , Mewa Presentations(MP), is described here.
66
67 MP introduces to UCW the concept of attributes. an attribute is essentially a named version of the defpresentation slot-like arguments. for example in :
68
69 (defpresentation person-editor (object-presentation)
70 ((string :label "First Name" :slot-name 'first-name :max-length 30)))
71
72 the (string :label "First Name" ...) form is an attribute definiton. Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run time (where the current system is done at compile time) to display the object. This allows a very flexible system of displaying objects which is reminiscent of CSS. I discovered this, rather than invent or design it, so there are some rough edges, but its a good start.
73
74 Its much easier to show this then to tell. Lets present our user class. Currently in UCW, you'd define a presentation as such :
75
76 (defpresentation user-presentation (object-presentation)
77 ((INTEGER :LABEL "USERID" :SLOT-NAME USERID)
78 (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
79 (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)))
80
81 which could be presented using PRESENT-OBJECT :
82
83 (present-object user :using 'user-presentation)
84
85 The equiv approach using mewa presentations is actually longer and more verbose(!) but it serves to demonstrate how the MP system works.
86
87 Mewa Presentations adds a set of attributes to a class, keyed off the class name. Attributes are inherited, so if you define an attribute on T, you can use it with any class.
88
89 MP stores named attributes keyed on a class name. to achieve the same functionality as the above using mp would look like this :
90
91 LISP-ON-LINES> (setf (find-attribute 'user :viewer) '(mewa-object-presentation :attributes (userid username password) :global-properties (:editablep nil)))
92 (:VIEWER MEWA-OBJECT-PRESENTATION
93 :ATTRIBUTES
94 (USERID USERNAME PASSWORD)
95 :GLOBAL-PROPERTIES
96 (:EDITABLEP NIL))
97 LISP-ON-LINES> (setf (find-attribute 'user 'userid) '(INTEGER :LABEL "USERID" :SLOT-NAME USERID))
98 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
99 LISP-ON-LINES> (setf (find-attribute 'user 'username) '(STRING :LABEL "USERNAME" :SLOT-NAME USERNAME))
100 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
101 LISP-ON-LINES> (setf (find-attribute 'user 'password) '(STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD))
102 (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD)
103
104 LISP-ON-LINES> (find-class-attributes 'user)
105 (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)
106 (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME)
107 (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID)
108 (:VIEWER MEWA-OBJECT-PRESENTATION
109 :ATTRIBUTES
110 (USERID USERNAME PASSWORD)
111 :GLOBAL-PROPERTIES
112 (:EDITABLEP NIL))
113 COMMON-LISP:NIL)
114
115
116 this is all turned into a UCW presentation at runtime using MAKE-PRESENTATION :
117
118 (defmethod render-on ((res response) (e presentations-index))
119 "
120 As you'll see, nothing is exported from the LISP-ON-LINES package.
121 if you wish to use LOL in your own package (or in UCW-USER or whatever),
122 you simply need to use the MEWA and META-MODEL packages"
123 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-lines::user :type :viewer)))
124
125
126 SET-ATTRIBUTE can be used in place of (setf (find-attribute)) when you want to "inherit" the properties of an existing attribute definition :
127
128 LISP-ON-LINES> (set-attribute 'user 'password '(string :label "password: (must be at leat 8 chars)"))
129 (PASSWORD STRING
130 :LABEL
131 "password: (must be at leat 8 chars)"
132 :SLOT-NAME
133 PASSWORD)
134
135
136 Now we want to create a presentation with which to edit the username. we will use the existing attributes on a subclass of mewa-object-presetation :
137
138 LISP-ON-LINES> (defcomponent user-editor (mewa-object-presentation)
139 ()
140 (:default-initargs
141 :attributes '((username :label "Enter your New Username") password)
142 :global-properties '(:editablep t)))
143 USER-EDITOR
144 LISP-ON-LINES> (setf (find-attribute 'user :editor) '(user-editor))
145 (:EDITOR USER-EDITOR)
146 LISP-ON-LINES>
147
148
149 which we then can display below our earlier example :
150
151 (defmethod render-on ((res response) (e presentations-index))
152 "
153 As you'll see, nothing is exported from the LISP-ON-LINES package.
154 if you wish to use LOL in your own package (or in UCW-USER or whatever),
155 you simply need to use the MEWA and META-MODEL packages"
156 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-lines::user :type :viewer))
157 (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-lines::user :type :editor)))
158
159
160
161 that should give you some idea on how it works .. ask me when you get confused :)
162
163
164
165
166
167
168
169
170
171
172