Commits

Andriy Kornatskyy  committed 63b468c

Moved html attribute processing from general widget to concrete

  • Participants
  • Parent commits 2eeaad7

Comments (0)

Files changed (4)

File src/wheezy/html/builder.py

             >>> w = Widget('label', 'zip_code', 'Zip Code', None)
             >>> w()
             <label for="zip-code">Zip Code</label>
+            >>> w = Widget('label', 'zip_code', None, None)
+            >>> w('Zip Code')
+            <label for="zip-code">Zip Code</label>
         """
         if value is None:
             value = self.value
         else:
             value = html_escape(value)
-        tag = self.tag(self.name, value, attrs)
-        if attrs and hasattr(tag, 'attrs'):
-            tag.attrs.update(attrs)
         if self.errors:
-            tag.append_attr('class_', CSS_CLASS_ERROR)
-        return tag
+            if 'class_' in attrs:
+                attrs['class_'] = CSS_CLASS_ERROR + ' ' + attrs['class_']
+            else:
+                attrs['class'] = CSS_CLASS_ERROR
+        return self.tag(self.name, value, attrs)
 
 
 class WidgetBuilder(object):
         ''
         >>> errors.append('required')
         >>> h = WidgetBuilder('age', '0', errors)
+        >>> h.textbox()
+        <input class="error" type="text" id="age" value="0" name="age" />
         >>> h.textbox(class_='b')
         <input class="error b" type="text" id="age" value="0" name="age" />
         >>> h.error()

File src/wheezy/html/factory.py

         Errors
 
         >>> errors = {
-        ...         'id': ['error 1'],
         ...         'name': ['error 2'],
         ...         'accept': ['error 3'],
         ...         'favorite_color': ['error 4']
 
         Render error message
 
-        >>> user.id.error()
-        <span class="error">error 1</span>
+        >>> user.favorite_color.error()
+        <span class="error">error 4</span>
 
         HTML tags got class ``error``.
 
-        >>> user.id.hidden()
-        <input class="error" type="hidden" name="id" value="12345" />
         >>> user.name.textbox(class_='x')  #doctest: +NORMALIZE_WHITESPACE
         <input class="error x" type="text" id="name" value="John"
             name="name" />
             name="name">John</textarea>
         >>> user.accept.checkbox()  #doctest: +NORMALIZE_WHITESPACE
         <input type="hidden" name="accept" /><input checked="checked"
-            name="accept" value="1" class="error" type="checkbox"
-            id="accept" />
+            name="accept" type="checkbox" id="accept" value="1"
+            class="error" />
         >>> user.favorite_color.label('Color:')
         <label class="error" for="favorite-color">Color:</label>
 

File src/wheezy/html/markup.py

             self.attrs.update(attrs)
         return self
 
-    def append_attr(self, name, value):
-        """
-            If there is no attribute with ``name`` than it added.
-
-            >>> t = Tag('x')
-            >>> t.append_attr('class', 'a')
-            >>> t
-            <x class="a" />
-
-            Existing attribute is extended with space and value.
-
-            >>> t.append_attr('class', 'b')
-            >>> t
-            <x class="b a" />
-        """
-        attrs = self.attrs
-        if name in attrs:
-            attrs[name] = value + ' ' + attrs[name]
-        else:
-            attrs[name] = value
-
     def __unicode__(self):  # pragma: nocover, python 3
         """
             >>> assert str_type(Tag('x')) == str_type('<x />')
         return self.render(str_type)
 
     def __str__(self):
+        """
+            >>> assert str(Tag('x')) == '<x />'
+        """
         return self.render(str)
 
     def __repr__(self):
             12
         """
         return ''.join(map(repr, self.tags))
-
-    def __getattr__(self, name):
-        return getattr(self.tags[-1], name)

File src/wheezy/html/widgets.py

 
 def textbox(name, value, attrs=None):
     """
-        >>> textbox('zip_code', '79053')
-        <input type="text" id="zip-code" value="79053" name="zip_code" />
+        >>> textbox('zip_code', '79053',
+        ...         attrs={'class': 'error'})  #doctest: +NORMALIZE_WHITESPACE
+        <input class="error" type="text" id="zip-code" value="79053"
+            name="zip_code" />
     """
-    return Tag('input', attrs={
+    tag_attrs = {
             'id': id(name),
             'name': name,
             'type': 'text',
             'value': value
-    })
+    }
+    if attrs:
+        tag_attrs.update(attrs)
+    return Tag('input', attrs=tag_attrs)
 
 
 def password(name, value, attrs=None):
     """
-        >>> password('passwd', '')
-        <input type="password" id="passwd" value="" name="passwd" />
+        >>> password('passwd', '',
+        ...         attrs={'class': 'error'})  #doctest: +NORMALIZE_WHITESPACE
+        <input class="error" type="password" id="passwd" value=""
+            name="passwd" />
     """
-    return Tag('input', attrs={
+    tag_attrs = {
             'id': id(name),
             'name': name,
             'type': 'password',
             'value': value
-    })
+    }
+    if attrs:
+        tag_attrs.update(attrs)
+    return Tag('input', attrs=tag_attrs)
 
 
-def textarea(name, value, attrs=None):
+def textarea(name, value, attrs):
     """
-        >>> textarea('message_text', 'x')  #doctest: +NORMALIZE_WHITESPACE
+        >>> textarea('message_text', 'x', {})  #doctest: +NORMALIZE_WHITESPACE
         <textarea rows="9" cols="40" id="message-text"
             name="message_text">x</textarea>
 
         ``value`` is empty.
 
-        >>> textarea('message_text', '')  #doctest: +NORMALIZE_WHITESPACE
-        <textarea rows="9" cols="40" id="message-text"
-            name="message_text"></textarea>
+        >>> textarea('message_text', '', attrs={
+        ...    'class': 'error', 'rows': '10'
+        ... })  #doctest: +NORMALIZE_WHITESPACE
+        <textarea rows="10" name="message_text" class="error" cols="40"
+            id="message-text"></textarea>
     """
-    return Tag('textarea', value, attrs={
+    tag_attrs = {
             'id': id(name),
             'name': name,
             'rows': '9',
             'cols': '40'
-    })
+    }
+    if attrs:
+        tag_attrs.update(attrs)
+    return Tag('textarea', value, tag_attrs)
 
 
-def checkbox(name, checked, attrs=None):
+def checkbox(name, checked, attrs):
     """
-        >>> checkbox('accept', 'True')  #doctest: +NORMALIZE_WHITESPACE
+        >>> checkbox('accept', 'True', {})  #doctest: +NORMALIZE_WHITESPACE
         <input type="hidden" name="accept" /><input checked="checked"
             type="checkbox" id="accept" value="1" name="accept" />
-        >>> checkbox('accept', 'False')  #doctest: +NORMALIZE_WHITESPACE
+        >>> checkbox('accept', 'False', {})  #doctest: +NORMALIZE_WHITESPACE
         <input type="hidden" name="accept" /><input type="checkbox"
             id="accept" value="1" name="accept" />
 
         >>> checkbox('accept', 'True',
-        ...         attrs={'class_': 'b'})  #doctest: +NORMALIZE_WHITESPACE
-        <input type="hidden" name="accept" /><input class="b"
-            checked="checked" name="accept" type="checkbox"
-            id="accept" value="1" />
+        ...         attrs={'class': 'b'})  #doctest: +NORMALIZE_WHITESPACE
+        <input type="hidden" name="accept" /><input checked="checked"
+            name="accept" type="checkbox" id="accept" value="1" class="b" />
      """
     tag_attrs = {
             'id': id(name),
     ))
 
 
-def label(name, value, attrs=None):
+def label(name, value, attrs):
     """
-        >>> label('zip_code', 'Zip Code')
+        >>> label('zip_code', 'Zip Code', {})
         <label for="zip-code">Zip Code</label>
         >>> label('zip_code', 'Zip Code', attrs={'class_': 'inline'})
         <label class="inline" for="zip-code">Zip Code</label>
         >>> colors
         [('2', 'Red'), ('1', 'Yellow')]
         >>> dropdown('favorite_color', '1', attrs={
-        ...     'choices': colors})  #doctest: +NORMALIZE_WHITESPACE
-        <select id="favorite-color" name="favorite_color"><option
-            value="2">Red</option><option selected="selected"
-            value="1">Yellow</option></select>
+        ...     'choices': colors,
+        ...     'class': 'error'
+        ... })  #doctest: +NORMALIZE_WHITESPACE
+        <select class="error" id="favorite-color"
+            name="favorite_color"><option value="2">Red</option><option
+            selected="selected" value="1">Yellow</option></select>
     """
     choices = attrs.pop('choices')
-    options = []
+    options = Fragment([])
+    append = options.tags.append
     for key, text in choices:
         if key == value:
             tag_attrs = {
             tag_attrs = {
                     'value': key
             }
-        options.append(Tag('option', inner=text, attrs=tag_attrs))
-    options = Fragment(options)
+        append(Tag('option', inner=text, attrs=tag_attrs))
     tag_attrs = {
             'id': id(name),
             'name': name
     }
+    if attrs:
+        tag_attrs.update(attrs)
     return Tag('select', inner=options, attrs=tag_attrs)
 
 
-def radio(name, value, attrs=None):
+def radio(name, value, attrs):
     """
         >>> from operator import itemgetter
         >>> scm = sorted({'git': 'Git', 'hg': 'Mercurial'}.items(),
         >>> scm
         [('git', 'Git'), ('hg', 'Mercurial')]
 
-        >>> radio('scm', 'hg',
-        ...         attrs={'choices': scm})  #doctest: +NORMALIZE_WHITESPACE
-        <label><input type="radio" name="scm" value="git"
-        />Git</label><label><input checked="checked" type="radio" name="scm"
-        value="hg" />Mercurial</label>
+        >>> radio('scm', 'hg', attrs={
+        ...     'choices': scm, 'class': 'error'
+        ... })  #doctest: +NORMALIZE_WHITESPACE
+        <label class="error"><input type="radio" name="scm" value="git"
+        />Git</label><label class="error"><input checked="checked"
+        type="radio" name="scm" value="hg" />Mercurial</label>
     """
     choices = attrs.pop('choices')
     elements = []
         if key == value:
             tag_attrs['checked'] = 'checked'
         append(Tag('label',
-            Fragment((Tag('input', attrs=tag_attrs), text))))
+            Fragment((Tag('input', attrs=tag_attrs), text)), attrs=attrs))
     return Fragment(elements)
 
 default = {