Commit | Line | Data |
---|---|---|
792bdc71 JPEPFS |
1 | #LyX 1.3 created this file. For more info see http://www.lyx.org/ |
2 | \lyxformat 221 | |
3 | \textclass article | |
4 | \language english | |
5 | \inputencoding auto | |
6 | \fontscheme default | |
7 | \graphics default | |
8 | \paperfontsize default | |
9 | \papersize Default | |
10 | \paperpackage a4 | |
11 | \use_geometry 0 | |
12 | \use_amsmath 0 | |
13 | \use_natbib 0 | |
14 | \use_numerical_citations 0 | |
15 | \paperorientation portrait | |
16 | \secnumdepth 3 | |
17 | \tocdepth 3 | |
18 | \paragraph_separation indent | |
19 | \defskip medskip | |
20 | \quotes_language english | |
21 | \quotes_times 2 | |
22 | \papercolumns 1 | |
23 | \papersides 1 | |
24 | \paperpagestyle default | |
25 | ||
26 | \layout Title | |
27 | ||
28 | LISP-ON-LINES | |
29 | \layout Section | |
30 | ||
31 | Components | |
32 | \layout Description | |
33 | ||
34 | Meta\SpecialChar ~ | |
35 | Model\SpecialChar ~ | |
36 | Protocol A Protocol for introspection on relational objects. | |
37 | \layout Description | |
38 | ||
39 | Mewa\SpecialChar ~ | |
40 | Presentations A Mewa-like | |
41 | \begin_inset Foot | |
42 | collapsed true | |
43 | ||
44 | \layout Standard | |
45 | ||
46 | http://www.adrian-lienhard.ch/files/mewa.pdf | |
47 | \end_inset | |
48 | ||
49 | layer for UncommonWeb | |
50 | \begin_inset Foot | |
51 | collapsed true | |
52 | ||
53 | \layout Standard | |
54 | ||
55 | http://common-lisp.net/project/ucw/ | |
56 | \end_inset | |
57 | ||
58 | Presentations. | |
59 | \layout Section | |
60 | ||
61 | Description | |
62 | \layout Standard | |
63 | ||
64 | LISP-ON-LINES (LOL) is a framework for rapid development of complex data-driven | |
65 | web appilcations. | |
66 | ||
67 | \layout Section | |
68 | ||
69 | Introduction: | |
70 | \layout Section | |
71 | ||
72 | Example: | |
73 | \layout Standard | |
74 | ||
75 | First we start with the data model. | |
76 | The Meta Model Protocol (MMP) is used to provide information on the data | |
77 | objects and how they relate to one another. | |
78 | Its is currently implemented as a layer over CLSQL | |
79 | \begin_inset Foot | |
80 | collapsed true | |
81 | ||
82 | \layout Standard | |
83 | ||
84 | http://clsql.b9.com/ | |
85 | \end_inset | |
86 | ||
87 | , although support is planned for other backends (CLOS, Elephant[4], whatever). | |
88 | \layout Standard | |
89 | ||
90 | The MMP shares its definition syntax with CLSQL's Object Oriented Data Definitio | |
91 | n Language (OODDL) | |
92 | \begin_inset Foot | |
93 | collapsed true | |
94 | ||
95 | \layout Standard | |
96 | ||
97 | http://clsql.b9.com/manual/ref-ooddl.html | |
98 | \begin_inset Note | |
99 | collapsed true | |
100 | ||
101 | \layout Standard | |
102 | ||
103 | Shouldn't this footnote be a bibliographical entry ? or something like that | |
104 | ? | |
105 | \end_inset | |
106 | ||
107 | ||
108 | \end_inset | |
109 | ||
110 | . | |
111 | The macro to define view-classes is named DEF-VIEW-CLASS/META, and takes | |
112 | the same arguments as DEF-VIEW-CLASS from CLSQL. | |
113 | For the purposes of this simple example, we will only need two functions | |
114 | from the MMP beyond what CLSQL provides : LIST-SLOTS and LIST-SLOT-TYPES[5]. | |
115 | \layout Standard | |
116 | ||
117 | We'll define a simple class to hold a user. | |
118 | \layout LyX-Code | |
119 | ||
120 | (def-view-class/meta user () | |
121 | \layout LyX-Code | |
122 | ||
123 | ((userid :initarg :userid :accessor userid :type integer :db-kind :key) | |
124 | \layout LyX-Code | |
125 | ||
126 | (username :initarg :username :accessor username :type string :db-kind | |
127 | :base) | |
128 | \layout LyX-Code | |
129 | ||
130 | (password :initarg :password :accessor password :type string :db-kind | |
131 | :base))) | |
132 | \layout LyX-Code | |
133 | ||
134 | \layout LyX-Code | |
135 | ||
136 | STYLE-WARNING: redefining META-MODEL.METADATA (USER) in DEFMETHOD | |
137 | \layout LyX-Code | |
138 | ||
139 | #<CLSQL-SYS::STANDARD-DB-CLASS USER> | |
140 | \layout LyX-Code | |
141 | ||
142 | \layout LyX-Code | |
143 | ||
144 | (defparameter user (make-instance 'user :userid 1 | |
145 | \layout LyX-Code | |
146 | ||
147 | :username "drewc" | |
148 | \layout LyX-Code | |
149 | ||
150 | :password "p@ssw0rd")) | |
151 | \layout LyX-Code | |
152 | ||
153 | \layout LyX-Code | |
154 | ||
155 | USER | |
156 | \layout LyX-Code | |
157 | ||
158 | \layout LyX-Code | |
159 | ||
160 | LISP-ON-LINES> (list-slots user) | |
161 | \layout LyX-Code | |
162 | ||
163 | (USERID USERNAME PASSWORD) | |
164 | \layout LyX-Code | |
165 | ||
166 | LISP-ON-LINES> (list-slot-types user) | |
167 | \layout LyX-Code | |
168 | ||
169 | ((USERID INTEGER) (USERNAME STRING) (PASSWORD STRING)) | |
170 | \layout LyX-Code | |
171 | ||
172 | ; compiling file "/tmp/fileQQsHyN" (written 03 JUN 2005 03:20:06 PM): | |
173 | \layout LyX-Code | |
174 | ||
175 | ; /tmp/fileQQsHyN.fasl written | |
176 | \layout LyX-Code | |
177 | ||
178 | ; compilation finished in 0:00:00 | |
179 | \layout LyX-Code | |
180 | ||
181 | \layout LyX-Code | |
182 | ||
183 | \layout LyX-Code | |
184 | ||
185 | (default-attributes user) | |
186 | \layout LyX-Code | |
187 | ||
188 | ((userid integer :label "User ID" :slot-name 'userid) | |
189 | \layout LyX-Code | |
190 | ||
191 | (username string :label "User name" :slot-name 'username) | |
192 | \layout LyX-Code | |
193 | ||
194 | (password string :label "Password" :slot-name 'password)) | |
195 | \layout LyX-Code | |
196 | ||
197 | \layout LyX-Code | |
198 | ||
199 | LISP-ON-LINES> (set-default-attributes user) | |
200 | \layout LyX-Code | |
201 | ||
202 | ((USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) | |
203 | \layout LyX-Code | |
204 | ||
205 | (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) | |
206 | \layout LyX-Code | |
207 | ||
208 | (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD)) | |
209 | \layout LyX-Code | |
210 | ||
211 | LISP-ON-LINES> (find-class-attributes user) | |
212 | \layout LyX-Code | |
213 | ||
214 | (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) | |
215 | \layout LyX-Code | |
216 | ||
217 | (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) | |
218 | \layout LyX-Code | |
219 | ||
220 | (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) | |
221 | \layout LyX-Code | |
222 | ||
223 | COMMON-LISP:NIL) | |
224 | \layout LyX-Code | |
225 | ||
226 | LISP-ON-LINES> ;;;; note that the mewa functions (find-attribute, set-attribute | |
227 | etc) can take either an instance, or a class-name as a symbol , ie : | |
228 | \layout LyX-Code | |
229 | ||
230 | ; No value | |
231 | \layout LyX-Code | |
232 | ||
233 | LISP-ON-LINES> (find-class-attributes 'user) | |
234 | \layout LyX-Code | |
235 | ||
236 | (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) | |
237 | \layout LyX-Code | |
238 | ||
239 | (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) | |
240 | \layout LyX-Code | |
241 | ||
242 | (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) | |
243 | \layout LyX-Code | |
244 | ||
245 | COMMON-LISP:NIL) | |
246 | \layout LyX-Code | |
247 | ||
248 | LISP-ON-LINES> (find-class-attributes (make-instance 'user)) | |
249 | \layout LyX-Code | |
250 | ||
251 | (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) | |
252 | \layout LyX-Code | |
253 | ||
254 | (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) | |
255 | \layout LyX-Code | |
256 | ||
257 | (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) | |
258 | \layout LyX-Code | |
259 | ||
260 | COMMON-LISP:NIL) | |
261 | \layout LyX-Code | |
262 | ||
263 | LISP-ON-LINES> | |
264 | \layout Standard | |
265 | ||
266 | Using that information, we have enough to create an interface to the object. | |
267 | UncommonWeb includes a powerful presentation system, but it is not quite | |
268 | dynamic enough for our needs. | |
269 | Mewa defines an approach to presentations that suits our purposes, but | |
270 | the paper is written from a smalltalk point of view. | |
271 | A mixture of the two , Mewa Presentations(MP), is described here. | |
272 | \layout Standard | |
273 | ||
274 | MP introduces to UCW the concept of attributes. | |
275 | an attribute is essentially a named version of the defpresentation slot-like | |
276 | arguments. | |
277 | for example in : | |
278 | \layout Standard | |
279 | ||
280 | (defpresentation person-editor (object-presentation) | |
281 | \layout Standard | |
282 | ||
283 | ((string :label "First Name" :slot-name 'first-name :max-length 30))) | |
284 | \layout Standard | |
285 | ||
286 | the (string :label "First Name" ...) form is an attribute definiton. | |
287 | Attributes are accessed through FIND-ATTIRIBUTES, and are composed at run | |
288 | time (where the current system is done at compile time) to display the | |
289 | object. | |
290 | This allows a very flexible system of displaying objects which is reminiscent | |
291 | of CSS. | |
292 | I discovered this, rather than invent or design it, so there are some rough | |
293 | edges, but its a good start. | |
294 | \layout Standard | |
295 | ||
296 | Its much easier to show this then to tell. | |
297 | Lets present our user class. | |
298 | Currently in UCW, you'd define a presentation as such : | |
299 | \layout Standard | |
300 | ||
301 | (defpresentation user-presentation (object-presentation) | |
302 | \layout Standard | |
303 | ||
304 | ((INTEGER :LABEL "USERID" :SLOT-NAME USERID) | |
305 | \layout Standard | |
306 | ||
307 | (STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) | |
308 | \layout Standard | |
309 | ||
310 | (STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD))) | |
311 | \layout Standard | |
312 | ||
313 | which could be presented using PRESENT-OBJECT : | |
314 | \layout Standard | |
315 | ||
316 | (present-object user :using 'user-presentation) | |
317 | \layout Standard | |
318 | ||
319 | The equiv approach using mewa presentations is actually longer and more | |
320 | verbose(!) but it serves to demonstrate how the MP system works. | |
321 | \layout Standard | |
322 | ||
323 | Mewa Presentations adds a set of attributes to a class, keyed off the class | |
324 | name. | |
325 | Attributes are inherited, so if you define an attribute on T, you can use | |
326 | it with any class. | |
327 | \layout Standard | |
328 | ||
329 | MP stores named attributes keyed on a class name. | |
330 | to achieve the same functionality as the above using mp would look like | |
331 | this : | |
332 | \layout Standard | |
333 | ||
334 | LISP-ON-LINES> (setf (find-attribute 'user :viewer) '(mewa-object-presentation | |
335 | :attributes (userid username password) :global-properties (:editablep nil))) | |
336 | \layout Standard | |
337 | ||
338 | (:VIEWER MEWA-OBJECT-PRESENTATION | |
339 | \layout Standard | |
340 | ||
341 | :ATTRIBUTES | |
342 | \layout Standard | |
343 | ||
344 | (USERID USERNAME PASSWORD) | |
345 | \layout Standard | |
346 | ||
347 | :GLOBAL-PROPERTIES | |
348 | \layout Standard | |
349 | ||
350 | (:EDITABLEP NIL)) | |
351 | \layout Standard | |
352 | ||
353 | LISP-ON-LINES> (setf (find-attribute 'user 'userid) '(INTEGER :LABEL "USERID" | |
354 | :SLOT-NAME USERID)) | |
355 | \layout Standard | |
356 | ||
357 | (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) | |
358 | \layout Standard | |
359 | ||
360 | LISP-ON-LINES> (setf (find-attribute 'user 'username) '(STRING :LABEL "USERNAME" | |
361 | :SLOT-NAME USERNAME)) | |
362 | \layout Standard | |
363 | ||
364 | (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) | |
365 | \layout Standard | |
366 | ||
367 | LISP-ON-LINES> (setf (find-attribute 'user 'password) '(STRING :LABEL "USERNAME" | |
368 | :SLOT-NAME PASSWORD)) | |
369 | \layout Standard | |
370 | ||
371 | (PASSWORD STRING :LABEL "USERNAME" :SLOT-NAME PASSWORD) | |
372 | \layout Standard | |
373 | ||
374 | LISP-ON-LINES> (find-class-attributes 'user) | |
375 | \layout Standard | |
376 | ||
377 | (USER (PASSWORD STRING :LABEL "PASSWORD" :SLOT-NAME PASSWORD) | |
378 | \layout Standard | |
379 | ||
380 | (USERNAME STRING :LABEL "USERNAME" :SLOT-NAME USERNAME) | |
381 | \layout Standard | |
382 | ||
383 | (USERID INTEGER :LABEL "USERID" :SLOT-NAME USERID) | |
384 | \layout Standard | |
385 | ||
386 | (:VIEWER MEWA-OBJECT-PRESENTATION | |
387 | \layout Standard | |
388 | ||
389 | :ATTRIBUTES | |
390 | \layout Standard | |
391 | ||
392 | (USERID USERNAME PASSWORD) | |
393 | \layout Standard | |
394 | ||
395 | :GLOBAL-PROPERTIES | |
396 | \layout Standard | |
397 | ||
398 | (:EDITABLEP NIL)) | |
399 | \layout Standard | |
400 | ||
401 | COMMON-LISP:NIL) | |
402 | \layout Standard | |
403 | ||
404 | this is all turned into a UCW presentation at runtime using MAKE-PRESENTATION | |
405 | : | |
406 | \layout Standard | |
407 | ||
408 | (defmethod render-on ((res response) (e presentations-index)) | |
409 | \layout Standard | |
410 | ||
411 | " | |
412 | \layout Standard | |
413 | ||
414 | As you'll see, nothing is exported from the LISP-ON-LINES package. | |
415 | ||
416 | \layout Standard | |
417 | ||
418 | if you wish to use LOL in your own package (or in UCW-USER or whatever), | |
419 | \layout Standard | |
420 | ||
421 | you simply need to use the MEWA and META-MODEL packages" | |
422 | \layout Standard | |
423 | ||
424 | (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line | |
425 | s::user :type :viewer))) | |
426 | \layout Standard | |
427 | ||
428 | SET-ATTRIBUTE can be used in place of (setf (find-attribute)) when you want | |
429 | to "inherit" the properties of an existing attribute definition : | |
430 | \layout Standard | |
431 | ||
432 | LISP-ON-LINES> (set-attribute 'user 'password '(string :label "password: | |
433 | (must be at leat 8 chars)")) | |
434 | \layout Standard | |
435 | ||
436 | (PASSWORD STRING | |
437 | \layout Standard | |
438 | ||
439 | :LABEL | |
440 | \layout Standard | |
441 | ||
442 | "password: (must be at leat 8 chars)" | |
443 | \layout Standard | |
444 | ||
445 | :SLOT-NAME | |
446 | \layout Standard | |
447 | ||
448 | PASSWORD) | |
449 | \layout Standard | |
450 | ||
451 | Now we want to create a presentation with which to edit the username. | |
452 | we will use the existing attributes on a subclass of mewa-object-presetation | |
453 | : | |
454 | \layout Standard | |
455 | ||
456 | LISP-ON-LINES> (defcomponent user-editor (mewa-object-presentation) | |
457 | \layout Standard | |
458 | ||
459 | () | |
460 | \layout Standard | |
461 | ||
462 | (:default-initargs | |
463 | \layout Standard | |
464 | ||
465 | :attributes '((username :label "Enter your New Username") password) | |
466 | \layout Standard | |
467 | ||
468 | :global-properties '(:editablep t))) | |
469 | \layout Standard | |
470 | ||
471 | USER-EDITOR | |
472 | \layout Standard | |
473 | ||
474 | LISP-ON-LINES> (setf (find-attribute 'user :editor) '(user-editor)) | |
475 | \layout Standard | |
476 | ||
477 | (:EDITOR USER-EDITOR) | |
478 | \layout Standard | |
479 | ||
480 | LISP-ON-LINES> | |
481 | \layout Standard | |
482 | ||
483 | which we then can display below our earlier example : | |
484 | \layout Standard | |
485 | ||
486 | (defmethod render-on ((res response) (e presentations-index)) | |
487 | \layout Standard | |
488 | ||
489 | " | |
490 | \layout Standard | |
491 | ||
492 | As you'll see, nothing is exported from the LISP-ON-LINES package. | |
493 | ||
494 | \layout Standard | |
495 | ||
496 | if you wish to use LOL in your own package (or in UCW-USER or whatever), | |
497 | \layout Standard | |
498 | ||
499 | you simply need to use the MEWA and META-MODEL packages" | |
500 | \layout Standard | |
501 | ||
502 | (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line | |
503 | s::user :type :viewer)) | |
504 | \layout Standard | |
505 | ||
506 | (<ucw:render-component :component (lisp-on-lines::make-presentation lisp-on-line | |
507 | s::user :type :editor))) | |
508 | \layout Standard | |
509 | ||
510 | that should give you some idea on how it works .. | |
511 | ask me when you get confused :) | |
512 | \the_end |