Full Changelog

2.1 (unreleased)

  • Tested on Python 3.9 - 3.12 and 2.7 on Linux. This is the last version to support Python 2.7!

  • webhelpers.html.builder:

    • Update the lists of empty elements, boolean attributes, and composed attributes in webhelpers2.html.builder to include all of those listed in the current HTML 5.1 draft.

    • The tag method misinterpreted its c``argument if was a string or literal. This caused the wrong output if the ``_nl arg was true; it put a newline after every character.

  • Python 3 compatibility.

  • Switch doc theme source to ‘pyramid-sphinx-themes’ Python distribution. This doesn’t change the theme; it only changes where we get it from. You can delete the ‘docs/_themes’ directory which the Makefile formerly checked out.

2.0 (2015-01-17)

No changes.

2.0rc3 (2015-01-13)

  • webhelpers.html.tags

    • Further changes to select, Options, Option and OptGroup:

      • The options argument no longer accepts sequences representing value-label pairs or option groups. Instead you must build up an Options instance and pass it. You can still pass a simple list of strings though.

      • The Options, Option, and OptGroup clsses have incompatible changes.

      • Move the selected_values argument from the Options constructor to the Options.render method. Calling str(options) now renders all the options unselected. To render the options with some selected you must call the render method (or let select call it for you).

      • The ‘Option.selected’ attribute is deleted.

      • Option and OptGroup no longer generate their own HTML.

      • The ‘SelectedValues’ class is deleted.

2.0rc2 (2014-11-11)

  • Several unit tests and bugfixes contributed by Jeff Dairiki.

  • webhelpers2.containers

    • [bug][py3k] Fix ordered_items when other_keys is set.

  • webhelpers2.html.builder

    • Add “checked” and “selected” to list of boolean attributes.

    • [bug] Fix “unknown keyword args” reporting in HTML().

  • webhelpers2.html.tags

    • Overhaul select, Options, Option, and OptGroup:

      • Users should test their calls to verify no incompatibilities have crept in , especially if using unusual argument types or edge cases.

      • The main helper is now Options; select is now a wrapper around it.

      • The classes are now fully autonomous and render themselves as strings. (Reverted in 2.0rc3.)

      • When options are rendered, the ‘value’ attribute is suppressed if it’s identical to the label or None.

      • SelectedValues is a new support class used to convert the selected_values arguments. (Reverted in 2.0rc3.)

    • [bug] Fix OptGroup.__repr__ to list its arguments in the correct order

  • webhelpers2.html.tools

    • [bug] Properly escape the string passed to js_obfuscate.

  • webhelpers2.misc

    • [feature] Reinstate formatted exceptions with StudlyException class. (Replaces ‘DeclarativeException’ which was deleted in 2.0b1.)

    • [bug] format_exception() did not work if called with exc=None (due to missing import sys.)

  • webhelpers2.number

    • [bug] The format size helpers now format negative numbers correctly. Previously they passed the number unchanged and appended the unit suffix, which changed the quantity.

    • [bug] median() was not computing the median correctly for even-length sequences

  • webhelpers2.text

    • [feature] New helper wrap_long_lines().

    • [bug] excerpt() now works correctly when text is a literal.

    • [bug] wrap_paragraphs() now works when width is a textwrap.TextWrapper instance.

2.0rc1 (2014-09-22)

  • webhelpers.html._literal

    • Implementation of ‘literal’ moved to this private module.

    • New method .lit_join() works like .join() but does not escape the parts.

  • webhelpers.html.builder:

    • ‘HTMLBuilder.__call__()’ accepts keyword args ‘nl’ and ‘lit’. If ‘nl’ is true, add a newline after each element. If ‘lit’ is true, don’t escape the elements when joining them.

    • ‘HTMLBuilder.literal()’ is the ‘literal’ class constructor. As a consequence it no longer accepts multiple positional args. Use ‘.__call__()’ with ‘lit=True’ as an alternative.

    • ‘.comment()’ adds a space before and after the content.

    • ‘HTMLBuilder.void_tags’ is a set of tag names to render in the self-closing style because they can never have content. It replaces the ‘empty_tags’ global. Add HTML 5 tags to list: “command”, “keygen”, “source”.

    • ‘HTMLBuilder.compose_attrs’ is a dict of attribute names to string separators. If the tag method is called with any of these attributes and their value is a list or tuple, join the elements into a string using this separator. The separators should be literals.

    • ‘HTMLBuilder.boolean_attrs’ is a set of attribute names which are converted to HTML boolean syntax if passed to the tag method. The current set is a conservative few commonly used in tags: “defer”, “disabled”, “multiple”, “readonly”. You can pass additional ones for a specific tag as the “_bool” argument to HTML.tag().

    • There doesn’t seem to be an authoritative list of all boolean attributes; here are some lists on the web: http://stackoverflow.com/questions/706384/boolean-html-attributes https://github.com/kangax/html-minifier/issues/63 We’re evaluating whether to include all these. We’re also evaluating whether it’s better to convert them globally in any tag they appear in, or to convert some of them on a tag-by-tag basis. As far as we can tell, any attribute that’s boolean in one case is boolean everywhere; we haven’t seen any attribute that’s boolean in one tag but non-boolean in another tag.

    • ‘HTMLBuilder’ has several literal constants as class attributes: EMPTY, SPACE, TAB2, TAB4, NL, BR, NL2, BR2.

    • Bugfixes:

      • Convert None to “” when passed to constructor.

      • Pass attribute when raising AttributeError.

      • re.sub overescapes in Python 3 if the third argument (the original string) is a literal, so convert it to a plain string.

    • Implementation changes:

      • ‘.comment()’ is now a regular method.

      • Replace UnfinishedTag with functools.partial.

      • Delete UnfinishedComment, UnfinishedLiteral, UnfinishedTag.

      • Refactor methods to call self instead of doing ad hoc joins.

      • Merge ‘make_tag()’ into ‘HTMLBuilder.tag()’. Make it call ‘self’ rather than joining strings.

      • Move ‘empty_tags’ to ‘HTMLBuilder.void_tags’.

      • Move part of ‘format_attrs()’ to ‘HTMLBuilder.optimize_attrs()’, and merge ‘_attr_decode()’ into it, and also None value handling. Move the compose dict local variable to a class attribute ‘compose_attrs’.

      • Implement boolean attribute conversion in ‘HTMLBuilder.optimize_attrs()’.

      • Refactor ‘format_attrs()’ to ‘HTMLBuilder.render_attrs()’. Change the argument to a dict instead of keyword args. Delete the None handling because ‘HTMLBuilder.optimize_attrs()’ now does it.

  • webhelpers.html.tags:

    • New class ‘Link’ is like ‘link_to_if’ but is lazily evaluated.

    • Delete ‘title()’. It’s too specific for a general-purpose library.

    • Delete ‘xml_declaration()’.

    • Delete ‘convert_boolean_attrs()’ and ‘css_classes()’. The HTML builder now does these itself.

    • When ‘link_to_if’ and ‘link_to_unless’ return just the label, escape it. Tag functions are always supposed to return literals.

    • The ‘id_format’ argument to the ‘ModelTags’ constructor now uses “{}” string formatting. It still accepts “%s” for backward compatibility and converts it to the newer format.

    • Add a space between the widget and the label when rendering ‘checkbox()’ or ‘radio()’ with the ‘label’ argument.

    • ‘checkbox()’ and ‘radio()’ have a new keyword argument ‘label_class’. This sets the <label>’s class attribute.

    • Bugfixes:

      • Python 3’s ‘map()’ behavior broke ‘select()’.

    • Implementation changes:

      • Call ‘HTML.tag()’ rather than attribute access for a slight performance improvement.

      • Input helpers call ‘_input()’ to render themselves. It subsumes the old ‘_set_input_attrs()’ code.

  • webhelpers.html.tools:

    • New home for ‘update_params()’. Beta 1 had left it in the ‘unfinished’ directory.

    • Implementation changes:

      • Unpack nested tag expression in ‘button_to()’.

  • Port doctests in ‘html’ subpackage to unit tests.

2.0b5 (2013-11-24)

  • Port to Python 3. Tested on Python 3.3.2 and 2.7.4.

  • Depend on the ‘six’ distribution for Python 2/3 unification.

  • Removed all “u” string prefixes so it should work on Python 3.2. (Prefixes in former doctests remain; these have not been supported as doctests since 2.0b4.)

2.0b4 (2013-11-11)

  • Change test suite to py.test, and convert doctests to unit tests. Some Python examples were left in the docs for documentation. Did not port the doctests in the ‘html’ subpackage because of the potential overhaul of that package.

  • delete submodules:

    • media (moved choose_height() to misc. get_dimensions() has equivalents on PyPI; e.g., the dimensions and imagefacts distributions)

  • webhelpers.containers:

    • Rename only_some_keys() to copy_keys(), and except_keys() to copy_keys_except(), and extract_keys() to split_dict(). In all these functions change the keys argument to \*keys. This parallels a previous change to del_keys() in 2.0b3.

  • webhelpers.html.tags:

    • The image() helper no longer accepts args ‘path’ or ‘use_pil’. In WebHelpers these invoked the ‘media’ package to parse the width and height from the image file, but the ‘media’ package was not ported to WebHelpers2. It raises TypeError if these args are specified.

  • webhelpers.text:

    • Change the argument signature of series(). The items are now positional args, and the keyword args are renamed to conj and strict.

2.0b3 (2013-04-07)

  • Delete submodules:

    • html.converters (merged to html.tools)

  • webhelpers.containers:

    • Rename del_quiet to del_keys, and change to accept keys as positional arguments.

    • Rename extract_keys to split_dict.

    • Delete get_many.

  • webhelpers2.html.misc:

    • Delete format_number. To display with thosands separators, use "{:,}".format(12346) (always comma) or "{:n}".format(12345) (locale-specific).

  • webhelpers.html.tags:

    • Delete required_legend().

  • webhelpers2.html.tools:

    • Merge ‘webhelpers2.html.converters’ into ‘webhelpers2.html.tools’.

    • Rename format_paragraphs to text_to_html (from converters module).

    • Rename render to html_to_text (from converters module).

    • Bugfix in text_html, should return a literal.

  • webhelpers.misc:

    • Delete all, any, and no. Python >= 2.5 has builtins for the first two.

    • Rename convert_or_none to convert.

  • webhelpers.number:

    • Keep the individual statistic helpers but delete the container classes (Stats and SimpleStats).

  • Delete the sample CSS stylesheet.

2.0b2 (2012-01-29)

  • All HTML tag helpers now convert underscores to hyphens in attribute names. This is to support HTML5 “data-” attributes as keyword args. Trailing underscores are still removed (“class_” -> “class”). (Bitbucket #55)

  • webhelpers2.html.tools:

    • Delete ‘highlighter’ arg in highight helper. It has been deprecated since WebHelpers 1.0b2.

2.0b1 (2012-01-26)

  • Import code and docs from WebHelpers 1.3. Source: https://bitbucket.org/bbangert/webhelpers/changeset/979fc4537c87c54eed933e5a84d43df51be88ff2

  • Rename top-level package to webhelpers2.

  • Delete submodules:

    • feedgenerator

    • html.grid

    • html.grid_demo

    • markdown

    • mimehelper

    • paginate

    • pylonslib (flash, grid, minify, secure_form)

    • textile

    • util

  • webhelpers2.containers:

    • Delete Accumulator: use collections.defaultdict(list) in stdlib or WebOb’s ‘MultiDict`.

    • Delete UniqueAccumulator: use collections.defaultdict(set) in stdlib.

  • webhelpers2.html.tags:

    • Delete Doctype: use simply “<!DOCTYPE html>” for HTML 5.

    • Rename sample stylesheet to ‘webhelpers2/static/stylesheets/webhelpers2.css’.

  • webhelpers2.misc:

    • Rename ‘subclasses_only’ to ‘subclasses_of’.

    • Delete DeclarativeException and OverwriteError.

  • Bugfix in leap year algorithm contributed by “rejoc” on GitHub. (webhelpers2.date._is_leap_year())

  • Moved ‘update_params()’ to the unfinished directory pending a new home; it was in the deleted util module.