Attachment 'patch-userform-login-improved-1.8.diff'

Download

   1 # HG changeset patch
   2 # User Paul Boddie <paul@boddie.org.uk>
   3 # Date 1299182511 -3600
   4 # Node ID 77bea805221c0b3de5f9af9b49e0bbae0af7e469
   5 # Parent  12a9b828133466eaeff0629a60e870e41b6296e2
   6 Changed the login form to group fields by authentication method, showing each
   7 method's hint below the fields. Each group of fields is within its own HTML
   8 form, so that only relevant fields are submitted.
   9 Added more HTML attributes to the HTML widget classes.
  10 
  11 diff -r 12a9b8281334 -r 77bea805221c MoinMoin/userform/login.py
  12 --- a/MoinMoin/userform/login.py	Sat Feb 26 21:28:45 2011 +0100
  13 +++ b/MoinMoin/userform/login.py	Thu Mar 03 21:01:51 2011 +0100
  14 @@ -4,6 +4,7 @@
  15  
  16      @copyright: 2001-2004 Juergen Hermann <jh@web.de>,
  17                  2003-2007 MoinMoin:ThomasWaldmann
  18 +                2011 Paul Boddie <paul@boddie.org.uk>
  19      @license: GNU GPL, see COPYING for details.
  20  """
  21  
  22 @@ -36,54 +37,71 @@
  23          sn = request.getScriptname()
  24          pi = request.getPathinfo()
  25          action = u"%s%s" % (sn, pi)
  26 -        hints = []
  27 +
  28 +        # Modules should really provide label and type details.
  29 +
  30 +        field_name_mapping = {"username" : "name"}
  31 +        field_type_mapping = {"password" : "password"}
  32 +        field_label_mapping = {"username" : _('Name'), "password" : _('Password'), "openid_identifier" : _('OpenID')}
  33 +        field_id_mapping = {"openid_identifier" : "openididentifier"}
  34 +
  35 +        # Generate a collection of login forms, one per module.
  36 +
  37 +        self._forms = html.DIV()
  38 +        self._forms.append(html.P().append(html.Text(_('This site supports the following login methods:'))))
  39 +
  40          for authm in request.cfg.auth:
  41 -            hint = authm.login_hint(request)
  42 -            if hint:
  43 -                hints.append(hint)
  44 -        self._form = html.FORM(action=action, name="loginform")
  45 -        self._table = html.TABLE(border="0")
  46  
  47 -        # Use the user interface language and direction
  48 -        lang_attr = request.theme.ui_lang_attr()
  49 -        self._form.append(html.Raw('<div class="userpref"%s>' % lang_attr))
  50 +            # If there are no inputs, don't bother generating a form.
  51  
  52 -        self._form.append(html.INPUT(type="hidden", name="action", value="login"))
  53 -        self._form.append(self._table)
  54 -        for hint in hints:
  55 -            self._form.append(html.P().append(html.Raw(hint)))
  56 -        self._form.append(html.Raw("</div>"))
  57 +            if not authm.login_inputs:
  58 +                continue
  59  
  60 -        cfg = request.cfg
  61 -        if 'username' in cfg.auth_login_inputs:
  62 -            self.make_row(_('Name'), [
  63 +            self._form = html.FORM(action=action, name="loginform")
  64 +            self._forms.append(self._form)
  65 +
  66 +            # Use the user interface language and direction.
  67 +
  68 +            lang_attr = request.theme.ui_lang_attr()
  69 +            self._form.append(html.Raw('<div class="userpref"%s>' % lang_attr))
  70 +
  71 +            self._form.append(html.INPUT(type="hidden", name="action", value="login"))
  72 +
  73 +            # Put fields in a table.
  74 +
  75 +            self._table = html.TABLE(border="0", style="table-layout: fixed")
  76 +            self._form.append(self._table)
  77 +
  78 +            # Generate the module's fields.
  79 +
  80 +            for field in authm.login_inputs:
  81 +                name = field_name_mapping.get(field, field)
  82 +                type = field_type_mapping.get(field, "text")
  83 +                label = field_label_mapping.get(field, field)
  84 +                kw = {}
  85 +                if field_id_mapping.has_key(field):
  86 +                    kw["id"] = field_id_mapping[field]
  87 +
  88 +                self.make_row(label, [
  89 +                    html.INPUT(
  90 +                        type=type, size="32", name=name, **kw
  91 +                    ),
  92 +                ], width="20%")
  93 +
  94 +            self.make_row('', [
  95                  html.INPUT(
  96 -                    type="text", size="32", name="name",
  97 +                    type="submit", name='login', value=_('Login')
  98                  ),
  99              ])
 100  
 101 -        if 'password' in cfg.auth_login_inputs:
 102 -            self.make_row(_('Password'), [
 103 -                html.INPUT(
 104 -                    type="password", size="32", name="password",
 105 -                ),
 106 -            ])
 107 +            # Finish the form with a hint.
 108  
 109 -        if 'openid_identifier' in cfg.auth_login_inputs:
 110 -            self.make_row(_('OpenID'), [
 111 -                html.INPUT(
 112 -                    type="text", size="32", name="openid_identifier",
 113 -                    id="openididentifier"
 114 -                ),
 115 -            ])
 116 +            hint = authm.login_hint(request)
 117 +            if hint:
 118 +                self._form.append(html.P().append(html.Raw(hint)))
 119 +            self._form.append(html.Raw("</div>"))
 120  
 121 -        self.make_row('', [
 122 -            html.INPUT(
 123 -                type="submit", name='login', value=_('Login')
 124 -            ),
 125 -        ])
 126 -
 127 -        return unicode(self._form)
 128 +        return unicode(self._forms)
 129  
 130  def getLogin(request):
 131      """ Return HTML code for the login. """
 132 diff -r 12a9b8281334 -r 77bea805221c MoinMoin/widget/html.py
 133 --- a/MoinMoin/widget/html.py	Sat Feb 26 21:28:45 2011 +0100
 134 +++ b/MoinMoin/widget/html.py	Thu Mar 03 21:01:51 2011 +0100
 135 @@ -148,6 +148,7 @@
 136          'rel': None,
 137          'rev': None,
 138          'shape': None,
 139 +        'style': None,
 140          'tabindex': None,
 141          'type': None,
 142      }
 143 @@ -156,18 +157,21 @@
 144      "abbreviated form (e.g., WWW, HTTP, etc.)"
 145      _ATTRS = {
 146          'class': None,
 147 +        'style': None,
 148      }
 149  
 150  class ACRONYM(CompositeElement):
 151      "acronyms"
 152      _ATTRS = {
 153          'class': None,
 154 +        'style': None,
 155      }
 156  
 157  class ADDRESS(CompositeElement):
 158      "information on author"
 159      _ATTRS = {
 160          'class': None,
 161 +        'style': None,
 162      }
 163  
 164  class AREA(EmptyElement):
 165 @@ -177,12 +181,14 @@
 166          'class': None,
 167          'href': None,
 168          'shape': None,
 169 +        'style': None,
 170      }
 171  
 172  class B(CompositeElement):
 173      "bold text style"
 174      _ATTRS = {
 175          'class': None,
 176 +        'style': None,
 177      }
 178  
 179  class BASE(EmptyElement):
 180 @@ -194,18 +200,21 @@
 181      "I18N BiDi over-ride"
 182      _ATTRS = {
 183          'class': None,
 184 +        'style': None,
 185      }
 186  
 187  class BIG(CompositeElement):
 188      "large text style"
 189      _ATTRS = {
 190          'class': None,
 191 +        'style': None,
 192      }
 193  
 194  class BLOCKQUOTE(CompositeElement):
 195      "long quotation"
 196      _ATTRS = {
 197          'class': None,
 198 +        'style': None,
 199      }
 200  
 201  class BODY(CompositeElement):
 202 @@ -218,6 +227,7 @@
 203          'link': None,
 204          'onload': None,
 205          'onunload': None,
 206 +        'style': None,
 207          'text': None,
 208          'vlink': None,
 209      }
 210 @@ -226,48 +236,56 @@
 211      "forced line break"
 212      _ATTRS = {
 213          'class': None,
 214 +        'style': None,
 215      }
 216  
 217  class BUTTON(CompositeElement):
 218      "push button"
 219      _ATTRS = {
 220          'class': None,
 221 +        'style': None,
 222      }
 223  
 224  class CAPTION(CompositeElement):
 225      "table caption"
 226      _ATTRS = {
 227          'class': None,
 228 +        'style': None,
 229      }
 230  
 231  class CITE(CompositeElement):
 232      "citation"
 233      _ATTRS = {
 234          'class': None,
 235 +        'style': None,
 236      }
 237  
 238  class CODE(CompositeElement):
 239      "computer code fragment"
 240      _ATTRS = {
 241          'class': None,
 242 +        'style': None,
 243      }
 244  
 245  class DD(CompositeElement):
 246      "definition description"
 247      _ATTRS = {
 248          'class': None,
 249 +        'style': None,
 250      }
 251  
 252  class DEL(CompositeElement):
 253      "deleted text"
 254      _ATTRS = {
 255          'class': None,
 256 +        'style': None,
 257      }
 258  
 259  class DFN(CompositeElement):
 260      "instance definition"
 261      _ATTRS = {
 262          'class': None,
 263 +        'style': None,
 264      }
 265  
 266  class DIV(CompositeElement):
 267 @@ -275,24 +293,28 @@
 268      _ATTRS = {
 269          'id': None,
 270          'class': None,
 271 +        'style': None,
 272      }
 273  
 274  class DL(CompositeElement):
 275      "definition list"
 276      _ATTRS = {
 277          'class': None,
 278 +        'style': None,
 279      }
 280  
 281  class DT(CompositeElement):
 282      "definition term"
 283      _ATTRS = {
 284          'class': None,
 285 +        'style': None,
 286      }
 287  
 288  class EM(CompositeElement):
 289      "emphasis"
 290      _ATTRS = {
 291          'class': None,
 292 +        'style': None,
 293      }
 294  
 295  class FORM(CompositeElement):
 296 @@ -307,6 +329,7 @@
 297          'name': None,
 298          'onreset': None,
 299          'onsubmit': None,
 300 +        'style': None,
 301          'target': None,
 302      }
 303      _DEFAULT_ATTRS = {
 304 @@ -317,36 +340,42 @@
 305      "heading"
 306      _ATTRS = {
 307          'class': None,
 308 +        'style': None,
 309      }
 310  
 311  class H2(CompositeElement):
 312      "heading"
 313      _ATTRS = {
 314          'class': None,
 315 +        'style': None,
 316      }
 317  
 318  class H3(CompositeElement):
 319      "heading"
 320      _ATTRS = {
 321          'class': None,
 322 +        'style': None,
 323      }
 324  
 325  class H4(CompositeElement):
 326      "heading"
 327      _ATTRS = {
 328          'class': None,
 329 +        'style': None,
 330      }
 331  
 332  class H5(CompositeElement):
 333      "heading"
 334      _ATTRS = {
 335          'class': None,
 336 +        'style': None,
 337      }
 338  
 339  class H6(CompositeElement):
 340      "heading"
 341      _ATTRS = {
 342          'class': None,
 343 +        'style': None,
 344      }
 345  
 346  class HEAD(CompositeElement):
 347 @@ -358,6 +387,7 @@
 348      "horizontal rule"
 349      _ATTRS = {
 350          'class': None,
 351 +        'style': None,
 352      }
 353  
 354  class HTML(CompositeElement):
 355 @@ -370,12 +400,14 @@
 356      "italic text style"
 357      _ATTRS = {
 358          'class': None,
 359 +        'style': None,
 360      }
 361  
 362  class IFRAME(CompositeElement):
 363      "inline subwindow"
 364      _ATTRS = {
 365          'class': None,
 366 +        'style': None,
 367      }
 368  
 369  class IMG(EmptyElement):
 370 @@ -385,6 +417,7 @@
 371          'alt': None,
 372          'border': None,
 373          'class': None,
 374 +        'style': None,
 375          'vspace': None,
 376      }
 377  
 378 @@ -409,6 +442,7 @@
 379          'readonly': None,
 380          'size': None,
 381          'src': None,
 382 +        'style': None,
 383          'tabindex': None,
 384          'type': None,
 385          'usemap': None,
 386 @@ -419,12 +453,14 @@
 387      "inserted text"
 388      _ATTRS = {
 389          'class': None,
 390 +        'style': None,
 391      }
 392  
 393  class KBD(CompositeElement):
 394      "text to be entered by the user"
 395      _ATTRS = {
 396          'class': None,
 397 +        'style': None,
 398      }
 399  
 400  class LABEL(CompositeElement):
 401 @@ -432,6 +468,7 @@
 402      _ATTRS = {
 403          'class': None,
 404          'for_': None,
 405 +        'style': None,
 406      }
 407  
 408      def _openingtag(self):
 409 @@ -455,6 +492,7 @@
 410      "list item"
 411      _ATTRS = {
 412          'class': None,
 413 +        'style': None,
 414      }
 415  
 416  class LINK(EmptyElement):
 417 @@ -467,6 +505,7 @@
 418          'media': None,
 419          'rel': None,
 420          'rev': None,
 421 +        'style': None,
 422          'target': None,
 423          'type': None,
 424      }
 425 @@ -475,6 +514,7 @@
 426      "client-side image map"
 427      _ATTRS = {
 428          'class': None,
 429 +        'style': None,
 430      }
 431  
 432  class META(EmptyElement):
 433 @@ -486,18 +526,21 @@
 434      "alternate content container for non script-based rendering"
 435      _ATTRS = {
 436          'class': None,
 437 +        'style': None,
 438      }
 439  
 440  class OL(CompositeElement):
 441      "ordered list"
 442      _ATTRS = {
 443          'class': None,
 444 +        'style': None,
 445      }
 446  
 447  class OPTGROUP(CompositeElement):
 448      "option group"
 449      _ATTRS = {
 450          'class': None,
 451 +        'style': None,
 452      }
 453  
 454  class OPTION(CompositeElement):
 455 @@ -507,6 +550,7 @@
 456          'disabled': None,
 457          'label': None,
 458          'selected': None,
 459 +        'style': None,
 460          'value': None,
 461      }
 462  
 463 @@ -514,24 +558,28 @@
 464      "paragraph"
 465      _ATTRS = {
 466          'class': None,
 467 +        'style': None,
 468      }
 469  
 470  class PRE(CompositeElement):
 471      "preformatted text"
 472      _ATTRS = {
 473          'class': None,
 474 +        'style': None,
 475      }
 476  
 477  class Q(CompositeElement):
 478      "short inline quotation"
 479      _ATTRS = {
 480          'class': None,
 481 +        'style': None,
 482      }
 483  
 484  class SAMP(CompositeElement):
 485      "sample program output, scripts, etc."
 486      _ATTRS = {
 487          'class': None,
 488 +        'style': None,
 489      }
 490  
 491  class SCRIPT(CompositeElement):
 492 @@ -550,6 +598,7 @@
 493          'onchange': None,
 494          'onfocus': None,
 495          'size': None,
 496 +        'style': None,
 497          'tabindex': None,
 498      }
 499  
 500 @@ -557,18 +606,21 @@
 501      "small text style"
 502      _ATTRS = {
 503          'class': None,
 504 +        'style': None,
 505      }
 506  
 507  class SPAN(CompositeElement):
 508      "generic language/style container"
 509      _ATTRS = {
 510          'class': None,
 511 +        'style': None,
 512      }
 513  
 514  class STRONG(CompositeElement):
 515      "strong emphasis"
 516      _ATTRS = {
 517          'class': None,
 518 +        'style': None,
 519      }
 520  
 521  class STYLE(CompositeElement):
 522 @@ -580,12 +632,14 @@
 523      "subscript"
 524      _ATTRS = {
 525          'class': None,
 526 +        'style': None,
 527      }
 528  
 529  class SUP(CompositeElement):
 530      "superscript"
 531      _ATTRS = {
 532          'class': None,
 533 +        'style': None,
 534      }
 535  
 536  class TABLE(CompositeElement):
 537 @@ -600,6 +654,7 @@
 538          'frame': None,
 539          'rules': None,
 540          'summary': None,
 541 +        'style': None,
 542          'width': None,
 543      }
 544  
 545 @@ -608,6 +663,7 @@
 546      _ATTRS = {
 547          'align': None,
 548          'class': None,
 549 +        'style': None,
 550      }
 551  
 552  class TD(CompositeElement):
 553 @@ -616,7 +672,9 @@
 554          'abbr': None,
 555          'align': None,
 556          'class': None,
 557 +        'style': None,
 558          'valign': None,
 559 +        'width': None,
 560          'colspan': None,
 561          'rowspan': None,
 562      }
 563 @@ -628,6 +686,7 @@
 564          'cols': None,
 565          'name': None,
 566          'rows': None,
 567 +        'style': None,
 568      }
 569  
 570  class TFOOT(CompositeElement):
 571 @@ -635,6 +694,7 @@
 572      _ATTRS = {
 573          'align': None,
 574          'class': None,
 575 +        'style': None,
 576      }
 577  
 578  class TH(CompositeElement):
 579 @@ -643,6 +703,8 @@
 580          'abbr': None,
 581          'align': None,
 582          'class': None,
 583 +        'style': None,
 584 +        'width': None,
 585      }
 586  
 587  class THEAD(CompositeElement):
 588 @@ -650,6 +712,7 @@
 589      _ATTRS = {
 590          'align': None,
 591          'class': None,
 592 +        'style': None,
 593      }
 594  
 595  class TITLE(CompositeElement):
 596 @@ -662,24 +725,28 @@
 597      _ATTRS = {
 598          'align': None,
 599          'class': None,
 600 +        'style': None,
 601      }
 602  
 603  class TT(CompositeElement):
 604      "teletype or monospaced text style"
 605      _ATTRS = {
 606          'class': None,
 607 +        'style': None,
 608      }
 609  
 610  class UL(CompositeElement):
 611      "unordered list"
 612      _ATTRS = {
 613          'class': None,
 614 +        'style': None,
 615      }
 616  
 617  class VAR(CompositeElement):
 618      "instance of a variable or program argument"
 619      _ATTRS = {
 620          'class': None,
 621 +        'style': None,
 622      }
 623  
 624  
 625 # HG changeset patch
 626 # User Paul Boddie <paul@boddie.org.uk>
 627 # Date 1299427097 -3600
 628 # Node ID 6b74207904b3a3d28233051d5945bc1fb9656002
 629 # Parent  1a333e78214f2d26882cee1f2d463e04e6d763df
 630 Made the form identifier unique.
 631 
 632 diff -r 1a333e78214f -r 6b74207904b3 MoinMoin/userform/login.py
 633 --- a/MoinMoin/userform/login.py	Sun Mar 06 02:32:17 2011 +0100
 634 +++ b/MoinMoin/userform/login.py	Sun Mar 06 16:58:17 2011 +0100
 635 @@ -50,14 +50,14 @@
 636          self._forms = html.DIV()
 637          self._forms.append(html.P().append(html.Text(_('This site supports the following login methods:'))))
 638  
 639 -        for authm in request.cfg.auth:
 640 +        for formnumber, authm in enumerate(request.cfg.auth):
 641  
 642              # If there are no inputs, don't bother generating a form.
 643  
 644              if not authm.login_inputs:
 645                  continue
 646  
 647 -            self._form = html.FORM(action=action, name="loginform")
 648 +            self._form = html.FORM(action=action, name="loginform%d" % formnumber)
 649              self._forms.append(self._form)
 650  
 651              # Use the user interface language and direction.

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2011-03-12 23:47:41, 15.2 KB) [[attachment:patch-userform-login-improved-1.8.diff]]
  • [get | view] (2011-03-12 23:47:19, 17.4 KB) [[attachment:patch-userform-login-improved.diff]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.