skip to navigation
skip to content

z3ext.formatter 1.3.0

Extensible TALES fomratter expression.

Latest Version: 1.4.2

Detailed Dcoumentation
======================


===============
z3ext.formatter
===============

This package adds extensible tales expression for various formatters.
You can change formatter setting per site basis (z3ext.controlpanel).

For configure default settings, add following code to zope.conf


  timezone UTC
  timezoneFormat 2
  principalTimezone true


Values for timezoneFormat are:
    1: No timezone
    2: Number of hours
    3: Timezone name

We need register controlpanel configlet

  >>> from zope.configuration import xmlconfig
  >>> context = xmlconfig.string("""
  ... 
  ...    
  ...  
  ... """)

We'll try emulate 

  >>> from zope.app.appsetup import product
  >>> product._configs['z3ext.formatter'] = {
  ...   'timezone': u'UTC', 'timezoneFormat': '2', 'principalTimezone': 'true'}

Let's check this

   >>> product.getProductConfiguration('z3ext.formatter')
   {'timezone': u'UTC', 'timezoneFormat': '2', 'principalTimezone': 'true'}


Usually initFormatter() function is colled during IDatabaseOpenedEvent event,
we simply call it directly:

   >>> from z3ext.formatter.config import initFormatter
   >>> initFormatter(None)

Now we can get IFormatterConfiglet utility

   >>> from zope.component import getUtility
   >>> from z3ext.formatter.interfaces import IFormatterConfiglet

   >>> configlet = getUtility(IFormatterConfiglet)

Setup request

   >>> from zope import interface
   >>> from zope.publisher.browser import TestRequest
   >>> from zope.annotation.interfaces import IAttributeAnnotatable

   >>> request = TestRequest(environ={'HTTP_ACCEPT_LANGUAGE': 'en'})
   >>> interface.directlyProvides(request, IAttributeAnnotatable)

   >>> from pytz import UTC
   >>> from datetime import date, datetime, timedelta


DateTime formatter
------------------

   >>> from z3ext.formatter.tests import ZPTPage
   >>> page = ZPTPage()
   >>> page.pt_edit(u'''
   ... 
   ...   
   ...     
   ...     
   ...     
   ...     
   ...     
   ...   
   ... ''', 'text/html')

   >>> dt = datetime(2007, 1, 1, 0, 0, 0, tzinfo=UTC)
   >>> dt
   datetime.datetime(2007, 1, 1, 0, 0, tzinfo=)

By default we use UTC timezone for output:

   >>> print page.render(request, now=dt)
   
     
       1/1/07 12:00 AM
       Jan 1, 2007 12:00:00 AM
       January 1, 2007 12:00:00 AM +000
       Monday, January 1, 2007 12:00:00 AM +000
       Jan 1, 2007 12:00:00 AM
     
   


If datetime object doesn't contain timezone information, UTC is used

   >>> print page.render(request, now=datetime(2007, 1, 1, 0, 0))
   
     
       1/1/07 12:00 AM
       Jan 1, 2007 12:00:00 AM
       January 1, 2007 12:00:00 AM +000
       Monday, January 1, 2007 12:00:00 AM +000
       Jan 1, 2007 12:00:00 AM
     
   


Now let's chane timezone to US/Pacific, we change only time zone
not datetime value

   >>> configlet.timezone = 'US/Pacific'

   >>> print page.render(request, now=dt)
   
     
       12/31/06 4:00 PM
       Dec 31, 2006 4:00:00 PM
       December 31, 2006 4:00:00 PM -800
       Sunday, December 31, 2006 4:00:00 PM -800
       Dec 31, 2006 4:00:00 PM
     
   


Now we can change timezone format to 3 (Timezone name)

   >>> configlet.timezoneFormat = 3

   >>> print page.render(request, now=dt)
   
     
       12/31/06 4:00 PM
       Dec 31, 2006 4:00:00 PM US/Pacific
       December 31, 2006 4:00:00 PM -800
       Sunday, December 31, 2006 4:00:00 PM US/Pacific
       Dec 31, 2006 4:00:00 PM US/Pacific
     
   


We also can redefine timezone for principal if we use principalTimezone true

   >>> from pytz import timezone
   >>> from zope import interface, component
   >>> class IPrincipal(interface.Interface):
   ...   pass

   >>> class Principal:
   ...     interface.implements(IPrincipal)
   ...
   ...     def __init__(self, id):
   ...         self.id = id
   ...         self.groups = []

   >>> @component.adapter(IPrincipal)
   ... @interface.implementer(interface.common.idatetime.ITZInfo)
   ... def getTimezone(prin):
   ...   if prin.id == 'user1':
   ...     return timezone('Europe/Paris')
   ...   elif prin.id == 'user2':
   ...     return timezone('Asia/Almaty')
   >>> component.provideAdapter(getTimezone)

   >>> request.setPrincipal(Principal('user1'))
   >>> print page.render(request, now=dt)
   
     
       1/1/07 1:00 AM
       Jan 1, 2007 1:00:00 AM Europe/Paris
       January 1, 2007 1:00:00 AM +100
       Monday, January 1, 2007 1:00:00 AM Europe/Paris
       Jan 1, 2007 1:00:00 AM Europe/Paris
     
   

   >>> request.setPrincipal(Principal('user2'))
   >>> print page.render(request, now=dt)
   
     
       1/1/07 6:00 AM
       Jan 1, 2007 6:00:00 AM Asia/Almaty
       January 1, 2007 6:00:00 AM +600
       Monday, January 1, 2007 6:00:00 AM Asia/Almaty
       Jan 1, 2007 6:00:00 AM Asia/Almaty
     
   

   >>> request.setPrincipal(None)


fancyDatetime formatter
-----------------------

   >>> now = datetime.now(UTC)

   >>> fpage = ZPTPage()
   >>> fpage.pt_edit(u'''
   ... 
   ...   
   ...     
   ...     
   ...     
   ...     
   ...   
   ... ''', 'text/html')

Today's datetime

   >>> today = now - timedelta(hours=1)

   >>> print fpage.render(request, now=today)
   
     
       Today at ...
       Today at ...
       Today at ...
       Today at ...
     
   


Yesterday's datetime

   >>> yesterday = now - timedelta(hours=25)

   >>> print fpage.render(request, now=yesterday)
   
     
       Yesterday at ...
       Yesterday at ...
       Yesterday at ...
       Yesterday at ...
     
   


Default timezone is UTC

   >>> now = datetime.now(UTC)
   >>> print fpage.render(request, now=now)
   
     
       Today at ...
       Today at ...
       Today at ...
       Today at ...
     
   


Date formatter
--------------

   >>> datepage = ZPTPage()
   >>> datepage.pt_edit(u'''
   ... 
   ...   
   ...     
   ...     
   ...   
   ... ''', 'text/html')

   >>> d = date(2007, 1, 1)
   >>> d
   datetime.date(2007, 1, 1)

   >>> print datepage.render(request, today=d)
   
     
       Jan 1, 2007
       1/1/07
     
   


Also you can get formatter from python code

   >>> from z3ext.formatter.utils import getFormatter
   >>> formatter = getFormatter(request, 'dateTime', 'full')
   >>> formatter.format(dt)
   u'Sunday, December 31, 2006 4:00:00 PM US/Pacific'

We will get FormatterNotDefined if formatter is unknown

   >>> getFormatter(request, 'unknown')
   Traceback (most recent call last):
   ...
   FormatterNotDefined: ...

Wrong format, we should add path expression

   >>> errpage = ZPTPage()
   >>> errpage.pt_edit(u'''
   ...     ''', 'text/html')
   >>> print errpage.render(request)
   Traceback (most recent call last):
   ...
   PTRuntimeError: ...

Unknown formatter

   >>> errpage = ZPTPage()
   >>> errpage.pt_edit(u'''
   ...     ''', 'text/html')
   >>> print errpage.render(request)
   Traceback (most recent call last):
   ...
   FormatterNotDefined: unknown


Custom formatter
================

We should define formatter factory and formatter itself
Let's implement formatter that accept string and currency name and
format as currency. Format of TALES expression whould be as
'formatter:,,,...:'
 is name of adapter that adapts IHTTPRequest to IFormatterFactory
also expression will pass  as args to factory.

   >>> from z3ext.formatter.interfaces import IFormatter, IFormatterFactory

Here code of formatter:

   >>> class MyFormatter(object):
   ...    interface.implements(IFormatter)
   ...
   ...    currencies = {'usd': '$', 'euro': 'Eur'}
   ...
   ...    def __init__(self, request, *args):
   ...       self.request = request
   ...       self.currency = self.currencies[args[0]]
   ...
   ...    def format(self, value):
   ...       return '%s %s'%(value, self.currency)

Now we need formatter factory:

   >>> class MyFormatterFactory(object):
   ...    interface.implements(IFormatterFactory)
   ...
   ...    def __init__(self, request):
   ...        self.request = request
   ...
   ...    def __call__(self, *args, **kw):
   ...        return MyFormatter(self.request, *args)

Now we need register factory as named adapter for IHTTPRequest

   >>> from zope.component import provideAdapter
   >>> from zope.publisher.interfaces.http import IHTTPRequest

   >>> provideAdapter(MyFormatterFactory, \
   ...   (IHTTPRequest,), IFormatterFactory, name='currency')

Now we can use formatter

   >>> page = ZPTPage()
   >>> page.pt_edit(u'''
   ... 
   ... 
   ... ''', 'text/html')

   >>> print page.render(request)
   121.04 $
   121.04 Eur


=======
CHANGES
=======

1.3.0 (2009-07-05)
------------------

- Added chameleon support

- Added 'formatter' chameleon expression


1.2.7 (2009-04-??)
------------------

- Do not use z3c.autoinclude


1.2.6 (2009-03-11)
------------------

- Added 'human' datetime formatter (XX minute(s) ago)

- Do not show seconds for fancyDatetime fomratter

- Fixed multple usage of one fancyDatetime formatter


1.2.5 (2008-11-23)
------------------

- z3ext.controlpanel is optional

- Added buildout for testing against zope3.4

1.2.4 (2008-10-21)
------------------

- Fixed russian translation

- nl translation updated


1.2.3 (2008-10-20)
------------------

- Added translations: nl, ru


1.2.2 (2008-10-10)
------------------

- Use new i18n domain z3ext.formatter


1.2.1 (2008-05-16)
------------------

- Replace 'autoinclude' with 'includeDependendcies'


1.2.0 (2008-03-25)
------------------

- Use z3c.autoinclude

- Code moved to svn.zope.org


1.1.2 (2008-03-06)
------------------

- Fixed bug in fancyDatetime formatter


1.1.1 (2008-02-05)
------------------

- Added 'Timezones' vocabulary

- Cleanup code


1.1.0 (2007-12-21)
------------------

- Added controlpanel configlet


1.0.0 (2007-12-07)
------------------

- Initial release.
File Type Py Version Uploaded on Size # downloads
z3ext.formatter-1.3.0.tar.gz (md5) Source 2009-07-05 09:56:50.370966 18KB 60

Log in to rate this package.