{ "info": { "author": "Chris Withers", "author_email": "chris@simplistix.co.uk", "bugtrack_url": null, "classifiers": [ "Development Status :: 6 - Mature", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Text Processing", "Topic :: Text Processing :: Filters", "Topic :: Text Processing :: Markup", "Topic :: Text Processing :: Markup :: HTML", "Topic :: Text Processing :: Markup :: XML" ], "description": "========\nTwiddler\n========\n\nTwiddler seeks to provide a way to render textual content from\ntemplate sources. It has two main aims:\n\n- be able to work with source material provided by designers and\n leaving them absolutely unchanged or work absolutely seamlessly\n with visual editors if there is any markup that needs to be\n added.\n\n- be absolutely as simple as possible while still being able to\n handle all that needs to be done. This, in particular, means no\n new languages should need to be known to be use Twiddler!\n\nBefore You Start\n================\n\nYou will need to know the syntax of the content you wish to\ngenerate, be that XML, HTML or plain text.\n\nYou will need to know some Python. You'll need to know very little\nto get going, but if you want to do more advanced manipulation,\nyou'll need to know more.\n\nInstallation\n============\n\nThe easyiest way to install Twiddler is:\n\n easy_install twiddler\n\nOr, if you're using zc.buildout, just specify 'twiddler' as \na required egg.\n\nHowever, you can also install by unpacking the source\ndistribution and placing the 'twiddler' folder somewhere on your \nPYTHONPATH.\n\nIf you do not install using easy_install or zc.buildout, you will \nalso need to make sure the following python packages are available \non your PYTHONPATH:\n\n- **elementtree**\n \n Even though this comes as standard in Python 2.5 or above,\n Twiddler has not yet been made compatible with the version that\n ships with Python 2.5. ElementTree must be seperately installed\n no matter what version of Python you are using and it can be\n downloaded from:\n\n http://effbot.org/zone/element-index.htm\n \n- **zope.interface**\n\n This comes as standard in Zope 2.9.0 and above, but if you're\n not using Zope, you'll need to download it from:\n\n http://download.zope.org/distribution/\n\n You'll need a knowledge of python eggs although the INSTALL.TXT\n in the .tar.gz file gives instructions.\n\n- **zope.testing**\n\n This is only needed if you want to run the included unit and doc\n tests. It comes as standard in Zope 2.9.0 and above, but if\n you're not using Zope and want to run the tests, it can be\n seperately downloaded from:\n\n http://download.zope.org/distribution/\n\n You'll need a knowledge of python eggs although the INSTALL.TXT\n in the .tar.gz file gives instructions.\n\n For instructions on installation with the various python web\n frameworks, please see the \"Further Information\" section below.\n\nUsage\n=====\n\nTo explain how Twiddlers work, we're going to use the plain python\nversion of Twiddler and do everything from scratch. Once you've\ninstalled Twiddler for plain python, the following examples will\nall work just fine.\n\nSo, to start off with, you create a Twiddler from some source\nstring:\n \n >>> from twiddler import Twiddler\n >>> t = Twiddler('''\n ... \n ...
Hello world!
\n ...
I'm in Italic!
\n ...
\n ... \n ... ''')\n\nFrom then on, you make the content dynamic by finding an element\nand then either replacing parts of it, removing it or repeating\nit. This can be done as often as you like. At any point, you can\ncall the Twiddler's render method to get a string that you can\nreturn to the browser.\n\nHere's a couple of simple examples of replacement:\n\n >>> t['greeting'].replace('Hello user!',style='color: red;')\n >>> t['test'].replace(value='my value')\n\nWe can see the results by rendering the Twiddler:\n\n >>> print t.render()\n \n \n
Hello user!
\n
I'm in Italic!
\n
\n \n \n\nHere's a simple example of removal:\n\n >>> t['stuff'].remove()\n >>> print t.render()\n \n \n
Hello user!
\n
\n \n \n\nHere's a simple example of repeating:\n \n >>> e = t['greeting'].repeater()\n >>> for i in range(3):\n ... e.repeat('Hello user %i!'%i,id='greeting'+str(i)) \n \n \n \n\n >>> print t.render()\n \n \n
Hello user 0!
\n
Hello user 1!
\n
Hello user 2!
\n
\n \n \n\nYou may be wondering where the lines in the\noutput above are coming from. Well, they're an artifact of how the\npython shell behaves, but one caused by another feature.\n\nThe repeat method returns the element that has just been\ninserted. This is useful if you want to repeat more complex\nstructures:\n\n >>> t = Twiddler('''\n ... \n ...
This is row 1
\n ... \n ... ''')\n >>> e = t['row'].repeater()\n >>> for i in range(3):\n ... c = e.repeat()\n ... c['number'].replace(str(i),name=False)\n >>> print t.render()\n \n \n
This is row 0
\n
This is row 1
\n
This is row 2
\n \n \n \nNow, you may have noticed that, so far, we've done all\nmanipulation of the elements from code outside of the source\ncode. Some people find the duality of source and code that\nmanipulates the source, particularly when they're likely to be in\ndifferent files on disk, unpleasant. To make life happier for\nthese people, Twiddler supports the inclusion of a code block in\nthe source itself as follows:\n\n >>> from twiddler.input.default import DefaultWithCodeBlock\n >>> t = Twiddler('''\n ... \n ... \n ...
This is row 1
\n ... \n ... ''',input=DefaultWithCodeBlock)\n\nThis code is executed when the render method is called:\n\n >>> print t.render()\n \n \n
This is row 0
\n
This is row 1
\n
This is row 2
\n \n \n\nYou'll notice that to get this to work, a different input parser\nhas to be specified. This is because code block execution can pose\na significant security problem when the source of the Twiddler\ncomes from user input and so the default parser that\nTwiddler uses will not look for code to execute.\n\nNow, when generating HTML, you often want to have a common style\nacross many pages. Twiddler lets you do this by allowing you to\ninsert parts of one Twiddler into another. \n\nSo, for example, here's our site template:\n\n >>> template = Twiddler('''\n ... \n ...

The Site Header

\n ...
Content goes here
\n ... \n ... ''')\n \nAnd here's a specific page:\n\n >>> page = Twiddler('''\n ... \n ... \n ...
This is our page content!
\n ... \n ... \n ... ''')\n \nNow, to put them together we do the following:\n\n >>> t = template.clone()\n >>> t['content'].replace(page['content'])\n >>> print t.render()\n \n \n

The Site Header

\n
This is our page content!
\n \n \n\nFinally, at any point, Twiddler's can be pickled:\n\n >>> from cPickle import dumps,loads\n >>> s = dumps(t)\n\nThis allows them to be saved to disk in a partially rendered\nstate. This should provide some great opportunities for speeding\nup page rendering by only having to render the changes you need to\nmake, when you need to make them.\n\nFor example, the Twiddler we have just pickled could be reloaded,\nand just the content replaced, without having to be-build the page\nfrom the seperate page and template components:\n\n >>> from_cache = loads(s)\n >>> from_cache['content'].replace('Our new content!')\n >>> print from_cache.render()\n \n \n

The Site Header

\n
Our new content!
\n \n \n\nFurther Information\n===================\n\nMore detailed information on each of Twiddler's aspects can be\nfound in the 'docs' directory of the distribution:\n\n*replace.txt*\n covers all possible uses of the replace method\n\n*repeat.txt*\n covers all possible uses of the repeat method\n\n*search.txt*\n covers all the ways you can search for elements\n\n*filters.txt*\n covers the use of filters for specific calls to replace and\n repeat along with setting up default filters such as html quoting\n and internationalisation. \n\n*inandout.txt*\n covers the usage of Twiddler with different input parsers\n and output renderers. This also covers the default parse and render\n objects in more detail. \n\n*execution.txt*\n covers all the ways that code can be executed as\n a result of calling either the render of execute\n methods. \n\n*templating.txt*\n covers the render, execute and clone methods as\n used to build complete output from multiple\n Twiddlers.\n\nIn addition, the interfaces implemented by the various components\nthat make up Twiddler are described in interfaces.py in the\n'twiddler' package.\n\nInstructions and examples for using Twiddler with various python\nweb frameworks can also be found in the following files, contained\nwithin their sub-packages:\n\n*zope2/readme.txt*\n covers usage of Twiddler in plain Zope 2.\n\nLicensing\n=========\n\nCopyright (c) 2006-2008 Simplistix Ltd\n\nThis Software is released under the MIT License:\nhttp://www.opensource.org/licenses/mit-license.html\nSee license.txt for more details.\n\nCredits\n=======\n\n**Chris Withers**\n Idea and development\n\n**Fredrik Lundh**\n The excellent ElementTree library\n\n**The Django Guys**\n For the idea of filters\n\n**Guido van Rossum**\n For being stubborn enough about XML that I thought more\n deeply about parsing and rendering ;-)\n\nChanges\n=======\n\n0.9.1\n-----\n\n- change readme.txt to reStructuredText\n\n- fix syntax errors in prototype benchmark files.\n\n0.9.0\n-----\n\n- changes to work with distutils, setuptools and zc.buildout\n\n0.8.0 \n-----\n\n- Initial Release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://www.simplistix.co.uk/software/python/twiddler", "keywords": "templating", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "twiddler", "package_url": "https://pypi.org/project/twiddler/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/twiddler/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://www.simplistix.co.uk/software/python/twiddler" }, "release_url": "https://pypi.org/project/twiddler/0.9.1/", "requires_dist": null, "requires_python": null, "summary": "A simple but flexible templating system for dynamically generating textual output.", "version": "0.9.1" }, "last_serial": 801077, "releases": { "0.9.0": [ { "comment_text": "", "digests": { "md5": "e8e6ea59eca72a67d5da81656a2a47d0", "sha256": "0039c92c395b518f267bb49631d996db801b92e92660f20a91dcc417fe8450e1" }, "downloads": -1, "filename": "twiddler-0.9.0-py2.5.egg", "has_sig": false, "md5_digest": "e8e6ea59eca72a67d5da81656a2a47d0", "packagetype": "bdist_egg", "python_version": "2.5", "requires_python": null, "size": 129435, "upload_time": "2008-07-24T19:23:43", "url": "https://files.pythonhosted.org/packages/09/b8/43d02eeaa617a0c17e5fe388a5cf476cff632b35f3129c62ef0f65c23e3e/twiddler-0.9.0-py2.5.egg" }, { "comment_text": "", "digests": { "md5": "ded2511740bc9d3c4bd8cfe99b19076d", "sha256": "856c9ac6827d2b2006a1a8253d5ddfff470f5ae352601d4671e434422b779897" }, "downloads": -1, "filename": "twiddler-0.9.0.tar.gz", "has_sig": false, "md5_digest": "ded2511740bc9d3c4bd8cfe99b19076d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 57675, "upload_time": "2008-07-24T19:23:35", "url": "https://files.pythonhosted.org/packages/ef/22/436a902452e9a62e6fad8831b047cdf9c0d1fb13cbbb6a759bc406b87126/twiddler-0.9.0.tar.gz" } ], "0.9.1": [ { "comment_text": "", "digests": { "md5": "a373cafc51db2457a96dffea35f57d20", "sha256": "67ab3e8c826b86f0e3171a9e9f9a1d708558666056a3915bedb13de273290377" }, "downloads": -1, "filename": "twiddler-0.9.1-py2.5.egg", "has_sig": false, "md5_digest": "a373cafc51db2457a96dffea35f57d20", "packagetype": "bdist_egg", "python_version": "2.5", "requires_python": null, "size": 131110, "upload_time": "2008-07-24T23:23:30", "url": "https://files.pythonhosted.org/packages/bc/a2/b7d182efc20aebd376581293e64cea01ca863f2e94694e0490b9f0d9fd63/twiddler-0.9.1-py2.5.egg" }, { "comment_text": "", "digests": { "md5": "98c920945e6afa34b71523381bf647fa", "sha256": "ae3ceb967339598b6e98b8a0026230663c0ecb8a70aeda1c8010f9006ec44db3" }, "downloads": -1, "filename": "twiddler-0.9.1.tar.gz", "has_sig": false, "md5_digest": "98c920945e6afa34b71523381bf647fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58688, "upload_time": "2008-07-24T23:23:21", "url": "https://files.pythonhosted.org/packages/38/80/f9fc71734f072d1716ab0e551d17f80b5bbc0d9de07035bf9968fa574f42/twiddler-0.9.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a373cafc51db2457a96dffea35f57d20", "sha256": "67ab3e8c826b86f0e3171a9e9f9a1d708558666056a3915bedb13de273290377" }, "downloads": -1, "filename": "twiddler-0.9.1-py2.5.egg", "has_sig": false, "md5_digest": "a373cafc51db2457a96dffea35f57d20", "packagetype": "bdist_egg", "python_version": "2.5", "requires_python": null, "size": 131110, "upload_time": "2008-07-24T23:23:30", "url": "https://files.pythonhosted.org/packages/bc/a2/b7d182efc20aebd376581293e64cea01ca863f2e94694e0490b9f0d9fd63/twiddler-0.9.1-py2.5.egg" }, { "comment_text": "", "digests": { "md5": "98c920945e6afa34b71523381bf647fa", "sha256": "ae3ceb967339598b6e98b8a0026230663c0ecb8a70aeda1c8010f9006ec44db3" }, "downloads": -1, "filename": "twiddler-0.9.1.tar.gz", "has_sig": false, "md5_digest": "98c920945e6afa34b71523381bf647fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58688, "upload_time": "2008-07-24T23:23:21", "url": "https://files.pythonhosted.org/packages/38/80/f9fc71734f072d1716ab0e551d17f80b5bbc0d9de07035bf9968fa574f42/twiddler-0.9.1.tar.gz" } ] }