We are still in our simple content types (SiteFolder, Folder, and Document.) We haven’t yet switched back to Projector.
Before we do, though, let’s have the ability to add content. That is, folders allow adding subfolders or documents.
$ cd ../../resources; mkdir step04; cd step04
(Unchanged) Copy the following into step04/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 step04/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 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 | from random import randint
from pyramid.decorator import reify
from pyramid.httpexceptions import HTTPFound
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()}
@reify
def parent_info(self):
parent = self.context.__parent__
parent_url = self.request.resource_url(parent)
return {
'title': parent.title,
'url': parent_url}
@view_config(renderer="templates/folder_view.pt",
context=Folder)
def folder_view(self):
return {"children": self.context.values()}
@view_config(name="add_folder", context=Folder)
def add_folder_view(self):
# Make a new Folder
title = self.request.POST['folder_title']
name = str(randint(0, 999999))
new_folder = Folder(name, self.context, title)
self.context[name] = new_folder
# Redirect to the new folder
url = self.request.resource_url(new_folder)
return HTTPFound(location=url)
@view_config(name="add_document", context=Folder)
def add_document_view(self):
# Make a new Document
title = self.request.POST['document_title']
name = str(randint(0, 999999))
new_document = Document(name, self.context, title)
self.context[name] = new_document
# Redirect to the new document
url = self.request.resource_url(new_document)
return HTTPFound(location=url)
@view_config(renderer="templates/document_view.pt",
context=Document)
def document_view(self):
return {}
|
(Unchanged) Copy the following into step04/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 | 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 step04/templates/document_view.pt:
1 2 3 4 5 6 7 | <div>
<h2>Document Title: ${context.title} in Folder
<a
href="${view.parent_info.url}">${view.parent_info.title}</a>
<a
</h2>
</div>
|
Copy the following into step04/templates/folder_view.pt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <div>
<h2>Folder Title: ${context.title} in Folder
<a
href="${view.parent_info.url}">${view.parent_info.title}</a>
</h2>
<ul>
<li tal:repeat="child children">
<a href="${view.request.resource_url(child)}">${child.title}</a>
</li>
</ul>
<p>
<form action="add_folder" method="POST">
<label for="folder_title">Add: Folder
Title</label>
<input name="folder_title"/>
<input type="submit"/></form>
</p>
</div>
|
Copy the following into step04/templates/site_view.pt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <div>
<h2>SiteFolder Title: ${context.title}</h2>
<ul>
<li tal:repeat="child children">
<a href="${child.__name__}">${child.title}</a>
</li>
</ul>
<p>
<form action="add_folder" method="POST">
<label for="folder_title">Add: Folder
Title</label>
<input name="folder_title"/>
<input type="submit"/></form>
<form action="add_document" method="POST">
<label for="document_title">Add: Document
Title</label>
<input name="document_title"/>
<input type="submit"/></form>
</p>
</div>
|
Copy the following into step04/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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | import unittest
from pyramid.testing import DummyRequest
from pyramid.testing import DummyResource
class DummySite(DummyResource):
title = "Dummy Title"
__name__ = "dummy"
__parent__ = None
def values(self):
v = DummyResource(title="Dummy Item")
return [v, v, v, v, v]
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, {})
def test_add_folder_view(self):
from pyramid.httpexceptions import HTTPFound
t = 'New Folder'
request=DummyRequest(params={'folder_title': t})
context = DummySite()
inst = self._makeOne(context, request)
result = inst.add_folder_view()
# XXX Need a test that the item actually went in the folder
self.assertEqual(HTTPFound, result.__class__)
def test_add_document_view(self):
from pyramid.httpexceptions import HTTPFound
request=DummyRequest(folder_title='New Document')
context = DummySite()
inst = self._makeOne(context, request)
result = inst.site_view()
#self.assertEqual(HTTPFound, result.__class__)
# XXX Need tests that the doc was actually added
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.
To enforce uniqueness, we randomly choose a satisfactorily large number.