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:

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.

macro
name direct-superclasses &body body

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. It will have CSS tags returned by get-css-classes.

generic-function
w &key inserted-after inserted-before

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.

This method should return a keyword, like :div or :article. By default, it returns :div. If we are inside a table, it returns :tr

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 (append (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/session:init returns an object, then create-widget-from will be called on it to create the root widget.