]> git.ipfire.org Git - people/ms/westferry.git/commitdiff
Create a simple engine for forms
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 22 Jul 2016 16:42:47 +0000 (18:42 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 22 Jul 2016 16:42:47 +0000 (18:42 +0200)
This allows to create forms without replicating HTML code
and allows accessing them very easily on the backend.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
22 files changed:
Makefile.am
po/POTFILES.in
src/templates/demo.html [new file with mode: 0644]
src/templates/modules/forms/element.html [new file with mode: 0644]
src/templates/modules/forms/fieldset.html [new file with mode: 0644]
src/templates/modules/forms/group.html [new file with mode: 0644]
src/templates/modules/forms/index.html [new file with mode: 0644]
src/templates/modules/forms/inputs/base.html [new file with mode: 0644]
src/templates/modules/forms/inputs/checkbox.html [new file with mode: 0644]
src/templates/modules/forms/inputs/text.html [new file with mode: 0644]
src/templates/modules/forms/inputs/textarea.html [new file with mode: 0644]
src/westferry/backend/__init__.py
src/westferry/backend/forms/__init__.py [new file with mode: 0644]
src/westferry/backend/forms/base.py [new file with mode: 0644]
src/westferry/backend/forms/choice.py [new file with mode: 0644]
src/westferry/backend/forms/main.py [new file with mode: 0644]
src/westferry/backend/forms/text.py [new file with mode: 0644]
src/westferry/backend/forms/yesno.py [new file with mode: 0644]
src/westferry/handlers/__init__.py
src/westferry/handlers/demo.py [new file with mode: 0644]
src/westferry/ui/__init__.py
src/westferry/ui/forms.py [new file with mode: 0644]

index 70993a1bd4691595e299b8b1e7cb2b8b4a287448..6eeef3bfeb48b923737e9d138b1f6f66e1e74b1b 100644 (file)
@@ -106,10 +106,21 @@ westferry_backend_PYTHON = \
 
 westferry_backenddir = $(pythondir)/westferry/backend
 
+westferry_backend_forms_PYTHON = \
+       src/westferry/backend/forms/__init__.py \
+       src/westferry/backend/forms/base.py \
+       src/westferry/backend/forms/choice.py \
+       src/westferry/backend/forms/main.py \
+       src/westferry/backend/forms/text.py \
+       src/westferry/backend/forms/yesno.py
+
+westferry_backend_formsdir = $(westferry_backenddir)/forms
+
 westferry_handlers_PYTHON = \
        src/westferry/handlers/__init__.py \
        src/westferry/handlers/analytics.py \
        src/westferry/handlers/base.py \
+       src/westferry/handlers/demo.py \
        src/westferry/handlers/index.py
 
 westferry_handlersdir = $(pythondir)/westferry/handlers
@@ -117,6 +128,7 @@ westferry_handlersdir = $(pythondir)/westferry/handlers
 westferry_ui_PYTHON = \
        src/westferry/ui/__init__.py \
        src/westferry/ui/base.py \
+       src/westferry/ui/forms.py \
        src/westferry/ui/graphs.py \
        src/westferry/ui/menu.py \
        src/westferry/ui/utils.py
@@ -128,12 +140,29 @@ westferry_uidir = $(pythondir)/westferry/ui
 templatesdir = $(datadir)/westferry/templates
 
 dist_templates_DATA = \
-       src/templates/base.html
+       src/templates/base.html \
+       src/templates/demo.html
 
 templates_modulesdir = $(templatesdir)/modules
 
 dist_templates_modules_DATA =
 
+templates_modules_formsdir = $(templates_modulesdir)/forms
+
+dist_templates_modules_forms_DATA = \
+       src/templates/modules/forms/element.html \
+       src/templates/modules/forms/fieldset.html \
+       src/templates/modules/forms/group.html \
+       src/templates/modules/forms/index.html
+
+templates_modules_forms_inputsdir = $(templates_modules_formsdir)/inputs
+
+dist_templates_modules_forms_inputs_DATA = \
+       src/templates/modules/forms/inputs/base.html \
+       src/templates/modules/forms/inputs/checkbox.html \
+       src/templates/modules/forms/inputs/text.html \
+       src/templates/modules/forms/inputs/textarea.html
+
 templates_modules_graphsdir = $(templates_modulesdir)/graphs
 
 dist_templates_modules_graphs_DATA = \
index 292abacccf2a3c5d372ec4bff2babf70d51940c9..82a7d6ac04602e1be55a5260b3d66b9b68529f28 100644 (file)
@@ -1,4 +1,6 @@
 src/westferry/backend/__version__.py
 src/westferry/handlers/analytics.py
 src/westferry/handlers/base.py
+src/westferry/handlers/demo.py
+src/westferry/handlers/index.py
 src/westferry/__init__.py
diff --git a/src/templates/demo.html b/src/templates/demo.html
new file mode 100644 (file)
index 0000000..9b3bda1
--- /dev/null
@@ -0,0 +1,5 @@
+{% extends "base.html" %}
+
+{% block main %}
+       {% module Form(form) %}
+{% end block %}
diff --git a/src/templates/modules/forms/element.html b/src/templates/modules/forms/element.html
new file mode 100644 (file)
index 0000000..34b1471
--- /dev/null
@@ -0,0 +1,13 @@
+<div class="form-group">
+       {% if e.label %}
+               <label class="col-sm-2 control-label">{{ e.label }}</label>
+       {% end %}
+
+       <div class="col-sm-10 {% if not e.label %}col-sm-offset-2{% end %}">
+               {% module FormInput(e) %}
+
+               {% if e.help %}
+                       <span class="help-block">{{ e.help }}</span>
+               {% end %}
+       </div>
+</div>
diff --git a/src/templates/modules/forms/fieldset.html b/src/templates/modules/forms/fieldset.html
new file mode 100644 (file)
index 0000000..18c76cb
--- /dev/null
@@ -0,0 +1,25 @@
+{% import westferry.backend.forms %}
+
+<fieldset {% if fs.disabled %}disabled{% end %}>
+       {% if fs.label %}
+               <legend>{{ fs.label }}</legend>
+       {% else %}
+               <hr>
+       {% end %}
+
+       {% if fs.help %}
+               <div class="row">
+                       <div class="col-md-10 col-md-offset-2">
+                               <span class="help-block">{{ fs.help }}</span>
+                       </div>
+               </div>
+       {% end %}
+
+       {% for e in fs %}
+               {% if isinstance(e, westferry.backend.forms.Group) %}
+                       {% module FormGroup(e) %}
+               {% else %}
+                       {% module FormElement(e) %}
+               {% end %}
+       {% end %}
+</fieldset>
diff --git a/src/templates/modules/forms/group.html b/src/templates/modules/forms/group.html
new file mode 100644 (file)
index 0000000..caacfb6
--- /dev/null
@@ -0,0 +1,11 @@
+<div class="form-inline">
+       {% for e in group %}
+               <div class="form-group">
+                       {% if e.label %}
+                               <label>{{ e.label }}</label>
+                       {% end %}
+
+                       {% module FormInput(e) %}
+               </div>
+       {% end %}
+</div>
diff --git a/src/templates/modules/forms/index.html b/src/templates/modules/forms/index.html
new file mode 100644 (file)
index 0000000..291721d
--- /dev/null
@@ -0,0 +1,21 @@
+{% import westferry.backend.forms %}
+
+<form class="form-horizontal" method="{{ f.method }}" action="{{ f.action }}">
+       {% raw xsrf_form_html() %}
+
+       {% for e in f %}
+               {% if isinstance(e, westferry.backend.forms.Fieldset) %}
+                       {% module FormFieldset(e) %}
+               {% elif isinstance(e, westferry.backend.forms.Group) %}
+                       {% module FormGroup(e) %}
+               {% else %}
+                       {% module FormElement(e) %}
+               {% end %}
+       {% end %}
+
+       <div class="form-group">
+               <div class="col-sm-10 col-sm-offset-2">
+                       <button type="submit" class="btn btn-primary">{{ f.submit_text or _("Submit") }}</button>
+               </div>
+       </div>
+</form>
diff --git a/src/templates/modules/forms/inputs/base.html b/src/templates/modules/forms/inputs/base.html
new file mode 100644 (file)
index 0000000..ed6b341
--- /dev/null
@@ -0,0 +1,11 @@
+{% import westferry.backend.forms %}
+
+{% if isinstance(input, westferry.backend.forms.MultilineTextInput) %}
+       {% module MultilineTextInput(input) %}
+{% elif isinstance(input, westferry.backend.forms.PasswordInput) %}
+       {% module PasswordInput(input) %}       
+{% elif isinstance(input, westferry.backend.forms.TextInput) %}
+       {% module TextInput(input) %}
+{% elif isinstance(input, westferry.backend.forms.YesNoInput) %}
+       {% module YesNoInput(input) %}
+{% end %}
diff --git a/src/templates/modules/forms/inputs/checkbox.html b/src/templates/modules/forms/inputs/checkbox.html
new file mode 100644 (file)
index 0000000..a4e56ab
--- /dev/null
@@ -0,0 +1,6 @@
+<div class="checkbox">
+       <label>
+               <input type="checkbox" name="{{ input.name }}" {% if input.value %}checked{% end %}>
+               {% if input.description %}{{ input.description }}{% end %}
+       </label>
+</div>
diff --git a/src/templates/modules/forms/inputs/text.html b/src/templates/modules/forms/inputs/text.html
new file mode 100644 (file)
index 0000000..6f3308c
--- /dev/null
@@ -0,0 +1,18 @@
+{% if input.prefix or input.suffix %}
+       <div class="input-group">
+               {% if input.prefix %}
+                       <div class="input-group-addon">{{ input.prefix }}</div>
+               {% end%}
+{% end %}
+
+<input type="{{ input.type }}" name="{{ input.name }}" class="form-control"
+       {% if input.placeholder %}placeholder="{{ input.placeholder }}"{% end %}
+       {% if input.disabled %}disabled{% end %}
+       {% if input.readonly %}readonly{% end %} />
+
+{% if input.prefix or input.suffix %}
+               {% if input.suffix %}
+                       <div class="input-group-addon">{{ input.suffix }}</div>
+               {% end %}
+       </div>
+{% end %}
diff --git a/src/templates/modules/forms/inputs/textarea.html b/src/templates/modules/forms/inputs/textarea.html
new file mode 100644 (file)
index 0000000..6e88343
--- /dev/null
@@ -0,0 +1,3 @@
+<textarea class="form-control" name="{{ input.name }}" rows="{{ input.lines }}"
+       {% if input.placeholder %}placeholder="{{ input.placeholder }}"{% end %}
+       >{% if input.value %}{{ input.value }}{% end %}</textarea>
index cad0eb38e8955442c05d2c21a0d0e73d11a4fc01..1cc3a3f9a71af9287c4254c97c0a430b1d82d33b 100644 (file)
@@ -20,3 +20,5 @@
 ###############################################################################
 
 from .main import Backend
+
+from . import forms
diff --git a/src/westferry/backend/forms/__init__.py b/src/westferry/backend/forms/__init__.py
new file mode 100644 (file)
index 0000000..c9683c6
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+from .base import Element
+from .main import Form, Fieldset, Group
+
+from .text import TextInput, MultilineTextInput, PasswordInput
+from .yesno import YesNoInput
diff --git a/src/westferry/backend/forms/base.py b/src/westferry/backend/forms/base.py
new file mode 100644 (file)
index 0000000..e2e8633
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+class Element(object):
+       # The element type
+       type = None
+
+       def __init__(self, form, name=None, label=None, default=None, **kwargs):
+               assert self.type
+
+               self.form = form
+               self.name = name
+               self.label = label
+               self.default = default
+
+               # Is this element editable?
+               self.disabled = False
+               self.readonly = False
+
+               # Help text
+               self.help = None
+
+               # Set defaults for inheriting classes
+               self._set_defaults()
+
+               # Set args
+               for k, v in kwargs.items():
+                       setattr(self, k, v)
+
+               self.init(**kwargs)
+
+       def _set_defaults(self):
+               pass
+
+       def init(self, *args, **kwargs):
+               pass
+
+       @property
+       def value(self):
+               """
+                       Returns the value that the user entered for this element.
+               """
+               return self.get_value()
+
+       def get_value(self):
+               return self.form._get_value(self.name, self.default)
diff --git a/src/westferry/backend/forms/choice.py b/src/westferry/backend/forms/choice.py
new file mode 100644 (file)
index 0000000..73e2421
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+from . import base
+
+class SingleChoiceInput(base.Element):
+       type = "single-choice"
+
+
+class MultipleChoiceInput(base.Element):
+       type = "multiple-choice"
diff --git a/src/westferry/backend/forms/main.py b/src/westferry/backend/forms/main.py
new file mode 100644 (file)
index 0000000..ab49ce0
--- /dev/null
@@ -0,0 +1,178 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+from . import base
+from . import choice
+from . import text
+from . import yesno
+
+class _Form(object):
+       def __init__(self, form):
+               self.form = form
+               self._elements = []
+
+               # Is this form disabled?
+               self.disabled = False
+
+       def __iter__(self):
+               """
+                       Iterating over a form will iterate over its elements.
+               """
+               return iter(self._elements)
+
+       @property
+       def parent_form(self):
+               if self.form:
+                       return self.form.parent_form
+
+               return self
+
+       @property
+       def elements(self):
+               for e in self._elements:
+                       if isinstance(e, _Form):
+                               for i in e._elements:
+                                       yield i
+
+                       else:
+                               yield e
+
+       def _add_element(self, element):
+               """
+                       Adds a new form element to this form.
+               """
+               assert isinstance(element, base.Element)
+               assert not element in self.elements
+
+               self._elements.append(element)
+
+       def _add_element_class(self, cls, *args, **kwargs):
+               e = cls(self, *args, **kwargs)
+               self._add_element(e)
+
+               return e
+
+       def get_element_by_name(self, name):
+               """
+                       Returns the element with the given name (if any).
+               """
+               for e in self.elements:
+                       if e.name == name:
+                               return e
+
+       # Have a shortcut to find elements by their name quickly.
+       get = get_element_by_name
+
+       def add_text_input(self, *args, **kwargs):
+               """
+                       Creates a new text input.
+               """
+               return self._add_element_class(text.TextInput, *args, **kwargs)
+
+       def add_multiline_text_input(self, *args, **kwargs):
+               """
+                       Creates a new multiline text input.
+               """
+               return self._add_element_class(text.MultilineTextInput, *args, **kwargs)
+
+       def add_password_input(self, *args, **kwargs):
+               """
+                       Creates a new password input.
+               """
+               return self._add_element_class(text.PasswordInput, *args, **kwargs)
+
+       def add_yesno_input(self, *args, **kwargs):
+               """
+                       Creates a new yes/no input.
+               """
+               return self._add_element_class(yesno.YesNoInput, *args, **kwargs)
+
+       def add_single_choice_input(self, *args, **kwargs):
+               """
+                       Creates a new single choice input.
+               """
+               return self._add_element_class(choice.SingleChoiceInput, *args, **kwargs)
+
+       def add_multiple_choice_input(self, *args, **kwargs):
+               """
+                       Creates a new multiple choice input.
+               """
+               return self._add_element_class(choice.MultipleChoiceInput, *args, **kwargs)
+
+       def _get_value(self, *args, **kwargs):
+               return self.parent_form._get_value(*args, **kwargs)
+
+
+class FormGroupMixin(object):
+       def add_group(self, *args, **kwargs):
+               group = Group(self, *args, **kwargs)
+               self._elements.append(group)
+
+               return group
+
+
+class Form(_Form, FormGroupMixin):
+       def __init__(self, handler, method="POST", action=""):
+               _Form.__init__(self, None)
+               self.handler = handler
+
+               self.method = method
+               self.action = action
+
+               # Text that is shown on the submit button
+               self.submit_text = None
+
+       def add_fieldset(self, *args, **kwargs):
+               fs = Fieldset(self, *args, **kwargs)
+               self._elements.append(fs)
+
+               return fs
+
+       def export(self):
+               """
+                       Returns a dictionary with all keys and values
+                       of the form.
+               """
+               ret = {}
+
+               for e in self.elements:
+                       ret[e.name] = e.value
+
+               return ret
+
+       def _get_value(self, name, default=None):
+               return self.handler.get_argument(name, default)
+
+
+class Fieldset(_Form, FormGroupMixin):
+       def __init__(self, *args, label=None, help=None, **kwargs):
+               _Form.__init__(self, *args, **kwargs)
+
+               self.label = label
+               self.help = help
+
+
+class Group(_Form):
+       def __init__(self, *args, label=None, **kwargs):
+               _Form.__init__(self, *args, **kwargs)
+
+               self.label = label
+               self.help = None
diff --git a/src/westferry/backend/forms/text.py b/src/westferry/backend/forms/text.py
new file mode 100644 (file)
index 0000000..11b42fa
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+from . import base
+
+class TextInput(base.Element):
+       type = "text"
+
+       def _set_defaults(self):
+               self.prefix = None
+               self.suffix = None
+
+               self._placeholder = None
+
+       def get_placeholder(self):
+               return self._placeholder or self.label
+
+       def set_placeholder(self, placeholder):
+               self._placeholder = placeholder
+
+       placeholder = property(get_placeholder, set_placeholder)
+
+
+class MultilineTextInput(TextInput):
+       type = "multiline-text"
+
+       def _set_defaults(self):
+               TextInput._set_defaults(self)
+
+               # Default number of rows
+               self.lines = 3
+
+
+class PasswordInput(TextInput):
+       type = "password"
diff --git a/src/westferry/backend/forms/yesno.py b/src/westferry/backend/forms/yesno.py
new file mode 100644 (file)
index 0000000..17b7f44
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+from . import base
+
+class YesNoInput(base.Element):
+       type = "yesno"
+
+       def _set_defaults(self):
+               self.description = None
+
+       def get_value(self):
+               value = base.Element.get_value(self)
+
+               # This only returns true or false
+               if value == "on":
+                       return True
+
+               return False
index bd3ac0b667baa6b57a0fd95cc4f002ff427754d3..60e04f724022fed52cd106eecaeab291220c8b44 100644 (file)
@@ -21,6 +21,7 @@
 
 from . import base
 from . import analytics
+from . import demo
 from . import index
 
 def get_handlers():
diff --git a/src/westferry/handlers/demo.py b/src/westferry/handlers/demo.py
new file mode 100644 (file)
index 0000000..d327899
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+from . import base
+from .. import backend
+from .. import ui
+
+from ..i18n import N_, _
+
+class DemoBaseHandler(base.BaseHandler):
+       @property
+       def menu(self):
+               _ = self.locale.translate
+
+               m = ui.menu.Menu(self, _("Demo"))
+
+               # Overview
+               m.add_handler(DemoOverviewHandler)
+               m.add_divider()
+
+               # Forms
+               m.add_handler(DemoFormHandler)
+
+               return m
+
+
+class DemoOverviewHandler(DemoBaseHandler):
+       url = r"/demo"
+       title = N_("Overview")
+
+       def get(self):
+               self.render("base.html")
+
+
+class DemoFormHandler(DemoBaseHandler):
+       url = r"/demo/forms"
+       title = N_("Forms")
+
+       def get(self):
+               self.render("demo.html", form=self.form)
+
+       def post(self):
+               data = self.form.export()
+               self.finish(data)
+
+       @property
+       def form(self):
+               """
+                       This creates a simple form that asks the user
+                       for their address.
+               """
+               _ = self.locale.translate
+
+               form = backend.forms.Form(self)
+               form.submit_text = _("Order")
+
+               # First name
+               e = form.add_text_input("first_name", label=_("First Name"), placeholder="John")
+               e.help = _("Please enter your first name")
+
+               # Last name
+               e = form.add_text_input("last_name", label=_("Last Name"), placeholder="Doe")
+               e.help = _("Please enter your last name")
+
+               # We create a fieldset for the address
+               fs1 = form.add_fieldset(label=_("Address"))
+               fs1.help = _("Please enter your address")
+
+               e = fs1.add_text_input("street", label=_("Street"))
+               e = fs1.add_text_input("city", label=_("City"))
+               e = fs1.add_text_input("post_code", label=_("Postcode"))
+
+               # Fieldset without label
+               fs2 = form.add_fieldset()
+
+               # Donation amount
+               e = fs2.add_text_input("donation", label=_("Donation"),
+                       placeholder=_("Donation"), suffix="€")
+
+               # Notes
+               e = fs2.add_multiline_text_input("notes", label=_("Notes"))
+
+               # Subscribe to newsletter?
+               e = fs2.add_yesno_input("subscribe_to_newsletter", description=_("Subscribe to newsletter?"))
+
+               return form
index 89ade9a1360d0b404f4162917ba9fd0544316ec6..7bcce3f2f1662f1b61f8426032edf35f8e42619e 100644 (file)
@@ -20,6 +20,7 @@
 ###############################################################################
 
 from . import base
+from . import forms
 from . import graphs
 from . import menu
 from . import utils
diff --git a/src/westferry/ui/forms.py b/src/westferry/ui/forms.py
new file mode 100644 (file)
index 0000000..ddd3ec1
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# Westferry - The IPFire web user interface                                   #
+# Copyright (C) 2015 IPFire development team                                  #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+from ..backend import forms
+from . import base
+
+class FormModule(base.BaseUIModule):
+       def render(self, form):
+               return self.render_string("modules/forms/index.html",
+                       f=form, forms=forms)
+
+
+class FormElementModule(base.BaseUIModule):
+       def render(self, element):
+               assert isinstance(element, forms.Element)
+
+               return self.render_string("modules/forms/element.html", e=element)
+
+
+class FormFieldsetModule(base.BaseUIModule):
+       def render(self, fieldset):
+               return self.render_string("modules/forms/fieldset.html", fs=fieldset)
+
+
+class FormGroupModule(base.BaseUIModule):
+       def render(self, group):
+               return self.render_string("modules/forms/group.html", group=group)
+
+
+class FormInputModule(base.BaseUIModule):
+       """
+               This is a proxy module that will pick the right
+               *InputModule.
+       """
+       def render(self, input):
+               return self.render_string("modules/forms/inputs/base.html", input=input)
+
+
+class TextInputModule(base.BaseUIModule):
+       def render(self, input):
+               assert isinstance(input, forms.TextInput)
+
+               return self.render_string("modules/forms/inputs/text.html", input=input)
+
+
+class MultilineTextInputModule(base.BaseUIModule):
+       def render(self, input):
+               assert isinstance(input, forms.MultilineTextInput)
+
+               return self.render_string("modules/forms/inputs/textarea.html", input=input)
+
+
+class YesNoInputModule(base.BaseUIModule):
+       def render(self, input):
+               assert isinstance(input, forms.YesNoInput)
+
+               return self.render_string("modules/forms/inputs/checkbox.html", input=input)