+ {% endif %}
+
+ {% block body %}{% endblock %}
+
+{% endblock %}
+
+{% block footer %}Example app v{{ app_version }} - all rights reserved.{% endblock %}
\ No newline at end of file
diff --git a/views/macros.njk b/views/macros.njk
new file mode 100644
index 0000000..6ba1583
--- /dev/null
+++ b/views/macros.njk
@@ -0,0 +1,136 @@
+{% macro message(type, content, raw=false, discreet=false) %}
+
+
+
+ {{ content|safe if raw else content }}
+
+
+{% endmacro %}
+
+{% macro messages(flash) %}
+ {% set flashed = flash() %}
+ {% set display = 0 %}
+
+ {% for type, bag in flashed %}
+ {% if bag|length %}
+ {% set display = 1 %}
+ {% endif %}
+ {% endfor %}
+
+ {% if display %}
+
+ {% for type, bag in flashed %}
+ {% for content in bag %}
+ {{ message(type, content) }}
+ {% endfor %}
+ {% endfor %}
+
+ {% endif %}
+{% endmacro %}
+
+{% macro csrf(getCSRFToken) %}
+
+{% endmacro %}
+
+{% macro field(_locals, type, name, value, placeholder, hint, validation_attributes='', extraData='') %}
+ {% set validation = _locals.validation() %}
+ {% set validation = validation[name] if validation[name] or null %}
+ {% set previousFormData = _locals.previousFormData() %}
+ {% set value = previousFormData[name] or value or validation.value or '' %}
+
+ {% if type == 'hidden' %}
+ {% if validation %}
+ {{ message('error', validation.message) }}
+ {% endif %}
+
+ {% else %}
+
+ {% if type == 'duration' %}
+
+ {% for f in extraData %}
+
+ {% if previousFormData[name] %}
+ {% set v = value[f] %}
+ {% else %}
+ {% set v = (value % 60) if f == 's' else (((value - value % 60) / 60 % 60) if f == 'm' else ((value - value % 3600) / 3600 if f == 'h')) %}
+ {% endif %}
+
+
+