Ask Your Question

Jinja includes and extends path issue

asked 2010-11-16 05:57:46 -0600

graeme's avatar

updated 2010-11-21 14:00:37 -0600

Evgeny's avatar

If TEMPLATE_DIRS is set, Askbot will use a template from that directory. However jinja still gets the original include path (I guess jinga gets the template root and jinga include paths are always relative to the template root).

Extends is unpredictable. {% extends "user.html" %} in user_stats etc gets it from the directory specified in TEMPLATE_DIRS whereas {% extends "two_column_body.html" %} seems to get it from the original (at least edits to it do not show).

I realise that using TEMPLATE_DIRS is not the currently recommended way to customise, but it would be nice to have it working consistently: it almost does, and I am more comfortable with it as it lets me use pip install rather than git to install askbot on my server.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted

answered 2010-11-16 20:16:34 -0600

Evgeny's avatar

updated 2010-11-17 21:52:41 -0600

Made a fix to this one too in version 0.6.30 (but read a note** below). Suppose you want to have custom skins placed in directory:


Add setting to your

ASKBOT_EXTRA_SKINS_DIR = '/home/graeme/forum_skins'

Note that the usual TEMPLATE_DIRS setting is not used by askbot.

Make one and have the following structure:


Skin names must be unique and should not clash with the "canned" ones. At this point names "default" and "common" are taken. Add to your skin only files that you want to make different from default, adding other files is not necessary.

edit: to debug Jinja2 templates set DEBUG=True and TEMPLATE_DEBUG=False in it's strange, but this combination of settings makes the errors in templates trigger debugging output.

Then you'll be able to set the skin from settings, however you have to restart the application to apply changes. Hopefully we'll figure out how to force jinja recompile templates on the go some time in the future.

The django's TEMPLATE_DIRS approach does not work with askbot because of how skinning system is set up. The few reasons for not using TEMPLATE_DIRS are: skins come with media as well as templates, they have name. So there is a specific expectation of the directory structure and I've decided to bypass the TEMPLATE_DIRS entirely. Maybe it's not the best way to go, drop a note if you have an idea...


Unfortunately at this point you are on your own in keeping your custom templates in sync with the project. A much more productive option is to use git to merge master branch with your changes to the default template.

edit flag offensive delete link more


maybe it's better to make ASKBOT_EXTRA_SKIN_DIRS into a string rather than a tuple of strings?
Evgeny's avatar Evgeny  ( 2010-11-16 20:22:01 -0600 )edit
Tuple rather than string seems consistent with usual Django config. For the moment, I am only making fairly minor changes to a few files so its easier to keep it in sync manually rather than learning git. If my skin diverges more that might change.
graeme's avatar graeme  ( 2010-11-16 23:42:02 -0600 )edit
I've turned it into a string for now because it makes more sense IMO to keep all extra skins in one directory. I think django uses tuple because there may be many apps and each can have own skin directories.
Evgeny's avatar Evgeny  ( 2010-11-17 20:47:48 -0600 )edit

I noticed this answer is a couple years old. Is it still advisable to edit the default templates directly (as opposed to creating a skin)? I've got my local setup cloned from the master branch so I can easily merge core changes.

mynameistechno's avatar mynameistechno  ( 2013-03-20 14:07:23 -0600 )edit

answered 2010-11-17 03:45:37 -0600

graeme's avatar

updated 2010-11-17 06:27:56 -0600

The current fix (in 0.6.30) had an issue with media paths. The media filter always returned paths to the default skin.

This (in skins/ did work:

skin_found = False
for skins in reversed(get_skin_dirs()):

    #see if file exists, if not, try skins 'default', then 'common'
    file_path = os.path.join(skins, use_skin, 'media', url)
    if not os.path.isfile(file_path):
        file_path = os.path.join(skins, 'default', 'media', url)
        if os.path.isfile(file_path):
            use_skin = 'default'
            skin_found = True
            file_path = os.path.join(skins, 'common', 'media', url)
            if os.path.isfile(file_path):
                use_skin = 'common'
                skin_found = True
        skin_found = True

if not skin_found:
    log_message = 'missing media resource %s in skin %s' \
                % (url, use_skin)
    use_skin = ''
    return None

This is not well tested ("works for me") and has not been tested at all with multiple skin directories.

Also note your server config needs to be updated if you use the new skin setting to ensure media is served directly by the server (rather than by the Django fast cgi process).

edit: if you are doing a variant of the default theme, you do need to copy the image directory over, as there are some relative references to images from the css.

edit flag offensive delete link more


Thanks, you are right. I've added these changes now, actually I had to redo some more stuff so that custom location skins work with runserver as well. Thanks again.
Evgeny's avatar Evgeny  ( 2010-11-17 20:21:53 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2010-11-16 05:57:46 -0600

Seen: 5,867 times

Last updated: Nov 21 '10