Archive
plone – come creare una browser view e vivere felici senza “restricted python”
Occorrente:
– un file di configurazione zcml
– un file contenente una classe python
In un normale pacchetto plone abbiamo già un configure.zcml che può fare al caso nostro. Apriamolo e aggiungiamo la registrazione della vista:
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" i18n_domain="my.package"> [...] <browser:page name="myview" for="Products.CMFPlone.interfaces.IPloneSiteRoot" class=".browser.MyView" permission="cmf.ManagePortal" /> [...] </configure>
NOTE
– è indispensabile che l’header della configurazione includa il namespace “browser”
– la vista sarà disponibile solo nella root del sito visto che l’abbiamo registrata per IPloneSiteRoot (per renderla accessibile ovunque è sufficiente utilizzare ‘for=”*”‘)
– per accedervi si dovrà avere il permesso “Manage portal”
Ora passiamo alla definizione della classe. Creaimo un file browser.py e aggiungiamo quanto segue:
from Products.Five import BrowserView class MyView(BrowserView): """ my browser view """ def __call__(self): return 'pippo'
Una volta restartata l’istanza potremo richiamare la nostra vista tramite http://myplone.com/@@myview che in questo caso restituirà “pippo”.
Se invece volessimo usarla per presentare dei contenuti dovremmo assegnargli un template:
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" i18n_domain="my.package"> [...] <browser:page name="myview" for="Products.CMFPlone.interfaces.IPloneSiteRoot" class=".browser.MyView" template="myviewtemplate.pt" permission="cmf.ManagePortal" /> [...] </configure>
e modificare la classe in maniera che al __call__ non venga restituito “pippo”:
from Products.Five import BrowserView class MyView(BrowserView): """ my browser view """ def getPippo(self): return 'pippo'
Nel template dovremo avere qualcosa del genere:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" lang="en" metal:use-macro="context/main_template/macros/master" i18n:domain="my.package"> <body> <tal:fill metal:fill-slot="main"> <div id="myview-wrapper"> <h3> questo è il valore di pippo: <span tal:content="view/getPippo" /> </h3> </div> </tal:fill>
Tutti gli attributi della vista sono accessibili tramite “view/nomeAttr”.
Ricordiamo che pythonicamante parlando un metodo/funzione è un attributo 😉
TIP: Tutto ciò è molto più veloce da creare usando paster: “bin/paster addcontent view”
Per maggiori delucidazione consultate http://collective-docs.plone.org/views/index.html
Se non trovate quello che cercate… cercate su google!!! 😛
openerp – how to add a custom field to an object
Adding a custom field to an existing object it’s as easy as the following few lines of code.
Let’s say you want to add a field to partner. Create a partner.py file into your module and add the following to it:
from osv import fields,osv class res_partner(osv.osv): _inherit = 'res.partner' _columns = { 'mytext':fields.char('My custom text field',size=64), } res_partner()
Now, if you want to display this field into partner’s view you have to override the form view.
Create a partner_view.xml into your module and add:
<?xml version="1.0" encoding="utf-8"?> <openerp> <data> <record id="mypartner_form" model="ir.ui.view"> <field name="name">partner.myform</field> <field name="model">res.partner</field> <field name="type">form</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="arch" type="xml"> <field name="name" position="after"> <field name="mytext" /> </field> </field> </record> </data> </openerp>
Then you’ll need to install your module or to upgrade it if already installed.
See openerp docs for further info.
Una vista per tutte
in un progetto sul quale ho lavorato di recente c’erano parecchi pacchetti. Uno di questi definiva alcune proprietà dell’utente e un set di metodi per poter accedere a tali proprietà.
Si aveva l’esigenza di richiamare questi metodi da tutti gli altri pacchetti del progetto in maniera da duplicare il meno possibile il codice.
Allora ho pensato di definire proprio come fa plone (plone_portal_state, plone_context_state, ecc) una vista accessibile ovunque che mettesse a diposizione il suddetto set di metodi.
Definiamo la vista:
<browser:page name="myhelpers_view" for="*" class="views.HelpersView" permission="zope2.View" />
class HelpersView(BrowserView): """ HelpersView browser view """ def getFoo(self): foo = 'boo' return foo def doThis(self): #do this and that return True def getThat(self): return self.context.stuff
Potremo poi accedere a tali metodi da tutte le altre viste (ma anche portlets e altro) richiamando la nostra vista (che è un named multi-adapter) grazie a “getMultiAdapter”, proprio come si fa con plone_portal_state:
from zope.component import getMultiAdapter class MyOtherView(BrowserView): [...] @property def my_helpers(self): return getMultiAdapter((self.context, self.request), name=u'myhelpers_view')
e potrò utilizzare i suoi metodi nel sequente modo:
def do_this(self): foo = self.my_helpers.getFoo() [...]
Analogamente, potró richiamarla nei template cosí:
<div tal:define="helpers context/@@my_helpers_view"> <span tal:content="helpers/getThis" /> </div>