2013-10-08 09:22:33 +00:00
# -*- coding: utf-8 -*-
2013-10-08 09:26:12 +00:00
"""
Website - context rendering needs to add some metadata to rendered fields ,
as well as render a few fields differently .
Also , adds methods to convert values back to openerp models .
"""
2013-10-08 09:22:33 +00:00
import itertools
2013-10-08 12:04:56 +00:00
import werkzeug . utils
2013-10-09 13:31:12 +00:00
from lxml import etree , html
2013-10-08 12:04:56 +00:00
2013-10-08 09:22:33 +00:00
from openerp . osv import orm , fields
2013-10-09 13:31:12 +00:00
from openerp . tools import ustr
2013-10-08 09:22:33 +00:00
class QWeb ( orm . AbstractModel ) :
""" QWeb object for rendering stuff in the website context
"""
_name = ' website.qweb '
_inherit = ' ir.qweb '
def get_converter_for ( self , field_type ) :
return self . pool . get (
' website.qweb.field. ' + field_type ,
self . pool [ ' website.qweb.field ' ] )
class Field ( orm . AbstractModel ) :
_name = ' website.qweb.field '
_inherit = ' ir.qweb.field '
def attributes ( self , cr , uid , field_name , record , options ,
source_element , g_att , t_att , qweb_context ) :
column = record . _model . _all_columns [ field_name ] . column
return itertools . chain (
super ( Field , self ) . attributes ( cr , uid , field_name , record , options ,
source_element , g_att , t_att ,
qweb_context ) ,
[ ( ' data-oe-translate ' , 1 if column . translate else 0 ) ]
)
2013-10-09 13:31:12 +00:00
def value_from_string ( self , value ) :
return value
def from_html ( self , cr , uid , model , column , element , context = None ) :
return self . value_from_string ( element . text_content ( ) . strip ( ) )
class Integer ( orm . AbstractModel ) :
_name = ' website.qweb.field.integer '
_inherit = [ ' website.qweb.field ' ]
value_from_string = int
2013-10-08 09:22:33 +00:00
class Float ( orm . AbstractModel ) :
_name = ' website.qweb.field.float '
_inherit = [ ' website.qweb.field ' , ' ir.qweb.field.float ' ]
2013-10-09 13:31:12 +00:00
value_from_string = float
2013-10-08 09:22:33 +00:00
class Text ( orm . AbstractModel ) :
_name = ' website.qweb.field.text '
_inherit = [ ' website.qweb.field ' , ' ir.qweb.field.text ' ]
2013-10-09 13:31:12 +00:00
def from_html ( self , cr , uid , model , column , element , context = None ) :
return element . text_content ( )
2013-10-08 09:22:33 +00:00
class Selection ( orm . AbstractModel ) :
_name = ' website.qweb.field.selection '
_inherit = [ ' website.qweb.field ' , ' ir.qweb.field.selection ' ]
2013-10-09 13:31:12 +00:00
def from_html ( self , cr , uid , model , column , element , context = None ) :
value = element . text_content ( ) . strip ( )
selection = column . reify ( cr , uid , model , column , context = context )
for k , v in selection :
if isinstance ( v , str ) :
v = ustr ( v )
if value == v :
return k
raise ValueError ( u " No value found for label %s in selection %s " % (
value , selection ) )
2013-10-08 09:22:33 +00:00
class ManyToOne ( orm . AbstractModel ) :
_name = ' website.qweb.field.many2one '
_inherit = [ ' website.qweb.field ' , ' ir.qweb.field.many2one ' ]
2013-10-09 13:31:12 +00:00
def from_html ( self , cr , uid , model , column , element , context = None ) :
# FIXME: this behavior is really weird, what if the user wanted to edit the name of the related thingy? Should m2os really be editable without a widget?
matches = self . pool [ column . _obj ] . name_search (
cr , uid , name = element . text_content ( ) . strip ( ) , context = context )
# FIXME: no match? More than 1 match?
assert len ( matches ) == 1
return matches [ 0 ] [ 0 ]
2013-10-08 09:22:33 +00:00
class HTML ( orm . AbstractModel ) :
_name = ' website.qweb.field.html '
_inherit = [ ' website.qweb.field ' , ' ir.qweb.field.html ' ]
2013-10-09 13:31:12 +00:00
def from_html ( self , cr , uid , model , column , element , context = None ) :
content = [ ]
if element . text : content . append ( element . text )
content . extend ( html . tostring ( child )
for child in element . iterchildren ( tag = etree . Element ) )
return ' \n ' . join ( content )
2013-10-08 09:22:33 +00:00
class Image ( orm . AbstractModel ) :
2013-10-08 12:04:56 +00:00
"""
Widget options :
` ` class ` `
set as attribute on the generated < img > tag
"""
2013-10-08 09:22:33 +00:00
_name = ' website.qweb.field.image '
_inherit = [ ' website.qweb.field ' , ' ir.qweb.field.image ' ]
2013-10-08 12:04:56 +00:00
def to_html ( self , cr , uid , field_name , record , options ,
source_element , t_att , g_att , qweb_context ) :
assert source_element . nodeName != ' img ' , \
" Oddly enough, the root tag of an image field can not be img. " \
" That is because the image goes into the tag, or it gets the " \
" hose again. "
return super ( Image , self ) . to_html (
cr , uid , field_name , record , options ,
source_element , t_att , g_att , qweb_context )
def record_to_html ( self , cr , uid , field_name , record , column , options = None ) :
cls = ' '
if ' class ' in options :
cls = ' class= " %s " ' % werkzeug . utils . escape ( options [ ' class ' ] )
return ' <img %s src= " /website/image?model= %s &field= %s &id= %s " /> ' % (
cls , record . _model . _name , field_name , record . id )
2013-10-08 12:20:39 +00:00
class Monetary ( orm . AbstractModel ) :
_name = ' website.qweb.field.monetary '
_inherit = [ ' website.qweb.field ' , ' ir.qweb.field.monetary ' ]