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

Release 0.9.0 (2010-07-19)
--------------------------

* [Enhancements]

  * Performance improved (about 5%).

  * (IMPORTANT!!)
    Fragment cache supported.
    See
      http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#fragment-cache
    for details.

  * (IMPORTANT!!)
    include() now takes keyword arguments as local variables.
    ex.
      <?py include('header.pyhtml', title='Example') ?>

  * Add new module 'tenjin.gae'.

  * Add 'input' argument to tenjin.Template() to create template object without file.
    ex.
      input = "<p>Hello ${name}</p>"
      t = tenjin.Template(None, input=input)
      html = t.render({'name': 'World'})

  * Add tenjin.Engine.add_template() to add template object explicitly.

  * User's guide (doc/users-guide.html) is rewrited entirely.

  * Add benchmark for Jinja2.


* [Changes]

  * (IMPORTANT!!)
    It is strongly recommended to close 'if', 'for', 'while', ... by
    corresponding '#endif', '#endfor', '#endwhile', and so on.
    See
      http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#planned-changes
    for details.

  * (IMPORTANT!!)
    Google App Engine support is changed. All you have to do is to call
    tenjin.gae.init() at first.
    See
      http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#google-appengine
    for details.

  * (IMPORTANT!!)
    tenjin.Engine is changed to share a cache storage between engines by default.
    This improves performance of Tenjin but your test scripts may get errors.
    If you get errors in your test scripts, clear cache storage for each test.

        def setUp(self):
	    tenjin.Engine.cache.clear()

    If you prefer previous behaviour, set tenjin.Engine.cache to None.

        ## create new MarshalCacheStorage object for each engine
        tenjin.Engine.cache = None
    
  * Now you can set default template class to tenjin.Engine.templateclass.
    ex.
      tenjin.Engine.templateclass = MyTemplate

  * 'cache' argument of tenjin.Engine() is changed.
     [old behaviour] if 'cache' is None, cache template object into memory.
     [new behaviour] if 'cache' is None, use default cache storage.

  * Default preamble is changed from "print ''.join(_buf)" to
    "print(''.join(_buf))".

  * 'doc/faq.html' is integrated into 'doc/users-guide.html'.

  * All test scripts are changed to import oktest instead of unittest.


* [Bugfixes]

  * Fixed to set correct file path of template object which is loaded from cache.

  * Fixed a bug that 'pytenjin -sbN' didn't trim line number on the last line


Release 0.8.1 (2009-06-14)
--------------------------

* [Bugfix]

  * Fix bugs on CacheStorage#unset(). (thanks Steve)

  * Fix tenjin.helpers.html.new_cycle() to work on Python 3.0.

* [Changes]

  * Update 'doc/faq.html' and add new section.
    'Is it possible to change indent restriction more flexible?'
    http://www.kuwata-lab.com/tenjin/pytenjin-faq.html#faq-flexibleindent



Release 0.8.0 (2009-06-07)
--------------------------

* [Bugfix]

  * !!IMPORTANT!!
    Template caching is changed to keep template file's timestamp
    instead of create time of cached object. See
    http://groups.google.com/group/kuwata-lab-products/browse_thread/thread/a0d447c282fb383d#msg_de39557405c9b656
    for details. (Thanks Steve)

* [Changes]

  * !!IMPORTANT!!
    HTML helper function 'tagattr()' is renamed to 'tagattrs()'.
    (Notice that new 'tagattr()' is added. See below.)

  * 'tagattrs()' is changed to add ' ' (space) at the first character.
    ex.
      (0.7.0)  tagattr(klass='error')     #=> 'class="error"'
      (0.7.1)  tagattrs(klass='error')    #=> ' class="error"'

  * 'tagattrs()' is changed to handle 'checked', 'selected', and
    'disabled' attributes.
    ex.
       >>> from tenjin.helpers.html import *
       >>> tagattrs(checked=True, selected='Y', disabled=1)
       ' checked="checked" selected="selected" disabled="disabled"'
       >>> tagattrs(checked=False, selected='', disabled=0)
       ''

* [Enhancements]

  * Add new HTML helper function 'tagattr()'.
    (Notice that 'tagattr()' in 0.7.0 is renamed into 'tagattrs()'.)
    ex.
      >>> from tenjin.helpers.html import *
      >>> tagattr('size', 20)
      ' size="20"'
      >>> tagattr('size', 0)
      ''
      >>> tagattr('size', 20, 'large')
      ' size="large"'
      >>> size = 20        # you can use tagattrs() instead of tagattr()
      >>> tagattrs(size=(size and 'large'))
      ' size="large"'

  * Add new HTML helper function 'new_cycle()'.
    ex.
      >>> from tenjin.helpers.html import *
      >>> cycle = new_cycle('odd, 'even')
      >>> cycle()
      'odd'
      >>> cycle()
      'even'
      >>> cycle()
      'odd'
      >>> cycle()
      'even'

  * (experimental) Template converter is changed to add dummy if-statement
    when first Python statement is indented. (Thanks Steve)
    ex.
      $ cat ex.pyhtml
      <html>
        <body>
          <ul>
            <?py for item in items: ?>
            <li>${item}</li>
            <?py #end ?>
          </ul>
        </body>
      </html>
      $ pytenjin -sb ex.pyhtml
      _buf.extend(('''<html>
        <body>
          <ul>\n''', ));
      if True: ## dummy
            for item in items:
                _buf.extend(('''      <li>''', escape(to_str(item)), '''</li>\n''', ));
            #end
            _buf.extend(('''    </ul>
        </body>
      </html>\n''', ));

  * Update User's Guide and FAQ.



Release 0.7.0 (2009-05-24)
--------------------------

* [Enhancements]

  * Python 3.0 is now supported officially.

  * Google AppEngine (GAE) supported.
    You can use pyTenjin on Google AppEngine with memcache.
    See FAQ: 'Is pyTenjin ready for Google App Engine?' section.
    http://www.kuwata-lab.com/tenjin/pytenjin-faq.html#faq-google-appengine

  * Logging support.
    ex:

      import logging
      logging.basicConfig(level=logging.DEBUG)
      tenjin.logger = logging
      tenjin.Engine().render('index.pyhtml')  # report some messages

  * enerate_tostrfun() can take not only encode-encoding but also
    decode-encoding. These are exclusive.

    ex:
      ## convert unicode object into binary(=str)
      to_str = tenjin.generate_tostrfunc(encode='utf-8')
      ## convert binary(=str) into unicode object
      to_str = tenjin.generate_tostrfunc(decode='utf-8')

  * (Experimental) HTML helper functions are now provided.
    ex:

      >>> import tenjin
      >>> from tenjin.helpers.html import *
      >>> checked(1==1)
      ' checked="checked"'
      >>> checked(1==0)
      ''
      >>> selected(1==1)
      ' selected="selected"'
      >>> tagattr(klass='error', style='color:red')
      'class="error" style="color:red"'
      >>> tagattr(width='', height=0)
      ''
      >>> nv('rank', 'A')      # name and value
      'name="rank" value="A"'
      >>> nv('rank', 'A', '.', klass='opt')
      'name="rank" value="A" id="rank.A" class="opt"'

  * New command-line option '-a cache' supported.
    This option enables you to generate template cache files in advance.

  * You can share caches between all engine objects.
    PyTenjin now uses full-path of template file as key of cache.
    So you can share caches between engines which have different
    search path.
    ex:

      shared = tenjin.MarshalCacheStorage()
      engine1 = tenjin.Engine(path=['views/books', 'views'], cache=shared)
      engine2 = tenjin.Engine(path=['views/authors', 'views'], cache=shared)

  * Pickle-base and text-base template caching support.
    If you pass 'cache=tenjin.PickleCacheStorage()' or
    'cache=tenjin.TextCacheStorage()' option to template.Engine(),
    pyTenjin creates pickle-base or text-base cache files instead of
    marshal-base caches.
    These are useful in environment in which marshal module is
    not available, such as Google AppEngine.

* [Changes]

  * 'cache' option for tenjin.Engine() changed.
    (0.6.2)
      cache=True  :  cached both in memory and file (marshal-based)
      cache=None  :  same as cache=True
      cache=False :  cached in meory but not in file
    (0.7.0)
      cache=True  :  cached both in memory and file (marshal-based)
      cache=None  :  cached in meory but not in file
      cache=False :  never cached both in memory nor file

  * to_str() is changed to encode unicode object into binary(=str)
    using utf-8 encoding in default.
    In short:

      to_str = generate_tostrfunc(encode='utf-8')   # 0.7.0
      to_str = generate_tostrfunc(encode=None)      # 0.6.2

  * Benchmark script now skips to do benchmark template libraries
    which are failed to import.

* [BugFix]

  * In preprocessing, error was raised when expression is not string.
    Now fixed.


Release 0.6.2 (2008-02-27)
--------------------------

* [Changes]

  * Package name is changed from 'pyTenjin' to 'Tenjin'

  * When '-S', '-a retrieve', '-X', or '-a statements' specified,
    pytenjin command replaces text before expressions into spaces
    and print it.

* [Bugfix]

  * pytenjin command printed "\n\n" instead of "\n" when '-U' specified.
    Fixed to print "\n".


Release 0.6.1 (2007-10-23)
--------------------------

* [Enhancements]

  * Benchmark script (benchmark/bench.py) is rewrited.

  * Benchmark supports Genshi, Mako, and Templetor.

  * Add examples.

* [Bugfix]

  * Typo in User's Guide is fixed.


Release 0.6.0 (2007-08-04)
--------------------------

* first release
