Package: django_layers
django layers=============This package provides support for "layers" of templates and static resourcesthat can be selecting depending on the request context.WARNING: The API documented below may change significantly before version 1.0Why?----Using layers you can provide alternative sets of templates ("skins")depending on different contexts. For example, using the same CMS youcan, from a single code base, host different frontend designs, havea different visitor/admin frontend, do A/B testing, etc.All of this within the same instance (so no separate instances each runningwith their own settings.py configuration)How?----pip/easy_install this package, django_layersThen add 'layers.middleware.LayerLoaderMiddleware' to yourMIDDLEWARE_CLASSES, e.g.MIDDLEWARE_CLASSES = ('layers.middleware.LayerLoaderMiddleware',...)Also, add 'layers.loader.LayerLoader' at the top of your TEMPLATE_LOADERS, priorto any other/django loaders. E.g.TEMPLATE_LOADERS = ('layers.loader.LayerLoader','django.template.loaders.filesystem.Loader','django.template.loaders.app_directories.Loader',)Optionally, if you have separate collections of static resources for each layer,add 'layers.finders.AppLayerFinder' as the first STATICFILE_FINDERS:STATICFILES_FINDERS = ('layers.finders.AppLayerFinder',# ...'django.contrib.staticfiles.finders.FileSystemFinder','django.contrib.staticfiles.finders.AppDirectoriesFinder',)and define which layers you have and where they need to be collected toLAYERS = {'visitor-a':STATIC_ROOT + '/visitor-a','visitor-b':STATIC_ROOT + '/visitor-b'}Now you can start using layers.Create the same templates as before but in stead (or on top of) storing themin your package's templates folder, store them in a folder called'layers/**layername**/templates'.E.g. you could havemypackage/templates/mypackage/foo.htmlmypackage/layers/visitor-a/templates/mypackage/foo.htmlmypackage/layers/visitor-b/templates/mypackage/foo.htmlThis creates two layers, "visitor-a" and "visitor-b" and a fallback if nolayer is selected.Additionally, create a file "layers.py" with a function "get_layers" thatwill return the layer to be used, e.g.def get_layer(request):if request.get_host().startswith("a."):return "visitor-a"if request.get_host().startswith("b."):return "visitor-b"You can do anything you like in the "get_layer" callable, as long as you returna layer or nothing.When requesting Django to render the template "mypackage/foo.html", it willrender any of the three templates above depending on the request context (thehostname used).Configuration per layer-----------------------You can also provide some global shared configuration per layer. Since alllayers will share the same settings.py, it's not possible to use that forlayer specific configuration.You can do this by defining a 'get_config' method in your package's layers.pyfile. This will simply return a dict containing the layer specific data foreach layer.E.g.def get_config():return {'visitor-a': dict(site_id=1, mailto='visitor-a@example.com'),'visitor-b': dict(site_id=2, mailto='visitor-b@example.com')}You can then access the current layer's configuration using 'get_current_layer':from layers.middleware import get_current_layerdef myview(request):layer = get_current_layer()return SomeModel.objects.filter(site_id=layer['site_id'])django_layers will scan all your packages for configuration and merge theconfiguration dictionaries together if necessary.Static resources per layer--------------------------You can store your per-layer statics in any app installed in your applicationin the layers/**layer**/**layername**/statics folder, e.g. you could havemypackage/static/css/foo.cssmypackage/layers/visitor-a/static/css/foo.cssmypackage/layers/visitor-b/static/css/foo.cssA request for /static/css/foo.css will result in visitor-a/static/css/foo.cssif the visitor-a layer is active, it will result in visitor-b/static/css/foo.cssif the visitor-b layer is active or in mypackage/static/css/foo.css otherwise.Static resources are served by the django 'runserver' command or by a webserverrunning in front of your application.django_layers provides an upgraded `runserver` command that knows which staticresources to serve depending on the active layer. It also comes with a`collectlayers` command that collects the layers into distinct staticfolders,similar to how 'collectstatic' works. Which layer is collected where is definedby the 'LAYERS' settings.py setting.E.g. given the previous LAYERS definitionpython manage.py collectlayerswill collect the global static resources and visitor-a specific resources intoSTATIC_ROOT + '/visitor-a' and another copy of the global static resourcesand visitor-b specific resources into STATIC_ROOT + '/visitor-b'