emacs.d/clones/lisp/www.cliki.net/Extension webactions.html
2022-10-07 15:47:14 +02:00

303 lines
No EOL
48 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>CLiki: Extension webactions</title>
<link rel="alternate" type="application/atom+xml" title="ATOM feed of edits to current article"
href="https://www.cliki.net/site/feed/article.atom?title=Extension%20webactions">
<link rel="stylesheet" href="static/css/style.css">
<link rel="stylesheet" href="static/css/colorize.css">
</head>
<body>
<span class="hidden">CLiki - Extension webactions</span>
<div id="content"><div id="content-area"><div id="article-title">Extension webactions</div><div id="article">Well it seems that I had similiar ideas about how a <a href="web.html" class="category">web</a> development tool might look as the implementor if <a href="kpax.html" class="internal">kpax</a> might have have also. However let me stress the following: The forthcoming code is totally undocumented and just used here internally. It combines a few ideas I had about <a href="https://www.cliki.net/web%20development" class="new">web development</a>, and it borrows from following things:
<ul>
<li> <a href="ucw.html" class="internal">ucw</a>
</li>
<li><a href="kpax.html" class="internal">kpax</a></li>
<li><a href="clim.html" class="internal">clim</a></li>
<ul><p>Yeah you read that write it borrows from <a href="clim.html" class="internal">clim</a>. On of it's major attractions to me is the Present/Accept Model. Some others have worked for me in this area and they ported this tool to the web surrounding. If there is some interest, then I might make it publicy available. Just let me know. <p>Now here's my take on extending <a href="webactions.html" class="internal">webactions</a> into that direction
</ul>
</ul><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_in-package.html" class="symbol">in-package</a> <span class="keyword">:qss.wa.shop</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> pane <span class="paren2">(<span class="nonparen"></span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">view-name <span class="keyword">:accessor</span> view-name <span class="keyword">:initarg</span> <span class="keyword">:view-name</span></span>)</span>
<span class="paren3">(<span class="nonparen">view-value <span class="keyword">:accessor</span> view-value <span class="keyword">:initarg</span> <span class="keyword">:view-value</span>
<span class="keyword">:initform</span> <span class="string">""</span></span>)</span>
<span class="paren3">(<span class="nonparen">model-slot <span class="keyword">:accessor</span> model-slot <span class="keyword">:initarg</span> <span class="keyword">:model-slot</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> input-pane <span class="paren2">(<span class="nonparen">pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">prompt <span class="keyword">:accessor</span> prompt <span class="keyword">:initarg</span> <span class="keyword">:prompt</span> <span class="keyword">:initform</span> <span class="string">""</span></span>)</span>
<span class="paren3">(<span class="nonparen">view-value-valid <span class="keyword">:accessor</span> view-value-valid <span class="keyword">:initform</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a></span>)</span>
<span class="paren3">(<span class="nonparen">is-missing <span class="keyword">:accessor</span> is-missing
<span class="keyword">:initarg</span> <span class="keyword">:is-missing</span>
<span class="keyword">:initform</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> checkbox-pane <span class="paren2">(<span class="nonparen">input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen"><i><span class="symbol">default</span></i> <span class="keyword">:accessor</span> <i><span class="symbol">default</span></i> <span class="keyword">:initarg</span> <span class="keyword">:default</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> text-input-pane <span class="paren2">(<span class="nonparen">input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">size <span class="keyword">:accessor</span> size <span class="keyword">:initarg</span> <span class="keyword">:size</span> <span class="keyword">:initform</span> <span class="string">"20"</span></span>)</span>
<span class="paren3">(<span class="nonparen">maxlength <span class="keyword">:accessor</span> maxlength <span class="keyword">:initarg</span> <span class="keyword">:maxlength</span> <span class="keyword">:initform</span>
<span class="string">"20"</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> text-area-input-pane <span class="paren2">(<span class="nonparen">input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">rows <span class="keyword">:accessor</span> rows <span class="keyword">:initarg</span> <span class="keyword">:rows</span> <span class="keyword">:initform</span> <span class="string">"10"</span></span>)</span>
<span class="paren3">(<span class="nonparen">cols <span class="keyword">:accessor</span> cols <span class="keyword">:initarg</span> <span class="keyword">:cols</span> <span class="keyword">:initform</span> <span class="string">"50"</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> password-input-pane <span class="paren2">(<span class="nonparen">text-input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> integer-input-pane <span class="paren2">(<span class="nonparen">text-input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> option-input-pane <span class="paren2">(<span class="nonparen">input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen"><i><span class="symbol">default</span></i> <span class="keyword">:accessor</span> <i><span class="symbol">default</span></i> <span class="keyword">:initarg</span> <span class="keyword">:default</span> <span class="keyword">:initform</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span>
<span class="paren3">(<span class="nonparen">options <span class="keyword">:accessor</span> options <span class="keyword">:initarg</span> <span class="keyword">:options</span> <span class="keyword">:type</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_list.html" class="symbol">list</a></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> view <span class="paren2">(<span class="nonparen"></span>)</span> <span class="paren2">(<span class="nonparen"></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> html-view <span class="paren2">(<span class="nonparen">view</span>)</span> <span class="paren2">(<span class="nonparen"></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> html-table-view <span class="paren2">(<span class="nonparen">html-view</span>)</span> <span class="paren2">(<span class="nonparen"></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defparametercm_defvar.html" class="symbol"><i><span class="symbol">defparameter</span></i></a> +html-view+ <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_make-instance.html" class="symbol">make-instance</a> 'html-view</span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defparametercm_defvar.html" class="symbol"><i><span class="symbol">defparameter</span></i></a> +html-table-view+ <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_make-instance.html" class="symbol">make-instance</a> 'html-table-view</span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> form <span class="paren2">(<span class="nonparen"></span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">panes <span class="keyword">:accessor</span> panes <span class="keyword">:initarg</span> <span class="keyword">:panes</span> <span class="keyword">:type</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_list.html" class="symbol">list</a></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> prompt-form <span class="paren2">(<span class="nonparen">form</span>)</span> <span class="paren2">(<span class="nonparen"></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defgeneric.html" class="symbol"><i><span class="symbol">defgeneric</span></i></a> form-validator <span class="paren2">(<span class="nonparen">form req</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="keyword">:documentation</span> <span class="string">"A collection to validata a whole form,
will probably call into view-validator which is used for
validating one visual element"</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defgeneric.html" class="symbol"><i><span class="symbol">defgeneric</span></i></a> view-validator <span class="paren2">(<span class="nonparen">input-pane</span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defgeneric.html" class="symbol"><i><span class="symbol">defgeneric</span></i></a> prompt-for <span class="paren2">(<span class="nonparen">thing view <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren2">(<span class="nonparen"><span class="keyword">:method</span> <span class="paren3">(<span class="nonparen"><span class="paren4">(<span class="nonparen">pane text-input-pane</span>)</span> <span class="paren4">(<span class="nonparen">view html-view</span>)</span> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren4">(<span class="nonparen">is-missing pane</span>)</span>
<span class="paren4">(<span class="nonparen">html-stream <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren5">(<span class="nonparen"><span class="paren6">(<span class="nonparen"><span class="keyword">:span</span> <span class="keyword">:class</span> <span class="string">"missing"</span></span>)</span>
<span class="paren6">(<span class="nonparen"><span class="paren1">(<span class="nonparen"><span class="keyword">:input</span> <span class="keyword">:type</span> <span class="string">"text"</span> <span class="keyword">:name</span> <span class="paren2">(<span class="nonparen">view-name
pane</span>)</span>
<span class="keyword">:size</span> <span class="paren2">(<span class="nonparen">size pane</span>)</span>
<span class="keyword">:maxlength</span> <span class="paren2">(<span class="nonparen">maxlength pane</span>)</span>
<span class="keyword">:value</span> <span class="string">""</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="nonparen">html-stream
<a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren5">(<span class="nonparen"><span class="paren6">(<span class="nonparen"><span class="keyword">:input</span> <span class="keyword">:type</span> <span class="string">"text"</span> <span class="keyword">:name</span> <span class="paren1">(<span class="nonparen">view-name pane</span>)</span>
<span class="keyword">:size</span> <span class="paren1">(<span class="nonparen">size pane</span>)</span>
<span class="keyword">:maxlength</span> <span class="paren1">(<span class="nonparen">maxlength pane</span>)</span>
<span class="keyword">:value</span> <span class="paren1">(<span class="nonparen">view-value pane</span>)</span>
</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><span class="keyword">:method</span> <span class="paren3">(<span class="nonparen"><span class="paren4">(<span class="nonparen">pane text-area-input-pane</span>)</span> <span class="paren4">(<span class="nonparen">view html-view</span>)</span> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren4">(<span class="nonparen">is-missing pane</span>)</span>
<span class="paren4">(<span class="nonparen">html-stream <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren5">(<span class="nonparen"><span class="paren6">(<span class="nonparen"><span class="keyword">:span</span> <span class="keyword">:class</span> <span class="string">"missing"</span></span>)</span>
<span class="paren6">(<span class="nonparen"><span class="paren1">(<span class="nonparen"><span class="keyword">:textarea</span> <span class="keyword">:name</span> <span class="paren2">(<span class="nonparen">view-name pane</span>)</span>
<span class="keyword">:cols</span> <span class="paren2">(<span class="nonparen">cols pane</span>)</span>
<span class="keyword">:rows</span> <span class="paren2">(<span class="nonparen">rows pane</span>)</span></span>)</span>
<span class="string">""</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="nonparen">html-stream
<a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren5">(<span class="nonparen"><span class="paren6">(<span class="nonparen"><span class="keyword">:textarea</span> <span class="keyword">:name</span> <span class="paren1">(<span class="nonparen">view-name pane</span>)</span>
<span class="keyword">:cols</span> <span class="paren1">(<span class="nonparen">cols pane</span>)</span>
<span class="keyword">:rows</span> <span class="paren1">(<span class="nonparen">rows pane</span>)</span></span>)</span>
<span class="paren6">(<span class="nonparen"><span class="keyword">:princ-safe</span> <span class="paren1">(<span class="nonparen">view-value pane</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="comment">;;; ATTENTION redundant code could be factored out
</span>
<span class="paren2">(<span class="nonparen"><span class="keyword">:method</span> <span class="paren3">(<span class="nonparen"><span class="paren4">(<span class="nonparen">pane password-input-pane</span>)</span> <span class="paren4">(<span class="nonparen">view html-view</span>)</span> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren4">(<span class="nonparen">is-missing pane</span>)</span>
<span class="paren4">(<span class="nonparen">html-stream <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren5">(<span class="nonparen"><span class="paren6">(<span class="nonparen"><span class="keyword">:span</span> <span class="keyword">:class</span> <span class="string">"missing"</span></span>)</span>
<span class="paren6">(<span class="nonparen"><span class="paren1">(<span class="nonparen"><span class="keyword">:input</span> <span class="keyword">:type</span> <span class="string">"password"</span> <span class="keyword">:name</span> <span class="paren2">(<span class="nonparen">view-name
pane</span>)</span>
<span class="keyword">:size</span> <span class="paren2">(<span class="nonparen">size pane</span>)</span>
<span class="keyword">:maxlength</span> <span class="paren2">(<span class="nonparen">maxlength pane</span>)</span>
<span class="keyword">:value</span> <span class="string">""</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="nonparen">html-stream
<a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren5">(<span class="nonparen"><span class="paren6">(<span class="nonparen"><span class="keyword">:input</span> <span class="keyword">:type</span> <span class="string">"password"</span> <span class="keyword">:name</span> <span class="paren1">(<span class="nonparen">view-name pane</span>)</span>
<span class="keyword">:size</span> <span class="paren1">(<span class="nonparen">size pane</span>)</span>
<span class="keyword">:maxlength</span> <span class="paren1">(<span class="nonparen">maxlength pane</span>)</span>
<span class="keyword">:value</span> <span class="string">""</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><span class="keyword">:method</span> <span class="paren3">(<span class="nonparen"><span class="paren4">(<span class="nonparen">pane option-input-pane</span>)</span> <span class="paren4">(<span class="nonparen">view html-view</span>)</span> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren3">(<span class="nonparen">html-stream
<a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen"><span class="keyword">:select</span> <span class="keyword">:name</span> <span class="paren6">(<span class="nonparen">view-name pane</span>)</span></span>)</span>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_dolist.html" class="symbol">dolist</a> <span class="paren6">(<span class="nonparen">option <span class="paren1">(<span class="nonparen">options pane</span>)</span></span>)</span>
<span class="paren6">(<span class="nonparen">html-stream
<a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_stringeqc_ng-not-lessp.html" class="symbol">string=</a> option <span class="paren3">(<span class="nonparen"><i><span class="symbol">default</span></i> pane</span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_progn.html" class="symbol"><i><span class="symbol">progn</span></i></a>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_inspect.html" class="symbol">inspect</a> option</span>)</span>
<span class="paren3">(<span class="nonparen">html-stream
<a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen"><span class="keyword">:option</span> <span class="keyword">:selected</span> <span class="string">"selected"</span></span>)</span>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_write-str_m_write-line.html" class="symbol">write-string</a> option <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen">html-stream
<a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a>
<span class="paren3">(<span class="nonparen"><span class="keyword">:option</span> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_write-str_m_write-line.html" class="symbol">write-string</a> option <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="comment">;; I feel the prompt and present stuff can be combined
</span><span class="comment">;; just for the time beeing I separate them
</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defgeneric.html" class="symbol"><i><span class="symbol">defgeneric</span></i></a> present <span class="paren2">(<span class="nonparen">thing view <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren2">(<span class="nonparen"><span class="keyword">:method</span> <span class="paren3">(<span class="nonparen"><span class="paren4">(<span class="nonparen">thing text-input-pane</span>)</span> <span class="paren4">(<span class="nonparen">view html-table-view</span>)</span> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_write-str_m_write-line.html" class="symbol">write-string</a> <span class="paren4">(<span class="nonparen">view-value thing</span>)</span> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a></span>)</span></span>)</span></span>)</span>
</span></div><p>Agreed, some of you can write this much more elegant. But for my use it's "good" enough and "extensible" enough.<p>As said it's not documented at all, because it was/is my first take on it.<p>Just so much
view-name is the name I like to give the visual control (in some web-form)
view-value is the containing value
model-slot is a link to a slot of a Database object. <p>The <a href="kpax.html" class="internal">kpax</a> developers have similiar but much more elaborated scheme. AFAIKS I would go in the same direction. <p>So here's what the <a href="kpax.html" class="internal">kpax</a> developers have written:
<div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> web-form-field-definition <span class="paren2">(<span class="nonparen"></span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">parent <span class="keyword">:accessor</span> get-parent <span class="keyword">:initarg</span> <span class="keyword">:parent</span></span>)</span>
<span class="paren3">(<span class="nonparen">name <span class="keyword">:accessor</span> get-name <span class="keyword">:initarg</span> <span class="keyword">:name</span></span>)</span>
<span class="paren3">(<span class="nonparen">label <span class="keyword">:accessor</span> get-label <span class="keyword">:initform</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_type.html" class="symbol">type</a> <span class="keyword">:accessor</span> get-type <span class="keyword">:initarg</span> <span class="keyword">:type</span></span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_formatter.html" class="symbol">formatter</a> <span class="keyword">:accessor</span> get-formatter <span class="keyword">:initform</span> #'<a href="https://www.cliki.net/site/HyperSpec/Body/fun_write-to-_nc-to-string.html" class="symbol">princ-to-string</a></span>)</span>
<span class="paren3">(<span class="nonparen">parser <span class="keyword">:accessor</span> get-parser <span class="keyword">:initform</span> #'<a href="https://www.cliki.net/site/HyperSpec/Body/fun_identity.html" class="symbol">identity</a></span>)</span>
<span class="paren3">(<span class="nonparen">validator <span class="keyword">:accessor</span> get-validator <span class="keyword">:initform</span> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_constantly.html" class="symbol">constantly</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a></span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen">options <span class="keyword">:accessor</span> get-options <span class="keyword">:initform</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span>
<span class="paren3">(<span class="nonparen">comments <span class="keyword">:accessor</span> get-comments <span class="keyword">:initform</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span>
</span></div><p>As you see they have though a little bit further. The have a formatter function, a parser function and a validator function tight to the visual element. But what they do not have is a link to some external objects (for persistence e.g). <p>My idea is that updates may look like this:<p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmethod.html" class="symbol"><i><span class="symbol">defmethod</span></i></a> update-model-from-view <span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">view input-pane</span>)</span> <span class="paren3">(<span class="nonparen">model t1-class</span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_slot-value.html" class="symbol">slot-value</a> model <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_slot-value.html" class="symbol">slot-value</a> view 'model-slot</span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen">view-value view</span>)</span></span>)</span></span>)</span>
</span></div><p>The <a href="kpax.html" class="internal">kpax</a> Developers have written:
<div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defun.html" class="symbol"><i><span class="symbol">defun</span></i></a> copy-slots-form-&gt;object <span class="paren2">(<span class="nonparen">form object slots</span>)</span>
<span class="string">"Copy the named slots from a form to an object"</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_dolist.html" class="symbol">dolist</a> <span class="paren3">(<span class="nonparen">slot slots</span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_cond.html" class="symbol"><i><span class="symbol">cond</span></i></a> <span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_symbolp.html" class="symbol">symbolp</a> slot</span>)</span>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_slot-value.html" class="symbol">slot-value</a> object slot</span>)</span> <span class="paren6">(<span class="nonparen">field-value form slot</span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_consp.html" class="symbol">consp</a> slot</span>)</span>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_slot-value.html" class="symbol">slot-value</a> object <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cdr</a> slot</span>)</span></span>)</span> <span class="paren6">(<span class="nonparen">field-value form <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> slot</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a>
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_error.html" class="symbol">error</a> <span class="string">"unknown slot spec ~s"</span> slot</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
</span></div><p>But as you can see this approaches are nearly identical. And this is an interesting coincidence. I did not know how that the <a href="kpax.html" class="internal">kpax</a> people did it that way. <p>Now let's see some small example:<p><h2> How I do a form </h2><p><div class="code"><span class="nonparen"><span class="comment">;;;; Input panes for addresses
</span><span class="comment">;; It's obvious that this code can be generated, just for now
</span><span class="comment">;; write it down by hand
</span><span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> address-street <span class="paren2">(<span class="nonparen">text-input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">prompt <span class="keyword">:initform</span> <span class="string">"Your address:"</span></span>)</span>
<span class="paren3">(<span class="nonparen">view-name <span class="keyword">:initform</span> <span class="string">"adr-street"</span></span>)</span>
<span class="paren3">(<span class="nonparen">model-slot <span class="keyword">:initform</span> 'qss.db:adr-street</span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> address-city <span class="paren2">(<span class="nonparen">text-input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">prompt <span class="keyword">:initform</span> <span class="string">"Your city:"</span></span>)</span>
<span class="paren3">(<span class="nonparen">view-name <span class="keyword">:initform</span> <span class="string">"adr-city"</span></span>)</span>
<span class="paren3">(<span class="nonparen">model-slot <span class="keyword">:initform</span> 'qss.db:adr-city</span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> address-zip <span class="paren2">(<span class="nonparen">text-input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">prompt <span class="keyword">:initform</span> <span class="string">"Your zip-code:"</span></span>)</span>
<span class="paren3">(<span class="nonparen">view-name <span class="keyword">:initform</span> <span class="string">"adr-zip"</span></span>)</span>
<span class="paren3">(<span class="nonparen">model-slot <span class="keyword">:initform</span> 'qss.db:adr-zip</span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> address-country <span class="paren2">(<span class="nonparen">text-input-pane</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">prompt <span class="keyword">:initform</span> <span class="string">"Your country:"</span></span>)</span>
<span class="paren3">(<span class="nonparen">view-name <span class="keyword">:initform</span> <span class="string">"adr-country"</span></span>)</span>
<span class="paren3">(<span class="nonparen">model-slot <span class="keyword">:initform</span> 'qss.db:adr-country</span>)</span></span>)</span></span>)</span>
<span class="comment">;;; the address input form
</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defclass.html" class="symbol"><i><span class="symbol">defclass</span></i></a> address-input-form <span class="paren2">(<span class="nonparen">form</span>)</span>
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">address-street <span class="keyword">:accessor</span> address-street
<span class="keyword">:initform</span> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_make-instance.html" class="symbol">make-instance</a> 'address-street</span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen">address-city <span class="keyword">:accessor</span> address-city
<span class="keyword">:initform</span> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_make-instance.html" class="symbol">make-instance</a> 'address-city</span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen">address-zip <span class="keyword">:accessor</span> address-zip
<span class="keyword">:initform</span> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_make-instance.html" class="symbol">make-instance</a> 'address-zip</span>)</span></span>)</span>
<span class="paren3">(<span class="nonparen">address-country <span class="keyword">:accessor</span> address-country
<span class="keyword">:initform</span> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_make-instance.html" class="symbol">make-instance</a> 'address-country</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmethod.html" class="symbol"><i><span class="symbol">defmethod</span></i></a> <a href="https://www.cliki.net/site/HyperSpec/Body/stagenfun_ini_ize-instance.html" class="symbol">initialize-instance</a> <span class="keyword">:after</span> <span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">form address-input-form</span>)</span> &amp;rest initargs</span>)</span>
<span class="string">"This step is done to have a 'flat' view into the form, this probably won't work
anytime, but if it does it eases the validation and output massivly, instead of
x calls one can use a loop."</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/sym_declare.html" class="symbol">declare</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/dec_ignorecm_ignorable.html" class="symbol">ignore</a> initargs</span>)</span></span>)</span>
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren3">(<span class="nonparen">panes form</span>)</span>
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_list.html" class="symbol">list</a> <span class="paren4">(<span class="nonparen">address-street form</span>)</span>
<span class="paren4">(<span class="nonparen">address-city form</span>)</span>
<span class="paren4">(<span class="nonparen">address-zip form</span>)</span>
<span class="paren4">(<span class="nonparen">address-country form</span>)</span></span>)</span></span>)</span></span>)</span>
</span></div><p>I do not have the exact counterpart, but some excerpt from it:<p><h2> The <a href="kpax.html" class="internal">kpax</a> way </h2><p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen"><i><span class="symbol">defwebform</span></i> demo-web-form
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen"><span class="keyword">:group</span> personal-info
<span class="keyword">:label</span> <span class="string">"Personal Info"</span>
<span class="keyword">:members</span> <span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen">fullname <span class="keyword">:text</span> <span class="keyword">:label</span> <span class="string">"Fullname"</span></span>)</span>
<span class="paren5">(<span class="nonparen">username <span class="keyword">:text</span> <span class="keyword">:label</span> <span class="string">"Username"</span>
<span class="keyword">:options</span> <span class="paren6">(<span class="nonparen"><span class="keyword">:size</span> 10</span>)</span>
<span class="keyword">:validator</span> <span class="paren6">(<span class="nonparen">all required <span class="paren1">(<span class="nonparen">limited-string 8 4</span>)</span> contains-no-spaces</span>)</span></span>)</span>
<span class="paren5">(<span class="nonparen">password <span class="keyword">:password</span> <span class="keyword">:label</span> <span class="string">"Password"</span>
<span class="keyword">:options</span> <span class="paren6">(<span class="nonparen"><span class="keyword">:size</span> 10</span>)</span>
<span class="keyword">:validator</span> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_or.html" class="symbol">or</a> optional <span class="paren1">(<span class="nonparen">limited-string 32</span>)</span></span>)</span></span>)</span>
<span class="paren5">(<span class="nonparen">password2 <span class="keyword">:password</span> <span class="keyword">:label</span> <span class="string">"Password"</span>
<span class="keyword">:options</span> <span class="paren6">(<span class="nonparen"><span class="keyword">:size</span> 10</span>)</span> <span class="keyword">:comment</span> <span class="string">"[Confirmation]"</span>
<span class="keyword">:validator</span> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_or.html" class="symbol">or</a> optional <span class="paren1">(<span class="nonparen">limited-string 32</span>)</span></span>)</span></span>)</span>
<span class="paren5">(<span class="nonparen">gender <span class="keyword">:choice</span>
<span class="keyword">:options</span> <span class="paren6">(<span class="nonparen"><span class="keyword">:values</span> <span class="special">*genders*</span> <span class="keyword">:style</span> <span class="keyword">:buttons</span></span>)</span>
<span class="keyword">:parser</span> parse-keyword <span class="keyword">:formatter</span> <a href="https://www.cliki.net/site/HyperSpec/Body/fun_string-up_g-capitalize.html" class="symbol">string-capitalize</a>
<span class="keyword">:validator</span> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_or.html" class="symbol">or</a> optional <span class="paren1">(<span class="nonparen">list-element <span class="special">*genders*</span></span>)</span></span>)</span></span>)</span>
<span class="paren5">(<span class="nonparen">age <span class="keyword">:text</span> <span class="keyword">:label</span> <span class="string">"Age"</span>
<span class="keyword">:options</span> <span class="paren6">(<span class="nonparen"><span class="keyword">:size</span> 4</span>)</span>
<span class="keyword">:parser</span> s-utils:parse-integer-safely
<span class="keyword">:validator</span> <span class="paren6">(<span class="nonparen">integer-range 0 150</span>)</span></span>)</span></span>)</span></span>)</span>
</span></span></span></span></span></div><p>Now it gets interesting. We can compare the design decisions:
The <a href="kpax.html" class="internal">kpax</a> Developers have tighten the validators to the slots of a class, I let them stay alone as "generic" functions", the <a href="ucw.html" class="internal">ucw</a> folks have bind it to the slots of the class also. The charactristics are therefor:
<ul>
<li>the <a href="ucw.html" class="internal">ucw</a> and <a href="kpax.html" class="internal">kpax</a> people have to think about the validators while defining this form.</li>
<li>In my solution this is deferred to later. </li>
</ul>
Of course that is not fully true, because they can give the slot a new value later also. <p>But their example has one advantage: They can see on one sight what they can expect for the slots of their view class. This is not true for my solution. You have to browse
<ul>
<li>the class</li>
<li> the generic functions (for parsing, presenting, formatting, validation)</li>
</ul><p>Of course my solution needs less memory. But this hardly could be a problem nowadays. So I'd argue the decisions from the <a href="ucw.html" class="internal">ucw</a> and <a href="kpax.html" class="internal">kpax</a> are the better ones.<p>What do you think?<p><hr>
<a href="https://www.cliki.net/web%20development" class="new">web development</a> <a href="webactions.html" class="internal">webactions</a> <a href="kpax.html" class="internal">kpax</a> <a href="ucw.html" class="internal">ucw</a></div></div>
<div id="footer" class="buttonbar"><ul><li><a href="Extension&#32;webactions.html">Current version</a></li>
<li><a href="https://www.cliki.net/site/history?article=Extension%20webactions">History</a></li>
<li><a href="https://www.cliki.net/site/backlinks?article=Extension%20webactions">Backlinks</a></li><li><a href="https://www.cliki.net/site/edit-article?title=Extension%20webactions&amp;from-revision=3556341378">Edit</a></li><li><a href="https://www.cliki.net/site/edit-article?create=t">Create</a></li></ul></div>
</div>
<div id="header-buttons" class="buttonbar">
<ul>
<li><a href="https://www.cliki.net/">Home</a></li>
<li><a href="https://www.cliki.net/site/recent-changes">Recent Changes</a></li>
<li><a href="CLiki.html">About</a></li>
<li><a href="Text&#32;Formatting.html">Text Formatting</a></li>
<li><a href="https://www.cliki.net/site/tools">Tools</a></li>
</ul>
<div id="search">
<form action="https://www.cliki.net/site/search">
<label for="search_query" class="hidden">Search CLiki</label>
<input type="text" name="query" id="search_query" value="" />
<input type="submit" value="search" />
</form>
</div>
</div>
<div id="pageheader">
<div id="header">
<span id="logo">CLiki</span>
<span id="slogan">the common lisp wiki</span>
<div id="login"><form method="post" action="https://www.cliki.net/site/login">
<label for="login_name" class="hidden">Account name</label>
<input type="text" name="name" id="login_name" class="login_input" />
<label for= "login_password" class="hidden">Password</label>
<input type="password" name="password" id="login_password" class="login_input" />
<input type="submit" name="login" value="login" id="login_submit" /><br />
<div id="register"><a href="https://www.cliki.net/site/register">register</a></div>
<input type="submit" name="reset-pw" value="reset password" id="reset_pw" />
</form>
</div>
</div>
</div>
</body></html>