django-widget-tweaks-1.4.8/ 0000775 0003720 0003720 00000000000 13632460065 016412 5 ustar travis travis 0000000 0000000 django-widget-tweaks-1.4.8/MANIFEST.in 0000664 0003720 0003720 00000000053 13632460034 020142 0 ustar travis travis 0000000 0000000 include *.txt
include *.rst
include LICENSE django-widget-tweaks-1.4.8/django_widget_tweaks.egg-info/ 0000775 0003720 0003720 00000000000 13632460065 024267 5 ustar travis travis 0000000 0000000 django-widget-tweaks-1.4.8/django_widget_tweaks.egg-info/PKG-INFO 0000664 0003720 0003720 00000036166 13632460065 025400 0 ustar travis travis 0000000 0000000 Metadata-Version: 1.1
Name: django-widget-tweaks
Version: 1.4.8
Summary: Tweak the form field rendering in templates, not in python-level form definitions.
Home-page: https://github.com/jazzband/django-widget-tweaks
Author: Mikhail Korobov
Author-email: kmike84@gmail.com
License: MIT license
Description: ====================
django-widget-tweaks
====================
.. image:: https://jazzband.co/static/img/badge.svg
:target: https://jazzband.co/
:alt: Jazzband
.. image:: https://img.shields.io/pypi/v/django-widget-tweaks.svg
:target: https://pypi.python.org/pypi/django-widget-tweaks
:alt: PyPI Version
.. image:: https://img.shields.io/travis/jazzband/django-widget-tweaks/master.svg
:target: http://travis-ci.org/jazzband/django-widget-tweaks
:alt: Build Status
Tweak the form field rendering in templates, not in python-level
form definitions. Altering CSS classes and HTML attributes is supported.
That should be enough for designers to customize field presentation (using
CSS and unobtrusive javascript) without touching python code.
License is MIT.
Installation
============
You can get Django Widget Tweaks by using pip::
$ pip install django-widget-tweaks
To enable `widget_tweaks` in your project you need to add it to `INSTALLED_APPS` in your projects
`settings.py` file::
INSTALLED_APPS = [
...
'widget_tweaks',
...
]
Usage
=====
This app provides two sets of tools that may be used together or standalone:
1. a ``render_field`` template tag for customizing form fields by using an
HTML-like syntax.
2. several template filters for customizing form field HTML attributes and CSS
classes
The ``render_field`` tag should be easier to use and should make form field
customizations much easier for designers and front-end developers.
The template filters are more powerful than the ``render_field`` tag, but they
use a more complex and less HTML-like syntax.
render_field
------------
This is a template tag that can be used as an alternative to aforementioned
filters. This template tag renders a field using a syntax similar to plain
HTML attributes.
Example::
{% load widget_tweaks %}
{% render_field form.search_query type="search" %}
{% render_field form.text rows="20" cols="20" title="Hello, world!" %}
{% render_field form.title class+="css_class_1 css_class_2" %}
{% render_field form.text placeholder=form.text.label %}
{% render_field form.search_query v-bind::class="{active:isActive}" %}
For fields rendered with ``{% render_field %}`` tag it is possible
to set error class and required fields class by using
``WIDGET_ERROR_CLASS`` and ``WIDGET_REQUIRED_CLASS`` template variables::
{% with WIDGET_ERROR_CLASS='my_error' WIDGET_REQUIRED_CLASS='my_required' %}
{% render_field form.field1 %}
{% render_field form.field2 %}
{% render_field form.field3 %}
{% endwith %}
You can be creative with these variables: e.g. a context processor could
set a default CSS error class on all fields rendered by
``{% render_field %}``.
attr
----
Adds or replaces any single html attribute for the form field.
Examples::
{% load widget_tweaks %}
{{ form.search_query|attr:"type:search" }}
{{ form.text|attr:"rows:20"|attr:"cols:20"|attr:"title:Hello, world!" }}
{{ form.search_query|attr:"autofocus" }}
{{ form.search_query|attr:"v-bind::class:{active:ValueEnabled}" }}
add_class
---------
Adds CSS class to field element. Split classes by whitespace in order to add
several classes at once.
Example::
{% load widget_tweaks %}
{{ form.title|add_class:"css_class_1 css_class_2" }}
set_data
--------
Sets HTML5 data attribute ( http://ejohn.org/blog/html-5-data-attributes/ ).
Useful for unobtrusive javascript. It is just a shortcut for 'attr' filter
that prepends attribute names with 'data-' string.
Example::
{% load widget_tweaks %}
{{ form.title|set_data:"filters:OverText" }}
append_attr
-----------
Appends attribute value with extra data.
Example::
{% load widget_tweaks %}
{{ form.title|append_attr:"class:css_class_1 css_class_2" }}
'add_class' filter is just a shortcut for 'append_attr' filter that
adds values to the 'class' attribute.
remove_attr
-----------
Removes any single html attribute for the form field.
Example::
{% load widget_tweaks %}
{{ form.title|remove_attr:"autofocus" }}
add_label_class
---------------
The same as `add_class` but adds css class to form labels.
Example::
{% load widget_tweaks %}
{{ form.title|add_label_class:"label_class_1 label_class_2" }}
add_error_class
---------------
The same as 'add_class' but adds css class only if validation failed for
the field (field.errors is not empty).
Example::
{% load widget_tweaks %}
{{ form.title|add_error_class:"error-border" }}
add_error_attr
--------------
The same as 'attr' but sets an attribute only if validation failed for
the field (field.errors is not empty). This can be useful when dealing
with accessibility::
{% load widget_tweaks %}
{{ form.title|add_error_attr:"aria-invalid:true" }}
add_required_class
------------------
The same as 'add_error_class' adds css class only for required field.
Example::
{% load widget_tweaks %}
{{ form.title|add_required_class:"is-required" }}
field_type and widget_type
--------------------------
``'field_type'`` and ``'widget_type'`` are template filters that return
field class name and field widget class name (in lower case).
Example::
{% load widget_tweaks %}
{{ field }}
Output::
Mixing render_field and filters
===============================
The render_field tag and filters mentioned above can be mixed.
Example::
{% render_field form.category|append_attr:"readonly:readonly" type="text" placeholder="Category" %}
returns::
Filter chaining
===============
The order django-widget-tweaks filters apply may seem counter-intuitive
(leftmost filter wins)::
{{ form.simple|attr:"foo:bar"|attr:"foo:baz" }}
returns::
It is not a bug, it is a feature that enables creating reusable templates
with overridable defaults.
Reusable field template example::
{# inc/field.html #}
{% load widget_tweaks %}
{{ field|attr:"foo:default_foo" }}
Example usage::
{# my_template.html #}
{% load widget_tweaks %}
With 'rightmost filter wins' rule it wouldn't be possible to override
``|attr:"foo:default_foo"`` in main template.
Contributing
============
If you've found a bug, implemented a feature or have a suggestion,
do not hesitate to contact me, fire an issue or send a pull request.
* Source code: https://github.com/jazzband/django-widget-tweaks/
* Bug tracker: https://github.com/jazzband/django-widget-tweaks/issues
Testing
-------
Make sure you have `tox `_ installed, then type
::
tox
from the source checkout.
NOT SUPPORTED
=============
MultiWidgets: SplitDateTimeWidget, SplitHiddenDateTimeWidget
Changes
=======
1.4.8 (2020-03-12)
------------------
* Fix Release version
1.4.7 (2020-03-10)
------------------
* Fix Travis deployment to Jazzband site
1.4.6 (2020-03-09)
------------------
* Feature remove attribute from field
* Added documentation for remove_attr feature
* Reformat code with black for PEP8 compatibility
* More consistent tox configuration
* adding a new templatetag, unittest and documentation
* Deprecate Python 2.7 support
* Use automatic formatting for all files
1.4.5 (2019-06-08)
------------------
* Fix rST formatting errors.
1.4.4 (2019-06-05)
------------------
* Add support for type attr.
* Add Python 3.7 and drop Python 3.3 support.
* Add support for double colon syntax.
1.4.3 (2018-09-6)
------------------
* Added add_label_class filter for CSS on form labels
* Removed compatibility code for unsupported Django versions
* Fixed support for non-value attributes in Django < 1.8
* Support non-value attributes in HTML5 by setting their value to True
1.4.2 (2018-03-19)
------------------
* update readme to make installation more clear
* shallow copy field before updating attributes
* drop Python 2.6 and Python 3.2 support
* always cast the result of render to a string
* fix import for django >= 2.0
* moved to jazzband
1.4.1 (2015-06-29)
------------------
* fixed a regression in django-widget-tweaks v1.4
(the field is no longer deep copied).
1.4 (2015-06-27)
----------------
* Django 1.7, 1.8 and 1.9 support;
* setup.py is switched to setuptools;
* testing improvements;
* Python 3.4 support is added;
* Python 2.5 is not longer supported;
* bitbucket repository is no longer supported (development is moved to github).
1.3 (2013-04-05)
----------------
* added support for ``WIDGET_ERROR_CLASS`` and ``WIDGET_REQUIRED_CLASS``
template variables that affect ``{% render_field %}``.
1.2 (2013-03-23)
----------------
* new ``add_error_attr`` template filter;
* testing improvements.
1.1.2 (2012-06-06)
------------------
* support for template variables is added to ``render_field`` tag;
* new ``field_type`` and ``widget_type`` filters.
1.1.1 (2012-03-22)
------------------
* some issues with ``render_field`` tag are fixed.
1.1 (2012-03-22)
----------------
* ``render_field`` template tag.
1.0 (2012-02-06)
----------------
* filters return empty strings instead of raising exceptions if field is missing;
* test running improvements;
* python 3 support;
* undocumented 'behave' filter is removed.
0.3 (2011-03-04)
----------------
* ``add_error_class`` filter.
0.2.1 (2011-02-03)
------------------
* Attributes customized in widgets are preserved;
* no more extra whitespaces;
* tests;
0.1 (2011-01-12)
----------------
Initial release.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires: django (>=1.11)
django-widget-tweaks-1.4.8/django_widget_tweaks.egg-info/dependency_links.txt 0000664 0003720 0003720 00000000001 13632460065 030335 0 ustar travis travis 0000000 0000000
django-widget-tweaks-1.4.8/django_widget_tweaks.egg-info/top_level.txt 0000664 0003720 0003720 00000000016 13632460065 027016 0 ustar travis travis 0000000 0000000 widget_tweaks
django-widget-tweaks-1.4.8/django_widget_tweaks.egg-info/SOURCES.txt 0000664 0003720 0003720 00000000611 13632460065 026151 0 ustar travis travis 0000000 0000000 CHANGES.rst
LICENSE
MANIFEST.in
README.rst
setup.cfg
setup.py
django_widget_tweaks.egg-info/PKG-INFO
django_widget_tweaks.egg-info/SOURCES.txt
django_widget_tweaks.egg-info/dependency_links.txt
django_widget_tweaks.egg-info/top_level.txt
widget_tweaks/__init__.py
widget_tweaks/models.py
widget_tweaks/tests.py
widget_tweaks/templatetags/__init__.py
widget_tweaks/templatetags/widget_tweaks.py django-widget-tweaks-1.4.8/CHANGES.rst 0000664 0003720 0003720 00000005264 13632460034 020217 0 ustar travis travis 0000000 0000000 Changes
=======
1.4.8 (2020-03-12)
------------------
* Fix Release version
1.4.7 (2020-03-10)
------------------
* Fix Travis deployment to Jazzband site
1.4.6 (2020-03-09)
------------------
* Feature remove attribute from field
* Added documentation for remove_attr feature
* Reformat code with black for PEP8 compatibility
* More consistent tox configuration
* adding a new templatetag, unittest and documentation
* Deprecate Python 2.7 support
* Use automatic formatting for all files
1.4.5 (2019-06-08)
------------------
* Fix rST formatting errors.
1.4.4 (2019-06-05)
------------------
* Add support for type attr.
* Add Python 3.7 and drop Python 3.3 support.
* Add support for double colon syntax.
1.4.3 (2018-09-6)
------------------
* Added add_label_class filter for CSS on form labels
* Removed compatibility code for unsupported Django versions
* Fixed support for non-value attributes in Django < 1.8
* Support non-value attributes in HTML5 by setting their value to True
1.4.2 (2018-03-19)
------------------
* update readme to make installation more clear
* shallow copy field before updating attributes
* drop Python 2.6 and Python 3.2 support
* always cast the result of render to a string
* fix import for django >= 2.0
* moved to jazzband
1.4.1 (2015-06-29)
------------------
* fixed a regression in django-widget-tweaks v1.4
(the field is no longer deep copied).
1.4 (2015-06-27)
----------------
* Django 1.7, 1.8 and 1.9 support;
* setup.py is switched to setuptools;
* testing improvements;
* Python 3.4 support is added;
* Python 2.5 is not longer supported;
* bitbucket repository is no longer supported (development is moved to github).
1.3 (2013-04-05)
----------------
* added support for ``WIDGET_ERROR_CLASS`` and ``WIDGET_REQUIRED_CLASS``
template variables that affect ``{% render_field %}``.
1.2 (2013-03-23)
----------------
* new ``add_error_attr`` template filter;
* testing improvements.
1.1.2 (2012-06-06)
------------------
* support for template variables is added to ``render_field`` tag;
* new ``field_type`` and ``widget_type`` filters.
1.1.1 (2012-03-22)
------------------
* some issues with ``render_field`` tag are fixed.
1.1 (2012-03-22)
----------------
* ``render_field`` template tag.
1.0 (2012-02-06)
----------------
* filters return empty strings instead of raising exceptions if field is missing;
* test running improvements;
* python 3 support;
* undocumented 'behave' filter is removed.
0.3 (2011-03-04)
----------------
* ``add_error_class`` filter.
0.2.1 (2011-02-03)
------------------
* Attributes customized in widgets are preserved;
* no more extra whitespaces;
* tests;
0.1 (2011-01-12)
----------------
Initial release.
django-widget-tweaks-1.4.8/PKG-INFO 0000664 0003720 0003720 00000036166 13632460065 017523 0 ustar travis travis 0000000 0000000 Metadata-Version: 1.1
Name: django-widget-tweaks
Version: 1.4.8
Summary: Tweak the form field rendering in templates, not in python-level form definitions.
Home-page: https://github.com/jazzband/django-widget-tweaks
Author: Mikhail Korobov
Author-email: kmike84@gmail.com
License: MIT license
Description: ====================
django-widget-tweaks
====================
.. image:: https://jazzband.co/static/img/badge.svg
:target: https://jazzband.co/
:alt: Jazzband
.. image:: https://img.shields.io/pypi/v/django-widget-tweaks.svg
:target: https://pypi.python.org/pypi/django-widget-tweaks
:alt: PyPI Version
.. image:: https://img.shields.io/travis/jazzband/django-widget-tweaks/master.svg
:target: http://travis-ci.org/jazzband/django-widget-tweaks
:alt: Build Status
Tweak the form field rendering in templates, not in python-level
form definitions. Altering CSS classes and HTML attributes is supported.
That should be enough for designers to customize field presentation (using
CSS and unobtrusive javascript) without touching python code.
License is MIT.
Installation
============
You can get Django Widget Tweaks by using pip::
$ pip install django-widget-tweaks
To enable `widget_tweaks` in your project you need to add it to `INSTALLED_APPS` in your projects
`settings.py` file::
INSTALLED_APPS = [
...
'widget_tweaks',
...
]
Usage
=====
This app provides two sets of tools that may be used together or standalone:
1. a ``render_field`` template tag for customizing form fields by using an
HTML-like syntax.
2. several template filters for customizing form field HTML attributes and CSS
classes
The ``render_field`` tag should be easier to use and should make form field
customizations much easier for designers and front-end developers.
The template filters are more powerful than the ``render_field`` tag, but they
use a more complex and less HTML-like syntax.
render_field
------------
This is a template tag that can be used as an alternative to aforementioned
filters. This template tag renders a field using a syntax similar to plain
HTML attributes.
Example::
{% load widget_tweaks %}
{% render_field form.search_query type="search" %}
{% render_field form.text rows="20" cols="20" title="Hello, world!" %}
{% render_field form.title class+="css_class_1 css_class_2" %}
{% render_field form.text placeholder=form.text.label %}
{% render_field form.search_query v-bind::class="{active:isActive}" %}
For fields rendered with ``{% render_field %}`` tag it is possible
to set error class and required fields class by using
``WIDGET_ERROR_CLASS`` and ``WIDGET_REQUIRED_CLASS`` template variables::
{% with WIDGET_ERROR_CLASS='my_error' WIDGET_REQUIRED_CLASS='my_required' %}
{% render_field form.field1 %}
{% render_field form.field2 %}
{% render_field form.field3 %}
{% endwith %}
You can be creative with these variables: e.g. a context processor could
set a default CSS error class on all fields rendered by
``{% render_field %}``.
attr
----
Adds or replaces any single html attribute for the form field.
Examples::
{% load widget_tweaks %}
{{ form.search_query|attr:"type:search" }}
{{ form.text|attr:"rows:20"|attr:"cols:20"|attr:"title:Hello, world!" }}
{{ form.search_query|attr:"autofocus" }}
{{ form.search_query|attr:"v-bind::class:{active:ValueEnabled}" }}
add_class
---------
Adds CSS class to field element. Split classes by whitespace in order to add
several classes at once.
Example::
{% load widget_tweaks %}
{{ form.title|add_class:"css_class_1 css_class_2" }}
set_data
--------
Sets HTML5 data attribute ( http://ejohn.org/blog/html-5-data-attributes/ ).
Useful for unobtrusive javascript. It is just a shortcut for 'attr' filter
that prepends attribute names with 'data-' string.
Example::
{% load widget_tweaks %}
{{ form.title|set_data:"filters:OverText" }}
append_attr
-----------
Appends attribute value with extra data.
Example::
{% load widget_tweaks %}
{{ form.title|append_attr:"class:css_class_1 css_class_2" }}
'add_class' filter is just a shortcut for 'append_attr' filter that
adds values to the 'class' attribute.
remove_attr
-----------
Removes any single html attribute for the form field.
Example::
{% load widget_tweaks %}
{{ form.title|remove_attr:"autofocus" }}
add_label_class
---------------
The same as `add_class` but adds css class to form labels.
Example::
{% load widget_tweaks %}
{{ form.title|add_label_class:"label_class_1 label_class_2" }}
add_error_class
---------------
The same as 'add_class' but adds css class only if validation failed for
the field (field.errors is not empty).
Example::
{% load widget_tweaks %}
{{ form.title|add_error_class:"error-border" }}
add_error_attr
--------------
The same as 'attr' but sets an attribute only if validation failed for
the field (field.errors is not empty). This can be useful when dealing
with accessibility::
{% load widget_tweaks %}
{{ form.title|add_error_attr:"aria-invalid:true" }}
add_required_class
------------------
The same as 'add_error_class' adds css class only for required field.
Example::
{% load widget_tweaks %}
{{ form.title|add_required_class:"is-required" }}
field_type and widget_type
--------------------------
``'field_type'`` and ``'widget_type'`` are template filters that return
field class name and field widget class name (in lower case).
Example::
{% load widget_tweaks %}
{{ field }}
Output::
Mixing render_field and filters
===============================
The render_field tag and filters mentioned above can be mixed.
Example::
{% render_field form.category|append_attr:"readonly:readonly" type="text" placeholder="Category" %}
returns::
Filter chaining
===============
The order django-widget-tweaks filters apply may seem counter-intuitive
(leftmost filter wins)::
{{ form.simple|attr:"foo:bar"|attr:"foo:baz" }}
returns::
It is not a bug, it is a feature that enables creating reusable templates
with overridable defaults.
Reusable field template example::
{# inc/field.html #}
{% load widget_tweaks %}
{{ field|attr:"foo:default_foo" }}
Example usage::
{# my_template.html #}
{% load widget_tweaks %}
With 'rightmost filter wins' rule it wouldn't be possible to override
``|attr:"foo:default_foo"`` in main template.
Contributing
============
If you've found a bug, implemented a feature or have a suggestion,
do not hesitate to contact me, fire an issue or send a pull request.
* Source code: https://github.com/jazzband/django-widget-tweaks/
* Bug tracker: https://github.com/jazzband/django-widget-tweaks/issues
Testing
-------
Make sure you have `tox `_ installed, then type
::
tox
from the source checkout.
NOT SUPPORTED
=============
MultiWidgets: SplitDateTimeWidget, SplitHiddenDateTimeWidget
Changes
=======
1.4.8 (2020-03-12)
------------------
* Fix Release version
1.4.7 (2020-03-10)
------------------
* Fix Travis deployment to Jazzband site
1.4.6 (2020-03-09)
------------------
* Feature remove attribute from field
* Added documentation for remove_attr feature
* Reformat code with black for PEP8 compatibility
* More consistent tox configuration
* adding a new templatetag, unittest and documentation
* Deprecate Python 2.7 support
* Use automatic formatting for all files
1.4.5 (2019-06-08)
------------------
* Fix rST formatting errors.
1.4.4 (2019-06-05)
------------------
* Add support for type attr.
* Add Python 3.7 and drop Python 3.3 support.
* Add support for double colon syntax.
1.4.3 (2018-09-6)
------------------
* Added add_label_class filter for CSS on form labels
* Removed compatibility code for unsupported Django versions
* Fixed support for non-value attributes in Django < 1.8
* Support non-value attributes in HTML5 by setting their value to True
1.4.2 (2018-03-19)
------------------
* update readme to make installation more clear
* shallow copy field before updating attributes
* drop Python 2.6 and Python 3.2 support
* always cast the result of render to a string
* fix import for django >= 2.0
* moved to jazzband
1.4.1 (2015-06-29)
------------------
* fixed a regression in django-widget-tweaks v1.4
(the field is no longer deep copied).
1.4 (2015-06-27)
----------------
* Django 1.7, 1.8 and 1.9 support;
* setup.py is switched to setuptools;
* testing improvements;
* Python 3.4 support is added;
* Python 2.5 is not longer supported;
* bitbucket repository is no longer supported (development is moved to github).
1.3 (2013-04-05)
----------------
* added support for ``WIDGET_ERROR_CLASS`` and ``WIDGET_REQUIRED_CLASS``
template variables that affect ``{% render_field %}``.
1.2 (2013-03-23)
----------------
* new ``add_error_attr`` template filter;
* testing improvements.
1.1.2 (2012-06-06)
------------------
* support for template variables is added to ``render_field`` tag;
* new ``field_type`` and ``widget_type`` filters.
1.1.1 (2012-03-22)
------------------
* some issues with ``render_field`` tag are fixed.
1.1 (2012-03-22)
----------------
* ``render_field`` template tag.
1.0 (2012-02-06)
----------------
* filters return empty strings instead of raising exceptions if field is missing;
* test running improvements;
* python 3 support;
* undocumented 'behave' filter is removed.
0.3 (2011-03-04)
----------------
* ``add_error_class`` filter.
0.2.1 (2011-02-03)
------------------
* Attributes customized in widgets are preserved;
* no more extra whitespaces;
* tests;
0.1 (2011-01-12)
----------------
Initial release.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires: django (>=1.11)
django-widget-tweaks-1.4.8/setup.cfg 0000664 0003720 0003720 00000000103 13632460065 020225 0 ustar travis travis 0000000 0000000 [bdist_wheel]
universal = 1
[egg_info]
tag_build =
tag_date = 0
django-widget-tweaks-1.4.8/LICENSE 0000664 0003720 0003720 00000002050 13632460034 017410 0 ustar travis travis 0000000 0000000 Copyright (c) 2011-2015 Mikhail Korobov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
django-widget-tweaks-1.4.8/README.rst 0000664 0003720 0003720 00000020110 13632460034 020067 0 ustar travis travis 0000000 0000000 ====================
django-widget-tweaks
====================
.. image:: https://jazzband.co/static/img/badge.svg
:target: https://jazzband.co/
:alt: Jazzband
.. image:: https://img.shields.io/pypi/v/django-widget-tweaks.svg
:target: https://pypi.python.org/pypi/django-widget-tweaks
:alt: PyPI Version
.. image:: https://img.shields.io/travis/jazzband/django-widget-tweaks/master.svg
:target: http://travis-ci.org/jazzband/django-widget-tweaks
:alt: Build Status
Tweak the form field rendering in templates, not in python-level
form definitions. Altering CSS classes and HTML attributes is supported.
That should be enough for designers to customize field presentation (using
CSS and unobtrusive javascript) without touching python code.
License is MIT.
Installation
============
You can get Django Widget Tweaks by using pip::
$ pip install django-widget-tweaks
To enable `widget_tweaks` in your project you need to add it to `INSTALLED_APPS` in your projects
`settings.py` file::
INSTALLED_APPS = [
...
'widget_tweaks',
...
]
Usage
=====
This app provides two sets of tools that may be used together or standalone:
1. a ``render_field`` template tag for customizing form fields by using an
HTML-like syntax.
2. several template filters for customizing form field HTML attributes and CSS
classes
The ``render_field`` tag should be easier to use and should make form field
customizations much easier for designers and front-end developers.
The template filters are more powerful than the ``render_field`` tag, but they
use a more complex and less HTML-like syntax.
render_field
------------
This is a template tag that can be used as an alternative to aforementioned
filters. This template tag renders a field using a syntax similar to plain
HTML attributes.
Example::
{% load widget_tweaks %}
{% render_field form.search_query type="search" %}
{% render_field form.text rows="20" cols="20" title="Hello, world!" %}
{% render_field form.title class+="css_class_1 css_class_2" %}
{% render_field form.text placeholder=form.text.label %}
{% render_field form.search_query v-bind::class="{active:isActive}" %}
For fields rendered with ``{% render_field %}`` tag it is possible
to set error class and required fields class by using
``WIDGET_ERROR_CLASS`` and ``WIDGET_REQUIRED_CLASS`` template variables::
{% with WIDGET_ERROR_CLASS='my_error' WIDGET_REQUIRED_CLASS='my_required' %}
{% render_field form.field1 %}
{% render_field form.field2 %}
{% render_field form.field3 %}
{% endwith %}
You can be creative with these variables: e.g. a context processor could
set a default CSS error class on all fields rendered by
``{% render_field %}``.
attr
----
Adds or replaces any single html attribute for the form field.
Examples::
{% load widget_tweaks %}
{{ form.search_query|attr:"type:search" }}
{{ form.text|attr:"rows:20"|attr:"cols:20"|attr:"title:Hello, world!" }}
{{ form.search_query|attr:"autofocus" }}
{{ form.search_query|attr:"v-bind::class:{active:ValueEnabled}" }}
add_class
---------
Adds CSS class to field element. Split classes by whitespace in order to add
several classes at once.
Example::
{% load widget_tweaks %}
{{ form.title|add_class:"css_class_1 css_class_2" }}
set_data
--------
Sets HTML5 data attribute ( http://ejohn.org/blog/html-5-data-attributes/ ).
Useful for unobtrusive javascript. It is just a shortcut for 'attr' filter
that prepends attribute names with 'data-' string.
Example::
{% load widget_tweaks %}
{{ form.title|set_data:"filters:OverText" }}
append_attr
-----------
Appends attribute value with extra data.
Example::
{% load widget_tweaks %}
{{ form.title|append_attr:"class:css_class_1 css_class_2" }}
'add_class' filter is just a shortcut for 'append_attr' filter that
adds values to the 'class' attribute.
remove_attr
-----------
Removes any single html attribute for the form field.
Example::
{% load widget_tweaks %}
{{ form.title|remove_attr:"autofocus" }}
add_label_class
---------------
The same as `add_class` but adds css class to form labels.
Example::
{% load widget_tweaks %}
{{ form.title|add_label_class:"label_class_1 label_class_2" }}
add_error_class
---------------
The same as 'add_class' but adds css class only if validation failed for
the field (field.errors is not empty).
Example::
{% load widget_tweaks %}
{{ form.title|add_error_class:"error-border" }}
add_error_attr
--------------
The same as 'attr' but sets an attribute only if validation failed for
the field (field.errors is not empty). This can be useful when dealing
with accessibility::
{% load widget_tweaks %}
{{ form.title|add_error_attr:"aria-invalid:true" }}
add_required_class
------------------
The same as 'add_error_class' adds css class only for required field.
Example::
{% load widget_tweaks %}
{{ form.title|add_required_class:"is-required" }}
field_type and widget_type
--------------------------
``'field_type'`` and ``'widget_type'`` are template filters that return
field class name and field widget class name (in lower case).
Example::
{% load widget_tweaks %}
{{ field }}
Output::
Mixing render_field and filters
===============================
The render_field tag and filters mentioned above can be mixed.
Example::
{% render_field form.category|append_attr:"readonly:readonly" type="text" placeholder="Category" %}
returns::
Filter chaining
===============
The order django-widget-tweaks filters apply may seem counter-intuitive
(leftmost filter wins)::
{{ form.simple|attr:"foo:bar"|attr:"foo:baz" }}
returns::
It is not a bug, it is a feature that enables creating reusable templates
with overridable defaults.
Reusable field template example::
{# inc/field.html #}
{% load widget_tweaks %}
{{ field|attr:"foo:default_foo" }}
Example usage::
{# my_template.html #}
{% load widget_tweaks %}
With 'rightmost filter wins' rule it wouldn't be possible to override
``|attr:"foo:default_foo"`` in main template.
Contributing
============
If you've found a bug, implemented a feature or have a suggestion,
do not hesitate to contact me, fire an issue or send a pull request.
* Source code: https://github.com/jazzband/django-widget-tweaks/
* Bug tracker: https://github.com/jazzband/django-widget-tweaks/issues
Testing
-------
Make sure you have `tox `_ installed, then type
::
tox
from the source checkout.
NOT SUPPORTED
=============
MultiWidgets: SplitDateTimeWidget, SplitHiddenDateTimeWidget
django-widget-tweaks-1.4.8/widget_tweaks/ 0000775 0003720 0003720 00000000000 13632460065 021253 5 ustar travis travis 0000000 0000000 django-widget-tweaks-1.4.8/widget_tweaks/templatetags/ 0000775 0003720 0003720 00000000000 13632460065 023745 5 ustar travis travis 0000000 0000000 django-widget-tweaks-1.4.8/widget_tweaks/templatetags/widget_tweaks.py 0000664 0003720 0003720 00000015520 13632460034 027157 0 ustar travis travis 0000000 0000000 import re
import types
from copy import copy
from django.template import Library, Node, TemplateSyntaxError
register = Library()
def silence_without_field(fn):
def wrapped(field, attr):
if not field:
return ""
return fn(field, attr)
return wrapped
def _process_field_attributes(field, attr, process):
# split attribute name and value from 'attr:value' string
# params = attr.split(':', 1)
# attribute = params[0]
params = re.split(r"(?
[@\w:_-]+
)
(?P
\+?=
)
(?P
['"]? # start quote
[^"']*
['"]? # end quote
)
""",
re.VERBOSE | re.UNICODE,
)
@register.tag
def render_field(parser, token):
"""
Render a form field using given attribute-value pairs
Takes form field as first argument and list of attribute-value pairs for
all other arguments. Attribute-value pairs should be in the form of
attribute=value or attribute="a value" for assignment and attribute+=value
or attribute+="value" for appending.
"""
error_msg = (
'%r tag requires a form field followed by a list of attributes and values in the form attr="value"'
% token.split_contents()[0]
)
try:
bits = token.split_contents()
tag_name = bits[0] # noqa
form_field = bits[1]
attr_list = bits[2:]
except ValueError:
raise TemplateSyntaxError(error_msg)
form_field = parser.compile_filter(form_field)
set_attrs = []
append_attrs = []
for pair in attr_list:
match = ATTRIBUTE_RE.match(pair)
if not match:
raise TemplateSyntaxError(error_msg + ": %s" % pair)
dct = match.groupdict()
attr, sign, value = (
dct["attr"],
dct["sign"],
parser.compile_filter(dct["value"]),
)
if sign == "=":
set_attrs.append((attr, value))
else:
append_attrs.append((attr, value))
return FieldAttributeNode(form_field, set_attrs, append_attrs)
class FieldAttributeNode(Node):
def __init__(self, field, set_attrs, append_attrs):
self.field = field
self.set_attrs = set_attrs
self.append_attrs = append_attrs
def render(self, context):
bounded_field = self.field.resolve(context)
field = getattr(bounded_field, "field", None)
if getattr(bounded_field, "errors", None) and "WIDGET_ERROR_CLASS" in context:
bounded_field = append_attr(
bounded_field, "class:%s" % context["WIDGET_ERROR_CLASS"]
)
if field and field.required and "WIDGET_REQUIRED_CLASS" in context:
bounded_field = append_attr(
bounded_field, "class:%s" % context["WIDGET_REQUIRED_CLASS"]
)
for k, v in self.set_attrs:
if k == "type":
bounded_field.field.widget.input_type = v.resolve(context)
else:
bounded_field = set_attr(
bounded_field, "%s:%s" % (k, v.resolve(context))
)
for k, v in self.append_attrs:
bounded_field = append_attr(
bounded_field, "%s:%s" % (k, v.resolve(context))
)
return str(bounded_field)
# ======================== remove_attr tag ==============================
@register.filter("remove_attr")
@silence_without_field
def remove_attr(field, attr):
if attr in field.field.widget.attrs:
del field.field.widget.attrs[attr]
return field
django-widget-tweaks-1.4.8/widget_tweaks/templatetags/__init__.py 0000664 0003720 0003720 00000000000 13632460034 026040 0 ustar travis travis 0000000 0000000 django-widget-tweaks-1.4.8/widget_tweaks/tests.py 0000664 0003720 0003720 00000040637 13632460034 022775 0 ustar travis travis 0000000 0000000 import string
try:
from unittest import TestCase, skipIf
except ImportError:
from unittest2 import TestCase, skipIf
from django import VERSION
from django import forms
from django.forms import Form, CharField, TextInput
from django.template import Template, Context
try:
from django.forms import SelectDateWidget # django >= 2.0
except ImportError:
from django.forms.extras.widgets import SelectDateWidget # django < 2.0
# ==============================
# Testing helpers
# ==============================
class MyForm(Form):
"""
Test form. If you want to test rendering of a field,
add it to this form and use one of 'render_...' functions
from this module.
"""
simple = CharField()
with_attrs = CharField(widget=TextInput(attrs={"foo": "baz", "egg": "spam"}))
with_cls = CharField(widget=TextInput(attrs={"class": "class0"}))
date = forms.DateField(widget=SelectDateWidget(attrs={"egg": "spam"}))
def render_form(text, form=None, **context_args):
"""
Renders template ``text`` with widget_tweaks library loaded
and MyForm instance available in context as ``form``.
"""
tpl = Template("{% load widget_tweaks %}" + text)
context_args.update({"form": MyForm() if form is None else form})
context = Context(context_args)
return tpl.render(context)
def render_field(field, template_filter, params, *args, **kwargs):
"""
Renders ``field`` of MyForm with filter ``template_filter`` applied.
``params`` are filter arguments.
If you want to apply several filters (in a chain),
pass extra ``template_filter`` and ``params`` as positional arguments.
In order to use custom form, pass form instance as ``form``
keyword argument.
"""
filters = [(template_filter, params)]
filters.extend(zip(args[::2], args[1::2]))
filter_strings = ['|%s:"%s"' % (f[0], f[1]) for f in filters]
render_field_str = "{{ form.%s%s }}" % (field, "".join(filter_strings))
return render_form(render_field_str, **kwargs)
def render_field_from_tag(field, *attributes):
"""
Renders MyForm's field ``field`` with attributes passed
as positional arguments.
"""
attr_strings = [" %s" % f for f in attributes]
tpl = string.Template("{% render_field form.$field$attrs %}")
render_field_str = tpl.substitute(field=field, attrs="".join(attr_strings))
return render_form(render_field_str)
def assertIn(value, obj):
assert value in obj, "%s not in %s" % (value, obj)
def assertNotIn(value, obj):
assert value not in obj, "%s in %s" % (value, obj)
# ===============================
# Test cases
# ===============================
class SimpleAttrTest(TestCase):
def test_attr(self):
res = render_field("simple", "attr", "foo:bar")
assertIn('type="text"', res)
assertIn('name="simple"', res)
assertIn('id="id_simple"', res)
assertIn('foo="bar"', res)
def test_attr_chaining(self):
res = render_field("simple", "attr", "foo:bar", "attr", "bar:baz")
assertIn('type="text"', res)
assertIn('name="simple"', res)
assertIn('id="id_simple"', res)
assertIn('foo="bar"', res)
assertIn('bar="baz"', res)
def test_add_class(self):
res = render_field("simple", "add_class", "foo")
assertIn('class="foo"', res)
def test_add_multiple_classes(self):
res = render_field("simple", "add_class", "foo bar")
assertIn('class="foo bar"', res)
def test_add_class_chaining(self):
res = render_field("simple", "add_class", "foo", "add_class", "bar")
assertIn('class="bar foo"', res)
def test_set_data(self):
res = render_field("simple", "set_data", "key:value")
assertIn('data-key="value"', res)
def test_replace_type(self):
res = render_field("simple", "attr", "type:date")
self.assertTrue(res.count("type=") == 1, (res, res.count("type=")))
assertIn('type="date"', res)
def test_replace_hidden(self):
res = render_field("simple", "attr", "type:hidden")
self.assertTrue(res.count("type=") == 1, (res, res.count("type=")))
assertIn('type="hidden"', res)
class ErrorsTest(TestCase):
def _err_form(self):
form = MyForm({"foo": "bar"}) # some random data
form.is_valid() # trigger form validation
return form
def test_error_class_no_error(self):
res = render_field("simple", "add_error_class", "err")
assertNotIn('class="err"', res)
def test_error_class_error(self):
form = self._err_form()
res = render_field("simple", "add_error_class", "err", form=form)
assertIn('class="err"', res)
def test_required_class(self):
res = render_field("simple", "add_required_class", "is-required")
assertIn('class="is-required"', res)
def test_required_class_requiredfield(self):
form = self._err_form()
res = render_field("simple", "add_required_class", "is-required", form=form)
assertIn('class="is-required"', res)
assertIn("required", res)
def test_error_attr_no_error(self):
res = render_field("simple", "add_error_attr", "aria-invalid:true")
assertNotIn('aria-invalid="true"', res)
def test_error_attr_error(self):
form = self._err_form()
res = render_field("simple", "add_error_attr", "aria-invalid:true", form=form)
assertIn('aria-invalid="true"', res)
class SilenceTest(TestCase):
def test_silence_without_field(self):
res = render_field("nothing", "attr", "foo:bar")
self.assertEqual(res, "")
res = render_field("nothing", "add_class", "some")
self.assertEqual(res, "")
res = render_field("nothing", "remove_attr", "some")
self.assertEqual(res, "")
class CustomizedWidgetTest(TestCase):
def test_attr(self):
res = render_field("with_attrs", "attr", "foo:bar")
assertIn('foo="bar"', res)
assertNotIn('foo="baz"', res)
assertIn('egg="spam"', res)
# XXX can be dropped once 1.8 is not supported
@skipIf(
VERSION < (1, 11, 0, "final", 0),
"see https://code.djangoproject.com/ticket/16754",
)
def test_selectdatewidget(self):
res = render_field("date", "attr", "foo:bar")
assertIn('egg="spam"', res)
assertIn('foo="bar"', res)
def test_attr_chaining(self):
res = render_field("with_attrs", "attr", "foo:bar", "attr", "bar:baz")
assertIn('foo="bar"', res)
assertNotIn('foo="baz"', res)
assertIn('egg="spam"', res)
assertIn('bar="baz"', res)
def test_attr_class(self):
res = render_field("with_cls", "attr", "foo:bar")
assertIn('foo="bar"', res)
assertIn('class="class0"', res)
def test_default_attr(self):
res = render_field("with_cls", "attr", "type:search")
assertIn('class="class0"', res)
assertIn('type="search"', res)
def test_add_class(self):
res = render_field("with_cls", "add_class", "class1")
assertIn("class0", res)
assertIn("class1", res)
def test_add_class_chaining(self):
res = render_field("with_cls", "add_class", "class1", "add_class", "class2")
assertIn("class0", res)
assertIn("class1", res)
assertIn("class2", res)
def test_remove_attr(self):
res = render_field("with_attrs", "remove_attr", "foo")
assertNotIn("foo", res)
class FieldReuseTest(TestCase):
def test_field_double_rendering_simple(self):
res = render_form(
'{{ form.simple }}{{ form.simple|attr:"foo:bar" }}{{ form.simple }}'
)
self.assertEqual(res.count("bar"), 1)
def test_field_double_rendering_simple_css(self):
res = render_form(
'{{ form.simple }}{{ form.simple|add_class:"bar" }}{{ form.simple|add_class:"baz" }}'
)
self.assertEqual(res.count("baz"), 1)
self.assertEqual(res.count("bar"), 1)
def test_field_double_rendering_attrs(self):
res = render_form(
'{{ form.with_cls }}{{ form.with_cls|add_class:"bar" }}{{ form.with_cls }}'
)
self.assertEqual(res.count("class0"), 3)
self.assertEqual(res.count("bar"), 1)
class SimpleRenderFieldTagTest(TestCase):
def test_attr(self):
res = render_field_from_tag("simple", 'foo="bar"')
assertIn('type="text"', res)
assertIn('name="simple"', res)
assertIn('id="id_simple"', res)
assertIn('foo="bar"', res)
def test_multiple_attrs(self):
res = render_field_from_tag("simple", 'foo="bar"', 'bar="baz"')
assertIn('type="text"', res)
assertIn('name="simple"', res)
assertIn('id="id_simple"', res)
assertIn('foo="bar"', res)
assertIn('bar="baz"', res)
class RenderFieldTagSilenceTest(TestCase):
def test_silence_without_field(self):
res = render_field_from_tag("nothing", 'foo="bar"')
self.assertEqual(res, "")
res = render_field_from_tag("nothing", 'class+="some"')
self.assertEqual(res, "")
class RenderFieldTagCustomizedWidgetTest(TestCase):
def test_attr(self):
res = render_field_from_tag("with_attrs", 'foo="bar"')
assertIn('foo="bar"', res)
assertNotIn('foo="baz"', res)
assertIn('egg="spam"', res)
# XXX can be dropped once 1.8 is not supported
@skipIf(
VERSION < (1, 11, 0, "final", 0),
"see https://code.djangoproject.com/ticket/16754",
)
def test_selectdatewidget(self):
res = render_field_from_tag("date", 'foo="bar"')
assertIn('egg="spam"', res)
assertIn('foo="bar"', res)
def test_multiple_attrs(self):
res = render_field_from_tag("with_attrs", 'foo="bar"', 'bar="baz"')
assertIn('foo="bar"', res)
assertNotIn('foo="baz"', res)
assertIn('egg="spam"', res)
assertIn('bar="baz"', res)
def test_attr_class(self):
res = render_field_from_tag("with_cls", 'foo="bar"')
assertIn('foo="bar"', res)
assertIn('class="class0"', res)
def test_default_attr(self):
res = render_field_from_tag("with_cls", 'type="search"')
assertIn('class="class0"', res)
assertIn('type="search"', res)
def test_append_attr(self):
res = render_field_from_tag("with_cls", 'class+="class1"')
assertIn("class0", res)
assertIn("class1", res)
def test_duplicate_append_attr(self):
res = render_field_from_tag("with_cls", 'class+="class1"', 'class+="class2"')
assertIn("class0", res)
assertIn("class1", res)
assertIn("class2", res)
def test_hyphenated_attributes(self):
res = render_field_from_tag("with_cls", 'data-foo="bar"')
assertIn('data-foo="bar"', res)
assertIn('class="class0"', res)
class RenderFieldWidgetClassesTest(TestCase):
def test_use_widget_required_class(self):
res = render_form(
"{% render_field form.simple %}", WIDGET_REQUIRED_CLASS="required_class"
)
assertIn('class="required_class"', res)
def test_use_widget_error_class(self):
res = render_form(
"{% render_field form.simple %}",
form=MyForm({}),
WIDGET_ERROR_CLASS="error_class",
)
assertIn('class="error_class"', res)
def test_use_widget_error_class_with_other_classes(self):
res = render_form(
'{% render_field form.simple class="blue" %}',
form=MyForm({}),
WIDGET_ERROR_CLASS="error_class",
)
assertIn('class="blue error_class"', res)
def test_use_widget_required_class_with_other_classes(self):
res = render_form(
'{% render_field form.simple class="blue" %}',
form=MyForm({}),
WIDGET_REQUIRED_CLASS="required_class",
)
assertIn('class="blue required_class"', res)
class RenderFieldTagFieldReuseTest(TestCase):
def test_field_double_rendering_simple(self):
res = render_form(
'{{ form.simple }}{% render_field form.simple foo="bar" %}{% render_field form.simple %}'
)
self.assertEqual(res.count("bar"), 1)
def test_field_double_rendering_simple_css(self):
res = render_form(
'{% render_field form.simple %}{% render_field form.simple class+="bar" %}{% render_field form.simple class+="baz" %}'
)
self.assertEqual(res.count("baz"), 1)
self.assertEqual(res.count("bar"), 1)
def test_field_double_rendering_attrs(self):
res = render_form(
'{% render_field form.with_cls %}{% render_field form.with_cls class+="bar" %}{% render_field form.with_cls %}'
)
self.assertEqual(res.count("class0"), 3)
self.assertEqual(res.count("bar"), 1)
def test_field_double_rendering_id(self):
res = render_form(
"{{ form.simple }}"
'{% render_field form.simple id="id_1" %}'
'{% render_field form.simple id="id_2" %}'
)
self.assertEqual(res.count("id_1"), 1)
self.assertEqual(res.count("id_2"), 1)
def test_field_double_rendering_id_name(self):
res = render_form(
"{{ form.simple }}"
'{% render_field form.simple id="id_1" name="n_1" %}'
'{% render_field form.simple id="id_2" name="n_2" %}'
)
self.assertEqual(res.count("id_1"), 1)
self.assertEqual(res.count("id_2"), 1)
self.assertEqual(res.count("n_1"), 1)
self.assertEqual(res.count("n_2"), 1)
def test_field_double_rendering_id_class(self):
res = render_form(
"{{ form.simple }}"
'{% render_field form.simple id="id_1" class="c_1" %}'
'{% render_field form.simple id="id_2" class="c_2" %}'
)
self.assertEqual(res.count("id_1"), 1)
self.assertEqual(res.count("id_2"), 1)
self.assertEqual(res.count("c_1"), 1)
self.assertEqual(res.count("c_2"), 1)
def test_field_double_rendering_name_class(self):
res = render_form(
"{{ form.simple }}"
'{% render_field form.simple name="n_1" class="c_1" %}'
'{% render_field form.simple name="n_2" class="c_2" %}'
)
self.assertEqual(res.count("n_1"), 1)
self.assertEqual(res.count("n_2"), 1)
self.assertEqual(res.count("c_1"), 1)
self.assertEqual(res.count("c_2"), 1)
def test_field_double_rendering_simple(self):
res = render_form('{% render_field form.simple foo="bar" v-model="username" %}')
self.assertEqual(res.count('v-model="username"'), 1)
class RenderFieldTagUseTemplateVariableTest(TestCase):
def test_use_template_variable_in_parametrs(self):
res = render_form(
'{% render_field form.with_attrs egg+="pahaz" placeholder=form.with_attrs.label %}'
)
assertIn('egg="spam pahaz"', res)
assertIn('placeholder="With attrs"', res)
class RenderFieldFilter_field_type_widget_type_Test(TestCase):
def test_field_type_widget_type_rendering_simple(self):
res = render_form(
'
{{ form.simple }}
'
)
assertIn('class="charfield textinput simple"', res)
class RenderFieldTagNonValueAttribute(TestCase):
def test_field_non_value(self):
res = render_form('{{ form.simple|attr:"foo" }}')
assertIn("foo", res)
assertNotIn("foo=", res)
def test_field_empty_value(self):
res = render_form('{{ form.simple|attr:"foo:" }}')
assertIn('foo=""', res)
def test_field_other_value(self):
res = render_form('{{ form.simple|attr:"foo:bar" }}')
assertIn('foo="bar"', res)
def test_field_double_colon(self):
res = render_form('{{ form.simple|attr:"v-bind::class:value" }}')
assertIn('v-bind:class="value"', res)
def test_field_double_colon_morethanone(self):
res = render_form('{{ form.simple|attr:"v-bind::class:{active:True}" }}')
assertIn('v-bind:class="{active:True}"', res)
def test_field_arroba(self):
res = render_form('{{ form.simple|attr:"@click:onClick" }}')
assertIn('@click="onClick"', res)
def test_field_arroba_dot(self):
res = render_form('{{ form.simple|attr:"@click.prevent:onClick" }}')
assertIn('@click.prevent="onClick"', res)
def test_field_double_colon_missing(self):
res = render_form('{{ form.simple|attr:"::class:{active:True}" }}')
assertIn(':class="{active:True}"', res)
django-widget-tweaks-1.4.8/widget_tweaks/models.py 0000664 0003720 0003720 00000000000 13632460034 023072 0 ustar travis travis 0000000 0000000 django-widget-tweaks-1.4.8/widget_tweaks/__init__.py 0000664 0003720 0003720 00000000000 13632460034 023346 0 ustar travis travis 0000000 0000000 django-widget-tweaks-1.4.8/setup.py 0000775 0003720 0003720 00000002075 13632460034 020127 0 ustar travis travis 0000000 0000000 #!/usr/bin/env python
from setuptools import setup
version = "1.4.8"
setup(
name="django-widget-tweaks",
version=version,
author="Mikhail Korobov",
author_email="kmike84@gmail.com",
url="https://github.com/jazzband/django-widget-tweaks",
description="Tweak the form field rendering in templates, not in python-level form definitions.",
long_description=open("README.rst").read() + "\n\n" + open("CHANGES.rst").read(),
license="MIT license",
requires=["django (>=1.11)"],
packages=["widget_tweaks", "widget_tweaks.templatetags"],
classifiers=[
"Development Status :: 5 - Production/Stable",
"Framework :: Django",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: Software Development :: Libraries :: Python Modules",
],
)