summaryrefslogtreecommitdiff
path: root/docs/narr/static.rst
blob: 02ee68eb6be768f9f3f0b5d567c0706e0d1e947f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
Static Resources
================

:mod:`pyramid` makes it possible to serve up "static" (non-dynamic)
resources from a directory on a filesystem.  This chapter describes
how to configure :mod:`pyramid` to do so.

.. index::
   triple: view; zcml; static resource
   single: add_static_view

.. _static_resources_section:

Serving Static Resources Using a ZCML Directive
-----------------------------------------------

Use of the ``static`` ZCML directive or the
:meth:`pyramid.configuration.configurator.add_static_view` method
is the preferred way to instruct :mod:`pyramid` to serve static
resources such as JavaScript and CSS files. This mechanism makes
static files available at a name relative to the application root URL,
e.g. ``/static``.

Note that the ``path`` provided to ``static`` may be a fully qualified
:term:`resource specification`, a package-relative path, or an
*absolute path*.  The ``path`` with the value ``a/b/c/static`` of a
``static`` directive in a ZCML file that resides in the "mypackage"
package will resolve to a package-qualified resource such as
``some_package:a/b/c/static``.

Here's an example of a ``static`` ZCML directive that will serve files
up under the ``/static`` URL from the ``/var/www/static`` directory of
the computer which runs the :mod:`pyramid` application using an
absolute path.

.. code-block:: xml
   :linenos:

   <static
      name="static"
      path="/var/www/static"
      />

Here's an example of a ``static`` directive that will serve files up
under the ``/static`` URL from the ``a/b/c/static`` directory of the
Python package named ``some_package`` using a fully qualified
:term:`resource specification`.

.. code-block:: xml
   :linenos:

   <static
      name="static"
      path="some_package:a/b/c/static"
      />

Here's an example of a ``static`` directive that will serve files up
under the ``/static`` URL from the ``static`` directory of the Python
package in which the ``configure.zcml`` file lives using a
package-relative path.

.. code-block:: xml
   :linenos:

   <static
      name="static"
      path="static"
      />

Whether you use for ``path`` a fully qualified resource specification,
an absolute path, or a package-relative path, When you place your
static files on the filesystem in the directory represented as the
``path`` of the directive, you will then be able to view the static
files in this directory via a browser at URLs prefixed with the
directive's ``name``.  For instance if the ``static`` directive's
``name`` is ``static`` and the static directive's ``path`` is
``/path/to/static``, ``http://localhost:6543/static/foo.js`` will
return the file ``/path/to/static/dir/foo.js``.  The static directory
may contain subdirectories recursively, and any subdirectories may
hold files; these will be resolved by the static view as you would
expect.

While the ``path`` argument can be a number of different things, the
``name`` argument of the ``static`` ZCML directive can also be one of
a number of things: a *view name* or a *URL*.  The above examples have
shown usage of the ``name`` argument as a view name.  When ``name`` is
a *URL* (or any string with a slash (``/``) in it), static resources
can be served from an external webserver.  In this mode, the ``name``
is used as the URL prefix when generating a URL using
:func:`pyramid.url.static_url`.

.. note::

   Using :func:`pyramid.url.static_url` in conjunction with a
   :meth:`pyramid.configuration.Configurator.add_static_view` makes
   it possible to put static media on a separate webserver during
   production (if the ``name`` argument to
   :meth:`pyramid.configuration.Configurator.add_static_view` is a
   URL), while keeping static media package-internal and served by the
   development webserver during development (if the ``name`` argument
   to :meth:`pyramid.configuration.Configurator.add_static_view` is
   a view name).  To create such a circumstance, we suggest using the
   :func:`pyramid.settings.get_settings` API in conjunction with a
   setting in the application ``.ini`` file named ``media_location``.
   Then set the value of ``media_location`` to either a view name or a
   URL depending on whether the application is being run in
   development or in production (use a different `.ini`` file for
   production than you do for development).  This is just a suggestion
   for a pattern; any setting name other than ``media_location`` could
   be used.

For example, the ``static`` ZCML directive may be fed a ``name``
argument which is ``http://example.com/images``:

.. code-block:: xml
   :linenos:

   <static
      name="http://example.com/images"
      path="mypackage:images"
      />

Because the ``static`` ZCML directive is provided with a ``name``
argument that is the URL prefix ``http://example.com/images``,
subsequent calls to :func:`pyramid.url.static_url` with paths that
start with the ``path`` argument passed to
:meth:`pyramid.configuration.Configurator.add_static_view` will
generate a URL something like ``http://example.com/logo.png``.  The
external webserver listening on ``example.com`` must be itself
configured to respond properly to such a request.  The
:func:`pyramid.url.static_url` API is discussed in more detail
later in this chapter.

The :meth:`pyramid.configuration.Configurator.add_static_view`
method offers an imperative equivalent to the ``static`` ZCML
directive.  Use of the ``add_static_view`` imperative configuration
method is completely equivalent to using ZCML for the same purpose.

.. index::
   single: generating static resource urls
   single: static resource urls

.. _generating_static_resource_urls:

Generating Static Resource URLs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When a :ref:`static_directive` ZCML directive or a call to the
``add_static_view`` method of a
:class:`pyramid.configuration.Configurator` is used to register a
static resource directory, a special helper API named
:func:`pyramid.static_url` can be used to generate the appropriate
URL for a package resource that lives in one of the directories named
by the static registration ``path`` attribute.

For example, let's assume you create a set of ``static`` declarations
in ZCML like so:

.. code-block:: xml
   :linenos:

   <static
      name="static1"
      path="resources/1"
      />

   <static
      name="static2"
      path="resources/2"
      />

These declarations create URL-accessible directories which have URLs
which begin, respectively, with ``/static1`` and ``/static2``.  The
resources in the ``resources/1`` directory are consulted when a user
visits a URL which begins with ``/static1``, and the resources in the
``resources/2`` directory are consulted when a user visits a URL which
begins with ``/static2``.

You needn't generate the URLs to static resources "by hand" in such a
configuration.  Instead, use the :func:`pyramid.url.static_url` API
to generate them for you.  For example, let's imagine that the
following code lives in a module that shares the same directory as the
above ZCML file:

.. code-block:: python
   :linenos:

   from pyramid.url import static_url
   from pyramid.chameleon_zpt import render_template_to_response

   def my_view(request):
       css_url = static_url('resources/1/foo.css', request)
       js_url = static_url('resources/2/foo.js', request)
       return render_template_to_response('templates/my_template.pt',
                                          css_url = css_url,
                                          js_url = js_url)

If the request "application URL" of the running system is
``http://example.com``, the ``css_url`` generated above would be:
``http://example.com/static1/foo.css``.  The ``js_url`` generated
above would be ``http://example.com/static2/foo.js``.

One benefit of using the :func:`pyramid.url.static_url` function
rather than constructing static URLs "by hand" is that if you need to
change the ``name`` of a static URL declaration in ZCML, the generated
URLs will continue to resolve properly after the rename.

URLs may also be generated by :func:`pyramid.url.static_url` to
static resources that live *outside* the :mod:`pyramid`
application.  This will happen when the ``name`` argument provided to
the ``static`` ZCML directive or the
:meth:`pyramid.configuration.Configurator.add_static_view` API
associated with the path fed to :func:`pyramid.url.static_url` is a
*URL* instead of a view name.  For example, the ``name`` argument
given to either the ZCML directive or the configurator API may be
``http://example.com`` while the the ``path`` given may be
``mypackage:images``:

.. code-block:: xml
   :linenos:

   <static
      name="static1"
      path="mypackage:images"
      />

Under such a configuration, the URL generated by ``static_url`` for
resources which begin with ``mypackage:images`` will be prefixed with
``http://example.com/images``:

.. code-block:: python

   static_url('mypackage:images/logo.png', request)
   # -> http://example.com/images/logo.png

.. index::
   single: static resource view

Advanced: Serving Static Resources Using a View Callable
--------------------------------------------------------

For more flexibility, static resources can be served by a :term:`view
callable` which you register manually.  For example, you may want
static resources to only be available when the :term:`context` of the
view is of a particular type, or when the request is of a particular
type.

The :class:`pyramid.view.static` helper class is used to perform
this task. This class creates an object that is capable acting as a
:mod:`pyramid` view callable which serves static resources from a
directory.  For instance, to serve files within a directory located on
your filesystem at ``/path/to/static/dir`` mounted at the URL path
``/static`` in your application, create an instance of the
:class:`pyramid.view.static` class inside a ``static.py`` file in
your application root as below.

.. ignore-next-block
.. code-block:: python
   :linenos:

   from pyramid.view import static
   static_view = static('/path/to/static/dir')

.. note:: the argument to :class:`pyramid.view.static` can also be
   a relative pathname, e.g. ``my/static`` (meaning relative to the
   Python package of the module in which the view is being defined).
   It can also be a :term:`resource specification`
   (e.g. ``anotherpackage:some/subdirectory``) or it can be a
   "here-relative" path (e.g. ``some/subdirectory``).  If the path is
   "here-relative", it is relative to the package of the module in
   which the static view is defined.
 
Subsequently, you may wire this view up to be accessible as
``/static`` using either the
:mod:`pyramid.configuration.Configurator.add_view` method or the
``<view>`` ZCML directive in your application's ``configure.zcml``
against either the class or interface that represents your root
object.  For example (ZCML):

.. code-block:: xml
   :linenos:

    <view
      context=".models.Root"
      view=".static.static_view"
      name="static"
    />   

In this case, ``.models.Root`` refers to the class of which your
:mod:`pyramid` application's root object is an instance.

You can also provide a ``context`` of ``*`` if you want the name
``static`` to be accessible as the static view against any model.
This will also allow ``/static/foo.js`` to work, but it will allow for
``/anything/static/foo.js`` too, as long as ``anything`` itself is
resolvable.

Note that you cannot use the :func:`pyramid.static_url` API to
generate URLs against resources made accessible by registering a
custom static view.

.. warning::

   To ensure that model objects contained in the root don't "shadow"
   your static view (model objects take precedence during traversal),
   or to ensure that your root object's ``__getitem__`` is never
   called when a static resource is requested, you can refer to your
   static resources as registered above in URLs as,
   e.g. ``/@@static/foo.js``.  This is completely equivalent to
   ``/static/foo.js``.  See :ref:`traversal_chapter` for information
   about "goggles" (``@@``).