Widgets
Widget objects should subclasses of reblocks/widget:widget
class
also, minimally you have to define a method for the
reblocks/widget:render
generic-function. This function should return
use reblocks/html:with-html
macro to render the widget.
Other parts of API
around widgets are:
reblocks/dependencies:get-dependencies
- returns a list ofCSS
/JS
dependencies.reblocks/widget:update
- marks a widget as need to update on the frontend.reblocks/widget:get-html-tag
- returns aHTML
tag instead of standardDIV
.reblocks/widget:get-css-classes
- returns a list ofCSS
classes. By default returns:WIDGET
and a widget class's name.reblocks/widget:create-widget-from
- return a widget for representing an object. This way widgets can be created out of strings, functions, etc.
Example
To define a widget, use reblocks/widget:defwidget
macro. It creates a class
with a proper meta-class. Old Weblocks version used this metaclass to
discover changes slots, and probably this feature will be returned back some day.
CL-USER> (reblocks/widget:defwidget hello ()
((name :initarg :name
:reader get-name)))
#<REBLOCKS/WIDGETS/MOP:WIDGET-CLASS COMMON-LISP-USER::HELLO>
CL-USER> (defmethod reblocks/widget:render ((widget hello))
(reblocks/html:with-html
(:span ("Hello ~A" (get-name widget)))))
#<STANDARD-METHOD REBLOCKS/WIDGET:RENDER (HELLO) {1004E27BC3}>
Then call this, to run a webserver and preview your widget in the browser:
CL-USER> (reblocks/preview:preview
(make-instance 'hello
:name "Bob"))
A result will look like this:
API
Base class for all widget objects.
A macro used to define new widget classes. Behaves exactly as
defclass, except adds reblocks/widgets/mop:widget-class
metaclass specification and
inherits from reblocks/widget:widget
if no DIRECT-SUPERCLASSES
are provided.
Define this method to render widget's content.
Use reblocks/html:with-html
macro to render HTML
.
You can use any other templating engine, just ensure
it writes output to reblocks/html:*stream*
Outer DIV
wrapper will be added automaticall, see get-html-tag
generic-function.
It will have CSS
tags returned by get-css-classes
generic-function.
This method should be called to update widget on a client.
Usually this required as a result of an action execution.
In the original Weblocks there was a mark-dirty method. This one replaces it. To make everything easier, the new protocol excludes "propagation". If you need to update other widgets, please define an "update" method for your widget. You can use :before or :after modifiers, to keep the current behavior and to add propagation code.
There are a few optional arguments to control the way how does widget should be updated. They can be useful to not update the whole parent widget.
If one of
INSERTED-AFTER
orINSERTED-BEFORE
is given, it should be a widget object to be used as an anchor. This can be useful to not rerender all children of some "list" widget when you adding a new element.When
REMOVED
argument is T the widget will be removed from theDOM
tree.
This method determines the enclosing tag of the widget.
The return value should either be a keyword like :div
,
which will be the enclosing tag, or a list of the form (:tag . attributes)
,
where :tag
is the enclosing tag (like :div
) and attributes is a property list.
The attributes property list has keywords for keys, corresponding to the attribute name and the values are the values of the attribute.
For example:
:div
- generates<div ...> widget content </div>
;(:div :display "flex")
- generates(<div ... :display "flex">widget content</div>
.
Note on attributes: in the attribute list the following attributes can not be specified, they will be ignored:
:class
- Use theget-css-classes
generic-function to specify these;:id
- This is the value of the dom-id slot of the widget, normally automatically managed by reblocks.
The default implementation returns
- :td
- inside a table row;
- :tr
- inside a table;
- :div
- by default.
Returns a list of classes for the widget.
Classes may be a strings or a keywords.
By default, :widget and keyworded class name are returned.
Use (list* :new-class (call-next-method))
to add new classes.
Methods of this generic should return an instance of subclass of reblocks/widget:widget The most obvious cases are transformation of strings and functions into the widget, but these methods are already supplied by Reblocks.
If reblocks/page:init-page
returns an object, then create-widget-from
will be called on it
to create the root widget.
String widget
This is a simple type of widget which can be made out of any string.
Create a widget from a string.
Whether to escape the output
for HTML
.