Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend a theme / override theme specific files #1557

Open
brunob opened this issue Apr 9, 2019 · 2 comments

Comments

Projects
None yet
2 participants
@brunob
Copy link
Contributor

commented Apr 9, 2019

Hi, we are a providing a public instance on searx.infini.fr a we use a personal theme based on Frama theme #276. Our theme is available here https://framagit.org/infini/themes-outils-libres/tree/master/searx and as you can see it override almost all of the files of oscar theme.

I'd like to switch our instance on simple theme and customize it a bit (just changing the favicon and add a link to a personal script in order to insert the top navbar we use on our public tools). For now, i haven't found a clean and maintainable way to extend an existing theme :

  • some people advice to copy all theme files and customize them as here #875 (comment)
  • or, worst, to directly patch the base theme #791 (comment) which "might conflict with future patches of searx"

I've seen thath jinja API propose join_path(template, parent) http://jinja.pocoo.org/docs/2.10/api/#jinja2.Environment.join_path but i'm not sure this is what i'm looking for and it doesn't seem to be used in searx.

So, is there a way to "make a theme based on another one" ?

PS : it may be related to #1042

@dalf

This comment has been minimized.

Copy link
Collaborator

commented Apr 11, 2019

Short answer : not possible, may be later but it requires a huge change.

Longer answer : Each time a .html template file reference another template file, the name of the theme is included.

Example for oscar/index.html

{% extends "oscar/base.html" %}
{% block content %}
...
                <h1 class="text-hide center-block"><img class="center-block img-responsive" src="{{ url_for('static', filename='img/searx_logo.png') }}" alt="searx logo"/>searx</h1>
...
    <div class="row">
        <div class="text-center col-sm-12 col-md-12">
            {% include 'oscar/search_full.html' %}
        </div>
...
{% endblock %}

And oscar/search_full.html :

{% from 'oscar/macros.html' import icon %}
...
        {% include 'oscar/advanced.html' %}
...

And oscar/advanced.html :

...
{% include 'oscar/categories.html' %}
...
{% include 'oscar/time-range.html' %}
...
{% include 'oscar/languages.html' %}
...

Scenario : you add yourtheme/search_full.html, declare the fact that yourtheme is based on oscar (a special file for example), so :

  • if you add yourtheme/search_full.html, index.html (declared in the oscar theme) will automatically use it.
  • when yourtheme/search_full.html include advanced.html, it will use oscar/advanced.html

Of course after an update :

  • if oscar/advanced.html doesn't exist anymore, yourtheme/search_full.html will have to be updated.
  • if oscar/index.html doesn't reference anymore search_full.html the customization won't work.

To sum up, it is okay for small and simple modifications, but at one point it becomes really not easy to maintain. Since theme are processed when they are called, it is not possible to pull the updates and automatically checks for inconsistencies (without scripts and tests that don't exist now).

About the implementation of this : with the default configuration Flask allows only one templates directory (no theme). That's why the name on the theme is included with each {% include ... %}. Note that {% include ... %} can reference multiple templates : http://jinja.pocoo.org/docs/2.10/templates/#include (so it is possible to do this {%include ['yourtheme/file.html', 'oscar/file.html'] %} (I know, not a real solution).

So to solve this request, the name of the theme needs to be removed from all {% include ... %} and searx must find a way to still get the template. This is not a simple thing because all themes have to be tested after the modification.

I don't think Blueprint are the solution because it's the same feature (search) but different templates.

But Loader are may be the solution : https://buxty.com/b/2012/05/custom-template-folders-with-flask/
and http://jinja.pocoo.org/docs/2.10/api/#loaders (provide a direct implementation for #1042).

The solution I see : write a custom Loader that use the "theme" variable inside the environement to automatically add the theme name to the template path.

@brunob

This comment has been minimized.

Copy link
Contributor Author

commented Apr 11, 2019

@dalf thx for the explanation, i understand that for now i have to copy all files from a theme to customize it :)

FTR, i come form a "world" where we have a function that allow to override the path of templates https://code.spip.net/autodoc/tree/ecrire/inc/utils.php.html#function_find_in_path and a template can declare that it override another one. This allow for instance to make a personal theme that declare it override oscar and just put the changed files in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.