changeset 605:bc5faca93699

Text templates now default to rendering as plain text; it is no longer necessary to explicitly specify the "text" method to the `render()` or `serialize()` method of the generated markup stream. See tickets #62 and #118.
author cmlenz
date Mon, 27 Aug 2007 19:04:20 +0000
parents 6d1fa718794f
children 9ada030ad986
files ChangeLog doc/templates.txt genshi/core.py genshi/filters/transform.py genshi/path.py genshi/template/base.py genshi/template/markup.py genshi/template/tests/directives.py genshi/template/tests/text.py genshi/template/text.py
diffstat 10 files changed, 41 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,9 @@
    which can speed up match templates in many cases, for example when a match
    template should only be applied once to a stream, or when it should not be
    applied recursively.
+ * Text templates now default to rendering as plain text; it is no longer
+   necessary to explicitly specify the "text" method to the `render()` or
+   `serialize()` method of the generated markup stream.
 
 
 Version 0.4.4
--- a/doc/templates.txt
+++ b/doc/templates.txt
@@ -129,7 +129,7 @@
   >>> from genshi.template import TextTemplate
   >>> tmpl = TextTemplate('Hello, $name!')
   >>> stream = tmpl.generate(name='world')
-  >>> print stream.render('text')
+  >>> print stream
   Hello, world!
 
 .. note:: If you want to use text templates, you should consider using the
--- a/genshi/core.py
+++ b/genshi/core.py
@@ -51,7 +51,7 @@
     returns the complete generated text at once. Both accept various parameters
     that impact the way the stream is serialized.
     """
-    __slots__ = ['events']
+    __slots__ = ['events', 'serializer']
 
     START = StreamEventKind('START') #: a start tag
     END = StreamEventKind('END') #: an end tag
@@ -65,12 +65,17 @@
     PI = StreamEventKind('PI') #: processing instruction
     COMMENT = StreamEventKind('COMMENT') #: comment
 
-    def __init__(self, events):
+    def __init__(self, events, serializer=None):
         """Initialize the stream with a sequence of markup events.
         
         :param events: a sequence or iterable providing the events
+        :param serializer: the default serialization method to use for this
+                           stream
+
+        :note: Changed in 0.5: added the `serializer` argument
         """
         self.events = events #: The underlying iterable producing the events
+        self.serializer = serializer #: The default serializion method
 
     def __iter__(self):
         return iter(self.events)
@@ -119,7 +124,7 @@
         :return: the filtered stream
         :rtype: `Stream`
         """
-        return Stream(_ensure(function(self)))
+        return Stream(_ensure(function(self)), serializer=self.serializer)
 
     def filter(self, *filters):
         """Apply filters to the stream.
@@ -143,7 +148,7 @@
         """
         return reduce(operator.or_, (self,) + filters)
 
-    def render(self, method='xml', encoding='utf-8', **kwargs):
+    def render(self, method=None, encoding='utf-8', **kwargs):
         """Return a string representation of the stream.
         
         Any additional keyword arguments are passed to the serializer, and thus
@@ -151,7 +156,8 @@
         
         :param method: determines how the stream is serialized; can be either
                        "xml", "xhtml", "html", "text", or a custom serializer
-                       class
+                       class; if `None`, the default serialization method of
+                       the stream is used
         :param encoding: how the output string should be encoded; if set to
                          `None`, this method returns a `unicode` object
         :return: a `str` or `unicode` object
@@ -159,6 +165,8 @@
         :see: XMLSerializer, XHTMLSerializer, HTMLSerializer, TextSerializer
         """
         from genshi.output import encode
+        if method is None:
+            method = self.serializer or 'xml'
         generator = self.serialize(method=method, **kwargs)
         return encode(generator, method=method, encoding=encoding)
 
@@ -211,13 +219,16 @@
         
         :param method: determines how the stream is serialized; can be either
                        "xml", "xhtml", "html", "text", or a custom serializer
-                       class
+                       class; if `None`, the default serialization method of
+                       the stream is used
         :return: an iterator over the serialization results (`Markup` or
                  `unicode` objects, depending on the serialization method)
         :rtype: ``iterator``
         :see: XMLSerializer, XHTMLSerializer, HTMLSerializer, TextSerializer
         """
         from genshi.output import get_serializer
+        if method is None:
+            method = self.serializer or 'xml'
         return get_serializer(method, **kwargs)(_ensure(self))
 
     def __str__(self):
--- a/genshi/filters/transform.py
+++ b/genshi/filters/transform.py
@@ -160,7 +160,8 @@
         transforms = self._mark(stream)
         for link in self.transforms:
             transforms = link(transforms)
-        return Stream(self._unmark(transforms))
+        return Stream(self._unmark(transforms),
+                      serializer=getattr(stream, 'serializer', None))
 
     def apply(self, function):
         """Apply a transformation to the stream.
--- a/genshi/path.py
+++ b/genshi/path.py
@@ -147,7 +147,8 @@
                                  updateonly=True)
                 elif result:
                     yield result
-        return Stream(_generate())
+        return Stream(_generate(),
+                      serializer=getattr(stream, 'serializer', None))
 
     def test(self, ignore_context=False):
         """Returns a function that can be used to track whether the path matches
--- a/genshi/template/base.py
+++ b/genshi/template/base.py
@@ -289,6 +289,8 @@
     directives should be applied.
     """
 
+    serializer = None
+
     def __init__(self, source, basedir=None, filename=None, loader=None,
                  encoding=None, lookup='lenient', allow_exec=True):
         """Initialize a template from either a string, a file-like object, or
@@ -423,7 +425,7 @@
         stream = self.stream
         for filter_ in self.filters:
             stream = filter_(iter(stream), ctxt)
-        return Stream(stream)
+        return Stream(stream, self.serializer)
 
     def _eval(self, stream, ctxt):
         """Internal stream filter that evaluates any expressions in `START` and
--- a/genshi/template/markup.py
+++ b/genshi/template/markup.py
@@ -64,6 +64,7 @@
                   ('content', ContentDirective),
                   ('attrs', AttrsDirective),
                   ('strip', StripDirective)]
+    serializer = 'xml'
 
     def __init__(self, source, basedir=None, filename=None, loader=None,
                  encoding=None, lookup='lenient', allow_exec=True):
--- a/genshi/template/tests/directives.py
+++ b/genshi/template/tests/directives.py
@@ -382,6 +382,7 @@
         """)
         self.assertEqual("""
                       Hi, you!
+
         """, str(tmpl.generate()))
 
     def test_function_with_star_args(self):
--- a/genshi/template/tests/text.py
+++ b/genshi/template/tests/text.py
@@ -70,7 +70,7 @@
           * 0
           * 1
           * 2
-""", tmpl.generate(items=range(3)).render('text'))
+""", tmpl.generate(items=range(3)).render())
 
     def test_empty_lines2(self):
         tmpl = OldTextTemplate("""Your items:
@@ -87,7 +87,7 @@
 
           * 2
 
-""", tmpl.generate(items=range(3)).render('text'))
+""", tmpl.generate(items=range(3)).render())
 
     def test_include(self):
         file1 = open(os.path.join(self.dirname, 'tmpl1.txt'), 'w')
@@ -161,7 +161,7 @@
   * 0
   * 1
   * 2
-""", tmpl.generate(items=range(3)).render('text'))
+""", tmpl.generate(items=range(3)).render())
 
     def test_empty_lines2(self):
         tmpl = NewTextTemplate("""Your items:
@@ -178,12 +178,12 @@
 
   * 2
 
-""", tmpl.generate(items=range(3)).render('text'))
+""", tmpl.generate(items=range(3)).render())
 
     def test_include(self):
         file1 = open(os.path.join(self.dirname, 'tmpl1.txt'), 'w')
         try:
-            file1.write("Included\n")
+            file1.write("Included")
         finally:
             file1.close()
 
--- a/genshi/template/text.py
+++ b/genshi/template/text.py
@@ -58,7 +58,7 @@
     ...  * ${'Item %d' % item}
     ... {% end %}
     ... ''')
-    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render('text')
+    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render()
     Dear Joe,
     <BLANKLINE>
     <BLANKLINE>
@@ -83,7 +83,7 @@
     ...  * $item
     ... {% end %}\
     ... ''')
-    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render('text')
+    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render()
     Dear Joe,
     <BLANKLINE>
     We have the following items for you:
@@ -103,7 +103,7 @@
     ...  * $item
     ... {% end %}\
     ... ''')
-    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render('text')
+    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render()
     Dear Joe,
     <BLANKLINE>
     {# This is a comment #}
@@ -122,6 +122,7 @@
                   ('if', IfDirective),
                   ('choose', ChooseDirective),
                   ('with', WithDirective)]
+    serializer = 'text'
 
     _DIRECTIVE_RE = r'((?<!\\)%s\s*(\w+)\s*(.*?)\s*%s|(?<!\\)%s.*?%s)'
     _ESCAPE_RE = r'\\\n|\\(\\)|\\(%s)|\\(%s)'
@@ -227,7 +228,7 @@
     ... 
     ... All the best,
     ... Foobar''')
-    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render('text')
+    >>> print tmpl.generate(name='Joe', items=[1, 2, 3]).render()
     Dear Joe,
     <BLANKLINE>
     We have the following items for you:
@@ -245,6 +246,7 @@
                   ('if', IfDirective),
                   ('choose', ChooseDirective),
                   ('with', WithDirective)]
+    serializer = 'text'
 
     _DIRECTIVE_RE = re.compile(r'(?:^[ \t]*(?<!\\)#(end).*\n?)|'
                                r'(?:^[ \t]*(?<!\\)#((?:\w+|#).*)\n?)',
Copyright (C) 2012-2017 Edgewall Software