# Themes With the django library themes, you are able to include a theme to your django app. It includes an menu-, navigation-, action- and bottombar. ## Requirements ### Python You need to ensure that Pillow is available in your python environment. ## Integration Clone the library in your django application. ### Configurations in your settings.py Add the following line to the list ```INSTALLED_APPS```: ``` 'themes.apps.ThemesConfig', ``` ### Configurations in your urls.py Add the following imports at the top of urls.py, ``` from django.conf import settings from django.conf.urls.static import static ``` the following line to the list ```urlpatterns```: ``` path('search/', .views.search, name='search'), ``` and add this lines at the very end (after the definition of ```urlpatterns```: ``` if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ``` ### Create a view for the search Add a view to your views.py: ``` def search(request): logger.arning("Search not yet implemented...") return HttpResponse("Search not implemented...") ``` ### Settings Replace the ```STATIC_URL``` definition in your ```settings.py``` with the following lines: ``` STATIC_ROOT = os.path.join(BASE_DIR, 'data', 'static') STATIC_URL = 'static/' MEDIA_ROOT = os.path.join(BASE_DIR, 'data', 'media') MEDIA_URL = '/media/' ``` ### Collect static Before the static data is available, you need to execute the command ```$ python manage.py collectstatic``` ## Usage ### Add a template Before we can use the theme, we need to create a template. Here we use the file ```/templates/app/page.html``` with the following contenet: ``` {% extends "themes/"|add:settings.page_theme|add:"/base.html" %} {% block content %} {{ page_content|safe }} {% endblock content %} ``` In the block content is your content, which will be passed to the template by the variable ```page_content```. ### Use the template in your view Now you need to adapt your view. Here is an example view using the theme. ``` from django.shortcuts import render from django.conf import settings from themes import Context def example(request, rel_path=''): context = Context(request) # needs to be executed first because of time mesurement # return render(request, 'app/page.html', context=context) ``` ### Upload the logo If you havn't created a user yet, you should do so with ```python manage.py createsuperuser ```. Visit http://127.0.0.1:8000/admin and login with that user. Klick on *Settings* in the *Themes* section and then on the *Settings object (1)*. Upload a logo with the Upload mechanism of *Page image:* and click *Save*. ### Create a context adaption From this point on, you can see a blank themed page. With the adaption of the context variable, you are able to define the content of the 3 bars on the top and the page_content itself. The bottom bar will be defined in the django administration page (THEMES->Bottom bars->ADD BOTTOM BAR). You need to adapt your view method. Add this between the context definition and the return statement: ``` context_adaption( context, request, title="Additional title", rel_path=rel_path, page_content=f"

Dummy page

The rel_path is {rel_path}", ) ``` Here as an example ```context.py```: ``` import inspect import logging from django.conf import settings from django.utils.translation import gettext as _ from themes import empty_entry_parameters from themes import gray_icon_url from themes import color_icon_url logger = logging.getLogger(settings.ROOT_LOGGER_NAME).getChild(__name__) BACK_UID = "back" EDIT_UID = "edit" LOGIN_UID = "login" def context_adaption(context, request, **kwargs): caller_name = inspect.currentframe().f_back.f_code.co_name logger.debug("The caller of context_adaption was %s", caller_name) try: context.set_additional_title(kwargs.pop('title')) except KeyError: pass # no title in kwargs menubar(context, request, caller_name, **kwargs) navigationbar(context, request, caller_name, **kwargs) actionbar(context, request, caller_name, **kwargs) for key in kwargs: context[key] = kwargs[key] logger.debug("context adapted: %s", repr(context)) def menubar(context, request, caller_name, **kwargs): bar = context[context.MENUBAR] bar.append_entry( LOGIN_UID, # uid _('Settings'), # name color_icon_url(request, 'settings.png'), # icon '/app/dummy/settings/page', # url False, # left kwargs.get("rel_path") == "dummy/settings/page" # active ) finalise_bar(request, bar) # Show bar, if empty def navigationbar(context, request, caller_name, **kwargs): bar = context[context.NAVIGATIONBAR] bar.append_entry( BACK_UID, # uid _('Back'), # name gray_icon_url(request, 'back.png'), # icon 'javascript:history.back()', # url True, # left False # active ) finalise_bar(request, bar) # Show bar, if empty def actionbar(context, request, caller_name, **kwargs): bar = context[context.ACTIONBAR] bar.append_entry( EDIT_UID, # uid _('Edit'), # name color_icon_url(request, 'edit.png'), # icon '/app/dummy/edit/page', # url True, # left kwargs.get("rel_path") == "dummy/edit/page" # active ) finalise_bar(request, bar) # Show bar, if empty def finalise_bar(request, bar): if len(bar) == 0: bar.append_entry(*empty_entry_parameters(request)) ```