Author: achiumenti Date: Wed Apr 9 13:59:58 2008 New Revision: 34
Modified: trunk/doc/chapters/getting-started.texinfo trunk/doc/chapters/intro.texinfo trunk/doc/chapters/lisplets.texinfo trunk/doc/chapters/pages.texinfo trunk/doc/chapters/server.texinfo Log: updating user manual
Modified: trunk/doc/chapters/getting-started.texinfo ============================================================================== --- trunk/doc/chapters/getting-started.texinfo (original) +++ trunk/doc/chapters/getting-started.texinfo Wed Apr 9 13:59:58 2008 @@ -1,3 +1,41 @@ @node Getting Started @comment node-name, next, previous, up @chapter Getting started with @value{claw} + +Now that you know how to write pages in @value{claw}, lets move to a further step: writing components. + +A real @value{claw} web application is made of a lisplet, several pages and resources, and, of course, many reusable +components that go into pages. + +Using reusable components, may dramatically improve your productivity. You can then create custom components libraries +that will give to your web application a crystal clear style, and speed up the creation of repetitive piece +of HTML code, as page templates for instance. + +So said, let's create our first @value{claw} component, a site template. +@cartouche +@lisp +(defcomponent site-template () ()) + +(defmethod wcomponent-parameters ((o site-template)) + (list :title :required :home-page "/claw/test/index.html")) + +(defmethod wcomponent-template ((o site-template)) + (html> + (head> + (title> + (wcomponent-parameter-value o :title)) + (style> :type "text/css" +"input.error { + background-color: #FF9999; +} +")) + (body> + (wcomponent-informal-parameters o) + (div> + :style "background-color: #DBDFE0;padding: 3px;" + (a> :href (wcomponent-parameter-value o :home-page) "home")) + (htcomponent-body o)))) +@end lisp +@end cartouche +Thought this is not the best template you can do, it's a nice starting point to explain how components are created +(and used).
Modified: trunk/doc/chapters/intro.texinfo ============================================================================== --- trunk/doc/chapters/intro.texinfo (original) +++ trunk/doc/chapters/intro.texinfo Wed Apr 9 13:59:58 2008 @@ -10,13 +10,13 @@ @value{claw} is based on components, highly reusable building blocks the make easy and fast the creation of a web application. By using and creating new components, the developer can create robust and consistent web application with the minimal effort.
-Each component may inject into a page ist own set of stylesheet and javasctipt files, and may come with its own class or instance javascript +Each component may inject into a page its own set of stylesheet and javascript files, and may come with its own class or instance javascript directives (a class directive is inserted only once into the page, while this is not true for an instance script). This leads to the creation of very sophisticated components with a very little effort.
-@value{claw} comes with its own authentication systme that lets you create both basic and form based authentication systems. +@value{claw} comes with its own authentication system that lets you create both basic and form based authentication systems.
-@value{claw} has the capability to force the page renderinig throught the protocol https of pages managing sensible data, using simple +@value{claw} has the capability to force the page rendering through the HTTPS protocol of pages managing sensible data, using simple directives.
@value{claw} comes with its own extensible localization and validation system. @@ -34,13 +34,13 @@
When a user asks for a page the request is sent to the @code{CLAWSERVER} that dispatches the request to the registered lisplets.
-Lisplets are web resource containers that hold web pages and other resource files, such as javascript, image, css, etc. files, or even funcions, under a common path. +Lisplets are web resource containers that hold web pages and other resource files, such as javascript, image, css, etc. files, or even functions, under a common path.
When a matching lisplet is then found, it dispatches the request to a registered resource that can be a page or a file or even a function.
If the request is sent for a file, this is then sent back to the browser if found.
-If the request is sent for a page, usually mapped to a html url, the dispatcher calls the page rendering function to display the page as an html resource. +If the request is sent for a page, usually mapped to a html URL, the dispatcher calls the page rendering function to display the page as an html resource.
If no resource is found a 404 message page, is sent to the user as feedback.
Modified: trunk/doc/chapters/lisplets.texinfo ============================================================================== --- trunk/doc/chapters/lisplets.texinfo (original) +++ trunk/doc/chapters/lisplets.texinfo Wed Apr 9 13:59:58 2008 @@ -32,7 +32,7 @@ At this point you have defined a web application registered to the URL ``http://localhost:4242/test'' that @value{claw} will be able to serve.
-All sessions and the authentication and authourization logic will be under the default realm ``claw'', +All sessions and the authentication and authorization logic will be under the default realm ``claw'', so if you register another lisplet into the server with the instruction: @cartouche @lisp @@ -71,7 +71,7 @@
@subsection Adding files and folders to a @code{LISPLET}
-Suppose now you want to provide, thought your web application, a file present on jour hard disk, for example: +Suppose now you want to provide, thought your web application, a file present on your hard disk, for example: ``/opt/webresources/images/matrix.jpg''.
This is made very simple with the following instructions @@ -84,9 +84,9 @@ @end cartouche
The jpeg file will now be available when accessing ``http://localhost:4242/test/images/matrix.jpg''. -The last rgument specifies the mime-type, but it's optional. +The last argument specifies the mime-type, but it's optional.
-If you want to regiter an entire folder, the process is very similar +If you want to register an entire folder, the process is very similar @cartouche @lisp (lisplet-register-resource-location *test-lisplet* @@ -100,10 +100,10 @@
@subsection Adding functions to a @code{LISPLET}
-Registering a function gives you more flexybility then registering a static resource as a file or a directory but the complexity +Registering a function gives you more flexibility then registering a static resource as a file or a directory but the complexity relies into the function that you want to register.
-For example, if you want to provide the same ``matrix.jpg'' file throught a function, you'll have to do something of the kind: +For example, if you want to provide the same ``matrix.jpg'' file through a function, you'll have to do something of the kind: @cartouche @lisp (lisplet-register-function-location *test-lisplet* @@ -118,7 +118,7 @@ "images/matrix2.jpg" ) @end lisp @end cartouche -Now the image will be availbe at the URL ``http://localhost:4242/test/images/matrix2.jpg''. +Now the image will be available at the URL ``http://localhost:4242/test/images/matrix2.jpg''.
The method @code{lisplet-register-function-location} accepts two optional keys: @itemize @minus @@ -139,10 +139,22 @@ @cartouche @lisp (defclass empty-page (page) ()) -(lisplet-register-page-location *test-lisplet* 'empty-page "index.html" :welcome-page-p t) +(lisplet-register-page-location *test-lisplet* 'empty-page "index.html" + :welcome-page-p t) @end lisp @end cartouche
This will provide an empty page at the URL ``http://localhost:4242/test/index.html'' and, since it is defined as a welcome page when you'll access the URL ``http://localhost:4242/test'' you will redirected to it. + +@section Sessions + +Sessions are common place where you sore stateful user data. Session handling is slightly different from the original one +implemented by @code{Hunchentoot}, so, to instantiate a session you have to use the method +@cartouche +@lisp +(lisplet-start-session) +@end lisp +@end cartouche +inside your code.
Modified: trunk/doc/chapters/pages.texinfo ============================================================================== --- trunk/doc/chapters/pages.texinfo (original) +++ trunk/doc/chapters/pages.texinfo Wed Apr 9 13:59:58 2008 @@ -1,3 +1,158 @@ @node Pages @comment node-name, next, previous, up @chapter Web application pages + +@value{claw} applications are usually made of pages. + +A @code{PAGE} is a @code{CLOS} class that contains the rendering logic and is called +by the @code{LISPLET} when the URL matches the page resource mapping. + +@section Writing your first @value{claw} page + +You already know how to register a @code{PAGE} into a @code{LISPLET}, if not, visit the previous chapter; what +you miss, is how to put content into a page. + +@value{claw} comes with the full set of html tags plus some custom components that we'll see in the next sections. + +All html tag are rendered with functions whose names are the tag name plus the character >. Tag attributes are pairs +of symbols for attribute names and strings for their values. + +For example the function that render a DIV tag with class attribute ``foo'' is: +@cartouche +@lisp +(div> :class "foo") +@end lisp +@end cartouche + +Given this short intro we are now ready to write our first @value{claw} page: +@cartouche +@lisp +(defclass index-page (page) ()) +(defmethod page-content ((index-page index-page)) + (html> + (head> + (title> "First sample page")) + (body> + (h1> "Hello world")))) +(lisplet-register-page-location *test-lisplet* 'index-page "index.html" + :welcome-page-p t) +@end lisp +@end cartouche + +So, overriding the method @code{PAGE-CONTENT} for your new defined page gives you the possibility +to insert its content. As you can see the method definition is very similar to an HTML file, thought +more concise. + +@subsection The special tag attribute: @code{:ID} and @code{:STATIC-ID} + +@value{claw} pages try to keep ``ID'' tag attributes unique among the page. This is particularly useful +when you have to render tags that expose their id inside a loop. +To see what happens when this situation occurs see the following example: +@cartouche +@lisp +(defmethod page-content ((sample-page sample-page)) + (html> + (head> + (title> "First sample page")) + (body> + (loop for letter in (list "A" "B" "C" "D") + collect (div> :id "item" letter))))) +@end lisp +@end cartouche + +will produce the following HTML code +@cartouche +@example +@format +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title>First sample page</title> + </head> + <body> + <div id="item">A</div> + <div id="item_1">B</div> + <div id="item_2">C</div> + <div id="item_3">D</div> + <script type="text/javascript"> +//<!-- +document.addEventListener('DOMContentLoaded', function(e) @{@}, false); +//--> + </script> + </body> +</html> +@end format +@end example +@end cartouche + +When you want to prevent the default behaviour on id generation you have to provide the tag with the +attribute @code{:STATIC-ID}, that will render into HTML as the attribute @code{:ID}, but without the id +unique logic generation. + +An important method that is present in all tags and component is the @code{GENERATE-ID} that you +may use to obtain a unique id and put into components or tags with @code{:STATIC-ID}. + +Look at the following to see how it can work: +@cartouche +@lisp +(defmethod page-content ((sample-page sample-page)) + (html> + (head> + (title> "First sample page")) + (body> + (loop for letter in (list "A" "B" "C" "D") + for id = (generate-id "item") then (generate-id "item") + collect (div> (span> :static-id id letter) + (span> :onclick + (format nil "alert(document.getElementById('~a').innerHTML);" + id) + "click me")))))) +@end lisp +@end cartouche +that will produce the following HTML code: +@cartouche +@example +@format +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title>First sample page</title> + </head> + <body> + <div> + <span id="item">A</span> + <span onclick="alert(document.getElementById('item').innerHTML);"> + click me</span> + </div> + <div> + <span id="item_1">B</span> + <span onclick="alert(document.getElementById('item_1').innerHTML);"> + click me</span> + </div> + <div> + <span id="item_2">C</span> + <span onclick="alert(document.getElementById('item_2').innerHTML);"> + click me</span> + </div> + <div> + <span id="item_3">D</span> + <span onclick="alert(document.getElementById('item_3').innerHTML);"> + click me</span> + </div> + <script type="text/javascript"> +//<!-- +document.addEventListener('DOMContentLoaded', function(e) @{@}, false); +//--> + </script> + </body> +</html> +@end format +@end example +@end cartouche + +So, the outside tag generated id, is used in the onclick method of the span tags to reference the +previous tag.
Modified: trunk/doc/chapters/server.texinfo ============================================================================== --- trunk/doc/chapters/server.texinfo (original) +++ trunk/doc/chapters/server.texinfo Wed Apr 9 13:59:58 2008 @@ -431,7 +431,8 @@
@cartouche @lisp -(defparameter *clawserver* (make-instance 'clawserver :port 4242 :sslport 4443 +(defparameter *clawserver* (make-instance 'clawserver :port 4242 + :sslport 4443 :ssl-certificate-file #P"/path/to/certificate/cacert.pem" :ssl-privatekey-file #P"/path/to/certificate/privkey.pem"))) (clawserver-start *clawserver*)