mirror of
https://github.com/searxng/searxng
synced 2024-01-01 19:24:07 +01:00
[feat] allow customization of logo and favicon
also removed searxng-wordmark from templates directory and build files, because it is no longer used anywhere
This commit is contained in:
parent
0245e82bd2
commit
0c202474c4
15 changed files with 92 additions and 12 deletions
|
@ -174,3 +174,4 @@ features or generally made searx better:
|
|||
- @micsthepick
|
||||
- Daniel Kukula `<https://github.com/dkuku>`
|
||||
- Patrick Evans `https://github.com/holysoles`
|
||||
- shreven `<https://shreven.org>`_ B8B56F6FC0EADCA5B6177BC5F599020F48EE6F97
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
docs_url: https://docs.searxng.org
|
||||
public_instances: https://searx.space
|
||||
wiki_url: https://github.com/searxng/searxng/wiki
|
||||
custom_files:
|
||||
logo: /path/to/file.png
|
||||
favicon_png: /path/to/file.png
|
||||
favicon_svg: /path/to/file.svg
|
||||
|
||||
``issue_url`` :
|
||||
If you host your own issue tracker change this URL.
|
||||
|
@ -23,3 +27,12 @@
|
|||
|
||||
``wiki_url`` :
|
||||
Link to your wiki (or ``false``)
|
||||
|
||||
``custom_files.logo`` :
|
||||
Filepath to a custom logo. Be sure it has the right file extension, as that's used to determine the mimetype.
|
||||
|
||||
``custom_files.favicon_png`` :
|
||||
Filepath to a custom PNG favicon.
|
||||
|
||||
``custom_files.favicon_svg`` :
|
||||
Filepath to a custom SVG favicon. When using, be sure to also set ``custom_files.favicon_png``, as some browsers still don't support SVG favicons.
|
||||
|
|
|
@ -29,6 +29,12 @@ brand:
|
|||
# links:
|
||||
# Uptime: https://uptime.searxng.org/history/darmarit-org
|
||||
# About: "https://searxng.org"
|
||||
# custom_files:
|
||||
# # If using custom logo, be sure to set the right file extension as it's used to determine the mimetype.
|
||||
# logo: /path/to/file.png
|
||||
# # For custom favicons, you must include a PNG version, as some browsers still don't support SVG favicons.
|
||||
# favicon_png: /path/to/file.png
|
||||
# favicon_svg: /path/to/file.svg
|
||||
|
||||
search:
|
||||
# Filter results. 0: None, 1: Moderate, 2: Strict
|
||||
|
|
|
@ -152,6 +152,7 @@ SCHEMA = {
|
|||
'public_instances': SettingsValue((False, str), 'https://searx.space'),
|
||||
'wiki_url': SettingsValue(str, 'https://github.com/searxng/searxng/wiki'),
|
||||
'custom': SettingsValue(dict, {'links': {}}),
|
||||
'custom_files': SettingsValue(dict, {}),
|
||||
},
|
||||
'search': {
|
||||
'safe_search': SettingsValue((0, 1, 2), 0),
|
||||
|
|
|
@ -151,7 +151,6 @@ module.exports = function (grunt) {
|
|||
svgo: ['--config', 'svg4web.svgo.js']
|
||||
},
|
||||
files: {
|
||||
'<%= _templates %>/simple/searxng-wordmark.min.svg': '<%= _brand %>/searxng-wordmark.svg',
|
||||
'img/searxng.svg': '<%= _brand %>/searxng.svg',
|
||||
'img/img_load_error.svg': '<%= _brand %>/img_load_error.svg'
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
text-align: center;
|
||||
|
||||
.title {
|
||||
background: url('../img/searxng.png') no-repeat;
|
||||
&.custom_logo {
|
||||
background-image: url('../../../../custom/logo');
|
||||
}
|
||||
background-image: url('../img/searxng.png');
|
||||
background-repeat: no-repeat;
|
||||
min-height: 4rem;
|
||||
margin: 4rem auto;
|
||||
background-position: center;
|
||||
|
|
|
@ -27,9 +27,11 @@
|
|||
{% block head %}
|
||||
<link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}">
|
||||
{% endblock %}
|
||||
<link rel="icon" href="{{ url_for('static', filename='img/favicon.png') }}" sizes="any">
|
||||
<link rel="icon" href="{{ url_for('static', filename='img/favicon.svg') }}" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="{{ url_for('static', filename='img/favicon.png') }}">
|
||||
<link rel="icon" href="{{ url_for('custom', custom_file='favicon_png', filename='img/favicon.png') }}" sizes="any">
|
||||
<link rel="apple-touch-icon" href="{{ url_for('custom', custom_file='favicon_png', filename='img/favicon.png') }}">
|
||||
{% if not get_setting('brand.custom_files.favicon_png', false) or get_setting('brand.custom_files.favicon_svg', false) %}
|
||||
<link rel="icon" href="{{ url_for('custom', custom_file='favicon_svg', filename='img/favicon.svg') }}" type="image/svg+xml">
|
||||
{% endif %}
|
||||
</head>
|
||||
<body class="{{ endpoint }}_endpoint" >
|
||||
<main id="main_{{ self._TemplateReference__context.name|replace("simple/", "")|replace(".html", "") }}" class="{{body_class}}">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{% from 'simple/icons.html' import icon_big %}
|
||||
{% block content %}
|
||||
<div class="index">
|
||||
<div class="title"><h1>SearXNG</h1></div>
|
||||
<div class="title{% if get_setting('brand.custom_files.logo', false) %} custom_logo{% endif %}"><h1>SearXNG</h1></div>
|
||||
{% include 'simple/simple_search.html' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<LongName>SearXNG metasearch</LongName>
|
||||
<Description>SearXNG is a metasearch engine that respects your privacy.</Description>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Image type="image/png">{{ url_for('static', filename='img/favicon.png', _external=True) }}</Image>
|
||||
<Image type="image/png">{{ url_for('custom', custom_file='favicon_png', filename='img/favicon.png', _external=True) }}</Image>
|
||||
{% if opensearch_method == 'GET' %}
|
||||
<Url rel="results" type="text/html" method="{{ opensearch_method }}" template="{{ url_for('search', _external=True) }}?q={searchTerms}"/>
|
||||
{% else %}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
{%- extends "simple/base.html" -%}
|
||||
{%- block header -%}
|
||||
<a href="{{ url_for('index') }}">{{- '' -}}
|
||||
<img class="logo" src="{{ url_for('static', filename='img/searxng.png') }}" alt="SearXNG">{{- '' -}}
|
||||
<img class="logo" src="{{ url_for('custom', custom_file='logo', filename='img/searxng.png') }}" alt="SearXNG">{{- '' -}}
|
||||
</a>{{- '' -}}
|
||||
{%- endblock -%}
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
<div id="search_header">
|
||||
<a id="search_logo" href="{{ url_for('index') }}" tabindex="0" title="{{ _('Display the front page') }}">
|
||||
<span hidden>SearXNG</span>
|
||||
{% include 'simple/searxng-wordmark.min.svg' without context %}
|
||||
<img width="23px" height="23px" src="
|
||||
{%- if not get_setting('brand.custom_files.favicon_svg', false) -%}
|
||||
{{ url_for('custom', custom_file='favicon_png', filename='img/favicon.svg') }}
|
||||
{%- else -%} {{ url_for('custom', custom_file='favicon_svg', filename='img/favicon.svg') }}
|
||||
{%- endif -%}
|
||||
"></img>
|
||||
</a>
|
||||
<div id="search_view">
|
||||
<div class="search_box">
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="92mm" height="92mm" viewBox="0 0 92 92"><g transform="translate(-40.921 -17.417)"><circle cx="75.921" cy="53.903" r="30" fill="none" fill-opacity="1" stroke="#3050ff" stroke-width="10" stroke-miterlimit="4" stroke-dasharray="none" stroke-opacity="1"/><path d="M67.515 37.915a18 18 0 0 1 21.051 3.313 18 18 0 0 1 3.138 21.078" fill="none" fill-opacity="1" stroke="#3050ff" stroke-width="5" stroke-miterlimit="4" stroke-dasharray="none" stroke-opacity="1"/><rect width="18.846" height="39.963" x="3.706" y="122.09" ry="0" transform="rotate(-46.235)" opacity="1" fill="#3050ff" fill-opacity="1" stroke="none" stroke-width="8" stroke-miterlimit="4" stroke-dasharray="none" stroke-opacity="1"/></g></svg>
|
Before Width: | Height: | Size: 746 B |
|
@ -37,6 +37,7 @@ from flask import (
|
|||
make_response,
|
||||
redirect,
|
||||
send_from_directory,
|
||||
send_file,
|
||||
)
|
||||
from flask.wrappers import Response
|
||||
from flask.json import jsonify
|
||||
|
@ -74,6 +75,7 @@ from searx import webutils
|
|||
from searx.webutils import (
|
||||
highlight_content,
|
||||
get_static_files,
|
||||
get_custom_files,
|
||||
get_result_templates,
|
||||
get_themes,
|
||||
exception_classname_to_text,
|
||||
|
@ -132,6 +134,7 @@ if not searx_debug and settings['server']['secret_key'] == 'ultrasecretkey':
|
|||
# about static
|
||||
logger.debug('static directory is %s', settings['ui']['static_path'])
|
||||
static_files = get_static_files(settings['ui']['static_path'])
|
||||
custom_files = get_custom_files()
|
||||
|
||||
# about templates
|
||||
logger.debug('templates directory is %s', settings['ui']['templates_path'])
|
||||
|
@ -256,6 +259,15 @@ def get_result_template(theme_name: str, template_name: str):
|
|||
|
||||
def custom_url_for(endpoint: str, **values):
|
||||
suffix = ""
|
||||
if endpoint == 'custom' and values.get('custom_file'):
|
||||
if values['custom_file'] in custom_files:
|
||||
values.pop('filename')
|
||||
if get_setting('ui.static_use_hash'):
|
||||
suffix = "?" + custom_files[values['custom_file']]['hash']
|
||||
else:
|
||||
# if there's no custom file defined in settings.yml, then use the default file
|
||||
values.pop('custom_file')
|
||||
endpoint = 'static'
|
||||
if endpoint == 'static' and values.get('filename'):
|
||||
file_hash = static_files.get(values['filename'])
|
||||
if not file_hash:
|
||||
|
@ -1279,8 +1291,25 @@ def opensearch():
|
|||
return resp
|
||||
|
||||
|
||||
@app.route('/custom/<path:custom_file>')
|
||||
def custom(custom_file):
|
||||
if custom_file in custom_files:
|
||||
filepath = custom_files[custom_file]['path']
|
||||
if os.path.isfile(filepath):
|
||||
if 'mimetype' in custom_files[custom_file]:
|
||||
return send_file(filepath, mimetype=custom_files[custom_file]['mimetype'])
|
||||
return send_file(filepath)
|
||||
logger.warning('%s does not exist or is not a file', filepath)
|
||||
return flask.abort(404)
|
||||
|
||||
|
||||
@app.route('/favicon.ico')
|
||||
def favicon():
|
||||
if 'favicon_png' in custom_files:
|
||||
filepath = custom_files['favicon_png']['path']
|
||||
if os.path.isfile(filepath):
|
||||
return send_file(filepath, mimetype='image/png')
|
||||
logger.warning('%s does not exist or is not a file', filepath)
|
||||
theme = request.preferences.get_value("theme")
|
||||
return send_from_directory(
|
||||
os.path.join(app.root_path, settings['ui']['static_path'], 'themes', theme, 'img'), # pyright: ignore
|
||||
|
|
|
@ -204,6 +204,28 @@ def get_static_files(static_path: str) -> Dict[str, str]:
|
|||
return static_files
|
||||
|
||||
|
||||
def get_custom_files() -> Dict[str, dict]:
|
||||
custom_files: Dict[str, dict] = {}
|
||||
|
||||
for option in settings['brand']['custom_files']:
|
||||
filepath = settings['brand']['custom_files'][option]
|
||||
if os.path.isfile(filepath):
|
||||
custom_files.setdefault(option, {})
|
||||
custom_files[option]['path'] = filepath
|
||||
custom_files[option]['hash'] = get_hash_for_file(pathlib.Path(filepath))
|
||||
if option == 'favicon_png':
|
||||
custom_files[option]['mimetype'] = 'image/png'
|
||||
if option == 'favicon_svg':
|
||||
custom_files[option]['mimetype'] = 'image/svg+xml'
|
||||
else:
|
||||
logger.warning('%s does not exist or is not a file', filepath)
|
||||
|
||||
if 'favicon_svg' in custom_files and 'favicon_png' not in custom_files:
|
||||
logger.warning('Some browsers only support PNG favicons, but you have only set an SVG favicon')
|
||||
|
||||
return custom_files
|
||||
|
||||
|
||||
def get_result_templates(templates_path):
|
||||
result_templates = set()
|
||||
templates_path_length = len(templates_path) + 1
|
||||
|
|
|
@ -8,7 +8,6 @@ STATIC_BUILT_PATHS=(
|
|||
'searx/static/themes/simple/js'
|
||||
'searx/static/themes/simple/src/generated/pygments.less'
|
||||
'searx/static/themes/simple/img'
|
||||
'searx/templates/simple/searxng-wordmark.min.svg'
|
||||
'searx/templates/simple/icons.html'
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue