Hi there!
I did some work to make tgext.crud use the various features of the
Twitter Bootstrap CSS framework.
Attached you will find a patch against the 0.5 tag (I wanted it to work
on TurboGears-2.1.5, using tgext.crud-0.5.1 just gives me
RenderingErrors related to Genshi).
Also, I did only port the Mako templates, as Genshi complained about the
XML() function not being defined (and even if I replace it by Markup()
in the tgext.crud templates, tw2 uses XML() again...)
Changes are:
- Display menu in a span2 column with highlighted current item
- Display New ${model} link as button with a Plus icon
- Optionally disable the "New" functionality altogether with a parameter
- Display rest of forms in a span10 on the right side.
To do:
- Pagination... Bootstrap includes some pagination styles
(http://twitter.github.com/bootstrap/components.html#pagination) but
they require having the pager using lists which I haven't found possible
in webhelpers.paginate
- Use a nicer style for the action buttons in the table --> sprox
e.g.
<a ... class="btn btn-mini"><i class="icon-pencil"></i> Edit</a>
<input type="submit" class="btn-mini btn-danger" ...
value="Delete" />
- Use the Bootstrap form elements --> tw2
Hope this patch can be useful in some way!
Cheers,
Moritz
--
You received this message because you are subscribed to the Google Groups
"TurboGears Trunk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/turbogears-trunk?hl=en.
# HG changeset patch
# User Moritz Schlarb <[email protected]>
# Date 1338026903 -7200
# Node ID eae3233ae69513c526b0e9271782322ae5d9b900
# Parent 7508978ed05dd0a7294ed6c8e86e3bedcbf681a3
Changed mako templates to support the bootstrap css framework
Since Bootstrap is the default template for Turbogears >= 2.2, this
will come in handy.
Additionally, CrudRestController now supports a new variable:
``allow_new`` to controll the availability and accessibility of creating
new objects. If it is set to False, the New button will be hidden and
accessing the /new method will result in a 403 error.
diff --git a/tgext/crud/controller.py b/tgext/crud/controller.py
--- a/tgext/crud/controller.py
+++ b/tgext/crud/controller.py
@@ -1,7 +1,7 @@
"""
"""
import tg
-from tg import expose, flash, redirect, tmpl_context, request
+from tg import expose, flash, redirect, tmpl_context, request, abort
from tg.decorators import without_trailing_slash, with_trailing_slash
from tg.controllers import RestController
@@ -72,61 +72,19 @@
sprox provider for data manipulation
session
link to the database
+ allow_new
+ Whether to allow creation of new objects
"""
title = "Turbogears Admin System"
keep_params = None
- style = literal('''
-#menu_items {
- padding:0px 12px 0px 2px;
- list-style-type:None;
- padding-left:0px;
-}
-
-#crud_leftbar {
- float:left;
- padding-left:0px;
-}
-
-#crud_content {
- float:left;
- width:80%;
-}
-
-#crud_content > h1,
-.crud_edit > h2,
-.crud_add > h2 {
- margin-top: 1px;
-}
-
-#crud_btn_new {
- margin:1ex 0;
-}
-
-#crud_btn_new > span {
- margin-left:2em;
-}
-
-#crud_search {
- float: right;
-}
-
-#crud_search input {
- border: 1px solid #CCC;
- background-color: white;
-}
-
-#crud_search input:hover {
- background-color: #EFEFEF;
-}
-''')
def _before(self, *args, **kw):
tmpl_context.title = self.title
tmpl_context.menu_items = self.menu_items
tmpl_context.kept_params = self._kept_params()
tmpl_context.crud_helpers = self.helpers
- tmpl_context.crud_style = self.style
+ tmpl_context.allow_new = self.allow_new
def __before__(self, *args, **kw):
# this will be removed in 2.2.*
@@ -134,7 +92,7 @@
tmpl_context.title = self.title
tmpl_context.kept_params = self._kept_params()
tmpl_context.crud_helpers = self.helpers
- tmpl_context.crud_style = self.style
+ tmpl_context.allow_new = self.allow_new
def _mount_point(self):
try:
@@ -174,7 +132,7 @@
adapted_menu_items[link] = model
return adapted_menu_items
- def __init__(self, session, menu_items=None):
+ def __init__(self, session, menu_items=None, allow_new=True):
if menu_items is None:
menu_items = {}
self.menu_items = self._adapt_menu_items(menu_items)
@@ -182,6 +140,7 @@
self.provider = ProviderTypeSelector().get_selector(self.model).get_provider(self.model, hint=session)
self.session = session
+ self.allow_new = allow_new
#this makes crc declarative
check_types = ['new_form', 'edit_form', 'table', 'table_filler', 'edit_filler']
@@ -247,8 +206,11 @@
@expose('tgext.crud.templates.new')
def new(self, *args, **kw):
"""Display a page to show a new record."""
- tmpl_context.widget = self.new_form
- return dict(value=kw, model=self.model.__name__)
+ if self.allow_new:
+ tmpl_context.widget = self.new_form
+ return dict(value=kw, model=self.model.__name__)
+ else:
+ abort(403)
@catch_errors(errors, error_handler=new)
@expose()
diff --git a/tgext/crud/templates/edit.mak b/tgext/crud/templates/edit.mak
--- a/tgext/crud/templates/edit.mak
+++ b/tgext/crud/templates/edit.mak
@@ -2,21 +2,21 @@
<%namespace name="menu_items" file="tgext.crud.templates.menu_items"/>
<%def name="title()">
-${tmpl_context.title} - ${model}
+${tmpl_context.title} - Edit ${model}
+</%def>
+<%def name="header()">
+ ${parent.header()}
</%def>
-<%def name="body_class()">tundra</%def>
-<%def name="header()">
- ${menu_items.menu_style()}
- ${parent.header()}
-</%def>
- <div id="main_content">
- ${menu_items.menu_items(pk_count)}
- <div id="crud_content">
- <div class="crud_edit">
- <h2>Edit ${model}</h2>
- ${tmpl_context.widget(value=value, action='./') | n}
- </div>
+<div id="main_content" class="row">
+ ${menu_items.menu_items(pk_count)}
+ <div id="crud_content" class="span10">
+ <div class="page-header">
+ <h1>Edit ${model}</h1>
</div>
- <div style="height:0px; clear:both;"> </div>
- </div> <!-- end main_content -->
+ <div class="crud_edit">
+ ${tmpl_context.widget(value=value, action='./') | n}
+ </div>
+ </div>
+</div>
+
\ No newline at end of file
diff --git a/tgext/crud/templates/get_all.mak b/tgext/crud/templates/get_all.mak
--- a/tgext/crud/templates/get_all.mak
+++ b/tgext/crud/templates/get_all.mak
@@ -2,11 +2,10 @@
<%namespace name="menu_items" file="tgext.crud.templates.menu_items"/>
<%def name="title()">
-${tmpl_context.title} - ${model} Listing
+ ${tmpl_context.title} - ${model} Listing
</%def>
<%def name="header()">
-${menu_items.menu_style()}
-<script>
+ <script>
function crud_search_field_changed(select) {
var selected = '';
for (var idx=0; idx != select.options.length; ++idx) {
@@ -16,35 +15,46 @@
var field = document.getElementById('crud_search_value');
field.name = selected.value;
}
-</script>
-${parent.header()}
+ </script>
+ ${parent.header()}
</%def>
-<%def name="body_class()">tundra</%def>
-<div id="main_content">
+
+<div id="main_content" class="row">
${menu_items.menu_items()}
- <div id="crud_content">
- <h1>${model} Listing</h1>
- <div id="crud_btn_new">
- <a href='${tg.url("new", params=tmpl_context.kept_params)}' class="add_link">New ${model}</a>
- % if tmpl_context.paginators:
- <span>${tmpl_context.paginators.value_list.pager(link=mount_point+'/')}</span>
- % endif
- <div id="crud_search">
- <form>
- <select id="crud_search_field" onchange="crud_search_field_changed(this);">
- <option value="${headers[0][0]}" selected="selected">${headers[0][1]}</option>
- % for field,name in headers[1:]:
- <option value="${field}">${name}</option>
- % endfor
- </select>
- <input id="crud_search_value" name="${headers[0][0]}" type="text" placeholder="equals"/>
- <input type="submit" value="Search"/>
- </form>
+ <div id="crud_content" class="span10">
+ <div class="page-header">
+ <h1>${model} Listing</h1>
+ </div>
+ <div class="row">
+ <div id="crud_btn_new" class="span2">
+ % if tmpl_context.allow_new:
+ <a href='${tg.url("new", params=tmpl_context.kept_params)}' class="add_link btn"><i class="icon-plus-sign"></i> New ${model}</a>
+ % endif
+
+ </div>
+ <div class="span3">
+ % if tmpl_context.paginators:
+ <span>${tmpl_context.paginators.value_list.pager(link=mount_point+'/')}</span>
+ % endif
+
+ </div>
+ <div class="span5">
+ <div id="crud_search" class="pull-right">
+ <form class="form-search">
+ <select id="crud_search_field" onchange="crud_search_field_changed(this);" class="input-medium">
+ <option value="${headers[0][0]}" selected="selected">${headers[0][1]}</option>
+ % for field,name in headers[1:]:
+ <option value="${field}">${name}</option>
+ % endfor
+ </select>
+ <input id="crud_search_value" name="${headers[0][0]}" type="text" placeholder="equals" class="search-query input-medium" />
+ <input type="submit" value="Search" class="btn" />
+ </form>
+ </div>
</div>
</div>
- <div class="crud_table">
- ${tmpl_context.widget(value=value_list, action=mount_point+'.json', attrs=dict(style="height:200px; border:solid black 3px;")) |n}
+ <div class="crud_table" class="row">
+ ${tmpl_context.widget(value=value_list, action=mount_point+'.json') |n}
</div>
</div>
- <div style="clear:both;"> </div>
</div>
diff --git a/tgext/crud/templates/menu_items.mak b/tgext/crud/templates/menu_items.mak
--- a/tgext/crud/templates/menu_items.mak
+++ b/tgext/crud/templates/menu_items.mak
@@ -5,12 +5,13 @@
</%def>
<%def name="menu_items(pk_count=0)">
- <div id="crud_leftbar">
- <div id="menu_items">
- <ul>
+ <div id="crud_leftbar" class="span2">
+ <div id="menu_items" class="well" style="padding: 9px 0;">
+ <ul class="nav nav-list">
+ <li class="nav-header">Menu</li>
% if hasattr(tmpl_context, 'menu_items'):
% for lower, item in sorted(tmpl_context.menu_items.iteritems()):
- <li>
+ <li class="${('', 'active')[model==item]}">
<a href="${tmpl_context.crud_helpers.make_link(lower, pk_count)}">${item}</a>
</li>
% endfor
diff --git a/tgext/crud/templates/new.mak b/tgext/crud/templates/new.mak
--- a/tgext/crud/templates/new.mak
+++ b/tgext/crud/templates/new.mak
@@ -5,19 +5,17 @@
${tmpl_context.title} - New ${model}
</%def>
<%def name="header()">
- ${menu_items.menu_style()}
${parent.header()}
</%def>
-<%def name="body_class()">tundra</%def>
-
-<div id="main_content">
+<div id="main_content" class="row">
${menu_items.menu_items()}
- <div id="crud_content">
+ <div id="crud_content" class="span10">
+ <div class="page-header">
+ <h1>New ${model}</h1>
+ </div>
<div class="crud_add">
- <h2>New ${model}</h2>
${tmpl_context.widget(value=value, action='./') | n}
</div>
</div>
- <div style="clear:both;"> </div>
</div>