1. Andriy Kornatskyy
  2. wheezy.html

Commits

Andriy Kornatskyy  committed f25531e

Added support for empty value in textbox and password widgets; Introduced emptybox widget.

  • Participants
  • Parent commits ab0dcd7
  • Branches default

Comments (0)

Files changed (2)

File src/wheezy/html/ext/lexer.py

View file
 RE_KWARGS = re.compile(
     '\s*(?P<name>\w+)\s*=\s*(?P<expr>([\'"].*?[\'"]|.+?))\s*\,')
 RE_STR_VALUE = re.compile(
-    '[\'"](?P<value>.+)[\'"]$')
+    '^[\'"](?P<value>.+)[\'"]$')
+RE_INT_VALUE = re.compile(
+    '^(?P<value>(\d+))$')
 RE_FUNCTIONS = re.compile(
     '\.(%s)\(' % '|'.join(known_functions))
 RE_FUNCTION = re.compile(
 def parse_known_function(expr):
     """
         >>> parse_known_function("dob")
-        'dob'
+        ('dob', 'dob')
         >>> parse_known_function("dob.format()")
-        'format_value(dob, None)'
+        ('dob', 'format_value(dob, None)')
         >>> parse_known_function("user.dob.format(_('YYYY/MM/DD'))")
-        "format_value(user.dob, _('YYYY/MM/DD'))"
+        ('user.dob', "format_value(user.dob, _('YYYY/MM/DD'))")
         >>> parse_known_function("user.dob.format(\
 format_provider=lambda value, ignore: value.strftime('%m-%d-%y'))")
-        "format_value(user.dob, format_provider=lambda value, \
-ignore: value.strftime('%m-%d-%y'))"
+        ('user.dob', "format_value(user.dob, format_provider=lambda value, \
+ignore: value.strftime('%m-%d-%y'))")
     """
     m = RE_FUNCTION.search(expr)
     if not m:
-        return expr
+        return expr, expr
     context = m.group('context')
     name = m.group('name')
     args = m.group('args') or 'None'
-    return "%s_value(%s, %s)" % (name, context, args)
+    return context, "%s_value(%s, %s)" % (name, context, args)
 
 
 def parse_kwargs(text):

File src/wheezy/html/ext/mako.py

View file
 
 import re
 
+from wheezy.html.ext.lexer import RE_INT_VALUE
 from wheezy.html.ext.lexer import RE_STR_VALUE
 from wheezy.html.ext.lexer import parse_known_function
 from wheezy.html.ext.lexer import parse_name
         ... '<input type="hidden" name="pref" value="abc" />', user=User())
     """
     name = parse_name(expr)
-    return '<input type="hidden" name="%(name)s" value="%(value)s" />' % {
-            'name': name,
-            'value': expression(expr, filter)}
+    return """\
+<input type="hidden" name="%(name)s" value="%(value)s" />""" % {
+        'name': name,
+        'value': expression(expr, filter)}
 
 
 def multiple_hidden(expr, params, filter):
     name = parse_name(expr)
     args, kwargs = parse_params(params)
     class_ = kwargs.pop('class', None)
-    return '<label for="%(id)s"%(attrs)s%(class)s>%(value)s</label>' % {
-            'id': html_id(name),
-            'name': name,
-            'value': expression(args[0], filter),
-            'attrs': join_attrs(kwargs),
-            'class': error_class(name, class_)}
+    return """\
+<label for="%(id)s"%(attrs)s%(class)s>%(value)s</label>""" % {
+        'id': html_id(name),
+        'name': name,
+        'value': expression(args[0], filter),
+        'attrs': join_attrs(kwargs),
+        'class': error_class(name, class_)}
 
 
 def input(expr, params, filter, input_type):
     """ HTML element input of type input_type.
 
+        >>> t = "${transfer_spec.min_amount.emptybox(maxlength=5)}"
+        >>> mako_template = widget_preprocessor(t, skip_imports=True)
+        >>> print(mako_template)
+        <input id="min-amount" name="min_amount" type="text" \
+maxlength="5"\\
+        % if 'min_amount' in errors:
+         class="error"\\
+        % endif
+        % if transfer_spec.min_amount:
+         value="${transfer_spec.min_amount}" />\\
+        % else:
+         />\\
+        % endif
+        <BLANKLINE>
+
         >>> t = "${credential.password.password(autocomplete='off')|h}"
         >>> mako_template = widget_preprocessor(t, skip_imports=True)
         >>> print(mako_template)
         % if 'password' in errors:
          class="error"\\
         % endif
-         value="${credential.password|h}" />
+        % if credential.password not in (None, ''):
+         value="${credential.password|h}" />\\
+        % else:
+         />\\
+        % endif
+        <BLANKLINE>
 
         >>> class Credential(object):
         ...     password = '<x'
         % if 'date_of_birth' in errors:
          class="error"\\
         % endif
-         value="${format_value(registration.date_of_birth, _('YYYY/MM/DD'))}"\
- />
+        % if registration.date_of_birth not in (None, ''):
+         value="${format_value(registration.date_of_birth, \
+_('YYYY/MM/DD'))}" />\\
+        % else:
+         />\\
+        % endif
+        <BLANKLINE>
 
         >>> from datetime import date
         >>> class Registration(object):
     name = parse_name(expr)
     args, kwargs = parse_params(params)
     class_ = kwargs.pop('class', None)
-    return """<input id="%(id)s" name="%(name)s" \
-type="%(type)s"%(attrs)s%(class)s value="%(value)s" />""" % {
-            'id': html_id(name),
-            'name': name,
-            'type': input_type,
-            'value': expression(parse_known_function(expr), filter),
-            'attrs': join_attrs(kwargs),
-            'class': error_class(name, class_)}
+    if input_type == 'empty':
+        input_type = 'text'
+        condition = ''
+    else:
+        condition = " not in (None, '')"
+    value, func = parse_known_function(expr)
+    return """\
+<input id="%(id)s" name="%(name)s" type="%(type)s"%(attrs)s%(class)s\
+%% if %(value)s%(condition)s:
+ value="${%(func)s%(filter)s}" />\\
+%% else:
+ />\\
+%% endif
+""" % {
+        'id': html_id(name),
+        'name': name,
+        'type': input_type,
+        'value': value,
+        'condition': condition,
+        'func': func,
+        'filter': filter,
+        'attrs': join_attrs(kwargs),
+        'class': error_class(name, class_)}
 
 
 def textarea(expr, params, filter):
     kwargs.setdefault('rows', '"9"')
     kwargs.setdefault('cols', '"40"')
     class_ = kwargs.pop('class', None)
-    return '<textarea id="%(id)s" name="%(name)s"%(attrs)s%(class)s>\
-%(value)s</textarea>' % {
-            'id': html_id(name),
-            'name': name,
-            'value': expression(expr, filter),
-            'attrs': join_attrs(kwargs),
-            'class': error_class(name, class_)}
+    return """\
+<textarea id="%(id)s" name="%(name)s"%(attrs)s%(class)s>\
+%(value)s</textarea>""" % {
+        'id': html_id(name),
+        'name': name,
+        'value': expression(expr, filter),
+        'attrs': join_attrs(kwargs),
+        'class': error_class(name, class_)}
 
 
 def checkbox(expr, params, filter):
  checked="checked"\\
 %% endif
  />""" % {
-            'id': html_id(name),
-            'name': name,
-            'value': expr,
-            'attrs': join_attrs(kwargs),
-            'class': error_class(name, class_)}
+        'id': html_id(name),
+        'name': name,
+        'value': expr,
+        'attrs': join_attrs(kwargs),
+        'class': error_class(name, class_)}
 
 
 def multiple_checkbox(expr, params, filter):
  />${text%(filter)s}</label>\\
 %% endfor
 """ % {
-            'id': html_id(name),
-            'name': name,
-            'choices': choices,
-            'value': expr,
-            'filter': filter,
-            'attrs': join_attrs(kwargs),
-            'class': error_class(name, class_)}
+        'id': html_id(name),
+        'name': name,
+        'choices': choices,
+        'value': expr,
+        'filter': filter,
+        'attrs': join_attrs(kwargs),
+        'class': error_class(name, class_)}
 
 
 def radio(expr, params, filter):
         % endif
          />${text}</label>\\
         % endfor
+        <BLANKLINE>
 
         >>> from operator import itemgetter
         >>> scm = sorted({
  checked="checked"\\
 %% endif
  />${text%(filter)s}</label>\\
-%% endfor""" % {
-            'id': html_id(name),
-            'name': name,
-            'value': expr,
-            'filter': filter,
-            'attrs': join_attrs(kwargs),
-            'class': error_class(name, class_),
-            'choices': choices}
+%% endfor
+""" % {
+        'id': html_id(name),
+        'name': name,
+        'value': expr,
+        'filter': filter,
+        'attrs': join_attrs(kwargs),
+        'class': error_class(name, class_),
+        'choices': choices}
 
 
 def select(expr, params, filter, select_type):
 >${text%(filter)s}</option>\\
 %% endfor
 </select>""" % {
-            'id': html_id(name),
-            'name': name,
-            'select_type': select_type,
-            'value': expr,
-            'filter': filter,
-            'attrs': join_attrs(kwargs),
-            'class': error_class(name, class_),
-            'choices': choices}
+        'id': html_id(name),
+        'name': name,
+        'select_type': select_type,
+        'value': expr,
+        'filter': filter,
+        'attrs': join_attrs(kwargs),
+        'class': error_class(name, class_),
+        'choices': choices}
 
 
 def error(expr, params, filter):
         % if '__ERROR__' in errors:
         <span class="error-message">${errors['__ERROR__'][-1]|h}</span>\\
         % endif
+        <BLANKLINE>
 
         >>> mako_template = widget_preprocessor(t, skip_imports=True)
         >>> assert_mako_equal(mako_template,
         % if 'username' in errors:
         <span class="error">${errors['username'][-1]}</span>\\
         % endif
+        <BLANKLINE>
 
         >>> mako_template = widget_preprocessor(t, skip_imports=True)
         >>> assert_mako_equal(mako_template,
     return """\\
 %% if '%(name)s' in errors:
 <span class="%(class)s">${errors['%(name)s'][-1]%(filter)s}</span>\\
-%% endif""" % {
-            'name': name,
-            'attrs': join_attrs(kwargs),
-            'class': class_,
-            'filter': filter}
+%% endif
+""" % {
+        'name': name,
+        'attrs': join_attrs(kwargs),
+        'class': class_,
+        'filter': filter}
 
 
 def info(expr, params, filter, class_):
         % if message:
         <span class="warning-message">${message}</span>\\
         % endif
+        <BLANKLINE>
 
         >>> t = "${message.info()}"
         >>> print(widget_preprocessor(t, skip_imports=True))
         % if message:
         <span class="info-message">${message}</span>\\
         % endif
+        <BLANKLINE>
 
         >>> mako_template = widget_preprocessor(t, skip_imports=True)
         >>> assert_mako_equal(mako_template,
         % if user.name_status:
         <span class="warning">${user.name_status|h}</span>\\
         % endif
+        <BLANKLINE>
 
         >>> t = "${user.name_status.info()|h}"
         >>> print(widget_preprocessor(t, skip_imports=True))
         % if user.name_status:
         <span class="info">${user.name_status|h}</span>\\
         % endif
+        <BLANKLINE>
 
         >>> class User(object):
         ...     name_status = 'Available'
     return """\\
 %% if %(value)s:
 <span class="%(class)s">%(info)s</span>\\
-%% endif""" % {
-            'value': expr,
-            'info': expression(expr, filter),
-            'class': class_}
+%% endif
+""" % {
+        'value': expr,
+        'info': expression(expr, filter),
+        'class': class_}
 
 
 # region: helpers
         'Hello'
         >>> expression('"Hello"', '|h')
         'Hello'
+        >>> expression('100')
+        '100'
         >>> expression('model.username')
         '${model.username}'
         >>> expression('model.username', '|h')
     if m:
         return m.group('value')
     else:
-        return '${%s%s}' % (text, filter)
+        m = RE_INT_VALUE.match(text)
+        if m:
+            return m.group('value')
+        else:
+            return '${%s%s}' % (text, filter)
 
 
 def join_attrs(kwargs):
     'hidden': hidden,
     'multiple_hidden': multiple_hidden,
     'label': label,
+    'emptybox': lambda expr, params, filter: input(
+            expr, params, filter, 'empty'),
     'textbox': lambda expr, params, filter: input(
             expr, params, filter, 'text'),
     'password': lambda expr, params, filter: input(
 }
 
 RE_WIDGETS = re.compile(
-        '(?<!##)\$\{((?P<expr>.+?)\.(?P<widget>%s){1}\((?P<params>.*?)\)\s*'
-        '(?P<filter>(\|\s*[\w,\s]+?|\s*)))\}'
+        '(?<!##)\s*\$\{((?P<expr>.+?)\.(?P<widget>%s){1}\((?P<params>.*?)\)\s*'
+        '(?P<filter>(\|\s*[\w,\s]+?|\s*)))\}\s*'
         % '|'.join(widgets))
 
 
 def widget_preprocessor(text, skip_imports=False):
     """
-        >>> t = "${credential.username.label('Username:')}\
-${credential.username.textbox()}${credential.username.error()}"
+        >>> t = "&nbsp;   ${credential.username.label('Username:')}\
+${credential.username.textbox()}${credential.username.error()} &nbsp;"
         >>> mako_template = widget_preprocessor(t)
         >>> print(mako_template)
         <%!
         from wheezy.html.utils import format_value
-        %><label for="username"\\
+        %>&nbsp;<label for="username"\\
         % if 'username' in errors:
          class="error"\\
         % endif
         % if 'username' in errors:
          class="error"\\
         % endif
+        % if credential.username not in (None, ''):
          value="${credential.username}" />\\
+        % else:
+         />\\
+        % endif
+        \\
         % if 'username' in errors:
         <span class="error">${errors['username'][-1]}</span>\\
         % endif
+        &nbsp;
     """
     result = []
     start = 0