= Do's and Dont's for Application Writers = This is a guide to writing Django applications, the goals I'm aiming for are: * the application should be easy to install for users * the application should play nice with other applications These are the guidelines I would propose, please comment and discuss. I hope this can become something everyone in the Django community can agree on. Throughout this document I will need to refer to an imaginary application for examples; let's call it mnemosyne, and put it in ibofobi.apps. When I need to refer to paths, I'll use relative paths rooted at the mnemosyne package directory. == Basics == * Your application should be Python 2.3-safe. Notably you should not use {{{@decorator}}}-syntax, instead do this: {{{ def foo(answer): ... foo = decorate(foo) }}} However, if your application is about developing (or requires) decorators, then perhaps this criteria makes no sense. Otherwise, it should be pointed out that Django itself has decorators functions, and so does a lot of Django apps. --erob == Templates == * To avoid name clashes with templates from other applications all your templates should go into {{{mnemosyne/templates/mnemosyne/}}}. The {{{mnemosyne/templates}}} directory will need to be added to {{{TEMPLATE_DIRS}}}, which happens automatically if the user has the {{{app_directory}}} template-loader in {{{TEMPLATE_LOADERS}}}, which is the preferred way to handle this. * Your templates should all extend a single {{{base}}}-template specific to your application, in my example it would be {{{mnemosyne/templates/mnemosyne/base.html}}} and all my templates would start with {{{ {% extends "mnemosyne/base.html" %} }}} and the {{{mnemosyne/base}}} template should either be a complete HTML-document, or (and I think this is preferrable) just be {{{ {% extends "base.html" %} }}} (unless you have any pages which should go under the admin, then they should extend {{{admin/base_site}}}.) ''Should I ''s/base/base_site/'' to be consistent with the admin-application? I personally prefer ''{{{bare}}}'' and ''{{{base}}}'' over ''{{{base}}}'' and ''{{{base_site}}}''; they are more concise and they lack the CTS-inducing underscore.'' * Your templates should assume that the site-templates have these blocks for you to fill: * {{{title}}}; obviously, the document's title, must be {{{}}}-safe, so no formatting * {{{extrahead}}}; anything extra your document wants stuffed into the {{{<head>}}} (e.g., a {{{<style>}}} or {{{<link>}}}s) * {{{content}}}; the main content of the document * You should refer to media-files with a configurable prefix, in the example a good setting would be {{{MNEMOSYNE_MEDIA_ROOT}}}. For example: {{{ <link rel='stylesheet' href='{{ MNEMOSYNE_MEDIA_ROOT }}/my.css' /> }}} * You should refer to pages in your application with either relative links, or where this is impractical or just plain impossible, with a configurable prefix. In the example I would go with {{{MNEMOSYNE_ROOT}}}. * Please, please, please. Try to write templates as correct XHTML. == Template tags == * Your application should provide template tags for those features which do not depend on the actual request being handled, for example a hypothetical blog application might provide template tags to get a list of categories, etc. This way sites can easily integrate your application outside your applications own views. == Media files == * Your media-files should go into {{{mnemosyne/media/}}}. ''Should that be ''{{{mnemosyne/media/mnemosyne/}}}''? It would mirror the templates, and probably looks better in ''{{{Alias}}}''-directives in Apache-configurations ;)'' == Settings == * Your application should have decent default values for {{{MNEMOSYNE_ROOT}}} and {{{MNEMOSYNE_MEDIA_ROOT}}}, for example {{{/mnemosyne}}} and {{{/media/mnemosyne}}}. * If you use source control, or want to publish your application on the web, it may be a good idea to move sensitive or machine/user specific settings like database passwords and such out of the main settings.py file. Check out the SplitSettings page for some ideas how this could be done. == Package and module structure == * Separate generic apps that you are intending to distribute into a different project from other projects which might happen to use that app. To avoid clashes, use a name for the project which is unique to you, the author, such as one based on a domain name that you own. Examples: {{{ project_for_acme_com/ apps/ myapp/ ibofobi/ apps/ mnemosyne/ }}} rather than: {{{ project_for_acme_com/ apps/ myapp/ mnemosyne/ }}} This will enable your urls.py module to be fully portable. == URLs == * What would be a place to expect application-specific admin-URLs to go? = Somewhat related stuff = * A template for an application {{{setup.py}}}: {{{ try: from setuptools import setup except ImportError: from distutils.core import setup setup(name = "mnemosyne", author = "Sune Kirkeby", url = "http://ibofobi.dk/stuff/mnemosyne/", version = '0.1', packages = ['ibofobi', 'ibofobi.apps', 'ibofobi.apps.mnemosyne', 'ibofobi.apps.mnemosyne.models', 'ibofobi.apps.mnemosyne.views', 'ibofobi.apps.mnemosyne.urls'], package_dir = {'': 'src'}, package_data = {'ibofobi.apps.mnemosyne': ['templates/mnemosyne/*.html', 'media/*',],}, # distutils complain about these, anyone know an easy way to silence it? namespace_packages = ['ibofobi.apps'], zip_safe = True, ) }}} * Is {{{templates/<app-name>/}}} and {{{media/}}} created by {{{django-admin startapp}}}? Should they be? * It would be nice if doing things this way was more natural in Django, than doing it any other way. For example it would be nice if {{{django.conf.settings}}} was in {{{Context}}} as {{{settings}}}, so templates would have access to {{{MNEMOSYNE_ROOT}}} and {{{MNEMOSYNE_MEDIA_ROOT}}}. * A ten-minute walk-through of an application might be good, to make the points in this document easier to visualize. = Comments = I would prefer to use {{{django-users}}} for comments and discussions on this document, wikis have very poor threading :) So, if you have comments, or there's something you just plain disagree with, please bring it up there. There is a better place for discussion than d-users: http://groups.google.com/group/django-hotclub Can "I" please adopt this or nix it? seems silly to have both mentioned.