trytond-galatea_cms/cms.py

320 lines
11 KiB
Python
Raw Normal View History

2014-11-07 14:24:08 +01:00
# This file is part galatea_cms module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
2014-05-27 09:45:10 +02:00
from trytond.model import ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.pyson import Bool, Equal, Eval, In, Not
from trytond import backend
2015-02-02 16:57:31 +01:00
from trytond.modules.galatea import GalateaVisiblePage
from trytond.modules.galatea.tools import slugify
2014-05-27 09:45:10 +02:00
2015-02-02 16:57:31 +01:00
__all__ = ['Menu', 'Article', 'ArticleWebsite', 'Block',
'Carousel', 'CarouselItem']
2014-05-27 09:45:10 +02:00
class Menu(ModelSQL, ModelView):
"Menu CMS"
__name__ = 'galatea.cms.menu'
2015-02-02 16:57:31 +01:00
_rec_name = 'name_used'
_order = [('parent', 'ASC'), ('sequence', 'ASC'), ('id', 'ASC')]
2015-02-02 16:57:31 +01:00
name = fields.Char('Name', translate=True, states={
'readonly': Eval('name_uri', False),
}, depends=['name_uri'])
name_uri = fields.Boolean('Use URI\'s name', states={
'invisible': ((Eval('target_type', '') != 'internal_uri')
| ~Bool(Eval('target_uri'))),
}, depends=['target_type', 'target_uri'])
2015-02-02 16:57:31 +01:00
name_used = fields.Function(fields.Char('Name', translate=True,
required=True),
'on_change_with_name', searcher='search_name_used')
2014-05-27 09:45:10 +02:00
code = fields.Char('Code', required=True,
help='Internal code.')
2015-02-02 16:57:31 +01:00
target_type = fields.Selection([
('internal_uri', 'Internal URI'),
('external_url', 'External URL'),
], 'Type', required=True)
target_uri = fields.Many2One('galatea.uri', 'Target URI', states={
'invisible': Eval('target_type', '') != 'internal_uri',
}, depends=['target_uri'])
target_url = fields.Char('Target URL', states={
'invisible': Eval('target_type', '') != 'external_url',
2015-02-02 16:57:31 +01:00
}, depends=['target_type'])
2015-02-23 20:25:30 +01:00
url = fields.Function(fields.Char('URL'),
'get_url')
2014-05-27 09:45:10 +02:00
parent = fields.Many2One("galatea.cms.menu", "Parent", select=True)
left = fields.Integer('Left', required=True, select=True)
right = fields.Integer('Right', required=True, select=True)
childs = fields.One2Many('galatea.cms.menu', 'parent', 'Children')
sequence = fields.Integer('Sequence')
2014-06-27 11:52:20 +02:00
nofollow = fields.Boolean('Nofollow',
help='Add attribute in links to not search engines continue')
2015-02-02 16:57:31 +01:00
active = fields.Boolean('Active', select=True)
# TODO: add website field? add domain in target_uri parent
# TODO: I think next fields should go to another module
css = fields.Char('CSS',
help='Class CSS in menu.')
icon = fields.Char('Icon',
help='Icon name show in menu.')
login = fields.Boolean('Login', help='Allow login users')
manager = fields.Boolean('Manager', help='Allow manager users')
2014-05-27 09:45:10 +02:00
2015-02-23 20:25:30 +01:00
@classmethod
def __setup__(cls):
super(Menu, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
cls._order.insert(1, ('id', 'ASC'))
2015-02-02 16:57:31 +01:00
@fields.depends('name_uri', 'target_uri', 'name')
def on_change_with_name(self, name=None):
return (self.target_uri.name if self.name_uri and self.target_uri
2015-02-02 16:57:31 +01:00
else self.name)
2014-05-27 09:45:10 +02:00
@classmethod
def search_name_used(cls, name, clause):
return [
['OR', [
('name_uri', '=', True),
('target_uri.name',) + tuple(clause[1:]),
], [
('name_uri', '=', False),
('name',) + tuple(clause[1:]),
]],
]
2015-02-23 20:25:30 +01:00
def get_url(self, name):
return (self.target_url if self.target_type == 'external_url'
else (self.target_uri.uri if self.target_uri else '#'))
2014-05-27 09:45:10 +02:00
@staticmethod
def default_left():
return 0
@staticmethod
def default_right():
return 0
@staticmethod
def default_sequence():
return 1
2015-02-02 16:57:31 +01:00
@staticmethod
def default_active():
return True
2014-05-27 09:45:10 +02:00
@classmethod
def validate(cls, menus):
super(Menu, cls).validate(menus)
cls.check_recursion(menus)
@classmethod
def copy(cls, menus, default=None):
if default is None:
default = {}
default['left'] = 0
default['right'] = 0
2015-02-02 16:57:31 +01:00
# new_menus = []
# for menu in menus:
# new_menu, = super(Menu, cls).copy([menu], default=default)
# new_menus.append(new_menu)
# return new_menus
return super(Menu, cls).copy(menus, default=default)
2014-05-27 09:45:10 +02:00
class Article(GalateaVisiblePage, ModelSQL, ModelView):
2014-05-27 09:45:10 +02:00
"Article CMS"
__name__ = 'galatea.cms.article'
2015-02-02 16:57:31 +01:00
websites = fields.Many2Many('galatea.cms.article-galatea.website',
'article', 'website', 'Websites', required=True)
2014-05-27 09:45:10 +02:00
description = fields.Text('Description', required=True, translate=True,
2015-02-02 16:57:31 +01:00
help='You could write wiki markup to create html content. Formats '
'text following the MediaWiki '
'(http://meta.wikimedia.org/wiki/Help:Editing) syntax.')
markup = fields.Selection([
(None, ''),
('wikimedia', 'WikiMedia'),
('rest', 'ReStructuredText'),
], 'Markup')
metadescription = fields.Char('Meta Description', translate=True,
help='Almost all search engines recommend it to be shorter '
2014-05-27 09:45:10 +02:00
'than 155 characters of plain text')
2015-02-02 16:57:31 +01:00
metakeywords = fields.Char('Meta Keywords', translate=True,
2014-05-27 09:45:10 +02:00
help='Separated by comma')
2015-02-02 16:57:31 +01:00
metatitle = fields.Char('Meta Title', translate=True)
attachments = fields.One2Many('ir.attachment', 'resource', 'Attachments')
2014-05-27 09:45:10 +02:00
@classmethod
def __setup__(cls):
super(Article, cls).__setup__()
domain_clause = ('allowed_models.model', 'in', ['galatea.cms.article'])
if domain_clause not in cls.template.domain:
cls.template.domain.append(domain_clause)
2014-05-27 09:45:10 +02:00
cls._error_messages.update({
'delete_articles': ('You can not delete '
'articles because you will get error 404 NOT Found. '
'Dissable active field.'),
})
@classmethod
def __register__(cls, module_name):
TableHandler = backend.get('TableHandler')
table = TableHandler(cls, module_name)
super(Article, cls).__register__(module_name)
table.not_null_action('galatea_website', action='remove')
table.not_null_action('template', action='remove')
2015-02-02 16:57:31 +01:00
@classmethod
def default_websites(cls):
Website = Pool().get('galatea.website')
websites = Website.search([('active', '=', True)])
return [w.id for w in websites]
@classmethod
def calc_uri_vals(cls, record_vals):
# TODO: calc parent and template?
uri_vals = super(Article, cls).calc_uri_vals(record_vals)
if 'template' in record_vals:
uri_vals['template'] = record_vals['template']
return uri_vals
2015-02-02 16:57:31 +01:00
@classmethod
def delete(cls, articles):
cls.raise_user_warning('delete_articles', 'delete_articles')
2015-02-19 10:23:35 +01:00
super(Article, cls).delete(articles)
2015-02-02 16:57:31 +01:00
class ArticleWebsite(ModelSQL):
'Galatea CMS Article - Website'
__name__ = 'galatea.cms.article-galatea.website'
article = fields.Many2One('galatea.cms.article', 'Article',
ondelete='CASCADE', select=True, required=True)
website = fields.Many2One('galatea.website', 'Website',
ondelete='RESTRICT', select=True, required=True)
2014-07-16 11:54:17 +02:00
2014-05-27 09:45:10 +02:00
class Block(ModelSQL, ModelView):
"Block CMS"
__name__ = 'galatea.cms.block'
name = fields.Char('Name', required=True)
2014-05-27 09:45:10 +02:00
code = fields.Char('Code', required=True, help='Internal code.')
type = fields.Selection([
('image', 'Image'),
('remote_image', 'Remote Image'),
('custom_code', 'Custom Code'),
], 'Type', required=True)
2015-02-02 16:57:31 +01:00
file = fields.Many2One('galatea.static.file', 'File', states={
2014-05-27 09:45:10 +02:00
'required': Equal(Eval('type'), 'image'),
'invisible': Not(Equal(Eval('type'), 'image'))
})
2015-02-02 16:57:31 +01:00
remote_image_url = fields.Char('Remote Image URL', states={
2014-05-27 09:45:10 +02:00
'required': Equal(Eval('type'), 'remote_image'),
'invisible': Not(Equal(Eval('type'), 'remote_image'))
})
custom_code = fields.Text('Custom Code', translate=True,
states={
'required': Equal(Eval('type'), 'custom_code'),
'invisible': Not(Equal(Eval('type'), 'custom_code'))
},
help='You could write wiki markup to create html content. Formats text following '
'the MediaWiki (http://meta.wikimedia.org/wiki/Help:Editing) syntax.')
height = fields.Integer('Height',
states = {
'invisible': Not(In(Eval('type'), ['image', 'remote_image']))
})
width = fields.Integer('Width',
states = {
'invisible': Not(In(Eval('type'), ['image', 'remote_image']))
})
alternative_text = fields.Char('Alternative Text',
states = {
'invisible': Not(In(Eval('type'), ['image', 'remote_image']))
})
click_url = fields.Char('Click URL', translate=True,
states = {
'invisible': Not(In(Eval('type'), ['image', 'remote_image']))
})
active = fields.Boolean('Active', select=True)
attachments = fields.One2Many('ir.attachment', 'resource', 'Attachments')
2015-01-15 11:19:05 +01:00
visibility = fields.Selection([
('public','Public'),
('register','Register'),
('manager','Manager'),
], 'Visibility', required=True)
2014-05-27 09:45:10 +02:00
@staticmethod
def default_active():
'Return True'
return True
@staticmethod
def default_type():
'Return Image'
return 'image'
2015-01-15 11:19:05 +01:00
@staticmethod
def default_visibility():
return 'public'
@fields.depends('name', 'code')
2014-05-27 09:45:10 +02:00
def on_change_name(self):
if self.name and not self.code:
self.code = slugify(self.name)
2014-06-12 19:37:16 +02:00
class Carousel(ModelSQL, ModelView):
"Carousel CMS"
__name__ = 'galatea.cms.carousel'
name = fields.Char('Name', translate=True, required=True)
2014-06-12 19:37:16 +02:00
code = fields.Char('Code', required=True,
help='Internal code. Use characters az09')
active = fields.Boolean('Active', select=True)
items = fields.One2Many('galatea.cms.carousel.item', 'carousel', 'Items')
@staticmethod
def default_active():
return True
def on_change_name(self):
if self.name and not self.code:
self.code = slugify(self.name)
2014-06-12 19:37:16 +02:00
class CarouselItem(ModelSQL, ModelView):
"Carousel Item CMS"
__name__ = 'galatea.cms.carousel.item'
carousel = fields.Many2One("galatea.cms.carousel", "Carousel", required=True)
name = fields.Char('Label', translate=True, required=True)
link = fields.Char('Link', translate=True,
help='URL absolute')
image = fields.Char('Image', translate=True,
help='Image with URL absolute')
sublabel = fields.Char('Sublabel', translate=True,
help='In case text carousel, second text')
description = fields.Char('Description', translate=True,
help='In cas text carousel, description text')
html = fields.Text('HTML', translate=True,
help='HTML formated item - Content carousel-inner')
active = fields.Boolean('Active', select=True)
sequence = fields.Integer('Sequence')
@staticmethod
def default_active():
return True
@staticmethod
def default_sequence():
return 1
@classmethod
def __setup__(cls):
super(CarouselItem, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
cls._order.insert(1, ('id', 'ASC'))