Splitter¶
CWF provides the ability to seperate your website into multiple sections that you can then stitch together.
The following is provided to allow for this:
- Import modifiers
Functions to help with injecting values into and stealing values from import paths.
- Website declaration
Classes that let you specify what makes up your website.
Creating a website¶
Below is a slightly stripped down version of the how I setup the website that was the inspiration for CWF.
At it’s core you have webthings
and webthings_main
in your import path
where webthings_main
knows about each part of your website
, and webthings
knows how to combine together the parts of
webthings_main
and what settings to set for the website to work.
So, given the following structure:
# Where the logic of the site actually goes.
# each urls.py here uses CWF Section logic
webthings_main/
__init__.py
index/
__init__.py
urls.py
views.py
news/
__init__.py
models.py
urls.py
views.py
events/
__init__.py
models.py
urls.py
views.py
photos/
__init__.py
models.py
urls.py
views.py
utils/
template_loaders.py
templates/
errors/
404.html
500.html
# All the configuration for the website is in a seperate module
webthings/
__init__.py
config/
__init__.py
common/
__init__.py
settings.py
site.py
urls.py
settings/
__init__.py
inclusions.py
logging.py
testing.py
other.py
wsgi/
prod.py
Note
For cwf to be able to put all your models under the
webthings_main.models
namespace, all your models must have
Meta.app_label
set:
from django.db import models
class AwesomeModel(models.Model):
[..]
class Meta:
app_label = 'webthings_main'
And each models.py
must have __all__
explicitly set to all the
models contained within:
__all__ = [AwesomeModel]
webthings.__init__
from cwf.splitter.imports import install_failed_import_handler
import sys
import os
def project_setup():
# Install failed import handler
install_failed_import_handler()
# Setup the site
from webthings.config.common import site
webthings.config.common.site
from cwf.splitter.website import Website
from cwf.splitter.parts import Part as P
from cwf.splitter.imports import inject
from cwf.sections import Section
import os
########################
### SETTINGS
########################
from webthings.config.common import settings
class theSite(object):
site = Section("", name='webthings').configure(''
, promote_children=True
)
js = Section("", name='js').configure(''
, alias = 'js'
, display = False
, module = None
, kls = None
)
# Create webthings.settings
settings.THESITE = theSite
inject(settings, 'webthings.settings')
########################
### ACTIVE
########################
# Create the website object to specify each part of the website
website = Website('webthings_main'
, P('index', first=True)
, P('news')
, P('events')
, P('photos')
)
# And configure the website
website.configure()
# Just make sure we can get the urls
# Note we also have webthings_main.models available now
# Because website.configure gives us webthings_main.urls and webthings_main.models
from webthings_main.urls import site
########################
### URLS
########################
# Create urls
# Depends on webthings being setup
# Note that settings.ROOT_URLCONF is set to 'urls'
from webthings.config.common import urls
inject(urls, 'urls')
webthings.config.common.settings
from cwf.splitter.imports import steal, inject
import os
########################
### INJECTION
########################
this_dir = os.path.dirname(__file__)
settings_dir = os.path.abspath(os.path.join(this_dir, '..', 'settings'))
steal('inclusions', 'logging', 'testing', 'other'
, folder=settings_dir, globals=globals(), locals=locals()
)
if DEBUG:
LOGGING['loggers']['']['level'] = 'DEBUG'
########################
### INSTALLED
########################
INSTALLED_APPS += (
'webthings_main'
, 'cwf'
, 'grappelli'
, 'django.contrib.admin'
, 'django.contrib.sessions'
, 'south'
)
########################
### TEMPLATES
########################
def __get_template_dirs__():
"""In a function so I don't pollute the settings namespace"""
import pkg_resources
webthings_main_folder = pkg_resources.resource_filename("webthings_main", "")
error_page_templates = pkg_resources.resource_filename("webthings_main", 'templates/errors')
return (webthings_main_folder, error_page_templates, )
TEMPLATE_DIRS = __get_template_dirs__()
# Use the AppNameLoader as suggested in the templates section of the docs
# To make it so cwf templates are available
TEMPLATE_LOADERS = (
'webthings_main.utils.template_loaders.AppNameLoader'
,
)
ROOT_URLCONF = 'urls'
webthings.config.common.urls
from django.conf.urls.defaults import patterns, include
from django.contrib import admin
from django.conf import settings
########################
### GRAPPELLI
########################
haveAdmin = 'django.contrib.admin' in settings.INSTALLED_APPS
if haveAdmin:
admin.autodiscover()
########################
### CWF GENERATED URLS
########################
theSite = settings.THESITE
site = theSite.site
from webthings_main.urls import site as main_site
site.merge(main_site, take_base=True)
if hasattr(theSite, 'js'):
js = theSite.js
site.adopt(js, consider_for_menu=False, include_as = 'js')
urlpatterns = site.patterns()
########################
### ADMIN URLS
########################
if haveAdmin:
urlpatterns += patterns('', (r'^grappelli/', include('grappelli.urls')))
urlpatterns += patterns('', (r'^admin/', include(admin.site.urls)))
webthings.wsgi.prod
import webthings
import sys
import os
def serve_site(production=True, internet=True):
"""
Ensure we have DJANGO_SETTINGS_MODULE environment variable
And return wsgi application for django
"""
os.umask(2)
# Setup project and set django_settings_module
os.environ['DJANGO_SETTINGS_MODULE'] = 'webthings.settings'
webthings.project_setup()
# Create and return wsgi app for django
import django.core.handlers.wsgi
return django.core.handlers.wsgi.WSGIHandler()
application = serve_site()
You can then have a uwsgi configuration that looks like:
[uwsgi]
chdir=/path/to/webthings/wsgi
module=prod:application
vacuum=True
home=/path/to/venv_for_webthings
uid=www-data
gid=www-data
disable-logging=true
touch-reload=/path/to/webthings/wsgi/prod.py
And an nginx configuration that looks like:
server {
server_name webthings;
upstream webthings {
ip_hash;
server unix:///run/uwsgi/app/webthings/socket;
}
location / {
include uwsgi_params;
uwsgi_pass webthings;
}
}