In Step 03: Type-Specific Views we had 3 “content types” (SiteFolder, Folder, and Document.) All, however, used the same view and template.
Pyramid traversal though lets you bind a view to a particular content type.
$ cd ../../resources; mkdir step03; cd step03
(Unchanged) Copy the following into step03/application.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from resources import bootstrap
def main():
config = Configurator(root_factory=bootstrap)
config.scan("views")
app = config.make_wsgi_app()
return app
if __name__ == '__main__':
app = main()
server = make_server(host='0.0.0.0', port=8080, app=app)
server.serve_forever()
|
Copy the following into step03/views.py:
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 | from pyramid.view import view_config
from resources import SiteFolder
from resources import Folder
from resources import Document
class ProjectorViews(object):
def __init__(self, context, request):
self.context = context
self.request = request
@view_config(renderer="templates/site_view.pt",
context=SiteFolder)
def site_view(self):
return {"children": self.context.values()}
@view_config(renderer="templates/folder_view.pt",
context=Folder)
def folder_view(self):
return {"children": self.context.values()}
@view_config(renderer="templates/document_view.pt",
context=Document)
def document_view(self):
return {}
|
(Unchanged) Copy the following into step03/resources.py:
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 | class Folder(dict):
def __init__(self, name, parent, title):
self.__name__ = name
self.__parent__ = parent
self.title = title
class SiteFolder(Folder):
pass
class Document(object):
def __init__(self, name, parent, title):
self.__name__ = name
self.__parent__ = parent
self.title = title
root = SiteFolder('', None, 'Projector Site')
def bootstrap(request):
# Let's make:
# /
# doc1
# doc2
# folder1/
# doc1
doc1 = Document('doc1', root, 'Document 01')
root['doc1'] = doc1
doc2 = Document('doc2', root, 'Document 02')
root['doc2'] = doc2
folder1 = Folder('folder1', root, 'Folder 01')
root['folder1'] = folder1
# Only has to be unique in folder
doc11 = Document('doc1', folder1, 'Document 01')
folder1['doc1'] = doc11
return root
|
Copy the following into step03/templates/document_view.pt:
1 2 3 | <div>
<h2>Document Title: ${context.title}</h2>
</div>
|
Copy the following into step03/templates/folder_view.pt:
1 2 3 4 5 6 7 8 | <div>
<h2>Folder Title: ${context.title}</h2>
<ul>
<li tal:repeat="child children">
<a href="${child.__name__}">${child.title}</a>
</li>
</ul>
</div>
|
Copy the following into step03/templates/site_view.pt:
1 2 3 4 5 6 7 8 | <div>
<h2>SiteFolder Title: ${context.title}</h2>
<ul>
<li tal:repeat="child children">
<a href="${child.__name__}">${child.title}</a>
</li>
</ul>
</div>
|
Copy the following into step03/tests.py:
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 | import unittest
from pyramid.testing import DummyRequest
from pyramid.testing import DummyResource
class DummySite(object):
title = "Dummy Title"
__name__ = "dummy"
__parent__ = None
def values(self):
return [1,2,3,4,5]
class ProjectorViewsUnitTests(unittest.TestCase):
def _makeOne(self, context, request):
from views import ProjectorViews
inst = ProjectorViews(context, request)
return inst
def test_site_view(self):
request = DummyRequest()
context = DummySite()
inst = self._makeOne(context, request)
result = inst.site_view()
self.assertEqual(len(result['children']), 5)
def test_folder_view(self):
request = DummyRequest()
context = DummySite()
inst = self._makeOne(context, request)
result = inst.folder_view()
self.assertEqual(len(result['children']), 5)
def test_document_view(self):
request = DummyRequest()
context = DummyResource()
inst = self._makeOne(context, request)
result = inst.document_view()
self.assertEqual(result, {})
class ProjectorFunctionalTests(unittest.TestCase):
def setUp(self):
from application import main
app = main()
from webtest import TestApp
self.testapp = TestApp(app)
def test_it(self):
res = self.testapp.get('/', status=200)
self.assertTrue('SiteFolder' in res.body)
res = self.testapp.get('/folder1', status=200)
self.assertTrue('Folder' in res.body)
res = self.testapp.get('/doc1', status=200)
self.assertTrue('Document' in res.body)
res = self.testapp.get('/doc2', status=200)
self.assertTrue('Document' in res.body)
res = self.testapp.get('/folder1/doc1', status=200)
self.assertTrue('Document' in res.body)
|
$ nosetests should report running 4 tests.
$ python application.py
Open http://127.0.0.1:8080/ in your browser.
Our container views now calculate the list of children and pass into the template, letting us navigate to children.
The tests now need more ceremony to mock up some dummy values, then test against them.