From 3aafe664a39fcf911e5e1494a4e7e3a08c948cbf Mon Sep 17 00:00:00 2001
From: Patrick Jentsch <pjentsch@sfb1288inf-Laptop.fritz.box>
Date: Fri, 17 Apr 2020 11:04:09 +0200
Subject: [PATCH] Add macros and use them

---
 app/corpora/views.py                          | 51 ++++++++-----
 app/models.py                                 |  3 -
 app/static/js/nopaque.js                      |  9 +--
 app/templates/admin/edit_user.html.j2         | 41 ++--------
 app/templates/auth/login.html.j2              | 30 ++------
 app/templates/auth/register.html.j2           | 40 ++--------
 app/templates/auth/reset_password.html.j2     | 20 +----
 .../auth/reset_password_request.html.j2       | 12 +--
 app/templates/corpora/add_corpus.html.j2      | 22 +-----
 app/templates/corpora/add_corpus_file.html.j2 | 51 +++----------
 app/templates/corpora/analyse_corpus.html.j2  | 23 +-----
 .../corpora/edit_corpus_file.html.j2          | 49 +++---------
 app/templates/macros.jinja                    | 30 --------
 app/templates/main/feedback.html.j2           |  2 +-
 app/templates/main/index.html.j2              | 28 +------
 app/templates/main/poster.html.j2             |  2 +-
 app/templates/materialize.jinja               | 76 +++++++++++++++++++
 app/templates/nopaque.html.j2                 |  2 +-
 app/templates/profile/settings.html.j2        | 48 +++---------
 app/templates/services/file-setup.html.j2     | 46 ++---------
 app/templates/services/nlp.html.j2            | 65 +++-------------
 app/templates/services/ocr.html.j2            | 55 ++------------
 22 files changed, 204 insertions(+), 501 deletions(-)
 delete mode 100644 app/templates/macros.jinja
 create mode 100644 app/templates/materialize.jinja

diff --git a/app/corpora/views.py b/app/corpora/views.py
index 5f0cdf61..96665d50 100644
--- a/app/corpora/views.py
+++ b/app/corpora/views.py
@@ -1,9 +1,7 @@
-from app import logger
 from flask import (abort, current_app, flash, make_response, redirect, request,
                    render_template, url_for, send_from_directory)
 from flask_login import current_user, login_required
 from threading import Thread
-from werkzeug.utils import secure_filename
 from . import corpora
 from .background_functions import (delete_corpus_, delete_corpus_file_,
                                    edit_corpus_file_)
@@ -129,10 +127,10 @@ def add_corpus_file(corpus_id):
         return make_response(
             {'redirect_url': url_for('corpora.corpus', corpus_id=corpus.id)},
             201)
-        # return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
     return render_template('corpora/add_corpus_file.html.j2',
+                           corpus=corpus,
                            add_corpus_file_form=add_corpus_file_form,
-                           corpus=corpus, title='Add corpus file')
+                           title='Add corpus file')
 
 
 @corpora.route('/<int:corpus_id>/files/<int:corpus_file_id>/delete')
@@ -170,25 +168,28 @@ def download_corpus_file(corpus_id, corpus_file_id):
                methods=['GET', 'POST'])
 @login_required
 def edit_corpus_file(corpus_id, corpus_file_id):
+    corpus = Corpus.query.get_or_404(corpus_id)
     corpus_file = CorpusFile.query.get_or_404(corpus_file_id)
     if not corpus_file.corpus_id == corpus_id:
         abort(404)
     if not (corpus_file.corpus.creator == current_user
             or current_user.is_administrator()):
         abort(403)
-    edit_corpus_file_form = EditCorpusFileForm()
+    edit_corpus_file_form = EditCorpusFileForm(prefix='edit-corpus-file-form')
     if edit_corpus_file_form.validate_on_submit():
-        ids = [field.id for field in edit_corpus_file_form if not
-               (field.id == 'submit'
-                or field.id == "csrf_token"
-                or field.id == "file")]
-        data = [field.data for field in edit_corpus_file_form if not
-                (field.id == 'submit'
-                 or field.id == "csrf_token"
-                 or field.id == "file")]
-        field_dict = dict(zip(ids, data))
-        stmt = db.update(CorpusFile).where(CorpusFile.id==corpus_file_id).values(**field_dict)
-        db.session.execute(stmt)
+        corpus_file.address = edit_corpus_file_form.address.data
+        corpus_file.author = edit_corpus_file_form.author.data
+        corpus_file.booktitle = edit_corpus_file_form.booktitle.data
+        corpus_file.chapter = edit_corpus_file_form.chapter.data
+        corpus_file.editor = edit_corpus_file_form.editor.data
+        corpus_file.institution = edit_corpus_file_form.institution.data
+        corpus_file.journal = edit_corpus_file_form.journal.data
+        corpus_file.pages = edit_corpus_file_form.pages.data
+        corpus_file.publisher = edit_corpus_file_form.publisher.data
+        corpus_file.publishing_year = \
+            edit_corpus_file_form.publishing_year.data
+        corpus_file.school = edit_corpus_file_form.school.data
+        corpus_file.title = edit_corpus_file_form.title.data
         db.session.commit()
         thread = Thread(target=edit_corpus_file_,
                         args=(current_app._get_current_object(),
@@ -196,9 +197,23 @@ def edit_corpus_file(corpus_id, corpus_file_id):
         thread.start()
         flash('Corpus file edited!')
         return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
+    # If no form is submitted or valid, fill out fields with current values
+    edit_corpus_file_form.address.data = corpus_file.address
+    edit_corpus_file_form.author.data = corpus_file.author
+    edit_corpus_file_form.booktitle.data = corpus_file.booktitle
+    edit_corpus_file_form.chapter.data = corpus_file.chapter
+    edit_corpus_file_form.editor.data = corpus_file.editor
+    edit_corpus_file_form.institution.data = corpus_file.institution
+    edit_corpus_file_form.journal.data = corpus_file.journal
+    edit_corpus_file_form.pages.data = corpus_file.pages
+    edit_corpus_file_form.publisher.data = corpus_file.publisher
+    edit_corpus_file_form.publishing_year.data = corpus_file.publishing_year
+    edit_corpus_file_form.school.data = corpus_file.school
+    edit_corpus_file_form.title.data = corpus_file.title
     return render_template('corpora/edit_corpus_file.html.j2',
+                           corpus_file=corpus_file, corpus=corpus,
                            edit_corpus_file_form=edit_corpus_file_form,
-                           corpus_file=corpus_file, title='Edit corpus file')
+                           title='Edit corpus file')
 
 
 @corpora.route('/<int:corpus_id>/prepare')
@@ -207,7 +222,7 @@ def prepare_corpus(corpus_id):
     corpus = Corpus.query.get_or_404(corpus_id)
     if not (corpus.creator == current_user or current_user.is_administrator()):
         abort(403)
-    if len(corpus.files.all()) > 0:
+    if corpus.files.all():
         corpus.status = 'submitted'
         db.session.commit()
         flash('Corpus marked for preparation!')
diff --git a/app/models.py b/app/models.py
index d4044e57..4925be71 100644
--- a/app/models.py
+++ b/app/models.py
@@ -256,7 +256,6 @@ class JobInput(db.Model):
 
     def to_dict(self):
         return {'id': self.id,
-                'dir': self.dir,
                 'filename': self.filename,
                 'job_id': self.job_id}
 
@@ -280,7 +279,6 @@ class JobResult(db.Model):
 
     def to_dict(self):
         return {'id': self.id,
-                'dir': self.dir,
                 'filename': self.filename,
                 'job_id': self.job_id}
 
@@ -432,7 +430,6 @@ class CorpusFile(db.Model):
                 'author': self.author,
                 'booktitle': self.booktitle,
                 'chapter': self.chapter,
-                'dir': self.dir,
                 'editor': self.editor,
                 'filename': self.filename,
                 'institution': self.institution,
diff --git a/app/static/js/nopaque.js b/app/static/js/nopaque.js
index e5f3ef65..cbefbc37 100644
--- a/app/static/js/nopaque.js
+++ b/app/static/js/nopaque.js
@@ -113,18 +113,11 @@ nopaque.Forms.init = function() {
     }
     form.addEventListener("submit", function(event) {
       event.preventDefault();
-      var formData, progressModalTitleElement;
+      var formData;
 
       formData = new FormData(form);
       // Initialize progress modal
       if (progressModalElement) {
-        progressModalTitleElement = progressModalElement.querySelector(".title");
-        for(let entry of formData.entries()) {
-          if (entry[0].endsWith("title")) {
-            progressModalTitleElement.innerText = entry[1];
-            break;
-          }
-        }
         progressElement.style.width = "0%";
         progressModal.open();
       }
diff --git a/app/templates/admin/edit_user.html.j2 b/app/templates/admin/edit_user.html.j2
index dd4e640b..42187b9e 100644
--- a/app/templates/admin/edit_user.html.j2
+++ b/app/templates/admin/edit_user.html.j2
@@ -12,44 +12,13 @@
     <form method="POST">
       <div class="card-content">
         {{ edit_user_form.hidden_tag() }}
-        <div class="input-field ">
-          <i class="material-icons prefix">account_circle</i>
-          {{ edit_user_form.username() }}
-          {{ edit_user_form.username.label }}
-          {% for error in edit_user_form.username.errors %}
-          <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">mail</i>
-          {{ edit_user_form.email() }}
-          {{ edit_user_form.email.label }}
-          {% for error in edit_user_form.email.errors %}
-          <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">swap_vert</i>
-          {{ edit_user_form.role() }}
-          {{ edit_user_form.role.label }}
-          {% for error in edit_user_form.role.errors %}
-          <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="switch">
-          <i class="material-icons prefix">check</i>
-          <label>
-            Confirmed
-            {{ edit_user_form.confirmed() }}
-            <span class="lever"></span>
-          </label>
-          {% for error in edit_user_form.confirmed.errors %}
-          <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
+        {{ materialize.field(edit_user_form.username, data_length='64', material_icon='account_circle') }}
+        {{ materialize.field(edit_user_form.email, class_='validate', material_icon='email', type='email') }}
+        {{ materialize.field(edit_user_form.role, material_icon='swap_vert') }}
+        {{ materialize.field(edit_user_form.confirmed, material_icon='check') }}
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(edit_user_form.submit) }}
+        {{ materialize.field(edit_user_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/auth/login.html.j2 b/app/templates/auth/login.html.j2
index 6f57d209..4561a966 100644
--- a/app/templates/auth/login.html.j2
+++ b/app/templates/auth/login.html.j2
@@ -26,41 +26,21 @@
 <div class="col s12 m8">
   <div class="card medium">
     <form method="POST">
-      {{ login_form.hidden_tag() }}
       <div class="card-content">
-        <div class="input-field">
-          <i class="material-icons prefix">person</i>
-          {{ login_form.user(class='validate') }}
-          {{ login_form.user.label }}
-          {% for error in login_form.user.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">vpn_key</i>
-          {{ login_form.password(class='validate') }}
-          {{ login_form.password.label }}
-          {% for error in login_form.password.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
+        {{ login_form.hidden_tag() }}
+        {{ materialize.field(login_form.user, material_icon='person') }}
+        {{ materialize.field(login_form.password, material_icon='vpn_key') }}
         <div class="row" style="margin-bottom: 0;">
           <div class="col s6 left-align">
             <a href="{{ url_for('auth.reset_password_request') }}">Forgot your password?</a>
           </div>
           <div class="col s6 right-align">
-            <div class="switch">
-              <label>
-                Remember me
-                {{ login_form.remember_me(class='validate') }}
-                <span class="lever"></span>
-              </label>
-            </div>
+            {{ materialize.field(login_form.remember_me) }}
           </div>
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(login_form.submit) }}
+        {{ materialize.field(login_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/auth/register.html.j2 b/app/templates/auth/register.html.j2
index 8b38326a..42259f07 100644
--- a/app/templates/auth/register.html.j2
+++ b/app/templates/auth/register.html.j2
@@ -24,43 +24,15 @@
 <div class="col s12 m8">
   <div class="card medium">
     <form method="POST">
-      {{ registration_form.hidden_tag() }}
       <div class="card-content">
-        <div class="input-field">
-          <i class="material-icons prefix">person</i>
-          {{ registration_form.username(class='validate', data_length='64') }}
-          {{ registration_form.username.label }}
-          {% for error in registration_form.username.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">vpn_key</i>
-          {{ registration_form.password(class='validate') }}
-          {{ registration_form.password.label }}
-          {% for error in registration_form.password.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">vpn_key</i>
-          {{ registration_form.password_confirmation(class='validate') }}
-          {{ registration_form.password_confirmation.label }}
-          {% for error in registration_form.password_confirmation.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">email</i>
-          {{ registration_form.email(class='validate', type='email') }}
-          {{ registration_form.email.label }}
-          {% for error in registration_form.email.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
+        {{ registration_form.hidden_tag() }}
+        {{ materialize.field(registration_form.username, data_length='64', material_icon='person') }}
+        {{ materialize.field(registration_form.password, data_length='128', material_icon='vpn_key') }}
+        {{ materialize.field(registration_form.password_confirmation, data_length='128', material_icon='vpn_key') }}
+        {{ materialize.field(registration_form.email, class_='validate', material_icon='email', type='email') }}
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(registration_form.submit) }}
+        {{ materialize.field(registration_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/auth/reset_password.html.j2 b/app/templates/auth/reset_password.html.j2
index 5c6740cf..dcf2aa4b 100644
--- a/app/templates/auth/reset_password.html.j2
+++ b/app/templates/auth/reset_password.html.j2
@@ -9,25 +9,13 @@
 <div class="col s12 m8">
   <div class="card">
     <form method="POST">
-      {{ reset_password_form.hidden_tag() }}
       <div class="card-content">
-        <div class="input-field">
-          {{ reset_password_form.password(class='validate') }}
-          {{ reset_password_form.password.label }}
-          {% for error in reset_password_form.password.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          {{ reset_password_form.password_confirmation(class='validate') }}
-          {{ reset_password_form.password_confirmation.label }}
-          {% for error in reset_password_form.password_confirmation.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
+        {{ reset_password_form.hidden_tag() }}
+        {{ materialize.field(reset_password_form.password, data_length='128') }}
+        {{ materialize.field(reset_password_form.password_confirmation, data_length='128') }}
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(reset_password_form.submit) }}
+        {{ materialize.field(reset_password_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/auth/reset_password_request.html.j2 b/app/templates/auth/reset_password_request.html.j2
index 9ea8d8ea..e25481a1 100644
--- a/app/templates/auth/reset_password_request.html.j2
+++ b/app/templates/auth/reset_password_request.html.j2
@@ -8,18 +8,12 @@
 <div class="col s12 m8">
   <div class="card">
     <form method="POST">
-      {{ reset_password_request_form.hidden_tag() }}
       <div class="card-content">
-        <div class="input-field">
-          {{ reset_password_request_form.email(class='validate', type='email') }}
-          {{ reset_password_request_form.email.label }}
-          {% for error in reset_password_request_form.email.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
+        {{ reset_password_request_form.hidden_tag() }}
+        {{ materialize.field(reset_password_request_form.email, class_='validate', material_icon='email', type='email') }}
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(reset_password_request_form.submit) }}
+        {{ materialize.field(reset_password_request_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/corpora/add_corpus.html.j2 b/app/templates/corpora/add_corpus.html.j2
index 39e33abf..9fb6d841 100644
--- a/app/templates/corpora/add_corpus.html.j2
+++ b/app/templates/corpora/add_corpus.html.j2
@@ -9,33 +9,19 @@
 <div class="col s12 m8">
   <div class="card">
     <form method="POST">
-      {{ add_corpus_form.hidden_tag() }}
       <div class="card-content">
+        {{ add_corpus_form.hidden_tag() }}
         <div class="row">
           <div class="col s12 m4">
-            <div class="input-field">
-              <i class="material-icons prefix">title</i>
-              {{ add_corpus_form.title(data_length='32') }}
-              {{ add_corpus_form.title.label }}
-              {% for error in add_corpus_form.title.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_corpus_form.title, data_length='32', material_icon='title') }}
           </div>
           <div class="col s12 m8">
-            <div class="input-field">
-              <i class="material-icons prefix">description</i>
-              {{ add_corpus_form.description(data_length='255') }}
-              {{ add_corpus_form.description.label }}
-              {% for error in add_corpus_form.description.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_corpus_form.description, data_length='255', material_icon='description') }}
           </div>
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(add_corpus_form.submit) }}
+        {{ materialize.field(add_corpus_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/corpora/add_corpus_file.html.j2 b/app/templates/corpora/add_corpus_file.html.j2
index fb7e3616..cee8457c 100644
--- a/app/templates/corpora/add_corpus_file.html.j2
+++ b/app/templates/corpora/add_corpus_file.html.j2
@@ -9,59 +9,27 @@
 
 <div class="col s12 m8">
   <form class="nopaque-submit-form" data-progress-modal="progress-modal">
-    {{ add_corpus_file_form.hidden_tag() }}
     <div class="card">
       <div class="card-content">
         <span class="card-title">Required metadata</span>
+        {{ add_corpus_file_form.hidden_tag() }}
         <div class="row">
           <div class="col s12 m4">
-            <div class="input-field">
-              <i class="material-icons prefix">person</i>
-              {{ add_corpus_file_form.author(data_length='255') }}
-              {{ add_corpus_file_form.author.label }}
-              {% for error in add_corpus_file_form.author.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_corpus_file_form.author, data_length='255', material_icon='person') }}
           </div>
           <div class="col s12 m4">
-            <div class="input-field">
-              <i class="material-icons prefix">title</i>
-              {{ add_corpus_file_form.title(data_length='255') }}
-              {{ add_corpus_file_form.title.label }}
-              {% for error in add_corpus_file_form.title.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_corpus_file_form.title, data_length='255', material_icon='title') }}
           </div>
           <div class="col s12 m4">
-            <div class="input-field">
-              <i class="material-icons prefix">access_time</i>
-              {{ add_corpus_file_form.publishing_year() }}
-              {{ add_corpus_file_form.publishing_year.label }}
-              {% for error in add_corpus_file_form.publishing_year.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_corpus_file_form.publishing_year, material_icon='access_time') }}
           </div>
           <div class="col s12">
-            <div class="file-field input-field">
-              <div class="btn">
-                <span>{{ add_corpus_file_form.file.label.text }}</span>
-                {{ add_corpus_file_form.file(accept='.vrt') }}
-              </div>
-              <div class="file-path-wrapper">
-                <input class="file-path validate" type="text">
-              </div>
-              {% for error in add_corpus_file_form.file.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_corpus_file_form.file, accept='.vrt') }}
           </div>
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(add_corpus_file_form.submit) }}
+        {{ materialize.field(add_corpus_file_form.submit, material_icon='send') }}
       </div>
     </div>
     <br>
@@ -69,8 +37,9 @@
       <li>
         <div class="collapsible-header"><i class="material-icons">add</i>Add additional metadata</div>
         <div class="collapsible-body">
-          {% for field in add_corpus_file_form if not (field.name.endswith(('author', 'csrf_token', 'file', 'publishing_year', 'submit', 'title'))) %}
-          {{ macros.render_field(field)}}
+          {% for field in add_corpus_file_form
+             if field.short_name not in ['author', 'csrf_token', 'file', 'publishing_year', 'submit', 'title'] %}
+          {{ materialize.field(field, data_length='255', material_icon=field.label.text[0:1]) }}
           {% endfor %}
         </div>
       </li>
@@ -95,7 +64,7 @@
 
 <div id="progress-modal" class="modal">
   <div class="modal-content">
-    <h4><i class="material-icons prefix">file_upload</i> Uploading files for <span class="title"></span></h4>
+    <h4><i class="material-icons prefix">file_upload</i> Uploading file...</h4>
     <div class="progress">
       <div class="determinate" style="width: 0%"></div>
     </div>
diff --git a/app/templates/corpora/analyse_corpus.html.j2 b/app/templates/corpora/analyse_corpus.html.j2
index 02f30024..2c5ecb0f 100644
--- a/app/templates/corpora/analyse_corpus.html.j2
+++ b/app/templates/corpora/analyse_corpus.html.j2
@@ -34,7 +34,7 @@
             </div>
             <div class="col s12 m2">
               <br class="hide-on-small-only">
-              {{ macros.submit_button(query_form.submit) }}
+              {{ materialize.field(query_form.submit, material_icon='send') }}
             </div>
           </div>
         </form>
@@ -49,27 +49,13 @@
         <form id="display-options-form">
           <div class="row">
             <div class="col s12 m6">
-              <div class="input-field">
-                <i class="material-icons prefix">format_list_numbered</i>
-                {{ display_options_form.results_per_page() }}
-                {{ display_options_form.results_per_page.label }}
-              </div>
+              {{ materialize.field(display_options_form.results_per_page, material_icon='format_list_numbered') }}
             </div>
             <div class="col s12 m6">
-              <div class="input-field">
-                <i class="material-icons prefix">short_text</i>
-                {{ display_options_form.result_context() }}
-                {{ display_options_form.result_context.label }}
-              </div>
+              {{ materialize.field(display_options_form.result_context, material_icon='short_text') }}
             </div>
             <div class="col s12">
-              <div class="switch">
-                <label>
-                  {{ display_options_form.expert_mode.label.text }}
-                  {{ display_options_form.expert_mode() }}
-                  <span class="lever"></span>
-                </label>
-              </div>
+              {{ materialize.field(display_options_form.expert_mode) }}
             </div>
           </div>
         </form>
@@ -152,7 +138,6 @@
 <div id="query-results-download-modal"
      class="modal modal-fixed-footer no-autoinit">
   <div class="modal-content">
-    {{ query_download_form.hidden_tag() }}
     <h4>Download current query Results</h4>
     <p>The results of the current query can be downlaoded as several files like csv or json. Those files can be used in other software like excel. Also it is easy to publish your results as raw data like this!</p>
     <table>
diff --git a/app/templates/corpora/edit_corpus_file.html.j2 b/app/templates/corpora/edit_corpus_file.html.j2
index 1c7ef7ef..07953471 100644
--- a/app/templates/corpora/edit_corpus_file.html.j2
+++ b/app/templates/corpora/edit_corpus_file.html.j2
@@ -4,7 +4,7 @@
 <div class="col s12 m4">
   <h3 id="title">...</h3>
   <p id="description">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et</p>
-  <a class="btn waves-effect waves-light" href="{{ url_for('corpora.corpus', corpus_id=corpus_file.corpus.id) }}"><i class="material-icons left">arrow_back</i>Back to corpus</a>
+  <a class="btn waves-effect waves-light" href="{{ url_for('corpora.corpus', corpus_id=corpus.id) }}"><i class="material-icons left">arrow_back</i>Back to corpus</a>
 </div>
 
 <div class="col s12 m8">
@@ -14,39 +14,18 @@
       <div class="card-content">
         <div class="row">
           <div class="col s12 m4">
-            <div class="input-field">
-              <i class="material-icons prefix">person</i>
-              {{ edit_corpus_file_form.author(data_length='255', value=corpus_file.author) }}
-              {{ edit_corpus_file_form.author.label }}
-              {% for error in edit_corpus_file_form.author.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(edit_corpus_file_form.author, data_length='255', material_icon='person') }}
           </div>
           <div class="col s12 m4">
-            <div class="input-field">
-              <i class="material-icons prefix">title</i>
-              {{ edit_corpus_file_form.title(data_length='255', value=corpus_file.title) }}
-              {{ edit_corpus_file_form.title.label }}
-              {% for error in edit_corpus_file_form.title.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(edit_corpus_file_form.title, data_length='255', material_icon='title') }}
           </div>
           <div class="col s12 m4">
-            <div class="input-field">
-              <i class="material-icons prefix">access_time</i>
-              {{ edit_corpus_file_form.publishing_year(value=corpus_file.publishing_year) }}
-              {{ edit_corpus_file_form.publishing_year.label }}
-              {% for error in edit_corpus_file_form.publishing_year.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(edit_corpus_file_form.publishing_year, material_icon='access_time') }}
           </div>
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(edit_corpus_file_form.submit) }}
+        {{ materialize.field(edit_corpus_file_form.submit, material_icon='send') }}
       </div>
     </div>
     <br>
@@ -54,20 +33,10 @@
       <li>
         <div class="collapsible-header"><i class="material-icons">edit</i>Edit additional metadata</div>
         <div class="collapsible-body">
-          <span>
-            <div class="row">
-              <div class="col s12">
-                {% for field in edit_corpus_file_form if not (field.name == "file"
-                  or field.name == "author"
-                  or field.name == "submit"
-                  or field.name == "csrf_token"
-                  or field.name == "title"
-                  or field.name == "publishing_year") %}
-                  {{ macros.render_field_with_value(field, corpus_file)}}
-                {% endfor %}
-              </div>
-            </div>
-          </span>
+          {% for field in edit_corpus_file_form
+             if field.short_name not in ['author', 'csrf_token', 'publishing_year', 'submit', 'title'] %}
+          {{ materialize.field(field) }}
+          {% endfor %}
         </div>
       </li>
     </ul>
diff --git a/app/templates/macros.jinja b/app/templates/macros.jinja
deleted file mode 100644
index d61de68b..00000000
--- a/app/templates/macros.jinja
+++ /dev/null
@@ -1,30 +0,0 @@
-{% macro render_field(field) %}
-<div class="input-field">
-  <i class="prefix">{{ field.label.text[0:1]|upper }}</i>
-  {{ field.label }}
-  {{ field(data_length='255')|safe }}
-  {% for error in field.errors %}
-  <span class="helper-text red-text">{{ error }}</span>
-  {% endfor %}
-</div>
-{% endmacro %}
-
-
-{% macro render_field_with_value(field, corpus_file) %}
-<div class="input-field">
-  <i class="prefix">{{ field.label.text[0:1]|upper }}</i>
-  {{ field.label }}
-  {{ field(value=corpus_file[field.name], data_length='255')| safe }}
-  {% for error in field.errors %}
-  <span class="helper-text red-text">{{ error }}</span>
-  {% endfor %}
-</div>
-{% endmacro %}
-
-
-{% macro submit_button(input) %}
-<button class="btn waves-effect waves-light" id="{{ input.id }}" name="{{ input.name }}" type="submit" value="{{ input.label.text }}">
-  {{ input.label.text }}
-  <i class="material-icons right">send</i>
-</button>
-{% endmacro %}
diff --git a/app/templates/main/feedback.html.j2 b/app/templates/main/feedback.html.j2
index eef11d7e..b156c108 100644
--- a/app/templates/main/feedback.html.j2
+++ b/app/templates/main/feedback.html.j2
@@ -26,7 +26,7 @@
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(feedback_form.submit) }}
+        {{ materialize.field(feedback_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/main/index.html.j2 b/app/templates/main/index.html.j2
index 4733e76b..fa18e901 100644
--- a/app/templates/main/index.html.j2
+++ b/app/templates/main/index.html.j2
@@ -145,39 +145,19 @@
               <div class="card-content">
                 <span class="card-title">Log in</span>
                 {{ login_form.hidden_tag() }}
-                <div class="input-field">
-                  <i class="material-icons prefix">person</i>
-                  {{ login_form.user(class='validate') }}
-                  {{ login_form.user.label }}
-                  {% for error in login_form.user.errors %}
-                    <span class="helper-text red-text">{{ error }}</span>
-                  {% endfor %}
-                </div>
-                <div class="input-field">
-                  <i class="material-icons prefix">vpn_key</i>
-                  {{ login_form.password(class='validate') }}
-                  {{ login_form.password.label }}
-                  {% for error in login_form.password.errors %}
-                    <span class="helper-text red-text">{{ error }}</span>
-                  {% endfor %}
-                </div>
+                {{ materialize.field(login_form.user, material_icon='person') }}
+                {{ materialize.field(login_form.password, material_icon='vpn_key') }}
                 <div class="row" style="margin-bottom: 0;">
                   <div class="col s6 left-align">
                     <a href="{{ url_for('auth.reset_password_request') }}">Forgot your password?</a>
                   </div>
                   <div class="col s6 right-align">
-                    <div class="switch">
-                      <label>
-                        Remember me
-                        {{ login_form.remember_me() }}
-                        <span class="lever"></span>
-                      </label>
-                    </div>
+                    {{ materialize.field(login_form.remember_me) }}
                   </div>
                 </div>
               </div>
               <div class="card-action right-align">
-                {{ macros.submit_button(login_form.submit) }}
+                {{ materialize.field(login_form.submit, material_icon='send') }}
               </div>
             </form>
           </div>
diff --git a/app/templates/main/poster.html.j2 b/app/templates/main/poster.html.j2
index ba0d9c2f..ba20e8b3 100644
--- a/app/templates/main/poster.html.j2
+++ b/app/templates/main/poster.html.j2
@@ -187,7 +187,7 @@
                       <a href="{{ url_for('auth.reset_password_request') }}">No account yet?</a>
                     </div>
                     <div class="col s6 right-align">
-                      {{ macros.submit_button(login_form.submit) }}
+                      {{ materialize.submit_button(login_form.submit) }}
                     </div>
                   </div>
                 </div>
diff --git a/app/templates/materialize.jinja b/app/templates/materialize.jinja
new file mode 100644
index 00000000..366654ad
--- /dev/null
+++ b/app/templates/materialize.jinja
@@ -0,0 +1,76 @@
+{% macro field(field) %}
+  {% if field.type == 'BooleanField' %}
+    {{ boolean_field(field, *args, **kwargs) }}
+  {% elif field.type == 'SubmitField' %}
+    {{ submit_field(field, *args, **kwargs) }}
+  {% elif field.type in ['FileField', 'MultipleFileField'] %}
+    {{ file_field(field, *args, **kwargs) }}
+  {% elif field.type in ['IntegerField', 'PasswordField', 'SelectField', 'StringField'] %}
+    {{ generic_field(field, *args, **kwargs) }}
+  {% endif %}
+{% endmacro %}
+
+{% macro boolean_field(field) %}
+<div class="switch">
+  {% if 'material_icon' in kwargs %}
+    <i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
+  {% endif %}
+  <label>
+    {{ field.label.text }}
+    {{ field() }}
+    <span class="lever"></span>
+  </label>
+  {% for error in field.errors %}
+    <span class="helper-text red-text">{{ error }}</span>
+  {% endfor %}
+</div>
+{% endmacro %}
+
+{% macro file_field(field) %}
+<div class="file-field input-field">
+  <div class="btn">
+    <span>{{ field.label.text }}</span>
+    {{ field(**kwargs) }}
+  </div>
+  <div class="file-path-wrapper">
+    <input class="file-path validate" type="text">
+  </div>
+</div>
+{% endmacro %}
+
+{% macro generic_field(field) %}
+  {% if field.type == 'IntegerField' %}
+    {% set tmp = kwargs.update({'type': 'number'}) %}
+    {% if 'class_' in kwargs and 'validate' not in kwargs['class_'] %}
+      {% set tmp = kwargs.update({'class_': kwargs['class_'] + ' validate'}) %}
+    {% else %}
+      {% set tmp = kwargs.update({'class_': 'validate'}) %}
+    {% endif %}
+  {% endif %}
+  <div class="input-field">
+    {% if 'material_icon' in kwargs %}
+      <i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
+    {% endif %}
+    {{ field(**kwargs) }}
+    {{ field.label }}
+    {% for error in field.errors %}
+      <span class="helper-text red-text">{{ error }}</span>
+    {% endfor %}
+  </div>
+{% endmacro %}
+
+{% macro submit_field(field) %}
+<button class="btn waves-effect waves-light" id="{{ field.id }}" name="{{ field.name }}" type="submit" value="{{ field.label.text }}">
+  {{ field.label.text }}
+  {% if 'material_icon' in kwargs %}
+    <i class="material-icons right">{{ kwargs.pop('material_icon') }}</i>
+  {% endif %}
+</button>
+{% endmacro %}
+
+{% macro submit_button(input) %}
+<button class="btn waves-effect waves-light" id="{{ input.id }}" name="{{ input.name }}" type="submit" value="{{ input.label.text }}">
+  {{ input.label.text }}
+  <i class="material-icons right">send</i>
+</button>
+{% endmacro %}
diff --git a/app/templates/nopaque.html.j2 b/app/templates/nopaque.html.j2
index e3839d3e..dd55f4bd 100644
--- a/app/templates/nopaque.html.j2
+++ b/app/templates/nopaque.html.j2
@@ -1,4 +1,4 @@
-{% import "macros.jinja" as macros %}
+{% import "materialize.jinja" as materialize %}
 
 <!DOCTYPE html>
 <html lang="en">
diff --git a/app/templates/profile/settings.html.j2 b/app/templates/profile/settings.html.j2
index 08b9a016..e24b386d 100644
--- a/app/templates/profile/settings.html.j2
+++ b/app/templates/profile/settings.html.j2
@@ -8,8 +8,8 @@
   <br class="hide-on-small-only">
   <div class="card">
     <form method="POST">
-      {{ edit_general_settings_form.hidden_tag() }}
       <div class="card-content">
+        {{ edit_general_settings_form.hidden_tag() }}
         <div class="row">
           <div class="col s9">
             <p><i class="material-icons left">brightness_3</i>{{ edit_general_settings_form.dark_mode.label.text }}</p>
@@ -46,7 +46,7 @@
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(edit_general_settings_form.save_settings) }}
+        {{ materialize.field(edit_general_settings_form.save_settings, material_icon='send') }}
       </div>
     </form>
   </div>
@@ -63,35 +63,14 @@
   <br class="hide-on-small-only">
   <div class="card">
     <form method="POST">
-      {{ edit_password_form.hidden_tag() }}
       <div class="card-content">
-        <div class="input-field ">
-          <i class="material-icons prefix">vpn_key</i>
-          {{ edit_password_form.current_password() }}
-          {{ edit_password_form.current_password.label }}
-          {% for error in edit_password_form.current_password.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">vpn_key</i>
-          {{ edit_password_form.password() }}
-          {{ edit_password_form.password.label }}
-          {% for error in edit_password_form.password.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
-        <div class="input-field">
-          <i class="material-icons prefix">vpn_key</i>
-          {{ edit_password_form.password_confirmation() }}
-          {{ edit_password_form.password_confirmation.label }}
-          {% for error in edit_password_form.password_confirmation.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
+        {{ edit_password_form.hidden_tag() }}
+        {{ materialize.field(edit_password_form.current_password, data_length='128', material_icon='vpn_key') }}
+        {{ materialize.field(edit_password_form.password, data_length='128', material_icon='vpn_key') }}
+        {{ materialize.field(edit_password_form.password_confirmation, data_length='128', material_icon='vpn_key') }}
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(edit_password_form.save_password) }}
+        {{ materialize.field(edit_password_form.save_password, material_icon='send') }}
       </div>
     </form>
   </div>
@@ -108,19 +87,12 @@
   <br class="hide-on-small-only">
   <div class="card">
     <form method="POST">
-      {{ edit_email_form.hidden_tag() }}
       <div class="card-content">
-        <div class="input-field">
-          <i class="material-icons prefix">mail</i>
-          {{ edit_email_form.email() }}
-          {{ edit_email_form.email.label }}
-          {% for error in edit_email_form.email.errors %}
-            <span class="helper-text red-text">{{ error }}</span>
-          {% endfor %}
-        </div>
+        {{ edit_email_form.hidden_tag() }}
+        {{ materialize.field(edit_email_form.email, class_='validate', material_icon='email', type='email') }}
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(edit_email_form.save_email) }}
+        {{ materialize.field(edit_email_form.save_email, material_icon='send') }}
       </div>
     </form>
   </div>
diff --git a/app/templates/services/file-setup.html.j2 b/app/templates/services/file-setup.html.j2
index 4bcd7020..c2798294 100644
--- a/app/templates/services/file-setup.html.j2
+++ b/app/templates/services/file-setup.html.j2
@@ -26,57 +26,25 @@
   <h3>Submit a job</h3>
   <div class="card">
     <form class="nopaque-submit-form" data-progress-modal="progress-modal">
-      {{ add_job_form.hidden_tag() }}
       <div class="card-content">
+        {{ add_job_form.hidden_tag() }}
         <div class="row">
           <div class="col s12 l4">
-            <div class="input-field">
-              <i class="material-icons prefix">title</i>
-              {{ add_job_form.title(data_length='32') }}
-              {{ add_job_form.title.label }}
-              {% for error in add_job_form.title.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.title, data_length='32', material_icon='title') }}
           </div>
           <div class="col s12 l8">
-            <div class="input-field">
-              <i class="material-icons prefix">description</i>
-              {{ add_job_form.description(data_length='255') }}
-              {{ add_job_form.description.label }}
-              {% for error in add_job_form.description.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.description, data_length='255', material_icon='description') }}
           </div>
           <div class="col s12">
-            <div class="file-field input-field">
-              <div class="btn">
-                <span>{{ add_job_form.files.label.text }}</span>
-                {{ add_job_form.files(accept='image/jpeg, image/png, image/tiff') }}
-              </div>
-              <div class="file-path-wrapper">
-                <input class="file-path validate" type="text">
-              </div>
-              {% for error in add_job_form.files.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.files, accept='image/jpeg, image/png, image/tiff') }}
           </div>
           <div class="col s12 hide">
-            <div class="input-field">
-              <i class="material-icons prefix">apps</i>
-              {{ add_job_form.version() }}
-              {{ add_job_form.version.label }}
-              {% for error in add_job_form.version.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.version, material_icon='apps') }}
           </div>
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(add_job_form.submit) }}
+        {{ materialize.submit_button(add_job_form.submit) }}
       </div>
     </form>
   </div>
@@ -84,7 +52,7 @@
 
 <div id="progress-modal" class="modal">
   <div class="modal-content">
-    <h4><i class="material-icons prefix">file_upload</i> Uploading files for <span class="title"></span></h4>
+    <h4><i class="material-icons prefix">file_upload</i> Uploading files...</h4>
     <div class="progress">
       <div class="determinate" style="width: 0%"></div>
     </div>
diff --git a/app/templates/services/nlp.html.j2 b/app/templates/services/nlp.html.j2
index 382af028..23ab5848 100644
--- a/app/templates/services/nlp.html.j2
+++ b/app/templates/services/nlp.html.j2
@@ -44,64 +44,23 @@
   <h3>Submit a job</h3>
   <div class="card">
     <form class="nopaque-submit-form" data-progress-modal="progress-modal">
-      {{ add_job_form.hidden_tag() }}
       <div class="card-content">
+        {{ add_job_form.hidden_tag() }}
         <div class="row">
           <div class="col s12 l4">
-            <div class="input-field">
-              <i class="material-icons prefix">title</i>
-              {{ add_job_form.title(data_length='32') }}
-              {{ add_job_form.title.label }}
-              {% for error in add_job_form.title.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.title, data_length='32', material_icon='title') }}
           </div>
-          <div class="col s12 l4">
-            <div class="input-field">
-              <i class="material-icons prefix">language</i>
-              {{ add_job_form.language() }}
-              {{ add_job_form.language.label }}
-              {% for error in add_job_form.language.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+          <div class="col s12 l8">
+            {{ materialize.field(add_job_form.description, data_length='255', material_icon='description') }}
           </div>
-          <div class="col s12 l4">
-            <div class="input-field">
-              <i class="material-icons prefix">language</i>
-              {{ add_job_form.version() }}
-              {{ add_job_form.version.label }}
-              {% for error in add_job_form.version.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+          <div class="col s12 l5">
+            {{ materialize.field(add_job_form.files, accept='text/plain') }}
           </div>
-        </div>
-        <div class="row">
-          <div class="col s12 l6">
-            <div class="file-field input-field">
-              <div class="btn">
-                <span>{{ add_job_form.files.label.text }}</span>
-                {{ add_job_form.files(accept='text/plain') }}
-              </div>
-              <div class="file-path-wrapper">
-                <input class="file-path validate" type="text">
-              </div>
-              {% for error in add_job_form.files.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+          <div class="col s12 l4">
+            {{ materialize.field(add_job_form.language, material_icon='language') }}
           </div>
-          <div class="col s12 l6">
-            <div class="input-field">
-              <i class="material-icons prefix">description</i>
-              {{ add_job_form.description(data_length='255') }}
-              {{ add_job_form.description.label }}
-              {% for error in add_job_form.description.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+          <div class="col s12 l3">
+            {{ materialize.field(add_job_form.version, material_icon='apps') }}
           </div>
           <div class="col s12">
             <span class="card-title">Preprocessing</span>
@@ -127,7 +86,7 @@
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(add_job_form.submit) }}
+        {{ materialize.field(add_job_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
@@ -135,7 +94,7 @@
 
 <div id="progress-modal" class="modal">
   <div class="modal-content">
-    <h4><i class="material-icons prefix">file_upload</i> Uploading files for <span class="title"></span></h4>
+    <h4><i class="material-icons prefix">file_upload</i> Uploading files...</h4>
     <div class="progress">
       <div class="determinate" style="width: 0%"></div>
     </div>
diff --git a/app/templates/services/ocr.html.j2 b/app/templates/services/ocr.html.j2
index 3483c11c..0cc3e640 100644
--- a/app/templates/services/ocr.html.j2
+++ b/app/templates/services/ocr.html.j2
@@ -26,62 +26,23 @@
   <h3>Submit a job</h3>
   <div class="card">
     <form class="nopaque-submit-form" data-progress-modal="progress-modal">
-      {{ add_job_form.hidden_tag() }}
       <div class="card-content">
+        {{ add_job_form.hidden_tag() }}
         <div class="row">
           <div class="col s12 l4">
-            <div class="input-field">
-              <i class="material-icons prefix">title</i>
-              {{ add_job_form.title(class="validate", data_length='32') }}
-              {{ add_job_form.title.label }}
-              {% for error in add_job_form.title.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.title, data_length='32', material_icon='title') }}
           </div>
           <div class="col s12 l8">
-            <div class="input-field">
-              <i class="material-icons prefix">description</i>
-              {{ add_job_form.description(class="validate", data_length='255') }}
-              {{ add_job_form.description.label }}
-              {% for error in add_job_form.description.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.description, data_length='255', material_icon='description') }}
           </div>
           <div class="col s12 l5">
-            <div class="file-field input-field">
-              <div class="btn">
-                <span>{{ add_job_form.files.label.text }}</span>
-                {{ add_job_form.files(accept='application/pdf') }}
-              </div>
-              <div class="file-path-wrapper">
-                <input class="file-path validate" type="text">
-              </div>
-              {% for error in add_job_form.files.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.files, accept='application/pdf') }}
           </div>
           <div class="col s12 l4">
-            <div class="input-field">
-              <i class="material-icons prefix">language</i>
-              {{ add_job_form.language(class="validate") }}
-              {{ add_job_form.language.label }}
-              {% for error in add_job_form.language.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.language, material_icon='language') }}
           </div>
           <div class="col s12 l3">
-            <div class="input-field">
-              <i class="material-icons prefix">apps</i>
-              {{ add_job_form.version(class="validate") }}
-              {{ add_job_form.version.label }}
-              {% for error in add_job_form.version.errors %}
-                <span class="helper-text red-text">{{ error }}</span>
-              {% endfor %}
-            </div>
+            {{ materialize.field(add_job_form.version, material_icon='apps') }}
           </div>
           <div class="col s12">
             <span class="card-title">Preprocessing</span>
@@ -152,7 +113,7 @@
         </div>
       </div>
       <div class="card-action right-align">
-        {{ macros.submit_button(add_job_form.submit) }}
+        {{ materialize.field(add_job_form.submit, material_icon='send') }}
       </div>
     </form>
   </div>
@@ -160,7 +121,7 @@
 
 <div id="progress-modal" class="modal">
   <div class="modal-content">
-    <h4><i class="material-icons left">file_upload</i>Uploading files for <span class="title"></span></h4>
+    <h4><i class="material-icons left">file_upload</i>Uploading files...</h4>
     <div class="progress">
       <div class="determinate" style="width: 0%"></div>
     </div>
-- 
GitLab