.. _tutor/architettura/package: Package ======= .. toctree:: :maxdepth: 1 :hidden: :titlesonly: model resources Un package è un insieme di :ref:`table` di *database* che servono a **implementare un’area funzionale dell'applicativo**. Ogni funzionalità che vogliamo attribuire all'applicativo verrà quindi raccolta e implementata da un package dedicato (es: "fatt", per tutta l'area funzionale legata alla fatturazione, o semplicemente "base" per le funzionalità di base). Ogni package è quindi costituito dalle seguenti cartelle: - :ref:`Model e Resources` , che conterranno rispettivamente i modelli dei dati e le risorse delle tabelle - :ref:`Lib` , che conterrà le librerie da importare - :ref:`Webpages` , che conterrà le differenti pagine specifiche che andremo a creare Come creare un package ---------------------- Analogamente a quanto avviene per la creazione dell' :ref:`istanza e del sito` , dall'interno della cartella *packages* è possibile creare un package con ``gnrmkpackage``:: gnrmkpackage nomepackage Com'è strutturato un package ---------------------------- Ogni package conterrà necessariamente un file ``main.py`` con le informazioni sulla struttura del package, ed eventualmente un :ref:`menu` . Il file *main* del package *fatt* di `Sandbox `_, per esempio, è così strutturato:: class Package(GnrDboPackage): def config_attributes(self): return dict(comment='Package demo fatturazione',sqlschema='fatt',language='it', name_short='Fatturazione', name_long='Fatturazione', name_full='Fatturazione') def config_db(self, pkg): pass def custom_type_money(self): return dict(dtype='N',format='#,###.00') def custom_type_percent(self): return dict(dtype='N',format='##.00') class Table(GnrDboTable): pass La prima parte viene solitamente compilata automaticamente dal compilatore del package. È poi possibile ridefinire dei metodi e delle classi. Nell'esempio ridefiniamo i due metodi ``custom_type_money`` e ``custom_type_percent``, che andranno quindi ad aggiungere un ``dtype`` particolare che verrà usato all'interno del package. In alternativa nel *main* è possibile anche ridefinire delle classi, per esempio avremmo potuto ridefinire la classe *Table* come segue:: class Table(GnrDboTable): def whoAmI(self): return self.fullname Il metodo *whoAmI*, che semplicemente ci restituisce il nostro nome completo, sarà disponibile per *ogni* tabella del package. Infine è possibile fare un mix-in di un metodo di pagina come segue:: class WebPage(GnrDboTable): def sandboxDiv(self,pane): return div('Questa è una pagina di Sandbox') Come si importa un package in un'istanza ---------------------------------------- I package attivi in un'istanza Genropy sono indicati nel file ``instanceconfig.xml`` che troviamo nella nostra istanza nella cartella *config*. Ad esempio, l' :ref:`instanceconfig` del progetto `Sandbox `_ presenterà i seguenti package:: Ogni riga rappresenta un package. I `packages built-in `_ (ovvero quelli di sistema di Genropy) saranno contraddistinti dal prefisso ``gnrcore``, gli altri package invece avranno la notazione *nomedelpackage pkgcode='nomedelpackage'*. L'ordine dei package non è casuale, bensì gli ultimi prevarranno sui primi, ovvero potranno andare a personalizzare i precedenti. .. hint:: Si noti che la presenza, nella prima riga, di un package **main**, in questo caso *sandbox*, avrà come conseguenza che questo package sarà incaricato di definire il menu principale. Qualora non si volesse invece definire un file *menu* ad hoc, ma utilizzare i menu di alcuni package specificati nell'istanza, sarà possibile specificare i menu da utilizzare come attributo:: .. sectionauthor:: Davide Paci