Birthday is now optional as a behaviour.

This commit is contained in:
Thomas Desvenain 2013-09-10 13:01:10 +02:00
parent df643b9d04
commit 0339000bdf
10 changed files with 61 additions and 28 deletions

View File

@ -4,6 +4,9 @@ Changelog
1.0 (unreleased)
----------------
- Birthday is now optional as a behaviour.
[thomasdesvenain]
- Use (-200, 1) years range for birthday field.
[vincentfretin]

View File

@ -6,6 +6,7 @@ from Products.CMFPlone.utils import safe_unicode
from collective.contact.core.interfaces import IVCard, IContactable
from collective.contact.core.content.held_position import IHeldPosition,\
HeldPosition
from collective.contact.core.behaviors import IBirthday
class HeldPositionVCard(grok.Adapter):
@ -35,7 +36,7 @@ class HeldPositionVCard(grok.Adapter):
vcard.add('fn')
vcard.fn.value = ' '.join([e for e in (firstname, lastname) if e])
if person.birthday is not None:
if IBirthday.providedBy(person) and person.birthday is not None:
vcard.add('bday')
vcard.bday.value = person.birthday.isoformat()

View File

@ -3,14 +3,17 @@ from zope.interface import Interface
from zope import schema
from Acquisition import aq_base
from z3c.form.widget import ComputedWidgetAttribute
from z3c.form.widget import FieldWidget
from plone.supermodel import model
from plone.supermodel.directives import fieldset
from plone.autoform.interfaces import IFormFieldProvider
from plone.autoform import directives as form
from plone.formwidget.masterselect import MasterSelectBoolField
from plone.formwidget.datetime.z3cform import DateWidget
from plone.app.textfield import RichText
from plone.app.dexterity.browser.types import TypeSchemaContext
from z3c.form.widget import ComputedWidgetAttribute
from Products.CMFDefault.utils import checkEmailAddress
from Products.CMFDefault.exceptions import EmailAddressInvalid
@ -233,6 +236,22 @@ DefaultParentAddress = ComputedWidgetAttribute(
field=IContactDetails['parent_address'], view=Interface)
def DateFieldWidget(field, request):
"""IFieldWidget factory for DatetimeWidget."""
widget = FieldWidget(field, DateWidget(request))
widget.years_range = (-200, 1)
return widget
class IBirthday(model.Schema):
form.widget(birthday=DateFieldWidget)
birthday = schema.Date(
title=_("Birthday"),
required=False,
)
class IRelatedOrganizations(model.Schema):
"""A content on which we can attach organizations
"""

View File

@ -21,6 +21,12 @@
provides=".behaviors.IGlobalPositioning"
/>
<plone:behavior
title="Birthday"
description="Contact have a birthday."
provides=".behaviors.IBirthday"
/>
<plone:behavior
title="Related organizations"
description="We can attach organizations on content."

View File

@ -4,6 +4,7 @@ from collective.contact.core.browser.contactable import BaseView
from collective.contact.core.browser.utils import get_ttw_fields,\
date_to_DateTime
from collective.contact.core.interfaces import IContactable
from collective.contact.core.behaviors import IBirthday
class Contact(BaseView):
@ -35,11 +36,14 @@ class Contact(BaseView):
self.person = person
self.fullname = person.Title()
self.title = held_position.Title()
birthday = person.birthday
if birthday is not None:
birthday = date_to_DateTime(birthday)
self.birthday = self.context.toLocalizedTime(birthday)
if IBirthday.providedBy(person):
birthday = person.birthday
if birthday is not None:
birthday = date_to_DateTime(birthday)
self.birthday = self.context.toLocalizedTime(birthday)
else:
self.birthday = None
self.gender = person.gender or ''

View File

@ -4,6 +4,7 @@ from collective.contact.core.browser.contactable import BaseView
from collective.contact.core.browser.utils import date_to_DateTime,\
get_ttw_fields
from collective.contact.core.interfaces import IContactable
from collective.contact.core.behaviors import IBirthday
class Person(BaseView):
@ -21,10 +22,13 @@ class Person(BaseView):
person = self.person
self.name = person.Title()
birthday = person.birthday
if birthday is not None:
birthday = date_to_DateTime(birthday)
self.birthday = self.context.toLocalizedTime(birthday)
if IBirthday.providedBy(person):
birthday = person.birthday
if birthday is not None:
birthday = date_to_DateTime(birthday)
self.birthday = self.context.toLocalizedTime(birthday)
else:
self.birthday = ""
self.person_title = person.person_title
self.gender = person.gender or ''

View File

@ -3,7 +3,6 @@ from zope.interface import implements
from zope.interface import Attribute
from z3c.form.interfaces import NO_VALUE
from z3c.form.browser.radio import RadioFieldWidget
from z3c.form.widget import FieldWidget
from five import grok
@ -12,7 +11,6 @@ from plone.dexterity.content import Container
from plone.dexterity.schema import DexteritySchemaPolicy
from plone.namedfile.field import NamedImage
from plone.supermodel import model
from plone.formwidget.datetime.z3cform import DateWidget
from collective.contact.core import _
from collective.contact.core.browser.contactable import Contactable
@ -20,13 +18,6 @@ from collective.contact.widget.interfaces import IContactContent
from collective.contact.core.content.held_position import IHeldPosition
def DateFieldWidget(field, request):
"""IFieldWidget factory for DatetimeWidget."""
widget = FieldWidget(field, DateWidget(request))
widget.years_range = (-200, 1)
return widget
class IPerson(model.Schema, IContactContent):
"""Interface for Person content type"""
@ -50,11 +41,6 @@ class IPerson(model.Schema, IContactContent):
title=_("Person title"),
required=False,
)
form.widget(birthday=DateFieldWidget)
birthday = schema.Date(
title=_("Birthday"),
required=False,
)
photo = NamedImage(
title=_("Photo"),
required=False,
@ -64,6 +50,7 @@ class IPerson(model.Schema, IContactContent):
"""Returns held positions of this person
"""
class PersonContactableAdapter(Contactable):
"""Contactable adapter for Person content type"""
@ -97,7 +84,10 @@ class Person(Container):
def get_held_positions(self):
return [obj for obj in self.values() if IHeldPosition.providedBy(obj)]
def get_held_positions_titles(self):
return [p.Title() for p in self.get_held_positions()]
class PersonSchemaPolicy(grok.GlobalUtility,
DexteritySchemaPolicy):

View File

@ -23,6 +23,7 @@
<property name="behaviors">
<element value="plone.app.content.interfaces.INameFromTitle"/>
<element value="collective.contact.core.behaviors.IContactDetails" />
<element value="collective.contact.core.behaviors.IBirthday" />
</property>
<property name="schema" />
<!-- DO NOT use a model_source or it removes manually added fields while reapplying the profile -->

View File

@ -21,6 +21,7 @@
<property name="behaviors">
<element value="collective.contact.core.behaviors.IContactDetails" />
<element value="collective.contact.core.behaviors.IGlobalPositioning" />
<element value="collective.contact.core.behaviors.IBirthday" />
</property>
<property name="schema" />
<!-- DO NOT use a model_source or it removes manually added fields while reapplying the profile -->

View File

@ -12,7 +12,7 @@ from ecreall.helpers.testing.base import BaseTest
from collective.contact.core.testing import INTEGRATION
from collective.contact.core.behaviors import IContactDetails,\
IGlobalPositioning
IGlobalPositioning, IBirthday
class TestBehaviors(unittest.TestCase, BaseTest):
@ -33,18 +33,22 @@ class TestBehaviors(unittest.TestCase, BaseTest):
name='collective.contact.core.behaviors.IContactDetails')
global_positioning_behavior = getUtility(IBehavior,
name='collective.contact.core.behaviors.IGlobalPositioning')
birthday_behavior = getUtility(IBehavior,
name='collective.contact.core.behaviors.IBirthday')
self.assertEqual(contact_details_behavior.interface, IContactDetails)
self.assertEqual(global_positioning_behavior.interface,
IGlobalPositioning)
self.assertEqual(birthday_behavior.interface, IBirthday)
IFormFieldProvider.providedBy(contact_details_behavior.interface)
IFormFieldProvider.providedBy(global_positioning_behavior.interface)
IFormFieldProvider.providedBy(birthday_behavior.interface)
def test_contact_details_fields(self):
item = self.testitem
self.assertIsNone(item.getAttributes())
for attr in ('country', 'region', 'zip_code', 'city', 'street',
'number', 'im_handle', 'cell_phone', 'phone', 'email',
'additional_address_details'):
'additional_address_details', 'birthday'):
self.assertTrue(hasattr(item, attr))
item.phone = '0655443322'
item.email = 'toto@example.com'