Merge pull request #848 from not-my-profile/help-route

Introduce `/help` route
This commit is contained in:
Alexandre Flament 2022-02-05 08:52:19 +01:00 committed by GitHub
commit bf987bb608
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 90 additions and 32 deletions

View File

@ -1,4 +1,4 @@
# About [searxng][url_for:index]
# About SearXNG
SearXNG is a fork from the well-known [searx] [metasearch engine], aggregating
the results of other [search engines][url_for:preferences] while not storing

Binary file not shown.

View File

@ -221,6 +221,16 @@ div.selectable_url {
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 {
display: flex;
flex-wrap: wrap;
@ -235,7 +245,8 @@ div.selectable_url {
display: none;
}
& > label {
& > label,
& > li > a {
order: 1;
padding: 0.7em;
margin: 0 0.7em;
@ -243,13 +254,21 @@ div.selectable_url {
text-transform: uppercase;
border: solid var(--color-toolkit-tabs-label-border);
border-width: 0 0 2px 0;
color: unset;
.disable-user-select();
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);
}

View File

@ -1,6 +0,0 @@
{% extends "oscar/base.html" %}
{% block title %}{{ _('about') }} - {% endblock %}
{% block content %}
{{ help.about | safe }}
{% include "__common__/aboutextend.html" ignore missing %}
{% endblock %}

View 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 %}

View File

@ -3,7 +3,7 @@
<a href="{{ url_for('index') }}">{{ instance_name }}</a>{{- "" -}}
</span>{{- "" -}}
<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>{{- "" -}}
</span>{{- "" -}}
</div>

View File

@ -1,5 +0,0 @@
{% extends 'simple/page_with_header.html' %}
{% block content %}
{{ help.about | safe }}
{% include "__common__/aboutextend.html" ignore missing %}
{% endblock %}

View File

@ -58,7 +58,7 @@
</main>
<footer>
<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="{{ get_setting('brand.issue_url') }}">{{ _('Issue tracker') }}</a> |
<a href="{{ url_for('stats') }}">{{ _('Engine stats') }}</a> |

View 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 %}

View File

@ -1,5 +1,5 @@
from typing import Dict
import os.path
# pyright: basic
from typing import Dict, NamedTuple
import pkg_resources
import flask
@ -9,8 +9,17 @@ import mistletoe
from . import get_setting
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):
@ -37,12 +46,16 @@ def render(app: flask.Flask):
define_link_targets = ''.join(f'[{name}]: {url}\n' for name, url in link_targets.items())
for filename in pkg_resources.resource_listdir(__name__, 'help'):
rootname, ext = os.path.splitext(filename)
for pagename in _TOC:
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':
continue
markdown = pkg_resources.resource_string(__name__, 'help/' + filename).decode()
markdown = define_link_targets + markdown
HELP[rootname] = mistletoe.markdown(markdown)
if pagename == 'about':
try:
content += pkg_resources.resource_string(__name__, 'templates/__common__/aboutextend.html').decode()
except FileNotFoundError:
pass
PAGES[pagename] = HelpPage(title=title, content=content)

View File

@ -877,8 +877,21 @@ def __get_translated_errors(unresponsive_engines: Iterable[UnresponsiveEngine]):
@app.route('/about', methods=['GET'])
def about():
"""Render about page"""
return render('about.html', help=user_help.HELP)
"""Redirect to about page"""
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'])

View File

@ -174,9 +174,9 @@ class ViewsTestCase(SearxTestCase):
self.assertIn(b'<description>first test content</description>', result.data)
def test_about(self):
result = self.app.get('/about')
result = self.app.get('/help/en/about')
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):
result = self.app.get('/healthz')