15 | {% include 'bootstrap3/layout/help_text_and_errors.html' %}
16 |
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009-2011 Miguel Araujo and contributors.
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/crispy_forms/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009 Daniel Greenfeld and contributors.
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/crispy_forms/tests/runtests_bootstrap3.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import os, sys
4 |
5 | os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings'
6 | parent = os.path.dirname(os.path.dirname(os.path.dirname(
7 | os.path.abspath(__file__))))
8 |
9 | sys.path.insert(0, parent)
10 |
11 | from django.test.simple import DjangoTestSuiteRunner
12 | from django.conf import settings
13 |
14 | settings.CRISPY_TEMPLATE_PACK = 'bootstrap3'
15 |
16 |
17 | def runtests():
18 | return DjangoTestSuiteRunner(failfast=False).run_tests([
19 | 'crispy_forms.TestBasicFunctionalityTags',
20 | 'crispy_forms.TestFormHelper',
21 | 'crispy_forms.TestBootstrapFormHelper',
22 | 'crispy_forms.TestBootstrap3FormHelper',
23 | 'crispy_forms.TestFormLayout',
24 | 'crispy_forms.TestBootstrapFormLayout',
25 | 'crispy_forms.TestBootstrap3FormLayout',
26 | 'crispy_forms.TestLayoutObjects',
27 | 'crispy_forms.TestBootstrapLayoutObjects',
28 | 'crispy_forms.TestDynamicLayouts',
29 | ], verbosity=1, interactive=True)
30 |
31 |
32 | if __name__ == '__main__':
33 | if runtests():
34 | sys.exit(1)
35 |
--------------------------------------------------------------------------------
/crispy_forms/base.py:
--------------------------------------------------------------------------------
1 | def from_iterable(iterables):
2 | """
3 | Backport of `itertools.chain.from_iterable` compatible with Python 2.5
4 | """
5 | for it in iterables:
6 | for element in it:
7 | if isinstance(element, dict):
8 | for key in element:
9 | yield key
10 | else:
11 | yield element
12 |
13 |
14 | class KeepContext(object):
15 | """
16 | Context manager that receives a `django.template.Context` instance and a list of keys
17 |
18 | Once the context manager is exited, it removes `keys` from the context, to avoid
19 | side effects in later layout objects that may use the same context variables.
20 |
21 | Layout objects should use `extra_context` to introduce context variables, never
22 | touch context object themselves, that could introduce side effects.
23 | """
24 | def __init__(self, context, keys):
25 | self.context = context
26 | self.keys = keys
27 |
28 | def __enter__(self):
29 | pass
30 |
31 | def __exit__(self, type, value, traceback):
32 | for key in list(self.keys):
33 | del self.context[key]
34 |
--------------------------------------------------------------------------------
/crispy_forms/templates/uni_form/layout/multifield.html:
--------------------------------------------------------------------------------
1 |
4 |
5 | {% if form_show_errors %}
6 | {% for field in multifield.bound_fields %}
7 | {% if field.errors %}
8 | {% for error in field.errors %}
9 |
8 | django-crispy-forms is a Django application that lets you easily build, customize and reuse forms using your favorite CSS framework, without writing template code and without having to take care of annoying details. You are currently looking at the documentation of the development release.
9 |
10 |
11 |
12 |
Support
13 |
14 | If you love django-crispy-forms, consider making a small donation on Flattr:
15 |
30 | {% endif %}
31 |
--------------------------------------------------------------------------------
/docs/_themes/LICENSE:
--------------------------------------------------------------------------------
1 | Modifications:
2 |
3 | Copyright (c) 2010 Kenneth Reitz.
4 |
5 |
6 | Original Project:
7 |
8 | Copyright (c) 2010 by Armin Ronacher.
9 |
10 |
11 | Some rights reserved.
12 |
13 | Redistribution and use in source and binary forms of the theme, with or
14 | without modification, are permitted provided that the following conditions
15 | are met:
16 |
17 | * Redistributions of source code must retain the above copyright
18 | notice, this list of conditions and the following disclaimer.
19 |
20 | * Redistributions in binary form must reproduce the above
21 | copyright notice, this list of conditions and the following
22 | disclaimer in the documentation and/or other materials provided
23 | with the distribution.
24 |
25 | * The names of the contributors may not be used to endorse or
26 | promote products derived from this software without specific
27 | prior written permission.
28 |
29 | We kindly ask you to only use these themes in an unmodified manner just
30 | for Flask and Flask-related products, not for unrelated projects. If you
31 | like the visual style and want to use it for your own projects, please
32 | consider making some larger changes to the themes (such as changing
33 | font faces, sizes, colors or margins).
34 |
35 | THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
39 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
43 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44 | ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
45 | POSSIBILITY OF SUCH DAMAGE.
46 |
--------------------------------------------------------------------------------
/crispy_forms/templates/bootstrap3/table_inline_formset.html:
--------------------------------------------------------------------------------
1 | {% load crispy_forms_tags %}
2 | {% load crispy_forms_utils %}
3 | {% load crispy_forms_field %}
4 |
5 | {% specialspaceless %}
6 | {% if formset_tag %}
7 | {% endif %}
51 | {% endspecialspaceless %}
52 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. django-crispy-forms documentation master file, created by
2 | sphinx-quickstart on Tue Nov 1 19:01:02 2011.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Forms have never been this crispy
7 | =================================
8 |
9 | django-crispy-forms provides you with a ``|crispy`` filter and ``{% crispy %}`` tag that will let you control the rendering behavior of your Django_ forms in a very elegant and DRY way. Have full control without writing custom form templates. All this without breaking the standard way of doing things in Django_, so it plays nice with any other form application.
10 |
11 | User Guide
12 | ~~~~~~~~~~
13 |
14 | Get the most out of django-crispy-forms
15 |
16 | .. toctree::
17 | :maxdepth: 2
18 |
19 | install
20 | filters
21 | crispy_tag_forms
22 | form_helper
23 | layouts
24 | template_packs
25 | crispy_tag_formsets
26 | dynamic_layouts
27 |
28 | .. toctree::
29 | :maxdepth: 1
30 |
31 | faq
32 |
33 | * See who's contributed to the project at `crispy-forms contributors`_
34 | * You can find a detailed history of the project in `Github's CHANGELOG`_
35 |
36 | .. _`crispy-forms contributors`: https://github.com/maraujop/django-crispy-forms/blob/dev/CONTRIBUTORS.txt
37 | .. _`Github's CHANGELOG`: https://github.com/maraujop/django-crispy-forms/blob/dev/CHANGELOG.md
38 |
39 | API documentation
40 | ~~~~~~~~~~~~~~~~~
41 |
42 | If you are looking for information on a specific function, class or method, this part of the documentation is for you.
43 |
44 | .. toctree::
45 | :maxdepth: 2
46 |
47 | api_helpers
48 | api_layout
49 | api_templatetags
50 |
51 | Developer Guide
52 | ~~~~~~~~~~~~~~~
53 |
54 | Think this is awesome and want to make it better? Read our contribution page, make it better, and you will be added to the `contributors`_ list!
55 |
56 | .. toctree::
57 | :maxdepth: 2
58 |
59 | contributing
60 |
61 | .. _contributors: https://github.com/maraujop/django-crispy-forms/blob/dev/CONTRIBUTORS.txt
62 | .. _Django: http://djangoproject.com
63 |
--------------------------------------------------------------------------------
/crispy_forms/templates/bootstrap/table_inline_formset.html:
--------------------------------------------------------------------------------
1 | {% load crispy_forms_tags %}
2 | {% load crispy_forms_utils %}
3 | {% load crispy_forms_field %}
4 |
5 | {% specialspaceless %}
6 | {% if formset_tag %}
7 | {% endif %}
56 | {% endspecialspaceless %}
57 |
--------------------------------------------------------------------------------
/docs/concepts.rst:
--------------------------------------------------------------------------------
1 | ========
2 | Concepts
3 | ========
4 |
5 | Form Helpers
6 | -------------
7 |
8 | The biggest advantage of this library are :ref:`form helpers` and layouts. The advantage of these tools is that they let you build forms with most of the coding done in Python, rather than HTML. We **strongly** suggest you study and learn the examples in the :ref:`form helpers` documentation.
9 |
10 | Don't Repeat Yourself
11 | ---------------------
12 |
13 | It has been written that if you do anything twice in code, you should wrap it up
14 | in a function or method. This project was born out of the desire to not have to
15 | rewrite similar forms multiple times over the same project. Just like we use the
16 | Django ORM to avoid writing simple queries again and again, it is advantageous to
17 | our sanity and code quality to not have to write `` 30 times across a project.
18 |
19 | The problem with building a form this way multiple times is that it is ripe for error. What about hidden fields? What if you forget the `{% csrf_token %}` token?
20 | What if you don't set the form method correctly?
21 |
22 | Think of django-uni-form like an ORM, it handles the small details so you can
23 | focus on the big picture of your project - the business logic that drives your
24 | site and is probably a lot more fun to deal with than the tiny particularities of
25 | forms.
26 |
27 | Section 508
28 | -----------
29 |
30 | Some years ago the United States congress defined `Section 508`_ as a means to provide enforcement for technology provided or purchased for the government that met a set of specifications so that those with disabilities could use said technologies. Unfortunately, the specification does not normally apply to commercial products not used by the US Government and many US Government projects weasel out of the specification.
31 |
32 | However, following Section 508 (and the World Wide Web Consortium's (W3C) `Web Accessibility Initiative`_ (WAI) is the right thing to do. It doesn't hurt to familiarize yourself with these specifications.
33 |
34 | In the meantime, django-uni-form provides a means to easily render Section 508 compliant forms. How awesome is that?
35 |
36 | .. _`Section 508`: http://en.wikipedia.org/wiki/Section_508
37 | .. _`Web Accessibility Initiative`: http://en.wikipedia.org/wiki/Web_Accessibility_Initiative
38 |
--------------------------------------------------------------------------------
/crispy_forms/templatetags/crispy_forms_utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import re
3 |
4 | from django import template
5 | from django.conf import settings
6 | try: # Django < 1.4
7 | from django.utils.encoding import force_unicode as force_text
8 | except ImportError:
9 | from django.utils.encoding import force_text
10 | from django.utils.functional import allow_lazy
11 |
12 | from crispy_forms.compatibility import text_type
13 |
14 | register = template.Library()
15 | TEMPLATE_PACK = getattr(settings, 'CRISPY_TEMPLATE_PACK', 'bootstrap')
16 |
17 |
18 | def selectively_remove_spaces_between_tags(value, template_pack, form_class):
19 | if (
20 | 'bootstrap' in template_pack
21 | and 'form-inline' in form_class
22 | ):
23 | # More than 3 strict whitespaces, see issue #250
24 | html = re.sub(r'>\s{3,}<', '> <', force_text(value))
25 | return re.sub(r'/><', r'/> <', force_text(html))
26 | else:
27 | html = re.sub(r'>\s{3,}<', '> <', force_text(value))
28 | return re.sub(r'/><', r'/> <', force_text(html))
29 | return value
30 | selectively_remove_spaces_between_tags = allow_lazy(
31 | selectively_remove_spaces_between_tags, text_type
32 | )
33 |
34 |
35 | class SpecialSpacelessNode(template.Node):
36 | def __init__(self, nodelist):
37 | self.nodelist = nodelist
38 |
39 | def render(self, context):
40 | try:
41 | template_pack = template.Variable('template_pack').resolve(context)
42 | except:
43 | template_pack = TEMPLATE_PACK
44 |
45 | try:
46 | form_attrs = template.Variable('form_attrs').resolve(context)
47 | except:
48 | form_attrs = {}
49 |
50 | return selectively_remove_spaces_between_tags(
51 | self.nodelist.render(context).strip(),
52 | template_pack,
53 | form_attrs.get('class', ''),
54 | )
55 |
56 |
57 | @register.tag
58 | def specialspaceless(parser, token):
59 | """
60 | Removes whitespace between HTML tags, and introduces a whitespace
61 | after buttons an inputs, necessary for Bootstrap to place them
62 | correctly in the layout.
63 | """
64 | nodelist = parser.parse(('endspecialspaceless',))
65 | parser.delete_first_token()
66 |
67 | return SpecialSpacelessNode(nodelist)
68 |
--------------------------------------------------------------------------------
/crispy_forms/templates/bootstrap3/field.html:
--------------------------------------------------------------------------------
1 | {% load crispy_forms_field %}
2 |
3 | {% if field.is_hidden %}
4 | {{ field }}
5 | {% else %}
6 | {% if field|is_checkbox %}
7 |
8 | {% if label_class %}
9 |
10 | {% endif %}
11 | {% endif %}
12 | <{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" {% if not field|is_checkbox %}class="form-group{% else %}class="checkbox{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_show_errors%}{% if field.errors %} has-error{% endif %}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
13 | {% if field.label and not field|is_checkbox and form_show_labels %}
14 |
17 | {% endif %}
18 |
19 | {% if field|is_checkboxselectmultiple %}
20 | {% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
21 | {% endif %}
22 |
23 | {% if field|is_radioselect %}
24 | {% include 'bootstrap3/layout/radioselect.html' %}
25 | {% endif %}
26 |
27 | {% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
28 | {% if field|is_checkbox and form_show_labels %}
29 |
34 | {% else %}
35 |
36 | {% crispy_field field %}
37 | {% include 'bootstrap3/layout/help_text_and_errors.html' %}
38 |
39 | {% endif %}
40 | {% endif %}
41 | {% if tag %}{{ tag }}{% else %}div{% endif %}>
42 | {% if field|is_checkbox %}
43 | {% if label_class %}
44 |
40 | {% crispy_field field %}
41 | {% include 'bootstrap3/layout/help_text_and_errors.html' %}
42 |
43 | {% endif %}
44 | {% endif %}
45 | {% if tag %}{{ tag }}{% else %}div{% endif %}>
46 | {% if field|is_checkbox %}
47 |
48 | {% endif %}
49 | {% endif %}
50 |
--------------------------------------------------------------------------------
/crispy_forms/tests/utils.py:
--------------------------------------------------------------------------------
1 | __all__ = ('override_settings',)
2 |
3 |
4 | try:
5 | from django.test.utils import override_settings
6 | except ImportError:
7 | # we are in Django 1.3
8 | from django.conf import settings, UserSettingsHolder
9 | from django.utils.functional import wraps
10 |
11 | class override_settings(object):
12 | """
13 | Acts as either a decorator, or a context manager. If it's a decorator
14 | it takes a function and returns a wrapped function. If it's a
15 | contextmanager it's used with the ``with`` statement. In either event
16 | entering/exiting are called before and after, respectively,
17 | the function/block is executed.
18 |
19 | This class was backported from Django 1.5
20 |
21 | As django.test.signals.setting_changed is not supported in 1.3,
22 | it's not sent on changing settings.
23 | """
24 | def __init__(self, **kwargs):
25 | self.options = kwargs
26 | self.wrapped = settings._wrapped
27 |
28 | def __enter__(self):
29 | self.enable()
30 |
31 | def __exit__(self, exc_type, exc_value, traceback):
32 | self.disable()
33 |
34 | def __call__(self, test_func):
35 | from django.test import TransactionTestCase
36 | if isinstance(test_func, type):
37 | if not issubclass(test_func, TransactionTestCase):
38 | raise Exception(
39 | "Only subclasses of Django SimpleTestCase "
40 | "can be decorated with override_settings")
41 | original_pre_setup = test_func._pre_setup
42 | original_post_teardown = test_func._post_teardown
43 |
44 | def _pre_setup(innerself):
45 | self.enable()
46 | original_pre_setup(innerself)
47 |
48 | def _post_teardown(innerself):
49 | original_post_teardown(innerself)
50 | self.disable()
51 | test_func._pre_setup = _pre_setup
52 | test_func._post_teardown = _post_teardown
53 | return test_func
54 | else:
55 | @wraps(test_func)
56 | def inner(*args, **kwargs):
57 | with self:
58 | return test_func(*args, **kwargs)
59 | return inner
60 |
61 | def enable(self):
62 | override = UserSettingsHolder(settings._wrapped)
63 | for key, new_value in self.options.items():
64 | setattr(override, key, new_value)
65 | settings._wrapped = override
66 |
67 | def disable(self):
68 | settings._wrapped = self.wrapped
69 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.txt:
--------------------------------------------------------------------------------
1 | ============
2 | Contributors
3 | ============
4 |
5 | django-crispy-forms Project Lead
6 | ================================
7 |
8 | * Miguel Araujo
9 |
10 | django-uni-form Project Founder
11 | ===============================
12 |
13 | * Daniel Greenfeld
14 |
15 | Contributors
16 | ============
17 |
18 | * Alison Rowland
19 | * Bojan Mihelac
20 | * bjunix
21 | * Casper S. Jensen
22 | * Chris Adams
23 | * Eddy Mulyono
24 | * j0hnsmith
25 | * James Pic
26 | * James Tauber
27 | * Karl Bowden
28 | * Marcin Grzybowski
29 | * Michael Lind Mortensen
30 | * mirumee
31 | * mvaerle
32 | * Nagy Viktor
33 | * Patrick Lauber
34 | * Patryk Zawadzki
35 | * Skylar Saveland
36 | * Stepan Rakhimov
37 | * John Maxwell
38 | * Richard Marko
39 | * Victor Nagy
40 | * Antti Kaihola
41 | * J. Javier Maestro
42 | * Issac Kelly
43 | * John Debs
44 | * Adam Cupiał
45 | * Nicolas Patry
46 | * Jonas Obrist
47 | * Charlie Denton
48 | * Jason Culverhouse
49 | * James Turnbull
50 | * Patrick Toal
51 | * David Bennett
52 | * bitrut
53 | * ximi
54 | * Christopher Petrilli
55 | * James Friedman
56 | * Jeroen Vloothuis
57 | * Daniel Izquierdo
58 | * gaftech
59 | * Michal Kuffa
60 | * Paul Oswald
61 | * Rudy Mutter
62 | * Samuel Goldszmidt
63 | * Andrei Antoukh
64 | *
65 | * Rivo Laks
66 | * Lloyd Philbrook
67 | * Piet Delport
68 | *
69 | * Markus Hametner
70 | * Thomas Grainger
71 | * Lee Semel
72 | *
73 | * Alex Yakovlev
74 | * Si Feng
75 | * Igor Katson
76 | * Ben Delevingne
77 | *
78 | * Evan Borgstrom
79 | * Daniel Shapiro
80 | *
81 | * Stefan "hr" Berder (白峰)
82 | * Suleyman Melikoglu
83 | * Vladislav Mitov
84 | * Nemesis Fixx
85 | * Chris Vigelius
86 | * David Cramer
87 | * Stas Rudakou
88 | * Tom Yam
89 | * Svyatoslav Bulbakha
90 | * Andres Vargas
91 | * Gabe Jackson
92 | * Camilo Nova
93 | *
94 | * Daniel Mascarenhas
95 | * Paras Kuhad
96 | * Kevin Trad
97 | * Steven Klass
98 | * David Fischer
99 | * Stefan Tjarks
100 | * Jan Dittberner
101 | * Michael Nielsen
102 | * Stephen Mitchell
103 | *
104 | * Christopher Adams
105 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 |
9 | # Internal variables.
10 | PAPEROPT_a4 = -D latex_paper_size=a4
11 | PAPEROPT_letter = -D latex_paper_size=letter
12 | ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
13 |
14 | .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
15 |
16 | help:
17 | @echo "Please use \`make ' where is one of"
18 | @echo " html to make standalone HTML files"
19 | @echo " dirhtml to make HTML files named index.html in directories"
20 | @echo " pickle to make pickle files"
21 | @echo " json to make JSON files"
22 | @echo " htmlhelp to make HTML files and a HTML help project"
23 | @echo " qthelp to make HTML files and a qthelp project"
24 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
25 | @echo " changes to make an overview of all changed/added/deprecated items"
26 | @echo " linkcheck to check all external links for integrity"
27 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
28 |
29 | clean:
30 | -rm -rf _build/*
31 |
32 | html:
33 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
34 | @echo
35 | @echo "Build finished. The HTML pages are in _build/html."
36 |
37 | dirhtml:
38 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
39 | @echo
40 | @echo "Build finished. The HTML pages are in _build/dirhtml."
41 |
42 | pickle:
43 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
44 | @echo
45 | @echo "Build finished; now you can process the pickle files."
46 |
47 | json:
48 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
49 | @echo
50 | @echo "Build finished; now you can process the JSON files."
51 |
52 | htmlhelp:
53 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
54 | @echo
55 | @echo "Build finished; now you can run HTML Help Workshop with the" \
56 | ".hhp project file in _build/htmlhelp."
57 |
58 | qthelp:
59 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
60 | @echo
61 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
62 | ".qhcp project file in _build/qthelp, like this:"
63 | @echo "# qcollectiongenerator _build/qthelp/django-uni-form.qhcp"
64 | @echo "To view the help file:"
65 | @echo "# assistant -collectionFile _build/qthelp/django-uni-form.qhc"
66 |
67 | latex:
68 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
69 | @echo
70 | @echo "Build finished; the LaTeX files are in _build/latex."
71 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
72 | "run these through (pdf)latex."
73 |
74 | changes:
75 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
76 | @echo
77 | @echo "The overview file is in _build/changes."
78 |
79 | linkcheck:
80 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
81 | @echo
82 | @echo "Link check complete; look for any errors in the above output " \
83 | "or in _build/linkcheck/output.txt."
84 |
85 | doctest:
86 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
87 | @echo "Testing of doctests in the sources finished, look at the " \
88 | "results in _build/doctest/output.txt."
89 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ===================
2 | django-crispy-forms
3 | ===================
4 |
5 | .. image:: https://travis-ci.org/maraujop/django-crispy-forms.png?branch=master
6 | :alt: Build Status
7 | :target: https://travis-ci.org/maraujop/django-crispy-forms
8 |
9 | The best way to have Django_ DRY forms. Build programmatic reusable layouts out of components, having full control of the rendered HTML without writing HTML in templates. All this without breaking the standard way of doing things in Django, so it plays nice with any other form application.
10 |
11 | The application mainly provides:
12 |
13 | * A filter named ``|crispy`` that will render elegant div based forms. Think of it as the built-in methods: ``as_table``, ``as_ul`` and ``as_p``. You cannot tune up the output, but it is easy to start using it.
14 | * A tag named ``{% crispy %}`` that will render a form based on your configuration and specific layout setup. This gives you amazing power without much hassle, helping you save tons of time.
15 |
16 | Django-crispy-forms supports several frontend frameworks, such as Twitter `Bootstrap`_ (versions 2 and 3), `Uni-form`_ and Foundation. You can also easily adapt your custom company's one, creating your own, `see the docs`_ for more information. You can easily switch among them using ``CRISPY_TEMPLATE_PACK`` setting variable.
17 |
18 | .. _`Uni-form`: http://sprawsm.com/uni-form
19 | .. _`Bootstrap`: http://twitter.github.com/bootstrap/index.html
20 | .. _`see the docs`: http://django-crispy-forms.rtfd.org
21 |
22 | Authors
23 | =======
24 |
25 | django-crispy-forms is the new django-uni-form. django-uni-form was an application created by `Daniel Greenfeld`_ that I leaded since version 0.8.0. The name change tries to better explain the purpose of the application, which changed in a significant way since its birth.
26 |
27 | If you are upgrading from django-uni-form, we have `instructions`_ for helping you.
28 |
29 | * Lead developer: `Miguel Araujo`_
30 |
31 | .. _`Daniel Greenfeld`: https://github.com/pydanny
32 | .. _`Miguel Araujo`: https://github.com/maraujop
33 | .. _`instructions`: http://django-crispy-forms.readthedocs.org/en/1.1.1/migration.html
34 |
35 | Example
36 | =======
37 |
38 | This is a teaser of what you can do with latest django-crispy-forms. `Find here the gist`_ for generating this form:
39 |
40 | .. image:: http://i.imgur.com/LSREg.png
41 |
42 | .. _`Find here the gist`: https://gist.github.com/1838193
43 |
44 | Documentation
45 | =============
46 |
47 | For extensive documentation see the ``docs`` folder or `read it on readthedocs`_
48 |
49 | .. _`read it on readthedocs`: http://django-crispy-forms.readthedocs.org/en/latest/index.html
50 |
51 | Special thanks
52 | ==============
53 |
54 | * To Daniel Greenfeld (`@pydanny`_) for his support, time and the opportunity given to me to do this.
55 | * The name of the project was suggested by the fantastic Audrey Roy (`@audreyr`_)
56 | * To Kenneth Love (`@kennethlove`_) for creating django-uni-form-contrib from which bootstrap template pack was started.
57 |
58 | .. _`@audreyr`: https://github.com/audreyr
59 | .. _`@pydanny`: https://github.com/pydanny
60 | .. _`@kennethlove`: https://github.com/kennethlove
61 |
62 | Note
63 | ----
64 |
65 | django-crispy-forms supports Django 1.3 or higher with Python 2.6.x, Python 2.7.x and Python 3.3.x. If you need to support Python 2.5 or Django 1.2 you will need to use a version of django-crispy-forms less than 1.3. For earlier versions of Django or Python you will need to use django-uni-form 0.7.0.
66 |
67 | .. _Django: http://djangoproject.com
68 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | set SPHINXBUILD=sphinx-build
6 | set ALLSPHINXOPTS=-d _build/doctrees %SPHINXOPTS% .
7 | if NOT "%PAPER%" == "" (
8 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
9 | )
10 |
11 | if "%1" == "" goto help
12 |
13 | if "%1" == "help" (
14 | :help
15 | echo.Please use `make ^` where ^ is one of
16 | echo. html to make standalone HTML files
17 | echo. dirhtml to make HTML files named index.html in directories
18 | echo. pickle to make pickle files
19 | echo. json to make JSON files
20 | echo. htmlhelp to make HTML files and a HTML help project
21 | echo. qthelp to make HTML files and a qthelp project
22 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
23 | echo. changes to make an overview over all changed/added/deprecated items
24 | echo. linkcheck to check all external links for integrity
25 | echo. doctest to run all doctests embedded in the documentation if enabled
26 | goto end
27 | )
28 |
29 | if "%1" == "clean" (
30 | for /d %%i in (_build\*) do rmdir /q /s %%i
31 | del /q /s _build\*
32 | goto end
33 | )
34 |
35 | if "%1" == "html" (
36 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% _build/html
37 | echo.
38 | echo.Build finished. The HTML pages are in _build/html.
39 | goto end
40 | )
41 |
42 | if "%1" == "dirhtml" (
43 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% _build/dirhtml
44 | echo.
45 | echo.Build finished. The HTML pages are in _build/dirhtml.
46 | goto end
47 | )
48 |
49 | if "%1" == "pickle" (
50 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% _build/pickle
51 | echo.
52 | echo.Build finished; now you can process the pickle files.
53 | goto end
54 | )
55 |
56 | if "%1" == "json" (
57 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% _build/json
58 | echo.
59 | echo.Build finished; now you can process the JSON files.
60 | goto end
61 | )
62 |
63 | if "%1" == "htmlhelp" (
64 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% _build/htmlhelp
65 | echo.
66 | echo.Build finished; now you can run HTML Help Workshop with the ^
67 | .hhp project file in _build/htmlhelp.
68 | goto end
69 | )
70 |
71 | if "%1" == "qthelp" (
72 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% _build/qthelp
73 | echo.
74 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
75 | .qhcp project file in _build/qthelp, like this:
76 | echo.^> qcollectiongenerator _build\qthelp\django-uni-form.qhcp
77 | echo.To view the help file:
78 | echo.^> assistant -collectionFile _build\qthelp\django-uni-form.ghc
79 | goto end
80 | )
81 |
82 | if "%1" == "latex" (
83 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% _build/latex
84 | echo.
85 | echo.Build finished; the LaTeX files are in _build/latex.
86 | goto end
87 | )
88 |
89 | if "%1" == "changes" (
90 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% _build/changes
91 | echo.
92 | echo.The overview file is in _build/changes.
93 | goto end
94 | )
95 |
96 | if "%1" == "linkcheck" (
97 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% _build/linkcheck
98 | echo.
99 | echo.Link check complete; look for any errors in the above output ^
100 | or in _build/linkcheck/output.txt.
101 | goto end
102 | )
103 |
104 | if "%1" == "doctest" (
105 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% _build/doctest
106 | echo.
107 | echo.Testing of doctests in the sources finished, look at the ^
108 | results in _build/doctest/output.txt.
109 | goto end
110 | )
111 |
112 | :end
113 |
--------------------------------------------------------------------------------
/crispy_forms/tests/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.db import models
3 |
4 | from crispy_forms.helper import FormHelper
5 |
6 |
7 | class TestForm(forms.Form):
8 | is_company = forms.CharField(label="company", required=False, widget=forms.CheckboxInput())
9 | email = forms.EmailField(label="email", max_length=30, required=True, widget=forms.TextInput(), help_text="Insert your email")
10 | password1 = forms.CharField(label="password", max_length=30, required=True, widget=forms.PasswordInput())
11 | password2 = forms.CharField(label="re-enter password", max_length=30, required=True, widget=forms.PasswordInput())
12 | first_name = forms.CharField(label="first name", max_length=5, required=True, widget=forms.TextInput())
13 | last_name = forms.CharField(label="last name", max_length=5, required=True, widget=forms.TextInput())
14 | datetime_field = forms.DateTimeField(label="date time", widget=forms.SplitDateTimeWidget())
15 |
16 | def clean(self):
17 | super(TestForm, self).clean()
18 | password1 = self.cleaned_data.get('password1', None)
19 | password2 = self.cleaned_data.get('password2', None)
20 | if not password1 and not password2 or password1 != password2:
21 | raise forms.ValidationError("Passwords dont match")
22 |
23 | return self.cleaned_data
24 |
25 |
26 | class TestForm2(TestForm):
27 | def __init__(self, *args, **kwargs):
28 | super(TestForm2, self).__init__(*args, **kwargs)
29 | self.helper = FormHelper(self)
30 |
31 |
32 | class CheckboxesTestForm(forms.Form):
33 | checkboxes = forms.MultipleChoiceField(
34 | choices = (
35 | (1, "Option one"),
36 | (2, "Option two"),
37 | (3, "Option three")
38 | ),
39 | initial = (1,),
40 | widget = forms.CheckboxSelectMultiple,
41 | )
42 |
43 | alphacheckboxes = forms.MultipleChoiceField(
44 | choices = (
45 | ('option_one', "Option one"),
46 | ('option_two', "Option two"),
47 | ('option_three', "Option three")
48 | ),
49 | initial = ('option_two', 'option_three'),
50 | widget = forms.CheckboxSelectMultiple,
51 | )
52 |
53 | numeric_multiple_checkboxes = forms.MultipleChoiceField(
54 | choices = (
55 | (1, "Option one"),
56 | (2, "Option two"),
57 | (3, "Option three")
58 | ),
59 | initial = (1, 2),
60 | widget = forms.CheckboxSelectMultiple,
61 | )
62 |
63 | inline_radios = forms.ChoiceField(
64 | choices = (
65 | ('option_one', "Option one"),
66 | ('option_two', "Option two"),
67 | ),
68 | widget = forms.RadioSelect,
69 | initial = 'option_two',
70 | )
71 |
72 |
73 | class CrispyTestModel(models.Model):
74 | email = models.CharField(max_length=20)
75 | password = models.CharField(max_length=20)
76 |
77 |
78 | class TestForm3(forms.ModelForm):
79 | class Meta:
80 | model = CrispyTestModel
81 | fields = ['email', 'password']
82 | exclude = ['password']
83 |
84 | def __init__(self, *args, **kwargs):
85 | super(TestForm3, self).__init__(*args, **kwargs)
86 | self.helper = FormHelper(self)
87 |
88 |
89 | class TestForm4(forms.ModelForm):
90 | class Meta:
91 | model = CrispyTestModel
92 |
93 |
94 | class TestForm5(forms.Form):
95 | choices = [
96 | (1, 1),
97 | (2, 2),
98 | (1000, 1000),
99 | ]
100 | checkbox_select_multiple = forms.MultipleChoiceField(
101 | widget=forms.CheckboxSelectMultiple,
102 | choices=choices
103 | )
104 | radio_select = forms.ChoiceField(
105 | widget=forms.RadioSelect,
106 | choices=choices
107 | )
108 | pk = forms.IntegerField()
109 |
--------------------------------------------------------------------------------
/crispy_forms/templatetags/crispy_forms_filters.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from django.conf import settings
3 | from django.forms import forms
4 | from django.forms.formsets import BaseFormSet
5 | from django.template import Context
6 | from django.template.loader import get_template
7 | from django.utils.functional import memoize
8 | from django.utils.safestring import mark_safe
9 | from django import template
10 |
11 | from crispy_forms.exceptions import CrispyError
12 | from crispy_forms.utils import flatatt
13 |
14 | TEMPLATE_PACK = getattr(settings, 'CRISPY_TEMPLATE_PACK', 'bootstrap')
15 | DEBUG = getattr(settings, 'DEBUG', False)
16 |
17 |
18 | def uni_formset_template(template_pack=TEMPLATE_PACK):
19 | return get_template('%s/uni_formset.html' % template_pack)
20 | uni_formset_template = memoize(uni_formset_template, {}, 1)
21 |
22 |
23 | def uni_form_template(template_pack=TEMPLATE_PACK):
24 | return get_template('%s/uni_form.html' % template_pack)
25 | uni_form_template = memoize(uni_form_template, {}, 1)
26 |
27 | register = template.Library()
28 |
29 |
30 | @register.filter(name='crispy')
31 | def as_crispy_form(form, template_pack=TEMPLATE_PACK, label_class="", field_class=""):
32 | """
33 | The original and still very useful way to generate a div elegant form/formset::
34 |
35 | {% load crispy_forms_tags %}
36 |
37 |
41 |
42 | or, if you want to explicitly set the template pack::
43 |
44 | {{ myform|crispy:"bootstrap" }}
45 |
46 | In ``bootstrap3`` for horizontal forms you can do::
47 |
48 | {{ myform|label_class:"col-lg-2",field_class:"col-lg-8" }}
49 | """
50 | if isinstance(form, BaseFormSet):
51 | template = uni_formset_template(template_pack)
52 | c = Context({
53 | 'formset': form,
54 | 'form_show_errors': True,
55 | 'form_show_labels': True,
56 | 'label_class': label_class,
57 | 'field_class': field_class,
58 | })
59 | else:
60 | template = uni_form_template(template_pack)
61 | c = Context({
62 | 'form': form,
63 | 'form_show_errors': True,
64 | 'form_show_labels': True,
65 | 'label_class': label_class,
66 | 'field_class': field_class,
67 | })
68 | return template.render(c)
69 |
70 |
71 | @register.filter(name='as_crispy_errors')
72 | def as_crispy_errors(form, template_pack=TEMPLATE_PACK):
73 | """
74 | Renders only form errors the same way as django-crispy-forms::
75 |
76 | {% load crispy_forms_tags %}
77 | {{ form|as_crispy_errors }}
78 |
79 | or::
80 |
81 | {{ form|as_crispy_errors:"bootstrap" }}
82 | """
83 | if isinstance(form, BaseFormSet):
84 | template = get_template('%s/errors_formset.html' % template_pack)
85 | c = Context({'formset': form})
86 | else:
87 | template = get_template('%s/errors.html' % template_pack)
88 | c = Context({'form': form})
89 | return template.render(c)
90 |
91 |
92 | @register.filter(name='as_crispy_field')
93 | def as_crispy_field(field, template_pack=TEMPLATE_PACK):
94 | """
95 | Renders a form field like a django-crispy-forms field::
96 |
97 | {% load crispy_forms_tags %}
98 | {{ form.field|as_crispy_field }}
99 |
100 | or::
101 |
102 | {{ form.field|as_crispy_field:"bootstrap" }}
103 | """
104 | if not isinstance(field, forms.BoundField) and DEBUG:
105 | raise CrispyError('|as_crispy_field got passed an invalid or inexistent field')
106 |
107 | template = get_template('%s/field.html' % template_pack)
108 | c = Context({'field': field, 'form_show_errors': True, 'form_show_labels': True})
109 | return template.render(c)
110 |
111 |
112 | @register.filter(name='flatatt')
113 | def flatatt_filter(attrs):
114 | return mark_safe(flatatt(attrs))
115 |
--------------------------------------------------------------------------------
/docs/template_packs.rst:
--------------------------------------------------------------------------------
1 | =====================================
2 | How to create your own template packs
3 | =====================================
4 |
5 | First you will have to name your template pack, for this you can't use the name of one of the available template packs in crispy-forms, due to name collisions. For example, let's say in the company we work for, a designer has come up with a CSS bootstrap internally known as ``chocolat``. The company has a Django project that needs to start using ``chocolat``, therefore we need to create a folder named ``chocolat`` within our templates directory. Check your ``TEMPLATE_DIRS`` setting in Django and pick your preferred path.
6 |
7 | Once we have that folder created, we will have to create a concrete directory hierarchy so that crispy-forms can pick it up. This is what bootstrap template pack (v2) looks like::
8 |
9 | .
10 | ├── accordion-group.html
11 | ├── accordion.html
12 | ├── betterform.html
13 | ├── display_form.html
14 | ├── errors.html
15 | ├── errors_formset.html
16 | ├── * field.html
17 | ├── layout
18 | │ ├── alert.html
19 | │ ├── * baseinput.html
20 | │ ├── button.html
21 | │ ├── checkboxselectmultiple.html
22 | │ ├── checkboxselectmultiple_inline.html
23 | │ ├── div.html
24 | │ ├── field_errors.html
25 | │ ├── field_errors_block.html
26 | │ ├── field_with_buttons.html
27 | │ ├── fieldset.html
28 | │ ├── formactions.html
29 | │ ├── help_text.html
30 | │ ├── help_text_and_errors.html
31 | │ ├── multifield.html
32 | │ ├── prepended_appended_text.html
33 | │ ├── radioselect.html
34 | │ ├── radioselect_inline.html
35 | │ ├── tab-link.html
36 | │ ├── tab.html
37 | │ └── uneditable_input.html
38 | ├── table_inline_formset.html
39 | ├── * uni_form.html
40 | ├── uni_formset.html
41 | ├── * whole_uni_form.html
42 | └── whole_uni_formset.html
43 |
44 | Take it easy, don't panic, we won't need this many templates for our template pack. Templates are also quite simple to follow if you understand what problem crispy-forms solves. The bare minimum would be the templates marked with an asterisk.
45 |
46 | Fundamentals
47 | ~~~~~~~~~~~~
48 |
49 | First, since crispy-forms 1.5.0, template packs are self contained, you cannot reference a template from a different template pack.
50 |
51 | crispy-forms has many features, but maybe you don't need your template pack to cover all of them. ``{% crispy %}`` templatetag renders forms using a global structure contained within ``whole_uni_form.html``. However, ``|crispy`` filter uses ``uni_form.html``. As you've probably guessed, the name of the templates comes from the old days of django-uni-form. Anyway, as an example, if we don't use ``|crispy`` filter, we don't really need to maintain a ``uni_form.html`` template within our template pack.
52 |
53 | If we are planning on using formsets + ``{% crispy %}`` we will need a ``whole_uni_formset.html``, instead if we use formsets + ``|crispy`` we will need ``uni_formset.html``.
54 |
55 | All of these templates use a tag named ``{% crispy_field %}`` that is loaded doing ``{% load crispy_forms_field %}``, that generates the html for ```` using ``field.html`` template, but previously doing Python preparation beforehand. In case you wonder the code for this tag lives in ``crispy_forms.templatetags.crispy_forms_field``, together with some other stuff.
56 |
57 | So a template pack for a very basic example covering only forms and the usage of ``{% crispy %}`` tag, would need 2 templates: ``whole_uni_form.html``, ``field.html``. Well, that's not completely true, because every layout object has a template attached. So if we wanted to use ``Div``, we would need ``div.html``. Some are not that obvious, if you need ``Submit``, you will need ``baseinput.html``. Some layout objects, don't really have a template attached, like ``HTML``.
58 |
59 | In the previous template tree, there are some templates that are there for DRY purposes, they are not really compulsory or part of a layout object, so don't worry too much.
60 |
61 | Starting
62 | ~~~~~~~~
63 |
64 | Now your best bet is probably start copying some or all of the templates under an existing crispy-forms template pack, such as ``bootstrap3``, then drop the ones you don't need. Next step is edit those templates, and adjust the HTML/CSS making it align with ``chocolat``, that sometimes means dropping/adding divs, classes and other stuff around. You can always create a form in your application, with a helper attached to that new template pack and start trying out your adaptation right away.
65 |
66 | Currently, there is an existing template pack for crispy-forms that doesn't live in core, developed by David Thenon as an external pluggable application named `crispy-forms-foundation`_, it's also a good reference to check out.
67 |
68 | Beware that crispy-forms evolves and adds new ``FormHelper.attributes``, if you want to use those in the future you will have to adapt your templates adding those variables and its handling.
69 |
70 | .. _`crispy-forms-foundation`: https://github.com/sveetch/crispy-forms-foundation
71 |
--------------------------------------------------------------------------------
/docs/_themes/flask_theme_support.py:
--------------------------------------------------------------------------------
1 | # flasky extensions. flasky pygments style based on tango style
2 | from pygments.style import Style
3 | from pygments.token import Keyword, Name, Comment, String, Error, \
4 | Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
5 |
6 |
7 | class FlaskyStyle(Style):
8 | background_color = "#f8f8f8"
9 | default_style = ""
10 |
11 | styles = {
12 | # No corresponding class for the following:
13 | #Text: "", # class: ''
14 | Whitespace: "underline #f8f8f8", # class: 'w'
15 | Error: "#a40000 border:#ef2929", # class: 'err'
16 | Other: "#000000", # class 'x'
17 |
18 | Comment: "italic #8f5902", # class: 'c'
19 | Comment.Preproc: "noitalic", # class: 'cp'
20 |
21 | Keyword: "bold #004461", # class: 'k'
22 | Keyword.Constant: "bold #004461", # class: 'kc'
23 | Keyword.Declaration: "bold #004461", # class: 'kd'
24 | Keyword.Namespace: "bold #004461", # class: 'kn'
25 | Keyword.Pseudo: "bold #004461", # class: 'kp'
26 | Keyword.Reserved: "bold #004461", # class: 'kr'
27 | Keyword.Type: "bold #004461", # class: 'kt'
28 |
29 | Operator: "#582800", # class: 'o'
30 | Operator.Word: "bold #004461", # class: 'ow' - like keywords
31 |
32 | Punctuation: "bold #000000", # class: 'p'
33 |
34 | # because special names such as Name.Class, Name.Function, etc.
35 | # are not recognized as such later in the parsing, we choose them
36 | # to look the same as ordinary variables.
37 | Name: "#000000", # class: 'n'
38 | Name.Attribute: "#c4a000", # class: 'na' - to be revised
39 | Name.Builtin: "#004461", # class: 'nb'
40 | Name.Builtin.Pseudo: "#3465a4", # class: 'bp'
41 | Name.Class: "#000000", # class: 'nc' - to be revised
42 | Name.Constant: "#000000", # class: 'no' - to be revised
43 | Name.Decorator: "#888", # class: 'nd' - to be revised
44 | Name.Entity: "#ce5c00", # class: 'ni'
45 | Name.Exception: "bold #cc0000", # class: 'ne'
46 | Name.Function: "#000000", # class: 'nf'
47 | Name.Property: "#000000", # class: 'py'
48 | Name.Label: "#f57900", # class: 'nl'
49 | Name.Namespace: "#000000", # class: 'nn' - to be revised
50 | Name.Other: "#000000", # class: 'nx'
51 | Name.Tag: "bold #004461", # class: 'nt' - like a keyword
52 | Name.Variable: "#000000", # class: 'nv' - to be revised
53 | Name.Variable.Class: "#000000", # class: 'vc' - to be revised
54 | Name.Variable.Global: "#000000", # class: 'vg' - to be revised
55 | Name.Variable.Instance: "#000000", # class: 'vi' - to be revised
56 |
57 | Number: "#990000", # class: 'm'
58 |
59 | Literal: "#000000", # class: 'l'
60 | Literal.Date: "#000000", # class: 'ld'
61 |
62 | String: "#4e9a06", # class: 's'
63 | String.Backtick: "#4e9a06", # class: 'sb'
64 | String.Char: "#4e9a06", # class: 'sc'
65 | String.Doc: "italic #8f5902", # class: 'sd' - like a comment
66 | String.Double: "#4e9a06", # class: 's2'
67 | String.Escape: "#4e9a06", # class: 'se'
68 | String.Heredoc: "#4e9a06", # class: 'sh'
69 | String.Interpol: "#4e9a06", # class: 'si'
70 | String.Other: "#4e9a06", # class: 'sx'
71 | String.Regex: "#4e9a06", # class: 'sr'
72 | String.Single: "#4e9a06", # class: 's1'
73 | String.Symbol: "#4e9a06", # class: 'ss'
74 |
75 | Generic: "#000000", # class: 'g'
76 | Generic.Deleted: "#a40000", # class: 'gd'
77 | Generic.Emph: "italic #000000", # class: 'ge'
78 | Generic.Error: "#ef2929", # class: 'gr'
79 | Generic.Heading: "bold #000080", # class: 'gh'
80 | Generic.Inserted: "#00A000", # class: 'gi'
81 | Generic.Output: "#888", # class: 'go'
82 | Generic.Prompt: "#745334", # class: 'gp'
83 | Generic.Strong: "bold #000000", # class: 'gs'
84 | Generic.Subheading: "bold #800080", # class: 'gu'
85 | Generic.Traceback: "bold #a40000", # class: 'gt'
86 | }
87 |
--------------------------------------------------------------------------------
/crispy_forms/tests/test_tags.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from django.conf import settings
3 | from django.forms.forms import BoundField
4 | from django.forms.models import formset_factory
5 | from django.template import loader, Context
6 |
7 | from .base import CrispyTestCase
8 | from .forms import TestForm
9 | from crispy_forms.templatetags.crispy_forms_field import crispy_addon
10 |
11 |
12 |
13 | class TestBasicFunctionalityTags(CrispyTestCase):
14 | def test_as_crispy_errors_form_without_non_field_errors(self):
15 | template = loader.get_template_from_string(u"""
16 | {% load crispy_forms_tags %}
17 | {{ form|as_crispy_errors }}
18 | """)
19 | form = TestForm({'password1': "god", 'password2': "god"})
20 | form.is_valid()
21 |
22 | c = Context({'form': form})
23 | html = template.render(c)
24 | self.assertFalse("errorMsg" in html or "alert" in html)
25 |
26 | def test_as_crispy_errors_form_with_non_field_errors(self):
27 | template = loader.get_template_from_string(u"""
28 | {% load crispy_forms_tags %}
29 | {{ form|as_crispy_errors }}
30 | """)
31 | form = TestForm({'password1': "god", 'password2': "wargame"})
32 | form.is_valid()
33 |
34 | c = Context({'form': form})
35 | html = template.render(c)
36 | self.assertTrue("errorMsg" in html or "alert" in html)
37 | self.assertTrue("