Skip to main content

Dynamically get URLs for your site-level and app-level static media.

Project description

django-staticmedia
==================

* Bugs_

.. _Bugs: http://bugs.launchpad.net/django-staticmedia

.. contents::

Overview
--------

django-staticmedia provides a lightweight framework for dynamically
obtaining the URLs and paths of your site-level and app-level static
media, such as images and css stylesheets. It lets you avoid
hardcoding absolute, site-specific paths to your static media files in
site-level and/or app-level templates, or in your Python code
(declaring widget assets). It can also be used as an alternative to
using a settings directive, much like 'ADMIN_MEDIA_PREFIX'.

Features
~~~~~~~~

* ``staticmedia.url``, ``staticmedia.path`` and
``staticmedia.resolve`` functions that you can use to dynamically
obtain the URL, path, or both (respectively) of your static media in
your Python code.

* A ``{% mediaurl %}`` and ``{% mediapath %}`` template tags.

* A submodule and management commands for generating configuraton
directives for various common web servers.

* A convenience function for generating urlpatterns that statically
serve your static media from Django (although this is slow and
insecure).


Settings
--------

``STATICMEDIA_MOUNTS``

Default: ``[]``

A sequence of ``(mount_url, mount_path)`` tuples. The term 'mount' in
this case just means directories on the filesystem, ``mount_path``,
that are expected to be available at a given url on the site,
``mount_url``. Usually these are served by a webserver, but can be
served by Django for testing purposes.

``STATICMEDIA_URL``

Default: ``/appmedia``

The URL prefix to use for each application media mount.


Using django-staticmedia
------------------------

Bundling media with your application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To bundle static media with your application, create a ``media``
directory in the root directory of you Django application::

myapp/
|---media/
\---models.py
\---urls.py

This ``media`` directory will then be picked up by django-staticmedia
as a mount point.

Getting the absolute URL or path for static media
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Static media should be specified relative to mount points. Extending
the above application structure example::

myapp/
|---media/
| \---button.png
\---models.py
\---urls.py

From Python code::

>>> import staticmedia
>>> staticmedia.resolve('button.png')
('/appmedia/myapp/button.png', '/path/to/myapp/media/button.png')
>>> staticmedia.url('button.png')
'/appmedia/myapp/button.png'
>>> staticmedia.path('button.png')
'/path/to/myapp/media/button.png'

Or from a template::

{% load staticmedia %}

{% mediaurl "button.png" %}
<!-- or -->
{% mediapath "button.png" %}


django-staticmedia first goes through your mounts specified with the
``STATICMEDIA_MOUNTS`` setting, and then through each application
mount (installed applications with a ``media`` directory in the
package). The URL the first mount point in which a 'button.png' file
exists is used.

In the above case, 'button.png' was found in the application media
directory, and since the default value of the ``STATICMEDIA_URL`` is
``'/appmedia'``, the expected URL of the static media file is
'/appmedia/myapp/button.png'.

Suppose you wanted to have a custom 'button.png' for a particular site
to use instead of the one bundled with the application media. You
could add a mount to ``STATICMEDIA_MOUNTS``::

STATICMEDIA_MOUNTS = (
('/sitemedia', '/sites/mysite/sitemedia')
)

Provided that a '/sites/mysite/sitemedia/button.png' file exists, a
call to ``staticmedia.resolve`` would now return
``'/sitemedia/button.png'``.


Avoiding media filename conflicts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A good convention to use is to 'namespace' application media, much
like application templates::

myapp/
|---media/
| \---myapp
| \---button.png
\---models.py
\---urls.py

Requesting media would look like::

>>> staticmedia.resolve('myapp/button.png')
('/appmedia/myapp/myapp/button.png',
'/path/to/myapp/media/myapp/button.png')

# if we have a 'myapp/button.png' file in the '/sitemedia'
# mount in the example above, then:

>>> staticmedia.resolve('myapp/button.png')
('/sitemedia/myapp/button.png', '/sites/mysite/sitemedia/myapp/button.png')


django-staticmedia and web servers
----------------------------------

Normally you want to delegate the serving of your static media to web
servers. django-staticmedia comes with a submodule to dynamically
generate configuration directives for some common web servers::

>>> from staticmedia import serverconf

>>> serverconf.nginx()
'location /appmedia/myapp { alias /path/to/myapp/media; }'

>>> serverconf.apache()
'Alias "/appmedia/myapp" "/path/to/myapp/media"'

>>> serverconf.lighttpd()
'alias.url += ( "/appmedia/myapp" => "/path/to/myapp/media" )

>>> serverconf.nginx(access_log='off')
'location /appmedia/myapp { alias /path/to/myapp/media; access_log off; }'

>>> serverconf.apache(diroptions='Indexes')
'Alias "/appmedia/myapp" "/path/to/myapp/media"
<Directory "/path/to/myapp/media">Options Indexes</Directory>'

You can also use a management command to print out the configuration
directives::

./manage.pystaticmedianginxconflocation/appmedia/myappalias/path/to/myapp/media; ./manage.py staticmedia apache-conf
Alias "/appmedia/myapp" "/path/to/myapp/media"

You can't use 'macro parameter character #' in math mode ./manage.py staticmedia list-mounts
/appmedia/myapp /path/to/myapp/media

Or from Python::

>>> import staticmedia
>>> staticmedia.get_mount_points()
(('/appmedia/myapp', '/path/to/myapp/media'),)


Serving static media with Django
--------------------------------

A convenience function is provided for automatically generating
urlpatterns that serve your mount points with the
``django.views.static.serve`` method. This isn't recommended outside
of a development environment as its slow and insecure.

In your urlconf::

from django.conf.urls.defaults import *
import staticmedia

urlpatterns = patterns(
'',
# your urls here
) + staticmedia.serve()

``staticmedia.serve`` optionally takes two arguments:

* ``debug``: If ``True``, only generate url patterns if the ``DEBUG``
setting is ``True``.
* ``show_indexes``: Takes a boolean that gets passed directly to
``django.views.static.serve`` (see official Django documentation for
details about this)

Changelog
---------

0.2.2
~~~~~

* Moved readme and license file to standard location.

0.2.1
~~~~~

* Fix for use of incorrect path separators returned by the ``resolve``
function on Windows.

0.2
~~~

* ``resolve`` function returns media url and path (backwards
incompatible), and added ``url`` and ``path`` methods (use ``url``
for previous behavior)
* templatetag library renamed to ``staticmedia`` to be more explicit,
and the ``media`` template tag split into ``mediaurl`` and
``mediapath`` template tags (backwards incompatible).
* added ``StaticMediaNotFound`` exception, which can be suppressed the
template tags by adding 'fail_silently' at the end of the tags

0.1.4
~~~~~

* Fixed ``Directory`` directive generated by
``staticmedia.serverconf.apache``.

0.1.3
~~~~~

* Renamed ``staticmedia.conf`` to ``staticmedia.serverconf``
* Added support for generating lighttpd ``alias`` directives
* Added support for passing nginx directives for the generated
``location`` directive

0.1.2
~~~~~

* Fixed template tag to allow resolving of context variables.
* Fixed url pattern generation in ``staticmedia.serve``.
* Added ``show_indexes`` argument to ``staticmedia.serve``.

0.1.1
~~~~~

* Fixed packaging.

0.1
~~~

* Initial release.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page