The idea of Weblocks CMS is to have an admin interface on the top of normal admin interface. First you edit application data schema - a set of models and their fields and include somewhere code which will create UI from this schema.
Weblocks CMS requires https://github.com/html/weblocks-twitter-bootstrap-application
It should work only with weblocks-prevalence
store.
Package uses weblocks assets so all dependencies should be installed automatically.
For schema editing we starting weblocks-cms application along with our admin application.
weblocks-cms application will be available on /super-admin url.
We edit schema in web-interface.
Schema is usually saved in < getcwd >/schema.lisp-expr
file after clicking "Preview Models" button.
Current schema is the one from which admin interface is generated.
It is in weblocks-cms:*current-schema*
variable and is updated when (weblocks-cms:refresh-schema)
evaluated
and during application loading.
First Weblocks CMS start (without schema) does not require initialization but when schema contains models and data related to these models you'll need initialization.
During application loading last schema should be loaded from schema file and classes should be generated from it. Classes (their symbols) should be in your application package, this is most convenient.
So, we set *models-package*
- a package for model classes somewhere in the code
(defparameter weblocks-cms:*models-package* :package-name-for-models)
and regenerating classes from schema
(weblocks-cms:regenerate-model-classes)
this should be evaluated before opening stores and this is required init code when you have schema and its data.
By default you can edit schema (on /super-admin) without authentication, to restrict access to application you should override weblocks-cms:weblocks-cms-access-granted function with some authentication logic.
Here is example of embedding generated models into your admin interface
(do-page
(apply
#'make-navigation
(append
(list
"toplevel"
(list
"Custom page"
(lambda(&rest args) ...)
nil))
(weblocks-cms:weblocks-cms-admin-menu)
(list :navigation-class 'bootstrap-navbar-navigation))))
The result is separate tab for every generated model and gridedit on every tab.
You can also use (weblocks-cms:make-gridedit-for-model-description < model description >)
to put grid where you want.
To make tree instead of grid you should add to your model column with name parent
and type "Single Relation".
In this case (weblocks-cms:weblocks-cms-admin-menu)
will create tree from such description instead of grid.
You can also use (weblocks-cms:make-tree-edit-for-model-description < model description >)
to put tree where you want.
You should also override weblocks-cms:tree-item-title
method for your models, default title gives only debug information.
-
Choice yes/no - turns into boolean value
T
orNIL
, displays in grid as "Yes" or "No" -
Integer - turns into integer number
-
String - turns into string
-
Few lines of text - textarea, turns into string, displays in grid as excerpt
-
Text editor - tinymce editor, turns into string, displays in grid as excerpt from text with stripped html tags.
There is also codemirror editor presentation. To make all presentations codemirror editor by default use following code.
(defmethod weblocks-cms::get-view-fields-for-field-type-and-description ((type (eql :editor-textarea)) description model-description-list)
(list
(list
(weblocks-cms::keyword->symbol (getf description :name))
:label (getf description :title)
:present-as 'codemirror)))
-
Date and time - date and time using Twitter Bootstrap widgets, turns into universal time (integer), displays in grid as date
-
Single choice - single choice from list, turns into keyword. List of values should be entered into "Type Data" textarea one at line.
-
Multiple choices - multiple choices from list, turns into list of keywords. List of values should be entered into "Type Data" textarea one at line.
-
File - writes string into object and puts file into
< getcwd >/pub/upload/< model name >-< field name >/
-
Single relation - used in few cases
- For a tree, when adding Single relation with name
parent
model will be automatically displayed as a tree and field will be used to connect branches.
`tree-item-title` method can be implemented for a normal appearance
- For relation with a tree, in this case you should write tree model name into "Type Data" textarea.
`weblocks-cms:tree-item-title` method can be implemented for a normal appearance
- For relation with other model, not a tree, in this case you should write model name into "Type Data" textarea.
`weblocks-cms:bootstrap-typeahead-title` method can be implemented for a normal appearance
- For a tree, when adding Single relation with name
-
Custom field - used for quick customization of fields. Gives you possibility to create your own list of Weblocks view fields for field.
For using it include dispatcher function symbol into "Type Data" textarea.
Dispatcher function here will receive parameters
* Type - `:form` or `:table`
* description - Weblocks CMS field description
* model-description - Weblocks CMS model description
And it should return list of result fields specifications. Similar field specifications used during defview.
Here is example of such specification
(list
'weblocks-cms::value ; Field symbol
:label "Value"
:present-as 'text
:reader (if (some-condition) #'some-reader-1 #'some-reader-2))
We recommend naming dispatcher <model-name>-<model-field-name>-cfd
. Here cfd means "custom field dispatcher".
For model Element with field Value it should be element-value-cfd
.