diff --git a/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/base.mako b/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/base.mako
new file mode 100644
index 0000000..27f7dd9
--- /dev/null
+++ b/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/base.mako
@@ -0,0 +1,2 @@
+<%inherit file="/base.mako" />
+${parent.body()}
diff --git a/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/foo.mako b/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/foo.mako
new file mode 100644
index 0000000..e3cbf37
--- /dev/null
+++ b/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/foo.mako
@@ -0,0 +1,10 @@
+<%inherit file="/foo/base.mako" />
+<%inherit file="/crud.mako" />
+
+<%def name="crud_name()">Foo%def>
+
+<%def name="menu()">
+
${h.link_to("Back to Foo", url('foo.list'))}
+%def>
+
+${parent.body()}
diff --git a/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/index.mako b/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/index.mako
new file mode 100644
index 0000000..f05d40e
--- /dev/null
+++ b/edbob/scaffolds/edbob/+package+/pyramid/templates/foo/index.mako
@@ -0,0 +1,12 @@
+<%inherit file="/foo/base.mako" />
+<%inherit file="/index.mako" />
+
+<%def name="title()">Foo%def>
+
+<%def name="menu()">
+ % if request.has_perm('foo.create'):
+ ${h.link_to("Create a new Foo", url('foo.new'))}
+ % endif
+%def>
+
+${parent.body()}
diff --git a/edbob/scaffolds/edbob/+package+/pyramid/templates/home.mako_tmpl b/edbob/scaffolds/edbob/+package+/pyramid/templates/home.mako_tmpl
index c8b919c..38bfa87 100644
--- a/edbob/scaffolds/edbob/+package+/pyramid/templates/home.mako_tmpl
+++ b/edbob/scaffolds/edbob/+package+/pyramid/templates/home.mako_tmpl
@@ -7,7 +7,7 @@
You must choose, but choose wisely:
-
+
diff --git a/edbob/scaffolds/edbob/+package+/pyramid/views/foo.py_tmpl b/edbob/scaffolds/edbob/+package+/pyramid/views/foo.py_tmpl
new file mode 100644
index 0000000..8fbf77b
--- /dev/null
+++ b/edbob/scaffolds/edbob/+package+/pyramid/views/foo.py_tmpl
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+``{{package}}.pyramid.views.foo`` -- Foo Views
+"""
+
+import transaction
+from pyramid.httpexceptions import HTTPFound
+
+import edbob
+from edbob.pyramid import filters
+from edbob.pyramid import forms
+from edbob.pyramid import grids
+from edbob.pyramid import Session
+
+import {{package}}
+
+
+class FooGrid(object):
+
+ def __init__(self, request):
+ self.request = request
+
+ def filter_map(self):
+ return filters.get_filter_map(
+ {{package}}.Foo,
+ ilike=['description'])
+
+ def search_config(self, fmap):
+ return filters.get_search_config(
+ 'foo.list', self.request, fmap,
+ include_filter_description=True,
+ filter_type_description='lk')
+
+ def search_form(self, config):
+ return filters.get_search_form(config)
+
+ def grid_config(self, search, fmap):
+ return grids.get_grid_config(
+ 'foo.list', self.request, search,
+ filter_map=fmap, sort='description',
+ deletable=True)
+
+ def sort_map(self):
+ return grids.get_sort_map(
+ {{package}}.Foo,
+ ['description'])
+
+ def query(self, config):
+ smap = self.sort_map()
+ q = Session.query({{package}}.Foo)
+ q = filters.filter_query(q, config)
+ q = grids.sort_query(q, config, smap)
+ return q
+
+ def __call__(self):
+
+ fmap = self.filter_map()
+ config = self.search_config(fmap)
+ search = self.search_form(config)
+ config = self.grid_config(search, fmap)
+ foos = grids.get_pager(self.query, config)
+
+ g = forms.AlchemyGrid(
+ {{package}}.Foo, foos, config,
+ gridurl=self.request.route_url('foo.list'),
+ objurl='foo.edit', delurl='foo.delete')
+
+ g.configure(
+ include=[
+ g.description,
+ ],
+ readonly=True)
+
+ grid = g.render(class_='clickable foo')
+ return grids.render_grid(self.request, grid, search)
+
+
+def foo_fieldset(foo, request):
+ fs = forms.make_fieldset(foo, crud_title="Foo",
+ url=request.route_url,
+ url_action=request.current_route_url(),
+ route_name='foo.list')
+
+ fs.configure(
+ include=[
+ fs.description,
+ ])
+ return fs
+
+
+def new_foo(request):
+
+ fs = foo_fieldset({{package}}.Foo, request)
+ if not fs.readonly and request.POST:
+ fs.rebind(data=request.params)
+ if fs.validate():
+
+ with transaction.manager:
+ fs.sync()
+ Session.add(fs.model)
+ Session.flush()
+ request.session.flash("%s \"%s\" has been %s." % (
+ fs.crud_title, fs.get_display_text(),
+ 'updated' if fs.edit else 'created'))
+
+ return HTTPFound(location=request.route_url('foo.list'))
+
+ return {'fieldset': fs, 'crud': True}
+
+
+def edit_foo(request):
+ """
+ View for editing a :class:`{{package}}.Foo` instance.
+ """
+
+ uuid = request.matchdict['uuid']
+ foo = Session.query({{package}}.Foo).get(uuid) if uuid else None
+ assert foo
+
+ fs = foo_fieldset(foo, request)
+ if request.POST:
+ fs.rebind(data=request.params)
+ if fs.validate():
+
+ with transaction.manager:
+ fs.sync()
+ fs.model = Session.merge(fs.model)
+ request.session.flash("%s \"%s\" has been %s." % (
+ fs.crud_title, fs.get_display_text(),
+ 'updated' if fs.edit else 'created'))
+ home = request.route_url('foo.list')
+
+ return HTTPFound(location=home)
+
+ return {'fieldset': fs, 'crud': True}
+
+
+def delete_foo(request):
+ uuid = request.matchdict['uuid']
+ foo = Session.query({{package}}.Foo).get(uuid) if uuid else None
+ assert foo
+
+ with transaction.manager:
+ Session.delete(foo)
+
+ return HTTPFound(location=request.route_url('foo.list'))
+
+
+def includeme(config):
+
+ config.add_route('foo.list', '/foo')
+ config.add_view(FooGrid, route_name='foo.list', renderer='/foo/index.mako',
+ permission='foo.list', http_cache=0)
+
+ config.add_route('foo.new', '/foo/new')
+ config.add_view(new_foo, route_name='foo.new', renderer='/foo/foo.mako',
+ permission='foo.create', http_cache=0)
+
+ config.add_route('foo.edit', '/foo/{uuid}/edit')
+ config.add_view(edit_foo, route_name='foo.edit', renderer='/foo/foo.mako',
+ permission='foo.edit', http_cache=0)
+
+ config.add_route('foo.delete', '/foo/{uuid}/delete')
+ config.add_view(delete_foo, route_name='foo.delete',
+ permission='foo.delete', http_cache=0)