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