documentation
This commit is contained in:
parent
995efffc52
commit
54910f4df9
81
cms/README.md
Normal file
81
cms/README.md
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Aircox.CMS
|
||||||
|
Simple CMS generator used in Aircox. Main features includes:
|
||||||
|
- website configuration and templating
|
||||||
|
- articles and static pages
|
||||||
|
- sections: embeddable views used to display related elements of an object
|
||||||
|
- posts related to external models:
|
||||||
|
- attributes binding, automatically updated
|
||||||
|
- personalization of view rendering, using templates or sections
|
||||||
|
- integrated admin interface if desired
|
||||||
|
- list and detail views + routing
|
||||||
|
- positioned menus using views
|
||||||
|
- comment
|
||||||
|
|
||||||
|
We aims here to automatize most common tasks and to ease website
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
# Architecture
|
||||||
|
A **Website** holds all required informations to run the server instance. It
|
||||||
|
is used to register all kind of posts, routes to the views, menus, etc.
|
||||||
|
|
||||||
|
Basically, for each type of publication, the user declare the corresponding
|
||||||
|
model, the routes, the sections used for rendering, and register them using
|
||||||
|
website.register.
|
||||||
|
|
||||||
|
## Posts
|
||||||
|
**Post** is the base model for a publication. **Article** is the provided model
|
||||||
|
for articles and static pages.
|
||||||
|
|
||||||
|
**RelatedPost** is used to generate posts related to a model, the corresponding
|
||||||
|
bindings and so on. The idea is that you declare your own models using it as
|
||||||
|
parent, and give informations for bindings and so on. This is as simple as:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class MyModelPost(RelatedPost):
|
||||||
|
class Relation:
|
||||||
|
model = MyModel
|
||||||
|
mapping = {
|
||||||
|
'thread': 'parent_field_name',
|
||||||
|
'title': 'name'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Routes
|
||||||
|
Routes are used to generate the URLs of the website. We provide some of the
|
||||||
|
common routes: for the detail view of course, but also to select all posts or
|
||||||
|
by thread, date, search, tags.
|
||||||
|
|
||||||
|
It is of course possible to create your own routes.
|
||||||
|
|
||||||
|
Routes are registered to a router (FIXME: it might be possible that we remove
|
||||||
|
this later)
|
||||||
|
|
||||||
|
|
||||||
|
## Section
|
||||||
|
Sections are used to render part of a publication, for example to render a
|
||||||
|
playlist related to the diffusion of a program.
|
||||||
|
|
||||||
|
If the rendering of a publication can vary depending the related element, in
|
||||||
|
most of the cases when we render elements, we can find the same patterns: a
|
||||||
|
picture, a text, a list of URLs/related posts/other items.
|
||||||
|
|
||||||
|
In order to avoid to much code writing and the multiplication of template
|
||||||
|
files (e.g. one for each type of publication), we prefer to declare these
|
||||||
|
sections and configure them. This reduce the work, keep design coherent,
|
||||||
|
and reduce the risk of bugs and so on.
|
||||||
|
|
||||||
|
|
||||||
|
## Website
|
||||||
|
This class is used to create the website itself and regroup all the needed
|
||||||
|
informations to make it beautiful. There are different steps to create the
|
||||||
|
website, using instance of the Website class:
|
||||||
|
|
||||||
|
1. Create the Website instance with all basic information: name, tags,
|
||||||
|
description, menus and so on.
|
||||||
|
2. For each type of publication, register it using a Post model, a list of
|
||||||
|
used sections, routes, and optional parameters. The given name is used
|
||||||
|
for routing.
|
||||||
|
3. Register website's URLs to Django.
|
||||||
|
4. Change templates and css styles if needed.
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,10 @@ from taggit.managers import TaggableManager
|
||||||
|
|
||||||
|
|
||||||
class Post (models.Model):
|
class Post (models.Model):
|
||||||
|
"""
|
||||||
|
Base model that can be used as is if wanted. Represent a generic
|
||||||
|
publication on the website.
|
||||||
|
"""
|
||||||
thread_type = models.ForeignKey(
|
thread_type = models.ForeignKey(
|
||||||
ContentType,
|
ContentType,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
|
@ -64,6 +68,9 @@ class Post (models.Model):
|
||||||
|
|
||||||
|
|
||||||
class Article (Post):
|
class Article (Post):
|
||||||
|
"""
|
||||||
|
Represent an article or a static page on the website.
|
||||||
|
"""
|
||||||
static_page = models.BooleanField(
|
static_page = models.BooleanField(
|
||||||
_('static page'),
|
_('static page'),
|
||||||
default = False,
|
default = False,
|
||||||
|
@ -141,12 +148,28 @@ class RelatedPostBase (models.base.ModelBase):
|
||||||
|
|
||||||
class RelatedPost (Post, metaclass = RelatedPostBase):
|
class RelatedPost (Post, metaclass = RelatedPostBase):
|
||||||
"""
|
"""
|
||||||
Use this post to generate Posts that are related to an external model. An
|
Post linked to an object of other model. This object is accessible through
|
||||||
extra field "related" will be generated, and some bindings are possible to
|
the field "related".
|
||||||
update te related object on save if desired;
|
|
||||||
|
|
||||||
This is done through a class name Relation inside the declaration of the new
|
It is possible to map attributes of the Post to the ones of the Related
|
||||||
model.
|
Object. It is also possible to automatically update post's thread based
|
||||||
|
on the Related Object's parent if it is required.
|
||||||
|
|
||||||
|
Mapping can ensure that the Related Object will be updated when mapped
|
||||||
|
fields of the Post are updated.
|
||||||
|
|
||||||
|
To configure the Related Post, you just need to create set attributes of
|
||||||
|
the Relation sub-class.
|
||||||
|
|
||||||
|
```
|
||||||
|
class MyModelPost(RelatedPost):
|
||||||
|
class Relation:
|
||||||
|
model = MyModel
|
||||||
|
mapping = {
|
||||||
|
'thread': 'parent_field_name',
|
||||||
|
'title': 'name'
|
||||||
|
}
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
related = None
|
related = None
|
||||||
|
|
||||||
|
@ -165,13 +188,11 @@ class RelatedPost (Post, metaclass = RelatedPostBase):
|
||||||
If there is a post_attr "thread", the corresponding rel_attr is used
|
If there is a post_attr "thread", the corresponding rel_attr is used
|
||||||
to update the post thread to the correct Post model (in order to
|
to update the post thread to the correct Post model (in order to
|
||||||
establish a parent-child relation between two models)
|
establish a parent-child relation between two models)
|
||||||
* thread_model: generated by the metaclass that point to the
|
* thread_model: generated by the metaclass, points to the RelatedPost
|
||||||
RelatedModel class related to the model that is the parent of
|
model generated for the mapping.thread object.
|
||||||
the current related one.
|
|
||||||
"""
|
"""
|
||||||
model = None
|
model = None
|
||||||
mapping = None # values to map { post_attr: rel_attr }
|
mapping = None # values to map { post_attr: rel_attr }
|
||||||
thread = None
|
|
||||||
thread_model = None
|
thread_model = None
|
||||||
|
|
||||||
def get_attribute (self, attr):
|
def get_attribute (self, attr):
|
||||||
|
|
|
@ -170,4 +170,5 @@ class SearchRoute (Route):
|
||||||
qs.distinct()
|
qs.distinct()
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
## TODO: by tag
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,11 @@ class Website:
|
||||||
|
|
||||||
def register (self, name, model, sections = None, routes = None,
|
def register (self, name, model, sections = None, routes = None,
|
||||||
list_kwargs = {}, detail_kwargs = {}):
|
list_kwargs = {}, detail_kwargs = {}):
|
||||||
|
"""
|
||||||
|
Register a detail and list view for a given model, using
|
||||||
|
routes. Just a wrapper around register_detail and
|
||||||
|
register_list.
|
||||||
|
"""
|
||||||
if sections:
|
if sections:
|
||||||
self.register_detail(
|
self.register_detail(
|
||||||
name, model,
|
name, model,
|
||||||
|
|
|
@ -36,7 +36,6 @@ class Actions:
|
||||||
def skip (cl, monitor, controller, source):
|
def skip (cl, monitor, controller, source):
|
||||||
source.skip()
|
source.skip()
|
||||||
|
|
||||||
|
|
||||||
class LiquidControl (View):
|
class LiquidControl (View):
|
||||||
template_name = 'aircox/liquidsoap/controller.html'
|
template_name = 'aircox/liquidsoap/controller.html'
|
||||||
|
|
||||||
|
|
|
@ -744,7 +744,7 @@ class Log (models.Model):
|
||||||
logger.info('log #%s: %s%s',
|
logger.info('log #%s: %s%s',
|
||||||
str(self),
|
str(self),
|
||||||
self.comment or '',
|
self.comment or '',
|
||||||
'\n - {}: #{}'.format(self.related_type, self.related_id)
|
' -- {} #{}'.format(self.related_type, self.related_id)
|
||||||
if self.related_object else ''
|
if self.related_object else ''
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user