[mod] typification of SearXNG: add new result type File

This PR adds a new result type: File

    Python class: searx/result_types/file.py
    Jinja template: searx/templates/simple/result_templates/file.html
    CSS (less) client/simple/src/less/result_types/file.less

Class 'File' (singular) replaces template 'files.html' (plural).  The renaming
was carried out because there is only one file (singular) in a result. Not to be
confused with the category 'files' where in multiple results can exist.

As mentioned in issue [1], the class '.category-files' was removed from the CSS
and the stylesheet was adopted in result_types/file.less (there based on the
templates and no longer based on the category).

[1] https://github.com/searxng/searxng/issues/5198

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
Markus Heiser
2025-10-13 09:28:42 +02:00
committed by Markus Heiser
parent ee6d4f322f
commit 9371658531
14 changed files with 493 additions and 254 deletions
@@ -3,7 +3,7 @@
{{ result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
{% if result.iframe_src -%}
<p class="altlink"><a class="btn-collapse collapsed media-loader disabled_if_nojs" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">{{ icon('music-note') }} {{ _('show media') }}</a></p>
<p class="altlink"><a class="btn-collapse collapsed media-loader disabled_if_nojs" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">{{ icon('play') }} {{ _('show media') }}</a></p>
{%- endif %}
{%- if result.content %}
<p class="content">
@@ -0,0 +1,74 @@
{% from "simple/macros.html" import result_header, result_sub_header, result_sub_footer, result_footer, result_link with context %}
{% from "simple/icons.html" import icon_small %}
{{ result_header(result, favicons, image_proxify) }}
{{ result_sub_header(result) }}
{% if result.abstract %}
<p class="abstract">{{ result.abstract|safe }}</p>
{% endif -%}
{%- if result.content %}
<p class="content">{{ result.content|safe }}</p>
{% endif -%}
<div class="attributes">
{% if result.author %}
<div>
<span>{{ _("Author") }}:</span>
<span>{{ result.author }}</span>
</div>
{% endif %}
{% if result.filename %}
<div>
<span>{{ _("Filename") }}:</span>
<span>{{ result.filename }}</span>
</div>
{% endif %}
{% if result.size %}
<div>
<span>{{ _("Filesize") }}:</span>
<span>{{ result.size }}</span>
</div>
{% endif %}
{% if result.time %}
<div>
<span>{{ _("Date") }}:</span>
<span>{{ result.time }}</span>
</div>
{% endif %}
{% if result.mimetype %}
<div>
<span>{{ _("Type") }}:</span>
<span>{{ result.mimetype }}</span>
</div>
{% endif %}
</div>
{% if result.embedded %}
{% if result.mtype in ("audio", "video") %}
<p class="altlink">
<a class="btn-collapse collapsed media-loader disabled_if_nojs"
data-target="#result-media-{{ index }}"
data-btn-text-collapsed="{{ _("show media") }}"
data-btn-text-not-collapsed="{{ _("hide media") }}"
>
{{ _("show media") }}
</a>
</p>
<div id="result-media-{{ index }}" class="embedded-{{ result.mtype }} invisible">
<{{ result.mtype }} controls preload="metadata" {% if result.thumbnail %}poster="{{ result.thumbnail }}" {% endif %}>
<source src="{{result.embedded}}" type="{{ result.mtype }}/{{ result.subtype }}">
</{{ result.mtype }}>
</div>
{% else %}
<p class="altlink">
<a href="{{result.embedded }}" target="_blank" rel="noopener noreferrer" download>
{{ _("Download") }}
</a>
</p>
{% endif %}
{% endif %}
{{ result_sub_footer(result) }}
{{ result_footer(result) }}
@@ -1,45 +0,0 @@
{% from 'simple/macros.html' import result_header, result_sub_header, result_sub_footer, result_footer, result_link with context %}
{% from 'simple/icons.html' import icon_small %}
{{- result_header(result, favicons, image_proxify) -}}
{{- result_sub_header(result) -}}
{%- if result.embedded -%}
<small> &bull; <a class="text-info btn-collapse collapsed cursor-pointer media-loader disabled_if_nojs" data-toggle="collapse" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">
{%- if result.mtype == 'audio' %}{{ icon_small('musical-notes') -}}
{%- elif result.mtype == 'video' %} {{ icon_small('play') -}}
{%- endif %} {{ _('show media') }}</a></small>
{%- endif -%}
{%- if result.embedded -%}
<div id="result-media-{{ index }}" class="collapse invisible">
{{- result.embedded|safe -}}
</div>
{%- endif -%}
{%- if result.abstract %}<p class="result-content result-abstract">{{ result.abstract|safe }}</p>{% endif -%}
{%- if result.img_src -%}
<div class="container-fluid">
<div class="row">
<img src="{{ image_proxify(result.img_src) }}" alt="{{ result.title|striptags }}" title="{{ result.title|striptags }}" style="width: auto; max-height: 60px; min-height: 60px;" class="col-xs-2 col-sm-4 col-md-4 result-content">
{%- if result.content %}<p class="result-content col-xs-8 col-sm-8 col-md-8">{{ result.content|safe }}</p>{% endif -%}
</div>
</div>
{%- else -%}
{%- if result.content %}<p class="result-content">{{ result.content|safe }}</p>{% endif -%}
{%- endif -%}
<table class="result-metadata result-content">
{%- if result.author %}<tr><td>{{ _('Author') }}</td><td>{{ result.author|safe }}</td></tr>{% endif -%}
{%- if result.filename %}<tr><td>{{ _('Filename') }}</td><td>{{ result.filename|safe }}</td></tr>{% endif -%}
{%- if result.size %}<tr><td>{{ _('Filesize') }}</td><td>{{ result.size|safe }}</td></tr>{%- endif -%}
{%- if result.time %}<tr><td>{{ _('Date') }}</td><td>{{ result.time|safe }}</td></tr>{% endif -%}
{%- if result.mtype %}<tr><td>{{ _('Type') }}</td><td>{{ result.mtype|safe }}/{{ result.subtype|safe }}</td></tr>{% endif -%}
</table>
{{ result_footer(result) }}