.. _le_stampe/stampe_genropy/stampe_risorsa/genro_html: Le basi di GnrHtml ================== .. toctree:: :maxdepth: 1 :hidden: :titlesonly: layout row cell Genropy offre un modo di creare stampe con il paradigma **descrittori/costruttori**, ovvero lo stesso approccio che abbiamo già incontrato nella definizione del `model `_ di un database o nella creazione di GUI. Ci riferiamo a questa feature con il nome **GnrHtml**, infatti qualsiasi stampa creata in Genropy si basa tutta sulla creazione di un HTML, il quale potrà essere stampato oppure immediatamente trasformato nel PDF corrispondente e quindi stampato. Elementi HTML ------------- È logico aspettarci che **GnrHtml** definisca tutti i metodi descrittori che mappino ogni possibile tag HTML, per permettere allo sviluppatore di descrivere l'HTML usando però Python e la consueta sintassi Genropy. :: page.div().span() E questo infatti è vero. Ma se esistessero solamente questi elementi HTML, il sistema non offrirebbe nessun reale aiuto allo sviluppatore. Così come avviene nella creazione delle GUI, Genropy definisce alcuni elementi originali che offrono molti vantaggi ed automatismi. Elementi originali GnrHtml -------------------------- Questi elementi originali sono - :ref:`Layout` - :ref:`Row` - :ref:`Cell` Si può dire che la definizione di una stampa in **Genropy** si ottiene usando queste tre tipologie di elementi ``layout``, ``row`` e ``cell``. :: layout = mypage.layout() row = layout.row(height = 10) cell = row.cell(value='Ciao', width = 20) Le regole di applicazione -------------------------- Vediamo in breve le regole per usare correttamente questi elementi. - Un elemento ``layout`` è un oggetto contenitore che può avere come figli solo elementi di tipo ``row`` - Ogni elemento di tipo ``row`` puo contenere solo elementi di tipo ``cell``. - Ogni elemento di tipo ``cell`` può contenere elementi HTML, dati del record oppure a sua volta un altro elemento di tipo ``layout``. In questo caso il layout, a sua volta, sarà ripartito in rows e via dicendo secondo quello che potremmo definire uno schema frattale. .. hint:: Attenzione alle sovrapposizioni! In caso di sovrapposizione tra righe, celle e layout, verranno applicate delle priorità di default per la definizione dei bordi: - tra layout e riga sul bordo inferiore prevarrà quanto definito nella riga - tra layout e riga sul bordo superiore prevarrà quanto definito nel layout - tra layout e cella sul bordo destro prevarrà quanto definito nella cella - tra layout e cella sul bordo sinistro prevarrà quanto definito nel layout Per ovviare a questo problema sarà quindi necessario specificare dei leggeri margini (es: top=1, left=1) per evitare la sovrapposizione dei blocchi. Si consulti a tal proposito l'esempio :ref:`Stampa custom 1: Vendite per Cliente` Misure elastiche ---------------- Abbiamo detto che un elemento ``layout`` può essere diviso orizzontalmente in elementi ``row``, ovvero fasce orizzontali delle quali possiamo indicare l'altezza con il parametro ``height``. Ma se si omette l'altezza di una ``row`` questa sarà considerata *elastica*. Questo significa che essa andrà ad occupare tutto lo spazio disponibile calcolato per differenza rispetto a quello delle altre righe. Vediamo di capirci con un esempio semplicissimo: :: l = c.layout(height=100) prima_riga = l.row(height=30) seconda_riga = l.row() terza_riga = l.row(height=20) Abbiamo definito un layout di altezza 100mm, e lo abbiamo suddiviso in 3 righe. La prima di altezza 30, la seconda priva di altezza, la terza di altezza 20. La seconda riga viene considerata *elastica* e la sua altezza calcolata sarà 100-30-20 = 50. Qualora definissimo più righe prive di altezza lo spazio libero verrebbe ripartito in parti uguali suddiviso sul numero di righe *elastiche*. :: l = c.layout(height=100) prima_riga = l.row(height=30) seconda_riga = l.row() terza_riga = l.row() In questo caso sia la seconda che la terza riga sono elastiche e avranno entrambe altezza calcolata di 35mm. Un discorso del tutto simile lo abbiamo per quanto riguarda la larghezza elastica degli elementi di tipo ``cell``. Infatti agli elementi di tipo ``cell`` si può assegnare una larghezza con il parametro ``width``. Se non viene indicata la ``width`` di una ``cell``, questa sarà considerata *elastica* ed occuperà lo spazio disponibile nella row. Qualora più celle non abbiano una larghezza assegnata lo spazio disponibile verrà ripartito in parti uguali fra tutte le celle senza larghezza della stessa riga. Il costruttore e HTML quotato ----------------------------- Ovviamente, per ottenere il file HTML della stampa occorre un apposito meccanismo di *rendering* , ovvero un oggetto costruttore, che partendo dalla descrizione definita con la sintassi **GnrHtml**, generi il codice HTML finale. Evidenziamo che il codice HTML generato sarà un "quotato", il che significa che ogni elemento avrà esplicitamente misure assolute espresse in millimetri. Questo è reso possibile dal fatto che il costruttore riconosce gli elementi *elastici* e per essi calcola le misure reali in millimetri.