yattag-1.7.2/0000755000175000017500000000000013011322433014452 5ustar individuindividu00000000000000yattag-1.7.2/PKG-INFO0000644000175000017500000001100413011322433015543 0ustar individuindividu00000000000000Metadata-Version: 1.1 Name: yattag Version: 1.7.2 Summary: Generate HTML or XML in a pythonic way. Pure python alternative to web template engines.Can fill HTML forms with default values and error messages. Home-page: http://www.yattag.org Author: Benjamin Le Forestier Author-email: benjamin@leforestier.org License: UNKNOWN Description: .. image:: https://travis-ci.org/leforestier/yattag.svg :target: https://travis-ci.org/leforestier/yattag Why use a template engine when you can generate HTML or XML documents with Python in a very readable way? ( full tutorial on yattag.org_ ) Basic example ------------- Nested html tags, no need to close tags. .. code:: python from yattag import Doc doc, tag, text = Doc().tagtext() with tag('html'): with tag('body', id = 'hello'): with tag('h1'): text('Hello world!') print(doc.getvalue()) Html form rendering ------------------- Yattag can fill your HTML forms with default values and error messages. Pass a ``defaults`` dictionnary of default values, and an ``errors`` dictionnary of error messages to the ``Doc`` constructor. Then, use the special ``input``, ``textarea``, ``select``, ``option`` methods when generating your documents. Example with default values ~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: python from yattag import Doc doc, tag, text = Doc( defaults = {'ingredient': ['chocolate', 'coffee']} ).tagtext() with tag('form', action = ""): with tag('label'): text("Select one or more ingredients") with doc.select(name = 'ingredient', multiple = "multiple"): for value, description in ( ("chocolate", "Dark chocolate"), ("almonds", "Roasted almonds"), ("honey", "Acacia honey"), ("coffee", "Ethiopian coffee") ): with doc.option(value = value): text(description) doc.stag('input', type = "submit", value = "Validate") print(doc.getvalue()) Example with default values and errors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: python from yattag import Doc doc, tag, text = Doc( defaults = { 'title': 'Untitled', 'contact_message': 'You just won the lottery!' }, errors = { 'contact_message': 'Your message looks like spam.' } ).tagtext() with tag('h1'): text('Contact form') with tag('form', action = ""): doc.input(name = 'title', type = 'text') with doc.textarea(name = 'contact_message'): pass doc.stag('input', type = 'submit', value = 'Send my message') print(doc.getvalue()) Full tutorial on yattag.org_ GitHub repo: https://github.com/leforestier/yattag .. _yattag.org: http://www.yattag.org Keywords: html,template,templating,xml,document,form,rendering Platform: UNKNOWN Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules yattag-1.7.2/setup.py0000664000175000017500000000273713011322105016173 0ustar individuindividu00000000000000from distutils.core import setup with open('README.rst') as fd: long_description = fd.read() setup( name='yattag', version='1.7.2', packages=['yattag'], author = 'Benjamin Le Forestier', author_email = 'benjamin@leforestier.org', url = 'http://www.yattag.org', keywords = ["html", "template", "templating", "xml", "document", "form", "rendering"], description = """\ Generate HTML or XML in a pythonic way. Pure python alternative to web template engines.\ Can fill HTML forms with default values and error messages.""", long_description = long_description, classifiers = [ 'Environment :: Web Environment', "Intended Audience :: Developers", "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Software Development :: Libraries :: Python Modules', ] ) yattag-1.7.2/yattag/0000755000175000017500000000000013011322433015743 5ustar individuindividu00000000000000yattag-1.7.2/yattag/doc.py0000644000175000017500000003535212777450301017110 0ustar individuindividu00000000000000from yattag.simpledoc import dict_to_attrs, html_escape, attr_escape, SimpleDoc, DocError try: range = xrange # for Python 2/3 compatibility except NameError: pass __all__ = ['Doc'] class SimpleInput(object): """ class representing text inputs, password inputs, hidden inputs etc... """ def __init__(self, name, tpe, attrs): self.name = name self.tpe = tpe self.attrs = attrs def render(self, defaults, errors, error_wrapper): lst = [] attrs = dict(self.attrs) error = errors and self.name in errors if error: _add_class(attrs, 'error') lst.append(error_wrapper[0]) lst.append(html_escape(errors[self.name])) lst.append(error_wrapper[1]) if self.name in defaults: attrs['value'] = str(defaults[self.name]) attrs['name'] = self.name lst.append('' % (self.tpe, dict_to_attrs(attrs))) return ''.join(lst) class CheckableInput(object): tpe = 'checkbox' def __init__(self, name, attrs): self.name = name self.rank = 0 self.attrs = attrs def setrank(self, n): self.rank = n def render(self, defaults, errors, error_wrapper): lst = [] attrs = dict(self.attrs) if self.rank == 0: if errors and self.name in errors: lst.append(error_wrapper[0]) lst.append(html_escape(errors[self.name])) lst.append(error_wrapper[1]) _add_class(attrs, 'error') if self.name in defaults and 'value' in self.attrs and defaults[self.name] == self.attrs['value']: attrs['checked'] = 'checked' attrs['name'] = self.name lst.append('' % (self.__class__.tpe, dict_to_attrs(attrs))) return ''.join(lst) class CheckboxInput(CheckableInput): pass class RadioInput(CheckableInput): tpe = 'radio' def groupclass(inputclass): class InputGroup(object): def __init__(self, name): self.name = name self.n_items = 0 def input(self, attrs): input_instance = inputclass(self.name, attrs) input_instance.setrank(self.n_items) self.n_items += 1 return input_instance return InputGroup class ContainerTag(object): tag_name = 'textarea' def __init__(self, name, attrs): self.name = name self.attrs = attrs def render(self, defaults, errors, error_wrapper, inner_content = ''): lst = [] attrs = dict(self.attrs) if errors and self.name in errors: lst.append(error_wrapper[0]) lst.append(html_escape(errors[self.name])) lst.append(error_wrapper[1]) _add_class(attrs, 'error') attrs['name'] = self.name lst.append('<%s %s>' % (self.__class__.tag_name, dict_to_attrs(attrs))) if self.name in defaults: lst.append(html_escape(str(defaults[self.name]))) else: lst.append(inner_content) lst.append('' % self.__class__.tag_name) return ''.join(lst) class Textarea(ContainerTag): pass class Select(ContainerTag): tag_name = 'select' class Option(object): def __init__(self, name, multiple, value, attrs): self.name = name self.multiple = multiple self.value = value self.attrs = attrs def render(self, defaults, errors, inner_content): selected = '' if self.name in defaults: if self.multiple: if self.value in defaults[self.name]: selected = True else: if self.value == defaults[self.name]: selected = True lst = ['') return ''.join(lst) def _attrs_from_args(required_keys, *args, **kwargs): # need to do all this to allow specifying attributes as (key, value) pairs # while maintaining backward compatibility with previous versions # of yattag, which allowed 'name', 'type', and 'value' attributes # as positional or as keyword arguments def raise_exception(arg): raise ValueError( "Optional attributes should be passed as (key, value) pairs or as keyword arguments." "Got %s (type %s)" % (repr(arg), repr(type(arg))) ) limit = 0 for arg in args: if isinstance(arg, tuple): break else: limit += 1 if limit > len(required_keys): raise_exception(args[limit-1]) attrs = dict(zip(required_keys[:limit],args[:limit])) for arg in args[limit:]: if isinstance(arg, tuple): attrs[arg[0]] = arg[1] else: raise_exception(arg) attrs.update( (('class', value) if key == 'klass' else (key, value)) for key, value in kwargs.items() ) required_attrs = [] for key in required_keys: try: required_attrs.append(attrs.pop(key)) except KeyError: raise ValueError( "the %s attribute is missing" % repr(key) ) return required_attrs + [attrs] class Doc(SimpleDoc): """ The Doc class extends the SimpleDoc class with form rendering capabilities. Pass default values or errors as dictionnaries to the Doc constructor, and use the `input`, `textarea`, `select`, `option` methods to append form elements to the document. """ SimpleInput = SimpleInput CheckboxInput = CheckboxInput RadioInput = RadioInput Textarea = Textarea Select = Select Option = Option class TextareaTag(object): def __init__(self, doc, name, attrs): # name is the name attribute of the textarea, ex: 'contact_message' # for