Browse Source

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

Introduce `/help` route
Alexandre Flament 3 years ago
parent
commit
bf987bb608

+ 1 - 1
searx/help/about.md

@@ -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

File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/css/searxng-rtl.min.css


File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/css/searxng-rtl.min.css.map


File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/css/searxng.min.css


File diff suppressed because it is too large
+ 0 - 0
searx/static/themes/simple/css/searxng.min.css.map


+ 21 - 2
searx/static/themes/simple/src/less/toolkit.less

@@ -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);
   }
   }
 
 

+ 0 - 6
searx/templates/oscar/about.html

@@ -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 - 0
searx/templates/oscar/help.html

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

+ 1 - 1
searx/templates/oscar/navbar.html

@@ -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>

+ 0 - 5
searx/templates/simple/about.html

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

+ 1 - 1
searx/templates/simple/base.html

@@ -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 - 0
searx/templates/simple/help.html

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

+ 26 - 13
searx/user_help.py

@@ -1,5 +1,5 @@
-from typing import Dict
-import os.path
+# pyright: basic
+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'):
-        rootname, ext = os.path.splitext(filename)
-
-        if ext != '.md':
-            continue
-
-        markdown = pkg_resources.resource_string(__name__, 'help/' + filename).decode()
-        markdown = define_link_targets + markdown
-        HELP[rootname] = mistletoe.markdown(markdown)
+    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 pagename == 'about':
+            try:
+                content += pkg_resources.resource_string(__name__, 'templates/__common__/aboutextend.html').decode()
+            except FileNotFoundError:
+                pass
+        PAGES[pagename] = HelpPage(title=title, content=content)

+ 15 - 2
searx/webapp.py

@@ -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"""
-    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'])
 @app.route('/autocompleter', methods=['GET', 'POST'])

+ 2 - 2
tests/unit/test_webapp.py

@@ -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')

Some files were not shown because too many files changed in this diff