Database-configured Theming in Pylons
Yesterday I looked at very simple theming in Pylons, and mentioned that I'd prefer loading the current theme from the database rather than the configuration file. So this evening I decided to see if I could achieve that.
Looking in environment.py, I noticed that SQLAlchemy and the models were being configured and initialised last in the load_environment method. I moved those two lines up to the top of that method, and changed "config" to "app_conf". Then I simply did a normal Session.query() to fetch my theme name out of the "variables" table in my database.
Now that I had my theme name, I constructed my theme directory using the path to the themes directory from my configuration file and the name of the theme from the database. Then I set up my static files and tempaltes directories using the new theme directory.
Lastly, I wanted to do something that Drupal, the CMS that powers this blog, does with it's theming system. Drupal has a set of fall-back templates so that if you don't provide (whether by mistake or by choice) all the templates a theme needs, the default Drupal templates are used. This was very easy to set up, because Mako's TemplateLookup class accepts a list of template paths. So all I did was add the normal Pylons template path to the list as well.
So now my file looks like this:
def load_environment(global_conf, app_conf): """ Configure the Pylons environment via the ``pylons.config`` object """ # Setup the SQLAlchemy database engine engine = engine_from_config(app_conf, 'sqlalchemy.') init_model(engine) # Pull out theme variable theme = Session.query(Variable).get(u'theme') if not theme: theme_name = u'default' else: theme_name = theme.value # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) theme_dir = os.path.join(app_conf[u'themes.directory'], theme_name) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(theme_dir, 'public'), templates=[os.path.join(theme_dir, 'templates'), os.path.join(root, 'templates')])
As usual, any comments or suggestions are welcome





