mirror of
https://github.com/searxng/searxng.git
synced 2025-02-17 02:40:03 +00:00
Merge pull request #848 from not-my-profile/help-route
Introduce `/help` route
This commit is contained in:
commit
bf987bb608
@ -1,4 +1,4 @@
|
|||||||
# About [searxng][url_for:index]
|
# About SearXNG
|
||||||
|
|
||||||
SearXNG is a fork from the well-known [searx] [metasearch engine], aggregating
|
SearXNG is a fork from the well-known [searx] [metasearch engine], aggregating
|
||||||
the results of other [search engines][url_for:preferences] while not storing
|
the results of other [search engines][url_for:preferences] while not storing
|
||||||
|
BIN
searx/static/themes/simple/css/searxng-rtl.min.css
vendored
BIN
searx/static/themes/simple/css/searxng-rtl.min.css
vendored
Binary file not shown.
Binary file not shown.
BIN
searx/static/themes/simple/css/searxng.min.css
vendored
BIN
searx/static/themes/simple/css/searxng.min.css
vendored
Binary file not shown.
Binary file not shown.
@ -221,6 +221,16 @@ div.selectable_url {
|
|||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.tabs {
|
||||||
|
border-bottom: 1px solid var(--color-toolkit-tabs-section-border);
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -235,7 +245,8 @@ div.selectable_url {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > label {
|
& > label,
|
||||||
|
& > li > a {
|
||||||
order: 1;
|
order: 1;
|
||||||
padding: 0.7em;
|
padding: 0.7em;
|
||||||
margin: 0 0.7em;
|
margin: 0 0.7em;
|
||||||
@ -243,13 +254,21 @@ div.selectable_url {
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border: solid var(--color-toolkit-tabs-label-border);
|
border: solid var(--color-toolkit-tabs-label-border);
|
||||||
border-width: 0 0 2px 0;
|
border-width: 0 0 2px 0;
|
||||||
|
color: unset;
|
||||||
|
|
||||||
.disable-user-select();
|
.disable-user-select();
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-bottom: 2px solid var(--color-categories-item-border-selected);
|
||||||
|
background: var(--color-categories-item-selected);
|
||||||
|
color: var(--color-categories-item-selected-font);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > label:hover {
|
& > label:hover,
|
||||||
|
& > li > a:hover {
|
||||||
border-bottom: 2px solid var(--color-categories-item-border-selected);
|
border-bottom: 2px solid var(--color-categories-item-border-selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
{% extends "oscar/base.html" %}
|
|
||||||
{% block title %}{{ _('about') }} - {% endblock %}
|
|
||||||
{% block content %}
|
|
||||||
{{ help.about | safe }}
|
|
||||||
{% include "__common__/aboutextend.html" ignore missing %}
|
|
||||||
{% endblock %}
|
|
12
searx/templates/oscar/help.html
Normal file
12
searx/templates/oscar/help.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% extends "oscar/base.html" %}
|
||||||
|
{% block title %}{{ page.title }} - {% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
{% for name, page in all_pages %}
|
||||||
|
<li {% if name == page_filename %}class="active"{% endif %}>
|
||||||
|
<a href="{{name}}">{{page.title}}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{{ page.content | safe }}
|
||||||
|
{% endblock %}
|
@ -3,7 +3,7 @@
|
|||||||
<a href="{{ url_for('index') }}">{{ instance_name }}</a>{{- "" -}}
|
<a href="{{ url_for('index') }}">{{ instance_name }}</a>{{- "" -}}
|
||||||
</span>{{- "" -}}
|
</span>{{- "" -}}
|
||||||
<span class="{% if rtl %}pull-left{% else %}pull-right{% endif %}">{{- "" -}}
|
<span class="{% if rtl %}pull-left{% else %}pull-right{% endif %}">{{- "" -}}
|
||||||
<a href="{{ url_for('about') }}">{{ _('about') }}</a>{{- "" -}}
|
<a href="{{ url_for('help_page', pagename='about') }}">{{ _('about') }}</a>{{- "" -}}
|
||||||
<a href="{{ url_for('preferences') }}">{{ _('preferences') }}</a>{{- "" -}}
|
<a href="{{ url_for('preferences') }}">{{ _('preferences') }}</a>{{- "" -}}
|
||||||
</span>{{- "" -}}
|
</span>{{- "" -}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
{% extends 'simple/page_with_header.html' %}
|
|
||||||
{% block content %}
|
|
||||||
{{ help.about | safe }}
|
|
||||||
{% include "__common__/aboutextend.html" ignore missing %}
|
|
||||||
{% endblock %}
|
|
@ -58,7 +58,7 @@
|
|||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
<p>
|
<p>
|
||||||
{{ _('Powered by') }} <a href="{{ url_for('about') }}">searxng</a> - {{ searx_version }} — {{ _('a privacy-respecting, hackable metasearch engine') }}<br/>
|
{{ _('Powered by') }} <a href="{{ url_for('help_page', pagename='about') }}">searxng</a> - {{ searx_version }} — {{ _('a privacy-respecting, hackable metasearch engine') }}<br/>
|
||||||
<a href="{{ searx_git_url }}">{{ _('Source code') }}</a> |
|
<a href="{{ searx_git_url }}">{{ _('Source code') }}</a> |
|
||||||
<a href="{{ get_setting('brand.issue_url') }}">{{ _('Issue tracker') }}</a> |
|
<a href="{{ get_setting('brand.issue_url') }}">{{ _('Issue tracker') }}</a> |
|
||||||
<a href="{{ url_for('stats') }}">{{ _('Engine stats') }}</a> |
|
<a href="{{ url_for('stats') }}">{{ _('Engine stats') }}</a> |
|
||||||
|
12
searx/templates/simple/help.html
Normal file
12
searx/templates/simple/help.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% extends 'simple/page_with_header.html' %}
|
||||||
|
{% block title %}{{ page.title }} - {% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<ul class="tabs">
|
||||||
|
{% for name, page in all_pages %}
|
||||||
|
<li>
|
||||||
|
<a href="{{name}}" {% if name == page_filename %}class="active"{% endif %}>{{page.title}}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{{ page.content | safe }}
|
||||||
|
{% endblock %}
|
@ -1,5 +1,5 @@
|
|||||||
from typing import Dict
|
# pyright: basic
|
||||||
import os.path
|
from typing import Dict, NamedTuple
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
@ -9,8 +9,17 @@ import mistletoe
|
|||||||
from . import get_setting
|
from . import get_setting
|
||||||
from .version import GIT_URL
|
from .version import GIT_URL
|
||||||
|
|
||||||
HELP: Dict[str, str] = {}
|
|
||||||
""" Maps a filename under help/ without the file extension to the rendered HTML. """
|
class HelpPage(NamedTuple):
|
||||||
|
title: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
|
||||||
|
# Whenever a new .md file is added to help/ it needs to be added here
|
||||||
|
_TOC = ('about',)
|
||||||
|
|
||||||
|
PAGES: Dict[str, HelpPage] = {}
|
||||||
|
""" Maps a filename under help/ without the file extension to the rendered page. """
|
||||||
|
|
||||||
|
|
||||||
def render(app: flask.Flask):
|
def render(app: flask.Flask):
|
||||||
@ -37,12 +46,16 @@ def render(app: flask.Flask):
|
|||||||
|
|
||||||
define_link_targets = ''.join(f'[{name}]: {url}\n' for name, url in link_targets.items())
|
define_link_targets = ''.join(f'[{name}]: {url}\n' for name, url in link_targets.items())
|
||||||
|
|
||||||
for filename in pkg_resources.resource_listdir(__name__, 'help'):
|
for pagename in _TOC:
|
||||||
rootname, ext = os.path.splitext(filename)
|
file_content = pkg_resources.resource_string(__name__, 'help/' + pagename + '.md').decode()
|
||||||
|
markdown = define_link_targets + file_content
|
||||||
|
assert file_content.startswith('# ')
|
||||||
|
title = file_content.split('\n', maxsplit=1)[0].strip('# ')
|
||||||
|
content: str = mistletoe.markdown(markdown)
|
||||||
|
|
||||||
if ext != '.md':
|
if pagename == 'about':
|
||||||
continue
|
try:
|
||||||
|
content += pkg_resources.resource_string(__name__, 'templates/__common__/aboutextend.html').decode()
|
||||||
markdown = pkg_resources.resource_string(__name__, 'help/' + filename).decode()
|
except FileNotFoundError:
|
||||||
markdown = define_link_targets + markdown
|
pass
|
||||||
HELP[rootname] = mistletoe.markdown(markdown)
|
PAGES[pagename] = HelpPage(title=title, content=content)
|
||||||
|
@ -877,8 +877,21 @@ def __get_translated_errors(unresponsive_engines: Iterable[UnresponsiveEngine]):
|
|||||||
|
|
||||||
@app.route('/about', methods=['GET'])
|
@app.route('/about', methods=['GET'])
|
||||||
def about():
|
def about():
|
||||||
"""Render about page"""
|
"""Redirect to about page"""
|
||||||
return render('about.html', help=user_help.HELP)
|
return redirect(url_for('help_page', pagename='about'))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/help/en/<pagename>', methods=['GET'])
|
||||||
|
def help_page(pagename):
|
||||||
|
"""Render help page"""
|
||||||
|
page = user_help.PAGES.get(pagename)
|
||||||
|
|
||||||
|
if page is None:
|
||||||
|
flask.abort(404)
|
||||||
|
|
||||||
|
return render(
|
||||||
|
'help.html', page=user_help.PAGES[pagename], all_pages=user_help.PAGES.items(), page_filename=pagename
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/autocompleter', methods=['GET', 'POST'])
|
@app.route('/autocompleter', methods=['GET', 'POST'])
|
||||||
|
@ -174,9 +174,9 @@ class ViewsTestCase(SearxTestCase):
|
|||||||
self.assertIn(b'<description>first test content</description>', result.data)
|
self.assertIn(b'<description>first test content</description>', result.data)
|
||||||
|
|
||||||
def test_about(self):
|
def test_about(self):
|
||||||
result = self.app.get('/about')
|
result = self.app.get('/help/en/about')
|
||||||
self.assertEqual(result.status_code, 200)
|
self.assertEqual(result.status_code, 200)
|
||||||
self.assertIn(b'<h1>About <a href="/">searxng</a></h1>', result.data)
|
self.assertIn(b'<h1>About SearXNG</h1>', result.data)
|
||||||
|
|
||||||
def test_health(self):
|
def test_health(self):
|
||||||
result = self.app.get('/healthz')
|
result = self.app.get('/healthz')
|
||||||
|
Loading…
Reference in New Issue
Block a user