Building pages from base-html-divs

<-Previous | ^UP^ | Next->

In the Creating and Publishing web pages topic, the slot body was identified as the slot that needed to be populated with a html string in order for the object to be rendered as a web page. The whole page and be defined as a single string in this slot if required, but building a page from base-html-divs may lead to an easier to manage page and encourages modularity and reuse, which in turn provides a common look and feel to pages

A base-html-div is an object, which evaluates the div message to a html string and then we include that message in the objects parent body. To populate the div slot, we need to write a html string to the inner-html slot. The base-html-div object then wraps this string with some standard html when div is evaluated.

(in-package :gwl-user)(define-object simple-page-with-section (base-html-page):computed-slots((body (with-lhtml-string ()(when gwl:*developing?* (str (the development-links)))(:h2 "Basic Page Sections")(str (the section-1 div))))):objects((section-1 :type 'base-html-div:inner-html(with-litml-string ()(:p "Using page sections to provide content")))))(publish-gwl-app "/simple-base-html-div" "gwl-user::simple-page-with-section")

This method, passing the value of inner-html directly into a base-html-div object works well for fairly simple cases and avoids the need for creating bespoke objects based on base-html-div, but for more complex calculations of the inner-html value, potentially involving a number of different inputs, it is often more practical and manageable to create specific objects by mixing in base-html-div

(in-package :gwl-user)(define-object simple-page-with-custom-section (base-html-page):computed-slots((input-list (list 1 2 3))(body (with-lhtml-string ()(when gwl:*developing?* (str (the development-links)))(:h2 "Basic Page Sections")(str (the section-1 div))))):objects((section-1 :type 'base-html-div-1:input-list (the input-list))))(define-object base-html-div-1 (base-html-div):input-slots(input-list):computed-slots((inner-html (with-lhtml-string ()(:table :border 1(:tr (:th "Content"))(dolist (c (the input-list))(htm (:tr (:td (fmt "Cell ~a content" c))))))))))(publish-gwl-app "/simple-page-with-custom-section" "gwl-user::simple-page-with-custom-section")

The difference between a base-html-div inner-html and div is that div wraps the html defined in inner-html with a html div tag and an internally generated id attribue for that tag.

GWL-USER (make-self 'base-html-div-object)

#<BASE-HTML-DIV-OBJECT #x210462B07D>

GWL-USER (the section-1 inner-html)

<table border="1"> <tr><th>Content</th></tr> <tr><td>Cell 1 content</td></tr> <tr><td>Cell 2 content</td></tr> <tr><td>Cell 3 content</td></tr></table>

GWL-USER (the section-1 div)

<div id="KDpTSEVFVC1TRUNUSU9OLTEp"> <table border="1"> <tr><th>Content</th></tr> <tr><td>Cell 1 content</td></tr> <tr><td>Cell 2 content</td></tr> <tr><td>Cell 3 content</td></tr> </table></div>
This div may then be surgically updated using AJAX, without the page being resubmitted. We'll cover using AJAX with GendL in the Using AJAX topic, but for now the main thing to take away is how the use of AJAX may affect the granularity of a base-html-div. If a single base-html-div was used for the whole page, then an AJAX update would have only marginal impact on both speed of display and bandwidth used. If every element in the page was its own base-html-div the overhead would be significant. So there's obviously a compromise somewhere in the middle. Best advice would be to group elements likely to be updated as a result of the same event together in the same base-html-div if possible.