Download - Moving an old-style product to Plone 3
Moving an old-style product to Plone 3Plone Conference 2008 - Washington D.C.
Ricardo [email protected]
October 27, 2008
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Contents
Contents
1 About the Example
2 Get it to work
3 Benefit from Plone 3
Ricardo Alves [email protected] Moving an old-style product to Plone 3
About the Example
TuxLiveFM
ProductAdd-on for Plone 2.5Archetypes-based content typesMixin classesNew portletSkin layers
Ricardo Alves [email protected] Moving an old-style product to Plone 3
About the Example
TuxLiveFM – Structure
Products/TuxLiveFM/
Extensions/Install.py
__init__.pyconfig.pycontent/
show.pyepisode.pyseries.py__init__.py
skins/tuxfmlive/
portlet_lastepisode.ptradioshow_view.ptradioepisode_view.pttuxlivefm.css.dtmlsearch_episodes.pt
license.txtreadme.txtversion.txt
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Get it to work
Fix broken code due to API changes(CMFCorePermissions, ...)Use GenericSetup for product installationMigrate portlets
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation
Define a profile using GenericSetup
TuxLiveFM/configure.zcml
<configurexmlns="http://namespaces.zope.org/zope"xmlns:genericsetup="http://namespaces.zope.org/genericsetup"i18n_domain="TuxLiveFM">
<genericsetup:registerProfilename="tuxlivefm"title="TuxLiveFM"directory="profiles/default"description="TuxLiveFM product."provides="Products.GenericSetup.interfaces.EXTENSION"/>
</configure>
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation - Types
TuxLiveFM/Extensions/Install.py
...# install typesclasses = listTypes(PROJECT_NAME)installTypes(self, out, classes, PROJECT_NAME)
...
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation - Types
profiles/default/types.xml
<?xml version="1.0"?><object name="portal_types" meta_type="Plone Types Tool"><object name="RadioShow"
meta_type="Factory-based Type Information with dynamic views"/><object name="RadioEpisode"
meta_type="Factory-based Type Information with dynamic views"/></object>
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation - Types
profiles/default/types/RadioShow.xml
<?xml version="1.0"?><object name="RadioShow"
meta_type="Factory-based Type Information with dynamic views"i18n:domain="plone"xmlns:i18n="http://xml.zope.org/namespaces/i18n">
<property name="title" i18n:translate="">Radio Show</property><property name="description"
i18n:translate="">Describes a Radio Show.</property><property name="content_icon">document_icon.gif</property><property name="content_meta_type">RadioShow</property><property name="product">tuxfm</property><property name="factory">addRadioShow</property><property name="immediate_view">base_view</property><property name="global_allow">True</property><property name="filter_content_types">True</property><property name="allowed_content_types">...
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation - Skins
TuxLiveFM/Extensions/Install.py
...# install skinsinstall_subskin(self, out, GLOBALS)
...
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation - Skins
profiles/default/skins.xml
<?xml version="1.0"?><object name="portal_skins" allow_any="False"
cookie_persistence="False" default_skin="TuxLiveFM">
<object name="tuxlivefm_templates"meta_type="Filesystem Directory View"directory="Products.TuxLiveFm:skins/tuxlivefm_templates"/>
<skin-path name="TuxLiveFM" based-on="Plone Default"><layer name="tuxlivefm_templates" insert-after="custom"/>
</skin-path>
</object>
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation - CSS
TuxLiveFM/Extensions/Install.py
...# register stylesheetscss_tool = getToolByName(self, ’portal_css’)stylesheets = css_tool.getResources()stylesheet_ids = [x.getId() for x in stylesheets]
if ’tuxlivefm.css’ not in stylesheet_ids:css_tool.registerStylesheet(
’tuxlivefm.css’,expression=’’,media=’screen’,rel=’stylesheet’,rendering=’import’)
...
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Product Installation - CSS
profiles/default/cssregistry.xml
<?xml version="1.0"?><object name="portal_css">
<stylesheet title="" cacheable="True" compression="safe"cookable="True" enabled="1" expression=""id="tuxlivefm.css" media="screen" rel="stylesheet"rendering="import"/>
</object>
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Get it to work
Migrate portlets
Convert legacy portlets, orCreate classic portlet
<assignmentmanager="plone.rightcolumn"category="content_type"key="RadioShow"type="portlets.Classic">
<property name="template">portlet_lastepisode</property><property name="macro">portlet</property>
</assignment>
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Benefit from Plone 3
New Components for specialized behavior
Define interfaces
class IRadioSeries(Interface):
def lastEpisodeURL(self):""" Returns the URL of the last episode available."""
def searchEpisodes(self, **kwargs):""" Perform search in the available episodes."""
Replace mixin class with an adapter
<adapter factory=".content.series.RadioSeries"for=".interfaces.IRadioShow"provides=".interfaces.IRadioSeries"/>
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Benefit from Plone 3
Use browser views
Add browser view EpisodeSearchView
Move related methods to the view class.
class SearchEpisodesView(BrowserView):
def searchEpisodes(self, **kwargs):series = IRadioSeries(self.context)return series.searchEpisodes(**kwargs)
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Benefit from Plone 3
Deprecate old code
Use zope.deprecation for modules to be removedDeprecation period of one or two feature releases
import zope.deprecationzope.deprecation.deprecated(’ShowSeriesMixin’,"Products.TuxLiveFM.content.series.ShowSeriesMixin has ""been deprecated and will be removed in version 0.3.")
Move deprecated templates to another layer.
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Benefit from Plone 3
Use Zope 3 Interfaces with Archetypes
Define Zope 3 schema interface for content types
from zope import schema...class IRadioShow(Interface):
body = schema.Text(title=_(u’Body’))...
Use ATFieldProperty as a bridge from fields to Python properties
from Products.Archetypes import public as atapi...
body = atapi.ATFieldProperty(’body’)...
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Benefit from Plone 3
TuxLiveFM – Structure
Products/TuxLiveFM/
__init__.pyconfig.pyinterfaces.pybrowser/
search_episodes.pysearch_episodes.pt
profiles/default/
types/types.xmlskins.xmlcssregistry.xmlportlets.xmlactionicons.xml
content/show.pyepisode.pyseries.py
skins/tuxfmlive/
radioshow_view.ptradioepisode_view.pttuxlivefm.css.dtmlportlet_lastepisode.pt
tuxfmlive_deprecated/search_episodes.pt
license.txtreadme.txtversion.txt
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Benefit from Plone 3
Eggify the Product
Use paster to create the package structure:paster create -t plone
Products.TuxLiveFM/Products/
TuxLiveFM/...
docsProducts.TuxLiveFM.egg-info/setup.cfgREADME.txtsetup.py
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Benefit from Plone 3
References
Plone Upgrade Guide –http://plone.org/documentation/manual/upgrade-guide/version/2.5-3.0/products
TuxLiveFM in the collective (soon)
Ricardo Alves [email protected] Moving an old-style product to Plone 3
Questions
Questions
Questions?
Ricardo Alves [email protected] Moving an old-style product to Plone 3