Commit f1793e2d authored by sylvain.thenault@logilab.fr's avatar sylvain.thenault@logilab.fr
Browse files

unification of meta-attributes handling:

* remove has_format, has_text_encoding, format, text_encoding methods on Entity
* remove rich_text_fields method on EntitySchema
* use instead has_metadata / meta_attribute on EntitySchema (from yams)
  and attribute_metadata on Entity

--HG--
branch : tls-sprint
parent 7ca89f4468e4
......@@ -89,13 +89,12 @@ class AnyEntity(Entity):
@classmethod
def __initialize__(cls):
super(ANYENTITY, cls).__initialize__() # XXX
eschema = cls.e_schema
eschema.format_fields = {}
# set a default_ATTR method for rich text format fields
for attr, formatattr in eschema.rich_text_fields():
if not hasattr(cls, 'default_%s' % formatattr):
setattr(cls, 'default_%s' % formatattr, cls._default_format)
eschema.format_fields[formatattr] = attr
# XXX move this away once the old widgets have been dropped!
eschema = cls.e_schema
for metaattr, (metadata, attr) in eschema.meta_attributes().iteritems():
if metadata == 'format' and not hasattr(cls, 'default_%s' % metaattr):
setattr(cls, 'default_%s' % metaattr, cls._default_format)
# meta data api ###########################################################
......@@ -414,9 +413,9 @@ class AnyEntity(Entity):
"""return True if fckeditor should be used to edit entity's attribute named
`attr`, according to user preferences
"""
if self.req.use_fckeditor() and self.has_format(attr):
if self.req.use_fckeditor() and self.has_metadata(attr, 'format'):
if self.has_eid() or '%s_format' % attr in self:
return self.format(attr) == 'text/html'
return self.attribute_metadata(attr, 'format') == 'text/html'
return self.req.property_value('ui.default-text-format') == 'text/html'
return False
......
......@@ -461,29 +461,12 @@ class Entity(AppRsetObject, dict):
needcheck = False
return mainattr, needcheck
@classmethod
@obsolete('use method of the same name on the schema')
def has_format(cls, attr):
"""return true if this entity's schema has a format field for the given
attribute
"""
return cls.e_schema.has_format(attr)
def format(self, attr):
"""return the mime type format for an attribute (if specified)"""
return getattr(self, '%s_format' % attr, None)
def text_encoding(self, attr):
"""return the text encoding for an attribute, default to site encoding
"""
encoding = getattr(self, '%s_encoding' % attr, None)
return encoding or self.vreg.property_value('ui.encoding')
def has_text_encoding(self, attr):
"""return true if this entity's schema has ab encoding field for the
given attribute
"""
return self.e_schema.has_subject_relation('%s_encoding' % attr)
def attribute_metadata(self, attr, metadata):
"""return a metadata for an attribute (None if unspecified)"""
value = getattr(self, '%s_%s' % (attr, metadata), None)
if value is None and metadata == 'encoding':
value = self.vreg.property_value('ui.encoding')
return value
def printable_value(self, attr, value=_marker, attrtype=None,
format='text/html', displaytime=True):
......@@ -505,17 +488,14 @@ class Entity(AppRsetObject, dict):
# description...
if props.get('internationalizable'):
value = self.req._(value)
attrformat = self.format(attr)
attrformat = self.attribute_metadata(attr, 'format')
if attrformat:
return self.mtc_transform(value, attrformat, format,
self.req.encoding)
elif attrtype == 'Bytes':
attrformat = self.format(attr)
attrformat = self.attribute_metadata(attr, 'format')
if attrformat:
try:
encoding = getattr(self, '%s_encoding' % attr)
except AttributeError:
encoding = self.req.encoding
encoding = self.attribute_metadata(attr, 'encoding')
return self.mtc_transform(value.getvalue(), attrformat, format,
encoding)
return u''
......
......@@ -322,28 +322,7 @@ class CubicWebEntitySchema(EntitySchema):
def schema_entity(self):
"""return True if this entity type is used to build the schema"""
return self.type in self.schema.schema_entity_types()
def has_format(self, attr):
"""return true if this entity's schema has a format field for the given
attribute
"""
return self.has_subject_relation('%s_format' % attr)
def has_format(self, attr):
"""return true if this entity's schema has an encoding field for the given
attribute
"""
return self.has_subject_relation('%s_format' % attr)
def rich_text_fields(self):
"""return an iterator on (attribute, format attribute) of rich text field
(the first tuple element containing the text and the second the text format)
"""
for rschema, _ in self.attribute_definitions():
if rschema.type.endswith('_format') and self.has_subject_relation(rschema.type[:-7]):
yield self.subject_relation(rschema.type[:-7]), rschema
def check_perm(self, session, action, eid=None):
# NB: session may be a server session or a request object
user = session.user
......
......@@ -45,16 +45,18 @@ class TidyHtmlFields(Hook):
accepts = ('Any',)
def call(self, session, entity):
for formatattr, attr in entity.e_schema.format_fields.iteritems():
try:
value = entity[attr]
except KeyError:
continue # no text to tidy
if isinstance(value, unicode): # filter out None and Binary
if self.event == 'before_add_entity':
fmt = entity.get(formatattr)
else:
fmt = entity.get_value(formatattr)
if fmt == 'text/html':
entity[attr] = soup2xhtml(value, session.encoding)
metaattrs = entity.e_schema.meta_attributes()
for metaattr, (metadata, attr) in metaattrs.iteritems():
if metadata == 'format':
try:
value = entity[attr]
except KeyError:
continue # no text to tidy
if isinstance(value, unicode): # filter out None and Binary
if self.event == 'before_add_entity':
fmt = entity.get(metaattr)
else:
fmt = entity.get_value(metaattr)
if fmt == 'text/html':
entity[attr] = soup2xhtml(value, session.encoding)
......@@ -475,16 +475,16 @@ class EntityFieldsForm(FieldsForm):
def form_field_format(self, field):
entity = self.entity
if field.eidparam and entity.has_format(field.name) and (
if field.eidparam and entity.has_metadata(field.name, 'format') and (
entity.has_eid() or '%s_format' % field.name in entity):
return self.entity.format(field.name)
return self.entity.attribute_metadata(field.name, 'format')
return self.req.property_value('ui.default-text-format')
def form_field_encoding(self, field):
entity = self.entity
if field.eidparam and entity.has_encoding(field.name) and (
if field.eidparam and entity.has_metadata(field.name, 'encoding') and (
entity.has_eid() or '%s_encoding' % field.name in entity):
return self.entity.text_encoding()
return self.entity.attribute_metadata(field.name, 'encoding')
return super(EntityFieldsForm, self).form_field_encoding(field)
def _form_field_entity_value(self, field, default_initial=True, load_bytes=False):
......
......@@ -373,7 +373,7 @@ def guess_field(eclass, rschema, role='subject', **kwargs):
return None
if targetschema == 'Password':
return StringField(widget=PasswordInput(), **kwargs)
if eschema.has_format(rschema):
if eschema.has_metadata(rschema, 'format'):
constraints = rschema.rproperty(eschema, targetschema, 'constraints')
for cstr in constraints:
if isinstance(cstr, StaticVocabularyConstraint):
......
......@@ -201,24 +201,24 @@ class EditController(ViewController):
if formparams.has_key('__%s_detach' % attr) or formparams.has_key('%s__detach' % attr):
# drop current file value
value = None
# no need to check value when nor explicit detach nor new file submitted,
# since it will think the attribut is not modified
# no need to check value when nor explicit detach nor new file
# submitted, since it will think the attribute is not modified
elif isinstance(value, unicode):
# file modified using a text widget
value = Binary(value.encode(entity.text_encoding(attr)))
value = Binary(value.encode(entity.attribute_metadata(attr, 'encoding')))
else:
# (filename, mimetype, stream)
val = Binary(value[2].read())
if not val.getvalue(): # usually an unexistant file
value = None
else:
# XXX suppose a File compatible schema
val.filename = value[0]
if entity.has_format(attr):
if entity.has_metadata(attr, 'format'):
key = '%s_format' % attr
formparams[key] = value[1]
self.relations.append('X %s_format %%(%s)s'
% (attr, key))
# XXX suppose a File compatible schema
if entity.e_schema.has_subject_relation('name') \
and not formparams.get('name'):
formparams['name'] = value[0]
......
......@@ -410,7 +410,7 @@ class TextWidget(Widget):
entity.req.fckeditor_config()
if with_format:
if entity.has_eid():
format = entity.format(self.name)
format = entity.attribute_metadata(self.name, 'format')
else:
format = ''
frname = eid_param(self.name + '_format', entity.eid)
......@@ -419,7 +419,7 @@ class TextWidget(Widget):
frname, format, frname)
return u'%s<textarea cubicweb:type="wysiwyg" onkeypress="autogrow(this)" name="%s" %s>%s</textarea>' % (
hidden, self.rname, self.format_attrs(), dvalue)
if with_format and entity.has_format(self.name):
if with_format and entity.has_metadata(self.name, 'format'):
fmtwdg = entity.get_widget(self.name + '_format')
fmtwdgstr = fmtwdg.edit_render(entity, tabindex=self.attrs['tabindex'])
self.attrs['tabindex'] = entity.req.next_tabindex()
......@@ -467,7 +467,7 @@ class FileWidget(Widget):
def _file_wdg(self, entity):
wdgs = [u'<input type="file" name="%s" %s/>' % (self.rname, self.format_attrs())]
req = entity.req
if entity.has_format(self.name) or entity.has_text_encoding(self.name):
if entity.has_metadata(self.name, 'format') or entity.has_metadata(self.name, 'encoding'):
divid = '%s-%s-advanced' % (self.name, entity.eid)
wdgs.append(u'<a href="%s" title="%s"><img src="%s" alt="%s"/></a>' %
(html_escape(toggle_action(divid)),
......@@ -509,14 +509,14 @@ class TextFileWidget(FileWidget):
def _edit_render(self, entity):
wdgs = [self._file_wdg(entity)]
if entity.format(self.name) in ('text/plain', 'text/html', 'text/rest'):
if entity.attribute_metadata(self.name, 'format') in ('text/plain', 'text/html', 'text/rest'):
msg = self._edit_msg(entity)
wdgs.append(u'<p><b>%s</b></p>' % msg)
twdg = TextWidget(self.vreg, self.subjtype, self.rschema, self.objtype)
twdg.rname = self.rname
data = getattr(entity, self.name)
if data:
encoding = entity.text_encoding(self.name)
encoding = entity.attribute_metadata(self.name, 'encoding')
try:
entity[self.name] = unicode(data.getvalue(), encoding)
except UnicodeError:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment