Tabelle HTML senza scrivere HTML: z3c.table

28 agosto 2009

Magari qualcuno non è troppo convinto di aver bisogno di una libreria python per costruire e gestire tabelle HTML, ma quando è uscito il pacchetto plone.z3ctable mi sono ricordato della possibilità che offre z3c.table.

All’inizio pensavo fosse una cosa complessa e tutto sommato inutile (posso fare tutto quel che serve in una browser view, giusto? :)), ma uno sguardo alla documentazione mi ha convinto a provarlo.

Cosa offre il pacchetto in sintesi:

  • tabella e colonne sono classi python
  • colonne sono adapter (possono comparire/scomparire/cambiare in base al context, alla request, all’interfaccia della tabella)
  • non c’è una skin di base, ma in modo banale si possono associare classi CSS a qualsiasi tag della tabella
  • i record sono calcolati in modo automatico a fronte di oggetti che presentano l’interfaccia IContainer (cartelle) ma anche su un contesto di puri dati (una lista di dizionari, ad esempio)
  • gestione del batch per la navigazione di tabelle con molte righe
  • separazione tra rendering della tabella e del batch

Usare z3c.table in estrema sintesi

Immaginiamo di dover costruire una tabella con dati immagazzinati in una lista di dizionari python. Per farlo usiamo una Browser View di Zope che presenti il render della nostra tabella z3c.table.

questo il codice del modulo python della Browser View:

from Products.Five import BrowserView
from z3c.table import table, column

# definisco l'unica colonna della tabella
class FirstColumn(column.Column):

  # weight determina la posizione rispetto ad altre eventuali colonne
  weight = 1
  header = u'Prima Colonna'

  def renderCell(self, item):
    # renderCell restituisce la stringa HTML da inserire
    # nella cella della colonna
    return item['k']

# SequenceTable consente di usare una lista come contesto
# da cui ottenere i record
class ResultsTable(table.SequenceTable):

  cssClasses = {'table': 'listing'}
  cssClassEven = u'even'
  cssClassOdd = u'odd'
  sortOn = None

  # NB: in plone avremmo bisogno di plone.z3ctable
  # e della riga seguente per far funzionare il batch:
  # batchProviderName = 'plonebatch'
  batchStart = 0
  batchSize = 5
  startBatchingAt = 5

  # se non si vuole usare l'adattamento per agganciare le colonne
  # il metodo seguente fa al caso nostro..
  def setUpColumns(self):
    c1 = FirstColumn(self.context, self.request, self)
    return [c1]

# la seguente Browser View è solo un esempio minimale
# con poca fantasia farete comparire le vostre tabelle dove utile
class ResultsView(BrowserView):

  def __init__(self, context, request):
    self.context = context
    self.request = request

  def get_results(self):
    ret = []
    for val in range(10):
      ret.append(dict(k=val))
    return ret

  def get_results_table(self):
    res = self.get_results()
    table = ResultsTable(res, self.request)
    table.update()
    return table.render() + table.renderBatch()

Il template basico da associare alla Browser View per “vedere” la tabella formarsi:

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
 <tal:block tal:content="structure view/get_results_table">
   tabella!
 </tal:block>
</body>
</html>

E infine la tabella che si materializza richiamando la vista nel nostro Browser:

<table class="listing">
  <thead>
    <tr>
      <th>Prima Colonna</th>
    </tr>
  </thead>
  <tbody>
    <tr class="even">
      <td>0</td>
    </tr>
    <tr class="odd">
      <td>1</td>
    </tr>
    <tr class="even">
      <td>2</td>
    </tr>
    <tr class="odd">
      <td>3</td>
    </tr>
    <tr class="even">
      <td>4</td>
    </tr>
  </tbody>
</table><div class="listingBar">
<span class="next">
<a href="http://localhost:8090/plone/prova?&amp;table-batchSize:int=5&amp;table-batchStart:int=5">Successivi 5 elementi »</a>
</span>
[1]
<a href="http://localhost:8090/plone/prova?&amp;table-batchSize:int=5&amp;table-batchStart:int=5">2</a>
</div>

Non è poi così noioso lavorare con le tabelle, no? 🙂

Annunci

4 Risposte to “Tabelle HTML senza scrivere HTML: z3c.table”

  1. Massimo Azzolini Says:

    può essere molto utile in qlc contesto in cui non è una “tabella” non è solo una tabella ma ha una certa semantica che esprimi meglio in un linguaggio *vero* piuttosto che html.
    Il renderizzare una tabella diventa il dettaglio.
    non male.

    in casi *normali*, si tratta di cannoni e mosche.

    il css nel codice python non mi piace per nulla: significa che il grafico deve aprire un file.py e capire cosa c’è scritto…


    • Il CSS non è nel codice. Gli attributi class vengono definiti nel codice, il che è completamente differente.
      Il grafico infatti non ha alcun bisogno di andare a smanacciare o vedere nel python, semplicemente usando firebug sulla pagina renderizzata gli permette di fare ciò che vuole.
      In sostanza, le classi CSS devono essere viste come degli “hook” nei sistemi a plugin: la decisione viene fatta upstream a chi fa il plugin s’adatta.


      • Simone, premesso che stiamo facendo filosofia…non sono d’accordo.

        la decisione viene presa da altri e non dal grafico:
        – se serve un’altra classe non lo può fare,
        – se ‘even’ e ‘odd’ hanno anche un’altra semantica non li può cambiare. ecc.

        il codice css (sia hook che definizione dello stile) è roba di templating e in quanto tale non mi piace che stia in un file .py.
        deve stare in un file .html o .pt (se vogliamo) ma mai nella definizione della classe.


Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: