From 21ccc2ec83319b47e8cf54cc28fc7f1ad5de4124 Mon Sep 17 00:00:00 2001
From: anonymous <anonymous>
Date: Wed, 24 Oct 2018 15:48:52 +0200
Subject: [PATCH] ODPSH-81: first draft for upload dataset design

---
 .../odsh/i18n/de/LC_MESSAGES/ckanext-odsh.mo  | Bin 1063 -> 1649 bytes
 .../odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po  |  39 ++
 ckanext/odsh/public/odsh.css                  | 143 ++++++
 ckanext/odsh/templates/macros/form.html       | 467 ++++++++++++++++++
 ckanext/odsh/templates/package/base.html      |  25 +
 .../templates/package/base_form_page.html     |   2 +-
 ckanext/odsh/templates/package/edit_base.html |  27 +
 ckanext/odsh/templates/package/edit_view.html |  25 +
 .../templates/package/new_package_form.html   |  34 ++
 ckanext/odsh/templates/package/new_view.html  |  36 ++
 .../snippets/package_basic_fields.html        | 118 +++--
 .../package/snippets/package_form.html        |  41 ++
 .../templates/package/snippets/stages.html    |  40 ++
 13 files changed, 934 insertions(+), 63 deletions(-)
 create mode 100644 ckanext/odsh/templates/macros/form.html
 create mode 100644 ckanext/odsh/templates/package/base.html
 create mode 100644 ckanext/odsh/templates/package/edit_base.html
 create mode 100644 ckanext/odsh/templates/package/edit_view.html
 create mode 100644 ckanext/odsh/templates/package/new_package_form.html
 create mode 100644 ckanext/odsh/templates/package/new_view.html
 create mode 100644 ckanext/odsh/templates/package/snippets/package_form.html
 create mode 100644 ckanext/odsh/templates/package/snippets/stages.html

diff --git a/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.mo b/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.mo
index 4d7b80af0180fb7b351aae69e49127f8953c2914..0d98aae1a0fcc34f9bb651cf5c0a88aa472f4a3a 100644
GIT binary patch
delta 839
zcmZ3^@sX$go)F7a1_lNOaRvqk83qQ1D<BRM?qOtL5Mp3p=w)PJ;AUW8Sis1@z{SA8
zu!fO=L6CugVLKy4?@6fmL#Vnpj0_BH3=9lEpz8iJGBEHkFfa%*F);8kFfhn5F)*+)
zFw`^XGC>S9W@2DqVPIgegVN4S3=F~y3=AGj3=E<S3=A<$3=EPC3=Bm~3=EtM3=BO?
z3=B*R3=Gql7#Q>z7#L<UF)(;BFfg28VqloS$iN`X%)r3Qz`(GC1)_fw3j>1~NFK_+
z&jOOKXJGgW6<}tCxJ;52;vfxHh(=>ph(kP~{8(17%NdGUK?X1|RI)NKFf%YPw6j8d
z+|A0sAi%)DFo~6cL4$#TVKG$S8CC`c4h9B>M^N>zSs55?>lqjr-m@|=I5RLX=z_w_
zF*!N4xL6@MKd-o?C^0jyq?o}mB}E}6u_UoLwS>VnuOzhy%!4sgi<65o3raHc^PnQd
z1&Jk@i8%_X6(y;8#R&0|#PnjQl9J4loKyz)qWsc{SIq5F!Di+q=B6^F73JqL<fT@W
zFyyBcXDB!qr6!i7D!4!`2aAD>Q7FhsOis<n&q+xwn#{#0%~O(@n_85Zm!8T{lD}Dn
zQHrVFB@twMVo8-kMrK}BY1-jE>8W`Po_T5cMY)L}*QVwvq-N%&rzWN5F*v0bCubC;
zW+s*9r6WZBi%L=vyx@||<c#ve+loK|0M{9kS(2KAP~@FhlA4}hl$ko&o!KMEFEJO%
zfU^8NhVs<RlGGvwxZ`v~3v%)kQy8lBob(i2^HPh_GgGY<0`hY*OER;q6+&~%Q*%nJ
j6&!PNQmqyA^z<h8F^h9YrDm2CC6?wgBxO!s%-jM1mV&>)

delta 255
zcmey!vz(*;o)F7a1_lNOE(Qh$83qQ191sTy?_pqI5Mp3p*vr7cz{bG9aDjn=L6Cug
z;W`5Y0}lfO!%GGR20jJ`hHnfE46Go`$iN`Uz`(%G$iSe-z`&r&$iU#mz`zi~$iOgx
zk%3`8BLf330|SErGuX}m20La322lnE22W-N24MyUhIlBym>FVVCzRjM%)nsFz`(GS
znSsHXfq~&MGXn#IV{&q8aj`;jeqM1&QDSCZN%7?Gj5d>tn4~t(WRhf>tic*6;*^@6
ZnU|-Kl3J_~m6};nlvtXZI{7VY3jiC)Cyf9A

diff --git a/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po b/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po
index a24a2df6..65175c4d 100644
--- a/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po
+++ b/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po
@@ -19,6 +19,45 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 2.3.4\n"
 
+msgid "odsh Create Dataset"
+msgstr "Datensatz-Upload"
+
+msgid "Enter title"
+msgstr "Titel eingeben"
+
+msgid "Enter description"
+msgstr "Beschreibung eingeben"
+
+msgid "Enter tags"
+msgstr "Stichwörter eingeben"
+
+msgid "Enter spatial extension"
+msgstr "Orte eingeben"
+
+msgid "Enter data"
+msgstr "Informationen eingeben"
+
+msgid "Add dataset"
+msgstr "Datensatz hinzufügen"
+
+msgid "next"
+msgstr "weiter"
+
+msgid "enter name"
+msgstr "Name eingeben"
+
+msgid "odsh tags placeholder"
+msgstr "z.B. Energie; Politik; Umwelt; Alle; ..."
+
+msgid "from"
+msgstr "von"
+
+msgid "to"
+msgstr "bis"
+
+msgid "timerange"
+msgstr "Zeitraum"
+
 msgid "Groups"
 msgstr "Kategorien"
 
diff --git a/ckanext/odsh/public/odsh.css b/ckanext/odsh/public/odsh.css
index 1c7d8a84..e65fc4f9 100644
--- a/ckanext/odsh/public/odsh.css
+++ b/ckanext/odsh/public/odsh.css
@@ -315,3 +315,146 @@ ul.dataset-resources {
     font-size: 15px;
     color: #003064 !important;
 }
+.control-required {
+    color: black;
+}
+
+label{
+    font-size: 16px;
+    font-weight: normal;
+}
+
+label:after {
+    content: "";
+}
+.controls input,
+.controls select,
+.controls ul.select2-choices,
+.controls textarea{
+    background-color:  #F6F7F9;
+    background-image: none;
+    -webkit-box-shadow: none;
+	-moz-box-shadow: none;
+    box-shadow: none;
+    border: 1px solid;
+    border-color: #77879f;
+    border-radius: 0;
+    font-size: 1em;
+    color:  #657592;
+    font-style: italic
+}
+
+.controls input[disabled]
+{
+    background-color:  #fdfdfd;
+    border-color: #e7e9ee;
+    color:  #e7e9ee;
+}
+
+.select2-default {
+    color:  #657592!important;
+}
+.select2-container-multi .select2-choices .select2-search-choice{
+    color:  #657592!important;
+}
+
+/* placeholders cannot be combined... */
+.controls input::-webkit-input-placeholder {
+    color:  #657592!important
+}
+
+.controls input::-webkit-input-placeholder {
+    color:  #657592!important
+}
+
+.controls input::-moz-placeholder {
+    color:  #657592!important
+}
+
+.controls input::-ms-placeholder {
+    color:  #657592!important
+}
+
+.controls input::placeholder {
+    color:  #657592!important
+}
+
+.controls textarea::-webkit-input-placeholder {
+    color:  #657592!important
+}
+
+.controls textarea::-webkit-input-placeholder {
+    color:  #657592!important
+}
+
+.controls textarea::-moz-placeholder {
+    color:  #657592!important
+}
+
+.controls textarea::-ms-placeholder {
+    color:  #657592!important
+}
+
+.controls textarea::placeholder {
+    color:  #657592!important
+}
+
+.btn-primary{
+    background-image: none;
+    background-color: #0089ca;
+    border: none;
+    border-radius: 0;
+    font-size:18px;
+    text-shadow: none;
+    font-weight: normal;
+    height: 40px;
+    padding-left: 28px;
+    padding-right: 28px;
+}
+
+.stages{
+    margin: -15px 0px 20px 0px
+}
+
+.stages li{
+    line-height: 20pt;
+    padding: 0;
+}
+
+/* simple removing content destroys layout */
+.stages li:before{
+    content:'';
+    background: none;
+    background-color: transparent;
+    width: 0px;
+}
+
+.stages li .highlight{
+    padding: 10px 10px;
+    font-size: 9pt;
+    line-height: 12pt;
+}
+
+.stages li.active .highlight {
+    color: #ffffff;
+    background: #bbc1cf;
+}
+
+.stages li.uncomplete .highlight{
+    color: #bbc1cf;
+}
+
+.toolbar .breadcrumb li:after {
+    content: "\f054";
+    font-family: FontAwesome;
+    padding: 0 0 0 5px;
+    color: darkgray;
+    font-size: 12pt;
+    transform: scale(1, 1.5);
+    display: inline-block;
+ -webkit-transform: scale(0.6, 0.9); /* Safari and Chrome */
+  -moz-transform: scale(1, 1.5); /* Firefox */
+  -ms-transform: scale(1, 1.5); /* IE 9+ */
+  -o-transform: scale(1, 1.5); /* Opera 
+}
+
diff --git a/ckanext/odsh/templates/macros/form.html b/ckanext/odsh/templates/macros/form.html
new file mode 100644
index 00000000..82812751
--- /dev/null
+++ b/ckanext/odsh/templates/macros/form.html
@@ -0,0 +1,467 @@
+{#
+Creates all the markup required for an input element. Handles matching labels to
+inputs, error messages and other useful elements.
+
+name - The name of the form parameter.
+id - The id to use on the input and label. Convention is to prefix with 'field-'.
+label - The human readable label.
+value - The value of the input.
+placeholder - Some placeholder text.
+type - The type of input eg. email, url, date (default: text).
+error - A list of error strings for the field or just true to highlight the field.
+classes - An array of classes to apply to the control-group.
+is_required - Boolean of whether this input is requred for the form to validate
+
+Examples:
+
+{% import 'macros/form.html' as form %}
+{{ form.input('title', label=_('Title'), value=data.title, error=errors.title) }}
+
+#}
+{% macro input(name, id='', label='', value='', placeholder='', type='text', error="", classes=[], attrs={},
+is_required=false) %}
+{%- set extra_html = caller() if caller -%}
+{%- set _type = 'text' if type=='date' and not value else type -%}
+{%- set onFocus = 'onfocus=(this.type=\'date\')' if type=='date' and not value else '' -%}
+
+{% call input_block(id or name, label, error, classes, extra_html=extra_html, is_required=is_required) %}
+<input id="{{ id or name }}" type="{{ _type }}" name="{{ name }}" value="{{ value | empty_and_escape }}" placeholder="{{ placeholder }}"
+    {{ onFocus }} {{ attributes(attrs) }} />
+{% endcall %}
+{% endmacro %}
+
+{#
+Builds a single checkbox input.
+
+name - The name of the form parameter.
+id - The id to use on the input and label. Convention is to prefix with 'field-'.
+label - The human readable label.
+value - The value of the input.
+checked - If true the checkbox will be checked
+error - An error string for the field or just true to highlight the field.
+classes - An array of classes to apply to the control-group.
+is_required - Boolean of whether this input is requred for the form to validate
+
+Example:
+
+{% import 'macros/form.html' as form %}
+{{ form.checkbox('remember', checked=true) }}
+
+#}
+{% macro checkbox(name, id='', label='', value='', checked=false, placeholder='', error="", classes=[], attrs={},
+is_required=false) %}
+{%- set extra_html = caller() if caller -%}
+<div class="control-group{{ " " ~ classes | join(" ") }}{% if error %} error{% endif %}">
+    <div class="controls">
+        <label class="checkbox" for="{{ id or name }}">
+            <input id="{{ id or name }}" type="checkbox" name="{{ name }}" value="{{ value | empty_and_escape }}"
+                {{ "checked " if checked }} {{ attributes(attrs) }} />
+            {{ label or name }}
+            {% if is_required %}{{ input_required() }}{% endif %}
+            {% if error and error is iterable %}<strong class="error-inline">{{ error|join(', ') }}</strong>{% endif %}
+        </label>
+        {{ extra_html }}
+    </div>
+</div>
+{% endmacro %}
+
+{#
+Creates all the markup required for an select element. Handles matching labels to
+inputs and error messages.
+
+A field should be a dict with a "value" key and an optional "text" key which
+will be displayed to the user. We use a dict to easily allow extension in
+future should extra options be required.
+
+name - The name of the form parameter.
+id - The id to use on the input and label. Convention is to prefix with 'field-'.
+label - The human readable label.
+options - A list/tuple of fields to be used as <options>.
+    selected - The value of the selected <option>.
+        error - A list of error strings for the field or just true to highlight the field.
+        classes - An array of classes to apply to the control-group.
+        is_required - Boolean of whether this input is requred for the form to validate
+
+        Examples:
+
+        {% import 'macros/form.html' as form %}
+        {{ form.select('year', label=_('Year'), options=[{'name':2010, 'value': 2010},{'name': 2011, 'value': 2011}],
+        selected=2011, error=errors.year) }}
+
+        #}
+        {% macro select(name, id='', label='', options='', selected='', error='', classes=[], attrs={},
+        is_required=false) %}
+        {% set classes = (classes|list) %}
+        {% do classes.append('control-select') %}
+
+        {%- set extra_html = caller() if caller -%}
+        {% call input_block(id or name, label or name, error, classes, extra_html=extra_html, is_required=is_required)
+        %}
+        <select id="{{ id or name }}" name="{{ name }}" {{ attributes(attrs) }}>
+            {% for option in options %}
+            <option value="{{ option.value }}" {% if option.value==selected %} selected{% endif %}>{{ option.text or
+                option.value }}</option>
+            {% endfor %}
+        </select>
+        {% endcall %}
+        {% endmacro %}
+
+        {#
+        Creates all the markup required for a Markdown textarea element. Handles
+        matching labels to inputs, selected item and error messages.
+
+        name - The name of the form parameter.
+        id - The id to use on the input and label. Convention is to prefix with 'field-'.
+        label - The human readable label.
+        value - The value of the input.
+        placeholder - Some placeholder text.
+        error - A list of error strings for the field or just true to highlight the field.
+        classes - An array of classes to apply to the control-group.
+        is_required - Boolean of whether this input is requred for the form to validate
+
+        Examples:
+
+        {% import 'macros/form.html' as form %}
+        {{ form.markdown('desc', id='field-description', label=_('Description'), value=data.desc, error=errors.desc) }}
+
+        #}
+        {% macro markdown(name, id='', label='', value='', placeholder='', error="", classes=[], attrs={},
+        is_required=false) %}
+        {% set classes = (classes|list) %}
+        {% do classes.append('control-full') %}
+        {% set markdown_tooltip = "
+        <pre><p>__Bold text__ or _italic text_</p><p># title<br>## secondary title<br>### etc</p><p>* list<br>* of<br>* items</p><p>http://auto.link.ed/</p></pre>
+        <p><b><a href='http://daringfireball.net/projects/markdown/syntax' target='_blank'>Full markdown syntax</a></b></p>
+        <p class='muted'><b>Please note:</b> HTML tags are stripped out for security reasons</p>" %}
+
+        {%- set extra_html = caller() if caller -%}
+        {% call input_block(id or name, label or name, error, classes, control_classes=["editor"],
+        extra_html=extra_html, is_required=is_required) %}
+        <textarea id="{{ id or name }}" name="{{ name }}" cols="20" rows="5" placeholder="{{ placeholder }}"
+            {{ attributes(attrs) }}>{{ value | empty_and_escape }}</textarea>
+        {% endcall %}
+        {% endmacro %}
+
+        {#
+        Creates all the markup required for a plain textarea element. Handles
+        matching labels to inputs, selected item and error messages.
+
+        name - The name of the form parameter.
+        id - The id to use on the input and label. Convention is to prefix with 'field-'.
+        label - The human readable label.
+        value - The value of the input.
+        placeholder - Some placeholder text.
+        error - A list of error strings for the field or just true to highlight the field.
+        classes - An array of classes to apply to the control-group.
+        is_required - Boolean of whether this input is requred for the form to validate
+
+        Examples:
+
+        {% import 'macros/form.html' as form %}
+        {{ form.textarea('desc', id='field-description', label=_('Description'), value=data.desc, error=errors.desc) }}
+
+        #}
+        {% macro textarea(name, id='', label='', value='', placeholder='', error="", classes=[], attrs={},
+        is_required=false, rows=5, cols=20) %}
+        {% set classes = (classes|list) %}
+        {% do classes.append('control-full') %}
+
+        {%- set extra_html = caller() if caller -%}
+        {% call input_block(id or name, label or name, error, classes, extra_html=extra_html, is_required=is_required)
+        %}
+        <textarea id="{{ id or name }}" name="{{ name }}" cols="{{ cols }}" rows="{{ rows }}" placeholder="{{ placeholder }}"
+            {{ attributes(attrs) }}>{{ value | empty_and_escape }}</textarea>
+        {% endcall %}
+        {% endmacro %}
+
+        {#
+        Creates all the markup required for an input element with a prefixed segment.
+        These are useful for showing url slugs and other fields where the input
+        information forms only part of the saved data.
+
+        name - The name of the form parameter.
+        id - The id to use on the input and label. Convention is to prefix with 'field-'.
+        label - The human readable label.
+        prepend - The text that will be prepended before the input.
+        value - The value of the input.
+        which will use the name key as the value.
+        placeholder - Some placeholder text.
+        error - A list of error strings for the field or just true to highlight the field.
+        classes - An array of classes to apply to the control-group.
+        is_required - Boolean of whether this input is requred for the form to validate
+
+        Examples:
+
+        {% import 'macros/form.html' as form %}
+        {{ form.prepend('slug', id='field-slug', prepend='/dataset/', label=_('Slug'), value=data.slug,
+        error=errors.slug) }}
+
+        #}
+        {% macro prepend(name, id='', label='', prepend='', value='', placeholder='', type='text', error="",
+        classes=[], attrs={}, is_required=false) %}
+        {# We manually append the error here as it needs to be inside the .input-prepend block #}
+        {% set classes = (classes|list) %}
+        {% do classes.append('error') if error %}
+        {%- set extra_html = caller() if caller -%}
+        {% call input_block(id or name, label or name, error='', classes=classes, extra_html=extra_html,
+        is_required=is_required) %}
+        <div class="input-prepend">
+            {% if prepend %}<span class="add-on">{{ prepend }}</span>{%- endif -%}
+            <input id="{{ id or name }}" type="{{ type }}" name="{{ name }}" value="{{ value | empty_and_escape }}"
+                placeholder="{{ placeholder }}" {{ attributes(attrs) }} />
+            {% if error and error is iterable %}<span class="error-block">{{ error|join(', ') }}</span>{% endif %}
+        </div>
+        {% endcall %}
+        {% endmacro %}
+
+        {#
+        Creates all the markup required for an custom key/value input. These are usually
+        used to let the user provide custom meta data. Each "field" has three inputs
+        one for the key, one for the value and a checkbox to remove it. So the arguments
+        for this macro are nearly all tuples containing values for the
+        (key, value, delete) fields respectively.
+
+        name - A tuple of names for the three fields.
+        id - An id string to be used for each input.
+        label - The human readable label for the main label.
+        values - A tuple of values for the (key, value, delete) fields. If delete
+        is truthy the checkbox will be checked.
+        placeholder - A tuple of placeholder text for the (key, value) fields.
+        error - A list of error strings for the field or just true to highlight the field.
+        classes - An array of classes to apply to the control-group.
+        is_required - Boolean of whether this input is requred for the form to validate
+
+        Examples:
+
+        {% import 'macros/form.html' as form %}
+        {{ form.custom(
+        names=('custom_key', 'custom_value', 'custom_deleted'),
+        id='field-custom',
+        label=_('Custom Field'),
+        values=(extra.key, extra.value, extra.deleted),
+        error=''
+        ) }}
+        #}
+        {% macro custom(names=(), id="", label="", values=(), placeholders=(), error="", classes=[], attrs={},
+        is_required=false, key_values=()) %}
+        {%- set classes = (classes|list) -%}
+        {%- set label_id = (id or names[0]) ~ "-key" -%}
+        {%- set extra_html = caller() if caller -%}
+        {%- do classes.append('control-custom') -%}
+
+        {% call input_block(label_id, label or name, error, classes, control_classes=["editor"], extra_html=extra_html,
+        is_required=is_required) %}
+        <div class="input-prepend" {{ attributes(attrs) }}>
+            <label for="{{ label_id }}" class="add-on">Key</label><input id="{{ id or names[0] }}-key" type="text" name="{{ names[0] }}"
+                value="{{ values[0] | empty_and_escape }}" placeholder="{{ placeholders[0] }}" />
+            <label for="{{ id or names[1] }}-value" class="add-on">Value</label><input id="{{ id or names[1] }}-value"
+                type="text" name="{{ names[1] }}" value="{{ values[1] | empty_and_escape }}" placeholder="{{ placeholders[1] }}" />
+            {% if values[0] or values[1] or error %}
+            <label class="checkbox" for="{{ id or names[2] }}-remove">
+                <input type="checkbox" id="{{ id or names[2] }}-remove" name="{{ names[2] }}" {% if values[2] %}
+                    checked{% endif %} /> <span>{{ _('Remove') }}</span>
+            </label>
+            {% endif %}
+        </div>
+        {% endcall %}
+        {% endmacro %}
+
+        {#
+        A generic input_block for providing the default markup for CKAN form elements.
+        It is expected to be called using a {% call %} block, the contents of which
+        will be inserted into the .controls element.
+
+        for - The id for the input that the label should match.
+        label - A human readable label.
+        error - A list of error strings for the field or just true.
+        classes - An array of custom classes for the outer element.
+        control_classes - An array of custom classes for the .control wrapper.
+        extra_html - An html string to be inserted after the errors eg. info text.
+        is_required - Boolean of whether this input is requred for the form to validate
+
+        Example:
+
+        {% import 'macros/form.html' as form %}
+        {% call form.input_block("field", "My Field") %}
+        <input id="field" type="text" name="{{ name }}" value="{{ value | empty_and_escape }}" />
+        {% endcall %}
+
+        #}
+        {% macro input_block(for, label, error="", classes=[], control_classes=[], extra_html="", is_required=false)
+        %}
+        <div class="control-group{{ " error" if error }}{{ " " ~ classes | join(' ') }}">
+            {%if label%}
+            <label class="control-label" for="{{ for }}">{{ label or _('Custom') }}: {% if is_required %}<span title="{{ _("This field is required") }}"
+                    class="control-required">*</span> {% endif %}</label>
+            {%endif%}
+            <div class="controls{{ " " ~ control_classes | join(' ') }}">
+                {{ caller() }}
+                {% if error and error is iterable %}<span class="error-block">{{ error|join(', ') }}</span>{% endif %}
+                {{ extra_html }}
+            </div>
+        </div>
+        {% endmacro %}
+
+        {#
+        Builds a list of errors for the current form.
+
+        errors - A dict of field/message pairs.
+        type - The alert-* class that should be applied (default: "error")
+        classes - A list of classes to apply to the wrapper (default: [])
+
+        Example:
+
+        {% import 'macros/form.html' as form %}
+        {{ form.errors(error_summary, type="warning") }}
+
+        #}
+        {% macro errors(errors={}, type="error", classes=[]) %}
+        {% if errors %}
+        <div class="error-explanation alert alert-{{ type }}{{ " " ~ classes | join(' ') }}">
+            <p>{{ _('The form contains invalid entries:') }}</p>
+            <ul>
+                {% for key, error in errors.items() %}
+                <li data-field-label="{{ key }}">{% if key %}{{ key }}: {% endif %}{{ error }}</li>
+                {% endfor %}
+            </ul>
+        </div>
+        {% endif %}
+        {% endmacro %}
+
+        {#
+        Renders an info box with a description. This will usually be used with in a
+        call block when creating an input element.
+
+        text - The text to include in the box.
+        inline - If true displays the info box inline with the input.
+        classes - A list of classes to add to the info box.
+
+        Example
+
+        {% import 'macros/form.html' as form %}
+        {% call form.input('name') %}
+        {{ form.info(_('My useful help text')) }}
+        {% endcall %}
+
+        #}
+        {% macro info(text='', inline=false, classes=[]) %}
+        {%- if text -%}
+        <div class="info-block{{ ' info-inline' if inline }}{{ " " ~ classes | join(' ') }}">
+            <i class="fa fa-info-circle"></i>
+            {{ text }}
+        </div>
+        {%- endif -%}
+        {% endmacro %}
+
+        {#
+        Builds a single hidden input.
+
+        name - name of the hidden input
+        value - value of the hidden input
+
+        Example
+        {% import 'macros/form.html' as form %}
+        {{ form.hidden('name', 'value') }}
+
+        #}
+        {% macro hidden(name, value) %}
+        <input type="hidden" name="{{ name }}" value="{{ value }}" />
+        {% endmacro %}
+
+        {#
+        Contructs hidden inputs for each name-value pair.
+
+        fields - [('name1', 'value1'), ('name2', 'value2'), ...]
+
+        Two parameter for excluding several names or name-value pairs.
+
+        except_names - list of names to be excluded
+        except - list of name-value pairs to be excluded
+
+
+        Example:
+        {% import 'macros/form.html' as form %}
+        {% form.hidden_from_list(fields=c.fields, except=[('topic', 'xyz')]) %}
+        {% form.hidden_from_list(fields=c.fields, except_names=['time_min', 'time_max']) %}
+        #}
+        {% macro hidden_from_list(fields, except_names=None, except=None) %}
+        {% set except_names = except_names or [] %}
+        {% set except = except or [] %}
+
+        {% for name, value in fields %}
+        {% if name and value and name not in except_names and (name, value) not in except %}
+        {{ hidden(name, value) }}
+        {% endif %}
+        {% endfor %}
+        {% endmacro %}
+
+        {#
+        Builds a space seperated list of html attributes from a dict of key/value pairs.
+        Generally only used internally by macros.
+
+        attrs - A dict of attribute/value pairs
+
+        Example
+
+        {% import 'macros/form.html' as form %}
+        {{ form.attributes({}) }}
+
+        #}
+        {%- macro attributes(attrs={}) -%}
+        {%- for key, value in attrs.items() -%}
+        {{ " " }}{{ key }}{% if value != "" %}="{{ value }}"{% endif %}
+        {%- endfor -%}
+        {%- endmacro -%}
+
+        {#
+        Outputs the "* Required field" message for the bottom of formss
+
+        Example
+        {% import 'macros/form.html' as form %}
+        {{ form.required_message() }}
+
+        #}
+        {% macro required_message() %}
+        <p class="control-required-message">
+            <span class="control-required">*</span> {{ _("Required field") }}
+        </p>
+        {% endmacro %}
+
+        {#
+        Builds a file upload for input
+
+        Example
+        {% import 'macros/form.html' as form %}
+        {{ form.image_upload(data, errors, is_upload_enabled=true) }}
+
+        #}
+        {% macro image_upload(data, errors, field_url='image_url', field_upload='image_upload',
+        field_clear='clear_upload',
+        is_url=false, is_upload=false, is_upload_enabled=false, placeholder=false,
+        url_label='', upload_label='', field_name='image_url') %}
+        {% set placeholder = placeholder if placeholder else _('http://example.com/my-image.jpg') %}
+        {% set url_label = url_label or _('Image URL') %}
+        {% set upload_label = upload_label or _('Image') %}
+
+        {% if is_upload_enabled %}
+        <div class="image-upload" data-module="image-upload" data-module-is_url="{{ 'true' if is_url else 'false' }}"
+            data-module-is_upload="{{ 'true' if is_upload else 'false' }}" data-module-field_url="{{ field_url }}"
+            data-module-field_upload="{{ field_upload }}" data-module-field_clear="{{ field_clear }}"
+            data-module-upload_label="{{ upload_label }}" data-module-field_name="{{ field_name }}">
+            {% endif %}
+
+            {{ input(field_url, label=url_label, id='field-image-url', placeholder=placeholder,
+            value=data.get(field_url), error=errors.get(field_url), classes=['control-full']) }}
+
+            {% if is_upload_enabled %}
+            {{ input(field_upload, label=upload_label, id='field-image-upload', type='file', placeholder='', value='',
+            error='', classes=['control-full']) }}
+            {% if is_upload %}
+            {{ checkbox(field_clear, label=_('Clear Upload'), id='field-clear-upload', value='true', error='',
+            classes=['control-full']) }}
+            {% endif %}
+            {% endif %}
+
+            {% if is_upload_enabled %}</div>{% endif %}
+
+        {% endmacro %}
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/base.html b/ckanext/odsh/templates/package/base.html
new file mode 100644
index 00000000..0d0920d5
--- /dev/null
+++ b/ckanext/odsh/templates/package/base.html
@@ -0,0 +1,25 @@
+{% extends "page.html" %}
+
+{% set pkg = c.pkg_dict or pkg_dict %}
+
+{% block breadcrumb_content_selected %} class="active"{% endblock %}
+
+{% block subtitle %}{{ _('Datasets') }}{% endblock %}
+
+{% block breadcrumb_content %}
+{% if pkg %}
+{% set dataset = h.dataset_display_name(pkg) %}
+{% if pkg.organization %}
+{% set organization = h.get_translated(pkg.organization, 'title') or pkg.organization.name %}
+<li>{% link_for _('Organizations'), controller='organization', action='index' %}</li>
+<li>{% link_for organization|truncate(30), controller='organization', action='read', id=pkg.organization.name %}</li>
+{% else %}
+<li>{% link_for _('Datasets'), controller='package', action='search' %}</li>
+{% endif %}
+<li {{ self.breadcrumb_content_selected() }}>{% link_for dataset|truncate(30), controller='package', action='read',
+    id=pkg.name %}</li>
+{% else %}
+<li>{% link_for _('Datasets'), controller='package', action='search' %}</li>
+<li class="active"><a href="">{{ _('Create Dataset') }}</a></li>
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/base_form_page.html b/ckanext/odsh/templates/package/base_form_page.html
index e4bb27d5..3e321e79 100644
--- a/ckanext/odsh/templates/package/base_form_page.html
+++ b/ckanext/odsh/templates/package/base_form_page.html
@@ -1,3 +1,3 @@
 {% ckan_extends %}
-{% block secondary_content %}
+{% block secondary%}
 {% endblock %}
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/edit_base.html b/ckanext/odsh/templates/package/edit_base.html
new file mode 100644
index 00000000..1ce1afcf
--- /dev/null
+++ b/ckanext/odsh/templates/package/edit_base.html
@@ -0,0 +1,27 @@
+{% extends 'package/base.html' %}
+
+{% set pkg = c.pkg_dict %}
+{% set pkg_dict = c.pkg_dict %}
+
+{% block breadcrumb_content_selected %}{% endblock %}
+
+{% block breadcrumb_content %}
+{% if pkg %}
+<li class="active">{% link_for _('Edit'), controller='package', action='edit', id=pkg.name %}</li>
+{% else %}
+<li class="active"><a href="">{{ _('odsh Create Dataset') }}</a></li>
+{% endif %}
+{% endblock %}
+
+{% block content_action %}
+{% link_for _('View dataset'), controller='package', action='read', id=pkg.name, class_='btn', icon='eye' %}
+{% endblock %}
+
+{% block content_primary_nav %}
+{{ h.build_nav_icon('dataset_edit', _('Edit metadata'), id=pkg.name) }}
+{{ h.build_nav_icon('dataset_resources', _('Resources'), id=pkg.name) }}
+{% endblock %}
+
+{% block secondary_content %}
+{% snippet 'package/snippets/info.html', pkg=pkg, hide_follow_button=true %}
+{% endblock %}
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/edit_view.html b/ckanext/odsh/templates/package/edit_view.html
new file mode 100644
index 00000000..4be46555
--- /dev/null
+++ b/ckanext/odsh/templates/package/edit_view.html
@@ -0,0 +1,25 @@
+{% extends "package/view_edit_base.html" %}
+
+{% block subtitle %}{{ _('Edit view') }} - {{ h.resource_display_name(c.resource) }}{% endblock %}
+{% block form_title %}{{ _('Edit view') }}{% endblock %}
+
+{% block breadcrumb_content %}
+{{ super() }}
+<li class="active"><a href="#">{{ _('Edit view') }}</a></li>
+{% endblock %}
+
+{% block content_primary_nav %}
+<li class="active"><a href="#"><i class="fa fa-pencil-square-o"></i> {{ _('Edit view') }}</a></li>
+{% endblock %}
+
+{% block form %}
+<form class="dataset-form dataset-resource-form form-horizontal" method="post" data-module="basic-form resource-form">
+    {% include 'package/snippets/view_form.html' %}
+    <div class="form-actions">
+        <button class="btn btn-danger pull-left" name="delete" value="Delete"> {{ _('Delete') }} </button>
+        <button class="btn {% if not h.resource_view_display_preview(data) %}hide{%endif%}" name="preview" value="True"
+            type="submit">{{ _('Preview') }}</button>
+        <button class="btn btn-primary" name="save" value="Save" type="submit">{{ _('Update') }}</button>
+    </div>
+</form>
+{% endblock %}
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/new_package_form.html b/ckanext/odsh/templates/package/new_package_form.html
new file mode 100644
index 00000000..42d66bfe
--- /dev/null
+++ b/ckanext/odsh/templates/package/new_package_form.html
@@ -0,0 +1,34 @@
+{% extends 'package/snippets/package_form.html' %}
+
+{% set form_style = c.form_style or c.action %}
+
+{% block stages %}
+{% if form_style != 'edit' %}
+<div class='search-form'>
+    <h2>{{ _('odsh Create Dataset') }}</h2>
+</div>
+{{ super() }}
+{% else %}
+
+{% endif %}
+{% endblock %}
+
+{% block save_button_text %}
+{% if form_style != 'edit' %}
+{{ _('next') }}
+{% else %}
+{{ _('Update Dataset') }}
+{% endif %}
+{% endblock %}
+
+{% block cancel_button %}
+{% if form_style != 'edit' %}
+{{ super() }}
+{% endif %}
+{% endblock %}
+
+{% block delete_button %}
+{% if form_style == 'edit' and h.check_access('package_delete', {'id': c.pkg_dict.id}) %}
+{{ super() }}
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/new_view.html b/ckanext/odsh/templates/package/new_view.html
new file mode 100644
index 00000000..9c95fd6b
--- /dev/null
+++ b/ckanext/odsh/templates/package/new_view.html
@@ -0,0 +1,36 @@
+{% extends "package/view_edit_base.html" %}
+
+{% block subtitle %}{{ _('Add view') }} - {{ h.resource_display_name(c.resource) }}{% endblock %}
+{% block form_title %}{{ _('Add view') }}{% endblock %}
+
+{% block breadcrumb_content %}
+{{ super() }}
+<li class="active"><a href="#">{{ _('Add view') }}</a></li>
+{% endblock %}
+
+{% block content_primary_nav %}
+<li class="active"><a href="#"><i class="fa fa-pencil-square-o"></i> {{ _('Add view') }}</a></li>
+{% endblock %}
+
+{% block form %}
+{% if resource_view.view_type == 'recline_view' and not datastore_available %}
+<p class="text-info">
+    <i class="fa fa-info-circle"></i>
+    {% trans %}
+    Data Explorer views may be slow and unreliable unless the DataStore extension is enabled. For more information,
+    please see the <a href='http://docs.ckan.org/en/latest/maintaining/data-viewer.html#viewing-structured-data-the-data-explorer'
+        target='_blank'>Data Explorer documentation</a>.
+    {% endtrans %}
+</p>
+{% endif %}
+
+<form class="dataset-form dataset-resource-form form-horizontal" method="post" data-module="basic-form resource-form">
+    {% include 'package/snippets/view_form.html' %}
+    <div class="form-actions">
+        <button class="btn {% if not h.resource_view_display_preview(data) %}hide{%endif%}" name="preview" value="True"
+            type="submit">{{ _('Preview') }}</button>
+        <button class="btn btn-primary" name="save" value="Save" type="submit">{% block save_button_text %}{{ _('Add')
+            }}{% endblock %}</button>
+    </div>
+</form>
+{% endblock %}
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/snippets/package_basic_fields.html b/ckanext/odsh/templates/package/snippets/package_basic_fields.html
index 000ccf97..45b0f2be 100644
--- a/ckanext/odsh/templates/package/snippets/package_basic_fields.html
+++ b/ckanext/odsh/templates/package/snippets/package_basic_fields.html
@@ -5,7 +5,8 @@
 <!-- field title -->
 {% block package_basic_fields_title %}
 {{ form.input('title', id='field-title', label=_('Title'), value=data.title,
-error=errors.title, classes=['control-full', 'control-large'], attrs={'data-module': 'slug-preview-target'}) }}
+error=errors.title, classes=['control-full', 'control-large'], attrs={'data-module': 'slug-preview-target'},
+is_required=true,placeholder=_('Enter title')) }}
 {% endblock %}
 
 {% block package_basic_fields_url %}
@@ -23,36 +24,42 @@ error=errors.title, classes=['control-full', 'control-large'], attrs={'data-modu
     <!-- field notes -->
     {% block package_basic_fields_description %}
     {{ form.markdown('notes', id='field-notes', label=_('Description'), value=data.notes,
-    error=errors.notes, is_required=true) }}
+    error=errors.notes, is_required=true, placeholder=_('Enter description')) }}
     {% endblock %}
 
 
     <!-- field license -->
-    {% block package_basic_fields_license %}
-    <div class="control-group">
-        {% set error = errors.license_id %}
-        <label class="control-label" for="field-license">
-            <span title="{{ _("This field is required") }}" class="control-required">*</span>
-            {{ _("License") }}
-        </label>
-        <div class="controls">
-            <select id="field-license" name="license_id">
-                {% set existing_license_id = data.get('license_id') %}
-                {% for license_id, license_desc in h.license_options(existing_license_id) %}
-                <option value="{{ license_id }}" {% if existing_license_id==license_id %}selected="selected" {% endif
-                    %}>{{ license_desc }}</option>
-                {% endfor %}
-            </select>
-            {% if error %}<span class="error-block">{{ error }}</span>{% endif %}
+    <label class="control-label" for="field-license">
+        {{ _("License") }}:
+        <span title="{{ _("This field is required") }}" class="control-required">*</span>
+    </label>
+    <div class='row'>
+        <div class='span4'>
+            {% block package_basic_fields_license %}
+            <div class="control-group">
+                {% set error = errors.license_id %}
+                <div class="controls">
+                    <select id="field-license" name="license_id" class="span4">
+                        {% set existing_license_id = data.get('license_id') %}
+                        {% for license_id, license_desc in h.license_options(existing_license_id) %}
+                        <option value="{{ license_id }}" {% if existing_license_id==license_id %}selected="selected" {%
+                            endif %}>{{ license_desc }}</option>
+                        {% endfor %}
+                    </select>
+                    {% if error %}<span class="error-block">{{ error }}</span>{% endif %}
+                </div>
+            </div>
+        </div>
+        <div class='span1'></div>
+        <div class='span4'>
+            <!-- field Namensnennung -->
+            {{ form.input('access_constraints', id='field-licence-name', value=data.access_constraints,
+            error=errors.access_constraints,
+            classes=['control-full'],type='text',is_required=true,attrs={'disabled':true,
+            'data-module':"odsh_form", 'data-module-licensetoggle':'true' }, placeholder=_('enter name')) }}
         </div>
     </div>
 
-    <!-- field Namensnennung -->
-    {% set access_constraints_label='Text für Namensnennung'%}
-    {{ form.input('access_constraints', id='field-licence-name', label=access_constraints_label,
-    value=data.access_constraints,
-    error=errors.access_constraints, classes=['control-full'],type='text',is_required=true,attrs={'disabled':true,
-    'data-module':"odsh_form", 'data-module-licensetoggle':'true' }) }}
     {% endblock %}
 
     <!-- field publish date -->
@@ -64,32 +71,6 @@ error=errors.title, classes=['control-full', 'control-large'], attrs={'data-modu
     value=publish_date_value,
     error=errors.publish_date, classes=['control-full'],type='date',is_required=true) }}
 
-    <!-- field groups -->
-    <div class="control-group">
-        {% set groups_label='Kategorien'%}
-        {% set multiselect_nonSelectedText='keine' %}
-        {% set multiselect_allSelectedText='alle' %}
-        {% set multiselect_nSelectedText='gewählt' %}
-        {% set spatial_extension_label='räumliche Ausdehnung'%}
-        <!-- {% set error = errors.groups %} -->
-        <label for="field-groups" class="control-label">
-            <span title="{{ _("This field is required") }}" class="control-required">*</span>
-            {{ groups_label }}
-        </label>
-        <div class="controls">
-            {% set existing_groups = data.get('groups') %}
-            <select id='field-groups' name="groups" multiple="multiple" data-module="odsh_form" data-module-multiselect='true'
-                data-module-nonSelectedText="{{multiselect_nonSelectedText}}" data-module-allSelectedText="{{multiselect_allSelectedText}}"
-                data-module-nSelectedText="{{multiselect_nSelectedText}}">
-                {% for option in h.groups_available()%}
-                <option value={{option.id}} {% if h.odsh_group_id_selected(data.groups,option['id']) %}selected="selected"
-                    {% endif %}>
-                    {{ option['display_name'] }}</option>
-                {% endfor %}
-            </select>
-            <!-- {% if error %}<span class="error-block">{{ error}}</span>{% endif %} -->
-        </div>
-    </div>
 
     <!-- field tags -->
     {% block package_basic_fields_tags %}
@@ -97,7 +78,7 @@ error=errors.title, classes=['control-full', 'control-large'], attrs={'data-modu
     '/api/2/util/tag/autocomplete?incomplete=?'} %}
     {{ form.input('tag_string', id='field-tags', label='Schlagwörter', value=data.tag_string, error=errors.tags,
     classes=['control-full'], attrs=tag_attrs,
-    is_required=true) }}
+    is_required=true, placeholder=_('odsh tags placeholder')) }}
     {% endblock %}
     {% block package_basic_fields_org %}
     {# if we have a default group then this wants remembering #}
@@ -136,21 +117,34 @@ error=errors.title, classes=['control-full', 'control-large'], attrs={'data-modu
     <!-- field spatial_extension -->
     {{ form.input('spatial_extension', id='field-spatial-extension', label=spatial_extension_label,
     value=data.spatial_extension,
-    error=errors.spatial_extension, classes=['control-full'],type='text',is_required=true) }}
+    error=errors.spatial_extension, classes=['control-full'],type='text',is_required=true,
+    placeholder=_('Enter spatial extension')) }}
 
-    <!-- field temporal_start -->
-    {% set temporal_start_label=_('odsh_temporal_start_label') %}
-    {{ form.input('temporal_start', id='field-temporal-start', label=temporal_start_label, value=data.temporal_start,
-    error=errors.temporal_start, classes=['control-full'],type='date',is_required=true) }}
-
-    <!-- field temporal_end -->
-    {% set temporal_end_label='Ende des Zeitraumes' %}
-    {{ form.input('temporal_end', id='field-temporal-end', label=temporal_end_label, value=data.temporal_end,
-    error=errors.temporal_end, classes=['control-full'],type='date',is_required=true) }}
+    <div class='row'>
+        <label for="start-end" class="control-label">{{ _('timerange') }}:
+            <span title="{{ _("This field is required") }}" class="control-required">*</span>
+        </label>
+        <div id='start-end' class='span5'>
+            <!-- field temporal_start -->
+            {% set temporal_start_label=_('odsh_temporal_start_label') %}
+            {{ form.input('temporal_start', id='field-temporal-start', value=data.temporal_start,
+            error=errors.temporal_start, classes=['control-full'],type='date',is_required=true,placeholder=_('from'))
+            }}
+        </div>
+        <div class='span1'></div>
+        <div class='span5'>
+            <!-- field temporal_end -->
+            {% set temporal_end_label='Ende des Zeitraumes' %}
+            {{ form.input('temporal_end', id='field-temporal-end', value=data.temporal_end,
+            error=errors.temporal_end, classes=['control-full'],type='date',is_required=true, placeholder=_('to')) }}
+        </div>
 
+    </div>
     <!-- field private -->
     <div class="control-group">
-        <label for="field-private" class="control-label">{{ _('Visibility') }}</label>
+        <label for="field-private" class="control-label">{{ _('Visibility') }}:
+            <span title="{{ _("This field is required") }}" class="control-required">*</span>
+        </label>
         <div class="controls">
             <select id="field-private" name="private">
                 {% for option in [('True', _('Private')), ('False', _('Public'))] %}
diff --git a/ckanext/odsh/templates/package/snippets/package_form.html b/ckanext/odsh/templates/package/snippets/package_form.html
new file mode 100644
index 00000000..c5e56718
--- /dev/null
+++ b/ckanext/odsh/templates/package/snippets/package_form.html
@@ -0,0 +1,41 @@
+{% import 'macros/form.html' as form %}
+{% set action = c.form_action or '' %}
+
+{# This provides a full page that renders a form for adding a dataset. It can
+then itself be extended to add/remove blocks of functionality. #}
+<form id="dataset-edit" class="dataset-form" method="post" action="{{ action }}" data-module="basic-form" novalidate>
+    {% block stages %}
+    {{ h.snippet('package/snippets/stages.html', stages=stage) }}
+    {% endblock %}
+
+    <input type="hidden" name="_ckan_phase" value="dataset_new_1" />
+    {# pkg_name used in 3 stage edit #}
+    <input type="hidden" name="pkg_name" value="{{ data.id }}" />
+    {% block errors %}{{ form.errors(error_summary) }}{% endblock %}
+
+    {% block basic_fields %}
+    {% snippet 'package/snippets/package_basic_fields.html', data=data, errors=errors, licenses=c.licenses,
+    groups_available=c.groups_available %}
+    {% endblock %}
+
+    {% block metadata_fields %}
+    {% snippet 'package/snippets/package_metadata_fields.html', data=data, errors=errors %}
+    {% endblock %}
+
+    {% block form_actions %}
+    <div class="form-actions">
+        {% block delete_button %}
+        {% if h.check_access('package_delete', {'id': data.id}) and not data.state == 'deleted' %}
+        <a class="btn btn-danger pull-left" href="{% url_for controller='package', action='delete', id=data.id %}"
+            data-module="confirm-action" data-module-content="{{ _('Are you sure you want to delete this dataset?') }}">{%
+            block delete_button_text %}{{ _('Delete') }}{% endblock %}</a>
+        {% endif %}
+        {% endblock %}
+        {% block save_button %}
+        <button class="btn btn-primary" type="submit" name="save">{% block save_button_text %}{{ _('Next: Add Data')
+            }}{%
+            endblock %}</button>
+        {% endblock %}
+    </div>
+    {% endblock %}
+</form>
\ No newline at end of file
diff --git a/ckanext/odsh/templates/package/snippets/stages.html b/ckanext/odsh/templates/package/snippets/stages.html
new file mode 100644
index 00000000..eb13f8bd
--- /dev/null
+++ b/ckanext/odsh/templates/package/snippets/stages.html
@@ -0,0 +1,40 @@
+{#
+Inserts a stepped progress indicator for the new package form. Each stage can
+have one of three states, "uncomplete", "complete" and "active".
+
+stages - A list of states for each of the three stages. Missing stages default
+to "uncomplete".
+
+Example:
+
+{% snippet 'package/snippets/stages.html', stages=['active'] %}
+{% snippet 'package/snippets/stages.html', stages=['complete', 'active'] %}
+{% snippet 'package/snippets/stages.html', stages=['active', 'complete'] %}
+
+#}
+{% set s1 = stages[0] or 'active' %}
+{% set s2 = stages[1] or 'uncomplete' %}
+{% if s1 != 'uncomplete' %}{% set class = 'stage-1' %}{% endif %}
+{% if s2 != 'uncomplete' %}{% set class = 'stage-2' %}{% endif %}
+
+<ol class="stages {{ class }}">
+    <li class="first {{ s1 }}">
+        {% if s1 != 'complete' %}
+        <span class="highlight">{{ _('Enter data') }}</span>
+        {% else %}
+        <button class="highlight" name="save" value="go-dataset" type="submit">{{ _('Enter data') }}</button>
+        {% endif %}
+    </li>
+    <li class="last {{ s2 }}">
+        {% if s2 != 'complete' %}
+        <span class="highlight">{{ _('Add dataset') }}</span>
+        {% else %}
+        {% if s1 == 'active' %}
+        {# stage 1 #}
+        <button class="highlight" name="save" value="go-resources" type="submit">{{ _('Add dataset') }}</button>
+        {% else %}
+        {% link_for _('Add dataset'), controller='package', action='new', class_="highlight" %}
+        {% endif %}
+        {% endif %}
+    </li>
+</ol>
\ No newline at end of file
-- 
GitLab