Browse Source

Misago forms utils #377

Rafał Pitoń 11 years ago
parent
commit
0c76c32d1d

+ 24 - 0
docs/developers/forms.rst

@@ -60,3 +60,27 @@ Thin wrapper around Django's ``TypedChoiceField``. This field renders nice yes/n
 
 
 .. warning::
 .. warning::
    ``YesNoSwitch`` coerces to ``int``, not to ``bool``! Remember about this when writing code dealing with forms containing this field!
    ``YesNoSwitch`` coerces to ``int``, not to ``bool``! Remember about this when writing code dealing with forms containing this field!
+
+
+Template Tags
+=============
+
+Misago defines custom templates extension named ``misago_forms``. This extension contains two template tags for rendering form fields:
+
+
+form_row
+--------
+
+This tag accepts form field as its first argument, and rends field complete with label, help and errors. Accept two extra arguments: label class and field class, allowing you to control size of horizontal forms::
+
+
+    {% load misago_forms %}
+
+    {% form_row form.somefield %}
+    {% form_row form.otherfield 'col-md-3' 'col-md-9' %}
+
+
+form_input
+----------
+
+This tag accepts form field as its only argument, and rends it's input.

+ 6 - 12
misago/core/templatetags/misago_forms.py

@@ -43,28 +43,22 @@ class FormRowNode(template.Node):
     def __init__(self, form_field, label_class, field_class):
     def __init__(self, form_field, label_class, field_class):
         self.form_field = template.Variable(form_field)
         self.form_field = template.Variable(form_field)
 
 
-        if label_class:
+        if label_class and field_class:
             self.label_class = template.Variable(label_class)
             self.label_class = template.Variable(label_class)
-        else:
-            self.label_class = None
-
-        if field_class:
             self.field_class = template.Variable(field_class)
             self.field_class = template.Variable(field_class)
         else:
         else:
+            self.label_class = None
             self.field_class = None
             self.field_class = None
 
 
     def render(self, context):
     def render(self, context):
         field = self.form_field.resolve(context)
         field = self.form_field.resolve(context)
 
 
-        try:
+        if self.label_class and self.field_class:
             label_class = self.label_class.resolve(context)
             label_class = self.label_class.resolve(context)
-        except:
-            label_class = self.label_class
-
-        try:
             field_class = self.field_class.resolve(context)
             field_class = self.field_class.resolve(context)
-        except:
-            field_class = self.field_class
+        else:
+            label_class = None
+            field_class = None
 
 
         template_pack = crispy_forms_filters.TEMPLATE_PACK
         template_pack = crispy_forms_filters.TEMPLATE_PACK
         template = get_template('%s/field.html' % template_pack)
         template = get_template('%s/field.html' % template_pack)

+ 108 - 0
misago/core/tests/test_templatetags.py

@@ -0,0 +1,108 @@
+from django.template import Context, Template, TemplateSyntaxError
+from django.test import TestCase
+from misago.core import forms
+
+
+class TestForm(forms.Form):
+    somefield = forms.CharField(label="Hello!", max_length=255)
+
+
+class FormRowTests(TestCase):
+    def setUp(self):
+        self.context = Context({'form': TestForm()})
+
+    def test_form_row_no_args(self):
+        """form_row with no args renders form row"""
+        tpl_content = """
+{% load misago_forms %}
+
+{% form_row form.somefield %}
+"""
+
+        tpl = Template(tpl_content)
+        render = tpl.render(self.context).strip()
+        self.assertIn('id_somefield', render)
+
+    def test_form_row_with_args(self):
+        """form_row with args renders form row"""
+        tpl_content = """
+{% load misago_forms %}
+
+{% form_row form.somefield "col-md-3" "col-md-9" %}
+"""
+
+        tpl = Template(tpl_content)
+        render = tpl.render(self.context).strip()
+
+        self.assertIn('id_somefield', render)
+        self.assertIn('col-md-3', render)
+        self.assertIn('col-md-9', render)
+
+    def test_form_row_with_value_args(self):
+        """form_row with values args renders form row"""
+        tpl_content = """
+{% load misago_forms %}
+
+{% with label="col-md-3" field="col-md-9" %}
+    {% form_row form.somefield label field %}
+{% endwith %}
+"""
+
+        tpl = Template(tpl_content)
+        render = tpl.render(self.context).strip()
+        self.assertIn('id_somefield', render)
+        self.assertIn('col-md-3', render)
+        self.assertIn('col-md-9', render)
+
+    def test_form_row_with_no_args(self):
+        """form_row with no args raises exception"""
+        tpl_content = """
+{% load misago_forms %}
+
+{% form_row %}
+"""
+
+        with self.assertRaises(TemplateSyntaxError):
+            tpl = Template(tpl_content)
+            render = tpl.render(self.context).strip()
+
+    def test_form_row_with_two_args(self):
+        """form_row with two args raises exception"""
+        tpl_content = """
+{% load misago_forms %}
+
+{% form_row form.somefield "col-md-9" %}
+"""
+
+        with self.assertRaises(TemplateSyntaxError):
+            tpl = Template(tpl_content)
+            render = tpl.render(self.context).strip()
+
+    def test_form_row_with_four_args(self):
+        """form_row with four args raises exception"""
+        tpl_content = """
+{% load misago_forms %}
+
+{% form_row form.somefield "col-md-9" "col-md-9" "col-md-9" %}
+"""
+
+        with self.assertRaises(TemplateSyntaxError):
+            tpl = Template(tpl_content)
+            render = tpl.render(self.context).strip()
+
+
+class FormInputTests(TestCase):
+    def setUp(self):
+        self.context = Context({'form': TestForm()})
+
+    def test_form_input(self):
+        """form_imput renders form field"""
+        tpl_content = """
+{% load misago_forms %}
+
+{% form_input form.somefield %}
+"""
+
+        tpl = Template(tpl_content)
+        render = tpl.render(self.context).strip()
+        self.assertIn('id_somefield', render)