.. _tutor/pagina/relative_path:
Path relativi
=============
Abbiamo detto che lo store che usiamo sul client è una Bag e quindi è di tipo gerarchico.
Per accedere ad un elemento dobbiamo fornire il suo path a partire dall'inizio dello store.
.. raw:: html
Per rendere il codice più leggibile e soprattutto rilocabile, è però possibile usare anche
dei path **relativi**. Un path relativo inizia sempre col simbolo '.' e gli elementi che lo
utilizzano devono necessariamente trovarsi contenuti (direttamente o indirettamente), in
un altro elemento che definisca l'attributo ``datapath`` che rappresenta l'origine.
Per chiarire il concetto riprendiamo l'esempio precedente
ma lo realizziamo con l'uso di path relativi.
.. raw:: html
Esaminando il codice notiamo ::
fb=root.formbuilder(cols=3, datapath='parameters',border_spacing='2px',
width='450px', fld_width='100%', colswidth='auto')
fb.input('^.string_to_show',lbl='String To Show',width='100%',colspan=3)
Il formbuilder ha ora un attributo ``datapath='parameters'`` e quindi al suo interno ogni
path che inizi con '.' è *relativo* a tale origine. Quindi, ad esempio, '``^.string_to_show``' equivale a scrivere
'``^parameters.string_to_show``'.
Si può notare che il codice è più leggibile perchè i path usati sono più corti.
Ma il motivo principale, che vedremo nel prossimo esempio, è che un path relativo
consente di riutilizzare il codice.
.. raw:: html
Esaminiamo il codice::
def main(self,root,**kwargs):
self.configurableDiv(root,'one','Hello world',color='green',border='1px solid red')
self.configurableDiv(root,'two','Great work')
self.configurableDiv(root,'three','How are you?',background='yellow',rounded=20)
Nel main ci limitaimo a chiamare 3 volte lo stesso metodo ``configurableDiv`` al quale passiamo
un 'nome', un testo di partenza e dei parametri di formattazione che desideriamo.
Vediamo ora il metodo ``configurableDiv`` in dettaglio::
def configurableDiv(self,pane,name,string_to_show,**kwargs):
startData=Bag(dict(string_to_show=string_to_show, **kwargs))
pane.data(name,startData)
box=pane.div(datapath=name,border='1px solid silver',rounded=10, margin='5px')
box.div(name,color='white',text_align='center',background='silver',
rounded_top=10,font_size='14px')
Il primo parametro è l'elemento a cui ci colleghiamo e viene indicato genericamente con *pane*.
Prepariamo poi una Bag con i dati ricevuti e usando il metodo ``data`` li andiamo a mettere all'indirizzo che riceviamo
nel parametro *name*.
Creiamo poi un div (che chiamiamo *box*), con alcuni attributi di natura puramente estetica e l'attributo
datapath che corrisponde al nome ricevuto, e al suo interno poniamo un div con il titolo.
Tutti gli elementi in *box* avranno quindi i path relativi *rilocati* all'indirizzo dello store
corrispondente al nome.
Potremo quindi cambiare i vari attributi dei tre testi indipendentemente
l'uno dall'altro.
Vediamo ora nell'ispector lo stato dello store:
.. image:: /_static/images/multi_esempio.png
:width: 300px
:align: center
.. raw:: html
L'unica differenza rispetto all'esempio precedente è che abbiamo reso assoluti
i path dell'attributo *padding* e *font_size* e per renderlo più chiaro
abbiamo colorato di rosso le loro etichette.
Provando ad usare l'esempio noterete che se assegnate il padding oppure il font_size, la scelta varrà
per tutti e tre i testi. Noterete anche che il valore si modifica in tutte le form.
Vediamo anche in questo caso l'inspector e notiamo il path *common* dove sono ora contenuti
i due attributi comuni.
.. image:: /_static/images/mixed.png
:width: 300px
:align: center