From c1a029a9962d47c621498663b9deff4218ce9efe Mon Sep 17 00:00:00 2001 From: Ferry Boender Date: Wed, 27 May 2015 23:02:42 +0200 Subject: [PATCH] Allow inclusion of application-wide custom CSS. --- doc/MANUAL.md | 48 +++++++++++++++++++++++++++-- examples/customize/custom.css | 12 ++++++++ examples/customize/customize.json | 20 ++++++++++++ examples/customize/job_customize.sh | 3 ++ src/scriptform.py | 32 ++++++++++++------- 5 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 examples/customize/custom.css create mode 100644 examples/customize/customize.json create mode 100755 examples/customize/job_customize.sh diff --git a/doc/MANUAL.md b/doc/MANUAL.md index 6b9852e..6bb6e49 100644 --- a/doc/MANUAL.md +++ b/doc/MANUAL.md @@ -32,6 +32,8 @@ This is the manual for version %%VERSION%%. - [Passwords](#users_passwords) - [Form limiting](#users_formlimit) - [Security considerations](#users_security) +1. [Form customization](#cust) + - [Custom CSS](#cust_css) 1. [Security](#security) ## Invocations @@ -119,6 +121,10 @@ Structurally, they are made up of the following elements: served. See also "[Serving static files](#output_static_files)". **Optional**, **String**. +- **`custom_css`**: Path to a file containing custom CSS. It will be included + in every page's header. See also "[Form customization](#cust)". **Optional**, + **String**. + - **`forms`**: A list of dictionaries of form definitions. **Required**, **List of dictionaries**. @@ -154,9 +160,6 @@ Structurally, they are made up of the following elements: view it, if you know its name. This is useful for other forms to redirect to this forms and such. - - **`style`**: A string of inline CSS which will be applied to the field. - **Optional**, **String**. - - **`fields`**: List of fields in the form. Each field is a dictionary. **Required**, **List of dictionaries**. @@ -177,6 +180,9 @@ Structurally, they are made up of the following elements: pre-filled forms which takes it values from the GET request. **Optional**, **boolean**, **Default:** `false`. + - **`style`**: A string of inline CSS which will be applied to the field. + **Optional**, **String**. + - **`...`**: Other options, which depend on the type of field. For more information, see [Field types](#field_types). **Optional**. @@ -525,6 +531,42 @@ For an example, see the [beginning of this chapter](#users). *does* support HTTPS, such as Apache. For more information on that, see the "Invocations" chapter. +## Form customization + +### Custom CSS + +You can customize a form input field's style using the **`style`** property of +the field definition in the form configuration. It takes a string that will be +put in the generated form's `style=""` HTML attribute. For example: + + "fields": [ + { + "name": "background", + "title": "Different background color", + "type": "string", + "style": "background-color: #C0FFC0;" + } + ] + +The example above will render as: + + + +You can also include a global piece of CSS by specifying the **`custom_css`** +property in the form definition. For example: + + { + "title": "Customized forms", + "custom_css": "custom.css", + "forms": [ + ... + +`custom.css` is the path to a file which will be included in the rendered HTML +page in the ` @@ -139,11 +141,11 @@ html_form = u'''

{title}

{description}

-
+
    {fields} -
  • +
  • @@ -222,13 +224,16 @@ class ScriptForm: config = json.load(file(self.config_file, 'r')) static_dir = None - forms = [] + custom_css = None users = None + forms = [] - if 'users' in config: - users = config['users'] if 'static_dir' in config: static_dir = config['static_dir'] + if 'custom_css' in config: + custom_css = file(config['custom_css'], 'r').read() + if 'users' in config: + users = config['users'] for form in config['forms']: form_name = form['name'] script = form['script'] @@ -248,7 +253,8 @@ class ScriptForm: config['title'], forms, users, - static_dir + static_dir, + custom_css ) self.form_config_singleton = form_config return form_config @@ -285,11 +291,12 @@ class FormConfig: file. It holds information (title, users, the form definitions) on the form configuration being served by this instance of ScriptForm. """ - def __init__(self, title, forms, users={}, static_dir=None): + def __init__(self, title, forms, users={}, static_dir=None, custom_css=None): self.title = title self.users = users self.forms = forms self.static_dir = static_dir + self.custom_css = custom_css self.log = logging.getLogger('FORMCONFIG') # Validate scripts @@ -811,7 +818,8 @@ class ScriptFormWebApp(WebAppHandler): ) output = html_list.format( - header=html_header.format(title=form_config.title), + header=html_header.format(title=form_config.title, + custom_css=form_config.custom_css), footer=html_footer, form_list=u''.join(h_form_list) ) @@ -893,7 +901,8 @@ class ScriptFormWebApp(WebAppHandler): html_errors += u'
' output = html_form.format( - header=html_header.format(title=form_config.title), + header=html_header.format(title=form_config.title, + custom_css=form_config.custom_css), footer=html_footer, title=form_def.title, description=form_def.description, @@ -985,7 +994,8 @@ class ScriptFormWebApp(WebAppHandler): msg = result['stdout'].decode('utf8') output = html_submit_response.format( - header=html_header.format(title=form_config.title), + header=html_header.format(title=form_config.title, + custom_css=form_config.custom_css), footer=html_footer, title=form_def.title, form_name=form_def.name,