SimpleTAL-4.1/0000755000175000017500000000000010364737165011762 5ustar cms103cms103SimpleTAL-4.1/Changes.txt0000644000175000017500000002526610354332656014101 0ustar cms103cms103simpleTAL / simpleTALES (Version 4.1) ------------------------------------- Version 4.1 ----------- New features: - Processing Instructions are now supported in HTML templates. Bug fixes: - The use of "&" in attributes was broken in 4.0 - fixed (thanks to Alain Spineux for the bug report). Version 4.0 ------------ This version of SimpleTAL is not 100% backwards compatible with the 3.x series of releases. Version 4.0 of SimpleTAL requires Python 2.2 or higher. New features: - Added support for minimizing boolean attributes in HTML (minimizeBooleanAtts = 1). - Switched HTML parser library from SGMLParser to HTMLParser. HTMLParser is generally less strict than the SGMLParser, however it doesn't handle unbalanced quotes around attributes (thanks to Carlos Neves for the initial patch). - Python 2.2 or higher supported. - All METAL namespace attributes are automatically omitted, not just those in XML templates. Version 3.13 ------------ New features: - Added support for compiling a template from a DOM tree (thanks to Benjamin Niemann for the patch). - Added support for iterators in the Context (thanks to Kevin Smith for the ideas). Bug fixes: - ElementTree paths can now be used from 'python: path ()' expressions (thanks to Jochen Kupperschmidt for the fix). Version 3.12 ------------ New features: - Integration with ElementTree. - Use Python 2.2's unicode function if available (honours the __unicode__ method) when converting non-unicode variables in the Context. Bug fixes: - Allow sub-classes of string and Unicode strings to be placed in the Context. Version 3.11 ------------ This release changes how HTML templates containing entity references and character references are handled. In previous releases any references contained in the HTML would be passed through to the output intact. In order to solve the double escaping bug described below all character references are now expanded in the output with the exception of <, > and & Bug fixes: - If multiple variable substitutions are used in a single 'string:' path and one failed the whole path would evaluate to an empty string. - When was used was output. - The global variable 'attrs' should be a dictionary, not a list (Thanks to Christoph Zwerschke for the bug report). - Content accessed through attrs would be double escaped. Version 3.10 ------------ New features: - Included API documentation and TAL reference guide with archive. Bug fixes: - Attributes on repeat tags were not correctly kept for nested repeats. (Thanks to Aadish Shrestha for the bug report) Version 3.9 ----------- This is release is focused on improving performance. Compared to version 3.8 the performance of expanding templates is ~45-70% faster. The performance of parsing templates is unchanged. WARNING: IF you rely on the internal workings of SimpleTALES in your application then there will be changes that are required to make use of this version of SimpleTAL. The API for SimpleTAL is however unchanged. New features: - Introduced simpleTALUtils.FastStringOutput which can be used to capture the output of SimpleTAL in a faster manner than StringIO. - Introduced simpleTALES.CachedFuncResult which can be used to wrap functions in the Context, and which cache's the result of the function call to ensure that the function is only called once during template expansion. - TALES no longer wraps all results in ContextVariable instances when returning values to TAL. - Changed copy.copy to {}.copy for performance improvement. - Removed logging.debug() calls from performance critical paths. - Replaced DefaultVariable class with simpleTALES.DEFAULTVALUE - Replaced NothingVariable class with None - Removed NoCallVariable - Removed isDefault, isNothing, isSequence, isCallable, and isTrue from ContextVariable. Version 3.8 ----------- New features: - Added new method getXMLTemplate to simpleTALUtils.TemplateCache - Comments in XML templates are now included in the output if pyxml is installed. - Lists can now be indexed into. Bug fixes: - TAL commands on METAL namespaced elements and vice-versa now work correctly (thanks to Kevin Smith for the bug report). Version 3.7 ----------- New features: - When non-ascii, non-Unicode strings are present in the Context a Unicode error is thrown. Now an ERROR log message indicates that this is the most likely cause of the problem. Bug fixes: - Correction to cgi-example (thanks to Frank Wierzbicki for the patch). - Local defines that reference earlier local defines on one tag now work. - Using default values in a repeat list now work as expected. - Errors during codec conversions will now use 'replace' rather than 'strict' Version 3.6 ----------- New features: - The XML Declaration can now be suppressed by passing suppressXMLDeclaration=1 to the template "expand" method. Bug fixes: - Removed stray 'info' logging call. Version 3.5 ----------- New features: - The 'test' function is now available to code used in 'python:' paths. Usage is the same as zope: test (test1,val1[,test2,val2][,default]). (Thanks to Mark McEahern for the feature request) - Uses PyXML (http://pyxml.sourceforge.net/) to determine the DOCTYPE of XML templates (if installed). (Thanks to Myers Carpenter for the implementation) Bug fixes: - CGI Example fixes. - XML Templates containing attributes with character entities are now output correctly. - HTML Templates with special characters as part of TAL or METAL commands are now handled correctly. - Default encoding is now iso-8859-1 rather than iso8859-1 Version 3.4 ----------- New features: - TemplateCache now uses MTIME rather than CTIME to spot changes to templates. - SimpleTAL is now compatible with PyXML 0.8.2 (Thanks to Myers Carpenter for the testing). - Added support for passing in an XML Doctype when calling template.expand - Added support to maintain XML singleton tags, including use of METAL and TAL on singleton tags. - Added support for using variables in paths (e.g. If colour='blue' then the path 'colourMap/?colour' is equivalent to 'colourMap/blue'). This is not part of the TALES specification, but is supported by Zope. (Thanks to Bastian Kleineidam for the initial implementation). Bug fixes: - If the logging module was not installed exceptions would be thrown when SimpleTAL attempted to log errors - fixed. Version 3.3 ----------- New features: - TemplateCache now supports inputEncoding, allowing HTML templates using character sets other than ISO8859-1 to be used. - Functions path, string, exists, and nocall are available to python: paths. - Functions can now receive parameters via paths by wrapping them in simpleTALES.PathFunctionVariable before placing them into the Context. Bug fixes: - In tal:attributes and tal:define double escaped semi-colons are now handled. - Space after a semi-colon in tal:attributes and tal:define is now handled (thanks to Sean Reifschneider) - Handling of stray quotes at the start and end of attributes shouldn't interfere with python: paths anymore. Version 3.2 ----------- This release incorporates patches from Wichert Akkerman implementing the Python TAL path and moving to string methods instead of using the string module. New features: - The 'python:' path can now be used, pass the parameter 'allowPythonPath=1' to the constructor of SimpleTALES.Context to enable this to be used. - simpleTALUtils now contains a template caching class (TemplateCache) that can be used to cache compiled templates, automatically invalidating the cache if the template file has changed. - The string module is no longer used, replaced by string methods Bug fixes: - Nested repeat variables with the same name are now scoped correctly. - If logging is available all error messages are now suppressed during testing. Version 3.1 ----------- With this release import statements need to be changed. Please now use: from simpletal import simpleTAL, simpleTALES. The API has not changed. New features: - SimpleTAL can now be installed using distutils, thanks to Michael Twomey. Bug fixes: - If tal:repeat and tal:content were used on the same element, the last piece of content would be present twice - fixed. - If a path element inside a string: path evaluated to something other than a string or unicode string, it would not be evaluated. Now an attempt to coerce the value to a string is done using the str function. Version 3.0 ----------- New features: - METAL Support added - The TAL and METAL name-spaces can now be bound to any prefix - When using XML Templates any elements in the TAL or METAL name-space have their start and end tags suppressed. Version 2.3 ----------- Bug fixes: - Using tal:repeat on empty lists would cause an exception to be thrown. Now the repeating elements are removed from the output. Version 2.2 ----------- Bug fixes: - HTML Document type declarations were not being passed through from the template - HTML Comments are now passed through to the output - End tags with no start tag now raise an error rather than failing silently - The first text element in a template is now combined with other text elements - XML Processing Instructions are now passed through the template correctly. Version 2.1 ----------- Bug fixes: - HTML Templates will now suppress the output of close tags for elements that are forbidden to have them in HTML 4.01. Additionally tags that can have no close tag in HTML can still have TAL attributes. This means that HTML templates can still be valid HTML, and produce valid HTML. For example: '' is now valid, and will only output the tag. New features: - A simplification of how local variables are handled brings a 5-10% performance gain Version 2.0 ----------- Complete refactoring of simpleTAL leading to very significant performance improvements. Bug fixes: - Any unknown entity references present in a HTML template were not passed through to the rendered template, now they are. - Attributes created using tal:attributes did not have their values escaped properly New features: - Large performance improvements by splitting the process into two - Templates once compiled can now be re-used, leading to large performance gains Version 1.1 ----------- Bug fixes: - The "structure" keyword when used in XML templates would fail with an exception. New features: - Added test cases for TALES and TAL (both HTML and XML) - Added allowTALInStructure flag to control expansion of TAL attributes Version 1.0 ----------- Initial release. SimpleTAL-4.1/PKG-INFO0000644000175000017500000000056610364737165013066 0ustar cms103cms103Metadata-Version: 1.0 Name: SimpleTAL Version: 4.1 Summary: SimpleTAL is a stand alone Python implementation of the TAL, TALES and METAL specifications used in Zope to power HTML and XML templates. Home-page: http://www.owlfish.com/software/simpleTAL/index.html Author: Colin Stewart Author-email: colin@owlfish.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN SimpleTAL-4.1/tests/0000755000175000017500000000000010364737163013122 5ustar cms103cms103SimpleTAL-4.1/tests/METALTests/0000755000175000017500000000000010364737163015007 5ustar cms103cms103SimpleTAL-4.1/tests/METALTests/XMLTests/0000755000175000017500000000000010364737164016473 5ustar cms103cms103SimpleTAL-4.1/tests/METALTests/XMLTests/METALNameSpaceTests.py0000644000175000017500000001105510347331422022475 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class METALNameSpaceTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, macros, page, result, errMsg="Error"): macroTemplate = simpleTAL.compileXMLTemplate (macros) #print "Macro template: " + str (macroTemplate) pageTemplate = simpleTAL.compileXMLTemplate (page) self.context.addGlobal ("site", macroTemplate) self.context.addGlobal ("here", pageTemplate) file = StringIO.StringIO () pageTemplate.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in macro: %s \npage: %s\ngot back %s \nexpected %s\n" % (errMsg, macros, page, realResult, result)) # Test that rebinding the namespaces works def testSingleBindNoCommands (self): self._runTest_ ('
Before blue After
' ,'Nowt white here' ,'\nNowt white here' ,"Single Bind, commands, failed.") def testSingleBindCommands (self): self._runTest_ ('
Before blue After
' ,'Nowt white here' ,'\n
Before white After
' ,"Single Bind, commands, failed.") # Test to ensure that using elements in the metal namespace omits tags def testMETALEmlement (self): self._runTest_ ('Before blue After' ,'Nowt white here' ,'\nBefore white After' ,"METAL namespace does not cause implicit omit-tag") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/METALTests/XMLTests/DefineMacroTests.py0000644000175000017500000001371210275160610022233 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES try: # Is PyXML's LexicalHandler available? from xml.sax.saxlib import LexicalHandler use_lexical_handler = 1 except ImportError: use_lexical_handler = 0 if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() pageTemplate = simpleTAL.compileXMLTemplate ("""

Expansion of macro one


""") class DefineMacroTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('needsQuoting', """Does "this" work?""") def _runTest_ (self, txt, result, errMsg="Error"): macroTemplate = simpleTAL.compileXMLTemplate (txt) self.context.addGlobal ("site", macroTemplate) file = StringIO.StringIO () pageTemplate.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, pageTemplate)) def _runCompileTest_ (self, txt, result, errMsg="Error"): try: macroTemplate = simpleTAL.compileXMLTemplate (txt) except simpleTAL.TemplateParseException, e: self.failUnless (str (e) == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, str(e), result, pageTemplate)) return self.fail ("Expected exception '%s' during compile - but got no exception" % result) def testSingleMacroDefinition (self): if (use_lexical_handler): result = '\n\n
No slots here
\n
\n' else: result = '\n\n
No slots here
\n

\n' self._runTest_ ('
No slots here
' ,result ,"Single macro with no slots failed.") def testTwoMacroDefinition (self): if (use_lexical_handler): result = '\n\n
No slots here
\n
\n' else: result = '\n\n
No slots here
\n

\n' self._runTest_ ('A second macro
No slots here
' ,result ,"Two macros with no slots failed.") def testNestedMacroDefinition (self): if (use_lexical_handler): result = '\n\nA second macro\n
\n' else: result = '\n\nA second macro\n

\n' self._runTest_ ('
A second macroNo slots here
' ,result ,"Nested macro with no slots failed.") def testDuplicateMacroDefinition (self): self._runCompileTest_ ('
A second macroNo slots here
' ,'[] Macro name one is already defined!' ,"Duplicate macro failed to error.") def testMacroTALDefinition (self): if (use_lexical_handler): result = '\n\n

testing

\n
\n' else: result = '\n\n

testing

\n

\n' self._runTest_ ('

Wibble

' , result ,"TAL Command on a macro failed.") def testSingletonMacros (self): if (use_lexical_handler): result = '\n\n

Wibble

\n
\n' else: result = '\n\n

Wibble

\n

\n' self._runTest_ ('

Wibble

' ,result ,"Singleton inside slot failed.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/METALTests/XMLTests/DefineSlotsTests.py0000644000175000017500000001604710007245640022302 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class DefineSlotsTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('needsQuoting', """Does "this" & work?""") def _runTest_ (self, macros, page, result, errMsg="Error"): macroTemplate = simpleTAL.compileXMLTemplate (macros) #print "Macro template: " + str (macroTemplate) pageTemplate = simpleTAL.compileXMLTemplate (page) self.context.addGlobal ("site", macroTemplate) self.context.addGlobal ("here", pageTemplate) file = StringIO.StringIO () pageTemplate.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in macro: %s \npage: %s\ngot back %s \nexpected %s\n" % (errMsg, macros, page, realResult, result)) def _runCompileTest_ (self, txt, result, errMsg="Error"): try: macroTemplate = simpleTAL.compileXMLTemplate (txt) except simpleTAL.TemplateParseException, e: self.failUnless (str (e) == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, str(e), result, pageTemplate)) return self.fail ("Expected exception '%s' during compile - but got no exception" % result) def testSingleSlot (self): self._runTest_ ('
Before blue After
' ,'Nowt white here' ,'\n
Before white After
' ,"Single slot expansion failed.") def testDoubleSlot (self): self._runTest_ ('
Before blue After red
' ,'Nowt white here black' ,'\n
Before white After black
' ,"Double slot expansion failed.") def testDoubleOneDefaultSlot (self): self._runTest_ ('
Before blue After red
' ,'Nowt white here purple' ,'\n
Before white After red
' ,"Double slot with default, expansion failed.") def testDoubleMacroDefaultSlot (self): self._runTest_ ('

Internal macro, colour blue: blue

Before blue After Internal
' ,'Nowt white' ,'\n
Before white After

Internal macro, colour blue: blue

' ,"Nested macro with same slot name.") def testDoubleMacroDoubleFillSlot (self): self._runTest_ ('

Internal macro, colour blue: blue

Before blue After Internal

pink!

finally outer blue again: blue goes here
' ,'Nowt white' ,'\n
Before white After

Internal macro, colour blue:

pink!

finally outer blue again: white
' ,"Nested macro with same slot name and slot being used failed.") def testSingleSlotDefaultTAL (self): self._runTest_ ('
Before blue After
' ,'Nowt here' ,'\n
Before testing After
' ,"Slot defaulting that holds TAL failed.") def testSingleSlotPassedInTAL (self): self._runTest_ ('
Before blue After
' ,'Nowt boo here' ,'\n
Before Does "this" & work? After
' ,"Slot filled with TAL failed.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/METALTests/HTMLTests/0000755000175000017500000000000010364737164016577 5ustar cms103cms103SimpleTAL-4.1/tests/METALTests/HTMLTests/METALNameSpaceTests.py0000644000175000017500000001066110347331422022603 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class METALNameSpaceTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, macros, page, result, errMsg="Error"): macroTemplate = simpleTAL.compileHTMLTemplate (macros) #print "Macro template: " + str (macroTemplate) pageTemplate = simpleTAL.compileHTMLTemplate (page) self.context.addGlobal ("site", macroTemplate) self.context.addGlobal ("here", pageTemplate) file = StringIO.StringIO () pageTemplate.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in macro: %s \npage: %s\ngot back %s \nexpected %s\n" % (errMsg, macros, page, realResult, result)) # Test that rebinding the namespaces works def testSingleBindNoCommands (self): self._runTest_ ('
Before blue After
' ,'Nowt white here' ,'Nowt white here' ,"Single Bind, commands, failed.") def testSingleBindCommands (self): self._runTest_ ('
Before blue After
' ,'Nowt white here' ,'
Before white After
' ,"Single Bind, commands, failed.") # Test to ensure that using elements in the metal namespace omits tags def testMETALEmlement (self): self._runTest_ ('Before blue After' ,'Nowt white here' ,'Before white After' ,"METAL namespace does not cause implicit omit-tag") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/METALTests/HTMLTests/DefineMacroTests.py0000644000175000017500000001202410007245640022332 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() pageTemplate = simpleTAL.compileHTMLTemplate ("""

Expansion of macro one

""") class DefineMacroTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('needsQuoting', """Does "this" work?""") def _runTest_ (self, txt, result, errMsg="Error"): macroTemplate = simpleTAL.compileHTMLTemplate (txt) self.context.addGlobal ("site", macroTemplate) file = StringIO.StringIO () pageTemplate.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, pageTemplate)) def _runCompileTest_ (self, txt, result, errMsg="Error"): try: macroTemplate = simpleTAL.compileHTMLTemplate (txt) except simpleTAL.TemplateParseException, e: self.failUnless (str (e) == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, str(e), result, pageTemplate)) return self.fail ("Expected exception '%s' during compile - but got no exception" % result) def testSingleMacroDefinition (self): self._runTest_ ('
No slots here
' ,'\n
No slots here
\n' ,"Single macro with no slots failed.") def testTwoMacroDefinition (self): self._runTest_ ('A second macro
No slots here
' ,'\n
No slots here
\n' ,"Two macros with no slots failed.") def testNestedMacroDefinition (self): self._runTest_ ('
A second macroNo slots here
' ,'\nA second macro\n' ,"Nested macro with no slots failed.") def testDuplicateMacroDefinition (self): self._runCompileTest_ ('
A second macroNo slots here
' ,'[] Macro name one is already defined!' ,"Duplicate macro failed to error.") def testUnballancedMacroDefinition (self): self._runCompileTest_ ('
' ,'[
] TAL/METAL Elements must be balanced - found close tag html expecting div' ,"Unballanced macro tag failed to error.") def testForbiddenEndTagMacroDefinition (self): self._runTest_ ('' ,'\n\n' ,"Macro on a forbidden end tag did not work.") def testMacroTALDefinition (self): self._runTest_ ('

Wibble

' ,'\n

testing

\n' ,"TAL Command on a macro failed.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/METALTests/HTMLTests/DefineSlotsTests.py0000644000175000017500000001535710007245640022411 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class DefineSlotsTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('needsQuoting', """Does "this" & work?""") def _runTest_ (self, macros, page, result, errMsg="Error"): macroTemplate = simpleTAL.compileHTMLTemplate (macros) #print "Macro template: " + str (macroTemplate) pageTemplate = simpleTAL.compileHTMLTemplate (page) self.context.addGlobal ("site", macroTemplate) self.context.addGlobal ("here", pageTemplate) file = StringIO.StringIO () pageTemplate.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in macro: %s \npage: %s\ngot back %s \nexpected %s\n" % (errMsg, macros, page, realResult, result)) def _runCompileTest_ (self, txt, result, errMsg="Error"): try: macroTemplate = simpleTAL.compileHTMLTemplate (txt) except simpleTAL.TemplateParseException, e: self.failUnless (str (e) == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, str(e), result, pageTemplate)) return self.fail ("Expected exception '%s' during compile - but got no exception" % result) def testSingleSlot (self): self._runTest_ ('
Before blue After
' ,'Nowt white here' ,'
Before white After
' ,"Single slot expansion failed.") def testDoubleSlot (self): self._runTest_ ('
Before blue After red
' ,'Nowt white here black' ,'
Before white After black
' ,"Double slot expansion failed.") def testDoubleOneDefaultSlot (self): self._runTest_ ('
Before blue After red
' ,'Nowt white here purple' ,'
Before white After red
' ,"Double slot with default, expansion failed.") def testDoubleMacroDefaultSlot (self): self._runTest_ ('

Internal macro, colour blue: blue

Before blue After Internal
' ,'Nowt white' ,'
Before white After

Internal macro, colour blue: blue

' ,"Nested macro with same slot name.") def testDoubleMacroDoubleFillSlot (self): self._runTest_ ('

Internal macro, colour blue: blue

Before blue After Internal

pink!

finally outer blue again: blue goes here
' ,'Nowt white' ,'
Before white After

Internal macro, colour blue:

pink!

finally outer blue again: white
' ,"Nested macro with same slot name and slot being used failed.") def testSingleSlotDefaultTAL (self): self._runTest_ ('
Before blue After
' ,'Nowt here' ,'
Before testing After
' ,"Slot defaulting that holds TAL failed.") def testSingleSlotPassedInTAL (self): self._runTest_ ('
Before blue After
' ,'Nowt boo here' ,'
Before Does "this" & work? After
' ,"Slot filled with TAL failed.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/0000755000175000017500000000000010364737163014565 5ustar cms103cms103SimpleTAL-4.1/tests/TALTests/XMLTests/0000755000175000017500000000000010364737165016252 5ustar cms103cms103SimpleTAL-4.1/tests/TALTests/XMLTests/CompileDOMTemplateTestCases.py0000644000175000017500000000630610275463722024070 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config import xml.dom from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() try: # Is PyXML's DOM2SAX available? import xml.dom.ext.Dom2Sax use_dom2sax = 1 except ImportError: use_dom2sax = 0 class CompileDOMTemplateTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': entry} self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('weblog', weblog) def _runTest_ (self, dom, result, errMsg="Error", allowTALInStructure=1): if (not use_dom2sax): return template = simpleTAL.compileDOMTemplate (dom) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, dom.toxml(), realResult, result, template)) def testContentNothing (self): domImpl = xml.dom.getDOMImplementation() doc = domImpl.createDocument ("", "html", None) h1 = doc.createElement ("h1") h1.setAttribute ("tal:content", "test") doc.firstChild.appendChild (h1) self._runTest_ (doc ,'\n

testing

' ,"DOM Template failed to compile.") SimpleTAL-4.1/tests/TALTests/XMLTests/TALNameSpaceTests.py0000644000175000017500000001535610016553112022034 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALNameSpaceTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def _runErrTest_ (self, txt, result, errMsg="Error"): try: template = simpleTAL.compileXMLTemplate (txt) except simpleTAL.TemplateParseException, e: realResult = str (e) self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back exception %s \nexpected exception %s\n" % (errMsg, txt, realResult, result)) return self.fail ("No exception thrown!") # Test that rebinding the namespaces works def testSingleBindNoCommands (self): self._runTest_ ('Hello' ,'\nHello' ,'Binding of namespace failed.') def testSingleBind (self): self._runTest_ ('Hello' ,'\nHello' ,'Binding of namespace failed.') def testSingleNestedBind (self): self._runTest_ ('

Hello

default contentdefault content' ,'\n

Hello

default contenttesting' ,'Binding of namespace failed to nest correctly') def testDoubleNestedBind (self): self._runTest_ ('

Hello

default contentdefault
default content' ,'\n

Hello

default contenttesting
testing' ,'Binding of namespace failed to nest correctly with 2 nests') def testOtherNameSpaces (self): self._runTest_ ('Hello' ,'\nHello' ,'Namespaces removed!') # Test to ensure that using elements in the tal namespace omits tags def testTALEmlement (self): self._runTest_ ('Hello' ,'\ntesting' ,'TAL Element written out') def testTALEmlementAttNameSpaced (self): self._runTest_ ('Hello' ,'\ntesting' ,'TAL Element failed when namespace specified for attribute') def testTALEmlementWithOmitTag (self): self._runTest_ ('Hello' ,'\ntesting' ,'TAL Element written out when omit tag specified') def testTALEmlementWithDefaultNS (self): self._runTest_ ('Hello' ,'\ntesting' ,'TAL Element written!') def testMetalBlockWithRepeat (self): self._runTest_ ('Some value here' ,'\nSome one hereSome two here' ,"Repeat on Metal:Block failed.") # Now test exceptions def testDefaultTALNameSpace (self): self._runErrTest_ ('Hello' ,'[] Can not use TAL name space by default, a prefix must be provided.' ,'Namespaces removed!') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALConditionTestCases.py0000644000175000017500000000647710007245640022732 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALConditionTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testConditionDefault (self): self._runTest_ ('Hello', '\nHello', "Condition 'default' did not evaluate to true") def testConditionExists (self): self._runTest_ ('Hello' , '\nHello', 'Condition for something that exists evaluated false') def testConditionNothing (self): self._runTest_ ('Hello' , '\n', 'Condition nothing evaluated to true') def testConditionMissing (self): self._runTest_ ('Hello' , '\n', 'Condition for something that does not exist evaluated to true') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALSingletonTests.py0000644000175000017500000002243110007245640022136 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config import xml.sax, xml.sax.handler, md5 from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class XMLChecksumHandler (xml.sax.handler.ContentHandler, xml.sax.handler.DTDHandler, xml.sax.handler.ErrorHandler): def __init__ (self, parser): xml.sax.handler.ContentHandler.__init__ (self) self.ourParser = parser def startDocument (self): self.digest = md5.new() def startPrefixMapping (self, prefix, uri): self.digest.update (prefix) self.digest.update (uri) def endPrefixMapping (self, prefix): self.digest.update (prefix) def startElement (self, name, atts): self.digest.update (name) allAtts = atts.getNames() allAtts.sort() for att in allAtts: self.digest.update (att) self.digest.update (atts [att]) def endElement (self, name): self.digest.update (name) def characters (self, data): self.digest.update (data) def processingInstruction (self, target, data): self.digest.update (target) self.digest.update (data) def skippedEntity (self, name): self.digest.update (name) # DTD Handler def notationDecl(self, name, publicId, systemId): self.digest.update (name) self.digest.update (publicId) self.digest.update (systemId) def unparsedEntityDecl(name, publicId, systemId, ndata): self.digest.update (name) self.digest.update (publicId) self.digest.update (systemId) self.digest.update (ndata) def error (self, excpt): print "Error: %s" % str (excpt) def warning (self, excpt): print "Warning: %s" % str (excpt) def getDigest (self): return self.digest.hexdigest() CHECKSUMPARSER = xml.sax.make_parser() CHECKSUMHANDLER = XMLChecksumHandler(CHECKSUMPARSER) CHECKSUMPARSER.setContentHandler (CHECKSUMHANDLER) CHECKSUMPARSER.setDTDHandler (CHECKSUMHANDLER) CHECKSUMPARSER.setErrorHandler (CHECKSUMHANDLER) def getXMLChecksum (doc): CHECKSUMPARSER.parse (StringIO.StringIO (doc)) return CHECKSUMHANDLER.getDigest() class TALSingletonTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', ['1',"Two",'3']) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() try: expectedChecksum = getXMLChecksum (result) except Exception, e: self.fail ("Exception (%s) thrown parsing XML expected result: %s" % (str (e), result)) try: realChecksum = getXMLChecksum (realResult) except Exception, e: self.fail ("Exception (%s) thrown parsing XML actual result: %s\nPage Template: %s" % (str (e), realResult, str (template))) self.failUnless (expectedChecksum == realChecksum, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def _runMacroTest_ (self, macros, page, result, errMsg="Error"): macroTemplate = simpleTAL.compileXMLTemplate (macros) pageTemplate = simpleTAL.compileXMLTemplate (page) self.context.addGlobal ("site", macroTemplate) self.context.addGlobal ("here", pageTemplate) file = StringIO.StringIO () pageTemplate.expand (self.context, file) realResult = file.getvalue() try: expectedChecksum = getXMLChecksum (result) except Exception, e: self.fail ("Exception (%s) thrown parsing XML expected result: %s" % (str (e), result)) try: realChecksum = getXMLChecksum (realResult) except Exception, e: self.fail ("Exception (%s) thrown parsing XML actual result: %s\nPage Template: %s\nMacro Template: %s" % (str (e), realResult, str (pageTemplate), str (macroTemplate))) self.failUnless (expectedChecksum == realChecksum, "%s - \npassed in macro: %s \n and page: %s\ngot back %s \nexpected %s\n\nPage Template: %s" % (errMsg, macros,page, realResult, result, pageTemplate)) def testDefineAttributes (self): self._runTest_ ("""

""" ,"""

""" ,"""Local define followed by attributes and global test failed.""") def testConditionDefine (self): self._runTest_ ("""

""" ,"""

""" ,"""Global define and condition failed""") def testRepeatAttributes (self): self._runTest_ ("""
""" ,"""


""" ,"""Repeat and attributes failed.""") def testContentRepeat (self): self._runTest_ ("""
""" ,"""
1

Two

3
""" ,"""Content with Repeat failed.""") def testReplaceRepeat (self): self._runTest_ ("""
""" ,"""1Two3""" ,"""Replace with Repeat failed.""") def testReplaceRepeatAttributes (self): self._runTest_ ("""
""" ,"""1Two3""" ,"""Replace with Repeat failed.""") def testContentRepeatAttributes (self): self._runTest_ ("""
""" ,"""
1

Two

3
""" ,"""Content with Repeat and Attributes failed.""") def testOmitTagContentRepeatAttributes (self): self._runTest_ ("""
""" ,"""1Two3""" ,"""OmitTag with Content and Repeat and Attributes failed.""") def testDefineMacroSlots (self): self._runMacroTest_ ("""
""" ,"""

Hello

""" ,"""

Hello

""" ,"""METAL with define-slot on singleton failed.""") def testDefineMacro (self): self._runMacroTest_ ("""""" ,"""

Hello

""" ,"""""" ,"""METAL with define-macro on singleton failed.""") def testUseMacro (self): self._runMacroTest_ ("""
""" ,"""
""" ,"""
""" ,"""METAL with use-macro on singleton failed.""") def testFillSlot (self): self._runMacroTest_ ("""
""" ,"""
""" ,"""""" ,"""METAL with fill-slot on singleton failed.""") def testRepeatUseMacro (self): self._runMacroTest_ ("""
""" ,"""

""" ,"""




""" ,"""METAL with repeat and use-macro on singleton failed.""") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALAttributeTestCases.py0000644000175000017500000002005510101564371022733 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES import xml.sax, xml.sax.handler, md5 if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class XMLChecksumHandler (xml.sax.handler.ContentHandler, xml.sax.handler.DTDHandler, xml.sax.handler.ErrorHandler): def __init__ (self, parser): xml.sax.handler.ContentHandler.__init__ (self) self.ourParser = parser def startDocument (self): self.digest = md5.new() def startPrefixMapping (self, prefix, uri): self.digest.update (prefix) self.digest.update (uri) def endPrefixMapping (self, prefix): self.digest.update (prefix) def startElement (self, name, atts): self.digest.update (name) allAtts = atts.getNames() allAtts.sort() for att in allAtts: self.digest.update (att) self.digest.update (atts [att]) def endElement (self, name): self.digest.update (name) def characters (self, data): self.digest.update (data) def processingInstruction (self, target, data): self.digest.update (target) self.digest.update (data) def skippedEntity (self, name): self.digest.update (name) # DTD Handler def notationDecl(self, name, publicId, systemId): self.digest.update (name) self.digest.update (publicId) self.digest.update (systemId) def unparsedEntityDecl(name, publicId, systemId, ndata): self.digest.update (name) self.digest.update (publicId) self.digest.update (systemId) self.digest.update (ndata) def error (self, excpt): print "Error: %s" % str (excpt) def warning (self, excpt): print "Warning: %s" % str (excpt) def getDigest (self): return self.digest.hexdigest() CHECKSUMPARSER = xml.sax.make_parser() CHECKSUMHANDLER = XMLChecksumHandler(CHECKSUMPARSER) CHECKSUMPARSER.setContentHandler (CHECKSUMHANDLER) CHECKSUMPARSER.setDTDHandler (CHECKSUMHANDLER) CHECKSUMPARSER.setErrorHandler (CHECKSUMHANDLER) def getXMLChecksum (doc): CHECKSUMPARSER.parse (StringIO.StringIO (doc)) return CHECKSUMHANDLER.getDigest() class TALAttributesTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('needsQuoting', """Does "this" work?""") self.context.addGlobal ('number', '5') self.context.addGlobal ('uniQuote', u'Does "this" work?') def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() try: expectedChecksum = getXMLChecksum (result) except Exception, e: self.fail ("Exception (%s) thrown parsing XML expected result: %s" % (str (e), result)) try: realChecksum = getXMLChecksum (realResult) except Exception, e: self.fail ("Exception (%s) thrown parsing XML actual result: %s\nPage Template: %s" % (str (e), realResult, str (template))) self.failUnless (expectedChecksum == realChecksum, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testAddingAnAttribute (self): self._runTest_ ('Hello' ,'\nHello' ,"Addition of attribute 'link' failed.") def testRemovingAnAttribute (self): self._runTest_ ('Hello' ,'\nHello' ,"Removal of attribute 'href' failed.") def testDefaultAttribute (self): self._runTest_ ('Hello' ,'\nHello' ,"Defaulting of attribute 'href' failed.") def testMultipleAttributes (self): self._runTest_ ('Hello' ,'\nHello' ,"Setting multiple attributes at once failed.") def testMultipleAttributesSpace (self): self._runTest_ ('Hello' ,'\nHello' ,"Setting multiple attributes at once, with spaces between semi-colons, failed.") def testMultipleAttributesEscaped (self): self._runTest_ ('Hello' ,'\nHello' ,"Setting multiple attributes at once, with spaces between semi-colons, failed.") def testAttributeEscaping (self): self._runTest_ ('Hello' ,"""\nHello""" ,"Escaping of new attributes failed.") def testNumberAttributeEscaping (self): self._runTest_ ('Hello' ,"""\nHello""" ,"Escaping of new attributes failed.") def testNumberAttributeEscaping2 (self): self._runTest_ ('Hello' ,"""\nHello""" ,"Escaping of new attributes failed.") def testAttributeCase (self): self._runTest_ ('Hello' ,"""\nHello""" ,"Capitalised attributes not carried through template.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALDefineTestCases.py0000644000175000017500000001112510007245640022160 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALDefineTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testDefineString (self): self._runTest_ ('

', '\n

testing

', "Simple string define failed.") def testDefineList (self): self._runTest_ ('

Hello

' , '\n

Hello one

Hello two

', 'List define failed.') def testDefineGlobal (self): self._runTest_ ('

' , '\n

testing

', 'Global did not set globally') def testDefineLocal (self): self._runTest_ ('

' , '\n

', 'Explicit local available globaly') def testDefineImplicitLocal (self): self._runTest_ ('

' , '\n

', 'Implicit local available globaly') def testDefineMultipleLocal (self): self._runTest_ ('

Testing

' , '\n

testing

This is a semi;colon

Test

', 'Multiple defines failed.') def testDefineMultipleMixed (self): self._runTest_ ('

Testing

' , '\n

testing

This is a semi;colon

Test

This is a semi;colon', 'Multiple defines failed.') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALSpecialCharsTestCases.py0000644000175000017500000000720110364736707023346 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALSpecialCharsTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context(allowPythonPath=1) self.context.addGlobal ('test', '< testing > experimenting & twice as useful') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error", allowTALInStructure=1): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testLessThanGreaterThanAmpersand (self): self._runTest_ ('Hello' ,"""\n< testing > experimenting & twice as useful""" ,"Less than, greater than or amperand were not encoded correctly") def testEscapedPythonPaths (self): self._runTest_ ('Hello' ,"""\n4000""" ,"Python bit shift failed.") def testAmpInTemplate (self): self._runTest_ (""" Hello Bye Bye""" ,""" Hello Bye Bye""" ,"& in template failed.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALEncodingTestCases.py0000644000175000017500000001031710156141637022524 0ustar cms103cms103#!/usr/bin/python # -*- coding: iso-8859-1 -*- """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO, codecs import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() isoDecoder = codecs.lookup ("iso-8859-1")[1] class TALEncodingTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'Testing this and that') self.context.addGlobal ('HighBC', isoDecoder ('This cost nothing, yep £0!')[0]) self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testISOToUTF8 (self): utf8Pound = "\xc2\xa3" template = simpleTAL.compileXMLTemplate ('\n£3.12? ') file = StringIO.StringIO() template.expand (self.context, file, 'utf-8') result = file.getvalue() expectedResult = '\n' + utf8Pound + "3.12? This cost nothing, yep " + utf8Pound + "0!" self.failUnless (result == expectedResult, "UTF8 Encoding failed. \nResult was: " + result + "\nExpected result: " + expectedResult) def testISOToISO (self): template = simpleTAL.compileXMLTemplate ('\n£3.12? ') file = StringIO.StringIO() template.expand (self.context, file, 'iso-8859-1') result = file.getvalue() expectedResult = '\n£3.12? This cost nothing, yep £0!' self.failUnless (result == expectedResult, "ISO Encoding failed. \nResult was: " + result + "\nExpected result: " + expectedResult) def testUTF8ToISO (self): template = simpleTAL.compileXMLTemplate ('\n\xc2\xa33.12? ') file = StringIO.StringIO() template.expand (self.context, file, 'iso-8859-1') result = file.getvalue() expectedResult = '\n£3.12? This cost nothing, yep £0!' self.failUnless (result == expectedResult, "UTF8 -> ISO Encoding failed. \nResult was: " + result + "\nExpected result: " + expectedResult) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALReplaceTestCases.py0000644000175000017500000000772110007245640022350 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALReplaceTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': entry} self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('weblog', weblog) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testContentNothing (self): self._runTest_ ('

' ,'\n' ,'Content of nothing did not remove tag.') def testContentDefault (self): self._runTest_ ('

Original

' ,'\n

Original

' ,'Content of default did not evaluate to existing content without tags') def testContentString (self): self._runTest_ ('

Original

' ,'\ntesting' ,'Content of string did not evaluate to contain string') def testContentStructure (self): # This test has specific needs - i.e. wrap the weblog/entry in a template... entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': simpleTAL.compileXMLTemplate(entry)} self.context.addGlobal ('weblog', weblog) self._runTest_ ('

Original

' ,'\nSome structure: Test subject' ,'Content of Structure did not evaluate to expected result') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALForbiddenEndTagTestCases.py0000644000175000017500000001407610007245640023755 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALForbiddenEndTagTestCases (unittest.TestCase): """ Tests to prove that XML templates do not perform end tag suppression on HTML elements that have forbidden end tags in HTML 4.01. See equivalent HTML test cases for end tag suppression. """ def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('scrWidth', '640') def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testAreaElement (self): self._runTest_ ('' ,'\n' ,"HTML Element AREA did NOT produce end tag.") def testBaseElement (self): self._runTest_ ('' ,'\n' ,"HTML Element BASE did NOT produce end tag.") def testBaseFontElement (self): self._runTest_ ('' ,'\n' ,"HTML Element BASEFONT did NOT produce end tag.") def testBRElement (self): self._runTest_ ('

' ,'\n

' ,"HTML Element BR did NOT produce end tag.") def testColElement (self): self._runTest_ ('' ,'\n' ,"HTML Element COL did NOT produce end tag.") def testFrameElement (self): self._runTest_ ('' ,'\n' ,"HTML Element FRAME did NOT produce end tag.") def testHRElement (self): self._runTest_ ('
' ,'\n
' ,"HTML Element HR did NOT produce end tag.") def testImgElement (self): self._runTest_ ('' ,'\n' ,"HTML Element IMG did NOT produce end tag.") def testInputElement (self): self._runTest_ ('' ,'\n' ,"HTML Element INPUT did NOT produce end tag.") def testIsIndexElement (self): self._runTest_ ('' ,'\n' ,"HTML Element ISINDEX did NOT produce end tag.") def testLinkElement (self): self._runTest_ ('' ,'\n' ,"HTML Element LINK did NOT produce end tag.") def testMetaElement (self): self._runTest_ ('' ,'\n' ,"HTML Element META did NOT produce end tag.") def testParamElement (self): self._runTest_ ('' ,'\n' ,"HTML Element PARAM did NOT produce end tag.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALRepeatTestCases.py0000644000175000017500000003365510101573014022214 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALRepeatTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('bigList', range (1,100)) self.context.addGlobal ('fourList', ["zero", "one", "two", "three"]) self.context.addGlobal ('nested', [{'title': 'Image 1', 'catList': [1,2,3]} ,{'title': 'Image 2', 'catList': [5,2,3]} ,{'title': 'Image 3', 'catList': [8,9,1]} ]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testInvalidPath (self): self._runTest_ ('

Hello

' ,'\n' , "Repeat of non-existant element failed") def testDefaultValue (self): self._runTest_ ('

Default Only

' ,'\n

Default Only

' , 'Default did not keep existing structure intact') def testEmptyList (self): self._runTest_ ('

Empty

' ,'\n' ,'Empty list repeat failed.' ) def testStringRepeat (self): self._runTest_ ('

' ,'\ntesting' ,'Itteration over string failed.') def testListRepeat (self): self._runTest_ ('

' ,'\n

one

two

' ,'Itteration over list failed.') def testTwoCmndsOneTagListRepeat (self): self._runTest_ ('

' ,'\n

one

two

' ,'Itteration over list with both content and repeat on same element failed.') def testNestedRepeat (self): self._runTest_ ('

' ,'\n

Image 1

123

Image 2

523

Image 3

891

' ,'Nested repeat did not create expected outcome.' ) def testNestedRepeatClasses (self): self._runTest_ ('

' ,'\n

1
2
3

5
2
3

8
9
1

' ,'Nested repeat with classes did not create expected outcome.' ) def testRepeatVarIndex (self): expectedResult = "" for num in xrange (0,99): expectedResult += str (num) expectedResult += "" self._runTest_ ('

Index

' ,'\n' + expectedResult ,"Repeat variable index failed." ) def testRepeatVarNumber (self): self._runTest_ ('

Index

' ,'\n123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899' ,'Repeat variable number failed.' ) def testRepeatVarEvenOdd (self): self._runTest_ ('

- OddEven

' ,'\n

zero - Even

one - Odd

two - Even

three - Odd

' ,'Repeat variables odd and even failed.' ) def testRepeatVarStartEnd (self): self._runTest_ ('

StartEnd

' ,'\n

Startzero

one

two

threeEnd

' ,'Repeat variables start and end failed.' ) def testRepeatVarLength (self): self._runTest_ ('

Len: lengthEntry:

' ,'\n

Len: 4Entry: zero

Entry: one

Entry: two

Entry: three

' ,'Repeat variable length failed.' ) def testRepeatVarLowerLetter (self): self._runTest_ ('

a,b,c,etc:

' ,'\n

a: zero

b: one

c: two

d: three

' ,'Repeat variable letter failed.' ) def testRepeatVarLowerLetterLarge (self): self._runTest_ ('

a,b,c,etc:

' ,'\n

a: 1

b: 2

c: 3

d: 4

e: 5

f: 6

g: 7

h: 8

i: 9

j: 10

k: 11

l: 12

m: 13

n: 14

o: 15

p: 16

q: 17

r: 18

s: 19

t: 20

u: 21

v: 22

w: 23

x: 24

y: 25

z: 26

ba: 27

bb: 28

bc: 29

bd: 30

be: 31

bf: 32

bg: 33

bh: 34

bi: 35

bj: 36

bk: 37

bl: 38

bm: 39

bn: 40

bo: 41

bp: 42

bq: 43

br: 44

bs: 45

bt: 46

bu: 47

bv: 48

bw: 49

bx: 50

by: 51

bz: 52

ca: 53

cb: 54

cc: 55

cd: 56

ce: 57

cf: 58

cg: 59

ch: 60

ci: 61

cj: 62

ck: 63

cl: 64

cm: 65

cn: 66

co: 67

cp: 68

cq: 69

cr: 70

cs: 71

ct: 72

cu: 73

cv: 74

cw: 75

cx: 76

cy: 77

cz: 78

da: 79

db: 80

dc: 81

dd: 82

de: 83

df: 84

dg: 85

dh: 86

di: 87

dj: 88

dk: 89

dl: 90

dm: 91

dn: 92

do: 93

dp: 94

dq: 95

dr: 96

ds: 97

dt: 98

du: 99

' ,'Repeat variable letter failed on a large list.' ) def testRepeatVarUpperLetter (self): self._runTest_ ('

A,B,C,etc:

' ,'\n

A: zero

B: one

C: two

D: three

' ,'Repeat variable Letter failed.' ) def testRepeatVarLowerRoman (self): self._runTest_ ('

i,ii,iii,etc:

' ,'\n

i: 1

ii: 2

iii: 3

iv: 4

v: 5

vi: 6

vii: 7

viii: 8

ix: 9

x: 10

xi: 11

xii: 12

xiii: 13

xiv: 14

xv: 15

xvi: 16

xvii: 17

xviii: 18

xix: 19

xx: 20

xxi: 21

xxii: 22

xxiii: 23

xxiv: 24

xxv: 25

xxvi: 26

xxvii: 27

xxviii: 28

xxix: 29

xxx: 30

xxxi: 31

xxxii: 32

xxxiii: 33

xxxiv: 34

xxxv: 35

xxxvi: 36

xxxvii: 37

xxxviii: 38

xxxix: 39

xl: 40

xli: 41

xlii: 42

xliii: 43

xliv: 44

xlv: 45

xlvi: 46

xlvii: 47

xlviii: 48

xlix: 49

l: 50

li: 51

lii: 52

liii: 53

liv: 54

lv: 55

lvi: 56

lvii: 57

lviii: 58

lix: 59

lx: 60

lxi: 61

lxii: 62

lxiii: 63

lxiv: 64

lxv: 65

lxvi: 66

lxvii: 67

lxviii: 68

lxix: 69

lxx: 70

lxxi: 71

lxxii: 72

lxxiii: 73

lxxiv: 74

lxxv: 75

lxxvi: 76

lxxvii: 77

lxxviii: 78

lxxix: 79

lxxx: 80

lxxxi: 81

lxxxii: 82

lxxxiii: 83

lxxxiv: 84

lxxxv: 85

lxxxvi: 86

lxxxvii: 87

lxxxviii: 88

lxxxix: 89

xc: 90

xci: 91

xcii: 92

xciii: 93

xciv: 94

xcv: 95

xcvi: 96

xcvii: 97

xcviii: 98

xcix: 99

' ,'Repeat variable roman failed.' ) def testRepeatVarUpperRoman (self): self._runTest_ ('

I,II,III,etc:

' ,'\n

I: 1

II: 2

III: 3

IV: 4

V: 5

VI: 6

VII: 7

VIII: 8

IX: 9

X: 10

XI: 11

XII: 12

XIII: 13

XIV: 14

XV: 15

XVI: 16

XVII: 17

XVIII: 18

XIX: 19

XX: 20

XXI: 21

XXII: 22

XXIII: 23

XXIV: 24

XXV: 25

XXVI: 26

XXVII: 27

XXVIII: 28

XXIX: 29

XXX: 30

XXXI: 31

XXXII: 32

XXXIII: 33

XXXIV: 34

XXXV: 35

XXXVI: 36

XXXVII: 37

XXXVIII: 38

XXXIX: 39

XL: 40

XLI: 41

XLII: 42

XLIII: 43

XLIV: 44

XLV: 45

XLVI: 46

XLVII: 47

XLVIII: 48

XLIX: 49

L: 50

LI: 51

LII: 52

LIII: 53

LIV: 54

LV: 55

LVI: 56

LVII: 57

LVIII: 58

LIX: 59

LX: 60

LXI: 61

LXII: 62

LXIII: 63

LXIV: 64

LXV: 65

LXVI: 66

LXVII: 67

LXVIII: 68

LXIX: 69

LXX: 70

LXXI: 71

LXXII: 72

LXXIII: 73

LXXIV: 74

LXXV: 75

LXXVI: 76

LXXVII: 77

LXXVIII: 78

LXXIX: 79

LXXX: 80

LXXXI: 81

LXXXII: 82

LXXXIII: 83

LXXXIV: 84

LXXXV: 85

LXXXVI: 86

LXXXVII: 87

LXXXVIII: 88

LXXXIX: 89

XC: 90

XCI: 91

XCII: 92

XCIII: 93

XCIV: 94

XCV: 95

XCVI: 96

XCVII: 97

XCVIII: 98

XCIX: 99

' ,'Repeat variable Roman failed.' ) def testLocalVarScope (self): self._runTest_ ('

bold

VAR EXISTS' ,'\n

zero

one

two

three

' ,'Local repeat variable remained accessible out of scope!' ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALHandlerTestCases.py0000755000175000017500000002715210142751013022351 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config import xml.sax, xml.sax.handler, md5 try: # check to see if pyxml is installed from xml.sax.saxlib import LexicalHandler use_lexical_handler = 1 except ImportError: use_lexical_handler = 0 class LexicalHandler: pass from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class XMLChecksumHandler (xml.sax.handler.ContentHandler, xml.sax.handler.DTDHandler, xml.sax.handler.ErrorHandler, LexicalHandler): def __init__ (self, parser): xml.sax.handler.ContentHandler.__init__ (self) self.ourParser = parser def getDigest (self): return self.digest.hexdigest() def startDocument (self): self.digest = md5.new() def startPrefixMapping (self, prefix, uri): self.digest.update (prefix) self.digest.update (uri) def endPrefixMapping (self, prefix): self.digest.update (prefix) def startElement (self, name, atts): self.digest.update (name) allAtts = atts.getNames() allAtts.sort() for att in allAtts: self.digest.update (att) self.digest.update (atts [att]) def endElement (self, name): self.digest.update (name) def characters (self, data): self.digest.update (data) def processingInstruction (self, target, data): self.digest.update (target) self.digest.update (data) def comment (self, data): self.digest.update (data) def skippedEntity (self, name): self.digest.update (name) # DTD Handler def notationDecl(self, name, publicId, systemId): self.digest.update (name) self.digest.update (publicId) self.digest.update (systemId) def unparsedEntityDecl(name, publicId, systemId, ndata): self.digest.update (name) self.digest.update (publicId) self.digest.update (systemId) self.digest.update (ndata) def error (self, excpt): print "Error: %s" % str (excpt) def warning (self, excpt): print "Warning: %s" % str (excpt) def startDTD(self, name, publicId, systemId): self.digest.update (name) self.digest.update (publicId) self.digest.update (systemId) CHECKSUMPARSER = xml.sax.make_parser() CHECKSUMHANDLER = XMLChecksumHandler(CHECKSUMPARSER) CHECKSUMPARSER.setContentHandler (CHECKSUMHANDLER) CHECKSUMPARSER.setDTDHandler (CHECKSUMHANDLER) CHECKSUMPARSER.setErrorHandler (CHECKSUMHANDLER) try: CHECKSUMPARSER.setFeature (xml.sax.handler.feature_external_ges, 0) except: pass if use_lexical_handler: CHECKSUMPARSER.setProperty(xml.sax.handler.property_lexical_handler, CHECKSUMHANDLER) def getXMLChecksum (doc): CHECKSUMPARSER.parse (StringIO.StringIO (doc)) return CHECKSUMHANDLER.getDigest() class TALHandlerTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileXMLTemplate (txt) fh = StringIO.StringIO () template.expand (self.context, fh) realResult = fh.getvalue() expectedChecksum = getXMLChecksum (result) try: realChecksum = getXMLChecksum (realResult) except Exception, e: self.fail ("Exception (%s) thrown parsing XML actual result: %s\nPage Template: %s" % (str (e), realResult, str (template))) self.failUnless (expectedChecksum == realChecksum, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testSingleEmptyElement (self): self._runTest_ ("", '\n') def testSingleElement (self): self._runTest_ ("start", '\nstart') def testSingleElementSpaces (self): self._runTest_ ('


', '\n


') def testSingleElementNewLines (self): self._runTest_ ('

', '\n


') def testSingleElementEasyAttributes (self): self._runTest_ ('
', '\n
') def testSingleElementHardAttributes (self): self._runTest_ ("""


""", """\n


""") def testSingleElementHarderAttributes (self): self._runTest_ ("""
""" ,"""
""") def testCDATASection (self): self._runTest_ (" CDATA section stuff & things.]]>" ,"""\nHere's some <escaped> CDATA section stuff & things.""" ,"CDATA section was not re-encoded correctly.") def testNameSpaces (self): self._runTest_ ("""\nTesting""" ,"""\nTesting""" ,"""Namespaces not preserved.""") def testProcessingInstructions (self): self._runTest_ ("""\n

Somemarkup

""" ,"""\n

Somemarkup

""" ,"""Processing instructions not preserved.""") def testCommentHandling (self): if (not use_lexical_handler): return self._runTest_ ("""\n

Here

""" ,"""\n

Here

""" ,"Comments not preserved.") def testDocumentTypeDeclaration (self): txt = """\n\n

Test

""" template = simpleTAL.compileXMLTemplate (txt) fh = StringIO.StringIO () template.expand (self.context, fh, docType="""""") realResult = fh.getvalue() expectedResult = """\n\n

Test

""" self.failUnless (realResult == expectedResult, "Doctype failed - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (txt, realResult, expectedResult, str(template))) def testXMLDeclarationSuppressionWithDocType (self): txt = """\n\n

Test

""" template = simpleTAL.compileXMLTemplate (txt) fh = StringIO.StringIO () template.expand (self.context, fh, docType="""""", suppressXMLDeclaration=1) realResult = fh.getvalue() expectedResult = """\n

Test

""" self.failUnless (realResult == expectedResult, "Doctype failed - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (txt, realResult, expectedResult, str(template))) def testXMLDeclarationSuppressionWithNoDocType (self): txt = """\n

Test

""" template = simpleTAL.compileXMLTemplate (txt) fh = StringIO.StringIO () template.expand (self.context, fh, suppressXMLDeclaration=1) realResult = fh.getvalue() expectedResult = """

Test

""" self.failUnless (realResult == expectedResult, "Doctype failed - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (txt, realResult, expectedResult, str(template))) def testDTDPassthru (self): if not use_lexical_handler: return self._runTest_ ("""Hi""", """\n\nHi""") def testSampleXHTML11Doc (self): """ Cut and pasted right out of the xhtml 1.1 spec """ if not use_lexical_handler: return self._runTest_ ("""\ Virtual Library

Moved to vlib.org.

""","""\ Virtual Library

Moved to vlib.org.

""") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/XMLTests/TALContentTestCases.py0000644000175000017500000001064210007245640022403 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALContentTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': entry} self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('weblog', weblog) def _runTest_ (self, txt, result, errMsg="Error", allowTALInStructure=1): template = simpleTAL.compileXMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testContentNothing (self): self._runTest_ ('

' ,'\n

' ,'Content of nothing did not evaluate to empty tag.') def testContentDefault (self): self._runTest_ ('

Original

' ,'\n

Original

' ,'Content of default did not evaluate to existing content') def testContentString (self): self._runTest_ ('

Original

' ,'\n

testing

' ,'Content of string did not evaluate to contain string') def testContentStructure (self): # This test has specific needs - i.e. wrap the weblog/entry in a template... entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': simpleTAL.compileXMLTemplate(entry)} self.context.addGlobal ('weblog', weblog) self._runTest_ ('

Original

' ,'\n

Some structure: Test subject

' ,'Content of Structure did not evaluate to expected result') def testTALDisabledContentStructure (self): self._runTest_ ('

Original

' ,'\n

Some structure:

' ,'Content of Structure did not evaluate to expected result' ,allowTALInStructure=0) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/0000755000175000017500000000000010364737164016355 5ustar cms103cms103SimpleTAL-4.1/tests/TALTests/HTMLTests/TALMinimizeBooleanAttsTestCases.py0000644000175000017500000001337210347326342025023 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALOmitTagTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('bob', 'bob') self.context.addGlobal ('disabled', 'disabled') self.context.addGlobal ('notdisabled', 'notdisabled') def _runTest_ (self, txt, result, errMsg="Error", minimizeBooleanAtts = 1): template = simpleTAL.compileHTMLTemplate (txt, minimizeBooleanAtts = minimizeBooleanAtts) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testTemplateWithBooleanAtt (self): self._runTest_ ('Hello' ,'Hello' ,"Template minimized boolean att failed.") def testTemplateWithBooleanAttWithBooleanDisabled (self): self._runTest_ ('Hello' ,'Hello' ,"Template minimized boolean att failed to output full form with support disabled." , 0) def testTemplateWithFullAtt (self): self._runTest_ ('Hello' ,'Hello' ,"Template full att failed.") def testTemplateWithFullAttWithBooleanDisabled (self): self._runTest_ ('Hello' ,'Hello' ,"Template full boolean att failed to output full form with support disabled." , 0) def testTemplateWithBadBooleanAtt (self): self._runTest_ ('Hello' ,'Hello' ,"Template bad boolean att failed.") def testTALRemoveBooleanAtt (self): self._runTest_ ('Hello' ,'Hello' ,"TAL failed to remove minimized boolean tag") def testTALAddBooleanAtt (self): self._runTest_ ('Hello' ,'Hello' ,"TAL failed to add minimized boolean tag") def testTALBadBooleanAtt (self): self._runTest_ ('Hello' ,'Hello' ,"TAL failed to add with bad minimized boolean tag") def testTALNonBooleanAtt (self): self._runTest_ ('Hello' ,'Hello' ,"TAL failed to add non-boolean tag") def testTALBooleanAttSupportDisabled (self): self._runTest_ ('Hello' ,'Hello' ,"TAL failed to keep long form when support for minimized form disabled" ,0) def testTemplateAllBooleanAtts (self): self._runTest_ (""" """ ,""" """ ,"Template failed to handle every boolean option") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALNameSpaceTests.py0000644000175000017500000001176510007245640022144 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALNameSpaceTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def _runErrTest_ (self, txt, result, errMsg="Error"): try: template = simpleTAL.compileHTMLTemplate (txt) except simpleTAL.TemplateParseException, e: realResult = str (e) self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back exception %s \nexpected exception %s\n" % (errMsg, txt, realResult, result)) return self.fail ("No exception thrown!") # Test that rebinding the namespaces works def testSingleBindNoCommands (self): self._runTest_ ('Hello' ,'Hello' ,'Binding of namespace failed.') def testSingleBind (self): self._runTest_ ('Hello' ,'Hello' ,'Binding of namespace failed.') def testSingleNestedBind (self): self._runTest_ ('

Hello

default contentdefault content' ,'

Hello

default contenttesting' ,'Binding of namespace failed to nest correctly') def testDoubleNestedBind (self): self._runTest_ ('

Hello

default contentdefault
default content' ,'

Hello

default contenttesting
testing' ,'Binding of namespace failed to nest correctly with 2 nests') def testOtherNameSpaces (self): self._runTest_ ('Hello' ,'Hello' ,'Namespaces removed!') # Now test exceptions def testDefaultTALNameSpace (self): self._runErrTest_ ('Hello' ,'[] Can not use TAL name space by default, a prefix must be provided.' ,'Namespaces removed!') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALConditionTestCases.py0000644000175000017500000000621410007245640023023 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALConditionTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testConditionDefault (self): self._runTest_ ('Hello', "Hello", "Condition 'default' did not evaluate to true") def testConditionExists (self): self._runTest_ ('Hello' , 'Hello', 'Condition for something that exists evaluated false') def testConditionNothing (self): self._runTest_ ('Hello' , '', 'Condition nothing evaluated to true') def testConditionMissing (self): self._runTest_ ('Hello' , '', 'Condition for something that does not exist evaluated to true') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALOmitTagTestCases.py0000644000175000017500000000612110007245640022436 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALOmitTagTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testOmitTagTrue (self): self._runTest_ ('Hello' ,'Hello' ,"Omit tag, true, failed.") def testOmitTagNoArg (self): self._runTest_ ('Hello' ,'Hello' ,"Omit tag, no arg, failed.") def testOmitTagEmptyArg (self): self._runTest_ ('Hello' ,'Hello' ,"Omit tag, empty arg, failed.") def testOmitTagFalse (self): self._runTest_ ('Hello' ,'Hello' ,"Omit tag, false, failed.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALDefineTestCases.py0000644000175000017500000001212210007245640022262 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALDefineTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testDefineString (self): self._runTest_ ('

', "

testing

", "Simple string define failed.") def testDefineList (self): self._runTest_ ('

Hello

' , '

Hello one

Hello two

', 'List define failed.') def testDefineGlobal (self): self._runTest_ ('

' , '

testing

', 'Global did not set globally') def testDefineLocal (self): self._runTest_ ('

' , '

', 'Explicit local available globaly') def testDefineImplicitLocal (self): self._runTest_ ('

' , '

', 'Implicit local available globaly') def testDefineDefault (self): self._runTest_ ('

Can you see me?

' , '

Can you see me?

', 'Default variable did not define proplerly.') def testDefineNothing (self): self._runTest_ ('

Can you see me?

' , '

', 'Nothing variable did not define proplerly.') def testDefineMultipleLocal (self): self._runTest_ ('

Testing

' , '

testing

This is a semi;colon

Test

', 'Multiple defines failed.') def testDefineMultipleMixed (self): self._runTest_ ('

Testing

' , '

testing

This is a semi;colon

Test

This is a semi;colon', 'Multiple defines failed.') def testDefineMultipleLocalRef (self): self._runTest_ ('

Testing

' , '

testing

testing

', 'Multiple local defines with references to earlier define failed.') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALSpecialCharsTestCases.py0000644000175000017500000000661710364672755023466 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALSpecialCharsTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context(allowPythonPath=1) self.context.addGlobal ('test', '< testing > experimenting & twice as useful') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testLessThanGreaterThanAmpersand (self): self._runTest_ ('Hello' ,"< testing > experimenting & twice as useful" ,"Less than, greater than or amperand were not encoded correctly") def testEscapedPythonPaths (self): self._runTest_ ('Hello' ,"4000" ,"Python bit shift failed.") def testAmpInTemplate (self): #logging.getLogger().setLevel(logging.DEBUG) NBSP = u"\xa0".encode ("iso-8859-1") self._runTest_ ('Hello Bye Bye' ,"""Hello Bye Bye""" ,"& in template failed.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALEncodingTestCases.py0000644000175000017500000001231510156141637022630 0ustar cms103cms103#!/usr/bin/python # -*- coding: iso-8859-1 -*- """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO, codecs import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() isoDecoder = codecs.lookup ("iso-8859-1")[1] import types try: class UnicodeSubclass(types.UnicodeType): pass oldPython = 0 except: # Python 2.1 oldPython = 1 class TALEncodingTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'Testing this and that') self.context.addGlobal ('HighBC', isoDecoder ('This cost nothing, yep £0!')[0]) self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('badascii', 'This costs nothing, yep £0') if (not oldPython): self.context.addGlobal ('inheritance', UnicodeSubclass(u'\u2018subclass\u2019')) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testISOToUTF8 (self): utf8Pound = "\xc2\xa3" template = simpleTAL.compileHTMLTemplate ('£3.12? ', 'iso-8859-1') file = StringIO.StringIO() template.expand (self.context, file, 'utf-8') result = file.getvalue() expectedResult = "" + utf8Pound + "3.12? This cost nothing, yep " + utf8Pound + "0!" self.failUnless (result == expectedResult, "UTF8 Encoding failed. \nResult was: " + result + "\nExpected result: " + expectedResult) def testISOToISO (self): template = simpleTAL.compileHTMLTemplate ('£3.12? ', 'iso-8859-1') file = StringIO.StringIO() template.expand (self.context, file, 'iso-8859-1') result = file.getvalue() expectedResult = "£3.12? This cost nothing, yep £0!" self.failUnless (result == expectedResult, "ISO Encoding failed. \nResult was: " + result + "\nExpected result: " + expectedResult) def testUTF8ToISO (self): template = simpleTAL.compileHTMLTemplate ('\xc2\xa33.12? ', 'utf-8') file = StringIO.StringIO() template.expand (self.context, file, 'iso-8859-1') result = file.getvalue() expectedResult = "£3.12? This cost nothing, yep £0!" self.failUnless (result == expectedResult, "UTF8 -> ISO Encoding failed. \nResult was: " + result + "\nExpected result: " + expectedResult) def testUnicodeSubclass (self): if (oldPython): return template = simpleTAL.compileHTMLTemplate ('', 'utf-8') file = StringIO.StringIO() template.expand (self.context, file, 'utf-8') result = file.getvalue() expectedResult = u"\u2018subclass\u2019".encode('utf-8') self.failUnless (result == expectedResult, "Unicode subclass failed. \nResult was: " + result + "\nExpected result: " + expectedResult) # def testBadAscii (self): # template = simpleTAL.compileHTMLTemplate ('

') # file = StringIO.StringIO() # template.expand (self.context, file, 'iso-8859-1') # result = file.getvalue() # expectedResult = "£3.12? This cost nothing, yep £0!" # self.failUnless (result == expectedResult, "ISO Encoding failed. \nResult was: " + result + "\nExpected result: " + expectedResult) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALReplaceTestCases.py0000644000175000017500000000727210007245640022455 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALReplaceTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': entry} self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('weblog', weblog) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testContentNothing (self): self._runTest_ ('

' ,'' ,'Content of nothing did not remove tag.') def testContentDefault (self): self._runTest_ ('

Original

' ,'

Original

' ,'Content of default did not evaluate to existing content without tags') def testContentString (self): self._runTest_ ('

Original

' ,'testing' ,'Content of string did not evaluate to contain string') def testContentStructure (self): # This test uses a specific context entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': simpleTAL.compileHTMLTemplate(entry)} self.context.addGlobal ('weblog', weblog) self._runTest_ ('

Original

' ,'Some structure: Test subject' ,'Content of Structure did not evaluate to expected result') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALForbiddenEndTagTestCases.py0000644000175000017500000001754610007245640024066 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALForbiddenEndTagTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('scrWidth', '640') def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testAreaElement (self): self._runTest_ ('' ,'' ,"HTML Element AREA produced end tag.") def testBaseElement (self): self._runTest_ ('' ,'' ,"HTML Element BASE produced end tag.") def testBaseFontElement (self): self._runTest_ ('' ,'' ,"HTML Element BASEFONT produced end tag.") def testBRElement (self): self._runTest_ ('

' ,'
' ,"HTML Element BR produced end tag.") def testColElement (self): self._runTest_ ('' ,'' ,"HTML Element COL produced end tag.") def testFrameElement (self): self._runTest_ ('' ,'' ,"HTML Element FRAME produced end tag.") def testHRElement (self): self._runTest_ ('
' ,'
' ,"HTML Element HR produced end tag.") def testImgElement (self): self._runTest_ ('' ,'' ,"HTML Element IMG produced end tag.") def testInputElement (self): self._runTest_ ('' ,'' ,"HTML Element INPUT produced end tag.") def testIsIndexElement (self): self._runTest_ ('' ,'' ,"HTML Element ISINDEX produced end tag.") def testLinkElement (self): self._runTest_ ('' ,'' ,"HTML Element LINK produced end tag.") def testMetaElement (self): self._runTest_ ('' ,'' ,"HTML Element META produced end tag.") def testParamElement (self): self._runTest_ ('' ,'' ,"HTML Element PARAM produced end tag.") # Same tests again, but with no end tag in the templates def testAreaElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element AREA produced end tag.") def testBaseElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element BASE produced end tag.") def testBaseFontElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element BASEFONT produced end tag.") def testBRElementNoClose (self): self._runTest_ ('
' ,'
' ,"HTML Element BR produced end tag.") def testColElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element COL produced end tag.") def testFrameElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element FRAME produced end tag.") def testHRElementNoClose (self): self._runTest_ ('
' ,'
' ,"HTML Element HR produced end tag.") def testImgElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element IMG produced end tag.") def testInputElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element INPUT produced end tag.") def testIsIndexElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element ISINDEX produced end tag.") def testLinkElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element LINK produced end tag.") def testMetaElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element META produced end tag.") def testParamElementNoClose (self): self._runTest_ ('' ,'' ,"HTML Element PARAM produced end tag.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALAttributesTestCases.py0000644000175000017500000001552410354332143023227 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALAttributesTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('link', 'www.owlfish.com') self.context.addGlobal ('needsQuoting', """Does "this" work?""") self.context.addGlobal ('number', 5) self.context.addGlobal ('uniQuote', u'Does "this" work?') self.context.addGlobal ('anotherdefault', {'inhere': simpleTALES.DEFAULTVALUE}) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testAddingAnAttribute (self): self._runTest_ ('Hello' ,'Hello' ,"Addition of attribute 'link' failed.") def testRemovingAnAttribute (self): self._runTest_ ('Hello' ,'Hello' ,"Removal of attribute 'href' failed.") def testDefaultAttribute (self): self._runTest_ ('Hello' ,'Hello' ,"Defaulting of attribute 'href' failed.") def testAnotherDefaultAttribute (self): self._runTest_ ('Hello' ,'Hello' ,"Defaulting of attribute 'href' failed.") def testMultipleAttributes (self): self._runTest_ ('Hello' ,'Hello' ,"Setting multiple attributes at once failed.") def testMultipleAttributesSpace (self): self._runTest_ ('Hello' ,'Hello' ,"Setting multiple attributes at once, with spaces between semi-colons, failed.") def testMultipleAttributesEscaped (self): self._runTest_ ('Hello' ,'Hello' ,"Setting multiple attributes at once, with spaces between semi-colons, failed.") def testAttributeEscaping (self): self._runTest_ ('Hello' ,"""Hello""" ,"Escaping of new attributes failed.") def testNumberAttributeEscaping (self): self._runTest_ ('Hello' ,"""Hello""" ,"Escaping of new attributes failed.") def testNumberAttributeEscaping (self): self._runTest_ ('Hello' ,"""Hello""" ,"Escaping of new attributes failed.") def testOriginalAttributes (self): self._runTest_ ('Hello' ,""""Testing"""" ,"Accessing existing attributes failed.") def testMultipleOriginalAttributes (self): self._runTest_ ('Hello' ,"""Value One""" ,"Accessing multiple existing attributes failed.") def testAmpersandEscapeInAttributes (self): self._runTest_ ('Hello' ,"""&Testing&""" ,"Accessing existing attributes failed.") #~ def testAttributeCase (self): #~ self._runTest_ ('Hello' #~ ,"""Hello""" #~ ,"HTML Attributes not treated as case insensitive.") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALRepeatTestCases.py0000644000175000017500000003466110136353026022325 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALRepeatTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('emptyList', []) self.context.addGlobal ('bigList', range (1,100)) self.context.addGlobal ('fourList', ["zero", "one", "two", "three"]) self.context.addGlobal ('nested', [{'title': 'Image 1', 'catList': [1,2,3]} ,{'title': 'Image 2', 'catList': [5,2,3], 'selected': simpleTALES.DEFAULTVALUE} ,{'title': 'Image 3', 'catList': [8,9,1]} ]) self.context.addGlobal ('defList', ["Hello", simpleTALES.DEFAULTVALUE, "World"]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () try: template.expand (self.context, file) except Exception, e: print "Error, template compiled to: " + str (template) raise e realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testInvalidPath (self): self._runTest_ ('

Hello

', "", "Repeat of non-existant element failed") def testDefaultValue (self): self._runTest_ ('

Default Only

', '

Default Only

', 'Default did not keep existing structure intact') def testStringRepeat (self): self._runTest_ ('

', 'testing', 'Itteration over string failed.') def testEmptyList (self): self._runTest_ ('

Empty

' ,'' ,'Empty list repeat failed.' ) def testListRepeat (self): self._runTest_ ('

', '

one

two

', 'Itteration over list failed.') def testTwoCmndsOneTagListRepeat (self): self._runTest_ ('

' ,'

one

two

' ,'Itteration over list with both content and repeat on same element failed.') def testAttributesInRepeat (self): self._runTest_ ('

' ,'

Image 1

Image 2

Image 3

' ,'Accessing attributes in repeat loop failed.') def testDefaultInContentInRepeat (self): self._runTest_ ('

Default Word

' ,'

Hello

Default Word

World

' ,'Using default content in repeat loop failed.') def testDefaultInReplaceInRepeat (self): self._runTest_ ('

Default Word

' ,'Hello

Default Word

World' ,'Using default content in repeat loop failed.') def testNestedRepeat (self): self._runTest_ ('

' ,'

Image 1

123

Image 2

523

Image 3

891

' ,'Nested repeat did not create expected outcome.' ) def testNestedRepeatClasses (self): self._runTest_ ('

' ,'

1
2
3

5
2
3

8
9
1

' ,'Nested repeat with classes did not create expected outcome.' ) def testNestedRepeatScope (self): self._runTest_ ('

' ,'

Image 1

123

Image 2

523

Image 3

891

' ,'Nested repeat did not create expected outcome.' ) def testRepeatVarIndex (self): expectedResult = "" for num in xrange (0,99): expectedResult += str (num) expectedResult += "" self._runTest_ ('

Index

' ,expectedResult ,"Repeat variable index failed." ) def testRepeatVarNumber (self): self._runTest_ ('

Index

' ,'123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899' ,'Repeat variable number failed.' ) def testRepeatVarEvenOdd (self): self._runTest_ ('

- OddEven

' ,'

zero - Even

one - Odd

two - Even

three - Odd

' ,'Repeat variables odd and even failed.' ) def testRepeatVarStartEnd (self): self._runTest_ ('

StartEnd

' ,'

Startzero

one

two

threeEnd

' ,'Repeat variables start and end failed.' ) def testRepeatVarLength (self): self._runTest_ ('

Len: lengthEntry:

' ,'

Len: 4Entry: zero

Entry: one

Entry: two

Entry: three

' ,'Repeat variable length failed.' ) def testRepeatVarLowerLetter (self): self._runTest_ ('

a,b,c,etc:

' ,'

a: zero

b: one

c: two

d: three

' ,'Repeat variable letter failed.' ) def testRepeatVarLowerLetterLarge (self): self._runTest_ ('

a,b,c,etc:

' ,'

a: 1

b: 2

c: 3

d: 4

e: 5

f: 6

g: 7

h: 8

i: 9

j: 10

k: 11

l: 12

m: 13

n: 14

o: 15

p: 16

q: 17

r: 18

s: 19

t: 20

u: 21

v: 22

w: 23

x: 24

y: 25

z: 26

ba: 27

bb: 28

bc: 29

bd: 30

be: 31

bf: 32

bg: 33

bh: 34

bi: 35

bj: 36

bk: 37

bl: 38

bm: 39

bn: 40

bo: 41

bp: 42

bq: 43

br: 44

bs: 45

bt: 46

bu: 47

bv: 48

bw: 49

bx: 50

by: 51

bz: 52

ca: 53

cb: 54

cc: 55

cd: 56

ce: 57

cf: 58

cg: 59

ch: 60

ci: 61

cj: 62

ck: 63

cl: 64

cm: 65

cn: 66

co: 67

cp: 68

cq: 69

cr: 70

cs: 71

ct: 72

cu: 73

cv: 74

cw: 75

cx: 76

cy: 77

cz: 78

da: 79

db: 80

dc: 81

dd: 82

de: 83

df: 84

dg: 85

dh: 86

di: 87

dj: 88

dk: 89

dl: 90

dm: 91

dn: 92

do: 93

dp: 94

dq: 95

dr: 96

ds: 97

dt: 98

du: 99

' ,'Repeat variable letter failed on a large list.' ) def testRepeatVarUpperLetter (self): self._runTest_ ('

A,B,C,etc:

' ,'

A: zero

B: one

C: two

D: three

' ,'Repeat variable Letter failed.' ) def testRepeatVarLowerRoman (self): self._runTest_ ('

i,ii,iii,etc:

' ,'

i: 1

ii: 2

iii: 3

iv: 4

v: 5

vi: 6

vii: 7

viii: 8

ix: 9

x: 10

xi: 11

xii: 12

xiii: 13

xiv: 14

xv: 15

xvi: 16

xvii: 17

xviii: 18

xix: 19

xx: 20

xxi: 21

xxii: 22

xxiii: 23

xxiv: 24

xxv: 25

xxvi: 26

xxvii: 27

xxviii: 28

xxix: 29

xxx: 30

xxxi: 31

xxxii: 32

xxxiii: 33

xxxiv: 34

xxxv: 35

xxxvi: 36

xxxvii: 37

xxxviii: 38

xxxix: 39

xl: 40

xli: 41

xlii: 42

xliii: 43

xliv: 44

xlv: 45

xlvi: 46

xlvii: 47

xlviii: 48

xlix: 49

l: 50

li: 51

lii: 52

liii: 53

liv: 54

lv: 55

lvi: 56

lvii: 57

lviii: 58

lix: 59

lx: 60

lxi: 61

lxii: 62

lxiii: 63

lxiv: 64

lxv: 65

lxvi: 66

lxvii: 67

lxviii: 68

lxix: 69

lxx: 70

lxxi: 71

lxxii: 72

lxxiii: 73

lxxiv: 74

lxxv: 75

lxxvi: 76

lxxvii: 77

lxxviii: 78

lxxix: 79

lxxx: 80

lxxxi: 81

lxxxii: 82

lxxxiii: 83

lxxxiv: 84

lxxxv: 85

lxxxvi: 86

lxxxvii: 87

lxxxviii: 88

lxxxix: 89

xc: 90

xci: 91

xcii: 92

xciii: 93

xciv: 94

xcv: 95

xcvi: 96

xcvii: 97

xcviii: 98

xcix: 99

' ,'Repeat variable roman failed.' ) def testRepeatVarUpperRoman (self): self._runTest_ ('

I,II,III,etc:

' ,'

I: 1

II: 2

III: 3

IV: 4

V: 5

VI: 6

VII: 7

VIII: 8

IX: 9

X: 10

XI: 11

XII: 12

XIII: 13

XIV: 14

XV: 15

XVI: 16

XVII: 17

XVIII: 18

XIX: 19

XX: 20

XXI: 21

XXII: 22

XXIII: 23

XXIV: 24

XXV: 25

XXVI: 26

XXVII: 27

XXVIII: 28

XXIX: 29

XXX: 30

XXXI: 31

XXXII: 32

XXXIII: 33

XXXIV: 34

XXXV: 35

XXXVI: 36

XXXVII: 37

XXXVIII: 38

XXXIX: 39

XL: 40

XLI: 41

XLII: 42

XLIII: 43

XLIV: 44

XLV: 45

XLVI: 46

XLVII: 47

XLVIII: 48

XLIX: 49

L: 50

LI: 51

LII: 52

LIII: 53

LIV: 54

LV: 55

LVI: 56

LVII: 57

LVIII: 58

LIX: 59

LX: 60

LXI: 61

LXII: 62

LXIII: 63

LXIV: 64

LXV: 65

LXVI: 66

LXVII: 67

LXVIII: 68

LXIX: 69

LXX: 70

LXXI: 71

LXXII: 72

LXXIII: 73

LXXIV: 74

LXXV: 75

LXXVI: 76

LXXVII: 77

LXXVIII: 78

LXXIX: 79

LXXX: 80

LXXXI: 81

LXXXII: 82

LXXXIII: 83

LXXXIV: 84

LXXXV: 85

LXXXVI: 86

LXXXVII: 87

LXXXVIII: 88

LXXXIX: 89

XC: 90

XCI: 91

XCII: 92

XCIII: 93

XCIV: 94

XCV: 95

XCVI: 96

XCVII: 97

XCVIII: 98

XCIX: 99

' ,'Repeat variable Roman failed.' ) def testLocalVarScope (self): self._runTest_ ('

bold

VAR EXISTS' ,'

zero

one

two

three

' ,'Local repeat variable remained accessible out of scope!' ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALIteratorRepeatTestCases.py0000644000175000017500000001554410347326342024043 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os, sys import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() try: b = StopIteration() ITERATOR_SUPPORT = 1 except: ITERATOR_SUPPORT = 0 class ActualIter: def __init__ (self, size): self.size = size self.cur = 0 def next (self): if (self.cur == self.size): raise StopIteration () self.cur += 1 return self.cur class IterContainer: def __init__ (self, size): self.size = size def __iter__ (self): return ActualIter (self.size) class TALIteratorRepeatTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('zeroCont', IterContainer (0)) self.context.addGlobal ('oneCont', IterContainer (1)) self.context.addGlobal ('twoCont', IterContainer (2)) self.context.addGlobal ('zeroAct', ActualIter (0)) self.context.addGlobal ('oneAct', ActualIter (1)) self.context.addGlobal ('twoAct', ActualIter (2)) def _runTest_ (self, txt, result, errMsg="Error"): if (not ITERATOR_SUPPORT): return template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () try: template.expand (self.context, file) except Exception, e: print "Error, template compiled to: " + str (template) raise e realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testZeroCont (self): self._runTest_ ('

Hello

', "", "Repeat of zero length container failed.") def testOneCont (self): self._runTest_ ('

Hello

', "

Hello

", "Repeat of single length container failed.") def testTwoCont (self): self._runTest_ ('

Hello

', "

Hello

Hello

", "Repeat of two length container failed.") def testZeroAct (self): self._runTest_ ('

Hello

', "", "Repeat of zero length actual failed.") def testOneAct (self): self._runTest_ ('

Hello

', "

Hello

", "Repeat of single length actual failed.") def testTwoAct (self): self._runTest_ ('

Hello

', "

Hello

Hello

", "Repeat of two length actual failed.") def testIndexAct (self): self._runTest_ ('

Hello

', "

0

1

", "Repeat of two length actual iterator failed to generate index.") def testNumberAct (self): self._runTest_ ('

Hello

', "

1

2

", "Repeat of two length actual iterator failed to generate numbers.") def testEvenAct (self): self._runTest_ ('

Hello

', "

1

0

", "Repeat of two length actual iterator failed to even.") def testOddAct (self): self._runTest_ ('

Hello

', "

0

1

", "Repeat of two length actual iterator failed to odd.") def testStartAct (self): self._runTest_ ('

Hello

', "

1

0

", "Repeat of two length actual iterator failed to start.") # The only way to see inside an iterator is to cheat, and call it early. Doing this might be unexpected, so iterators don't support end. # def testEndAct (self): # self._runTest_ ('

Hello

', "

0

1

", "Repeat of two length actual iterator failed to end.") def testLengthAct (self): self._runTest_ ('

Hello

', "

%s

%s

" % (str (sys.maxint), str (sys.maxint)), "Repeat of two length actual iterator failed to generate length.") def testLetterSmallAct (self): self._runTest_ ('

Hello

', "

a

b

", "Repeat of two length actual iterator failed to letter.") def testLetterAct (self): self._runTest_ ('

Hello

', "

A

B

", "Repeat of two length actual iterator failed to Letter.") def testSmallRomanNumAct (self): self._runTest_ ('

Hello

', "

i

ii

", "Repeat of two length actual iterator failed to generate roman numerals.") def testRomanNumAct (self): self._runTest_ ('

Hello

', "

I

II

", "Repeat of two length actual iterator failed to generate roman numerals.") if __name__ == '__main__': unittest.main()SimpleTAL-4.1/tests/TALTests/HTMLTests/TALHandlerTestCases.py0000755000175000017500000001136210354332656022466 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALHandlerTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testEmptyFile (self): self._runTest_ ("", "", "Empty template contains more text than given.") def testSingleEmptyElement (self): self._runTest_ ("", "") def testSingleElement (self): self._runTest_ ("start", "start") def testUnbalancedDocument (self): self._runTest_ ("startend", "startend") def testNoCloseElement (self): self._runTest_ ("

Hello.
World

", "

Hello.
World

") def testCaseSensitivity (self): self._runTest_ ("

Hello.
World

", "

Hello.
World

") def testComments (self): self._runTest_ ("

Boo

", "

Boo

") def testUnbalancedCloseTag (self): try: template = simpleTAL.compileHTMLTemplate ("

Hello World

") file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.fail ("No exception raised during parsing of unbalanced tag.") except simpleTAL.TemplateParseException, e: pass def testEncodedCharsSection (self): self._runTest_ ("""

<section> stuff & things.

""" ,"""

<section> stuff & things.

""" ,"Quoted chars were not re-encoded correctly.") def testDocumentTypeDeclaration (self): self._runTest_("""

""" ,"""

testing

""" ,"""Document type was not output correctly.""" ) def testHTMLComments (self): self._runTest_("""

""" ,"""

testing

""" ,"""Comment not output correctly.""" ) def testProcessingInstructions (self): self._runTest_ ("""\n

Somemarkup

""" ,"""\n

Somemarkup

""" ,"""Processing instructions not preserved.""") if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALTests/HTMLTests/TALContentTestCases.py0000644000175000017500000001007610007245640022510 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class TALContentTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': entry} self.context.addGlobal ('test', 'testing') self.context.addGlobal ('one', [1]) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('weblog', weblog) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testContentNothing (self): self._runTest_ ('

' ,'

' ,'Content of nothing did not evaluate to empty tag.') def testContentDefault (self): self._runTest_ ('

Original

' ,'

Original

' ,'Content of default did not evaluate to existing content') def testContentString (self): self._runTest_ ('

Original

' ,'

testing

' ,'Content of string did not evaluate to contain string') def testContentStructure (self): # This test has specific needs - i.e. wrap the weblog/entry in a template... entry = """Some structure: """ entryTemplate = simpleTAL.compileHTMLTemplate(entry) weblog = {'subject': 'Test subject', 'entry': entryTemplate} self.context.addGlobal ('weblog', weblog) self._runTest_ ('

Original

' ,'

Some structure: Test subject

' ,'Content of Structure did not evaluate to expected result') def testTALDisabledContentStructure (self): self._runTest_ ('

Original

' ,'

Some structure:

' ,'Content of Structure did not evaluate to expected result') if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALESTests/0000755000175000017500000000000010364737164015016 5ustar cms103cms103SimpleTAL-4.1/tests/TALESTests/StringTests.py0000644000175000017500000001432310136353026017650 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() def simpleFunction (): return "Hello" def simpleFalseFunc (): return 0 class StringTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('top', 'Hello from the top') self.context.addGlobal ('alt', 'Wobble the way') self.context.addGlobal ('holder', {'helloFunc': simpleFunction ,'falseFunc': simpleFalseFunc}) self.context.addGlobal ('version', 3.1) self.context.addGlobal ('uniString', u"Hello") def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testEmptyString (self): self._runTest_ ('Exists' ,'' ,'Empty string returned something!' ) def testStaticString (self): self._runTest_ ('Exists' ,'Hello World!' ,'Static string didnt appear!' ) def testSingleVariable (self): self._runTest_ ('Exists' ,'Hello from the top' ,'Single variable failed.' ) def testStartVariable (self): self._runTest_ ('Exists' ,'Hello from the top of here' ,'Start variable failed.' ) def testMidVariable (self): self._runTest_ ('Exists' ,'Thoughts - Hello from the top eh?' ,'Mid variable failed.' ) def testEndVariable (self): self._runTest_ ('Exists' ,'Thought - Hello from the top' ,'End variable failed.' ) def testNumericVariable (self): self._runTest_ ('Exists' ,'Thought - 3.1' ,'Numeric test variable failed.' ) def testUnicodeVariable (self): self._runTest_ ('Exists' ,'Thought - Hello' ,'Unicode test variable failed.' ) def testSinglePath (self): self._runTest_ ('Exists' ,'Hello from the top' ,'Single path failed.' ) def testStartPath (self): self._runTest_ ('Exists' ,'Hello from the top of here' ,'Start path failed.' ) def testMidPath (self): self._runTest_ ('Exists' ,'Thoughts - Hello from the topeh?' ,'Mid path failed.' ) def testEndPath (self): self._runTest_ ('Exists' ,'Thought - Hello from the top' ,'End path failed.' ) def testMultiplePath (self): self._runTest_ ('Exists' ,'Thought - Hello from the top is here and recursive' ,'Multiple paths failed.' ) def testNoSuchPath (self): self._runTest_ ('Exists' ,'' ,'No such path failed.' ) def testTrailingDollar (self): self._runTest_ ('Exists' ,'A trailing dollar: ' ,'No such path failed.' ) def testDollarEscaping (self): self._runTest_ ('Exists' ,'$A trailing $dollar: $' ,'No such path failed.' ) def testPartialMissing (self): self._runTest_ ('Exists' ,'First bit here: Wobble the way second bit not: there.' ,'Combination of non-existant variable and existing test failed.' ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALESTests/ExistsTests.py0000644000175000017500000001012210347326342017657 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() def simpleFunction (): return "Hello World" def nestedFunction (): return {'nest': simpleFunction} class ExistsTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('top', 'Hello from the top') self.context.addGlobal ('alt', 'Wobble the way') self.context.addGlobal ('theMap', {'top': 'Hello', 'onelevel': {'top': 'Bye'}}) self.context.addGlobal ('funcMap', {'simple': simpleFunction, 'nested': nestedFunction}) self.context.addGlobal ('topFunc', simpleFunction) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testOneVarDoesExist (self): self._runTest_ ('Top' ,'Top' ,'Exists check on single variable failed.' ) def testOneVarDoesNotExist (self): self._runTest_ ('Top' ,'' ,'Exists check on single variable that does not exist failed.' ) def testTwoVarDoesExist (self): self._runTest_ ('Top' ,'Top' ,'Exists check on two variables failed.' ) def testTwoVarDoesNotExist (self): self._runTest_ ('Top' ,'' ,'Exists check on two variables that dont exist failed.' ) def testOneFuncExist (self): self._runTest_ ('Top' ,'Top' ,'Exists check on one function failed.' ) def testTwoFuncExist (self): self._runTest_ ('Top' ,'Top' ,'Exists check on two function failed.' ) def testNothingExists (self): self._runTest_ ('Top' ,'Top' ,'Nothing should exist!' ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALESTests/NoCallTests.py0000644000175000017500000001012710007245640017547 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() class CallRecorder: def __init__ (self): self.called = 0 def simpleFunction (self): self.called = 1 return "Hello" class NoCallTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.recorder = CallRecorder() self.context.addGlobal ('top', 'Hello from the top') self.context.addGlobal ('alt', 'Wobble the way') self.context.addGlobal ('holder', {'recorder': self.recorder.simpleFunction}) def _runTest_ (self, txt, result, errMsg="Error", expectedRecorderVal=0): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) self.failUnless (self.recorder.called == expectedRecorderVal, 'Call recorder detected that the call recorder object has state %s' % str (self.recorder.called)) def testNoCallString (self): self._runTest_ ('Exists' ,'Exists' ,'Binding string using nocall failed.' ) def testNoCallRecorder (self): self._runTest_ ('Exists' ,'Exists' ,'Binding function using nocall failed.' ) def testNoCallORPath (self): self._runTest_ ('Exists' ,'Exists' ,'Binding function using nocall as first part of path failed' ) def testNoCallORPathTwo (self): self._runTest_ ('Exists' ,'Exists' ,'Binding function using nocall as second part of path failed' ) def testNoCallRecorderInfra (self): self._runTest_ ('Exists' ,'Exists' ,'Recorder failed to note call' ,1 ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALESTests/VariablePathTest.py0000644000175000017500000000751710007245640020567 0ustar cms103cms103#!/usr/bn/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() def simpleFunction (): return "Hello World" def nestedFunction (): return {'nest': simpleFunction} def pathFunction (thePath): return thePath class PathTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('colours', {'blue': 'The sea is blue', 'red': 'The ball is red', 'green': 'The grass is green'}) self.context.addGlobal ('aList', ['blue', 'green']) self.context.addGlobal ('goodColour', 'goodColourPath') self.context.addGlobal ('goodColourPath', 'Black is good') self.context.addGlobal ('noSuchColour', 'pink') def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testRepeatVariablePath (self): self._runTest_ ('
  • List
' ,'
  • The sea is blue
  • The grass is green
' ,'Path variable during repeat failed.' ) def testLocalVariablePath (self): self._runTest_ ('

It is red:

' ,'

It is red: The ball is red

' ,'Local variable path failed.' ) def testGlobalVariablePath (self): self._runTest_ ('

' ,'

Black is good

' ,'Global variable path failed.' ) def testNoSuchVariablePath (self): self._runTest_ ('

' ,'

' ,'No such variable failed.' ) def testNoSuchVariablePath2 (self): self._runTest_ ('

' ,'

' ,'No such variable2 failed.' ) SimpleTAL-4.1/tests/TALESTests/PythonPathTests.py0000644000175000017500000001561210007245640020501 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() def simpleFunction (param): return "Hello %s" % param def helloFunction (): return "Hello" def exceptionalFunction (param): raise Exception (param) class PythonPathTests (unittest.TestCase): def setUp (self): pass def _runTest_ (self, txt, result, errMsg="Error", allowPythonPath=0): self.context = simpleTALES.Context(allowPythonPath=allowPythonPath) self.context.addGlobal ('top', 'Hello from the top') self.context.addGlobal ('exceptFunc', exceptionalFunction) self.context.addGlobal ('helloFunc', simpleFunction) self.context.addGlobal ('helloPath', simpleTALES.PathFunctionVariable(simpleFunction)) self.context.addGlobal ('helloFunction', helloFunction) self.context.addGlobal ('myList', [1,2,3,4,5,6]) self.context.addGlobal ('testing', 'testing') self.context.addGlobal ('map', {'test': 'maptest'}) self.context.addGlobal ('data', {'one': 1, 'zero': 0}) template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testPythonPathException (self): self._runTest_ ("""Exists""" ,'Exception: Test exception!' ,'Exception thrown during python path not handled!' ,allowPythonPath=1 ) def testPythonPathDisabled (self): self._runTest_ ("""Exists""" ,'0' ,'Python path with allowPythonPath=false still expanded!' ,allowPythonPath=0 ) def testPythonPathFuncSuccess (self): self._runTest_ ("""Exists""" ,'Hello Colin!' ,'Python path with function failed.' ,allowPythonPath=1 ) def testPythonPathSliceSuccess (self): self._runTest_ ("""Exists""" ,'34' ,'Python path with slice failed.' ,allowPythonPath=1 ) def testPythonStringCompare (self): self._runTest_ ("""Passed.""" ,'Passed.' ,'Python string compare failed.' ,allowPythonPath=1 ) def testPythonPathFunc (self): self._runTest_ ("""Passed.""" ,'maptest' ,'Python path function call failed' ,allowPythonPath=1 ) def testPythonStringFunc (self): self._runTest_ ("""Passed.""" ,'Hello maptest there' ,'Python string function call failed' ,allowPythonPath=1 ) def testPythonExistsFunc1 (self): self._runTest_ ("""Passed.""" ,'Passed.' ,'Python exists function call failed' ,allowPythonPath=1 ) def testPythonExistsFunc2 (self): self._runTest_ ("""Passed.""" ,'' ,'Python exists function call failed' ,allowPythonPath=1 ) def testPythonNocallFunc (self): self._runTest_ ("""Passed.""" ,'Passed.' ,'Python nocall function call failed' ,allowPythonPath=1 ) def testPythonPathFuncWithFunc (self): self._runTest_ ("""Passed.""" ,'Passed.' ,'Python path function using a function failed' ,allowPythonPath=1 ) def testPythonPathFuncWithPath (self): self._runTest_ ("""Passed.""" ,'Passed.' ,'Python path function wrapped in a PathFunctionVariable failed' ,allowPythonPath=1 ) def testTestFunctionDefault (self): self._runTest_ ("""Passed.""" ,'Passed.' ,'Test function failed to use default.' ,allowPythonPath=1 ) def testTestFunctionTwoArgs (self): self._runTest_ ("""Passed.""" ,'' ,'Test function failed to use default of false.' ,allowPythonPath=1 ) def testTestFunctionThreeArgs (self): self._runTest_ ("""Passed.""" ,'2' ,'Test function failed to use default.' ,allowPythonPath=1 ) def testTestFunctionFiveArgs (self): self._runTest_ ("""Passed.""" ,'5' ,'Test function failed to use default.' ,allowPythonPath=1 ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALESTests/NotTests.py0000644000175000017500000001072110007245640017137 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() def simpleFunction (): return "Hello" def simpleFalseFunc (): return 0 class NotTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.context.addGlobal ('top', 'Hello from the top') self.context.addGlobal ('alt', 'Wobble the way') self.context.addGlobal ('holder', {'helloFunc': simpleFunction ,'falseFunc': simpleFalseFunc}) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testNotNothing (self): self._runTest_ ('Exists' ,'Exists' ,'not:nothing returned false' ) def testNotDefault (self): self._runTest_ ('Exists' ,'' ,'not:default returned true' ) def testNotNoSuchPath (self): self._runTest_ ('Exists' ,'Exists' ,'not:no/such/path returned false' ) def testNotSomething (self): self._runTest_ ('Exists' ,'' ,'not:string returned true' ) def testNotFalse (self): self._runTest_ ('Exists' ,'Exists' ,'not:false returned false' ) def testNotExists (self): self._runTest_ ('Exists' ,'' ,'not:exists:nothing returned true' ) def testNotORPathOne (self): self._runTest_ ('Exists' ,'' ,'not:no/such/path | holder/helloFunc returned true' ) def testNotORPathTwo (self): self._runTest_ ('Exists' ,'Exists' ,'not:no/such/path | holder/falseFunc returned false' ) def testNotORPathThree (self): self._runTest_ ('Exists' ,'' ,'no/such/path | not:holder/helloFunc returned true' ) def testNotORPathFour (self): self._runTest_ ('Exists' ,'Exists' ,'no/such/path | not:holder/falseFunc returned false' ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/TALESTests/ElementTreeTests.py0000644000175000017500000000735110347326342020623 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 20045Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config try: from simpletal import simpleElementTree ELEMENT_TREE_SUPPORT = 1 except: ELEMENT_TREE_SUPPORT = 0 from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() def simpleFunction (param): return "Hello %s" % param def helloFunction (): return "Hello" class ElementTreeTestCases (unittest.TestCase): def setUp (self): pass def _runTest_ (self, txt, result, errMsg="Error", allowPythonPath=0): if (not ELEMENT_TREE_SUPPORT): logging.warn ("No ElementTree support found, skipping test.") return self.context = simpleTALES.Context(allowPythonPath=allowPythonPath) self.context.addGlobal ('top', 'Hello from the top') self.context.addGlobal ('helloFunc', simpleFunction) self.context.addGlobal ('helloPath', simpleTALES.PathFunctionVariable(simpleFunction)) self.context.addGlobal ('helloFunction', helloFunction) self.context.addGlobal ('myList', [1,2,3,4,5,6]) self.context.addGlobal ('testing', 'testing') self.context.addGlobal ('map', {'test': 'maptest'}) self.context.addGlobal ('data', {'one': 1, 'zero': 0}) testXML = 'This is a test' xmlTree = simpleElementTree.parseFile (StringIO.StringIO (testXML)) self.context.addGlobal ("xml", xmlTree) template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testNormalTree (self): self._runTest_ ("""Exists""" ,'This is a test' ,'Simple Element Tree test failed.' ,allowPythonPath=1 ) def testPythonPathTree (self): self._runTest_ ("""Exists""" ,'This is a test' ,'Python path use of Element Tree failed.' ,allowPythonPath=1 )SimpleTAL-4.1/tests/TALESTests/PathTests.py0000644000175000017500000001522010347326342017300 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os import StringIO import logging, logging.config from simpletal import simpleTAL, simpleTALES if (os.path.exists ("logging.ini")): logging.config.fileConfig ("logging.ini") else: logging.basicConfig() def simpleFunction (): return "Hello World" def nestedFunction (): return {'nest': simpleFunction} def pathFunction (thePath): return thePath class CallRecorder: def __init__ (self): self.called = 0 def simpleFunction (self): self.called += 1 return "Hello" class PathTests (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.recorder = CallRecorder() self.context.addGlobal ('top', 'Hello from the top') self.context.addGlobal ('alt', 'Wobble the way') self.context.addGlobal ('theMap', {'top': 'Hello', 'onelevel': {'top': 'Bye'}}) self.context.addGlobal ('funcMap', {'simple': simpleFunction, 'nested': nestedFunction, 'pathFunc': simpleTALES.PathFunctionVariable (pathFunction)}) self.context.addGlobal ('topFunc', simpleFunction) self.context.addGlobal ('pathFunc', simpleTALES.PathFunctionVariable (pathFunction)) self.context.addGlobal ('cacheFunc', simpleTALES.CachedFuncResult (self.recorder.simpleFunction)) self.context.addGlobal ('alist', [{'a': 'An A', 'b': 'A B'},"Hello!"]) def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def _runCacheTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) self.failUnless (self.recorder.called == 1, 'Recorder shows function was called %s times!' % str (self.recorder.called)) def testSimpleTopPath (self): self._runTest_ ('Top' ,'Hello from the top' ,'Simple top level path failed.' ) def testOneLevelMap (self): self._runTest_ ('Map' ,'Hello' ,'One level deep map access failed.' ) def testTwoLevelMap (self): self._runTest_ ('Map' ,'Bye' ,'Two level deep map access failed.' ) def testOneLevelFuncMap (self): self._runTest_ ('Map' ,'Hello World' ,'One level deep function access failed.' ) def testTwoLevelFuncMap (self): self._runTest_ ('Map' ,'Hello World' ,'Two level deep function access failed.' ) def testTopLevelFunc (self): self._runTest_ ('Map' ,'Hello World' ,'Top level function access failed.' ) def testFirstORPath (self): self._runTest_ ('hmm' ,'Hello from the top' ,'First valid path was not selected.' ) def testSecondORPath (self): self._runTest_ ('hmm' ,'Wobble the way' ,'Second valid path was not selected.' ) def testPathFunctionNoParams (self): self._runTest_ ('hmm' ,'' ,'Path Function with no parameters failed.' ) def testPathFunctionWithOnePath (self): self._runTest_ ('hmm' ,'firstPath' ,'Path Function with one parameter failed.' ) def testPathFunctionWithTwoPath (self): self._runTest_ ('hmm' ,'firstPath/second' ,'Path Function with two parameters failed.' ) def testPathFunctionWithOnePathOneDeep (self): self._runTest_ ('hmm' ,'firstPath' ,'Path Function with one parameter, nested one deep, failed.' ) def testAList (self): self._runTest_ ('hmm' ,'An A' ,'Index into list then dictionary failed.' ) def testAList2ndItem (self): self._runTest_ ('hmm' ,'Hello!' ,'Index into list failed.' ) def testAListNoSuchItem (self): self._runTest_ ('hmm' ,'' ,'Index past end of list failed.' ) def testCachedFuction (self): self._runCacheTest_ ('' ,'HelloHello' ,"Cached function didn't return as expected." ) if __name__ == '__main__': unittest.main() SimpleTAL-4.1/tests/PerformanceTests/0000755000175000017500000000000010364737163016406 5ustar cms103cms103SimpleTAL-4.1/tests/PerformanceTests/XMLTests/0000755000175000017500000000000010364737164020072 5ustar cms103cms103SimpleTAL-4.1/tests/PerformanceTests/XMLTests/BasicTemplateTest.py0000644000175000017500000001151710347326342024017 0ustar cms103cms103""" Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Performance test cases. """ from simpletal import simpleTAL, simpleTALES, simpleTALUtils import time, StringIO, cStringIO, sys performanceTemplate = """

Performance Template

Some text, with some tags that are adding to the parsing load.

This title is dynamic

Here's a table as well - lots of tags in there:
Simple
Sample
Real Results
Expected Results
Template parsed each time around the loop
100
Slow, SGMLParser takes a while
Slow
Template parsed once, then used multiple times
100
Fast!
Hopefully faster than parsing each time
XML Version
100
Faster than SGML
Still too slow
XML Version of TALTemplates
100
As fast as SGML
We can hope.
Here's a list of thing:
  • An item
That should do...

""" context = simpleTALES.Context() context.addGlobal ("title", "Performance testing!") context.addGlobal ("myList", ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]) def NGTemplates (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.XMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) def NGTemplateOverhead (count): file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.XMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) print "Timing TAL templates" result = NGTemplates (10000) print "Result: " + str(result) + " for 10000 template expansions" print "Timing TAL templates (with template parsing)" result = NGTemplateOverhead (1000) print "Result: " + str(result) + " for 1000 template expansions" SimpleTAL-4.1/tests/PerformanceTests/HTMLTests/0000755000175000017500000000000010364737164020176 5ustar cms103cms103SimpleTAL-4.1/tests/PerformanceTests/HTMLTests/BasicTemplateTest.py0000644000175000017500000001146610347326342024126 0ustar cms103cms103""" Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Performance test cases. """ from simpletal import simpleTAL, simpleTALES, simpleTALUtils import time, StringIO, cStringIO, sys performanceTemplate = """

Performance Template

Some text, with some tags that are adding to the parsing load.

This title is dynamic

Here's a table as well - lots of tags in there:
Simple
Sample
Real Results
Expected Results
Template parsed each time around the loop
100
Slow, SGMLParser takes a while
Slow
Template parsed once, then used multiple times
100
Fast!
Hopefully faster than parsing each time
XML Version
100
Faster than SGML
Still too slow
XML Version of TALTemplates
100
As fast as SGML
We can hope.
Here's a list of thing:
  • An item
That should do...

""" context = simpleTALES.Context() context.addGlobal ("title", "Performance testing!") context.addGlobal ("myList", ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]) def NGTemplates (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.HTMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) def NGTemplateOverhead (count): file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.HTMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) print "Timing TAL templates" result = NGTemplates (10000) print "Result: " + str(result) + " for 10000 template expansions" print "Timing TAL templates (with template parsing)" result = NGTemplateOverhead (1000) print "Result: " + str(result) + " for 1000 template expansions" SimpleTAL-4.1/tests/PerformanceTests/HTMLTests/DeeplyNestedRepeatTest.py0000644000175000017500000001002210347326342025122 0ustar cms103cms103""" Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Performance test cases. """ from simpletal import simpleTAL, simpleTALES, simpleTALUtils import time, StringIO, cStringIO, sys performanceTemplate = """

Performance Template

Itteration title

Colour

  • All numbers

""" # 3 X 7 X 8 = 168 itterations per template expansion. thirdLevelList = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"] secondLevelList = [{"colour": "red", "num": thirdLevelList}, {"colour": "orange", "num": thirdLevelList}, {"colour": "yellow", "num": thirdLevelList}, {"colour": "green", "num": thirdLevelList}, {"colour": "blue", "num": thirdLevelList}, {"colour": "indigo", "num": thirdLevelList}, {"colour": "violet", "num": thirdLevelList}] firstLevelList = [{"title": "First", "content": secondLevelList}, {"title": "Second", "content": secondLevelList}, {"title": "Third", "content": secondLevelList}] context = simpleTALES.Context() context.addGlobal ("title", "Performance testing!") context.addGlobal ("myList", firstLevelList ) def NGTemplates (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.HTMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) def NGTemplateOverhead (count): file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.HTMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) print "Timing TAL templates" result = NGTemplates (1000) print "Result: " + str(result) + " for 1000 template expansions" print "Timing TAL templates (with template parsing)" result = NGTemplateOverhead (1000) print "Result: " + str(result) + " for 1000 template expansions" SimpleTAL-4.1/tests/PerformanceTests/HTMLTests/DeeplyNestedRepeatProfile.py0000644000175000017500000001075010036647026025613 0ustar cms103cms103""" Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Performance test cases. """ from simpletal import simpleTAL, simpleTALES, simpleTALUtils import time, StringIO, cStringIO, sys #import hotshot, hotshot.stats import profile, pstats import gc print "Disabling garbage collection!" gc.disable() performanceTemplate = """

Performance Template

Itteration title

Colour

  • All numbers

""" # 3 X 7 X 8 = 168 itterations per template expansion. thirdLevelList = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"] secondLevelList = [{"colour": "red", "num": thirdLevelList}, {"colour": "orange", "num": thirdLevelList}, {"colour": "yellow", "num": thirdLevelList}, {"colour": "green", "num": thirdLevelList}, {"colour": "blue", "num": thirdLevelList}, {"colour": "indigo", "num": thirdLevelList}, {"colour": "violet", "num": thirdLevelList}] firstLevelList = [{"title": "First", "content": secondLevelList}, {"title": "Second", "content": secondLevelList}, {"title": "Third", "content": secondLevelList}] context = simpleTALES.Context() context.addGlobal ("title", "Performance testing!") context.addGlobal ("myList", firstLevelList ) def NGTemplates (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.HTMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) def NGTemplateOverhead (count): file = file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): tempFile = StringIO.StringIO (performanceTemplate) compiler = simpleTAL.HTMLTemplateCompiler() compiler.parseTemplate (tempFile) template = compiler.getTemplate() #template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) print "Timing TAL templates" #profiler = hotshot.Profile ("profile.data") profiler = profile.run("NGTemplates (20)", "profile.data") #profiler = profile.run("NGTemplateOverhead (20)", "profile.data") #profiler.runcall (NGTemplates, 20) print "Re-enabling garbage collection." gc.enable() print "Loading profile data." #data = hotshot.stats.load ("profile.data") data = pstats.Stats("profile.data") data = data.strip_dirs() sortedData = data.sort_stats ('time', 'calls') sortedData.print_stats (25) #sortedData.print_callees ('cmdRepeat') #sortedData.print_callees ('cmdContent') data.print_callees ('cmdEndTagEndScope')SimpleTAL-4.1/tests/PerformanceTests/HTMLTests/BasicMETALTest.py0000644000175000017500000000746710347326342023223 0ustar cms103cms103""" Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Performance test cases. """ from simpletal import simpleTAL, simpleTALES, simpleTALUtils import time, StringIO, cStringIO, sys macroTemplate = """

Macros follow

A sample macro

  • First
Important Stuff, worth £££s
Table
""" performanceTemplate = """

Performance Template

Some text, with some tags that are adding to the parsing load.

This title is dynamic

Here's a table as well - lots of tags in there:
Here's a list of thing:

things

things

That should do...

""" context = simpleTALES.Context() context.addGlobal ("title", "Performance testing!") context.addGlobal ("myList", ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]) template = simpleTAL.compileHTMLTemplate (performanceTemplate) macTemplate = simpleTAL.compileHTMLTemplate (macroTemplate) context.addGlobal ("macTemp", macTemplate) def METALTime (count, template): file = simpleTALUtils.FastStringOutput() start = time.clock() for attempt in xrange (count): template.expand (context, file) end = time.clock() #print "Resuling file: " + file.getvalue() return (end - start) #print "Timing TAL templates" #result = NGTemplates (2000) #print "Result: " + str(result) + " for 2000 template expansions" # Pre-expand macros expanded = simpleTALUtils.ExpandMacros (context, template) #print expanded realTemplate = simpleTAL.compileHTMLTemplate (expanded) print "Timing macro expansion..." result = METALTime (4000, realTemplate) print "Total time %s for 4000 itterations" % (str (result)) SimpleTAL-4.1/tests/TALUtilsTests/0000755000175000017500000000000010364737165015610 5ustar cms103cms103SimpleTAL-4.1/tests/TALUtilsTests/MacroExpansionTestCases.py0000644000175000017500000000704110007246642022716 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os, codecs import StringIO import logging, logging.config from simpletal import simpleTALUtils, simpleTALES, simpleTAL macroTemplate = simpleTAL.compileHTMLTemplate (""" World is White """) #print "Macro is: %s" % str (macroTemplate) class MacroExpansionTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() entry = """Some structure: """ weblog = {'subject': 'Test subject', 'entry': entry} self.context.addGlobal ('test', 'testing') self.context.addGlobal ('mac', macroTemplate) self.context.addGlobal ('two', ["one", "two"]) self.context.addGlobal ('three', [1,"Two",3]) self.context.addGlobal ('weblog', weblog) def _runTest_ (self, template, txt, result, errMsg="Error"): realResult = simpleTALUtils.ExpandMacros (self.context, template) self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testMacroExpansionSlots (self): txt = '
HelloBlue
' template = simpleTAL.compileHTMLTemplate (txt) self._runTest_ (template ,txt ,'World is Blue' ,'Expasion with slots failed.') def testXMLMacroExpansionSlots (self): txt = '\n
HelloBlue
' template = simpleTAL.compileXMLTemplate (txt) self._runTest_ (template ,txt ,'\nWorld is Blue' ,'Expasion with slots failed.') if __name__ == '__main__': unittest.main()SimpleTAL-4.1/tests/TALUtilsTests/TemplateCacheTestCases.py0000644000175000017500000002676210011064411022465 0ustar cms103cms103#!/usr/bin/python """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os, codecs, os.path, time import StringIO import logging, logging.config from simpletal import simpleTALUtils, simpleTALES, simpleTAL HTMLTemplate1 = """

Title

""" HTMLTemplate2 = """

Title

Message

""" XMLTemplate1 = """\n

Title

""" XMLTemplate2 = """\n

Title

Message

""" TEMP_DIR="/tmp/" HTML_TEMPLATE_NAME='TemplateCacheTestCasesHtmlTemplate.html' XML_TEMPLATE_NAME='TemplateCacheTestCasesXmlTemplate.xml' EXPXML_TEMPLATE_NAME='TemplateCacheTestCasesXmlTemplate.xhtml' #print "Macro is: %s" % str (macroTemplate) class TemplateCacheTestCases (unittest.TestCase): def setUp (self): self.context = simpleTALES.Context() self.cache = simpleTALUtils.TemplateCache() self.context.addGlobal ('title', 'Cache Test') self.context.addGlobal ('message', 'Testing the cache...') def _runTest_ (self, template, txt, result, errMsg="Error"): realResult = simpleTALUtils.ExpandMacros (self.context, template) self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testHTMLTemplateCacheNoFile (self): # Remove any previously created test files name = os.path.join (TEMP_DIR, HTML_TEMPLATE_NAME) try: os.remove (name) except: pass # This should error out... try: template = self.cache.getTemplate (name) self.fail ("Expected exception trying to retrieve anavailable template") except Exception, e: # Pass! pass def testHTMLTemplateCache (self): # Remove any previously created test files name = os.path.join (TEMP_DIR, HTML_TEMPLATE_NAME) try: os.remove (name) except: pass # Ensure that time ellapses so that a ctime change is recorded time.sleep (1) tf = open (name, 'w') tf.write (HTMLTemplate1) tf.close() # Get the template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """

Cache Test

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.misses == 1, "Cache miss not recorded!") # Get the cached template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """

Cache Test

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.hits == 1, "Cache hit not recorded!") # Update the template, should cause a re-compile of the template # Ensure that time ellapses so that a ctime change is recorded time.sleep (1) tf = open (name, 'w') tf.write (HTMLTemplate2) tf.close() # Get the template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """

Cache Test

Testing the cache...

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.misses == 2, "Cache miss not recorded!") # Get the cached template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """

Cache Test

Testing the cache...

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.hits == 2, "Cache hit not recorded!") def testXMLTemplateCacheNoFile (self): # Remove any previously created test files name = os.path.join (TEMP_DIR, XML_TEMPLATE_NAME) try: os.remove (name) except: pass # This should error out... try: template = self.cache.getTemplate (name) self.fail ("Expected exception trying to retrieve anavailable template") except Exception, e: # Pass! pass def testXMLTemplateCache (self): # Remove any previously created test files name = os.path.join (TEMP_DIR, XML_TEMPLATE_NAME) try: os.remove (name) except: pass # Ensure that time ellapses so that a ctime change is recorded time.sleep (1) tf = open (name, 'w') tf.write (XMLTemplate1) tf.close() # Get the template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.misses == 1, "Cache miss not recorded!") # Get the cached template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.hits == 1, "Cache hit not recorded!") # Update the template, should cause a re-compile of the template # Ensure that time ellapses so that a ctime change is recorded time.sleep (1) tf = open (name, 'w') tf.write (XMLTemplate2) tf.close() # Get the template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

Testing the cache...

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.misses == 2, "Cache miss not recorded!") # Get the cached template template = self.cache.getTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

Testing the cache...

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.hits == 2, "Cache hit not recorded!") def testExplicitXMLTemplateCache (self): # Remove any previously created test files name = os.path.join (TEMP_DIR, EXPXML_TEMPLATE_NAME) try: os.remove (name) except: pass # Ensure that time ellapses so that a ctime change is recorded time.sleep (1) tf = open (name, 'w') tf.write (XMLTemplate1) tf.close() # Get the template template = self.cache.getXMLTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.misses == 1, "Cache miss not recorded!") # Get the cached template template = self.cache.getXMLTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.hits == 1, "Cache hit not recorded!") # Update the template, should cause a re-compile of the template # Ensure that time ellapses so that a ctime change is recorded time.sleep (1) tf = open (name, 'w') tf.write (XMLTemplate2) tf.close() # Get the template template = self.cache.getXMLTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

Testing the cache...

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.misses == 2, "Cache miss not recorded!") # Get the cached template template = self.cache.getXMLTemplate (name) outputFile = StringIO.StringIO () template.expand (self.context, outputFile) expectedResult = """\n

Cache Test

Testing the cache...

""" self.failUnless (outputFile.getvalue() == expectedResult ,"Error: template did not expand to expected result. Expected: %s got: %s" % (expectedResult, outputFile.getvalue())) self.failUnless (self.cache.hits == 2, "Cache hit not recorded!") if __name__ == '__main__': unittest.main()SimpleTAL-4.1/tests/TALUtilsTests/HTMLStructureCleanerTestCases.py0000644000175000017500000001161610007245640023747 0ustar cms103cms103#!/usr/bin/python # -*- coding: iso-8859-1 -*- """ Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Unit test cases. """ import unittest, os, codecs import StringIO import logging, logging.config from simpletal import simpleTALUtils isoText = """

Some bad html follows

This is < than that, but > than this. SimpleTAL & SimpleTALES = Simple Templating This, though, is good: £33! (That's £33!) """ uniText = unicode (isoText, "iso-8859-1") cleanResultText = """

Some bad html follows

This is < than that, but > than this. SimpleTAL & SimpleTALES = Simple Templating This, though, is good: £33! (That's £33!) """ cleanResult = unicode (cleanResultText, "iso-8859-1") class HTMLStructureCleanerTestCases (unittest.TestCase): def setUp (self): pass def _runTest_ (self, txt, result, errMsg="Error"): template = simpleTAL.compileHTMLTemplate (txt) file = StringIO.StringIO () template.expand (self.context, file) realResult = file.getvalue() self.failUnless (realResult == result, "%s - \npassed in: %s \ngot back %s \nexpected %s\n\nTemplate: %s" % (errMsg, txt, realResult, result, template)) def testCleaningISOString (self): cleaner = simpleTALUtils.HTMLStructureCleaner () result = cleaner.clean (isoText, "iso-8859-1") self.failUnless (result == cleanResult, "Clean-up failed, expected:\n%s\n Got back:\n%s\n" % (cleanResult, result)) def testCleaningUniString (self): cleaner = simpleTALUtils.HTMLStructureCleaner () result = cleaner.clean (uniText) self.failUnless (result == cleanResult, "Clean-up failed, expected:\n%s\n Got back:\n%s\n" % (cleanResult, result)) def testCleaningISOStream (self): cleaner = simpleTALUtils.HTMLStructureCleaner () isoStream = StringIO.StringIO (isoText) result = cleaner.clean (isoStream, "iso-8859-1") self.failUnless (result == cleanResult, "Clean-up failed, expected:\n%s\n Got back:\n%s\n" % (cleanResult, result)) def testCleaningUniStream (self): cleaner = simpleTALUtils.HTMLStructureCleaner () uniStream = StringIO.StringIO (uniText) result = cleaner.clean (uniStream) self.failUnless (result == cleanResult, "Clean-up failed, expected:\n%s\n Got back:\n%s\n" % (cleanResult, result)) def testCleanURL (self): goodLink = u"""link""" cleaner = simpleTALUtils.HTMLStructureCleaner () uniStream = StringIO.StringIO (goodLink) result = cleaner.clean (uniStream) self.failUnless (result == goodLink, "Clean-up failed, expected:\n%s\n Got back:\n%s\n" % (goodLink.encode ('ascii', 'ignore'), result.encode ('ascii', 'ignore'))) def testUnCleanURL (self): badLink = u"""link""" goodLink = u"""link""" cleaner = simpleTALUtils.HTMLStructureCleaner () uniStream = StringIO.StringIO (badLink) result = cleaner.clean (uniStream) self.failUnless (result == goodLink, "Clean-up failed, expected:\n%s\n Got back:\n%s\n" % (goodLink.encode ('ascii', 'ignore'), result.encode ('ascii', 'ignore'))) if __name__ == '__main__': unittest.main()SimpleTAL-4.1/README.txt0000644000175000017500000000177710364736707013475 0ustar cms103cms103simpleTAL / simpleTALES (Version 4.1) ------------------------------------- This is an implementation of the TAL and TALES specifications see (http://www.zope.org/Documentation/Books/ZopeBook/current/AppendixC.stx) Installation ------------ To install SimpleTAL under Unix: (Note that to perform the installation of SimpleTAL you will probably have to have the Python Development package installed.) 1 - Become root 2 - Run "python setup.py install" Under MacOS X: 1 - Run "sudo python setup.py install" 2 - Close the terminal program and re-open it. Notes ----- This code is made freely available under a BSD style license, see LICENSE.txt for more details. The DummyLogger.py module is used if you do not have either Python 2.3 or the logging code from http://www.red-dove.com/python_logging.html installed. Note that the unit test cases (under tests) require logging to be installed to run. Documentation ------------- Documentation on the SimpleTAL API can be found in documentation/html/ SimpleTAL-4.1/setup.py0000644000175000017500000000103107740043117013456 0ustar cms103cms103#!/usr/bin/env python import sys, os sys.path.insert(0, os.path.join(os.getcwd(),'lib')) from distutils.core import setup import simpletal setup(name="SimpleTAL", version= simpletal.__version__, description="SimpleTAL is a stand alone Python implementation of the TAL, TALES and METAL specifications used in Zope to power HTML and XML templates.", author="Colin Stewart", author_email="colin@owlfish.com", url="http://www.owlfish.com/software/simpleTAL/index.html", packages=[ 'simpletal', ], package_dir = {'': 'lib'}, ) SimpleTAL-4.1/runtests.py0000755000175000017500000000344010142751013014205 0ustar cms103cms103#!/usr/bin/env python """Regression testing framework Borrowed from http://www.diveintopython.org/ This module will search for scripts in the same directory named XYZtest.py. Each such script should be a test suite that tests a module through PyUnit. (As of Python 2.1, PyUnit is included in the standard library as "unittest".) This script will aggregate all found test suites into one big test suite and run them all at once. * Modified to use os.path.walk to find all the test scripts * Modified to find all python scripts, not just ones of the form *test.py """ import sys, os, re, unittest # If logging is available, suppress it to avoid confusion. try: import logging rootLogger = logging.getLogger () rootLogger.setLevel (logging.CRITICAL) except: pass #ensure that the module in this directory is used instead of the system one #or else we would be testing the system one and not the one with the changes :) import sys sys.path.insert(0, os.path.join(os.getcwd(),'lib')) print "System path is: " + str (sys.path) def path_vistor(files, dirname, names): """Visits each file in the and appends the filename to the given list""" if (dirname.find ("PerformanceTests") > 0): return for name in names: files.append(os.path.join(dirname, name)) def regressionTest(): #Find all the files to run files = [] os.path.walk("tests", path_vistor, files) test = re.compile(".*\.py$", re.IGNORECASE) files = filter(test.search, files) #load each test into the testsuite filenameToModuleName = lambda f: os.path.splitext(f)[0] moduleNames = map(filenameToModuleName, files) modules = map(__import__, moduleNames) load = unittest.defaultTestLoader.loadTestsFromModule return unittest.TestSuite(map(load, modules)) if __name__ == "__main__": unittest.main(defaultTest="regressionTest") SimpleTAL-4.1/LICENSE.txt0000644000175000017500000000273510364736707013615 0ustar cms103cms103SimpleTAL 4.1 -------------------------------------------------------------------- Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SimpleTAL-4.1/documentation/0000755000175000017500000000000010364737164014632 5ustar cms103cms103SimpleTAL-4.1/documentation/html/0000755000175000017500000000000010364737164015576 5ustar cms103cms103SimpleTAL-4.1/documentation/html/api-simpletal.html0000644000175000017500000000760610347331422021222 0ustar cms103cms103 SimpleTAL API: simpleTAL Module

SimpleTAL API: simpleTAL Module

Documentation on how to use the simpleTAL Module.

simpleTAL

Two helper functions are provided for convenience, one for compiling HTML templates, and one for compiling XML templates.  If an error is encountered during compilation (for example mismatched TAL tags or bad syntax) an TemplateParseException will be thrown.

compileHTMLTemplate (template, inputEncoding="ISO-8859-1", minimizeBooleanAtts=0)

Compiles the passed in HTML template into an instance of the 'Template' class.  The template object should be either a string containing the template, or a file-like object.  The inputEncoding specifies the encoding that the template was written using and deafults to iso-8859-1.  The minimizeBooleanAtts flag controls whether HTML boolean attributes (e.g. <img ismap>) should be written out in minimized form.  See below for details of how to use the Template class.

compileXMLTemplate (template)

Compiles the passed in XML template into an instance of the 'Template' class.  The template object should be either a string containing the template, or a file-like object.  The XML template must be a well formed XML document.  The character set will be determined from the prolog of the template or be assumed to be utf-8.  See below for details of how to use the Template class.

compileDOMTemplate (dom)

Compiles an XML template that is stored as a DOM tree.  This requires PyXML to be installed to function. 

Template Instances

The compiled templates contain all of the logic required to be able to expand themselves for a given context.  They can be kept around and reused as often as required, there is no need or benefit to re-compiling them unless the underlying template changes.  They have one method of interest as part of the external API:


def expand (self, context, outputFile[,outputEncoding] [,docType][,suppressXMLDeclaration])

This method will expand the template, using the simpleTALES.Context object provided, and write the output into the given file-like object.  If the template is a HTML template then the result will, by default, be encoded in iso-8859-1.  If no outputEncoding is specified and the template is an XML template then it will default to utf-8.

The docType and suppressXMLDeclaration variables apply only to XML Templates. 

Python's support for XML does not currently extend to the LexicalHandler API, which is required for an application to be able to read an XML documents DOCTYPE.  If pyXML is installed SimpleTAL will make use of it to determine the XML DOCTYPE, otherwise the doctype must be passed as a named variable to the expand method.

For example to produce a valid strict XHTML document without pyXML use:


template.expand (context, outputFile, docType='<!DOCTYPE html  PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">')

If the suppressXMLDeclaration is set to true then the XML Declaration will not be included in the output (required for XHTML in IE6).

Back to SimpleTAL API

PubTal Version

SimpleTAL-4.1/documentation/html/index.html0000644000175000017500000000317110347331422017561 0ustar cms103cms103 SimpleTAL

SimpleTAL

Welcome to SimpleTAL

SimpleTAL is a stand alone Python implementation of the TAL, TALES and METAL specifications used in Zope to power HTML and XML templates. SimpleTAL is an independent implementation of TAL; there are no dependencies on Zope nor is any of the Zope work re-used.

A mailing list exists for discussion of SimpleTAL and support questions.

Feedback, feature enhancements and bug fixes will all be gladly received!

PubTal Version

SimpleTAL-4.1/documentation/html/api-simpletales.html0000644000175000017500000000726110347331422021547 0ustar cms103cms103 SimpleTAL API: simpleTALES Module.

SimpleTAL API: simpleTALES Module.

Documentation on how to use the simpleTALES Module.

simpleTALES

The only external class in this module is the Context class.

Context ([options] [,allowPythonPath])

Creates a new Context object, used by SimpleTAL when expanding a template.  The options variable, if passed, will be made available as a global variable under the name "options" as per the TALES specification.

By default Python TAL paths (e.g. 'python: 1 + 2') are not allowed.  If you require them, and you completely trust the authors of the templates, they can be enabled by passing in allowPythonPath=1.

Context.addGlobal (name, value)

Adds the value to the context under name.  Value can either be a fundamental python data type or a callable object.  For example, take the code:


class Test:
	def __init__ (self, val):
		self.val = val
		
	def getResult (self):
		return str (self.val + 4)
		
test = Test (10)

context = SimpleTALES.Context()
context.addGlobal ("number14", test.getResult)
context.addGlobal ("data", {"one": {"blue": ("Cat", "Dog", "Mouse"), "pink": ["One"]}})

The affect of this context is shown for several different TALES expressions:


<b tal:define="test1 nocall:number14"></b>

The method 'getResult' is bound to the local variable test1.


<b tal:define="test2 number14"></b>

The local variable test2 is assigned the value "14"


<b tal:repeat="pets data/one/blue"><i tal:replace="pets"></i></b>

Prints out <b>CatDogMouse</b>

All strings placed into the context, and all strings returned by callable objects should be unicode strings.  This allows the rendering of the template into different character sets  without requiring any code changes.

PathFunctionVariable (callableObject)

This class wraps a callable object (e.g. function) so that it can receive part of a TAL path as it's argument.  To use this simply create a new instance of the PathFunctionVariable and then place this into the Context (see above).  The path passed to the function is that part of the path not already used.  For example if the function "helloFunc" is placed in the Context the path "helloFunc/an/example" results in the string "an/example" being passed to the function.

CachedFuncResult (callableObject)

This class wraps a callable object (e.g. function) so that the callable is only called once.  In normal SimpleTAL operation any function placed into a Context will be called multiple times during template expansion.  To ensure that it is only called once simply wrap in the CachedFuncResult object first.

clearCache ()

Clears the cache.  Use this to clear the cache between multiple template expansions if the callable should be executed once per template expansion.

Back to SimpleTAL API

PubTal Version

SimpleTAL-4.1/documentation/html/notes.html0000644000175000017500000001570410347331422017607 0ustar cms103cms103 Notes on SimpleTAL

Notes on SimpleTAL

Notes, known limitations, and differences between SimpleTAL and Zope's ZPT.

Notes

Some notes on aspects of SimpleTAL that might require a little explanation.  If there is something you feel should be included in here, please let me know.

HTML and XHTML Templates

As a bug fix version 2.1 of SimpleTAL now processes HTML templates slightly differently to XML templates.  In the HTML 4.01 specification there are several elements (e.g. <img>) for which end tags are forbidden.  This would normally cause a problem with TAL, because all tags that have TAL attributes on them must be closed.  To solve this problem SimpleTAL has been modified to:

  • Allow TAL attributes on all HTML elements that forbid close tags, and process them despite the lack of close tag
  • When compiling a HTML template issue a warning if a close tag is present for elements that are forbidden to have close tags.  (Only supported if logging is installed)
  • To suppress the output of close tags for elements that are forbidden to have close tags.

These changes ensure that a HTML template can still be a valid HTML document, even if TAL needs to be used on elements that forbid end tags.  Additionally the output from the expanded template will also be valid HTML, in that the end tags will be suppressed even if present in the template.

As a consequence of this change it is important that any XHTML templates are handled as XML rather than HTML, i.e. by calling compileXMLTemplate to compile the template.

Character set encoding

SimpleTAL fully supports international character sets, providing all of the encoding options that Python supports.  To painlessly support the correct conversion between character sets, just follow these simple rules:

  • When calling compileHTMLTemplate pass in the character set encoding the template was written in.
  • A template passed to compileXMLTemplate must be a well formed XML document.  If it's not in UTF-8 then ensure the prolog of the document specifies what format it is in.
  • Convert to unicode all strings passed into SimpleTALES.Context
  • When calling template.expand, pass in the encoding you would like the template output to be in.

Structured Content

When content is included into a template using 'tal:content' or 'tal:replace' the content is by default treated as text.  This means that the '<', '>' and '&' characters will be automatically escaped so that they appear in the rendered template correctly.

When using the 'structure' keyword, however, SimpleTAL will pass the content straight through into the template with no escaping.  As such it's important to realise that the content placed into a template in such a way can affect the validity of the output.  For example if you take user input that contains HTML markup it's important to ensure that the markup is valid HTML, otherwise the resulting template output will not be valid.  In order to assist in doing this I've put together a class (HTMLStructureCleaner) in simpleTALUtils that will escape any stray  '<', '>' or '&' characters present while leaving all elements and attributes intact.

The restriction in SimpleTAL 1.x when including structured content into an XML template is now removed - the structure is not re-parsed, and so does not have to be valid XML.

Object Attributes versus Key Values

When adding a mapping object (e.g. a Dictionary) to the Context, care should be taken on the naming conventions used within the mapping.  When SimpleTAL/ES resolves a path, it will first look for attributes on the object with that name, before trying to treat the object as a mapping object.  What this means in practice is that paths which match object attributes (e.g. methods) will never select the values given in the mapping.  As an example of this consider the following:


Template:  <p tal:repeat="item dict/items"><b tal:replace="item"></b></p>

Context:  
myDict = {'items': [1,2,3]}
Context.addGlobal ("dict", myDict)


You would expect the output from this to be:

<p>1</p><p>2</p><p>3</p>

However this is not what happens.  Instead the variable "item" will be set to the output of "myDict.items()" - i.e. it will call the Python dictionary method 'items()'.

I have considered changing this so that mapping checks are made first in path resolution rather than attribute lookups.  When I checked the Zope 2.5 behaviour however, I found that it works the same way as SimpleTAL, so for now I've left it to be consistent with Zope.

Using < and > in TAL Paths

When using the 'python:' path type, care must be taken with the use of the less than (<) and greater than (>) signs.  These must be escaped in the same way as all other HTML markup.  For example:

use: <div tal:condition="python: a &lt; b">Conditional Text</div>
instead of: <div tal:condition="python: a < b">Conditional Text</div>

Known limitations

  1. Repeat Variables do not support 'first' and 'last'.
  2. When using 'not:' on an empty expression the result will be true rather than an error.
  3. Path type 'python:' is not supported by default.  You can enable this by passing allowPythonPath=1 to the Context constructor.  Note that this should only be used when the authors of the templates are completely trusted, the code included in the 'python:' path can do anything.
  4. TAL markup "on-error" is not yet supported.
  5. HTML Templates will have duplicate attributes if an attribute is added using "tal:attributes" and the name is in upper case.  The cause of this is the HTMLParser implementation, which always converts attributes to lower case.

Known differences

Non-existent path types, e.g. '<b tal:content="total: $totalAmount"></b>' are not supported.  In Zope, this results in the path being interpreted as a string - in simpleTAL/ES the result will be an error.

Back to SimpleTAL

PubTal Version

SimpleTAL-4.1/documentation/html/api-simpleelementtree.html0000644000175000017500000000573710347331422022756 0ustar cms103cms103 SimpleTAL API: simpleElementTree Module.

SimpleTAL API: simpleElementTree Module.

Documentation on how to use the simpleElementTree Module.

simpleElementTree

This module provides optional integration with ElementTree, allowing XML documents to be parsed and placed directly into the Context.  The contents of the XML document can then be accessed using an sub-set of XPATH from within TAL templates.

parseFile (file)

This function takes one parameter, which should be either a file-like object or a string holding the name of a file on the filesystem.  The file is read, the XML it contains is parsed, and an instance of simpleTALES.ContextVariable is returned.

The returned ContextVariable can then be added to the Context using addGlobal in the normal way, e.g.

xmlTree = simpleElementTree.parseFile (file="input.xml")
context = simpleTALES.Context(allowPythonPath=1)
context.addGlobal ("input", xmlTree)

ElementTree Paths

The Context variable provided by parseFile provides the following syntax for path access in TAL:

  • Accessing the variable directly returns the Text value for this node.
  • Accessing variable/find/path returns the first node to match the path, as supported by ElementTree (see XPath Support in ElementTree).
  • Accessing variable/findall/path returns a list of nodes that match the path, as supported by ElementTree (see XPath Support in ElementTree).
  • Accessing variable@name returns the XML attribute "name".
  • Accessing variable/anotherElement is a short-cut for variable/find/anotherElement.

Here are some examples:

<html>
  <body>
    <h1 tal:attributes="class input/title/@type" tal:content="input/title">Title here</h1>
    <ul>
      <li tal:repeat="note input/findall/.//note">
      <b tal:condition="note/@type" tal:replace="string: Note (${note/@type}) - $note and then some"></b>
      </li>
    </ul>
  </body>
</html>

PubTal Version

SimpleTAL-4.1/documentation/html/api-simpletalutils.html0000644000175000017500000001044310347331422022274 0ustar cms103cms103 SimpleTAL API: simpleTALUtils Module.

SimpleTAL API: simpleTALUtils Module.

Documentation on how to use the simpleTALUtils Module.

simpleTALUtils

This module holds optional classes and functions that might be of use while using SimpleTAL, but are not required by SimpleTAL directly.

def ExpandMacros (context, template, outputEncoding="ISO-8859-1")

This function can be used to expand a template which contains METAL macros, while leaving in place all the TAL and METAL commands.  Doing this makes editing a template which uses METAL macros easier, because the results of the macro can be seen immediately.

The macros referred to by the passed in template must be present in the context so that their contents can be referenced.  The outputEncoding determines the encoding of the returned string, which will contain the expanded macro.

FastStringOutput

This class implements a very restricted File type object that can return a string containing all data written into it.  Unlike StringIO, FastStringOutput only supports write operations, and so is faster.  Only two methods are supported: write and getvalue.

write (data)

Used by SimpleTAL to write the expanded template.

getvalue ()

Use this to retrieve a string with the resulting output.

TemplateCache

This class implements a cache for compiled templates which automatically invalidates entries when their template file changes.  The instance has one public method: getTemplate

getTemplate (name, inputEncoding="ISO-8859-1")

This method will return a compiled template from the file 'name'.  If the file ends in '.xml' it will be compiled using simpleTAL.compileXMLTemplate, otherwise it will be compiled as a HTML template.  If the method is called again it will check to see whether the file 'name' has changed since the last call, and if it has it will re-compile the template,otherwise it will return the cached version.

HTML Templates will be taken as being stored in the "inputEncoding", XML templates ignore this parameter.

getXMLTemplate (name)

This method will return a compiled XML template from the file 'name'.  This works identically to getTemplate as described above, except that it always treats the template as XML.

HTMLStructureCleaner

This class can be used to encode any stray special characters within a given string or file-like object.  Its intended use is in preparing data that will be placed into a Context object and then included in a template using the 'structure' keyword.  The class uses the Python SGML parser to determine what tags are present, so any HTML markup will be left intact.  As an example, take the content:

This is some <b>bad</b> html that is < than great!

If this was included in a template in its current state the result would be bad markup.  Once cleaned by this class, the result would be:

This is some <b>bad</b> html that is &lt; than great!

The class has one external method:

def clean (self, content, encoding=None)

The content should be either a string or a file-like object.  If the string is a unicode string (u"") it will be cleaned as is.  If the string is an ordinary string then the encoding must be supplied, and it will first be converted to unicode.  If the content object is a file-like object then it will be converted only if the encoding is supplied.

The call returns a unicode string that has the '<', '>' and '&' characters encoded.

Back to SimpleTAL API

PubTal Version

SimpleTAL-4.1/documentation/html/tal-guide.html0000644000175000017500000002502410347331422020326 0ustar cms103cms103 TAL/TALES & METAL Reference Guide

TAL/TALES & METAL Reference Guide

A guide to using TAL, TALES, and METAL.

Introduction

This is a simple reference guide to the TAL and TALES languages.  Formal language specifications are hosted by Zope: TAL, TALES, and METAL.

TAL Commands

TAL consists of seven different commands (highest priority first): define, condition, repeat, content, replace, attributes, and omit-tag.  Commands are attributes on HTML or XML tags, e.g. <div tal:content="article">Article goes here</div>

tal:define

Syntax: tal:define="[local | global] name expression [; define-expression...]

Description: Sets the value of "name" to "expression".  By default the name will be applicable in the "local" scope, which consists of this tag, and all other tags nested inside this tag.  If the "global" keyword is used then this name will keep its value for the rest of the document.

Example: <div tal:define="global title book/theTitle; local chapterTitle book/chapter/theTitle">

tal:condition

Syntax: tal:condition="expression"

Description:  If the expression evaluates to true then this tag and all its children will be output.  If the expression evaluates to false then this tag and all its children will not be included in the output.

Example: <h1 tal:condition="user/firstLogin">Welcome to this page!</h1>

tal:repeat

Syntax: tal:repeat="name expression"

Description:  Evaluates "expression", and if it is a sequence, repeats this tag and all children once for each item in the sequence.  The "name" will be set to the value of the item in the current iteration, and is also the name of the repeat variable.  The repeat variable is accessible using the TAL path: repeat/name and has the following properties:

  1. index - Iteration number starting from zero

  2. number - Iteration number starting from one

  3. even - True if this is an even iteration

  4. odd - True if this is an odd iteration

  5. start - True if this is the first item in the sequence

  6. end - True if this is the last item in the sequence.  For iterators this is never true

  7. length - The length of the sequence.  For iterators this is maxint as the length of an iterator is unknown

  8. letter - The lower case letter for this iteration, starting at "a"

  9. Letter - Upper case version of letter

  10. roman - Iteration number in Roman numerals, starting at i

  11. Roman - Upper case version of roman

Example:

<table>
<tr tal:repeat="fruit basket">
<td tal:content="repeat/fruit/number"></td>
<td tal:content="fruit/name"></td>
</tr>
</table>

tal:content

Syntax: tal:content="[text | structure] expression"

Description:  Replaces the contents of the tag with the value of "expression".  By default, and if the "text" keyword is present, then the value of the expression will be escaped as required (i.e. characters "&<> will be escaped).  If the "structure" keyword is present then the value will be output with no escaping performed.

Example: <h1 tal:content="user/firstName"></h1>

tal:replace

Syntax: tal:replace="[text | structure] expression"

Description: Behaves identically to tal:content, except that the tag is removed from the output (as if tal:omit-tag had been used).

Example: <h1>Welcome <b tal:replace="user/firstName"></b></h1>

tal:attributes

Syntax: tal:attributes="name expression[;attributes-expression]"

Description:  Evaluates each "expression" and replaces the tag's attribute "name".  If the expression evaluates to nothing then the attribute is removed from the tag.  If the expression evaluates to default then the original tag's attribute is kept.  If the "expression" requires a semi-colon then it must be escaped by using ";;".

Example: <a tal:attributes="href user/homepage;title user/fullname">Your Homepage</a>

tal:omit-tag

Syntax: tal:omit-tag="expression"

Description: Removes the tag (leaving the tags content) if the expression evaluates to true.  If expression is empty then it is taken as true.

Example: <p><b tal:omit-tag="not:user/firstVisit">Welcome</b> to this page!</h1>

TALES Expressions

The expressions used in TAL are called TALES expressions.  The simplest TALES expression is a path which references a value, e.g. page/body references the body property of the page object.

path

Syntax: [path:]string[|TALES Expression]

Description: A path, optionally starting with the modifier 'path:', references a property of an object.  The '/' delimiter is used to end the name of an object and the start of the property name.  Properties themselves may be objects that in turn have properties.  The '|' ("or") character is used to find an alternative value to a path if the first path evaluates to 'Nothing' or does not exist.

Example: <p tal:content="book/chapter/title | string:Untitled"></p>

There are several built in paths that can be used in paths:

  1. nothing - acts as None in Python

  2. default - keeps the existing value of the node (tag content or attribute value)

  3. options - the dictionary of values passed to the template (through the Context __init__ method)

  4. repeat - access the current repeat variable (see tal:repeat)

  5. attrs - a dictionary of original attributes of the current tag

  6. CONTEXTS - a dictionary containing all of the above

exists

Syntax: exists:path

Description: Returns true if the path exists, false otherwise.  This is particularly useful for removing tags from output when the tags will have no content.

Example: <p tal:omit-tag="not:exists:book/chapter/title" tal:content="book/chapter/title"></p>

nocall

Syntax: nocall:path

Description: Returns a reference to a path, but without evaluating the path.  Useful when you wish to define a new name to reference a function, not the current value of a function.

Example: <p tal:define="title nocall:titleFunction" tal:content="title"></p>

not

Syntax: not:tales-path

Description: Returns the inverse of the tales-path.  If the path returns true, not:path will return false.

Example: <p tal:condition="not: user/firstLogin">Welcome to the site!</p>

string

Syntax: string:text

Description:  Evaluates to a literal string with value text while substituting variables with the form ${pathName} and $pathName

Example: <b tal:content="string:Welcome ${user/name}!"></b>

python

Syntax: python:python-code

Description:  Evaluates the python-code and returns the result.  The python code must be properly escaped, e.g. "python: 1 < 2" must be written as "python: 1 &lt; 2".  The python code has access to all Python functions, including four extra functions that correspond to their TALES commands: path (string), string (string), exists (string), and nocall (string)

Example: <div tal:condition="python: path (basket/items) &gt; 1">Checkout!</div>

METAL Macro Language

METAL is a macro language commonly used with TAL & TALES.  METAL allows part of a template to be used as a macro in later parts of a template, or a separate template altogether.

metal:define-macro

Syntax: metal:define-macro="name"

Description:  Defines a new macro that can be reference later as "name".

Example:  <div metal:define-macro="footer">Copyright <span tal:content="page/lastModified">2004</span></div>

metal:use-macro

Syntax: metal:use-macro="expression"

Description:  Evaluates "expression" and uses this as a macro.

Example:  <div metal:use-macro="footer"></div>

metal:define-slot

Syntax: metal:define-slot="name"

Description:  Defines a customisation point in a macro with the given name.

Example: 

<div metal:define-macro="footer">

<b>Standard disclaimer for the site.</b>

<i metal:define-slot="Contact">Contact admin@site.com</i>

</div>

metal:fill-slot

Syntax: metal:fill-slot="name"

Description:  Replaces the content of a slot with this element.

Example: 

<div metal:use-macro="footer">

<i metal:fill-slot="Contact">Contact someone else</i>

</div>

PubTal Version

SimpleTAL-4.1/documentation/html/api.html0000644000175000017500000000521310347331422017222 0ustar cms103cms103 SimpleTAL API

SimpleTAL API

Documentation on how to use the SimpleTAL API.

SimpleTAL consists of three different modules: simpleTAL, simpleTALES, and simpleTALUtils.  The API for each of these modules is documented separately:

  • simpleTAL - contains functions to compile HTML and XML templates into objects ready for use.
  • simpleTALES - contains the Context class which provides the environment in which templates are expanded.
  • simpleTALUtils - optional utility functions for dealing with SimpleTAL templates.
  • simpleElementTree - optional integration with ElementTree allowing XML documents to be parsed and placed directly into the Context instance.

International character support

SimpleTAL supports all character sets that Python supports.  To use non-ASCII characters first convert them to Unicode strings prior to placing them into the Context object.

Logging in SimpleTAL

SimpleTAL uses the logging library, which is shipped as part of Python 2.3, to handle logging of debug messages, warnings, and errors.  When used on a system that has no logging library SimpleTAL will suppress all logging messages.

To control the output of logging messages from SimpleTAL it is necessary to retrieve the logger objects for each module, which can be done using:

simpleTALLogger = logging.getLogger ("simpleTAL")
simpleTALESLogger = logging.getLogger ("simpleTALES")

The configuration of these loggers can then be adjusted as described in the logging library documentation.  For example to stop warnings being logged:

simpleTALLogger.setLevel (logging.ERROR)
simpleTALESLogger.setLevel (logging.ERROR)

Back to SimpleTAL

PubTal Version

SimpleTAL-4.1/documentation/style/0000755000175000017500000000000010364737164015772 5ustar cms103cms103SimpleTAL-4.1/documentation/style/site.css0000644000175000017500000000203510101613234017424 0ustar cms103cms103.navbar { margin-top: 2em; text-align: center; } h1 { margin-bottom: 0px; padding-bottom: 0px; } #subject { font-style: italic; margin-top: 0px; padding-top: 0px; } #footer { font-size: smaller; margin-top: 2em; } #footer p { padding: 0px; margin: 0px; } #version { margin-top: 2em; font-size: smaller; float: right; } code { font-size: small; margin-top: 0em; white-space: pre; font-family: monospace; overflow: auto; } p + code { margin-top: 0em; } /* To work around the block effect of using
 as well as  - more IE bugs  */
pre {
	display: block;
	margin-top: 0px;
	margin-bottom: 0px;
	margin-left: 30px;
	line-height: 100%;
}

* Paragraphs in tables are small */
table p {
	margin: 0px;
}

/* Ordinary tables have borders. */
table {
	border: 1px solid black;
}
td {
	border: 1px solid black;
}

/* Nested tables do not. */
td table {
	border: 0px;
}

td table td {
	border: 0px;
}

/* Lists with paragraphs in them should not be spread out. */
li p {
	margin: 0px;
}


.configOptions {
	margin-left: 2em;
}
SimpleTAL-4.1/documentation/documentation.config0000644000175000017500000000064110101613234020647 0ustar  cms103cms103# Configuration file for SimpleTAL Documentation
#
# If SiteConfig is used it must be the first entry in the config file.
# 
# Use ignore-filter to specify regular expressions for files that should not be treated
# as content (examples shown here are files in CVS directories and backup files)

content-dir src
dest-dir html
template-dir templates
ignore-filter .*\.svn.*
ignore-filter .*~$

SimpleTAL-4.1/documentation/src/0000755000175000017500000000000010364737164015421 5ustar  cms103cms103SimpleTAL-4.1/documentation/src/api.txt0000644000175000017500000000401710202213623016711 0ustar  cms103cms103title: SimpleTAL API
subject: Documentation on how to use the SimpleTAL API.

SimpleTAL consists of three different modules: simpleTAL, simpleTALES, and simpleTALUtils.  The API for each of these modules is documented separately:
  • simpleTAL - contains functions to compile HTML and XML templates into objects ready for use.
  • simpleTALES - contains the Context class which provides the environment in which templates are expanded.
  • simpleTALUtils - optional utility functions for dealing with SimpleTAL templates.
  • simpleElementTree - optional integration with ElementTree allowing XML documents to be parsed and placed directly into the Context instance.

International character support

SimpleTAL supports all character sets that Python supports. To use non-ASCII characters first convert them to Unicode strings prior to placing them into the Context object.

Logging in SimpleTAL

SimpleTAL uses the logging library, which is shipped as part of Python 2.3, to handle logging of debug messages, warnings, and errors. When used on a system that has no logging library SimpleTAL will suppress all logging messages. To control the output of logging messages from SimpleTAL it is necessary to retrieve the logger objects for each module, which can be done using:
simpleTALLogger = logging.getLogger ("simpleTAL")
simpleTALESLogger = logging.getLogger ("simpleTALES")
The configuration of these loggers can then be adjusted as described in the logging library documentation. For example to stop warnings being logged:
simpleTALLogger.setLevel (logging.ERROR)
simpleTALESLogger.setLevel (logging.ERROR)
Back to SimpleTAL SimpleTAL-4.1/documentation/src/tal-guide.sxw0000644000175000017500000003025610326747752020047 0ustar cms103cms103PK…ŽW3á¥19mimetypeapplication/vnd.sun.xml.writerPK…ŽW3Configurations2/PK…ŽW3 Pictures/PK…ŽW3 layout-cachecd`d(0d``àd``1x$@"!0Ž;aSdPK¥©½ú$5PK…ŽW3 content.xmlÕ]Ýr7²¾?O¨r\v•È%9¶©X{lGÙxKÊQ…ônκ\)p$q43˜`$q7[•78çbo²7ûhy’íÆÏüqøO‰tU*Ö ÝÆ×F#}ý»û($·,•\į:í£Âb_<½>øÐÿ¶õòàwçÿñµ¹Ïºð³ˆÅªå‹XÁ¿zDzkZ_Œ•Jºž'›Wm‘Ž¼ã££#Ï<ØRMÂùôšÂ‘+v¯æR#ANL xk G¤ôn.5€5ýPäÔwwwí»MÙyõê•÷cïÒûV¤Íu¹y|3“^·æzø9]’¥¡¦ |… .½N»ã9Úˆ):Wg$pÄq X:ˆTÑŠÁåí¨Ik33·¹-ü1MçOŒ¦(L},0õI‘ªñ ˽ô® Qÿï겘—4šË òñù)OæknH\!ÄêÓ¼z¦N½»”+––Èý¹ä> ý܈"š15(Zìá’G-gt8öLsN,ƒ™¬¼ºìùcÑ‚˜/&nñX*£el©†ûÒ©%µŸ»Xc&ÀËŸ‡rZóCyþµkñ†˜ç˜Fàø=EÓÞ$ˆð€ …!Òˆ‡“j[‰¢T2ÀÃ}KšVo¾Œ>‹ˆv¦˜†Cr™ù< ’Æò<¡‰gæ éÁ+óÂ5¼I9 ɇ˜CÔeäªgÞ.Òà-WR¥ŒFä,5lÉ•ˆÅ´J†ß,z+­l Ó±5b1K93½Ò¸B’påƒwù= ÖдÁp3µlPÐJ¿¥`9Œä øî÷äŠÇþXK>+ò‡YÒ§«uÕ³ÍÕ×E¯?Ìj¸œÑà^›§’œëù‚f©÷{¡ÆÜŸêe^7¨gÞÎhp¯ÍSY½&Aoâ€†Ì ëÃûe0ÞàŽÆÚdö‡‡óÔ ”«ãn¸¬o íÞ›Â(w]Á,›¹o]CyÇ¥\¤¡×° ØW4S0FÅý–f‘/úÿ•¡\wr1Vt”Òdìàæ·ú¡eˈ`âhB.«—Ç…¤?Ô“¹RO6“ê8')d$©âLæ“n³÷SÝêBjXQÉi<§ÝQ²ûœ§·4ŒÙcêOÍŸM©Ê ¹?[Õ™í¹ª–byU§&}IUw`Õ)¤˜íÔL\ÜSµŸƒ9]q0=‘¥>#ý]ϪYòñÊ .;e‚rüÐ BïîˆiÄ÷Y;ñÐÖêýèë¸4‡ã9œlÌátcÏ7æðÕÆ^lÌáåÆ^mÌ¡s4‹…WƒíÏÄñ C¦ê8Öeo}kÈÌN–µ’dà_mÛË0Ô[»×¿ýãÿšœ[FÈg0} ùü¨ƒƒÜœìÂ{4þÓŒ¿0ð|68ÞŸñµ“ñï^ìÂ'í£}²ÁËÝØàùÑù«]Øàt¿p€Y×.Œð@X1o<ÙUÞøË¿–Χ¾:y>Ïl¶ù3Ì)—¶A§}übL°Í”r¼:Ú#l3­\ÚRœî ¶™U.m‚“vçÅÁ`›™å 6x9w1}\l3±\Ú§íÓÓ=‚Á6Ë¥mð¼}ôrL°Í¼r¼èì ¶šW.m„¯ÚM§•ÞÌCBÛ€‡]Öx’ý%c1èlϧ_í.“NZ"S!YËÚÕ™Õèý> 3©R)â¼Øº.³¾;ÝŒ ü¸1“oìu¸|2­6žFØwŒâ­BâRÓ…¡¾¹´¦¡ç‡$û¢×(ýDK¿è•ä£1@‡«‹Y8:8×¹mûS²àïDÁ0äj€ƒŽ>Œ$bH$Þ¶#jØ)h3LÉÓ1™T$I¹H¹š!O¥zÖ%‚o"›€ãøµ £J¿ÂKµúE±ì¬TÊ™bÒØ\D\µ•ëÆ¡1ZГïúW—D¤äGø:Ö.º&4žkå4ôI¨Î~ }îÕíõo¿ü“BŒ÷C?=©³7扌ƒ°—ݰхu¾ü„T' ð‡í4]½I¬è}—ÝQÿ¡ðÁ×&£P hø‰`?Âî“”I¼›H>žÙYj/Ûíö§ÚæËþ†™ ŒÐ·Kz ð‚‘è–†Cäüö˯ØÔÁ O…(xWšß·T†f¡Ò ´®w< ɦ;IBðXu30Ò£C¾Ò—;$wcî+¨U6Sx è›jŒ˜é0Ǩ%-)ô~è$û¡¨6¹i€±8“ÐbÓ·Ð÷†±„pÐÀزÍ'E/†§»^^wîù–¶×ºë»À…Q\=BÜx SŸÎˆ ä<‰bi¿ °orJëÛÄ}(Ö†~ÎGYÁÙúˆ®Ã¡ä> '˜b Âå7ÍX ¥tˆÌÃBgiÈ=’LMÃmÿ! åòb¡Pý0 4Ê5s+ôP7îLÏxLêéåáRŒxl!ô'ÂjbSXiÉ:¶Ž;Û†˜Y€ÖÆ—éŽC©EÒí ì"Ÿïz˜4Œa¦mhsQ·¦ÊiP䀘&bbâ#ä"‘ƒƒãRBaßD<²Z%n­D5²ãC™›Ÿ¥:7ÀÿÔ,øZkÐ7”¢ê¶«Qœ¸»5j­š‹ï£Að)“8Ç.ãM¨wmO‹@¹cjV¢¡C™<)ömÝÚlAH‡=há†jzâj·9p̳gùºspÎã€ÝƒÿŸ¼w¶ ö¶‰T˜U€2ÃTDä¯,…*^£Œ%eZþKyr±©L¢Ä>?n\œ* ^ЖCaKEÌ’‡MÛ§íÖ(P #Y£?m˼qóhQTHgÈ®îõ¬ID*óÞ1ÌLª—«-©²x¤ÆFSÔÌäg‘iæ«,eŸ¶¾5øÁÊÌâhEK·ÆbÖÇa¹¬^—Zò…­t E­Î,t±Îî=k;€Ò~Õm`4¹†µ<…åŸCp&Oyr¬6z‹ó"¬Æ6Îm½÷³ÆJLnâf%ë:V7ÛÆH±0"ôŽ€¥M´—ó‹Ã*@.öÄ9ÅŽøûš·?ÈÞ!´Éæû?,àß²1½˜ó,Ä}ØÇNô¾³0Û!ˆòY‚SMUŽP‹Ä- MïqŠby 0D€ WU†½a°¨`ïÙãÔCʵ|3¨[u6‹¢’¾62  ¥‘gEs©ÌüiÛ%]ܨÇ<ÝÒrì„Ù7_jÊâ ¡TðX¾ã—Á¦a"NÁ® Œ¥åY¼Kup[·KùˆÇX³mRäÝ€G4̪9l86¤ˆ·|ŠØˆL/ʤ*ÇïÁÄZ€ÏÙZg¥›çù—uõ4Û`z™ž+¹m*žÚítcðI,;ž™’¸qÄ, K)ØÿGò¥Ó®HgxâV¼ÒEªµ}Ò1Øb%üéÜÈÓÑ[W‡ÓG*6D?s żZy­%J@3‹5Éa©ëš7ð3Ö°çg‹ÂÄÅñÁÔA8é À¹änËe׌b!X¥R¾"O/zä"Ÿž‘+ °gf<6÷RÈdagîºB‰°V 6§íœê„¦Žõ_{ú—ß‹À÷:\â,8ŸL4¨‡š—­W扠ÆvWJž¸,{1Àþì§}‡²–ÏÔEðO‘ã?×§mƒ#Ý7Ú¾‡Dèg‘åµ |׉€9Kí/Ðʸß)Q™“²á°jkLVnÓÑ3ÿÀbòËoÅ¡+dðqP9PÈYé_uíÖM“Šô%i×¥›\cIb€‹èDo4CiM¬²fiL0=-$4jþ³Õü)¬›ëÏŠOyCŽG5×Bhˆ©â·nßÖ6’šZ³~S‰¤FÒ÷&±bEJ¼£€g€ìžËG9ïKê[›ê©±^Wõ†ôì~ˆõ‹ œã&«–Œò]ûxsCǼҒBJ5Èx¨ç­kgÛ>–‡+Ýң܂ó£“UÎŽWKB±„J«°D~/b}Kâz¢ÆùIHMéõ«¶«hçÒXÔ/EH›€TºRFˆñ7Í<Å´ÂýÆ=€q‘âjÚg»Œ RF_áàúMu(ÓúáŠ,­oëœò˜<Æ5NE62¡òŽ€ûÓO<æê§ŸHÄ`¢‚Ξ¶á)kå@·~ûT2V*ïTs„ˆ™Z›’|ÏT¾+6¬ ¬H°w¢û»ÿþ¾ñc¿7­>úxàq ÞZ2jÓäßK*<óhd¥tDûêz…Óµ;ÏýN%áY=ê×¶'¸@›-‚[6W–>¦ÖŽêÐÞÆÑ·É^^0癉¾=˜…4 qÍ`?©Oue@ïšpÇdämuÒíöu‹.]êl#.&¶W³ÔõÉžmw=(Óù‚¾2¸(©X&…ØxG㥸p-70]wà´tGùÌLt¬ã½3ÿ²½/|®´ñIþl\Q?äÒ~^¸’Gº¢i.ùGŠ8ï"6û¨ÀDU$Õc5Ð(ÁÒ°¡xéÛìÂL™cS®´G Y<&Øšê²ÚåP×¢ˆdø‹eU©®CC%F 7ýñ¸„²¥ÕY+’M³qÇñÛ9kÿFs–6ó7f+WK‹=€±¤‰#î`}£´·ZÞ„^Ól¡*¿øN$“Tÿ†qìdxW6} „W­¯Ìù†«Xã+Ðþ„òåmËßšP7ÆDÎã!¾‹šýÕŠº Û^ò.¼mG`¨˜¡‚„‡›> @®¹›âòP>íC ".Í=ðDàe|Š.>æ©ìˆã‡úmÓY|ž9þÿä/™PgfâÍÏsæd«7iu*ÜSà!4 HÀ¥Rå_˜í[{nÖüZòüËá)õUaFû‚Ð âñiíaÙÖà3€‡sâ!ÃM]8ç±]nºl²”åÜïÔ˜¿¯ô98m§÷ÉcùÔD.ð {a<‹e¡d{è Ò\#RÙ€ån¢`šÿ|T¸ÔçK)Æ5··€s>‚¾î…7 Çbê::¢°hÁ“Qx‚hR‘箉#@„øI‡Ë"¨¶“Ùï\ï8¤pŠ*ß½5Žo(ýÍPIô¨x|ηœ.‚· Ê }îòZ2´Ç%ÛCi¹ÑøŸQÆsŸn`ß÷eBR$“ßÿD—ÿ²”àH–à?‚hð…(`8xx´Ôs¼'J*QüŠ…Íñ¾“ð×eê åúñ ·›š;!{œÒ›¼/ÕÌ2/}ûÊ‘òœ†‘§ T$;Ö¹C¤x‡JZ {Nh¥å^ âV.¸к„"0ê‘éVf(å‡C;w‹Õò*ìa>÷˜ÐYTÃe¾ÂŒ ò¨‹¨†®oFÁOZäŠY:Uê Ô#Ó[ž!*×Hp1I17¶ -²:ÝŒ°-øÆAð+I”ãèY@ï [ÃÝ‚ŠPm;$,Å0¤zên«-Q‰¶”8„9U[ÕöaN9L}J”¸ 1Iþ€=âµl€FÛ—h$Ì !á%SÜññ}G½.D’ æVW§ª8ã¬V¨’åc52ž¤Ö\ŸÜ.ÓE!Ìö®¼:ÎûY“:=%Ú $ñª/ÜÁpÙs‘a†ŒZ!E)4ùÐ詵¯åD]/EÉUZ`ÃÌV1÷såL¦’ƒéMâåúMÜÄl7ä 0õ¤(j9oJÉ}i°iÙ.jüÏ_™F:¼©GžûÏP1òй ªèõ—:0X¿Ä…=ᅥOìYÓìË™‹$ ù€µ9ï[NÓé&µJV\'²Å·RÀ/»kðSé5X~ 1;\쳫¿»Ï^æœyÆŸgÚ{˜|^bÕ!«Q-Ïcµ3éO׸ߍÐ-ü[E I¶©¢CVGMõlî ²S ÇÌ¢îyuRPW#`(šV¦ºßü#çß Ÿí“ý÷ .hÇWô1ò|Ã×e®x½ýEàù¸¡p|6\^í´™ÊéŒq§¹ÙŒ·úÞ«n;<úý°©ÛµútyÝH쥜+ÆzOónÀ>3Ëþl"Gw%»^^*à}I)V£«Ï×Qÿ‡ë®Íˆ·>I´ýã]^ÛzL@ Ú\âOLaÁÀ"ö[ß4s˜Ë±¹xµ‚7u›ÇƒJƒ0y^š›º·3ðhõö7-×)Jp-‹ t6z˜‡F}÷”9¢4LP!ÝݼÂR®ËÐôý‡¥3²â‘—"ÁÞ¢79¢'eþÅ¥gbu™n§#Ò²þGNi:"/•}6õÐ(~´z‰°íS æÖsu™‡¶ëÝ-´üI«×³V_ÍZ}=kõ›Y«¿µú»Y«of­ÞÌZ¯†–Gƒ¸«ú´„¸f;²/…y³r˜>̓^{tèìí-ãj´ßDž-±{;\eþ(À>ý¶Ö0×ÿC-ϰ°-¡Óî×\ƒÌ‘„†jÉ]Øçqi£6 {Ô“í‡'óº´Ù4ã£oóJHc4Šwªâ–ó÷9:uZ_ÖŒ´æ«š~§™$ à È`k‘N.òx Åš’ê¿YÇË7›j"6ô¬º§¯¿[n®åÄ(¬\PUÁÀ܉ZôÇîÛa¬ÍrB•FCßzŸ»l„‚IŽõaôpß|T­NœµÅj¹ŠošMÜ—p«ï,¯1ñ*ö`ÐNG¤‚ÒßJ©¬­×-]@pNxóuóºßŒl«U«µ?@YJ†‘~;7?¢öéZÄè$F·Íúÿa3-lþvžKEŨ g·€´ªiw`í]³[[…M‰‰Î‰é•fŸ”u»ìõtŒü4úîOPKÿÑ&òt*PK…ŽW3¶p4“^^meta.xml OpenOffice.org/1.9.125$Linux OpenOffice.org_project/680m125$Build-8947TAL/TALES & METAL Reference GuideA guide to using TAL, TALES, and METAL.2004-07-16T21:47:272005-10-23T18:52:08TAL TALES METALen-GB29PT5H29M36SPK…ŽW3Thumbnails/thumbnail.pngUy4ØÎyÝtÓ*¦‚¢¶¨)Q-µt’H«Ôš*Ú©T_æµÖxÈë`ÄšZ«ÆRB™’šZ‚IEMK /ªb„X[RBI¬Ñ¯ý÷óÎùî½çÞsç~¿ß÷Ý{S¯º£T¿Òþ ¨¢]]¼”cœ²=U9¨ìû§UÄÀ!S´ Ì'¦x±„ÿ€o{Ì…‡Ù”^aŽé俹®ÆZhE–à‡ ‘3;fŸ6vvvPËËÂ5ÀÛvödðÿB«êîÊÊÊæ/WPå‹‘Ë_“@RÙtRƼH*Á÷®ÉÖ´>¦åt°Å¬ÐeIAÚ7𜱠jÊ>•˜«±5ŒÙßloŒÊw´+[¿Ê£à}èŽ Smz’UPû„ÕL2ÐIÛ•D8Ë 2YGŸ°žFN`ôÐÔë#æ8kŽKïôn³•=…½ì§êÚUXH¥Û²‹ÀPž>%–MN¢ á’bƒ¸” üøØ1„‰ '·:>½K×.tOßJý¥‹QOˆï¦Ï,°’iëÔÙÛtã’ ¾¼*=ä©}1Tœ‘׉º÷Øi=t\±à¬+È«úbkÜçÕiyí+siôìA›1ÍîO»Ü°‹ØYsES´YÞ¦=%G¹<#UK¹g‘…¿U¥þN}àÚÝÏ F¯²N:õn õLÌ ü_óîG03†`üU=ç¿ ¤2ïÁŽé!a@Z@äVŠO®c¢S²jixÙ-Yâ™Ó\«:z6î£:®cZãä¿0ó,Y1œÊ^ùç³ͽ²^Ð^K°¬mh¶Ü‚XOVéßzñáGel>l¤¯ùkÊ0…Na‡%óÒ›¼¹A˜cÈ÷nùëËÈAóvï•.‹‡k*1±ÕÓG”~„n £Dyoz¥À’*4£§=^”¹ wyœú­~WZÅøfUL_0ôü´óµxb=X›¶8gi¼œ·+b¹ zÒÈ}¨îäÀuÆU&$ÞŸmæí2kÓz¤4ÅÖwå˜Q@úöiRá¿ýד™€õSh°Ðó“ùm Rú–[øÛLÞÀôB¼ÛA~ ^[vt ]í|,d¿IÊ¥b.2‚,ËxHùm" @Pz¦u=åY%…«Ž›K/Nøxà!Ñ›öãv£r¿vÇ苃B³Å8C»©ñwäÀ¯ev„†Ý1y£9¨›?rW´Èºðsqº¡’Qa¥‘Ó(nV´„» âò¬]9:9¶ršÿu®qv—í5–“)~êi#¹~‹X׉FrÁµ*ÞgG5°b¢Ñ ²þíL#†¨× 6’•¦‰ºOsŽŸ;B?*”ô”þ$†ØÏ¿]šcS‘ÓºJ)é÷Œ,ý—þÚnSi»[Ã=cgU«?.1}¿9­FÑ.G“Ý~ù,•-ˆ¥g?ïi°ºUsƒ4&¡[UœÄ¿7ýs˜·ÀJ ûM+S}FAœÍ.±ÛîÎ]ìmÖ«b~8¸vÝðö|SxÙ(TñòÒaÄhº›Í¼r¹Aè­È›4[ýÁþ;|i¤v§VÔ<Ֆ븙˜qÉgöPÏÒòüVKC³/Ë>a8…•êÌÏnyô‰Ü‚%‰mÂ]|¹L7Qå=~Öü:•ãþ3Ð)†í7®™R%Ô®Ó¹”…’ê4‹£êò¹è.Õé-AWJ˜ÿRš™ðÖóM×ÔÒ,Œ¦NŒqb+ÀÈòÇEwø¼Å$<ÆÔñ^••#±o¿noª=îÊÕŸhÀ_òOAý06¿“I·²gõ‘ ë ™Â,e•O¤žòËTWÄ$n¦‰VìüNt/#ÞžÔHº*ß·é{ÌX=æ4†ÁzèüõøœC·üJF)»É(ó ê˜½Â9ÀLðÞÉ`lÒ <¿?Íÿœrû{uhtÿ¸ÚÄßìÂ<bøÿt“Î Þç~ïKV~œ4ÂÝåüæOÿPKªš5_PK…ŽW3 settings.xmlÍY[SêH~ß_añº¥ xÅRN0 r“«ð6$ ä0™É™™Ø_¿–bP6ªõÅ$ÓÓ—é¯oÃݯ…KOÞ@H‡³ûLöLÏœ³¸í°é}¦×5Oo2¿ ÝñÉıàÖæ–ïS§”By‚Û™¼]-ßgfJy·šÆ=`«Og\Lµœ®ëÚê=³Þ° ›¿ÓApœG´Ù|>¯E«R‹³‰3ý†wV[‘l6pο¡¾x×dmÓ'ã K7îVÌ×jœ: ÜÐú“õgF\´ûÍàýL2q{>Ó÷‘Þ@ºÜËlVÔÒÇ©Láòê:w}§}å²?çLTký0¶ÇV³8¾¹Ë›ËÜa¼ŸÀ™Îb•Î^œ_$dÞ™ñ  6 J3¦ ·Œ9§@X¦ „ÉdTXQð@BÛ°‹û„P¹7ûS—x§³aö׳ŠX´CS,÷;ñн¥ªTÑ›)„X>À“»€—ÍfÏß®HÉåôÄÊJgLáèqM#°#Æí]1àa:¹RÜã}Õ¯ª=âÜí"§m°Í¸H~È!S“XŠ‹x¶Y=!ãŠìKm ü ˜c>~ŒÌ]Ëë`'À²_Z½ø‚(,hÿ¥¶Ý"‚t  ã+LÇHdŸ¥´0Á¨6„¶³Ï1ø×°kèy6Qq™x„À˜2.Àt„T(*è.¦*¬á»cßœVò¢‚ÕJ ÄA”¸ë arô@Š<ÒAý)Tùxgi<À'+˜³¸Åç´€Õ"ˆPP”¿}!ƒ$Ê ÍÉC+Êì R‹¤Ò¨¬¡–à “ê–ÛRˆ„«‹¢ÃˆXf´=UŽòF ú†1  _ñŠŽ/ Ò¾Ä17sš‚þ{±€üxÎ…áôéoM·éØí/É >í=U½1kSkjü/ÿzºmvi±Óÿ™t`uãÏúEÓnLÃõðq>~1ŒŽ›wÚ¦>ì‹+¢í—úèµ’oçúþèµê —ÅË¥¾ýØ_–Ü<®÷ñÙÔÉ ï·úÅ7‹µ—ÃÕKnãÍz¤ÔúGG>ßÃÁ‚¶ºAÝðÔðµÊï|8ð²Öy[PF«kÈz)jeãy˜ËËñyu>z-꤬/†X¹µÝ¾Dºë#o˜ëå‘çKï¡]çB]gÃ×ö¬D‹³Q®ß%¯mÎqïÓÊwÀÆ`Œ«¨ï.f ³~» ÄæŒ~ ÿãäɰ™X÷]e‡ÐÝv˜°‡Æ#´†&¥Ó¸žG—= ¢L9~š0 vši®CÞ ¿ºæh²å2" y¤|Lhy}Köciø¼"ŸÑá†tkùÌR~&iø:S†ðí(tRSò…Àã Á–…ð‡ûÂúõ« }ߪ ¢ñu†ÙLùÀ°qµNÖ”$*“,vËÙCW,¿Ò±Ata¡‚xMÖÿÆÓNm 'è”¬Š¬‘1¼@ý´“ D8†ü0ª%·#f4TGa7–¦Ix©Ø´—ö¾iëÕŸ9V Ð2(åA$'µaÐîÏ™GO—0;fì<䊬Ì\U}©œÉ2D±8jV'Ì'´(€ÌoÖ;Â0³ ó7©<=˜o<ˆ® jdÉýmÄmò0:õ§{NýP£Äæ5©ýã]ÄáöŠÄšO÷ÙÎû›cƒï°X$ˆîÀÒñs‘ây˜8?&©V;¯ú´/¿Ai»~+ü PK¡ s]ÁPK…ŽW3META-INF/manifest.xml­”1oÂ0…÷þ ×{|ÀT!RJ•Ú†Ž&¹$–;²/”üûºUCš…6ÛÙ~÷½»7x±:WšÐyeM̧bšÔfÊ1?$OÑ_-ï÷›Ý:yßoY%ÊÑÓ¼+Øþðøò¼f<ØÕhvy®RÖ›dÃ^;]`lß8ãÝ•È(ãþ›†2þrŒyITÏlàÛž?›L¦Ð‰ˆõ¤\iŒÐk¯&ÆLɈÚc.ëZ«TRØN&¾1"˜Š§ï›òF먖TÆ8ŒâÑ(‘Z“«¢qßÃnëk‰ŸÝj> Ý«”‡þ?«•‘®ækÙÚ†¢T¦%ÞhAx&ñ ƒC`š¿ò•ë©ÕèGÇVHòÐaXR6ÕÑH¥=PWŠÚcÃÇ ‰Âr‰v=ä§X~PKoUy©8}PK…ŽW3á¥19mimetypePK…ŽW3DConfigurations2/PK…ŽW3 rPictures/PK…ŽW3¥©½ú$5 ™layout-cachePK…ŽW3ÛQ•ùŠm ÷content.xmlPK…ŽW3ÿÑ&òt* Ostyles.xmlPK…ŽW3¶p4“^^ymeta.xmlPK…ŽW3ªš5_ýThumbnails/thumbnail.pngPK…ŽW3¡ s]Á x'settings.xmlPK…ŽW3oUy©8}Î,META-INF/manifest.xmlPK OI.SimpleTAL-4.1/documentation/src/api-simpletalutils.txt0000644000175000017500000000702010101613234021757 0ustar cms103cms103title: SimpleTAL API: simpleTALUtils Module. subject: Documentation on how to use the simpleTALUtils Module.

simpleTALUtils

This module holds optional classes and functions that might be of use while using SimpleTAL, but are not required by SimpleTAL directly.

def ExpandMacros (context, template, outputEncoding="ISO-8859-1")

This function can be used to expand a template which contains METAL macros, while leaving in place all the TAL and METAL commands. Doing this makes editing a template which uses METAL macros easier, because the results of the macro can be seen immediately. The macros referred to by the passed in template must be present in the context so that their contents can be referenced. The outputEncoding determines the encoding of the returned string, which will contain the expanded macro.

FastStringOutput

This class implements a very restricted File type object that can return a string containing all data written into it. Unlike StringIO, FastStringOutput only supports write operations, and so is faster. Only two methods are supported: write and getvalue.

write (data)

Used by SimpleTAL to write the expanded template.

getvalue ()

Use this to retrieve a string with the resulting output.

TemplateCache

This class implements a cache for compiled templates which automatically invalidates entries when their template file changes. The instance has one public method: getTemplate

getTemplate (name, inputEncoding="ISO-8859-1")

This method will return a compiled template from the file 'name'. If the file ends in '.xml' it will be compiled using simpleTAL.compileXMLTemplate, otherwise it will be compiled as a HTML template. If the method is called again it will check to see whether the file 'name' has changed since the last call, and if it has it will re-compile the template,otherwise it will return the cached version. HTML Templates will be taken as being stored in the "inputEncoding", XML templates ignore this parameter.

getXMLTemplate (name)

This method will return a compiled XML template from the file 'name'. This works identically to getTemplate as described above, except that it always treats the template as XML.

HTMLStructureCleaner

This class can be used to encode any stray special characters within a given string or file-like object. Its intended use is in preparing data that will be placed into a Context object and then included in a template using the 'structure' keyword. The class uses the Python SGML parser to determine what tags are present, so any HTML markup will be left intact. As an example, take the content:
This is some <b>bad</b> html that is < than great!
If this was included in a template in its current state the result would be bad markup. Once cleaned by this class, the result would be:
This is some <b>bad</b> html that is &lt; than great!
The class has one external method:
def clean (self, content, encoding=None)
The content should be either a string or a file-like object. If the string is a unicode string (u"") it will be cleaned as is. If the string is an ordinary string then the encoding must be supplied, and it will first be converted to unicode. If the content object is a file-like object then it will be converted only if the encoding is supplied. The call returns a unicode string that has the '<', '>' and '&' characters encoded. Back to SimpleTAL API SimpleTAL-4.1/documentation/src/api-simpletales.txt0000644000175000017500000000570210101613234021233 0ustar cms103cms103title: SimpleTAL API: simpleTALES Module. subject: Documentation on how to use the simpleTALES Module.

simpleTALES

The only external class in this module is the Context class.

Context ([options] [,allowPythonPath])

Creates a new Context object, used by SimpleTAL when expanding a template. The options variable, if passed, will be made available as a global variable under the name "options" as per the TALES specification. By default Python TAL paths (e.g. 'python: 1 + 2') are not allowed. If you require them, and you completely trust the authors of the templates, they can be enabled by passing in allowPythonPath=1.

Context.addGlobal (name, value)

Adds the value to the context under name. Value can either be a fundamental python data type or a callable object. For example, take the code:

class Test:
	def __init__ (self, val):
		self.val = val
		
	def getResult (self):
		return str (self.val + 4)
		
test = Test (10)

context = SimpleTALES.Context()
context.addGlobal ("number14", test.getResult)
context.addGlobal ("data", {"one": {"blue": ("Cat", "Dog", "Mouse"), "pink": ["One"]}})

The affect of this context is shown for several different TALES expressions:

<b tal:define="test1 nocall:number14"></b>
The method 'getResult' is bound to the local variable test1.

<b tal:define="test2 number14"></b>

The local variable test2 is assigned the value "14"

<b tal:repeat="pets data/one/blue"><i tal:replace="pets"></i></b>

Prints out <b>CatDogMouse</b> All strings placed into the context, and all strings returned by callable objects should be unicode strings. This allows the rendering of the template into different character sets without requiring any code changes.

PathFunctionVariable (callableObject)

This class wraps a callable object (e.g. function) so that it can receive part of a TAL path as it's argument. To use this simply create a new instance of the PathFunctionVariable and then place this into the Context (see above). The path passed to the function is that part of the path not already used. For example if the function "helloFunc" is placed in the Context the path "helloFunc/an/example" results in the string "an/example" being passed to the function.

CachedFuncResult (callableObject)

This class wraps a callable object (e.g. function) so that the callable is only called once. In normal SimpleTAL operation any function placed into a Context will be called multiple times during template expansion. To ensure that it is only called once simply wrap in the CachedFuncResult object first.

clearCache ()

Clears the cache. Use this to clear the cache between multiple template expansions if the callable should be executed once per template expansion. Back to SimpleTAL API SimpleTAL-4.1/documentation/src/api-simpletal.txt0000644000175000017500000000621310326772266020725 0ustar cms103cms103title: SimpleTAL API: simpleTAL Module subject: Documentation on how to use the simpleTAL Module.

simpleTAL

Two helper functions are provided for convenience, one for compiling HTML templates, and one for compiling XML templates. If an error is encountered during compilation (for example mismatched TAL tags or bad syntax) an TemplateParseException will be thrown.

compileHTMLTemplate (template, inputEncoding="ISO-8859-1", minimizeBooleanAtts=0)

Compiles the passed in HTML template into an instance of the 'Template' class. The template object should be either a string containing the template, or a file-like object. The inputEncoding specifies the encoding that the template was written using and deafults to iso-8859-1. The minimizeBooleanAtts flag controls whether HTML boolean attributes (e.g. <img ismap>) should be written out in minimized form. See below for details of how to use the Template class.

compileXMLTemplate (template)

Compiles the passed in XML template into an instance of the 'Template' class. The template object should be either a string containing the template, or a file-like object. The XML template must be a well formed XML document. The character set will be determined from the prolog of the template or be assumed to be utf-8. See below for details of how to use the Template class.

compileDOMTemplate (dom)

Compiles an XML template that is stored as a DOM tree. This requires PyXML to be installed to function.

Template Instances

The compiled templates contain all of the logic required to be able to expand themselves for a given context. They can be kept around and reused as often as required, there is no need or benefit to re-compiling them unless the underlying template changes. They have one method of interest as part of the external API:

def expand (self, context, outputFile[,outputEncoding] [,docType][,suppressXMLDeclaration])

This method will expand the template, using the simpleTALES.Context object provided, and write the output into the given file-like object. If the template is a HTML template then the result will, by default, be encoded in iso-8859-1. If no outputEncoding is specified and the template is an XML template then it will default to utf-8. The docType and suppressXMLDeclaration variables apply only to XML Templates. Python's support for XML does not currently extend to the LexicalHandler API, which is required for an application to be able to read an XML documents DOCTYPE. If pyXML is installed SimpleTAL will make use of it to determine the XML DOCTYPE, otherwise the doctype must be passed as a named variable to the expand method. For example to produce a valid strict XHTML document without pyXML use:

template.expand (context, outputFile, docType='<!DOCTYPE html  PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">')

If the suppressXMLDeclaration is set to true then the XML Declaration will not be included in the output (required for XHTML in IE6). Back to SimpleTAL API SimpleTAL-4.1/documentation/src/api-simpleelementtree.txt0000644000175000017500000000430410202213623022431 0ustar cms103cms103title: SimpleTAL API: simpleElementTree Module. subject: Documentation on how to use the simpleElementTree Module.

simpleElementTree

This module provides optional integration with ElementTree, allowing XML documents to be parsed and placed directly into the Context. The contents of the XML document can then be accessed using an sub-set of XPATH from within TAL templates.

parseFile (file)

This function takes one parameter, which should be either a file-like object or a string holding the name of a file on the filesystem. The file is read, the XML it contains is parsed, and an instance of simpleTALES.ContextVariable is returned. The returned ContextVariable can then be added to the Context using addGlobal in the normal way, e.g.
xmlTree = simpleElementTree.parseFile (file="input.xml")
context = simpleTALES.Context(allowPythonPath=1)
context.addGlobal ("input", xmlTree)

ElementTree Paths

The Context variable provided by parseFile provides the following syntax for path access in TAL:
  • Accessing the variable directly returns the Text value for this node.
  • Accessing variable/find/path returns the first node to match the path, as supported by ElementTree (see XPath Support in ElementTree).
  • Accessing variable/findall/path returns a list of nodes that match the path, as supported by ElementTree (see XPath Support in ElementTree).
  • Accessing variable@name returns the XML attribute "name".
  • Accessing variable/anotherElement is a short-cut for variable/find/anotherElement.
Here are some examples:
<html>
  <body>
    <h1 tal:attributes="class input/title/@type" tal:content="input/title">Title here</h1>
    <ul>
      <li tal:repeat="note input/findall/.//note">
      <b tal:condition="note/@type" tal:replace="string: Note (${note/@type}) - $note and then some"></b>
      </li>
    </ul>
  </body>
</html>
SimpleTAL-4.1/documentation/src/index.txt0000644000175000017500000000202710101613234017246 0ustar cms103cms103title: SimpleTAL subject: Welcome to SimpleTAL SimpleTAL is a stand alone Python implementation of the TAL, TALES and METAL specifications used in Zope to power HTML and XML templates. SimpleTAL is an independent implementation of TAL; there are no dependencies on Zope nor is any of the Zope work re-used. A mailing list exists for discussion of SimpleTAL and support questions. Feedback, feature enhancements and bug fixes will all be gladly received! SimpleTAL-4.1/documentation/src/notes.txt0000644000175000017500000001422710347331422017304 0ustar cms103cms103title: Notes on SimpleTAL subject: Notes, known limitations, and differences between SimpleTAL and Zope's ZPT.

Notes

Some notes on aspects of SimpleTAL that might require a little explanation. If there is something you feel should be included in here, please let me know.

HTML and XHTML Templates

As a bug fix version 2.1 of SimpleTAL now processes HTML templates slightly differently to XML templates. In the HTML 4.01 specification there are several elements (e.g. <img>) for which end tags are forbidden. This would normally cause a problem with TAL, because all tags that have TAL attributes on them must be closed. To solve this problem SimpleTAL has been modified to:
  • Allow TAL attributes on all HTML elements that forbid close tags, and process them despite the lack of close tag
  • When compiling a HTML template issue a warning if a close tag is present for elements that are forbidden to have close tags. (Only supported if logging is installed)
  • To suppress the output of close tags for elements that are forbidden to have close tags.
These changes ensure that a HTML template can still be a valid HTML document, even if TAL needs to be used on elements that forbid end tags. Additionally the output from the expanded template will also be valid HTML, in that the end tags will be suppressed even if present in the template. As a consequence of this change it is important that any XHTML templates are handled as XML rather than HTML, i.e. by calling compileXMLTemplate to compile the template.

Character set encoding

SimpleTAL fully supports international character sets, providing all of the encoding options that Python supports. To painlessly support the correct conversion between character sets, just follow these simple rules:
  • When calling compileHTMLTemplate pass in the character set encoding the template was written in.
  • A template passed to compileXMLTemplate must be a well formed XML document. If it's not in UTF-8 then ensure the prolog of the document specifies what format it is in.
  • Convert to unicode all strings passed into SimpleTALES.Context
  • When calling template.expand, pass in the encoding you would like the template output to be in.

Structured Content

When content is included into a template using 'tal:content' or 'tal:replace' the content is by default treated as text. This means that the '<', '>' and '&' characters will be automatically escaped so that they appear in the rendered template correctly. When using the 'structure' keyword, however, SimpleTAL will pass the content straight through into the template with no escaping. As such it's important to realise that the content placed into a template in such a way can affect the validity of the output. For example if you take user input that contains HTML markup it's important to ensure that the markup is valid HTML, otherwise the resulting template output will not be valid. In order to assist in doing this I've put together a class (HTMLStructureCleaner) in simpleTALUtils that will escape any stray '<', '>' or '&' characters present while leaving all elements and attributes intact. The restriction in SimpleTAL 1.x when including structured content into an XML template is now removed - the structure is not re-parsed, and so does not have to be valid XML.

Object Attributes versus Key Values

When adding a mapping object (e.g. a Dictionary) to the Context, care should be taken on the naming conventions used within the mapping. When SimpleTAL/ES resolves a path, it will first look for attributes on the object with that name, before trying to treat the object as a mapping object. What this means in practice is that paths which match object attributes (e.g. methods) will never select the values given in the mapping. As an example of this consider the following:

Template:  <p tal:repeat="item dict/items"><b tal:replace="item"></b></p>

Context:  
myDict = {'items': [1,2,3]}
Context.addGlobal ("dict", myDict)


You would expect the output from this to be:
<p>1</p><p>2</p><p>3</p>
However this is not what happens. Instead the variable "item" will be set to the output of "myDict.items()" - i.e. it will call the Python dictionary method 'items()'. I have considered changing this so that mapping checks are made first in path resolution rather than attribute lookups. When I checked the Zope 2.5 behaviour however, I found that it works the same way as SimpleTAL, so for now I've left it to be consistent with Zope.

Using < and > in TAL Paths

When using the 'python:' path type, care must be taken with the use of the less than (<) and greater than (>) signs. These must be escaped in the same way as all other HTML markup. For example: use: <div tal:condition="python: a &lt; b">Conditional Text</div> instead of: <div tal:condition="python: a < b">Conditional Text</div>

Known limitations

  1. Repeat Variables do not support 'first' and 'last'.
  2. When using 'not:' on an empty expression the result will be true rather than an error.
  3. Path type 'python:' is not supported by default. You can enable this by passing allowPythonPath=1 to the Context constructor. Note that this should only be used when the authors of the templates are completely trusted, the code included in the 'python:' path can do anything.
  4. TAL markup "on-error" is not yet supported.
  5. HTML Templates will have duplicate attributes if an attribute is added using "tal:attributes" and the name is in upper case. The cause of this is the HTMLParser implementation, which always converts attributes to lower case.

Known differences

Non-existent path types, e.g. '<b tal:content="total: $totalAmount"></b>' are not supported. In Zope, this results in the path being interpreted as a string - in simpleTAL/ES the result will be an error. Back to SimpleTAL SimpleTAL-4.1/documentation/templates/0000755000175000017500000000000010364737164016630 5ustar cms103cms103SimpleTAL-4.1/documentation/templates/template.html0000644000175000017500000000174110101613234021310 0ustar cms103cms103 Title

Title

Subject

Body

Version

SimpleTAL-4.1/examples/0000755000175000017500000000000010364737163013576 5ustar cms103cms103SimpleTAL-4.1/examples/cgi-example/0000755000175000017500000000000010364737164015772 5ustar cms103cms103SimpleTAL-4.1/examples/cgi-example/fields.html0000644000175000017500000000136607742066601020131 0ustar cms103cms103 Title

Title

Name: (Please fill in)
Occupation: (Please fill in)
Age:
SimpleTAL-4.1/examples/cgi-example/results.html0000644000175000017500000000074307705371204020357 0ustar cms103cms103 Title

Title

Name: Your name
Occupation: Your occupation
Age: Your age

SimpleTAL-4.1/examples/cgi-example/simple-cgi.py0000755000175000017500000000737710007245640020401 0ustar cms103cms103#!/usr/bin/python """ Example TAL based CGI Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! A demonstration of how TAL/TALES can be used from a cgi program. Quick instructions: 1 - Copy this file and the two templates ("fields.html" and "results.html") to the cgi-bin directory on your webserver 2 - Ensure that simpleTAL, simpleTALES and DummyLogger are installed in your site-packages directory 3 - Go to http://servername/cgi-bin/simple-cgi.py Module Dependencies: simpleTAL, simpleTALES """ from simpletal import simpleTAL, simpleTALES import cgi, sys class ExampleCGI: def __init__ (self): self.missingFields = {} self.fieldValues = {} self.form = cgi.FieldStorage() self.formValid = 1 self.context = simpleTALES.Context() def buildContext (self, title): self.context.addGlobal ("missingFields", self.missingFields) self.context.addGlobal ("fieldValues", self.fieldValues) self.context.addGlobal ("title", title) def getValue (self, name, mandatory=1): if (self.form.has_key (name)): self.fieldValues [name] = self.form [name].value elif (mandatory): self.missingFields [name] = 1 self.formValid = 0 def main (self): if (self.form.has_key ("submit")): # Recieved the posting, get the name, occupation, and (optional) age self.getValue ("username") self.getValue ("occupation") self.getValue ("age", mandatory=0) if (self.formValid): # Valid form, show the results self.buildContext ("Valid Results") self.expandTemplate ("results.html") else: self.buildContext ("Missing fields") self.expandTemplate ("fields.html") else: self.buildContext ("Enter data") self.expandTemplate ("fields.html") def expandTemplate (self, templateName): # Print out the headers sys.stdout.write ("Content-Type: text/html\n") # HTML is following sys.stdout.write ("\n") # blank line, end of headers # Expand the template and print it out templateFile = open (templateName, 'r') template = simpleTAL.compileHTMLTemplate (templateFile) # Close the template file templateFile.close() # Expand the template as HTML using this context template.expand (self.context, sys.stdout) sys.exit (0) # Entry point for the cgi cgiInstance = ExampleCGI() cgiInstance.main() SimpleTAL-4.1/examples/elementtree-example/0000755000175000017500000000000010364737164017541 5ustar cms103cms103SimpleTAL-4.1/examples/elementtree-example/basic-example.py0000755000175000017500000000445110202213623022610 0ustar cms103cms103#!/usr/bin/python """ Example TAL program Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! As simple as it gets: 1 - Create a context 2 - Compile a template 3 - Expand the template Module Dependencies: simpleTAL, simpleTALES """ from simpletal import simpleTAL, simpleTALES, simpleElementTree import sys xmlTree = simpleElementTree.parseFile (file="input.xml") # Create the context that is used by the template context = simpleTALES.Context(allowPythonPath=1) # Add the XML element tree to the context context.addGlobal ("input", xmlTree) # Open the template file templateFile = open ("basic.xml", 'r') # Compile a template template = simpleTAL.compileXMLTemplate (templateFile) # Close the template file templateFile.close() # Expand the template as HTML using this context template.expand (context, sys.stdout, "utf-8") SimpleTAL-4.1/examples/structure-example/0000755000175000017500000000000010364737164017270 5ustar cms103cms103SimpleTAL-4.1/examples/structure-example/structure-example.py0000644000175000017500000000500610007245640023317 0ustar cms103cms103""" Example TAL program Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! This shows how to include structure into a template, and how multiple templates can be embedded within each other. Module Dependencies: simpleTAL, simpleTALES """ from simpletal import simpleTAL, simpleTALES import sys # Create the context that is used by the template context = simpleTALES.Context() context.addGlobal ("title", "Hello World") context.addGlobal ("author", "Colin Stewart") # A list that contains a dictionary chapters = [{"heading": "Introduction", "text": "Some text here"} ,{"heading": "Details", "text": "Notice tags are preserved."} ] advancedText = 'Structured text can contain other templates like this - written by Me' chapters.append ({"heading": "Advanced", "text": simpleTAL.compileHTMLTemplate (advancedText)}) context.addGlobal ("doc", chapters) templateFile = open ("structure.html", 'r') template = simpleTAL.compileHTMLTemplate (templateFile) templateFile.close() template.expand (context, sys.stdout)SimpleTAL-4.1/examples/structure-example/structure.html0000644000175000017500000000034707613363735022224 0ustar cms103cms103

The title

Chapter Heading

Text

SimpleTAL-4.1/examples/metal-example/0000755000175000017500000000000010364737164016332 5ustar cms103cms103SimpleTAL-4.1/examples/metal-example/page.html0000644000175000017500000000026507630206126020126 0ustar cms103cms103

The title

SimpleTAL!
SimpleTAL-4.1/examples/metal-example/macro.html0000644000175000017500000000033207630206126020306 0ustar cms103cms103

The title

This macro is brought to you by the colour blue. Now you know.

SimpleTAL-4.1/examples/metal-example/metal-example.py0000755000175000017500000000451310007245640021430 0ustar cms103cms103#!/usr/bin/python """ Example TAL program Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! An example of how to use METAL. Module Dependencies: simpleTAL, simpleTALES """ from simpletal import simpleTAL, simpleTALES import sys # Creat the context that is used by the template context = simpleTALES.Context() # Add a string to the context under the variable title context.addGlobal ("title", "Simple METAL Example") # Compile the macro pages templateFile = open ("macro.html", 'r') macros = simpleTAL.compileHTMLTemplate (templateFile) templateFile.close() # Add the macros page to the Context context.addGlobal ("sitemacros", macros) # Now compile the page which will use the macros templateFile = open ("page.html", 'r') page = simpleTAL.compileHTMLTemplate (templateFile) templateFile.close() # Expand the page using this context page.expand (context, sys.stdout) SimpleTAL-4.1/examples/basic/0000755000175000017500000000000010364737164014660 5ustar cms103cms103SimpleTAL-4.1/examples/basic/basic-example.py0000755000175000017500000000471310364672755017760 0ustar cms103cms103#!/usr/bin/python """ Example TAL program Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! As simple as it gets: 1 - Create a context 2 - Compile a template 3 - Expand the template Module Dependencies: simpleTAL, simpleTALES """ from simpletal import simpleTAL, simpleTALES import sys # Creat the context that is used by the template context = simpleTALES.Context(allowPythonPath=1) # Add a string to the context under the variable title context.addGlobal ("title", "Colours of the rainbow") # A list of strings colours = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"] # Add the list to the context under the variable rainbow context.addGlobal ("rainbow", colours) # Open the template file templateFile = open ("basic.html", 'r') # Compile a template template = simpleTAL.compileHTMLTemplate (templateFile) # Close the template file templateFile.close() # Expand the template as HTML using this context template.expand (context, sys.stdout, outputEncoding="utf-8") SimpleTAL-4.1/examples/basic/basic.html0000644000175000017500000000040010364672755016625 0ustar cms103cms103

The title

  • Colour of the rainbow
  • One Two

SimpleTAL-4.1/lib/0000755000175000017500000000000010364737163012526 5ustar cms103cms103SimpleTAL-4.1/lib/simpletal/0000755000175000017500000000000010364737164014521 5ustar cms103cms103SimpleTAL-4.1/lib/simpletal/simpleTAL.py0000644000175000017500000015700210364672755016736 0ustar cms103cms103""" simpleTAL Interpreter Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! The classes in this module implement the TAL language, expanding both XML and HTML templates. Module Dependencies: logging, simpleTALES, simpleTALTemplates """ try: import logging except: import DummyLogger as logging import xml.sax, cgi, StringIO, codecs, re, sgmlentitynames, types import simpletal, copy, sys import FixedHTMLParser __version__ = simpletal.__version__ try: # Is PyXML's LexicalHandler available? from xml.sax.saxlib import LexicalHandler use_lexical_handler = 1 except ImportError: use_lexical_handler = 0 class LexicalHandler: pass try: # Is PyXML's DOM2SAX available? import xml.dom.ext.Dom2Sax use_dom2sax = 1 except ImportError: use_dom2sax = 0 import simpleTALES # Name-space URIs METAL_NAME_URI="http://xml.zope.org/namespaces/metal" TAL_NAME_URI="http://xml.zope.org/namespaces/tal" # All commands are of the form (opcode, args, commandList) # The numbers are the opcodes, and also the order of priority # Argument: [(isLocalFlag (Y/n), variableName, variablePath),...] TAL_DEFINE = 1 # Argument: expression, endTagSymbol TAL_CONDITION = 2 # Argument: (varname, expression, endTagSymbol) TAL_REPEAT = 3 # Argument: (replaceFlag, type, expression) TAL_CONTENT = 4 # Not used in byte code, only ordering. TAL_REPLACE = 5 # Argument: [(attributeName, expression)] TAL_ATTRIBUTES = 6 # Argument: expression TAL_OMITTAG = 7 # Argument: (originalAttributeList, currentAttributeList) TAL_START_SCOPE = 8 # Argument: String to output TAL_OUTPUT = 9 # Argument: None TAL_STARTTAG = 10 # Argument: Tag, omitTagFlag TAL_ENDTAG_ENDSCOPE = 11 # Argument: None TAL_NOOP = 13 # METAL Starts here # Argument: expression, slotParams, endTagSymbol METAL_USE_MACRO = 14 # Argument: macroName, endTagSymbol METAL_DEFINE_SLOT=15 # Only used for parsing METAL_FILL_SLOT=16 METAL_DEFINE_MACRO=17 METAL_NAME_REGEX = re.compile ("[a-zA-Z_][a-zA-Z0-9_]*") SINGLETON_XML_REGEX = re.compile ('^<[^\s/>]+(?:\s*[^=>]+="[^">]+")*\s*/>') ENTITY_REF_REGEX = re.compile (r'(?:&[a-zA-Z][\-\.a-zA-Z0-9]*[^\-\.a-zA-Z0-9])|(?:&#[xX]?[a-eA-E0-9]*[^0-9a-eA-E])') # The list of elements in HTML that can not have end tags - done as a dictionary for fast # lookup. HTML_FORBIDDEN_ENDTAG = {'AREA': 1, 'BASE': 1, 'BASEFONT': 1, 'BR': 1, 'COL': 1 ,'FRAME': 1, 'HR': 1, 'IMG': 1, 'INPUT': 1, 'ISINDEX': 1 ,'LINK': 1, 'META': 1, 'PARAM': 1} # List of element:attribute pairs that can use minimized form in HTML HTML_BOOLEAN_ATTS = {'AREA:NOHREF': 1, 'IMG:ISMAP': 1, 'OBJECT:DECLARE': 1 , 'INPUT:CHECKED': 1, 'INPUT:DISABLED': 1, 'INPUT:READONLY': 1, 'INPUT:ISMAP': 1 , 'SELECT:MULTIPLE': 1, 'SELECT:DISABLED': 1 , 'OPTGROUP:DISABLED': 1 , 'OPTION:SELECTED': 1, 'OPTION:DISABLED': 1 , 'TEXTAREA:DISABLED': 1, 'TEXTAREA:READONLY': 1 , 'BUTTON:DISABLED': 1, 'SCRIPT:DEFER': 1} class TemplateInterpreter: def __init__ (self): self.programStack = [] self.commandList = None self.symbolTable = None self.slotParameters = {} self.commandHandler = {} self.commandHandler [TAL_DEFINE] = self.cmdDefine self.commandHandler [TAL_CONDITION] = self.cmdCondition self.commandHandler [TAL_REPEAT] = self.cmdRepeat self.commandHandler [TAL_CONTENT] = self.cmdContent self.commandHandler [TAL_ATTRIBUTES] = self.cmdAttributes self.commandHandler [TAL_OMITTAG] = self.cmdOmitTag self.commandHandler [TAL_START_SCOPE] = self.cmdStartScope self.commandHandler [TAL_OUTPUT] = self.cmdOutput self.commandHandler [TAL_STARTTAG] = self.cmdOutputStartTag self.commandHandler [TAL_ENDTAG_ENDSCOPE] = self.cmdEndTagEndScope self.commandHandler [METAL_USE_MACRO] = self.cmdUseMacro self.commandHandler [METAL_DEFINE_SLOT] = self.cmdDefineSlot self.commandHandler [TAL_NOOP] = self.cmdNoOp def tagAsText (self, (tag,atts), singletonFlag=0): """ This returns a tag as text. """ result = ["<"] result.append (tag) for attName, attValue in atts: result.append (' ') result.append (attName) result.append ('="') result.append (cgi.escape (attValue, quote=1)) result.append ('"') if (singletonFlag): result.append (" />") else: result.append (">") return "".join (result) def initialise (self, context, outputFile): self.context = context self.file = outputFile def cleanState (self): self.scopeStack = [] self.programCounter = 0 self.movePCForward = None self.movePCBack = None self.outputTag = 1 self.originalAttributes = {} self.currentAttributes = [] # Used in repeat only. self.repeatAttributesCopy = [] self.currentSlots = {} self.repeatVariable = None self.tagContent = None # tagState flag as to whether there are any local variables to pop self.localVarsDefined = 0 # Pass in the parameters self.currentSlots = self.slotParameters def popProgram (self): vars, self.commandList, self.symbolTable = self.programStack.pop() self.programCounter,self.scopeStack,self.slotParameters,self.currentSlots, self.movePCForward,self.movePCBack,self.outputTag,self.originalAttributes,self.currentAttributes,self.repeatVariable,self.tagContent,self.localVarsDefined = vars def pushProgram (self): vars = (self.programCounter ,self.scopeStack ,self.slotParameters ,self.currentSlots ,self.movePCForward ,self.movePCBack ,self.outputTag ,self.originalAttributes ,self.currentAttributes ,self.repeatVariable ,self.tagContent ,self.localVarsDefined) self.programStack.append ((vars,self.commandList, self.symbolTable)) def execute (self, template): self.cleanState() self.commandList, self.programCounter, programLength, self.symbolTable = template.getProgram() cmndList = self.commandList while (self.programCounter < programLength): cmnd = cmndList [self.programCounter] #print "PC: %s - Executing command: %s" % (str (self.programCounter), str (cmnd)) self.commandHandler[cmnd[0]] (cmnd[0], cmnd[1]) def cmdDefine (self, command, args): """ args: [(isLocalFlag (Y/n), variableName, variablePath),...] Define variables in either the local or global context """ foundLocals = 0 for isLocal, varName, varPath in args: result = self.context.evaluate (varPath, self.originalAttributes) if (isLocal): if (not foundLocals): foundLocals = 1 self.context.pushLocals () self.context.setLocal (varName, result) else: self.context.addGlobal (varName, result) self.localVarsDefined = foundLocals self.programCounter += 1 def cmdCondition (self, command, args): """ args: expression, endTagSymbol Conditionally continues with execution of all content contained by it. """ result = self.context.evaluate (args[0], self.originalAttributes) #~ if (result is None or (not result)): conditionFalse = 0 if (result is None): conditionFalse = 1 else: if (not result): conditionFalse = 1 try: temp = len (result) if (temp == 0): conditionFalse = 1 except: # Result is not a sequence. pass if (conditionFalse): # Nothing to output - evaluated to false. self.outputTag = 0 self.tagContent = None self.programCounter = self.symbolTable[args[1]] return self.programCounter += 1 def cmdRepeat (self, command, args): """ args: (varName, expression, endTagSymbol) Repeats anything in the cmndList """ if (self.repeatVariable is not None): # We are already part way through a repeat # Restore any attributes that might have been changed. if (self.currentAttributes != self.repeatAttributesCopy): self.currentAttributes = copy.copy (self.repeatAttributesCopy) self.outputTag = 1 self.tagContent = None self.movePCForward = None try: self.repeatVariable.increment() self.context.setLocal (args[0], self.repeatVariable.getCurrentValue()) self.programCounter += 1 return except IndexError, e: # We have finished the repeat self.repeatVariable = None self.context.removeRepeat (args[0]) # The locals were pushed in context.addRepeat self.context.popLocals() self.movePCBack = None # Suppress the final close tag and content self.tagContent = None self.outputTag = 0 self.programCounter = self.symbolTable [args[2]] # Restore the state of repeatAttributesCopy in case we are nested. self.repeatAttributesCopy = self.scopeStack.pop() return # The first time through this command result = self.context.evaluate (args[1], self.originalAttributes) if (result is not None and result == simpleTALES.DEFAULTVALUE): # Leave everything un-touched. self.programCounter += 1 return try: # We have three options, either the result is a natural sequence, an iterator., or something that can produce an iterator. isSequence = len (result) if (isSequence): # Only setup if we have a sequence with length self.repeatVariable = simpleTALES.RepeatVariable (result) else: # Delete the tags and their contents self.outputTag = 0 self.programCounter = self.symbolTable [args[2]] return except: # Not a natural sequence, can it produce an iterator? if (hasattr (result, "__iter__") and callable (result.__iter__)): # We can get an iterator! self.repeatVariable = simpleTALES.IteratorRepeatVariable (result.__iter__()) elif (hasattr (result, "next") and callable (result.next)): # Treat as an iterator self.repeatVariable = simpleTALES.IteratorRepeatVariable (result) else: # Just a plain object, let's not loop # Delete the tags and their contents self.outputTag = 0 self.programCounter = self.symbolTable [args[2]] return try: curValue = self.repeatVariable.getCurrentValue() except IndexError, e: # The iterator ran out of values before we started - treat as an empty list self.outputTag = 0 self.repeatVariable = None self.programCounter = self.symbolTable [args[2]] return # We really do want to repeat - so lets do it self.movePCBack = self.programCounter self.context.addRepeat (args[0], self.repeatVariable, curValue) # We keep the old state of the repeatAttributesCopy for nested loops self.scopeStack.append (self.repeatAttributesCopy) # Keep a copy of the current attributes for this tag self.repeatAttributesCopy = copy.copy (self.currentAttributes) self.programCounter += 1 def cmdContent (self, command, args): """ args: (replaceFlag, structureFlag, expression, endTagSymbol) Expands content """ result = self.context.evaluate (args[2], self.originalAttributes) if (result is None): if (args[0]): # Only output tags if this is a content not a replace self.outputTag = 0 # Output none of our content or the existing content, but potentially the tags self.movePCForward = self.symbolTable [args[3]] self.programCounter += 1 return elif (not result == simpleTALES.DEFAULTVALUE): # We have content, so let's suppress the natural content and output this! if (args[0]): self.outputTag = 0 self.tagContent = (args[1], result) self.movePCForward = self.symbolTable [args[3]] self.programCounter += 1 return else: # Default, let's just run through as normal self.programCounter += 1 return def cmdAttributes (self, command, args): """ args: [(attributeName, expression)] Add, leave, or remove attributes from the start tag """ attsToRemove = {} newAtts = [] for attName, attExpr in args: resultVal = self.context.evaluate (attExpr, self.originalAttributes) if (resultVal is None): # Remove this attribute from the current attributes attsToRemove [attName]=1 elif (not resultVal == simpleTALES.DEFAULTVALUE): # We have a value - let's use it! attsToRemove [attName]=1 if (isinstance (resultVal, types.UnicodeType)): escapedAttVal = resultVal elif (isinstance (resultVal, types.StringType)): # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii escapedAttVal = unicode (resultVal, 'ascii') else: # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii escapedAttVal = unicode (resultVal) newAtts.append ((attName, escapedAttVal)) # Copy over the old attributes for oldAttName, oldAttValue in self.currentAttributes: if (not attsToRemove.has_key (oldAttName)): newAtts.append ((oldAttName, oldAttValue)) self.currentAttributes = newAtts # Evaluate all other commands self.programCounter += 1 def cmdOmitTag (self, command, args): """ args: expression Conditionally turn off tag output """ result = self.context.evaluate (args, self.originalAttributes) if (result is not None and result): # Turn tag output off self.outputTag = 0 self.programCounter += 1 def cmdOutputStartTag (self, command, args): # Args: tagName tagName, singletonTag = args if (self.outputTag): if (self.tagContent is None and singletonTag): self.file.write (self.tagAsText ((tagName, self.currentAttributes), 1)) else: self.file.write (self.tagAsText ((tagName, self.currentAttributes))) if (self.movePCForward is not None): self.programCounter = self.movePCForward return self.programCounter += 1 return def cmdEndTagEndScope (self, command, args): # Args: tagName, omitFlag, singletonTag if (self.tagContent is not None): contentType, resultVal = self.tagContent if (contentType): if (isinstance (resultVal, Template)): # We have another template in the context, evaluate it! # Save our state! self.pushProgram() resultVal.expandInline (self.context, self.file, self) # Restore state self.popProgram() # End of the macro expansion (if any) so clear the parameters self.slotParameters = {} else: if (isinstance (resultVal, types.UnicodeType)): self.file.write (resultVal) elif (isinstance (resultVal, types.StringType)): # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (unicode (resultVal, 'ascii')) else: # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (unicode (resultVal)) else: if (isinstance (resultVal, types.UnicodeType)): self.file.write (cgi.escape (resultVal)) elif (isinstance (resultVal, types.StringType)): # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (cgi.escape (unicode (resultVal, 'ascii'))) else: # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (cgi.escape (unicode (resultVal))) if (self.outputTag and not args[1]): # Do NOT output end tag if a singleton with no content if not (args[2] and self.tagContent is None): self.file.write ('') if (self.movePCBack is not None): self.programCounter = self.movePCBack return if (self.localVarsDefined): self.context.popLocals() self.movePCForward,self.movePCBack,self.outputTag,self.originalAttributes,self.currentAttributes,self.repeatVariable,self.tagContent,self.localVarsDefined = self.scopeStack.pop() self.programCounter += 1 def cmdOutput (self, command, args): self.file.write (args) self.programCounter += 1 def cmdStartScope (self, command, args): """ args: (originalAttributes, currentAttributes) Pushes the current state onto the stack, and sets up the new state """ self.scopeStack.append ((self.movePCForward ,self.movePCBack ,self.outputTag ,self.originalAttributes ,self.currentAttributes ,self.repeatVariable ,self.tagContent ,self.localVarsDefined)) self.movePCForward = None self.movePCBack = None self.outputTag = 1 self.originalAttributes = args[0] self.currentAttributes = args[1] self.repeatVariable = None self.tagContent = None self.localVarsDefined = 0 self.programCounter += 1 def cmdNoOp (self, command, args): self.programCounter += 1 def cmdUseMacro (self, command, args): """ args: (macroExpression, slotParams, endTagSymbol) Evaluates the expression, if it resolves to a SubTemplate it then places the slotParams into currentSlots and then jumps to the end tag """ value = self.context.evaluate (args[0], self.originalAttributes) if (value is None): # Don't output anything self.outputTag = 0 # Output none of our content or the existing content self.movePCForward = self.symbolTable [args[2]] self.programCounter += 1 return if (not value == simpleTALES.DEFAULTVALUE and isinstance (value, SubTemplate)): # We have a macro, so let's use it self.outputTag = 0 self.slotParameters = args[1] self.tagContent = (1, value) # NOTE: WE JUMP STRAIGHT TO THE END TAG, NO OTHER TAL/METAL COMMANDS ARE EVALUATED. self.programCounter = self.symbolTable [args[2]] return else: # Default, let's just run through as normal self.programCounter += 1 return def cmdDefineSlot (self, command, args): """ args: (slotName, endTagSymbol) If the slotName is filled then that is used, otherwise the original conent is used. """ if (self.currentSlots.has_key (args[0])): # This slot is filled, so replace us with that content self.outputTag = 0 self.tagContent = (1, self.currentSlots [args[0]]) # Output none of our content or the existing content # NOTE: NO FURTHER TAL/METAL COMMANDS ARE EVALUATED self.programCounter = self.symbolTable [args[1]] return # Slot isn't filled, so just use our own content self.programCounter += 1 return class HTMLTemplateInterpreter (TemplateInterpreter): def __init__ (self, minimizeBooleanAtts = 0): TemplateInterpreter.__init__ (self) self.minimizeBooleanAtts = minimizeBooleanAtts if (minimizeBooleanAtts): # Override the tagAsText method for this instance self.tagAsText = self.tagAsTextMinimizeAtts def tagAsTextMinimizeAtts (self, (tag,atts), singletonFlag=0): """ This returns a tag as text. """ result = ["<"] result.append (tag) upperTag = tag.upper() for attName, attValue in atts: if (HTML_BOOLEAN_ATTS.has_key ('%s:%s' % (upperTag, attName.upper()))): # We should output a minimised boolean value result.append (' ') result.append (attName) else: result.append (' ') result.append (attName) result.append ('="') result.append (cgi.escape (attValue, quote=1)) result.append ('"') if (singletonFlag): result.append (" />") else: result.append (">") return "".join (result) class Template: def __init__ (self, commands, macros, symbols, doctype = None): self.commandList = commands self.macros = macros self.symbolTable = symbols self.doctype = doctype # Setup the macros for macro in self.macros.values(): macro.setParentTemplate (self) # Setup the slots for cmnd, arg in self.commandList: if (cmnd == METAL_USE_MACRO): # Set the parent of each slot slotMap = arg[1] for slot in slotMap.values(): slot.setParentTemplate (self) def expand (self, context, outputFile, outputEncoding=None, interpreter=None): """ This method will write to the outputFile, using the encoding specified, the expanded version of this template. The context passed in is used to resolve all expressions with the template. """ # This method must wrap outputFile if required by the encoding, and write out # any template pre-amble (DTD, Encoding, etc) self.expandInline (context, outputFile, interpreter) def expandInline (self, context, outputFile, interpreter=None): """ Internally used when expanding a template that is part of a context.""" if (interpreter is None): ourInterpreter = TemplateInterpreter() ourInterpreter.initialise (context, outputFile) else: ourInterpreter = interpreter try: ourInterpreter.execute (self) except UnicodeError, unierror: logging.error ("UnicodeError caused by placing a non-Unicode string in the Context object.") raise simpleTALES.ContextContentException ("Found non-unicode string in Context!") def getProgram (self): """ Returns a tuple of (commandList, startPoint, endPoint, symbolTable) """ return (self.commandList, 0, len (self.commandList), self.symbolTable) def __str__ (self): result = "Commands:\n" index = 0 for cmd in self.commandList: if (cmd[0] != METAL_USE_MACRO): result = result + "\n[%s] %s" % (str (index), str (cmd)) else: result = result + "\n[%s] %s, (%s{" % (str (index), str (cmd[0]), str (cmd[1][0])) for slot in cmd[1][1].keys(): result = result + "%s: %s" % (slot, str (cmd[1][1][slot])) result = result + "}, %s)" % str (cmd[1][2]) index += 1 result = result + "\n\nSymbols:\n" for symbol in self.symbolTable.keys(): result = result + "Symbol: " + str (symbol) + " points to: " + str (self.symbolTable[symbol]) + ", which is command: " + str (self.commandList[self.symbolTable[symbol]]) + "\n" result = result + "\n\nMacros:\n" for macro in self.macros.keys(): result = result + "Macro: " + str (macro) + " value of: " + str (self.macros[macro]) return result class SubTemplate (Template): """ A SubTemplate is part of another template, and is used for the METAL implementation. The two uses for this class are: 1 - metal:define-macro results in a SubTemplate that is the macro 2 - metal:fill-slot results in a SubTemplate that is a parameter to metal:use-macro """ def __init__ (self, startRange, endRangeSymbol): """ The parentTemplate is the template for which we are a sub-template. The startRange and endRange are indexes into the parent templates command list, and defines the range of commands that we can execute """ Template.__init__ (self, [], {}, {}) self.startRange = startRange self.endRangeSymbol = endRangeSymbol def setParentTemplate (self, parentTemplate): self.parentTemplate = parentTemplate self.commandList = parentTemplate.commandList self.symbolTable = parentTemplate.symbolTable def getProgram (self): """ Returns a tuple of (commandList, startPoint, endPoint, symbolTable) """ return (self.commandList, self.startRange, self.symbolTable[self.endRangeSymbol]+1, self.symbolTable) def __str__ (self): endRange = self.symbolTable [self.endRangeSymbol] result = "SubTemplate from %s to %s\n" % (str (self.startRange), str (endRange)) return result class HTMLTemplate (Template): """A specialised form of a template that knows how to output HTML """ def __init__ (self, commands, macros, symbols, doctype = None, minimizeBooleanAtts = 0): self.minimizeBooleanAtts = minimizeBooleanAtts Template.__init__ (self, commands, macros, symbols, doctype = None) def expand (self, context, outputFile, outputEncoding="ISO-8859-1",interpreter=None): """ This method will write to the outputFile, using the encoding specified, the expanded version of this template. The context passed in is used to resolve all expressions with the template. """ # This method must wrap outputFile if required by the encoding, and write out # any template pre-amble (DTD, Encoding, etc) encodingFile = codecs.lookup (outputEncoding)[3](outputFile, 'replace') self.expandInline (context, encodingFile, interpreter) def expandInline (self, context, outputFile, interpreter=None): """ Ensure we use the HTMLTemplateInterpreter""" if (interpreter is None): ourInterpreter = HTMLTemplateInterpreter(minimizeBooleanAtts = self.minimizeBooleanAtts) ourInterpreter.initialise (context, outputFile) else: ourInterpreter = interpreter Template.expandInline (self, context, outputFile, ourInterpreter) class XMLTemplate (Template): """A specialised form of a template that knows how to output XML """ def __init__ (self, commands, macros, symbols, doctype = None): Template.__init__ (self, commands, macros, symbols) self.doctype = doctype def expand (self, context, outputFile, outputEncoding="iso-8859-1", docType=None, suppressXMLDeclaration=0,interpreter=None): """ This method will write to the outputFile, using the encoding specified, the expanded version of this template. The context passed in is used to resolve all expressions with the template. """ # This method must wrap outputFile if required by the encoding, and write out # any template pre-amble (DTD, Encoding, etc) # Write out the XML prolog encodingFile = codecs.lookup (outputEncoding)[3](outputFile, 'replace') if (not suppressXMLDeclaration): if (outputEncoding.lower() != "utf-8"): encodingFile.write ('\n' % outputEncoding.lower()) else: encodingFile.write ('\n') if not docType and self.doctype: docType = self.doctype if docType: encodingFile.write (docType) encodingFile.write ('\n') self.expandInline (context, encodingFile, interpreter) class TemplateCompiler: def __init__ (self): """ Initialise a template compiler. """ self.commandList = [] self.tagStack = [] self.symbolLocationTable = {} self.macroMap = {} self.endTagSymbol = 1 self.commandHandler = {} self.commandHandler [TAL_DEFINE] = self.compileCmdDefine self.commandHandler [TAL_CONDITION] = self.compileCmdCondition self.commandHandler [TAL_REPEAT] = self.compileCmdRepeat self.commandHandler [TAL_CONTENT] = self.compileCmdContent self.commandHandler [TAL_REPLACE] = self.compileCmdReplace self.commandHandler [TAL_ATTRIBUTES] = self.compileCmdAttributes self.commandHandler [TAL_OMITTAG] = self.compileCmdOmitTag # Metal commands self.commandHandler [METAL_USE_MACRO] = self.compileMetalUseMacro self.commandHandler [METAL_DEFINE_SLOT] = self.compileMetalDefineSlot self.commandHandler [METAL_FILL_SLOT] = self.compileMetalFillSlot self.commandHandler [METAL_DEFINE_MACRO] = self.compileMetalDefineMacro # Default namespaces self.setTALPrefix ('tal') self.tal_namespace_prefix_stack = [] self.metal_namespace_prefix_stack = [] self.tal_namespace_prefix_stack.append ('tal') self.setMETALPrefix ('metal') self.metal_namespace_prefix_stack.append ('metal') self.log = logging.getLogger ("simpleTAL.TemplateCompiler") def setTALPrefix (self, prefix): self.tal_namespace_prefix = prefix self.tal_namespace_omittag = '%s:omit-tag' % self.tal_namespace_prefix self.tal_attribute_map = {} self.tal_attribute_map ['%s:attributes'%prefix] = TAL_ATTRIBUTES self.tal_attribute_map ['%s:content'%prefix]= TAL_CONTENT self.tal_attribute_map ['%s:define'%prefix] = TAL_DEFINE self.tal_attribute_map ['%s:replace'%prefix] = TAL_REPLACE self.tal_attribute_map ['%s:omit-tag'%prefix] = TAL_OMITTAG self.tal_attribute_map ['%s:condition'%prefix] = TAL_CONDITION self.tal_attribute_map ['%s:repeat'%prefix] = TAL_REPEAT def setMETALPrefix (self, prefix): self.metal_namespace_prefix = prefix self.metal_attribute_map = {} self.metal_attribute_map ['%s:define-macro'%prefix] = METAL_DEFINE_MACRO self.metal_attribute_map ['%s:use-macro'%prefix] = METAL_USE_MACRO self.metal_attribute_map ['%s:define-slot'%prefix] = METAL_DEFINE_SLOT self.metal_attribute_map ['%s:fill-slot'%prefix] = METAL_FILL_SLOT def popTALNamespace (self): newPrefix = self.tal_namespace_prefix_stack.pop() self.setTALPrefix (newPrefix) def popMETALNamespace (self): newPrefix = self.metal_namespace_prefix_stack.pop() self.setMETALPrefix (newPrefix) def tagAsText (self, (tag,atts), singletonFlag=0): """ This returns a tag as text. """ result = ["<"] result.append (tag) for attName, attValue in atts: result.append (' ') result.append (attName) result.append ('="') result.append (cgi.escape (attValue, quote=1)) result.append ('"') if (singletonFlag): result.append (" />") else: result.append (">") return "".join (result) def getTemplate (self): template = Template (self.commandList, self.macroMap, self.symbolLocationTable) return template def addCommand (self, command): if (command[0] == TAL_OUTPUT and (len (self.commandList) > 0) and self.commandList[-1][0] == TAL_OUTPUT): # We can combine output commands self.commandList[-1] = (TAL_OUTPUT, self.commandList[-1][1] + command[1]) else: self.commandList.append (command) def addTag (self, tag, tagProperties={}): """ Used to add a tag to the stack. Various properties can be passed in the dictionary as being information required by the tag. Currently supported properties are: 'command' - The (command,args) tuple associated with this command 'originalAtts' - The original attributes that include any metal/tal attributes 'endTagSymbol' - The symbol associated with the end tag for this element 'popFunctionList' - A list of functions to execute when this tag is popped 'singletonTag' - A boolean to indicate that this is a singleton flag """ # Add the tag to the tagStack (list of tuples (tag, properties, useMacroLocation)) self.log.debug ("Adding tag %s to stack" % tag[0]) command = tagProperties.get ('command',None) originalAtts = tagProperties.get ('originalAtts', None) singletonTag = tagProperties.get ('singletonTag', 0) if (command is not None): if (command[0] == METAL_USE_MACRO): self.tagStack.append ((tag, tagProperties, len (self.commandList)+1)) else: self.tagStack.append ((tag, tagProperties, None)) else: self.tagStack.append ((tag, tagProperties, None)) if (command is not None): # All tags that have a TAL attribute on them start with a 'start scope' self.addCommand((TAL_START_SCOPE, (originalAtts, tag[1]))) # Now we add the TAL command self.addCommand(command) else: # It's just a straight output, so create an output command and append it self.addCommand((TAL_OUTPUT, self.tagAsText (tag, singletonTag))) def popTag (self, tag, omitTagFlag=0): """ omitTagFlag is used to control whether the end tag should be included in the output or not. In HTML 4.01 there are several tags which should never have end tags, this flag allows the template compiler to specify that these should not be output. """ while (len (self.tagStack) > 0): oldTag, tagProperties, useMacroLocation = self.tagStack.pop() endTagSymbol = tagProperties.get ('endTagSymbol', None) popCommandList = tagProperties.get ('popFunctionList', []) singletonTag = tagProperties.get ('singletonTag', 0) for func in popCommandList: apply (func, ()) self.log.debug ("Popped tag %s off stack" % oldTag[0]) if (oldTag[0] == tag[0]): # We've found the right tag, now check to see if we have any TAL commands on it if (endTagSymbol is not None): # We have a command (it's a TAL tag) # Note where the end tag symbol should point (i.e. the next command) self.symbolLocationTable [endTagSymbol] = len (self.commandList) # We need a "close scope and tag" command self.addCommand((TAL_ENDTAG_ENDSCOPE, (tag[0], omitTagFlag, singletonTag))) return elif (omitTagFlag == 0 and singletonTag == 0): # We are popping off an un-interesting tag, just add the close as text self.addCommand((TAL_OUTPUT, '')) return else: # We are suppressing the output of this tag, so just return return else: # We have a different tag, which means something like
which never closes is in # between us and the real tag. # If the tag that we did pop off has a command though it means un-balanced TAL tags! if (endTagSymbol is not None): # ERROR msg = "TAL/METAL Elements must be balanced - found close tag %s expecting %s" % (tag[0], oldTag[0]) self.log.error (msg) raise TemplateParseException (self.tagAsText(oldTag), msg) self.log.error ("Close tag %s found with no corresponding open tag." % tag[0]) raise TemplateParseException ("" % tag[0], "Close tag encountered with no corresponding open tag.") def parseStartTag (self, tag, attributes, singletonElement=0): # Note down the tag we are handling, it will be used for error handling during # compilation self.currentStartTag = (tag, attributes) # Look for tal/metal attributes foundTALAtts = [] foundMETALAtts = [] foundCommandsArgs = {} cleanAttributes = [] originalAttributes = {} tagProperties = {} popTagFuncList = [] TALElementNameSpace = 0 prefixToAdd = "" tagProperties ['singletonTag'] = singletonElement # Determine whether this element is in either the METAL or TAL namespace if (tag.find (':') > 0): # We have a namespace involved, so let's look to see if its one of ours namespace = tag[0:tag.find (':')] if (namespace == self.metal_namespace_prefix): TALElementNameSpace = 1 prefixToAdd = self.metal_namespace_prefix +":" elif (namespace == self.tal_namespace_prefix): TALElementNameSpace = 1 prefixToAdd = self.tal_namespace_prefix +":" if (TALElementNameSpace): # We should treat this an implicit omit-tag foundTALAtts.append (TAL_OMITTAG) # Will go to default, i.e. yes foundCommandsArgs [TAL_OMITTAG] = "" for att, value in attributes: originalAttributes [att] = value if (TALElementNameSpace and not att.find (':') > 0): # This means that the attribute name does not have a namespace, so use the prefix for this tag. commandAttName = prefixToAdd + att else: commandAttName = att self.log.debug ("Command name is now %s" % commandAttName) if (att[0:5] == "xmlns"): # We have a namespace declaration. prefix = att[6:] if (value == METAL_NAME_URI): # It's a METAL namespace declaration if (len (prefix) > 0): self.metal_namespace_prefix_stack.append (self.metal_namespace_prefix) self.setMETALPrefix (prefix) # We want this function called when the scope ends popTagFuncList.append (self.popMETALNamespace) else: # We don't allow METAL/TAL to be declared as a default msg = "Can not use METAL name space by default, a prefix must be provided." raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) elif (value == TAL_NAME_URI): # TAL this time if (len (prefix) > 0): self.tal_namespace_prefix_stack.append (self.tal_namespace_prefix) self.setTALPrefix (prefix) # We want this function called when the scope ends popTagFuncList.append (self.popTALNamespace) else: # We don't allow METAL/TAL to be declared as a default msg = "Can not use TAL name space by default, a prefix must be provided." raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) else: # It's nothing special, just an ordinary namespace declaration cleanAttributes.append ((att, value)) elif (self.tal_attribute_map.has_key (commandAttName)): # It's a TAL attribute cmnd = self.tal_attribute_map [commandAttName] if (cmnd == TAL_OMITTAG and TALElementNameSpace): self.log.warn ("Supressing omit-tag command present on TAL or METAL element") else: foundCommandsArgs [cmnd] = value foundTALAtts.append (cmnd) elif (self.metal_attribute_map.has_key (commandAttName)): # It's a METAL attribute cmnd = self.metal_attribute_map [commandAttName] foundCommandsArgs [cmnd] = value foundMETALAtts.append (cmnd) else: cleanAttributes.append ((att, value)) tagProperties ['popFunctionList'] = popTagFuncList # This might be just content if ((len (foundTALAtts) + len (foundMETALAtts)) == 0): # Just content, add it to the various stacks self.addTag ((tag, cleanAttributes), tagProperties) return # Create a symbol for the end of the tag - we don't know what the offset is yet self.endTagSymbol += 1 tagProperties ['endTagSymbol'] = self.endTagSymbol # Sort the METAL commands foundMETALAtts.sort() # Sort the tags by priority foundTALAtts.sort() # We handle the METAL before the TAL allCommands = foundMETALAtts + foundTALAtts firstTag = 1 for talAtt in allCommands: # Parse and create a command for each cmnd = self.commandHandler [talAtt](foundCommandsArgs[talAtt]) if (cmnd is not None): if (firstTag): # The first one needs to add the tag firstTag = 0 tagProperties ['originalAtts'] = originalAttributes tagProperties ['command'] = cmnd self.addTag ((tag, cleanAttributes), tagProperties) else: # All others just append self.addCommand(cmnd) if (firstTag): tagProperties ['originalAtts'] = originalAttributes tagProperties ['command'] = (TAL_STARTTAG, (tag, singletonElement)) self.addTag ((tag, cleanAttributes), tagProperties) else: # Add the start tag command in as a child of the last TAL command self.addCommand((TAL_STARTTAG, (tag,singletonElement))) def parseEndTag (self, tag): """ Just pop the tag and related commands off the stack. """ self.popTag ((tag,None)) def parseData (self, data): # Just add it as an output self.addCommand((TAL_OUTPUT, data)) def compileCmdDefine (self, argument): # Compile a define command, resulting argument is: # [(isLocalFlag (Y/n), variableName, variablePath),...] # Break up the list of defines first commandArgs = [] # We only want to match semi-colons that are not escaped argumentSplitter = re.compile ('(?2 elements means a local|global flag if (len (stmtBits) > 2): if (stmtBits[0] == 'global'): isLocal = 0 varName = stmtBits[1] expression = ' '.join (stmtBits[2:]) elif (stmtBits[0] == 'local'): varName = stmtBits[1] expression = ' '.join (stmtBits[2:]) else: # Must be a space in the expression that caused the >3 thing varName = stmtBits[0] expression = ' '.join (stmtBits[1:]) else: # Only two bits varName = stmtBits[0] expression = ' '.join (stmtBits[1:]) commandArgs.append ((isLocal, varName, expression)) return (TAL_DEFINE, commandArgs) def compileCmdCondition (self, argument): # Compile a condition command, resulting argument is: # path, endTagSymbol # Sanity check if (len (argument) == 0): # No argument passed msg = "No argument passed! condition commands must be of the form: 'path'" self.log.error (msg) raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) return (TAL_CONDITION, (argument, self.endTagSymbol)) def compileCmdRepeat (self, argument): # Compile a repeat command, resulting argument is: # (varname, expression, endTagSymbol) attProps = argument.split (' ') if (len (attProps) < 2): # Error, badly formed repeat command msg = "Badly formed repeat command '%s'. Repeat commands must be of the form: 'localVariable path'" % argument self.log.error (msg) raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) varName = attProps [0] expression = " ".join (attProps[1:]) return (TAL_REPEAT, (varName, expression, self.endTagSymbol)) def compileCmdContent (self, argument, replaceFlag=0): # Compile a content command, resulting argument is # (replaceFlag, structureFlag, expression, endTagSymbol) # Sanity check if (len (argument) == 0): # No argument passed msg = "No argument passed! content/replace commands must be of the form: 'path'" self.log.error (msg) raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) structureFlag = 0 attProps = argument.split (' ') if (len(attProps) > 1): if (attProps[0] == "structure"): structureFlag = 1 express = " ".join (attProps[1:]) elif (attProps[1] == "text"): structureFlag = 0 express = " ".join (attProps[1:]) else: # It's not a type selection after all - assume it's part of the path express = argument else: express = argument return (TAL_CONTENT, (replaceFlag, structureFlag, express, self.endTagSymbol)) def compileCmdReplace (self, argument): return self.compileCmdContent (argument, replaceFlag=1) def compileCmdAttributes (self, argument): # Compile tal:attributes into attribute command # Argument: [(attributeName, expression)] # Break up the list of attribute settings first commandArgs = [] # We only want to match semi-colons that are not escaped argumentSplitter = re.compile ('(?") else: result.append (">") return "".join (result) def handle_startendtag (self, tag, attributes): self.handle_starttag (tag, attributes) if not (HTML_FORBIDDEN_ENDTAG.has_key (tag.upper())): self.handle_endtag(tag) def handle_starttag (self, tag, attributes): self.log.debug ("Recieved Start Tag: " + tag + " Attributes: " + str (attributes)) atts = [] for att, attValue in attributes: # We need to spot empty tal:omit-tags if (attValue is None): if (att == self.tal_namespace_omittag): atts.append ((att, u"")) else: atts.append ((att, att)) else: # Expand any SGML entity references or char references goodAttValue = [] last = 0 match = ENTITY_REF_REGEX.search (attValue) while (match): goodAttValue.append (attValue[last:match.start()]) ref = attValue[match.start():match.end()] if (ref.startswith ('&#')): # A char reference if (ref[2] in ['x', 'X']): # Hex refValue = int (ref[3:-1], 16) else: refValue = int (ref[2:-1]) goodAttValue.append (unichr (refValue)) else: # A named reference. goodAttValue.append (unichr (sgmlentitynames.htmlNameToUnicodeNumber.get (ref[1:-1], 65533))) last = match.end() match = ENTITY_REF_REGEX.search (attValue, last) goodAttValue.append (attValue [last:]) atts.append ((att, u"".join (goodAttValue))) if (HTML_FORBIDDEN_ENDTAG.has_key (tag.upper())): # This should have no end tag, so we just do the start and suppress the end self.parseStartTag (tag, atts) self.log.debug ("End tag forbidden, generating close tag with no output.") self.popTag ((tag, None), omitTagFlag=1) else: self.parseStartTag (tag, atts) def handle_endtag (self, tag): self.log.debug ("Recieved End Tag: " + tag) if (HTML_FORBIDDEN_ENDTAG.has_key (tag.upper())): self.log.warn ("HTML 4.01 forbids end tags for the %s element" % tag) else: # Normal end tag self.popTag ((tag, None)) def handle_data (self, data): self.parseData (cgi.escape (data)) # These two methods are required so that we expand all character and entity references prior to parsing the template. def handle_charref (self, ref): self.log.debug ("Got Ref: %s", ref) self.parseData (unichr (int (ref))) def handle_entityref (self, ref): self.log.debug ("Got Ref: %s", ref) # Use handle_data so that <&> are re-encoded as required. self.handle_data( unichr (sgmlentitynames.htmlNameToUnicodeNumber.get (ref, 65533))) # Handle document type declarations def handle_decl (self, data): self.parseData (u'' % data) # Pass comments through un-affected. def handle_comment (self, data): self.parseData (u'' % data) def handle_pi (self, data): self.log.debug ("Recieved processing instruction.") self.parseData (u'' % data) def report_unbalanced (self, tag): self.log.warn ("End tag %s present with no corresponding open tag.") def getTemplate (self): template = HTMLTemplate (self.commandList, self.macroMap, self.symbolLocationTable, minimizeBooleanAtts = self.minimizeBooleanAtts) return template class XMLTemplateCompiler (TemplateCompiler, xml.sax.handler.ContentHandler, xml.sax.handler.DTDHandler, LexicalHandler): def __init__ (self): TemplateCompiler.__init__ (self) xml.sax.handler.ContentHandler.__init__ (self) self.doctype = None self.log = logging.getLogger ("simpleTAL.XMLTemplateCompiler") self.singletonElement = 0 def parseTemplate (self, file): self.ourParser = xml.sax.make_parser() self.log.debug ("Setting features of parser") try: self.ourParser.setFeature (xml.sax.handler.feature_external_ges, 0) except: pass if use_lexical_handler: self.ourParser.setProperty(xml.sax.handler.property_lexical_handler, self) self.ourParser.setContentHandler (self) self.ourParser.setDTDHandler (self) self.ourParser.parse (file) def parseDOM (self, dom): if (not use_dom2sax): self.log.critical ("PyXML is not available, DOM can not be parsed.") self.ourParser = xml.dom.ext.Dom2Sax.Dom2SaxParser() self.log.debug ("Setting features of parser") if use_lexical_handler: self.ourParser.setProperty(xml.sax.handler.property_lexical_handler, self) self.ourParser.setContentHandler (self) self.ourParser.setDTDHandler (self) self.ourParser.parse (dom) def startDTD(self, name, public_id, system_id): self.log.debug ("Recieved DOCTYPE: " + name + " public_id: " + public_id + " system_id: " + system_id) if public_id: self.doctype = '' % (name, public_id, system_id,) else: self.doctype = '' % (name, system_id,) def startElement (self, tag, attributes): self.log.debug ("Recieved Real Start Tag: " + tag + " Attributes: " + str (attributes)) try: xmlText = self.ourParser.getProperty (xml.sax.handler.property_xml_string) if (SINGLETON_XML_REGEX.match (xmlText)): # This is a singleton! self.singletonElement=1 except xml.sax.SAXException, e: # Parser doesn't support this property pass # Convert attributes into a list of tuples atts = [] for att in attributes.getNames(): self.log.debug ("Attribute name %s has value %s" % (att, attributes[att])) atts.append ((att, attributes [att])) self.parseStartTag (tag, atts, singletonElement=self.singletonElement) def endElement (self, tag): self.log.debug ("Recieved Real End Tag: " + tag) self.parseEndTag (tag) self.singletonElement = 0 def characters (self, data): #self.log.debug ("Recieved Real Data: " + data) # Escape any data we recieve - we don't want any: <&> in there. self.parseData (cgi.escape (data)) def processingInstruction (self, target, data): self.log.debug ("Recieved processing instruction.") self.parseData (u'' % (target, data)) def comment (self, data): # This is only called if your XML parser supports the LexicalHandler interface. self.parseData (u'' % data) def getTemplate (self): template = XMLTemplate (self.commandList, self.macroMap, self.symbolLocationTable, self.doctype) return template def compileHTMLTemplate (template, inputEncoding="ISO-8859-1", minimizeBooleanAtts = 0): """ Reads the templateFile and produces a compiled template. To use the resulting template object call: template.expand (context, outputFile) """ if (isinstance (template, types.StringType) or isinstance (template, types.UnicodeType)): # It's a string! templateFile = StringIO.StringIO (template) else: templateFile = template compiler = HTMLTemplateCompiler() compiler.parseTemplate (templateFile, inputEncoding, minimizeBooleanAtts) return compiler.getTemplate() def compileXMLTemplate (template): """ Reads the templateFile and produces a compiled template. To use the resulting template object call: template.expand (context, outputFile) """ if (isinstance (template, types.StringType)): # It's a string! templateFile = StringIO.StringIO (template) else: templateFile = template compiler = XMLTemplateCompiler() compiler.parseTemplate (templateFile) return compiler.getTemplate() def compileDOMTemplate (template): """ Traverses the DOM and produces a compiled template. To use the resulting template object call: template.expand (context, outputFile) """ compiler = XMLTemplateCompiler () compiler.parseDOM (template) return compiler.getTemplate() SimpleTAL-4.1/lib/simpletal/FixedHTMLParser.py0000644000175000017500000000360110364672755020000 0ustar cms103cms103""" Fixed up HTMLParser Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! The classes in this module implement the TAL language, expanding both XML and HTML templates. Module Dependencies: logging, simpleTALES, simpleTALTemplates """ import simpletal import HTMLParser class HTMLParser (HTMLParser.HTMLParser): def unescape(self, s): # Just return the data - we don't partially unescaped data! return s SimpleTAL-4.1/lib/simpletal/sgmlentitynames.py0000644000175000017500000001545610143200164020305 0ustar cms103cms103""" simpleTAL Implementation Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! A dictionary of HTML entity names to their decimal value. """ htmlNameToUnicodeNumber = {"nbsp": 160 ,"iexcl": 161 ,"cent": 162 ,"pound": 163 ,"curren": 164 ,"yen": 165 ,"brvbar": 166 ,"sect": 167 ,"uml": 168 ,"copy": 169 ,"ordf": 170 ,"laquo": 171 ,"not": 172 ,"shy": 173 ,"reg": 174 ,"macr": 175 ,"deg": 176 ,"plusmn": 177 ,"sup2": 178 ,"sup3": 179 ,"acute": 180 ,"micro": 181 ,"para": 182 ,"middot": 183 ,"cedil": 184 ,"sup1": 185 ,"ordm": 186 ,"raquo": 187 ,"frac14": 188 ,"frac12": 189 ,"frac34": 190 ,"iquest": 191 ,"Agrave": 192 ,"Aacute": 193 ,"Acirc": 194 ,"Atilde": 195 ,"Auml": 196 ,"Aring": 197 ,"AElig": 198 ,"Ccedil": 199 ,"Egrave": 200 ,"Eacute": 201 ,"Ecirc": 202 ,"Euml": 203 ,"Igrave": 204 ,"Iacute": 205 ,"Icirc": 206 ,"Iuml": 207 ,"ETH": 208 ,"Ntilde": 209 ,"Ograve": 210 ,"Oacute": 211 ,"Ocirc": 212 ,"Otilde": 213 ,"Ouml": 214 ,"times": 215 ,"Oslash": 216 ,"Ugrave": 217 ,"Uacute": 218 ,"Ucirc": 219 ,"Uuml": 220 ,"Yacute": 221 ,"THORN": 222 ,"szlig": 223 ,"agrave": 224 ,"aacute": 225 ,"acirc": 226 ,"atilde": 227 ,"auml": 228 ,"aring": 229 ,"aelig": 230 ,"ccedil": 231 ,"egrave": 232 ,"eacute": 233 ,"ecirc": 234 ,"euml": 235 ,"igrave": 236 ,"iacute": 237 ,"icirc": 238 ,"iuml": 239 ,"eth": 240 ,"ntilde": 241 ,"ograve": 242 ,"oacute": 243 ,"ocirc": 244 ,"otilde": 245 ,"ouml": 246 ,"divide": 247 ,"oslash": 248 ,"ugrave": 249 ,"uacute": 250 ,"ucirc": 251 ,"uuml": 252 ,"yacute": 253 ,"thorn": 254 ,"yuml": 255 ,"fnof": 402 ,"Alpha": 913 ,"Beta": 914 ,"Gamma": 915 ,"Delta": 916 ,"Epsilon": 917 ,"Zeta": 918 ,"Eta": 919 ,"Theta": 920 ,"Iota": 921 ,"Kappa": 922 ,"Lambda": 923 ,"Mu": 924 ,"Nu": 925 ,"Xi": 926 ,"Omicron": 927 ,"Pi": 928 ,"Rho": 929 ,"Sigma": 931 ,"Tau": 932 ,"Upsilon": 933 ,"Phi": 934 ,"Chi": 935 ,"Psi": 936 ,"Omega": 937 ,"alpha": 945 ,"beta": 946 ,"gamma": 947 ,"delta": 948 ,"epsilon": 949 ,"zeta": 950 ,"eta": 951 ,"theta": 952 ,"iota": 953 ,"kappa": 954 ,"lambda": 955 ,"mu": 956 ,"nu": 957 ,"xi": 958 ,"omicron": 959 ,"pi": 960 ,"rho": 961 ,"sigmaf": 962 ,"sigma": 963 ,"tau": 964 ,"upsilon": 965 ,"phi": 966 ,"chi": 967 ,"psi": 968 ,"omega": 969 ,"thetasym": 977 ,"upsih": 978 ,"piv": 982 ,"bull": 8226 ,"hellip": 8230 ,"prime": 8242 ,"Prime": 8243 ,"oline": 8254 ,"frasl": 8260 ,"weierp": 8472 ,"image": 8465 ,"real": 8476 ,"trade": 8482 ,"alefsym": 8501 ,"larr": 8592 ,"uarr": 8593 ,"rarr": 8594 ,"darr": 8595 ,"harr": 8596 ,"crarr": 8629 ,"lArr": 8656 ,"uArr": 8657 ,"rArr": 8658 ,"dArr": 8659 ,"hArr": 8660 ,"forall": 8704 ,"part": 8706 ,"exist": 8707 ,"empty": 8709 ,"nabla": 8711 ,"isin": 8712 ,"notin": 8713 ,"ni": 8715 ,"prod": 8719 ,"sum": 8721 ,"minus": 8722 ,"lowast": 8727 ,"radic": 8730 ,"prop": 8733 ,"infin": 8734 ,"ang": 8736 ,"and": 8743 ,"or": 8744 ,"cap": 8745 ,"cup": 8746 ,"int": 8747 ,"there4": 8756 ,"sim": 8764 ,"cong": 8773 ,"asymp": 8776 ,"ne": 8800 ,"equiv": 8801 ,"le": 8804 ,"ge": 8805 ,"sub": 8834 ,"sup": 8835 ,"nsub": 8836 ,"sube": 8838 ,"supe": 8839 ,"oplus": 8853 ,"otimes": 8855 ,"perp": 8869 ,"sdot": 8901 ,"lceil": 8968 ,"rceil": 8969 ,"lfloor": 8970 ,"rfloor": 8971 ,"lang": 9001 ,"rang": 9002 ,"loz": 9674 ,"spades": 9824 ,"clubs": 9827 ,"hearts": 9829 ,"diams": 9830 ,"quot": 34 ,"amp": 38 ,"lt": 60 ,"gt": 62 ,"OElig": 338 ,"oelig": 339 ,"Scaron": 352 ,"scaron": 353 ,"Yuml": 376 ,"circ": 710 ,"tilde": 732 ,"ensp": 8194 ,"emsp": 8195 ,"thinsp": 8201 ,"zwnj": 8204 ,"zwj": 8205 ,"lrm": 8206 ,"rlm": 8207 ,"ndash": 8211 ,"mdash": 8212 ,"lsquo": 8216 ,"rsquo": 8217 ,"sbquo": 8218 ,"ldquo": 8220 ,"rdquo": 8221 ,"bdquo": 8222 ,"dagger": 8224 ,"Dagger": 8225 ,"permil": 8240 ,"lsaquo": 8249 ,"rsaquo": 8250 ,"euro": 8364} SimpleTAL-4.1/lib/simpletal/DummyLogger.py0000644000175000017500000000402410007245151017306 0ustar cms103cms103""" simpleTALES Implementation Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! Dummy logging module, used when logging (http://www.red-dove.com/python_logging.html) is not installed. """ class DummyLogger: def debug (self, *args): pass def info (self, *args): pass def warn (self, *args): pass def error (self, *args): pass def critical (self, *args): pass def getLogger (*params): return DummyLogger() def debug (*args): pass def info (*args): pass def warn (*args): pass def error (*args): pass def critical (*args): pass SimpleTAL-4.1/lib/simpletal/simpleElementTree.py0000644000175000017500000001011410275154602020502 0ustar cms103cms103""" ElementTree integration for SimpleTAL Copyright (c) 2004 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! The parseFile function in this module will return a Element object that implements simpleTALES.ContextVariable and makes XML documents available with the following path logic: - Accessing Element directly returns the Element.text value - Accessing Element/find and Element/findall passes the text (up to attribute accessor) to the corresponding Element function - Accessing the Element@name access the attribute "name" - Accessing Element/anotherElement is a short-cut for Element/find/anotherElement Module Dependencies: simpleTALES, elementtree """ from elementtree import ElementTree import simpleTALES class SimpleElementTreeVar (ElementTree._ElementInterface, simpleTALES.ContextVariable): def __init__(self, tag, attrib): ElementTree._ElementInterface.__init__(self, tag, attrib) simpleTALES.ContextVariable.__init__(self) def value (self, pathInfo = None): if (pathInfo is not None): pathIndex, paths = pathInfo ourParams = paths[pathIndex:] attributeName = None if (len (ourParams) > 0): # Look for attribute index if (ourParams[-1].startswith ('@')): # Attribute lookup attributeName = ourParams [-1][1:] ourParams = ourParams [:-1] # Do we do a find? activeElement = self if len (ourParams) > 0: # Look for a find or findall first if (ourParams [0] == 'find'): # Find the element if possible activeElement = self.find ("/".join (ourParams [1:])) elif (ourParams [0] == 'findall'): # Short cut this raise simpleTALES.ContextVariable (self.findall ("/".join (ourParams[1:]))) else: # Assume that we wanted to use find activeElement = self.find ("/".join (ourParams)) # Did we find an element and are we looking for an attribute? if (attributeName is not None and activeElement is not None): attrValue = activeElement.attrib.get (attributeName, None) raise simpleTALES.ContextVariable (attrValue) # Just return the element if (activeElement is None): # Wrap it raise simpleTALES.ContextVariable (None) raise activeElement else: return self def __unicode__ (self): return self.text def __str__ (self): return str (self.text) def parseFile (file): treeBuilder = ElementTree.TreeBuilder (element_factory = SimpleElementTreeVar) xmlTreeBuilder = ElementTree.XMLTreeBuilder (target=treeBuilder) if (not hasattr (file, 'read')): ourFile = open (file) xmlTreeBuilder.feed (ourFile.read()) ourFile.close() else: xmlTreeBuilder.feed (file.read()) return xmlTreeBuilder.close() SimpleTAL-4.1/lib/simpletal/simpleTALUtils.py0000644000175000017500000002536310275504577017760 0ustar cms103cms103""" simpleTALUtils Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! This module is holds utilities that make using SimpleTAL easier. Initially this is just the HTMLStructureCleaner class, used to clean up HTML that can then be used as 'structure' content. Module Dependencies: None """ import StringIO, os, stat, threading, sys, codecs, sgmllib, cgi, re, types import simpletal, simpleTAL __version__ = simpletal.__version__ # This is used to check for already escaped attributes. ESCAPED_TEXT_REGEX=re.compile (r"\&\S+?;") class HTMLStructureCleaner (sgmllib.SGMLParser): """ A helper class that takes HTML content and parses it, so converting any stray '&', '<', or '>' symbols into their respective entity references. """ def clean (self, content, encoding=None): """ Takes the HTML content given, parses it, and converts stray markup. The content can be either: - A unicode string, in which case the encoding parameter is not required - An ordinary string, in which case the encoding will be used - A file-like object, in which case the encoding will be used if present The method returns a unicode string which is suitable for addition to a simpleTALES.Context object. """ if (isinstance (content, types.StringType)): # Not unicode, convert converter = codecs.lookup (encoding)[1] file = StringIO.StringIO (converter (content)[0]) elif (isinstance (content, types.UnicodeType)): file = StringIO.StringIO (content) else: # Treat it as a file type object - and convert it if we have an encoding if (encoding is not None): converterStream = codecs.lookup (encoding)[2] file = converterStream (content) else: file = content self.outputFile = StringIO.StringIO (u"") self.feed (file.read()) self.close() return self.outputFile.getvalue() def unknown_starttag (self, tag, attributes): self.outputFile.write (tagAsText (tag, attributes)) def unknown_endtag (self, tag): self.outputFile.write ('') def handle_data (self, data): self.outputFile.write (cgi.escape (data)) def handle_charref (self, ref): self.outputFile.write (u'&#%s;' % ref) def handle_entityref (self, ref): self.outputFile.write (u'&%s;' % ref) class FastStringOutput: """ A very simple StringIO replacement that only provides write() and getvalue() and is around 6% faster than StringIO. """ def __init__ (self): self.data = [] def write (self, data): self.data.append (data) def getvalue (self): return "".join (self.data) class TemplateCache: """ A TemplateCache is a multi-thread safe object that caches compiled templates. This cache only works with file based templates, the ctime of the file is checked on each hit, if the file has changed the template is re-compiled. """ def __init__ (self): self.templateCache = {} self.cacheLock = threading.Lock() self.hits = 0 self.misses = 0 def getTemplate (self, name, inputEncoding='ISO-8859-1'): """ Name should be the path of a template file. If the path ends in 'xml' it is treated as an XML Template, otherwise it's treated as an HTML Template. If the template file has changed since the last cache it will be re-compiled. inputEncoding is only used for HTML templates, and should be the encoding that the template is stored in. """ if (self.templateCache.has_key (name)): template, oldctime = self.templateCache [name] ctime = os.stat (name)[stat.ST_MTIME] if (oldctime == ctime): # Cache hit! self.hits += 1 return template # Cache miss, let's cache this template return self._cacheTemplate_ (name, inputEncoding) def getXMLTemplate (self, name): """ Name should be the path of an XML template file. """ if (self.templateCache.has_key (name)): template, oldctime = self.templateCache [name] ctime = os.stat (name)[stat.ST_MTIME] if (oldctime == ctime): # Cache hit! self.hits += 1 return template # Cache miss, let's cache this template return self._cacheTemplate_ (name, None, xmlTemplate=1) def _cacheTemplate_ (self, name, inputEncoding, xmlTemplate=0): self.cacheLock.acquire () try: tempFile = open (name, 'r') if (xmlTemplate): # We know it is XML template = simpleTAL.compileXMLTemplate (tempFile) else: # We have to guess... firstline = tempFile.readline() tempFile.seek(0) if (name [-3:] == "xml") or (firstline.strip ()[:5] == '" return result class MacroExpansionInterpreter (simpleTAL.TemplateInterpreter): def __init__ (self): simpleTAL.TemplateInterpreter.__init__ (self) # Override the standard interpreter way of doing things. self.macroStateStack = [] self.commandHandler [simpleTAL.TAL_DEFINE] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_CONDITION] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_REPEAT] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_CONTENT] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_ATTRIBUTES] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_OMITTAG] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_START_SCOPE] = self.cmdStartScope self.commandHandler [simpleTAL.TAL_OUTPUT] = self.cmdOutput self.commandHandler [simpleTAL.TAL_STARTTAG] = self.cmdOutputStartTag self.commandHandler [simpleTAL.TAL_ENDTAG_ENDSCOPE] = self.cmdEndTagEndScope self.commandHandler [simpleTAL.METAL_USE_MACRO] = self.cmdUseMacro self.commandHandler [simpleTAL.METAL_DEFINE_SLOT] = self.cmdDefineSlot self.commandHandler [simpleTAL.TAL_NOOP] = self.cmdNoOp self.inMacro = None self.macroArg = None # Original cmdOutput # Original cmdEndTagEndScope def popProgram (self): self.inMacro = self.macroStateStack.pop() simpleTAL.TemplateInterpreter.popProgram (self) def pushProgram (self): self.macroStateStack.append (self.inMacro) simpleTAL.TemplateInterpreter.pushProgram (self) def cmdOutputStartTag (self, command, args): newAtts = [] for att, value in self.originalAttributes.items(): if (self.macroArg is not None and att == "metal:define-macro"): newAtts.append (("metal:use-macro",self.macroArg)) elif (self.inMacro and att=="metal:define-slot"): newAtts.append (("metal:fill-slot", value)) else: newAtts.append ((att, value)) self.macroArg = None self.currentAttributes = newAtts simpleTAL.TemplateInterpreter.cmdOutputStartTag (self, command, args) def cmdUseMacro (self, command, args): simpleTAL.TemplateInterpreter.cmdUseMacro (self, command, args) if (self.tagContent is not None): # We have a macro, add the args to the in-macro list self.inMacro = 1 self.macroArg = args[0] def cmdEndTagEndScope (self, command, args): # Args: tagName, omitFlag if (self.tagContent is not None): contentType, resultVal = self.tagContent if (contentType): if (isinstance (resultVal, simpleTAL.Template)): # We have another template in the context, evaluate it! # Save our state! self.pushProgram() resultVal.expandInline (self.context, self.file, self) # Restore state self.popProgram() # End of the macro expansion (if any) so clear the parameters self.slotParameters = {} # End of the macro self.inMacro = 0 else: if (isinstance (resultVal, types.UnicodeType)): self.file.write (resultVal) elif (isinstance (resultVal, types.StringType)): self.file.write (unicode (resultVal, 'ascii')) else: self.file.write (unicode (str (resultVal), 'ascii')) else: if (isinstance (resultVal, types.UnicodeType)): self.file.write (cgi.escape (resultVal)) elif (isinstance (resultVal, types.StringType)): self.file.write (cgi.escape (unicode (resultVal, 'ascii'))) else: self.file.write (cgi.escape (unicode (str (resultVal), 'ascii'))) if (self.outputTag and not args[1]): self.file.write ('') if (self.movePCBack is not None): self.programCounter = self.movePCBack return if (self.localVarsDefined): self.context.popLocals() self.movePCForward,self.movePCBack,self.outputTag,self.originalAttributes,self.currentAttributes,self.repeatVariable,self.tagContent,self.localVarsDefined = self.scopeStack.pop() self.programCounter += 1 def ExpandMacros (context, template, outputEncoding="ISO-8859-1"): out = StringIO.StringIO() interp = MacroExpansionInterpreter() interp.initialise (context, out) template.expand (context, out, outputEncoding=outputEncoding, interpreter=interp) # StringIO returns unicode, so we need to turn it back into native string result = out.getvalue() reencoder = codecs.lookup (outputEncoding)[0] return reencoder (result)[0] SimpleTAL-4.1/lib/simpletal/__init__.py0000644000175000017500000000002410364736707016630 0ustar cms103cms103__version__ = "4.1" SimpleTAL-4.1/lib/simpletal/simpleTALES.py0000644000175000017500000004537610347326342017165 0ustar cms103cms103""" simpleTALES Implementation Copyright (c) 2005 Colin Stewart (http://www.owlfish.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! The classes in this module implement the TALES specification, used by the simpleTAL module. Module Dependencies: logging """ import types, sys try: import logging except: import DummyLogger as logging import simpletal, simpleTAL __version__ = simpletal.__version__ DEFAULTVALUE = "This represents a Default value." class PathNotFoundException (Exception): pass class ContextContentException (Exception): """ This is raised when invalid content has been placed into the Context object. For example using non-ascii characters instead of Unicode strings. """ pass PATHNOTFOUNDEXCEPTION = PathNotFoundException() class ContextVariable: def __init__ (self, value = None): self.ourValue = value def value (self, currentPath=None): if (callable (self.ourValue)): return apply (self.ourValue, ()) return self.ourValue def rawValue (self): return self.ourValue def __str__ (self): return repr (self.ourValue) class RepeatVariable (ContextVariable): """ To be written""" def __init__ (self, sequence): ContextVariable.__init__ (self, 1) self.sequence = sequence self.position = 0 self.map = None def value (self, currentPath=None): if (self.map is None): self.createMap() return self.map def rawValue (self): return self.value() def getCurrentValue (self): return self.sequence [self.position] def increment (self): self.position += 1 if (self.position == len (self.sequence)): raise IndexError ("Repeat Finished") def createMap (self): self.map = {} self.map ['index'] = self.getIndex self.map ['number'] = self.getNumber self.map ['even'] = self.getEven self.map ['odd'] = self.getOdd self.map ['start'] = self.getStart self.map ['end'] = self.getEnd # TODO: first and last need to be implemented. self.map ['length'] = len (self.sequence) self.map ['letter'] = self.getLowerLetter self.map ['Letter'] = self.getUpperLetter self.map ['roman'] = self.getLowerRoman self.map ['Roman'] = self.getUpperRoman # Repeat implementation goes here def getIndex (self): return self.position def getNumber (self): return self.position + 1 def getEven (self): if ((self.position % 2) != 0): return 0 return 1 def getOdd (self): if ((self.position % 2) == 0): return 0 return 1 def getStart (self): if (self.position == 0): return 1 return 0 def getEnd (self): if (self.position == len (self.sequence) - 1): return 1 return 0 def getLowerLetter (self): result = "" nextCol = self.position if (nextCol == 0): return 'a' while (nextCol > 0): nextCol, thisCol = divmod (nextCol, 26) result = chr (ord ('a') + thisCol) + result return result def getUpperLetter (self): return self.getLowerLetter().upper() def getLowerRoman (self): romanNumeralList = (('m', 1000) ,('cm', 900) ,('d', 500) ,('cd', 400) ,('c', 100) ,('xc', 90) ,('l', 50) ,('xl', 40) ,('x', 10) ,('ix', 9) ,('v', 5) ,('iv', 4) ,('i', 1) ) if (self.position > 3999): # Roman numbers only supported up to 4000 return ' ' num = self.position + 1 result = "" for roman, integer in romanNumeralList: while (num >= integer): result += roman num -= integer return result def getUpperRoman (self): return self.getLowerRoman().upper() class IteratorRepeatVariable (RepeatVariable): def __init__ (self, sequence): RepeatVariable.__init__ (self, sequence) self.curValue = None self.iterStatus = 0 def getCurrentValue (self): if (self.iterStatus == 0): self.iterStatus = 1 try: self.curValue = self.sequence.next() except StopIteration, e: self.iterStatus = 2 raise IndexError ("Repeat Finished") return self.curValue def increment (self): # Need this for the repeat variable functions. self.position += 1 try: self.curValue = self.sequence.next() except StopIteration, e: self.iterStatus = 2 raise IndexError ("Repeat Finished") def createMap (self): self.map = {} self.map ['index'] = self.getIndex self.map ['number'] = self.getNumber self.map ['even'] = self.getEven self.map ['odd'] = self.getOdd self.map ['start'] = self.getStart self.map ['end'] = self.getEnd # TODO: first and last need to be implemented. self.map ['length'] = sys.maxint self.map ['letter'] = self.getLowerLetter self.map ['Letter'] = self.getUpperLetter self.map ['roman'] = self.getLowerRoman self.map ['Roman'] = self.getUpperRoman def getEnd (self): if (self.iterStatus == 2): return 1 return 0 class PathFunctionVariable (ContextVariable): def __init__ (self, func): ContextVariable.__init__ (self, value = func) self.func = func def value (self, currentPath=None): if (currentPath is not None): index, paths = currentPath result = ContextVariable (apply (self.func, ('/'.join (paths[index:]),))) # Fast track the result raise result class CachedFuncResult (ContextVariable): def value (self, currentPath=None): try: return self.cachedValue except: self.cachedValue = ContextVariable.value (self) return self.cachedValue def clearCache (self): try: del self.cachedValue except: pass class PythonPathFunctions: def __init__ (self, context): self.context = context def path (self, expr): return self.context.evaluatePath (expr) def string (self, expr): return self.context.evaluateString (expr) def exists (self, expr): return self.context.evaluateExists (expr) def nocall (self, expr): return self.context.evaluateNoCall (expr) def test (self, *arguments): if (len (arguments) % 2): # We have an odd number of arguments - which means the last one is a default pairs = arguments[:-1] defaultValue = arguments[-1] else: # No default - so use None pairs = arguments defaultValue = None index = 0 while (index < len (pairs)): test = pairs[index] index += 1 value = pairs[index] index += 1 if (test): return value return defaultValue class Context: def __init__ (self, options=None, allowPythonPath=0): self.allowPythonPath = allowPythonPath self.globals = {} self.locals = {} self.localStack = [] self.repeatStack = [] self.populateDefaultVariables (options) self.log = logging.getLogger ("simpleTALES.Context") self.true = 1 self.false = 0 self.pythonPathFuncs = PythonPathFunctions (self) def addRepeat (self, name, var, initialValue): # Pop the current repeat map onto the stack self.repeatStack.append (self.repeatMap) self.repeatMap = self.repeatMap.copy() self.repeatMap [name] = var # Map this repeatMap into the global space self.addGlobal ('repeat', self.repeatMap) # Add in the locals self.pushLocals() self.setLocal (name, initialValue) def removeRepeat (self, name): # Bring the old repeat map back self.repeatMap = self.repeatStack.pop() # Map this repeatMap into the global space self.addGlobal ('repeat', self.repeatMap) def addGlobal (self, name, value): self.globals[name] = value def pushLocals (self): # Push the current locals onto a stack so that we can safely over-ride them. self.localStack.append (self.locals) self.locals = self.locals.copy() def setLocal (self, name, value): # Override the current local if present with the new one self.locals [name] = value def popLocals (self): self.locals = self.localStack.pop() def evaluate (self, expr, originalAtts = None): # Returns a ContextVariable #self.log.debug ("Evaluating %s" % expr) if (originalAtts is not None): # Call from outside self.globals['attrs'] = originalAtts suppressException = 1 else: suppressException = 0 # Supports path, exists, nocall, not, and string expr = expr.strip () try: if expr.startswith ('path:'): return self.evaluatePath (expr[5:].lstrip ()) elif expr.startswith ('exists:'): return self.evaluateExists (expr[7:].lstrip()) elif expr.startswith ('nocall:'): return self.evaluateNoCall (expr[7:].lstrip()) elif expr.startswith ('not:'): return self.evaluateNot (expr[4:].lstrip()) elif expr.startswith ('string:'): return self.evaluateString (expr[7:].lstrip()) elif expr.startswith ('python:'): return self.evaluatePython (expr[7:].lstrip()) else: # Not specified - so it's a path return self.evaluatePath (expr) except PathNotFoundException, e: if (suppressException): return None raise e def evaluatePython (self, expr): if (not self.allowPythonPath): self.log.warn ("Parameter allowPythonPath is false. NOT Evaluating python expression %s" % expr) return self.false #self.log.debug ("Evaluating python expression %s" % expr) globals={} for name, value in self.globals.items(): if (isinstance (value, ContextVariable)): value = value.rawValue() globals [name] = value globals ['path'] = self.pythonPathFuncs.path globals ['string'] = self.pythonPathFuncs.string globals ['exists'] = self.pythonPathFuncs.exists globals ['nocall'] = self.pythonPathFuncs.nocall globals ['test'] = self.pythonPathFuncs.test locals={} for name, value in self.locals.items(): if (isinstance (value, ContextVariable)): value = value.rawValue() locals [name] = value try: result = eval(expr, globals, locals) if (isinstance (result, ContextVariable)): return result.value() return result except Exception, e: # An exception occured evaluating the template, return the exception as text self.log.warn ("Exception occurred evaluating python path, exception: " + str (e)) return "Exception: %s" % str (e) def evaluatePath (self, expr): #self.log.debug ("Evaluating path expression %s" % expr) allPaths = expr.split ('|') if (len (allPaths) > 1): for path in allPaths: # Evaluate this path try: return self.evaluate (path.strip ()) except PathNotFoundException, e: # Path didn't exist, try the next one pass # No paths evaluated - raise exception. raise PATHNOTFOUNDEXCEPTION else: # A single path - so let's evaluate it. # This *can* raise PathNotFoundException return self.traversePath (allPaths[0]) def evaluateExists (self, expr): #self.log.debug ("Evaluating %s to see if it exists" % expr) allPaths = expr.split ('|') # The first path is for us # Return true if this first bit evaluates, otherwise test the rest try: result = self.traversePath (allPaths[0], canCall = 0) return self.true except PathNotFoundException, e: # Look at the rest of the paths. pass for path in allPaths[1:]: # Evaluate this path try: pathResult = self.evaluate (path.strip ()) # If this is part of a "exists: path1 | exists: path2" path then we need to look at the actual result. if (pathResult): return self.true except PathNotFoundException, e: pass # If we get this far then there are *no* paths that exist. return self.false def evaluateNoCall (self, expr): #self.log.debug ("Evaluating %s using nocall" % expr) allPaths = expr.split ('|') # The first path is for us try: return self.traversePath (allPaths[0], canCall = 0) except PathNotFoundException, e: # Try the rest of the paths. pass for path in allPaths[1:]: # Evaluate this path try: return self.evaluate (path.strip ()) except PathNotFoundException, e: pass # No path evaluated - raise error raise PATHNOTFOUNDEXCEPTION def evaluateNot (self, expr): #self.log.debug ("Evaluating NOT value of %s" % expr) # Evaluate what I was passed try: pathResult = self.evaluate (expr) except PathNotFoundException, e: # In SimpleTAL the result of "not: no/such/path" should be TRUE not FALSE. return self.true if (pathResult is None): # Value was Nothing return self.true if (pathResult == DEFAULTVALUE): return self.false try: resultLen = len (pathResult) if (resultLen > 0): return self.false else: return self.true except: # Not a sequence object. pass if (not pathResult): return self.true # Everything else is true, so we return false! return self.false def evaluateString (self, expr): #self.log.debug ("Evaluating String %s" % expr) result = "" skipCount = 0 for position in xrange (0,len (expr)): if (skipCount > 0): skipCount -= 1 else: if (expr[position] == '$'): try: if (expr[position + 1] == '$'): # Escaped $ sign result += '$' skipCount = 1 elif (expr[position + 1] == '{'): # Looking for a path! endPos = expr.find ('}', position + 1) if (endPos > 0): path = expr[position + 2:endPos] # Evaluate the path - missing paths raise exceptions as normal. try: pathResult = self.evaluate (path) except PathNotFoundException, e: # This part of the path didn't evaluate to anything - leave blank pathResult = u'' if (pathResult is not None): if (isinstance (pathResult, types.UnicodeType)): result += pathResult else: # THIS IS NOT A BUG! # Use Unicode in Context if you aren't using Ascii! result += unicode (pathResult) skipCount = endPos - position else: # It's a variable endPos = expr.find (' ', position + 1) if (endPos == -1): endPos = len (expr) path = expr [position + 1:endPos] # Evaluate the variable - missing paths raise exceptions as normal. try: pathResult = self.traversePath (path) except PathNotFoundException, e: # This part of the path didn't evaluate to anything - leave blank pathResult = u'' if (pathResult is not None): if (isinstance (pathResult, types.UnicodeType)): result += pathResult else: # THIS IS NOT A BUG! # Use Unicode in Context if you aren't using Ascii! result += unicode (pathResult) skipCount = endPos - position - 1 except IndexError, e: # Trailing $ sign - just suppress it self.log.warn ("Trailing $ detected") pass else: result += expr[position] return result def traversePath (self, expr, canCall=1): # canCall only applies to the *final* path destination, not points down the path. # Check for and correct for trailing/leading quotes if (expr.startswith ('"') or expr.startswith ("'")): if (expr.endswith ('"') or expr.endswith ("'")): expr = expr [1:-1] else: expr = expr [1:] elif (expr.endswith ('"') or expr.endswith ("'")): expr = expr [0:-1] pathList = expr.split ('/') path = pathList[0] if path.startswith ('?'): path = path[1:] if self.locals.has_key(path): path = self.locals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (callable (path)):path = apply (path, ()) elif self.globals.has_key(path): path = self.globals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (callable (path)):path = apply (path, ()) #self.log.debug ("Dereferenced to %s" % path) if self.locals.has_key(path): val = self.locals[path] elif self.globals.has_key(path): val = self.globals[path] else: # If we can't find it then raise an exception raise PATHNOTFOUNDEXCEPTION index = 1 for path in pathList[1:]: #self.log.debug ("Looking for path element %s" % path) if path.startswith ('?'): path = path[1:] if self.locals.has_key(path): path = self.locals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (callable (path)):path = apply (path, ()) elif self.globals.has_key(path): path = self.globals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (callable (path)):path = apply (path, ()) #self.log.debug ("Dereferenced to %s" % path) try: if (isinstance (val, ContextVariable)): temp = val.value((index,pathList)) elif (callable (val)):temp = apply (val, ()) else: temp = val except ContextVariable, e: # Fast path for those functions that return values return e.value() if (hasattr (temp, path)): val = getattr (temp, path) else: try: try: val = temp[path] except TypeError: val = temp[int(path)] except: #self.log.debug ("Not found.") raise PATHNOTFOUNDEXCEPTION index = index + 1 #self.log.debug ("Found value %s" % str (val)) if (canCall): try: if (isinstance (val, ContextVariable)): result = val.value((index,pathList)) elif (callable (val)):result = apply (val, ()) else: result = val except ContextVariable, e: # Fast path for those functions that return values return e.value() else: if (isinstance (val, ContextVariable)): result = val.realValue else: result = val return result def __str__ (self): return "Globals: " + str (self.globals) + "Locals: " + str (self.locals) def populateDefaultVariables (self, options): vars = {} self.repeatMap = {} vars['nothing'] = None vars['default'] = DEFAULTVALUE vars['options'] = options # To start with there are no repeats vars['repeat'] = self.repeatMap vars['attrs'] = None # Add all of these to the global context for name in vars.keys(): self.addGlobal (name,vars[name]) # Add also under CONTEXTS self.addGlobal ('CONTEXTS', vars)