bd31ceb288f4906e46484c3014df9c5a023a0d7f
[philo.git] / docs / models / nodes-and-views.rst
1 Nodes and Views: Building Website structure
2 ===========================================
3 .. currentmodule:: philo.models
4
5 Nodes
6 -----
7
8 :class:`Node`\ s are the basic building blocks of a website using Philo. They define the URL hierarchy and connect each URL to a :class:`View` subclass instance which is used to generate an HttpResponse.
9
10 .. class:: Node
11
12    :class:`!Node` subclasses :class:`TreeEntity`. It defines the following additional methods and attributes:
13
14    .. attribute:: view
15
16       :class:`GenericForeignKey` to a non-abstract subclass of :class:`View`
17
18    .. attribute:: accepts_subpath
19
20       A property shortcut for :attr:`self.view.accepts_subpath <View.accepts_subpath>`
21
22    .. method:: render_to_response(request[, extra_context=None])
23
24       This is a shortcut method for :meth:`View.render_to_response`
25
26    .. method:: get_absolute_url([request=None, with_domain=False, secure=False])
27
28       This is essentially a shortcut for calling :meth:`construct_url` without a subpath - which will return the URL of the Node.
29
30    .. method:: construct_url([subpath="/", request=None, with_domain=False, secure=False])
31
32       This method will do its best to construct a URL based on the Node's location. If with_domain is True, that URL will include a domain and a protocol; if secure is True as well, the protocol will be https. The request will be used to construct a domain in cases where a call to :meth:`Site.objects.get_current` fails.
33
34       Node urls will not contain a trailing slash unless a subpath is provided which ends with a trailing slash. Subpaths are expected to begin with a slash, as if returned by :func:`django.core.urlresolvers.reverse`.
35
36       :meth:`construct_url` may raise the following exceptions:
37
38       - :class:`NoReverseMatch` if "philo-root" is not reversable -- for example, if :mod:`philo.urls` is not included anywhere in your urlpatterns.
39       - :class:`Site.DoesNotExist <ObjectDoesNotExist>` if with_domain is True but no :class:`Site` or :class:`RequestSite` can be built.
40       - :class:`AncestorDoesNotExist` if the root node of the site isn't an ancestor of the node constructing the URL.
41
42 Views
43 -----
44
45 Abstract View Models
46 ++++++++++++++++++++
47 .. class:: View
48
49    :class:`!View` is an abstract model that represents an item which can be "rendered", either in response to an :class:`HttpRequest` or as a standalone. It subclasses :class:`Entity`, and defines the following additional methods and attributes:
50
51    .. attribute:: accepts_subpath
52
53       Defines whether this :class:`View` can handle subpaths. Default: ``False``
54
55    .. method:: handles_subpath(subpath)
56
57       Returns True if the the :class:`View` handles the given subpath, and False otherwise.
58
59    .. attribute:: nodes
60
61       A generic relation back to nodes.
62
63    .. method:: reverse([view_name=None, args=None, kwargs=None, node=None, obj=None])
64
65       If :attr:`accepts_subpath` is True, try to reverse a URL using the given parameters using ``self`` as the urlconf.
66
67       If ``obj`` is provided, :meth:`get_reverse_params` will be called and the results will be combined with any ``view_name``, ``args``, and ``kwargs`` that may have been passed in.
68
69       This method will raise the following exceptions:
70
71       - :class:`ViewDoesNotProvideSubpaths` if :attr:`accepts_subpath` is False.
72       - :class:`ViewCanNotProvideSubpath` if a reversal is not possible.
73
74    .. method:: get_reverse_params(obj)
75
76       This method is not implemented on the base class. It should return a ``view_name``, ``args``, ``kwargs`` tuple suitable for reversing a url for the given ``obj`` using ``self`` as the urlconf. If a reversal will not be possible, this method should raise :class:`ViewCanNotProvideSubpath`.
77
78    .. method:: attributes_with_node(node)
79
80       Returns a :class:`QuerySetMapper` using the :class:`node <Node>`'s attributes as a passthrough.
81
82    .. method:: render_to_response(request[, extra_context=None])
83
84       Renders the :class:`View` as an :class:`HttpResponse`. This will raise :const:`philo.exceptions.MIDDLEWARE_NOT_CONFIGURED` if the `request` doesn't have an attached :class:`Node`. This can happen if :class:`philo.middleware.RequestNodeMiddleware` is not in :setting:`settings.MIDDLEWARE_CLASSES` or if it is not functioning correctly.
85
86       :meth:`!render_to_response` will send the :obj:`view_about_to_render <philo.signals.view_about_to_render>` signal, then call :meth:`actually_render_to_response`, and finally send the :obj:`view_finished_rendering <philo.signals.view_finished_rendering>` signal before returning the ``response``.
87
88    .. method:: actually_render_to_response(request[, extra_context=None])
89
90       Concrete subclasses must override this method to provide the business logic for turning a ``request`` and ``extra_context`` into an :class:`HttpResponse`.
91
92 .. class:: MultiView
93
94    :class:`!MultiView` is an abstract model which represents a section of related pages - for example, a :class:`~philo.contrib.penfield.BlogView` might have a foreign key to :class:`Page`\ s for an index, an entry detail, an entry archive by day, and so on. :class:`!MultiView` subclasses :class:`View`, and defines the following additional methods and attributes:
95
96    .. attribute:: accepts_subpath
97
98       Same as :attr:`View.accepts_subpath`. Default: ``True``
99
100    .. attribute:: urlpatterns
101
102       Returns urlpatterns that point to views (generally methods on the class). :class:`!MultiView`\ s can be thought of as "managing" these subpaths.
103
104    .. method:: actually_render_to_response(request[, extra_context=None])
105
106       Resolves the remaining subpath left after finding this :class:`View`'s node using :attr:`self.urlpatterns <urlpatterns>` and renders the view function (or method) found with the appropriate args and kwargs.
107
108    .. method:: get_context()
109
110       Hook for providing instance-specific context - such as the value of a Field - to all views.
111
112    .. method:: basic_view(field_name)
113
114       Given the name of a field on ``self``, accesses the value of that field and treats it as a :class:`View` instance. Creates a basic context based on :meth:`get_context` and any extra_context that was passed in, then calls the :class:`View` instance's :meth:`~View.render_to_response` method. This method is meant to be called to return a view function appropriate for :attr:`urlpatterns`.
115
116 Concrete View Subclasses
117 ++++++++++++++++++++++++
118
119 .. class:: Redirect
120
121    A :class:`View` subclass. Defines a 301 or 302 redirect to a different url on an absolute or relative path.
122
123    .. attribute:: STATUS_CODES
124
125       A choices tuple of redirect status codes (temporary or permanent).
126
127    .. attribute:: status_code
128
129       An :class:`IntegerField` which uses :attr:`STATUS_CODES` as its choices. Determines whether the redirect is considered temporary or permanent.
130
131    .. attribute:: target_node
132
133       An optional :class:`ForeignKey` to a :class:`Node`. If provided, that node will be used as the basis for the redirect.
134
135    .. attribute:: url_or_subpath
136
137       A :class:`CharField` which may contain an absolute or relative URL. This will be validated with :class:`philo.validators.RedirectValidator`.
138
139    .. attribute:: reversing_parameters
140
141       A :class:`~philo.models.fields.JSONField` instance. If the value of :attr:`reversing_parameters` is not None, the :attr:`url_or_subpath` will be treated as the name of a view to be reversed. The value of :attr:`reversing_parameters` will be passed into the reversal as args if it is a list or as kwargs if it is a dictionary.
142
143    .. attribute:: target_url
144
145       Calculates and returns the target url based on the :attr:`target_node`, :attr:`url_or_subpath`, and :attr:`reversing_parameters`.
146
147    .. method:: actually_render_to_response(request[, extra_context=None])
148
149       Returns an :class:`HttpResponseRedirect` to :attr:`self.target`.
150
151 .. class:: File
152
153    A :class:`View` subclass. Stores an arbitrary file.
154
155    .. attribute:: mimetype
156
157       Defines the mimetype of the uploaded file. This will not be validated.
158
159    .. attribute:: file
160
161       Contains the uploaded file. Files are uploaded to ``philo/files/%Y/%m/%d``.
162
163    .. method:: __unicode__()
164
165       Returns the name of :attr:`self.file <file>`.
166
167 Pages
168 *****
169
170 :class:`Page`\ s are the most frequently used :class:`View` subclass. They define a basic HTML page and its associated content. Each :class:`Page` renders itself according to a :class:`Template`. The :class:`Template` may contain :ttag:`container` tags, which define related :class:`Contentlet`\ s and :class:`ContentReference`\ s for any page using that :class:`Template`.
171
172 .. class:: Page
173
174    A :class:`View` subclass. Represents a page - something which is rendered according to a template. The page will have a number of related Contentlets depending on the template selected - but these will appear only after the page has been saved with that template.
175
176    .. attribute:: template
177
178       A :class:`ForeignKey` to the :class:`Template` used to render this :class:`Page`.
179
180    .. attribute:: title
181
182       The name of this page. Chances are this will be used for organization - i.e. finding the page in a list of pages - rather than for display.
183
184    .. attribute:: containers
185
186       Returns :attr:`self.template.containers <Template.containers>` - a tuple containing the specs of all :ttag:`container`\ s defined in the :class:`Template`. The value will be cached on the instance so that multiple accesses will be less expensive.
187
188    .. method:: render_to_string([request=None, extra_context=None])
189
190       In addition to rendering as an :class:`HttpResponse`, a :class:`Page` can also render as a string. This means, for example, that :class:`Page`\ s can be used to render emails or other non-HTML-related content with the same :ttag:`container`-based functionality as is used for HTML.
191
192    .. method:: actually_render_to_response(request[, extra_context=None])
193
194       Returns an :class:`HttpResponse` with the content of the :meth:`render_to_string` method and the mimetype set to :attr:`self.template.mimetype <Template.mimetype>`.
195
196    .. clean_fields(self[, exclude=None)
197
198       This is an override of the default model clean_fields method. Essentially, in addition to validating the fields, this method validates the :class:`Template` instance that is used to render this :class:`Page`. This is useful for catching template errors before they show up as 500 errors on a live site.
199
200    .. method:: __unicode__()
201
202       Returns :meth:`self.title <title>`
203
204 .. class:: Template
205
206    Subclasses :class:`TreeModel`. Represents a database-driven django template. Defines the following additional methods and attributes:
207
208    .. attribute:: name
209
210       The name of the template. Used for organization and debugging.
211
212    .. attribute:: documentation
213
214       Can be used to let users know what the template is meant to be used for.
215
216    .. attribute:: mimetype
217
218       Defines the mimetype of the template. This is not validated. Default: ``text/html``.
219
220    .. attribute:: code
221
222       An insecure :class:`~philo.models.fields.TemplateField` containing the django template code for this template.
223
224    .. attribute:: containers
225
226       Returns a tuple where the first item is a list of names of contentlets referenced by containers, and the second item is a list of tuples of names and contenttypes of contentreferences referenced by containers. This will break if there is a recursive extends or includes in the template code. Due to the use of an empty Context, any extends or include tags with dynamic arguments probably won't work.
227
228    .. method:: __unicode__()
229
230       Returns the results of the :meth:`~TreeModel.get_path` method, using the "name" field and a chevron joiner.
231
232 .. class:: Contentlet
233
234    Defines a piece of content on a page. This content is treated as a secure :class:`~philo.models.fields.TemplateField`.
235
236    .. attribute:: page
237
238       The page which this :class:`Contentlet` is related to.
239
240    .. attribute:: name
241
242       This represents the name of the container as defined by a :ttag:`container` tag.
243
244    .. attribute:: content
245
246       A secure :class:`~philo.models.fields.TemplateField` holding the content for this :class:`Contentlet`. Note that actually using this field as a template requires use of the :ttag:`include_string` template tag.
247
248    .. method:: __unicode__()
249
250       Returns :attr:`self.name <name>`
251
252 .. class:: ContentReference
253
254    Defines a model instance related to a page.
255
256    .. attribute:: page
257
258       The page which this :class:`ContentReference` is related to.
259
260    .. attribute:: name
261
262       This represents the name of the container as defined by a :ttag:`container` tag.
263
264    .. attribute:: content
265
266       A :class:`GenericForeignKey` to a model instance. The content type of this instance is defined by the :ttag:`container` tag which defines this :class:`ContentReference`.
267
268    .. method:: __unicode__()
269
270       Returns :attr:`self.name <name>`