Upload
menttes
View
454
Download
0
Embed Size (px)
DESCRIPTION
La charla propone hacer un recorrido y revisión de componentes y conceptos empleados en Zope que puedan ser empleados de forma independiente en otras aplicaciones, incluso que no sean web.
Citation preview
Reusando componentes Zope fuera de Zope (y la web)
Roberto AllendeMenttes / Plone Foundation
http://robertoallende.comtwitter: robertoallende
Buildout ZODB Zope Page Templates Adaptadores
Buildout is a Python-based build system for creating, assembling and deploying applications from multiple parts, some of which may be non-Python-based. It lets you create a buildout configuration and reproduce the same software later.
Buildout
Tool for working with eggs
Repeatable
Developer oriented
Buildout | Features
$ easy_install zc.buildout
Buildout | Install
$ svn co http://miproyecto$ python bootstrap.py$ bin/buildout -v…$ bin/miproyecto.py
Buildout | Deploy con buildout
project/ bootstrap.py buildout.cfg .installed.cfg parts/ develop-eggs/ bin/ buildout miproyecto eggs/ downloads/
Buildout | Deploy con buildout
[buildout]index-url = http://pypi.it.uwosh.edu/parts = instance zopepy
eggdeps degraph
extends = http://download.zope.org/Zope2/index/2.13.0a3/versions.cfgeggs = tl.eggdeps
[instance]recipe = plone.recipe.zope2instanceuser = admin:adminhttp-address = 8080products = ${buildout:directory}/products
Buildout | buildout.cfg
http://buildout.org
Buildout | Mas información
Don’t squeeze your objects into tables: store them in an object database.
ZODB
Transparent persistence for Python objects
Full ACID-compatible transaction support
History/undo ability
Efficient support for binary large objects (BLOBs)
Pluggable storages
Scalable architecture
ZODB | Features
$ easy_install ZODB3$ easy_install ZODB3……
$ python$ python>>> import ZODB>>> import ZODB
ZODB | Instalación
>>> from ZODB.FileStorage import FileStorage>>> from ZODB.FileStorage import FileStorage>>> from ZODB.DB import DB>>> from ZODB.DB import DB>>> storage = FileStorage('Data.fs')>>> storage = FileStorage('Data.fs')>>> db = DB(storage)>>> db = DB(storage)>>> connection = db.open()>>> connection = db.open()>>> root = connection.root()>>> root = connection.root()
ZODB | Configuración
>>> root['account-1'] = Account()>>> root['account-1'] = Account()>>> root['account-2'] = Account()>>> root['account-2'] = Account()
ZODB | Haciendo un objeto persistente
>>> import transaction>>> import transaction>>> transaction.commit()>>> transaction.commit()>>> root.keys()>>> root.keys()['account-1', 'account-2']['account-1', 'account-2']
ZODB | Transactions
http://zodb.orghttp://zodb.org
ZODB | Mas Lectura
Zope Page Template allows you to generate Zope Page Template allows you to generate HTML dynamically.HTML dynamically.
Chameleon compiles templates to Python byte-code. It includes a Chameleon compiles templates to Python byte-code. It includes a complete implementation of the Zope Page Templates (ZPT) language and complete implementation of the Zope Page Templates (ZPT) language and a partial implementation of the Genshi language.a partial implementation of the Genshi language.
ZPT vía Chameleon
ZPT templates are valid XML documentsZPT templates are valid XML documents
It uses namespaces for attributes and tags to It uses namespaces for attributes and tags to define the template behaviour. define the template behaviour.
Works on Python 2.4, 2.5 and 2.6, including Works on Python 2.4, 2.5 and 2.6, including Google App EngineGoogle App Engine
PHP, Java, PerlPHP, Java, Perl
ZPT vía Chameleon
$ easy_install Chameleon$ easy_install Chameleon
ZPT vía Chameleon | Install
<table border="1"><table border="1"> <tr <tr tal:repeat="row range(10)"tal:repeat="row range(10)">> <td<td tal:repeat="column range(10)" tal:repeat="column range(10)">> <span <span tal:define="x repeat.row.number;tal:define="x repeat.row.number; y repeat.column.number;y repeat.column.number; z x * y"z x * y" tal:replace="string:$x * $y = $z"tal:replace="string:$x * $y = $z">1 * 1 =>1 * 1 = </span></span> </td></td> </tr></tr></table></table>
ZPT vía Chameleon | Template loader
from chameleon.zpt import loaderfrom chameleon.zpt import loader
template_path = os.path.join(os.path.dirname(__file__), "..", "templates")template_path = os.path.join(os.path.dirname(__file__), "..", "templates")template_loader = loader.TemplateLoader(template_path, template_loader = loader.TemplateLoader(template_path, auto_reload=os.environ['SERVER_SOFTWARE'].startswith('Dev'))auto_reload=os.environ['SERVER_SOFTWARE'].startswith('Dev'))
ZPT vía Chameleon | Ejemplo
def TestHandler(RequestHandler):def TestHandler(RequestHandler): def get(self):def get(self): template = template_loader.load("test.pt")template = template_loader.load("test.pt") self.response.body = template(name="test")self.response.body = template(name="test")
ZPT vía Chameleon | Ejemplo
http://chameleon.repoze.orghttp://chameleon.repoze.org
http://blog.notdot.nethttp://blog.notdot.netWebapps on App Engine, part 4: TemplatingWebapps on App Engine, part 4: Templating
ZPT vía Chameleon | Mas Lectura
Dynamic adaptation might feel like a type Dynamic adaptation might feel like a type declaration, but it's not!declaration, but it's not!
It specifies a behavior, not a type; it's dynamic; It specifies a behavior, not a type; it's dynamic; it's optional.it's optional.
Adapters
class File(object):class File(object): body = 'foo bar'body = 'foo bar'
class FileSize(object):class FileSize(object):
def __init__(self, context):def __init__(self, context): self.context = contextself.context = context
def getSize(self):def getSize(self): return len(self.context.body)return len(self.context.body)
tamano = FileSize(File())tamano = FileSize(File())print client.request()print client.request()
Adapters | Wrapper
Intrusivo clase base Intrusivo clase base
Test aisladamente Test aisladamente
Control factory Control factory
Colision de nombresColision de nombres
Patches compitenPatches compiten
Lo hace RubyLo hace Ruby
Wrapping es molestoWrapping es molesto
Zope es Cool!Zope es Cool!
Adapters | Comparación con Otros
por Brandon Craig Rhodes
Herencia
oo
xx
xx
xx
Mixin
oo
oo
xx
xx
MonkeyPatch
oo
xx
xx
xx
Adapter
oo
oo
oo
oo
xx
oo
oo
oo
oo
oo
oo
Adaptera'la Zope
1. Define an interface1. Define an interface
2. Register our adapter2. Register our adapter
3. Request adaptation3. Request adaptation
Adapters | 1, 2, 3
$ easy_install zope.interface$ easy_install zope.interface$ easy_install zope.component$ easy_install zope.component
Adapters | Install
import zope.interfaceimport zope.interfaceclass IFile(zope.interface.Interface):class IFile(zope.interface.Interface):
body = zope.interface.Attribute('Contents of the file.')body = zope.interface.Attribute('Contents of the file.')
class ISize(zope.interface.Interface):class ISize(zope.interface.Interface):
def getSize():def getSize(): 'Return the size of an object.''Return the size of an object.'
Adapters | Define an interface
from zope.interface.adapter import AdapterRegistryfrom zope.interface.adapter import AdapterRegistryregistry = AdapterRegistry()registry = AdapterRegistry()registry.register([IFile], ISize, '', FileSize)registry.register([IFile], ISize, '', FileSize)
Adapters | Register our adapterRegister our adapter
>>>>>> def hook(provided, object): def hook(provided, object):>>>>>> adapter = registry.lookup1(zope.interface.providedBy(object), adapter = registry.lookup1(zope.interface.providedBy(object),>>>>>> provided, '') provided, '')>>>>>> return adapter(object) return adapter(object)
>>> >>> from zope.interface.interface import adapter_hooksfrom zope.interface.interface import adapter_hooks>>>>>> adapter_hooks.append(hook)adapter_hooks.append(hook)
>>> size = ISize(file)>>> size = ISize(file)>>> size.getSize()>>> size.getSize()77
Adapters | Request adaptationRequest adaptation
Using the Adapter RegistryUsing the Adapter Registryhttp://docs.zope.org/zope3/Book/ifaceschema/human/show.htmlhttp://docs.zope.org/zope3/Book/ifaceschema/human/show.html
Using Grok to walk like a DuckUsing Grok to walk like a DuckBrandon Rhodes - Pycon08, PloneConf 08Brandon Rhodes - Pycon08, PloneConf 08
Adapters | Mas Lectura