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;"> &nbsp; </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
+        &nbsp;
+      </div>
+      <div class="span3">
+        % if tmpl_context.paginators:
+          <span>${tmpl_context.paginators.value_list.pager(link=mount_point+'/')}</span>
+        % endif
+        &nbsp;
+      </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;"> &nbsp; </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;"> &nbsp; </div>
 </div>

Reply via email to