Skip to content

Commit

Permalink
global: refactor current_theme_icons
Browse files Browse the repository at this point in the history
* current_theme_icons doesn't need the application context anymore
  • Loading branch information
utnapischtim committed Jun 29, 2023
1 parent 7de64ef commit 49314bc
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 54 deletions.
16 changes: 12 additions & 4 deletions invenio_theme/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from flask import Blueprint

from . import config
from .icons import ThemeIcons
from .proxies import current_theme_icons
from .shared import menu
from .views import (
blueprint,
Expand All @@ -32,7 +34,10 @@ def __init__(self, app=None, **kwargs):
:param app: An instance of :class:`~flask.Flask`.
:param \**kwargs: Keyword arguments are passed to ``init_app`` method.
"""
self.app = None

if app:
self.app = app
self.init_app(app, **kwargs)

def init_app(self, app, **kwargs):
Expand Down Expand Up @@ -66,9 +71,7 @@ def init_app(self, app, **kwargs):
# Register context processor
@app.context_processor
def _theme_icon_ctx_processor():
from invenio_theme.proxies import current_theme_icons

return dict(current_theme_icons=current_theme_icons)
return {"current_theme_icons": current_theme_icons}

app.context_processor(lambda: {"menu": menu})

Expand All @@ -89,8 +92,13 @@ def init_config(self, app):
# Set THEME_<name>_TEMPLATE from <name>_TEMPLATE variables if not
# already set.
for varname in _vars:
theme_varname = "THEME{}".format(varname)
theme_varname = f"THEME_{varname}"
if app.config[theme_varname] is None:
app.config[theme_varname] = app.config[varname]

app.config.setdefault("ADMIN_BASE_TEMPLATE", config.ADMIN_BASE_TEMPLATE)

@property
def icons(self):
"""Return icons."""
return ThemeIcons(self.app.config["APP_THEME"], self.app.config["THEME_ICONS"])
59 changes: 59 additions & 0 deletions invenio_theme/icons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2020 CERN.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

"""Theme Icons."""


class ThemeIcons:
"""Defines names for theme icons used in CSS classes.
This class is used via the proxy ``current_theme_icons``, which initialize
it with the right parameters. Also, the ``current_theme_icons`` proxy is
automatically available in templates because it is added via a template
context processor.
Examples of usage:
.. code-block:: python
current_theme_icons.cogs
current_theme_icons['cogs']
Note, that the proxy is dependent on the Flask application context, thus
it can often be useful to wrap it in lazy string, to only have it evaluated
when needed:
.. code-block:: python
from invenio_i18n import LazyString
LazyString(lambda: f'<i class="{current_theme_icons.cogs}"></i>')
"""

def __init__(self, app_themes, theme_icons):
"""Initialize."""
self._app_themes = app_themes or []
self._theme_icons = theme_icons or {}

def __getattr__(self, name):
"""Attribute support for getting an icon."""
return self.__getitem__(name)

def __getitem__(self, key):
"""Get a icon for a specific theme."""
for theme in self._app_themes:
if theme in self._theme_icons:
# Icon exists for theme
if key in self._theme_icons[theme]:
return self._theme_icons[theme][key]
# Pattern exists for theme
# If an icon is not defined we create it via a pattern -
# e.g. the smeantic ui pattern is ``{} icon`` and the
# bootstrap3 pattern is ``fa fa-{} fa-fw``.
elif "*" in self._theme_icons[theme]:
return self._theme_icons[theme]["*"].format(key)
return ""
52 changes: 2 additions & 50 deletions invenio_theme/proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,59 +11,11 @@
from flask import current_app
from werkzeug.local import LocalProxy

from .icons import ThemeIcons

current_theme_icons = LocalProxy(
lambda: ThemeIcons(
current_app.config["APP_THEME"], current_app.config["THEME_ICONS"]
)
)
"""Proxy to the theme icon finder."""


class ThemeIcons:
"""Defines names for theme icons used in CSS classes.
This class is used via the proxy ``current_theme_icons``, which initialize
it with the right parameters. Also, the ``current_theme_icons`` proxy is
automatically available in templates because it is added via a template
context processor.
Examples of usage:
.. code-block:: python
current_theme_icons.cogs
current_theme_icons['cogs']
Note, that the proxy is dependent on the Flask application context, thus
it can often be useful to wrap it in lazy string, to only have it evaluated
when needed:
.. code-block:: python
from speaklater import make_lazy_string
make_lazy_string(lambda: f'<i class="{current_theme_icons.cogs}"></i>')
"""

def __init__(self, app_themes, theme_icons):
"""Initialize."""
self._app_themes = app_themes or []
self._theme_icons = theme_icons or {}

def __getattr__(self, name):
"""Attribute support for getting an icon."""
return self.__getitem__(name)

def __getitem__(self, key):
"""Get a icon for a specific theme."""
for theme in self._app_themes:
if theme in self._theme_icons:
# Icon exists for theme
if key in self._theme_icons[theme]:
return self._theme_icons[theme][key]
# Pattern exists for theme
# If an icon is not defined we create it via a pattern -
# e.g. the smeantic ui pattern is ``{} icon`` and the
# bootstrap3 pattern is ``fa fa-{} fa-fw``.
elif "*" in self._theme_icons[theme]:
return self._theme_icons[theme]["*"].format(key)
return ""

0 comments on commit 49314bc

Please sign in to comment.