Merge pull request #2481 / [mod] template preferences: split into elements

HINT: this patch has no functional change / it is the preparation for following changes and bugfixes

Over the years, the preferences template became an unmanageable beast. To make the source code more readable the monolith is splitted into elements. The splitting into elements also has the advantage that a new template can make use of them.

The reversed checkbox is a quirk that is only used in the prefereces and must be eliminated in the long term. For this the macro 'checkbox_onoff_reversed' was added to the preferences.html template. The 'checkbox' macro is also a quirk of the preferences.html we don't want to use in other templates (it is an input-checkbox in a HTML form that was misused for status display).
This commit is contained in:
Markus Heiser 2023-06-02 19:55:43 +02:00 committed by GitHub
commit 1541f8660e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 645 additions and 449 deletions

View file

@ -60,6 +60,11 @@
padding: 0; padding: 0;
} }
.leaflet-container img.leaflet-tile {
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
mix-blend-mode: plus-lighter;
}
.leaflet-container.leaflet-touch-zoom { .leaflet-container.leaflet-touch-zoom {
-ms-touch-action: pan-x pan-y; -ms-touch-action: pan-x pan-y;
touch-action: pan-x pan-y; touch-action: pan-x pan-y;
@ -423,8 +428,11 @@ svg.leaflet-image-layer.leaflet-interactive path {
.leaflet-control-attribution a:focus { .leaflet-control-attribution a:focus {
text-decoration: underline; text-decoration: underline;
} }
.leaflet-control-attribution svg { .leaflet-attribution-flag {
display: inline !important; display: inline !important;
vertical-align: baseline !important;
width: 1em;
height: 0.6669em;
} }
.leaflet-left .leaflet-control-scale { .leaflet-left .leaflet-control-scale {
margin-left: 5px; margin-left: 5px;
@ -438,12 +446,10 @@ svg.leaflet-image-layer.leaflet-interactive path {
line-height: 1.1; line-height: 1.1;
padding: 2px 5px 1px; padding: 2px 5px 1px;
white-space: nowrap; white-space: nowrap;
overflow: hidden;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
background: rgba(255, 255, 255, 0.8);
background: #fff; text-shadow: 1px 1px #fff;
background: rgba(255, 255, 255, 0.5);
} }
.leaflet-control-scale-line:not(:first-child) { .leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777; border-top: 2px solid #777;
@ -537,8 +543,6 @@ svg.leaflet-image-layer.leaflet-interactive path {
} }
.leaflet-popup-scrolled { .leaflet-popup-scrolled {
overflow: auto; overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
} }
.leaflet-oldie .leaflet-popup-content-wrapper { .leaflet-oldie .leaflet-popup-content-wrapper {
@ -647,11 +651,11 @@ svg.leaflet-image-layer.leaflet-interactive path {
} }
/* Printing */ /* Printing */
@media print { @media print {
/* Prevent printers from removing background-images of controls. */ /* Prevent printers from removing background-images of controls. */
.leaflet-control { .leaflet-control {
-webkit-print-color-adjust: exact; -webkit-print-color-adjust: exact;
color-adjust: exact; print-color-adjust: exact;
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"file":"searxng.head.min.js","sources":["../src/js/head/00_init.js"],"sourcesContent":["/* SPDX-License-Identifier: AGPL-3.0-or-later */\n(function (w, d) {\n 'use strict';\n\n // add data- properties\n var script = d.currentScript || (function () {\n var scripts = d.getElementsByTagName('script');\n return scripts[scripts.length - 1];\n })();\n\n w.searxng = {\n settings: JSON.parse(atob(script.getAttribute('client_settings')))\n };\n\n // update the css\n var hmtlElement = d.getElementsByTagName(\"html\")[0];\n hmtlElement.classList.remove('no-js');\n hmtlElement.classList.add('js');\n\n})(window, document);\n"],"names":["w","d","script","currentScript","scripts","getElementsByTagName","length","searxng","settings","JSON","parse","atob","getAttribute","hmtlElement","classList","remove","add","window","document"],"mappings":"CACA,SAAWA,EAAGC,gBAIZ,IAAIC,EAASD,EAAEE,eAAkB,WAC/B,IAAIC,EAAUH,EAAEI,qBAAqB,UACrC,OAAOD,EAAQA,EAAQE,OAAS,GAFD,GAKjCN,EAAEO,QAAU,CACVC,SAAUC,KAAKC,MAAMC,KAAKT,EAAOU,aAAa,sBAIhD,IAAIC,EAAcZ,EAAEI,qBAAqB,QAAQ,GACjDQ,EAAYC,UAAUC,OAAO,SAC7BF,EAAYC,UAAUE,IAAI,OAhB5B,CAkBGC,OAAQC"} {"version":3,"file":"searxng.head.min.js","sources":["../src/js/head/00_init.js"],"sourcesContent":["/* SPDX-License-Identifier: AGPL-3.0-or-later */\n(function (w, d) {\n 'use strict';\n\n // add data- properties\n var script = d.currentScript || (function () {\n var scripts = d.getElementsByTagName('script');\n return scripts[scripts.length - 1];\n })();\n\n w.searxng = {\n settings: JSON.parse(atob(script.getAttribute('client_settings')))\n };\n\n // update the css\n var hmtlElement = d.getElementsByTagName(\"html\")[0];\n hmtlElement.classList.remove('no-js');\n hmtlElement.classList.add('js');\n\n})(window, document);\n"],"names":["w","d","script","currentScript","scripts","getElementsByTagName","length","searxng","settings","JSON","parse","atob","getAttribute","hmtlElement","classList","remove","add","window","document"],"mappings":"CACA,SAAWA,EAAGC,GACZ,aAGA,IAAIC,EAASD,EAAEE,eAAkB,WAC/B,IAAIC,EAAUH,EAAEI,qBAAqB,QAAQ,EAC7C,OAAOD,EAAQA,EAAQE,OAAS,EACjC,EAAE,EAEHN,EAAEO,QAAU,CACVC,SAAUC,KAAKC,MAAMC,KAAKT,EAAOU,aAAa,iBAAiB,CAAC,CAAC,CACnE,EAGA,IAAIC,EAAcZ,EAAEI,qBAAqB,MAAM,EAAE,GACjDQ,EAAYC,UAAUC,OAAO,OAAO,EACpCF,EAAYC,UAAUE,IAAI,IAAI,CAE/B,GAAEC,OAAQC,QAAQ"}

File diff suppressed because one or more lines are too long

View file

@ -428,7 +428,7 @@ reversed-checkbox displays unchecked checkedboxes as checked, and vice versa.
see https://github.com/searxng/searxng/blob/3408d061aab9abc6168fec9bbc6deab71b236dac/searx/templates/simple/preferences.html#L313 see https://github.com/searxng/searxng/blob/3408d061aab9abc6168fec9bbc6deab71b236dac/searx/templates/simple/preferences.html#L313
*/ */
input.checkbox-onoff[type="checkbox"], input.checkbox-onoff[type="checkbox"],
.reversed-checkbox input.checkbox-onoff[type="checkbox"]:checked { input.checkbox-onoff.reversed-checkbox[type="checkbox"]:checked {
background: var(--color-toolkit-checkbox-onoff-off-background); background: var(--color-toolkit-checkbox-onoff-off-background);
&::before { &::before {
@ -440,7 +440,7 @@ input.checkbox-onoff[type="checkbox"],
} }
input.checkbox-onoff[type="checkbox"]:checked, input.checkbox-onoff[type="checkbox"]:checked,
.reversed-checkbox input.checkbox-onoff[type="checkbox"] { input.checkbox-onoff.reversed-checkbox[type="checkbox"] {
background: var(--color-toolkit-checkbox-onoff-on-background); background: var(--color-toolkit-checkbox-onoff-on-background);
&::before { &::before {

View file

@ -52,33 +52,12 @@
</article> </article>
{%- endmacro -%} {%- endmacro -%}
<!-- --> <!-- input checkbox, on/off slider user can tap-->
{%- macro tabs_open() -%}
<div class="tabs" role="tablist">
{%- endmacro -%}
{%- macro tab_header(name, id, label, checked) -%}
<input type="radio" name="{{ name }}" id="tab-{{ id }}" {% if checked is sameas true %}checked="checked"{% endif %} />
<label id="tab-label-{{ label }}" for="tab-{{ id }}" role="tab" aria-controls="tab-content-{{ id }}">{{ label }}</label>
<section id="tab-content-{{ id }}" role="tabpanel" aria-labelledby="tab-label-{{ label }}" aria-hidden="false">
{%- endmacro -%}
{%- macro tab_footer() -%}
</section>
{%- endmacro -%}
{%- macro tabs_close() -%}
</div>
{%- endmacro -%}
{%- macro checkbox_onoff(name, checked) -%} {%- macro checkbox_onoff(name, checked) -%}
<input type="checkbox" name="{{ name }}" id="{{ name }}" value="None" class="checkbox-onoff" {% if checked %}checked{% endif %} /> <input type="checkbox" {{- ' ' -}}
{%- endmacro -%} name="{{ name }}" {{- ' ' -}}
id="{{ name }}" {{- ' ' -}}
{%- macro checkbox(name, checked, disabled) -%} aria-labelledby="pref_{{ name }}"{{- ' ' -}}
{%- if checked == '?' -%} class="checkbox-onoff"{{- ' ' -}}
{{- icon_small('warning') -}} {%- if checked -%} checked{%- endif -%}/>
{%- else -%}
<input type="checkbox"{% if name %} name="{{ name }}"{% endif %} value="None"{% if checked %} checked{% endif %}{% if disabled %} disabled{% endif %} />
{%- endif -%}
{%- endmacro -%} {%- endmacro -%}

View file

@ -1,5 +1,7 @@
{% set body_class = "page_with_header" %} {%- set body_class = "page_with_header" -%}
{% extends "simple/base.html" %} {%- extends "simple/base.html" -%}
{% block header %} {%- block header -%}
<a href="{{ url_for('index') }}"><img class="logo" src="{{ url_for('static', filename='img/searxng.png') }}" alt="SearXNG"></a> <a href="{{ url_for('index') }}">{{- '' -}}
{% endblock %} <img class="logo" src="{{ url_for('static', filename='img/searxng.png') }}" alt="SearXNG">{{- '' -}}
</a>{{- '' -}}
{%- endblock -%}

View file

@ -1,7 +1,40 @@
{% from 'simple/macros.html' import tabs_open, tabs_close, tab_header, tab_footer, checkbox_onoff, checkbox %} {%- from 'simple/icons.html' import icon_big -%}
{% from 'simple/icons.html' import icon_big %} {%- extends "simple/page_with_header.html" -%}
{% extends "simple/page_with_header.html" %} {%- macro tabs_open() -%}
<div class="tabs" role="tablist">
{%- endmacro -%}
{%- macro tab_header(name, id, label, checked) -%}
<input type="radio" name="{{ name }}" id="tab-{{ id }}" {% if checked is sameas true %}checked="checked"{% endif %} />
<label id="tab-label-{{ id }}" for="tab-{{ id }}" role="tab" aria-controls="tab-content-{{ id }}">{{ label }}</label>
<section id="tab-content-{{ id }}" role="tabpanel" aria-labelledby="tab-label-{{ id }}" aria-hidden="false">
{%- endmacro -%}
{%- macro tab_footer() -%}
</section>
{%- endmacro -%}
{%- macro tabs_close() -%}
</div>
{%- endmacro -%}
{%- macro checkbox(name, checked, disabled) -%}
{%- if checked == '?' -%}
{{- icon_small('warning') -}}
{%- else -%}
<input type="checkbox" {%- if name %} name="{{ name }}" {%- endif %} value="None" {%- if checked %} checked {%- endif -%}{%- if disabled %} disabled {%- endif -%}/>
{%- endif -%}
{%- endmacro -%}
{%- macro checkbox_onoff_reversed(name, checked) -%}
<input type="checkbox" {{- ' ' -}}
name="{{ name }}" {{- ' ' -}}
id="{{ name }}" {{- ' ' -}}
aria-labelledby="pref_{{ name }}"{{- ' ' -}}
class="checkbox-onoff reversed-checkbox"{{- ' ' -}}
{%- if checked -%} checked{%- endif -%}/>
{%- endmacro -%}
{%- macro plugin_preferences(section) -%} {%- macro plugin_preferences(section) -%}
{%- for plugin in plugins -%} {%- for plugin in plugins -%}
@ -9,7 +42,7 @@
<fieldset>{{- '' -}} <fieldset>{{- '' -}}
<legend>{{ _(plugin.name) }}</legend>{{- '' -}} <legend>{{ _(plugin.name) }}</legend>{{- '' -}}
<div class="value"> <div class="value">
{{- checkbox_onoff('plugin_' + plugin.id, plugin.id not in allowed_plugins) -}} {{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins) -}}
</div>{{- '' -}} </div>{{- '' -}}
<div class="description"> <div class="description">
{{- _(plugin.description) -}} {{- _(plugin.description) -}}
@ -19,427 +52,190 @@
{%- endfor -%} {%- endfor -%}
{%- endmacro -%} {%- endmacro -%}
{% macro engine_about(search_engine) -%} {%- macro engine_about(search_engine) -%}
{% if search_engine.about is defined %} {%- if search_engine.about is defined -%}
{% set about = search_engine.about %} {%- set about = search_engine.about -%}
<div class="engine-tooltip" role="tooltip">{{- "" -}} <div class="engine-tooltip" role="tooltip">{{- '' -}}
<p class="engine-description"></p>{{- "" -}} <p class="engine-description"></p>{{- '' -}}
<p><a href="{{about.website}}" rel="noreferrer">{{about.website}}</a></p> <p><a href="{{about.website}}" rel="noreferrer">{{about.website}}</a></p>{{- '' -}}
{%- if about.wikidata_id -%}<p><a href="https://www.wikidata.org/wiki/{{about.wikidata_id}}" rel="noreferrer">wikidata.org/wiki/{{about.wikidata_id}}</a></p>{%- endif -%} {%- if about.wikidata_id -%}
{%- if search_engine.enable_http %}<p>{{ icon_big('exclamation-sign', 'No HTTPS') }}{{ _('No HTTPS')}}</p>{% endif -%} <p><a href="https://www.wikidata.org/wiki/{{about.wikidata_id}}" rel="noreferrer">wikidata.org/wiki/{{about.wikidata_id}}</a></p>
{%- if reliabilities.get(search_engine.name, {}).errors or reliabilities.get(search_engine.name, {}).checker -%}
<a href="{{ url_for('stats', engine=search_engine.name|e) }}" title="{{ _('View error logs and submit a bug report') }}">
{{ _('View error logs and submit a bug report') -}}
</a>
{%- endif -%} {%- endif -%}
<p><span class="right">{{ _("!bang for this engine") }}</span>{% for bang in [search_engine.name] + [search_engine.shortcut] %}<span class="bang"> {{ '!' + bang.replace(' ', '_') }}</span>{% endfor %}</p> {%- if search_engine.enable_http -%}
<p><span class="right">{{ _("!bang for its categories") }}</span>{% for bang in search_engine.categories %}<span class="bang"> {{ '!' + bang.replace(' ', '_') }}</span>{% endfor %}</p> <p>{{- icon_big('exclamation-sign', 'No HTTPS') -}}{{- _('No HTTPS')-}}</p>
</div> {% endif -%}
{%- if reliabilities.get(search_engine.name, {}).errors or reliabilities.get(search_engine.name, {}).checker -%}
<a href="{{ url_for('stats', engine=search_engine.name|e) }}" {{- ' ' -}}
title="{{ _('View error logs and submit a bug report') }}">
{{- _('View error logs and submit a bug report') -}}
</a>
{%- endif -%}
<p>{{- '' -}}
<span class="right">{{ _("!bang for this engine") }}</span>{{- '' -}}
{%- for bang in [search_engine.name] + [search_engine.shortcut] -%}
<span class="bang"> {{ '!' + bang.replace(' ', '_') }}</span>
{%- endfor -%}
</p>{{- '' -}}
<p>{{- '' -}}
<span class="right">{{ _("!bang for its categories") }}</span>
{%- for bang in search_engine.categories -%}
<span class="bang">{{ '!' + bang.replace(' ', '_') }}</span>
{%- endfor -%}
</p>{{- '' -}}
</div>
{%- endif -%} {%- endif -%}
{%- endmacro %} {%- endmacro -%}
{%- macro engine_time(engine_name) -%} {%- macro engine_time(engine_name) -%}
<td class="{{ label }}">{{- "" -}} <td class="{{ label }}">{{- '' -}}
{%- if stats[engine_name].time != None -%} {%- if stats[engine_name].time != None -%}
<span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- "" -}} <span class="stacked-bar-chart-value">{{- stats[engine_name].time -}}</span>{{- '' -}}
<span class="stacked-bar-chart" aria-labelledby="{{engine_name}}_chart" aria-hidden="true"> <span class="stacked-bar-chart" aria-labelledby="{{engine_name}}_chart" aria-hidden="true">
{%- if max_rate95 is not none and max_rate95 > 0 -%} {%- if max_rate95 is not none and max_rate95 > 0 -%}
<div class="stacked-bar-chart-median bar{{ (100 * (stats[engine_name].time / max_rate95))|round }}"></div>{{- "" -}} <div class="stacked-bar-chart-median bar{{ (100 * (stats[engine_name].time / max_rate95))|round }}"></div>{{- '' -}}
<div class="stacked-bar-chart-rate80 bar{{ (100 * ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95))|round }}"></div>{{- "" -}} <div class="stacked-bar-chart-rate80 bar{{ (100 * ((stats[engine_name].rate80 - stats[engine_name].time) / max_rate95))|round }}"></div>{{- '' -}}
<div class="stacked-bar-chart-rate95 bar{{ (100 * ((stats[engine_name].rate95 - stats[engine_name].rate80) / max_rate95))|round }}"></div>{{- "" -}} <div class="stacked-bar-chart-rate95 bar{{ (100 * ((stats[engine_name].rate95 - stats[engine_name].rate80) / max_rate95))|round }}"></div>{{- '' -}}
<span class="stacked-bar-chart-rate100"></span> <span class="stacked-bar-chart-rate100"></span>
{%- endif -%} {%- endif -%}
</span>{{- "" -}} </span>{{- '' -}}
<div class="engine-tooltip text-left" role="tooltip" id="{{engine_name}}_graph">{{- "" -}} <div class="engine-tooltip text-left" role="tooltip" id="{{engine_name}}_graph">{{- '' -}}
<p>{{ _('Median') }}: {{ stats[engine_name].time }}</p>{{- "" -}} <p>{{ _('Median') }}: {{ stats[engine_name].time }}</p>{{- '' -}}
<p>{{ _('P80') }}: {{ stats[engine_name].rate80 }}</p>{{- "" -}} <p>{{ _('P80') }}: {{ stats[engine_name].rate80 }}</p>{{- '' -}}
<p>{{ _('P95') }}: {{ stats[engine_name].rate95 }}</p>{{- "" -}} <p>{{ _('P95') }}: {{ stats[engine_name].rate95 }}</p>{{- '' -}}
</div> </div>
{%- endif -%} {%- endif -%}
</td> </td>
{%- endmacro -%} {%- endmacro -%}
{%- macro engine_reliability(engine_name) -%} {%- macro engine_reliability(engine_name) -%}
{% set r = reliabilities.get(engine_name, {}).get('reliablity', None) %} {%- set r = reliabilities.get(engine_name, {}).get('reliablity', None) -%}
{% set checker_result = reliabilities.get(engine_name, {}).get('checker', []) %} {%- set checker_result = reliabilities.get(engine_name, {}).get('checker', []) -%}
{% set errors = reliabilities.get(engine_name, {}).get('errors', []) %} {%- set errors = reliabilities.get(engine_name, {}).get('errors', []) -%}
{% if r != None %} {%- if r != None -%}
{% if r <= 50 %}{% set label = 'danger' %} {%- if r <= 50 -%}
{% elif r < 80 %}{% set label = 'warning' %} {% set label = 'danger' -%}
{% elif r < 90 %}{% set label = '' %} {%- elif r < 80 -%}
{% else %}{% set label = 'success' %} {%- set label = 'warning' -%}
{% endif %} {%- elif r < 90 %}
{% else %} {%- set label = '' -%}
{% set r = '' %} {%- else -%}
{% endif %} {%- set label = 'success' -%}
{% if checker_result or errors %} {%- endif -%}
<td class="{{ label }} column-reliability">{{- "" -}} {% else %}
<a href="{{ url_for('stats', engine=engine_name|e) }}">{{- "" -}} {%- set r = '' -%}
<span aria-labelledby="{{engine_name}}_reliability"> {%- endif -%}
{{ icon_big('warning', 'The engine is not reliabled') }} {{ r -}} {%- if checker_result or errors -%}
</span>{{- "" -}} <td class="{{ label }} column-reliability">{{- '' -}}
</a>{{- "" -}} <a href="{{ url_for('stats', engine=engine_name|e) }}">{{- '' -}}
<div class="engine-tooltip" role="tooltip" id="{{engine_name}}_reliability"> <span aria-labelledby="{{engine_name}}_reliability">
{{- icon_big('warning', 'The engine is not reliabled') }} {{ r -}}
</span>{{- '' -}}
</a>{{- '' -}}
<div class="engine-tooltip" role="tooltip" id="{{engine_name}}_reliability">
{%- if checker_result -%} {%- if checker_result -%}
<p>{{ _("Failed checker test(s): ") }} {{ ', '.join(checker_result) }}</p> <p>{{ _("Failed checker test(s): ") }} {{ ', '.join(checker_result) }}</p>
{%- endif -%} {%- endif -%}
{%- if errors %}<p>{{ _('Errors:') }}</p>{% endif -%} {%- if errors -%}<p>{{ _('Errors:') }}</p>{%- endif -%}
{%- for error in errors -%} {%- for error in errors -%}
<p>{{ error }} </p>{{- "" -}} <p>{{ error }}</p>{{- '' -}}
{%- endfor -%} {%- endfor -%}
</div>{{- "" -}} </div>{{- '' -}}
</td> </td>
{%- else -%} {%- else -%}
<td class="{{ label }}">{% if r %}<span>{{ r }}</span>{% endif %}</td> <td class="{{ label }}">{% if r %}<span>{{ r }}</span>
{%- endif -%} {%- endif -%}
</td>
{%- endif -%}
{%- endmacro -%} {%- endmacro -%}
{% block head %} {% endblock %} {%- block head -%}{%- endblock -%}
{% block linkto_preferences %}{% endblock %} {%- block linkto_preferences -%}{%- endblock -%}
{% block content %}
<h1>{{ _('Preferences') }}</h1>
<form id="search_form" method="post" action="{{ url_for('preferences') }}" autocomplete="off" class="reversed-checkbox"> {%- block content -%}
{{ tabs_open() }} <h1>{{ _('Preferences') }}</h1>
{{ tab_header('maintab', 'general', _('General'), True) }} <form id="search_form" method="post" action="{{ url_for('preferences') }}" autocomplete="off">
{% if 'categories' not in locked_preferences %} {{- tabs_open() -}}
<fieldset>
<legend>{{ _('Default categories') }}</legend>
{% set display_tooltip = false %} {{- tab_header('maintab', 'general', _('General'), True) -}}
{% include 'simple/categories.html' %} {%- if 'categories' not in locked_preferences -%}
</fieldset> <fieldset>
{% endif %} <legend>{{- _('Default categories') -}}</legend>
{% if 'language' not in locked_preferences %} {% set display_tooltip = false %}
<fieldset> {% include 'simple/categories.html' %}
<legend id="pref_language">{{ _('Search language') }}</legend> </fieldset>
<p class="value">{{- '' -}} {%- endif -%}
<select name='language' aria-labelledby="pref_language" aria-describedby="desc_language">{{- '' -}} {%- if 'language' not in locked_preferences -%}
<option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Default language') }} [all]</option> {%- include 'simple/preferences/language.html' -%}
<option value="auto" {% if current_language == 'auto' %}selected="selected"{% endif %}>{{ _('Auto-detect') }} [auto]</option>
{%- for sxng_tag,lang_name,country_name,english_name,flag in sxng_locales | sort(attribute=1) -%}
<option value="{{ sxng_tag }}" {% if sxng_tag == current_language %}selected="selected"{% endif %}>{% if flag %}{{ flag }} {% endif%} {{- lang_name }} {% if country_name %} - {{ country_name }} {% endif %} [{{sxng_tag}}]</option>
{%- endfor -%}
</select>{{- '' -}}
</p>
<div class="description" id="desc_language">
{{- _('What language do you prefer for search?') }} {{ _('Choose Auto-detect to let SearXNG detect the language of your query.') -}}
</div>
</fieldset>
{% endif %}
{% if 'autocomplete' not in locked_preferences %}
<fieldset>
<legend id="pref_autocomplete">{{ _('Autocomplete') }}</legend>
<p class="value">
<select name="autocomplete" aria-labelledby="pref_autocomplete">
<option value=""> - </option>
{%- for backend in autocomplete_backends -%}
<option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
{%- endfor -%}
</select>
</p>
<div class="description">{{ _('Find stuff as you type') }}</div>
</fieldset>
{% endif %} {% endif %}
{%- if 'autocomplete' not in locked_preferences -%}
{%- include 'simple/preferences/autocomplete.html' -%}
{%- endif -%}
{% if 'safesearch' not in locked_preferences %} {% if 'safesearch' not in locked_preferences %}
<fieldset> {%- include 'simple/preferences/safesearch.html' -%}
<legend id="pref_safesearch">{{ _('SafeSearch') }}</legend> {%- endif -%}
<p class="value"> {{- plugin_preferences('general') -}}
<select name='safesearch' aria-labelledby="pref_safesearch"> {%- if 'doi_resolver' not in locked_preferences %}
<option value="2" {% if safesearch == '2' %}selected="selected"{% endif %}>{{ _('Strict') }}</option> {%- include 'simple/preferences/doi_resolver.html' -%}
<option value="1" {% if safesearch == '1' %}selected="selected"{% endif %}>{{ _('Moderate') }}</option> {%- endif -%}
<option value="0" {% if safesearch == '0' %}selected="selected"{% endif %}>{{ _('None') }}</option> {%- include 'simple/preferences/tokens.html' -%}
</select> {{- tab_footer() -}}
</p>
<p class="description">{{ _('Filter content') }}</p>
</fieldset>
{% endif %}
{{ plugin_preferences('general') }}
{% if 'doi_resolver' not in locked_preferences %}
<fieldset>
<legend id="pref_doi_resolver">{{ _('Open Access DOI resolver') }}</legend>
<p class="value">
<select id='doi_resolver' name='doi_resolver' aria-labelledby="pref_doi_resolver">
{%- for doi_resolver_name,doi_resolver_url in doi_resolvers.items() -%}
<option value="{{ doi_resolver_name }}" {% if doi_resolver_url == current_doi_resolver %}selected="selected"{% endif %}>
{{- doi_resolver_name }} - {{ doi_resolver_url -}}
</option>
{%- endfor -%}
</select>
</p>
<div class="description"><!-- {{ _('Redirect to open-access versions of publications when available (plugin required)') }} --></div>
</fieldset>
{% endif %}
<fieldset>
<legend id="pref_tokens">{{ _('Engine tokens') }}</legend>
<p class="value">
<input name="tokens" aria-labelledby="pref_tokens" type="text" autocomplete="off" spellcheck="false" autocorrect="off" value='{{ preferences.tokens.get_value() }}'/>
</p>
<p class="description">{{ _('Access tokens for private engines') }}</p>
</fieldset>
{{ tab_footer() }}
{{ tab_header('maintab', 'ui', _('User interface')) }}
{% if 'locale' not in locked_preferences %}
<fieldset>
<legend id="pref_locale">{{ _('Interface language') }}</legend>
<p class="value">
<select name='locale' aria-labelledby="pref_locale">
{%- for locale_id,locale_name in locales.items() | sort -%}
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
{%- endfor -%}
</select>
</p>
<div class="description">{{ _('Change the language of the layout') }}</div>
</fieldset>
{% endif %}
{% if 'theme' not in locked_preferences %}
<fieldset>
<legend id="pref_theme">{{ _('Theme') }}</legend>
<p class="value">
<select name="theme" aria-labelledby="pref_theme">
{%- for name in themes -%}
<option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
{%- endfor -%}
</select>
</p>
<div class="description">{{ _('Change SearXNG layout') }}</div>
</fieldset>
<fieldset>
<legend id="pref_simple_style">{{ _('Theme style') }}</legend>
<p class="value">
<select name="simple_style" aria-labelledby="pref_simple_style">
{%- for name in ['auto', 'light', 'dark'] -%}
<option value="{{ name }}" {% if name == preferences.get_value('simple_style') %}selected="selected"{% endif %}>{{ _(name) }}</option>
{%- endfor -%}
</select>
</p>
<div class="description">{{ _('Choose auto to follow your browser settings') }}</div>
</fieldset>
<fieldset>
<legend id="pref_center_alignment">{{ _('Center Alignment') }}</legend>
<p class="value">
<select name="center_alignment" aria-labelledby="pref_center_alignment">
<option value="1" {% if preferences.get_value('center_alignment') %}selected="selected"{% endif %}>{{ _('On') }}</option>
<option value="0" {% if not preferences.get_value('center_alignment') %}selected="selected"{% endif %}>{{ _('Off')}}</option>
</select>
</p>
<div class="description">{{ _('Displays results in the center of the page (Oscar layout).') }}</div>
</fieldset>
{% endif %}
{% if 'results_on_new_tab' not in locked_preferences %}
<fieldset>
<legend id="pref_results_on_new_tab">{{ _('Results on new tabs') }}</legend>
<p class="value">
<select name='results_on_new_tab' aria-labelledby="pref_results_on_new_tab">
<option value="1" {% if results_on_new_tab %}selected="selected"{% endif %}>{{ _('On') }}</option>
<option value="0" {% if not results_on_new_tab %}selected="selected"{% endif %}>{{ _('Off')}}</option>
</select>
</p>
<div class="description">{{_('Open result links on new browser tabs') }}</div>
</fieldset>
{% endif %}
{% if 'infinite_scroll' not in locked_preferences %}
<fieldset>
<legend>{{ _('Infinite scroll') }}</legend>
<p class="value">
<select name='infinite_scroll'>
<option value="1" {% if infinite_scroll %}selected="selected"{% endif %}>{{ _('On') }}</option>
<option value="0" {% if not infinite_scroll %}selected="selected"{% endif %}>{{ _('Off')}}</option>
</select>
</p>
<div class="description">{{ _('Automatically load next page when scrolling to bottom of current page') }}</div>
</fieldset>
{% endif %}
{{ plugin_preferences('ui') }}
{{ tab_footer() }}
{{ tab_header('maintab', 'privacy', _('Privacy')) }} {{- tab_header('maintab', 'ui', _('User interface')) -}}
{% if 'method' not in locked_preferences %} {%- if 'locale' not in locked_preferences -%}
<fieldset> {%- include 'simple/preferences/ui_locale.html' -%}
<legend id="pref_method">{{ _('HTTP Method') }}</legend> {%- endif -%}
<p class="value"> {%- if 'theme' not in locked_preferences -%}
<select name='method' aria-labelledby="pref_method"> {%- include 'simple/preferences/theme.html' -%}
<option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option> {%- endif -%}
<option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option> {%- if 'results_on_new_tab' not in locked_preferences -%}
</select> {%- include 'simple/preferences/results_on_new_tab.html' -%}
</p> {%- endif -%}
<div class="description">{{ _('Change how forms are submitted, <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods" rel="external">learn more about request methods</a>') }}</div> {%- if 'infinite_scroll' not in locked_preferences -%}
</fieldset> {%- include 'simple/preferences/infinite_scroll.html' -%}
{% endif %} {%- endif -%}
{% if 'image_proxy' not in locked_preferences %} {{- plugin_preferences('ui') -}}
<fieldset> {{- tab_footer() -}}
<legend id="pref_image_proxy">{{ _('Image proxy') }}</legend>
<p class="value">
<select name='image_proxy' aria-labelledby="pref_image_proxy">
<option value="1" {% if image_proxy %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>
<option value="0" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled') }}</option>
</select>
</p>
<div class="description">{{ _('Proxying image results through SearXNG') }}</div>
</fieldset>
{% endif %}
{% if 'query_in_title' not in locked_preferences %}
<fieldset>
<legend id="pref_query_in_title">{{ _("Query in the page's title") }}</legend>
<p class="value">
<select name='query_in_title' aria-labelledby="pref_query_in_title">
<option value="1" {% if query_in_title %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>
<option value="0" {% if not query_in_title %}selected="selected"{% endif %}>{{ _('Disabled') }}</option>
</select>
</p>
<div class="description">{{ _("When enabled, the result page's title contains your query. Your browser can record this title") }}</div>
</fieldset>
{% endif %}
{{ plugin_preferences('privacy') }}
{{ tab_footer() }}
{{ tab_header('maintab', 'engines', _('Engines')) }}
<p>{{ _('Currently used search engines') }}</p>
{{ tabs_open() }}
{% set ns = namespace(checked=true) %}
{% for categ in categories_as_tabs + [DEFAULT_CATEGORY] %}
{{ tab_header('enginetab', 'category' + categ, _(categ), ns.checked )}}
{% set ns.checked = false %}
{% if categ == DEFAULT_CATEGORY %}
<p>{{_('This tab does not exists in the user interface, but you can search in these engines by its !bangs.')}} <a href="{{ url_for('info', pagename='search-syntax') }}">&#9432;</a></p>
{% endif %}
<div class="scrollx">
<table class="striped table_engines">
<tr>{{- "" -}}
<th class="engine_checkbox">{{ _("Allow") }}</th>{{- "" -}}
<th class="name">{{ _("Engine name") }}</th>{{- "" -}}
<th class="shortcut">{{ _("Bang") }}</th>{{- "" -}}
<th>{{ _("Supports selected language") }}</th>{{- "" -}}
<th>{{ _("SafeSearch") }}</th>{{- "" -}}
<th>{{ _("Time range") }}</th>{{- "" -}}
{%- if enable_metrics %}<th>{{ _("Response time") }}</th>{% endif -%}
<th>{{ _("Max time") }}</th>{{- "" -}}
{%- if enable_metrics %}<th>{{ _("Reliability") }}</th>{% endif -%}
</tr>
{% for group, group_bang, engines in engines_by_category[categ] | group_engines_in_tab %}
{% if loop.length > 1 %}
<tr>
<th class="engine-group" colspan="2">{{_(group)}}</th>
<th class="engine-group" colspan="7">{% if group_bang %}<span class="bang">{{group_bang}}</span>{% endif %}</th>
</tr>{{- "" -}}
{% endif %}
{% for search_engine in engines %}
{% if not search_engine.private %}
{% set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') %}
<tr>{{- "" -}}
<td>{{ checkbox_onoff(engine_id, (search_engine.name, categ) in disabled_engines) }}</td>{{- "" -}}
<th class="name" data-engine-name="{{ search_engine.name }}">{% if search_engine.enable_http %}{{ icon_big('warning', 'No HTTPS') }}{% endif -%}
<label for="{{ engine_id }}">
{{- search_engine.name -}}
{%- if search_engine.about and search_engine.about.language %}
({{search_engine.about.language | upper}})
{%- endif -%}
</label>
{{- engine_about(search_engine) -}}
</th>{{- "" -}}
<td class="shortcut"><span class="bang">{{ '!' + shortcuts[search_engine.name] }}</span></td>{{- "" -}}
<td>{{ checkbox(None, supports[search_engine.name]['supports_selected_language'], true) }}</td>{{- "" -}}
<td>{{ checkbox(None, supports[search_engine.name]['safesearch'], true) }}</td>{{- "" -}}
<td>{{ checkbox(None, supports[search_engine.name]['time_range_support'], true) }}</td>{{- "" -}}
{%- if enable_metrics %}{{- engine_time(search_engine.name) -}}{% endif -%}
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>{{- "" -}}
{%- if enable_metrics %}{{ engine_reliability(search_engine.name) -}}{% endif -%}
</tr>
{% endif %}
{% endfor %}
{% endfor %}
</table>
</div>
{{ tab_footer() }}
{% endfor %}
{{ tabs_close() }}
{{ tab_footer() }}
{{ tab_header('maintab', 'query', _('Special Queries')) }} {{- tab_header('maintab', 'privacy', _('Privacy')) -}}
{% if answerers %} {%- if 'method' not in locked_preferences -%}
<div class="scrollx"> {%- include 'simple/preferences/method.html' -%}
<table class="striped"> {%- endif -%}
<tr> {%- if 'image_proxy' not in locked_preferences -%}
<th>{{ _('Allow') }}</th> {%- include 'simple/preferences/image_proxy.html' -%}
<th>{{ _('Keywords') }}</th> {%- endif -%}
<th>{{ _('Name') }}</th> {%- if 'query_in_title' not in locked_preferences -%}
<th>{{ _('Description') }}</th> {%- include 'simple/preferences/query_in_title.html' -%}
<th>{{ _('Examples') }}</th> {%- endif -%}
</tr> {{- plugin_preferences('privacy') -}}
<td></td> {{- tab_footer() -}}
<th scope="colgroup" colspan="4">{{ _("This is the list of SearXNG's instant answering modules.") }}</th>
{% for answerer in answerers %}
<tr>
<td></td>
<td>{{ answerer.keywords|join(', ') }}</td>
<td>{{ answerer.info.name }}</td>
<td>{{ answerer.info.description }}</td>
<td>{{ answerer.info.examples|join(', ') }}</td>
</tr>
{% endfor %}
<td></td>
<th scope="colgroup" colspan="4">{{ _('This is the list of plugins.') }}</th>
{%- for plugin in plugins -%}
{%- if plugin.preference_section == 'query' -%}
<tr>
<td>{{- checkbox_onoff('plugin_' + plugin.id, plugin.id not in allowed_plugins) -}}</td>
<td>{{ plugin.query_keywords|join(', ') }}</td>
<td>{{ _(plugin.name) }}</td>
<td>{{ _(plugin.description) }}</td>
<td>{{ plugin.query_examples }}</td>
</tr>
{%- endif -%}
{%- endfor -%}
</table>
</div>
{% endif %}
{{ tab_footer() }}
{{ tab_header('maintab', 'cookies', _('Cookies')) }} {{- tab_header('maintab', 'engines', _('Engines')) -}}
<p class="text-muted">{{- "" -}} <p>
{{- _('This is the list of cookies and their values SearXNG is storing on your computer.') }}<br />{{- "" -}} {{- _('Currently used search engines') -}}
{{- _('With that list, you can assess SearXNG transparency.') }}<br />{{- "" -}} </p>
</p> {{- tabs_open() -}}
{% if cookies %} {%- include 'simple/preferences/engines.html' -%}
<table class="cookies"> {{- tabs_close() -}}
<tr>{{- "" -}} {{- tab_footer() -}}
<th>{{ _('Cookie name') }}</th>{{- "" -}}
<th>{{ _('Value') }}</th>{{- "" -}}
</tr>
{% for cookie in cookies %}
<tr>{{- "" -}}
<td>{{ cookie }}</td>{{- "" -}}
<td>{{ cookies[cookie] }}</td>{{- "" -}}
</tr>
{% endfor %}
</table>
{% else %}
{% include 'simple/messages/no_cookies.html' %}
{% endif %}
<h4>{{ _('Search URL of the currently saved preferences') }} :</h4>
<div class="selectable_url">
<pre>{{ url_for('index', _external=True) }}?preferences={{ preferences_url_params|e }}{% raw %}&amp;q=%s{% endraw %}</pre>
</div>
<p class="small_font">{{ _('Note: specifying custom settings in the search URL can reduce privacy by leaking data to the clicked result sites.') }}</p>
<h4>{{ _('URL to restore your preferences in another browser') }} :</h4>
<div class="selectable_url">
<pre>{{ url_for('preferences', _external=True) }}?preferences={{ preferences_url_params|e }}&amp;save=1</pre>
</div>
<p class="small_font">{{ _('Specifying custom settings in the preferences URL can be used to sync preferences across devices.') }}</p>
{{ tab_footer() }}
{{ tabs_close() }}
<p class="small_font">{{ _('These settings are stored in your cookies, this allows us not to store this data about you.') }} {{- tab_header('maintab', 'query', _('Special Queries')) -}}
<br /> {%- if answerers -%}
{{ _("These cookies serve your sole convenience, we don't use these cookies to track you.") }} {%- include 'simple/preferences/answerers.html' -%}
</p> {%- endif -%}
{{- tab_footer() -}}
<input type="submit" value="{{ _('Save') }}" /> {{- tab_header('maintab', 'cookies', _('Cookies')) -}}
<div class="{% if rtl %}left{% else %}right{% endif %} preferences_back"><a href="{{ url_for('clear_cookies') }}">{{ _('Reset defaults') }}</a></div> {%- include 'simple/preferences/cookies.html' -%}
<div class="{% if rtl %}left{% else %}right{% endif %} preferences_back"><a href="{{ url_for('index') }}">{{ _('Back') }}</a></div> {{- tab_footer() -}}
</form> {{- tabs_close() -}}
{% endblock %} {%- include 'simple/preferences/footer.html' -%}
</form>{{- '' -}}
{%- endblock -%}

View file

@ -0,0 +1,43 @@
<div class="scrollx">{{- '' -}}
<table class="striped">{{- '' -}}
<tr>{{- '' -}}
<th>{{ _('Allow') }}</th>{{- '' -}}
<th>{{ _('Keywords') }}</th>{{- '' -}}
<th>{{ _('Name') }}</th>{{- '' -}}
<th>{{ _('Description') }}</th>{{- '' -}}
<th>{{ _('Examples') }}</th>{{- '' -}}
</tr>{{- '' -}}
<td></td>{{- '' -}}
<th scope="colgroup" colspan="4">
{{- _("This is the list of SearXNG's instant answering modules.") -}}
</th>
{%- for answerer in answerers -%}
<tr>{{- '' -}}
<td></td>{{- '' -}}
<td>{{ answerer.keywords|join(', ') }}</td>{{- '' -}}
<td>{{ answerer.info.name }}</td>{{- '' -}}
<td>{{ answerer.info.description }}</td>{{- '' -}}
<td>{{ answerer.info.examples|join(', ') }}</td>{{- '' -}}
</tr>
{%- endfor -%}
<td></td>{{- '' -}}
<th scope="colgroup" colspan="4">
{{- _('This is the list of plugins.') -}}
</th>{{- '' -}}
{%- for plugin in plugins -%}
{%- if plugin.preference_section == 'query' -%}
<tr>{{- '' -}}
<td>{{- checkbox_onoff_reversed('plugin_' + plugin.id, plugin.id not in allowed_plugins) -}}</td>{{- '' -}}
<td>{{ plugin.query_keywords|join(', ') }}</td>{{- '' -}}
<td>{{ _(plugin.name) }}</td>{{- '' -}}
<td>{{ _(plugin.description) }}</td>{{- '' -}}
<td>{{ plugin.query_examples }}</td>{{- '' -}}
</tr>
{%- endif -%}
{%- endfor -%}
</table>{{- '' -}}
</div>{{- '' -}}

View file

@ -0,0 +1,17 @@
<fieldset>{{- '' -}}
<legend id="pref_autocomplete">{{- _('Autocomplete') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="autocomplete" aria-labelledby="pref_autocomplete">{{- '' -}}
<option value=""> - </option>
{%- for backend in autocomplete_backends -%}
<option value="{{ backend }}"
{%- if backend == autocomplete %} selected="selected" {%- endif -%}>
{{- backend -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Find stuff as you type') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,12 @@
<fieldset>{{- '' -}}
<legend id="pref_center_alignment">{{ _('Center Alignment') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<select name="center_alignment" aria-labelledby="pref_center_alignment">{{- '' -}}
<option value="1" {% if preferences.get_value('center_alignment') %}selected="selected"{% endif %}>{{ _('On') }}</option>{{- '' -}}
<option value="0" {% if not preferences.get_value('center_alignment') %}selected="selected"{% endif %}>{{ _('Off')}}</option>{{- '' -}}
</select>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _('Displays results in the center of the page (Oscar layout).') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,45 @@
<p class="text-muted">
{{- _('This is the list of cookies and their values SearXNG is storing on your computer.') }}
<br />{{- _('With that list, you can assess SearXNG transparency.') -}}
<br />{{- '' -}}
</p>
{% if cookies %}
<table class="cookies">
<tr>{{- '' -}}
<th>{{ _('Cookie name') }}</th>{{- '' -}}
<th>{{ _('Value') }}</th>{{- '' -}}
</tr>
{%- for cookie in cookies -%}
<tr>{{- '' -}}
<td>{{ cookie }}</td>{{- '' -}}
<td>{{ cookies[cookie] }}</td>{{- '' -}}
</tr>
{%- endfor -%}
</table>
{%- else -%}
{% include 'simple/messages/no_cookies.html' %}
{% endif %}
<h4>
{{- _('Search URL of the currently saved preferences') -}}:{{- '' -}}
</h4>{{- '' -}}
<div class="selectable_url">{{- '' -}}
<pre>
{{- url_for('index', _external=True) -}}?preferences={{- preferences_url_params|e -}}
{%- raw -%}&amp;q=%s{%- endraw -%}
</pre>{{- '' -}}
</div>{{- '' -}}
<p class="small_font">
{{- _('Note: specifying custom settings in the search URL can reduce privacy by leaking data to the clicked result sites.') -}}
</p>
<h4>
{{- _('URL to restore your preferences in another browser') -}}:{{- '' -}}
</h4>{{- '' -}}
<div class="selectable_url">{{- '' -}}
<pre>
{{- url_for('preferences', _external=True) -}}?preferences={{- preferences_url_params|e -}}
&amp;save=1{{- '' -}}
</pre>{{- '' -}}
</div>{{- '' -}}
<p class="small_font">
{{- _('Specifying custom settings in the preferences URL can be used to sync preferences across devices.') -}}
</p>

View file

@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_doi_resolver">{{- _('Open Access DOI resolver') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select id='doi_resolver' name='doi_resolver' aria-labelledby="pref_doi_resolver">{{- '' -}}
{%- for doi_resolver_name,doi_resolver_url in doi_resolvers.items() -%}
<option value="{{ doi_resolver_name }}"
{%- if doi_resolver_url == current_doi_resolver %} selected="selected" {%- endif -%}>
{{- doi_resolver_name }} - {{ doi_resolver_url -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Select service used by DOI rewrite') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,93 @@
{%- set ns = namespace(checked=true) -%}
{%- for categ in categories_as_tabs + [DEFAULT_CATEGORY] -%}
{{- tab_header('enginetab', 'category_' + categ, _(categ), ns.checked ) -}}
{%- set ns.checked = false -%}
{%- if categ == DEFAULT_CATEGORY -%}
<p>
{{- _('This tab does not exists in the user interface, but you can search in these engines by its !bangs.') -}}
{{- ' ' -}}<a href="{{ url_for('info', pagename='search-syntax') }}">&#9432;</a>
</p>
{%- endif -%}
<div class="scrollx">{{- '' -}}
<table class="striped table_engines">{{- '' -}}
<tr>{{- '' -}}
<th class="engine_checkbox">{{- _("Allow") -}}</th>{{- '' -}}
<th class="name">{{- _("Engine name") -}}</th>{{- '' -}}
<th class="shortcut">{{ _("!bang") -}}</th>{{- '' -}}
<th>{{- _("Supports selected language") -}}</th>{{- '' -}}
<th>{{- _("SafeSearch") -}}</th>{{- '' -}}
<th>{{- _("Time range") -}}</th>{{- '' -}}
{%- if enable_metrics -%}
<th>{{- _("Response time") -}}</th>
{%- endif -%}
<th>{{- _("Max time") -}}</th>
{%- if enable_metrics -%}
<th>{{- _("Reliability") }}</th>
{%- endif -%}
</tr>{{- '' -}}
{%- for group, group_bang, engines in engines_by_category[categ] | group_engines_in_tab -%}
{%- if loop.length > 1 -%}
<tr>{{- '' -}}
<th class="engine-group" colspan="2">{{- _(group) -}}</th>{{- '' -}}
<th class="engine-group" colspan="7">
{%- if group_bang -%}
<span class="bang">{{- group_bang -}}</span>
{%- endif -%}</th>{{- '' -}}
</tr>{{- '' -}}
{%- endif -%}
{%- for search_engine in engines -%}
{%- if not search_engine.private -%}
{%- set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') -%}
<tr>{{- '' -}}
<td>
{{- checkbox_onoff_reversed(engine_id, (search_engine.name, categ) in disabled_engines) -}}
</td>{{- '' -}}
<th class="name" data-engine-name="{{ search_engine.name }}">
{%- if search_engine.enable_http -%}
{{- icon_big('warning', 'No HTTPS') -}}
{%- endif -%}
<label for="{{ engine_id }}">
{{- ' ' -}}{{- search_engine.name -}}
{%- if search_engine.about and search_engine.about.language -%}
{{- ' ' -}}({{search_engine.about.language | upper}})
{%- endif -%}
</label>
{{- engine_about(search_engine) -}}
</th>{{- '' -}}
<td class="shortcut">{{- '' -}}
<span class="bang">{{ '!' + shortcuts[search_engine.name] }}</span>{{- '' -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['supports_selected_language'], true) -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['safesearch'], true) -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['time_range_support'], true) -}}
</td>{{- '' -}}
{%- if enable_metrics -%}
{{- engine_time(search_engine.name) -}}
{%- endif -%}
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">
{{- search_engine.timeout -}}
</td>{{- '' -}}
{%- if enable_metrics -%}
{{- engine_reliability(search_engine.name) -}}
{%- endif -%}
</tr>
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
</table>{{- '' -}}
</div>
{{- tab_footer() -}}
{%- endfor -%}

View file

@ -0,0 +1,14 @@
<p class="small_font">
{{- _('These settings are stored in your cookies, this allows us not to store this data about you.') -}}
<br />{{- _("These cookies serve your sole convenience, we don't use these cookies to track you.") -}}
</p>{{- '' -}}
<input type="submit" value="{{ _('Save') }}" />{{- '' -}}
<div class="{% if rtl %}left{% else %}right{% endif %} preferences_back">{{- '' -}}
<a href="{{ url_for('clear_cookies') }}">{{ _('Reset defaults') }}</a>{{- '' -}}
</div>{{- '' -}}
<div class="{% if rtl %}left{% else %}right{% endif %} preferences_back">{{- '' -}}
<a href="{{ url_for('index') }}">{{ _('Back') }}</a>{{- '' -}}
</div>

View file

@ -0,0 +1,12 @@
<fieldset>{{- '' -}}
<legend id="pref_image_proxy">{{ _('Image proxy') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<select name='image_proxy' aria-labelledby="pref_image_proxy">{{- '' -}}
<option value="1" {% if image_proxy %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>{{- '' -}}
<option value="0" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled') }}</option>{{- '' -}}
</select>{{- '' -}}
</p>
<div class="description">
{{- _('Proxying image results through SearXNG') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,12 @@
<fieldset>{{- '' -}}
<legend>{{ _('Infinite scroll') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<select name='infinite_scroll'>{{- '' -}}
<option value="1" {% if infinite_scroll %}selected="selected"{% endif %}>{{ _('On') }}</option>{{- '' -}}
<option value="0" {% if not infinite_scroll %}selected="selected"{% endif %}>{{ _('Off')}}</option>{{- '' -}}
</select>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _('Automatically load next page when scrolling to bottom of current page') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,27 @@
<fieldset>{{- '' -}}
<legend id="pref_language">{{- _('Search language') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='language' aria-labelledby="pref_language" aria-describedby="desc_language">{{- '' -}}
<option value="all"
{%- if current_language == 'all' %} selected="selected" {%- endif -%}>
{{- _('Default language') }} [all] {{- '' -}}
</option>{{- '' -}}
<option value="auto"
{%- if current_language == 'auto' %} selected="selected" {%- endif -%}>
{{- _('Auto-detect') }} [auto] {{- '' -}}
</option>{{- '' -}}
{% for sxng_tag,lang_name,country_name,english_name,flag in sxng_locales | sort(attribute=1) -%}
<option value="{{ sxng_tag }}"
{%- if sxng_tag == current_language %} selected="selected" {%- endif -%}>
{%- if flag -%}{{ flag }} {% endif -%}
{{ lang_name }}{%- if country_name -%}-{{ country_name }}{%- endif -%}
{{- ' ' -}}[{{sxng_tag}}]{{- '' -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description" id="desc_language">
{{- _('What language do you prefer for search?') }} {{- ' ' -}}
{{- _('Choose Auto-detect to let SearXNG detect the language of your query.') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_method">{{- _('HTTP Method') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='method' aria-labelledby="pref_method">{{- '' -}}
<option value="POST"
{%- if method == 'POST' %} selected="selected"{%- endif -%}>POST{{- '' -}}
</option>{{- '' -}}
<option value="GET"
{%- if method == 'GET' %} selected="selected"{%- endif -%}>GET{{- '' -}}
</option>{{- '' -}}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Change how forms are submitted, <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods" rel="external">learn more about request methods</a>') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,12 @@
<fieldset>{{- '' -}}
<legend id="pref_query_in_title">{{ _("Query in the page's title") }}</legend>
<p class="value">{{- '' -}}
<select name='query_in_title' aria-labelledby="pref_query_in_title">{{- '' -}}
<option value="1" {% if query_in_title %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>{{- '' -}}
<option value="0" {% if not query_in_title %}selected="selected"{% endif %}>{{ _('Disabled') }}</option>{{- '' -}}
</select>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _("When enabled, the result page's title contains your query. Your browser can record this title") -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,12 @@
<fieldset>{{- '' -}}
<legend id="pref_results_on_new_tab">{{ _('Results on new tabs') }}</legend>{{- '' -}}
<p class="value">{{- '' -}}
<select name='results_on_new_tab' aria-labelledby="pref_results_on_new_tab">{{- '' -}}
<option value="1" {% if results_on_new_tab %}selected="selected"{% endif %}>{{ _('On') }}</option>{{- '' -}}
<option value="0" {% if not results_on_new_tab %}selected="selected"{% endif %}>{{ _('Off')}}</option>{{- '' -}}
</select>{{- '' -}}
</p>{{- '' -}}
<div class="description">
{{- _('Open result links on new browser tabs') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,22 @@
<fieldset>{{- '' -}}
<legend id="pref_safesearch">{{- _('SafeSearch') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='safesearch' aria-labelledby="pref_safesearch">{{- '' -}}
<option value="2"
{%- if safesearch == '2' %} selected="selected" {%- endif -%}>
{{- _('Strict') -}}
</option>{{- '' -}}
<option value="1"
{%- if safesearch == '1' %} selected="selected" {%- endif -%}>
{{- _('Moderate') -}}
</option>{{- '' -}}
<option value="0"
{%- if safesearch == '0' %} selected="selected" {%- endif -%}>
{{- _('None') -}}
</option>{{- '' -}}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Filter content') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,35 @@
<fieldset>{{- '' -}}
<legend id="pref_theme">{{- _('Theme') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="theme" aria-labelledby="pref_theme">{{- '' -}}
{%- for name in themes -%}
<option value="{{ name }}"
{%- if name == theme %} selected="selected"{%- endif -%}>
{{- name -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Change SearXNG layout') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}
<fieldset>{{- '' -}}
<legend id="pref_simple_style">{{- _('Theme style') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name="simple_style" aria-labelledby="pref_simple_style">
{%- for name in ['auto', 'light', 'dark'] -%}
<option value="{{ name }}"
{%- if name == preferences.get_value('simple_style') %} selected="selected" {%- endif -%}>
{{- _(name) -}}
</option>
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Choose auto to follow your browser settings') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}
{%- include 'simple/preferences/center_alignment.html' -%}

View file

@ -0,0 +1,11 @@
<fieldset>{{- '' -}}
<legend id="pref_tokens">{{- _('Engine tokens') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<input name="tokens" aria-labelledby="pref_tokens" type="text"
autocomplete="off" spellcheck="false" autocorrect="off"
value='{{ preferences.tokens.get_value() }}'/>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Access tokens for private engines') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -0,0 +1,16 @@
<fieldset>{{- '' -}}
<legend id="pref_ui_locale">{{- _('Interface language') -}}</legend>{{- '' -}}
<div class="value">{{- '' -}}
<select name='locale' aria-labelledby="pref_ui_locale">{{- '' -}}
{%- for locale_id,locale_name in locales.items() | sort -%}
<option value="{{ locale_id }}"
{%- if locale_id == current_locale %} selected="selected" {%- endif %}>
{{- locale_name -}}
</option>{{- '' -}}
{%- endfor -%}
</select>{{- '' -}}
</div>{{- '' -}}
<div class="description">
{{- _('Change the language of the layout') -}}
</div>{{- '' -}}
</fieldset>{{- '' -}}

View file

@ -201,7 +201,7 @@ class ViewsTestCase(SearxTestCase):
self.assertIn( self.assertIn(
b'<input type="checkbox" id="checkbox_general" name="category_general" checked="checked"/>', result.data b'<input type="checkbox" id="checkbox_general" name="category_general" checked="checked"/>', result.data
) )
self.assertIn(b'<legend id="pref_locale">Interface language</legend>', result.data) self.assertIn(b'<legend id="pref_ui_locale">Interface language</legend>', result.data)
def test_browser_locale(self): def test_browser_locale(self):
result = self.app.get('/preferences', headers={'Accept-Language': 'zh-tw;q=0.8'}) result = self.app.get('/preferences', headers={'Accept-Language': 'zh-tw;q=0.8'})