summaryrefslogtreecommitdiff
path: root/docs/narr/introduction.rst
blob: fdc3ce77b1d34a761211ada3b1e64a6b37fc67aa (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
:mod:`repoze.bfg` Introduction
==============================

:mod:`repoze.bfg` is a Python web framework.  It is inspired by
:term:`Zope`, :term:`Pylons`, and :term:`Django`.  :mod:`repoze.bfg`
uses the :term:`WSGI` protocol to handle requests and responses.

Similarities to Other Frameworks
--------------------------------

.. sidebar:: Django's Authors Explain Why It Doesn't Use "MVC" Terminology

  Django appears to be a MVC framework, but you call the Controller
  the "view", and the View the "template". How come you don't use the
  standard names?  Well, the standard names are debatable.

  In our interpretation of MVC, the "view" describes the data that
  gets presented to the user. It's not necessarily how the data looks,
  but which data is presented. The view describes which data you see,
  not how you see it. It's a subtle distinction.

  So, in our case, a "view" is the Python callback function for a
  particular URL, because that callback function describes which data
  is presented.

  Furthermore, it's sensible to separate content from presentation -
  which is where templates come in. In Django, a "view" describes
  which data is presented, but a view normally delegates to a
  template, which describes how the data is presented.

  Where does the "controller" fit in, then? In Django's case, it's
  probably the framework itself: the machinery that sends a request to
  the appropriate view, according to the Django URL configuration.

:mod:`repoze.bfg` was inspired by :term:`Zope`, :term:`Pylons` and
:term:`Django`.

The :mod:`repoze.bfg` concept of :term:`traversal` is inspired by
:term:`Zope`.  Additionally, :mod:`repoze.bfg` uses a :term:`Zope
Component Architecture` :term:`application registry` internally, as
does Zope 2, Zope 3, and :term:`Grok`.  Like Zope, :mod:`repoze.bfg`
allows you to create applications which do not need to be forked or
otherwise modified to be extended or overridden by a third party
developer.

The :mod:`repoze.bfg` concept of :term:`URL dispatch` is inspired by
the :term:`Routes` system used by :term:`Pylons`.  Like Pylons,
:mod:`repoze.bfg` is mostly policy-free.  It makes no assertions about
which database you should use, and its built-in templating facilities
are only for convenience.  In essence, it only supplies a mechanism to
map URLs to :term:`view` code, along with a convention for calling
those views.  You are free to use third-party components in your
application that fit your needs.  Also like Pylons, :mod:`repoze.bfg`
is dependent upon :term:`WSGI`.

The Django docs explain that Django is not an "MVC"
("model/view/controller") framework in their `FAQ
<http://www.djangoproject.com/documentation/faq/>`_.  The sidebar to
the right has the Django authors' take on why "MVC" terminology
doesn't match the web very well.  The concepts of :term:`view` and
:term:`model` are used by :mod:`repoze.bfg` as they would be by
Django.

The skeleton code generator of :mod:`repoze.bfg` generates a directory
layout very similar to the directory layout suggested by the `Django
Book <http://www.djangobook.com/>`_ .  

Differences from Other Frameworks
---------------------------------

Like :term:`Zope`, the :mod:`repoze.bfg` framework imposes more
`control inversion <http://plope.com/control_inversion>`_ upon
application developers than other Python frameworks such as
:term:`Pylons`.  For example :mod:`repoze.bfg` allows you to
explicitly resolve a URL to a :term:`context` object before invoking a
:term:`view`.  Pylons and other Python "MVC" frameworks have no such
intermediate step; they resolve a URL directly to a "controller".
Another example: using the :mod:`repoze.bfg` security subsystem
assumes that you're willing to attach an :term:`ACL` to a
:term:`context` object; the ACL is checked by the framework itself
instead of by user code, and access is permitted or denied by the
framework itself rather than by user code.  Such a task would
typically be performed by user-space decorators in other Python web
frameworks.

Like Zope, but unlike :term:`Pylons` applications or most
:term:`Django` applications, when you build a :mod:`repoze.bfg`
application, if you obey certain constraints, the application you
produce can be reused, modified, re-integrated, or extended by
third-party developers without modification to the original
application itself.  See :ref:`extending_chapter` for more information
about extending or modifying an existing :mod:`repoze.bfg`
application.

:mod:`repoze.bfg` uses a :term:`Zope Component Architecture`
:term:`application registry` under the hood.  However, while a Zope
application developer tends to need to understand concepts such as
"adapters", "utilities", and "interfaces" to create a non-trivial
application, a :mod:`repoze.bfg` application developer isn't required
to understand any of these concepts.  :mod:`repoze.bfg` hides all
interaction with the component architecture registry behind
special-purpose API functions.

Like :term:`Pylons`, but unlike :term:`Zope`, a :mod:`repoze.bfg`
application developer may use completely imperative code to perform
common framework configuration tasks such as adding a view or a route.
In Zope, :term:`ZCML` is typically required for similar purposes.  In
:term:`Grok`, :term:`decorator` objects and class-level declarations
are used for this purpose.  :mod:`repoze.bfg` *supports* :term:`ZCML`
and supports decorator-based configuration, but does not require
either. See :ref:`configuration_narr` for more information.

Also unlike :term:`Zope` and unlike other "full-featured" frameworks
such as :term:`Django`, :mod:`repoze.bfg` makes no assumptions about
which persistence mechanisms you should use to build an application.
Zope applications are typically reliant on :term:`ZODB`;
:mod:`repoze.bfg` allows you to build :term:`ZODB` applications, but
it has no reliance on the ZODB package.  Likewise, :term:`Django`
tends to assume that you want to store your application's data in a
relational database.  :mod:`repoze.bfg` makes no such assumption; it
allows you to use a relational database but doesn't encourage or
discourage an application developer about such a decision.

Why?
----

*Familiarity*: As web developers, we've become accustomed to working
in very particular ways over the years.  This framework is a
canonization of practices that "fit our brains".

*Simplicity*: :mod:`repoze.bfg` attempts to be a *"pay only for what
you eat"* framework in which you can be productive quickly with
partial knowledge.  We contrast this with *"pay up front for what
anyone might eventually want to eat"* frameworks, which tend to expect
you to understand a great many concepts and technologies fully before
you can be truly productive.  :mod:`repoze.bfg` doesn't force you to
use any particular technology to produce an application, and we try to
keep the core set of concepts you need to understand to a minimum.

*Minimalism*: :mod:`repoze.bfg` provides only the very basics: *URL to
code mapping*, *templating*, *security*, and *resources*.  There is
not much more to the framework than these pieces: you are expected to
provide the rest.

*Documentation*: Because :mod:`repoze.bfg` is minimal, it's relatively
easy to keep its documentation up-to-date, which is helpful to bring
new developers up to speed.  It's our goal that nothing remain
undocumented about :mod:`repoze.bfg`.

*Speed*: :mod:`repoze.bfg` is faster than many other popular Python
web frameworks for common tasks such as templating and simple response
generation.  The "hardware is cheap" mantra has its limits when you're
responsible for managing a great many machines: the fewer you need,
the less pain you'll have.

It's Tested
-----------

*If it ain't tested, it's broke.* We strive to test :mod:`repoze.bfg`
completely.  Below a run of the ``nosetests`` command configured to
show code coverage information run against the :mod:`repoze.bfg`
trunk shortly after the 1.2a1 release.

.. code-block:: bash
   :linenos:

    [chrism@snowpro trunk]$ python setup.py nosetests --with-coverage
    running nosetests
    running egg_info
    writing requirements to repoze.bfg.egg-info/requires.txt
    writing repoze.bfg.egg-info/PKG-INFO
    writing namespace_packages to repoze.bfg.egg-info/namespace_packages.txt
    writing top-level names to repoze.bfg.egg-info/top_level.txt
    writing dependency_links to repoze.bfg.egg-info/dependency_links.txt
    writing entry points to repoze.bfg.egg-info/entry_points.txt
    writing manifest file 'repoze.bfg.egg-info/SOURCES.txt'
    running build_ext
    ...........................................................................
    ...........................................................................
    ...........................................................................
    ...........................................................................
    ...........................................................................
    ...........................................................................
    ...........................................................................
    ...........................................................................
    ...........................................................................
    ...........................................................................
    .................................................
    Name                                                   Stmts   Exec  Cover   Missing
    ------------------------------------------------------------------------------------
    repoze.bfg                                                 0      0   100%   
    repoze.bfg.authentication                                198    198   100%   
    repoze.bfg.authorization                                  51     51   100%   
    repoze.bfg.chameleon_text                                 46     46   100%   
    repoze.bfg.chameleon_zpt                                  39     39   100%   
    repoze.bfg.compat                                          8      8   100%   
    repoze.bfg.compat.pkgutil_26                               0      0   100%   
    repoze.bfg.configuration                                 605    605   100%   
    repoze.bfg.encode                                         49     49   100%   
    repoze.bfg.events                                         22     22   100%   
    repoze.bfg.exceptions                                      2      2   100%   
    repoze.bfg.includes                                        1      1   100%   
    repoze.bfg.interfaces                                     66     66   100%   
    repoze.bfg.location                                       14     14   100%   
    repoze.bfg.log                                             9      9   100%   
    repoze.bfg.paster                                         58     58   100%   
    repoze.bfg.path                                           38     38   100%   
    repoze.bfg.registry                                       15     15   100%   
    repoze.bfg.renderers                                      47     47   100%   
    repoze.bfg.request                                        57     57   100%   
    repoze.bfg.resource                                      127    127   100%   
    repoze.bfg.router                                        109    109   100%   
    repoze.bfg.scripting                                      12     12   100%   
    repoze.bfg.security                                      123    123   100%   
    repoze.bfg.settings                                       38     38   100%   
    repoze.bfg.static                                         53     53   100%   
    repoze.bfg.testing                                       282    282   100%   
    repoze.bfg.tests                                           1      1   100%   
    repoze.bfg.tests.fixtureapp                                1      1   100%   
    repoze.bfg.tests.fixtureapp.models                         4      4   100%   
    repoze.bfg.tests.fixtureapp.subpackage                     1      1   100%   
    repoze.bfg.tests.fixtureapp.views                          4      4   100%   
    repoze.bfg.tests.grokkedapp                               53     53   100%   
    repoze.bfg.tests.grokkedapp.another                       37     37   100%   
    repoze.bfg.tests.grokkedapp.subpackage                     3      3   100%   
    repoze.bfg.tests.grokkedapp.subpackage.notinit             3      3   100%   
    repoze.bfg.tests.grokkedapp.subpackage.subsubpackage       3      3   100%   
    repoze.bfg.tests.routesapp                                 1      1   100%   
    repoze.bfg.tests.routesapp.views                           4      4   100%   
    repoze.bfg.tests.test_authentication                     487    487   100%   
    repoze.bfg.tests.test_authorization                      132    132   100%   
    repoze.bfg.tests.test_chameleon_text                     165    165   100%   
    repoze.bfg.tests.test_chameleon_zpt                      150    150   100%   
    repoze.bfg.tests.test_compat                               7      7   100%   
    repoze.bfg.tests.test_configuration                     2277   2277   100%   
    repoze.bfg.tests.test_encode                              47     47   100%   
    repoze.bfg.tests.test_events                              80     80   100%   
    repoze.bfg.tests.test_integration                         64     64   100%   
    repoze.bfg.tests.test_location                            34     34   100%   
    repoze.bfg.tests.test_log                                 11     11   100%   
    repoze.bfg.tests.test_paster                             111    111   100%   
    repoze.bfg.tests.test_path                               122    122   100%   
    repoze.bfg.tests.test_registry                            34     34   100%   
    repoze.bfg.tests.test_renderers                          150    150   100%   
    repoze.bfg.tests.test_request                            138    138   100%   
    repoze.bfg.tests.test_resource                           352    352   100%   
    repoze.bfg.tests.test_router                             494    494   100%   
    repoze.bfg.tests.test_scripting                           47     47   100%   
    repoze.bfg.tests.test_security                           315    315   100%   
    repoze.bfg.tests.test_settings                           138    138   100%   
    repoze.bfg.tests.test_static                             126    126   100%   
    repoze.bfg.tests.test_testing                            562    562   100%   
    repoze.bfg.tests.test_threadlocal                         74     74   100%   
    repoze.bfg.tests.test_traversal                          926    926   100%   
    repoze.bfg.tests.test_url                                224    224   100%   
    repoze.bfg.tests.test_urldispatch                        192    192   100%   
    repoze.bfg.tests.test_view                               407    407   100%   
    repoze.bfg.tests.test_wsgi                                99     99   100%   
    repoze.bfg.tests.test_zcml                               781    781   100%   
    repoze.bfg.threadlocal                                    26     26   100%   
    repoze.bfg.traversal                                     187    187   100%   
    repoze.bfg.url                                            76     76   100%   
    repoze.bfg.urldispatch                                   101    101   100%   
    repoze.bfg.view                                          120    120   100%   
    repoze.bfg.wsgi                                           26     26   100%   
    repoze.bfg.zcml                                          299    299   100%   
    ------------------------------------------------------------------------------------
    TOTAL                                                  11765  11765   100%   
    ----------------------------------------------------------------------
    Ran 799 tests in 2.080s

    OK