SlideShare a Scribd company logo
Event Driven Programming in
           Plone
                     Matt Hamilton


    ...or how to extend Plone the lazy way



                Matt Hamilton
             Technical Director, Netsight
Who am I?


                    - Matt Hamilton
                    - Technical Director of
                         Netsight Internet Solutions

                    - A Plone ‘integrator’
                matth@netsight.co.uk
                     @hammertoe


Matt Hamilton       European Plone Symposium 2010, Sorrento          2
Who is this talk for?


           - Integrators
           - Those newish to Plone, they can
                assemble together a site from a
                number of products, but don't really
                want to alter them

           - I consider myself 'experienced' but this
                was a bit of an epiphany for me


Matt Hamilton           European Plone Symposium 2010, Sorrento   3
What is the problem?




                          ?
Matt Hamilton   European Plone Symposium 2010, Sorrento   4
What is the problem?




                I want to change the functionality of an
                existing product, but don't want to
                change the guts of it.




Matt Hamilton             European Plone Symposium 2010, Sorrento   5
What is the problem?




                Came from a real life problem.
                Developing Netsight's new website.
                Wanted to use plone.app.discussion, but
                needed to add spam checking on
                comments




Matt Hamilton            European Plone Symposium 2010, Sorrento   6
What is the problem?




Matt Hamilton   European Plone Symposium 2010, Sorrento   7
What is the problem?




                plone.app.discussion has captcha
                support already, but I wanted to add
                Akismet support, but no easy extension
                point




Matt Hamilton            European Plone Symposium 2010, Sorrento   8
Admittedly, I could have offered to
                refactor the whole p.a.discussion code ;)




Matt Hamilton             European Plone Symposium 2010, Sorrento   9
Considered Approaches


           - I could subclass the product and
                override it
                ➡ A lot of boiler-plate for small change

           - I could use an adapter and adapt the
                behaviour
                ➡ No adapter lookup where I needed it

           - I could 'just hack it in the original code'
                ➡ Yuck! Maintainability nightmare


Matt Hamilton                European Plone Symposium 2010, Sorrento   10
Eureka!

Matt Hamilton   European Plone Symposium 2010, Sorrento   11
Eureka!




                Use Events!


Matt Hamilton    European Plone Symposium 2010, Sorrento        12
Eureka!




           - I realised I could leave p.a.discussion
                alone, and just listen for an event for
                when a comment is added and then
                check it for spam

           - I can listen for an event from Plone and
                then do the behaviour afterwards



Matt Hamilton            European Plone Symposium 2010, Sorrento        13
Advantages




           - Leave the existing code alone
           - Work around lack of suitable extension
                point

           - Very little boilerplate code
           - All happens in same transaction still

Matt Hamilton           European Plone Symposium 2010, Sorrento           14
Zope's Event System




           - Events
           - Subscribers


Matt Hamilton        European Plone Symposium 2010, Sorrento   15
A Simple Event
    in configure.zcml:

    <subscriber
      for=".interfaces.IMyObject
           .interfaces.IMyEvent"
      handler=".events.myEventHandler"
      />


    in events.py:

    def myEventHandler( object, event):
        object.doSomeThing()


Matt Hamilton           European Plone Symposium 2010, Sorrento       16
Event Simpler Event


   in events.py:

   from five import grok
   from interfaces import IMyObject, IMyEvent

   @@grok.subscribe(IMyObject, IMyEvent)
   def myEventHandler( object, event):
       object.doSomeThing()




Matt Hamilton      European Plone Symposium 2010, Sorrento   17
Example - Spam Checking

     in events.py:

     from five import grok
     from plone.app.discussion.interfaces 
                        import IComment
     from zope.lifecycleevent.interfaces 
                        import IObjectAddedEvent

     @@grok.subscribe(IComment,
                     IObjectAddedEvent)
     def checkForSpam( comment, event):
         wf = getToolByName(comment,
                            'portal_workflow')
         if is_spam(comment.text):
              wf.doActionFor(comment, ‘spam’)


Matt Hamilton        European Plone Symposium 2010, Sorrento   18
Next Example - GetPaid




            GetPaid is an eCommerce add-on to
            Plone

            ➡ Allows you to mark any piece of
              content as ‘buyable’




Matt Hamilton         European Plone Symposium 2010, Sorrento   19
PloneConf 2010 Registration

                       User clicks ‘register’


         User fills in ‘add attendee’ form, and hits submit


         Event fired indicating object added to container


      Event subscriber marks item as buyable, adds to
       shopping cart, and then redirects to cart view
Matt Hamilton         European Plone Symposium 2010, Sorrento   20
GetPaid Example

     from Products.CMFCore.utils import getToolByName
     from getpaid.core.interfaces import workflow_states
     import interfaces

     def handlePaymentReceived( order, event ):

             if event.destination !=workflow_states.order.finance.CHARGED:
                 return
                
             for item in order.shopping_cart.values():
                 ob = item.resolve()
                 workflow = getToolByName( ob, 'portal_workflow')
                 state = workflow.getInfoFor( ob, 'review_state' )          
                 if state == 'published':
                     return
                 workflow.doActionFor( ob, 'publish')



Matt Hamilton              European Plone Symposium 2010, Sorrento    21
Other Ideas



           - Whenever a Folder is created, add
                some default content to it

           - When a Page is added, set some
                metadata fields

           - When an Event is added, check that an
                expiry date has been set no more than
                12 months in the future


Matt Hamilton           European Plone Symposium 2010, Sorrento            22
Questions?
        Matt Hamilton


matth@netsight.co.uk

More Related Content

PDF
The Flexibility of Open Source: A Case Study of a large Corporate Intranet
PDF
An introduction to Zope Page Templates and their use outside of Zope (+Audio)
PPT
Lipstick On a Pig (+Audio)
PDF
Plone Intranet talk at Plone Open Garden 2014, Sorrento
PDF
Plone and Sharepoint
PDF
A Journey Through Open Source
PDF
Adventures in Wonderland - A Plone Developer's Year in iOS
PDF
BathCamp #32 - CMS Smackdown! - Plone
The Flexibility of Open Source: A Case Study of a large Corporate Intranet
An introduction to Zope Page Templates and their use outside of Zope (+Audio)
Lipstick On a Pig (+Audio)
Plone Intranet talk at Plone Open Garden 2014, Sorrento
Plone and Sharepoint
A Journey Through Open Source
Adventures in Wonderland - A Plone Developer's Year in iOS
BathCamp #32 - CMS Smackdown! - Plone

Similar to Plone: Event Driven Programming (20)

PDF
Soirée BPM - Introduction Logica
PDF
Internationalizing a React Application with Polyglot
PDF
Survival of the Fittest: Modernize your NonStop applications today
PDF
Open Mobile Broadcasting Phones
PDF
Rat Pack Remote Control – an Internet of Things basics hands on workshop by S...
PDF
Running a Plone product on Substance D
PPSX
Export consulting for IT&C companies
PDF
How To Write A Robot For Google Wave
PDF
Linked Open Camera @ Fammi Sapere 2010
PPTX
OroCRM CTO Yoav Kutner Presents at Meet Magento
PDF
Puppet Camp Germany 2020 - Puppet Control Repo and GIT
PDF
Matomo: Your data compass
PDF
Agile cymru Slicing Stories July 2015
PDF
easy_install digipy &amp; mlboost
PDF
Dive into Pinkoi 2013
PDF
Rat Pack Remote Control - a technical Internet of Things (tm) basics primer
PDF
Roadmap monthly newsletter - June 2011
PDF
iPhone Apps with HTML5
PDF
Lean Thinking in IT by Marie-Pia Ignace, Lean IT Summit 2014
PPTX
Building a winning video marketing strategy - #MozCon 2013
Soirée BPM - Introduction Logica
Internationalizing a React Application with Polyglot
Survival of the Fittest: Modernize your NonStop applications today
Open Mobile Broadcasting Phones
Rat Pack Remote Control – an Internet of Things basics hands on workshop by S...
Running a Plone product on Substance D
Export consulting for IT&C companies
How To Write A Robot For Google Wave
Linked Open Camera @ Fammi Sapere 2010
OroCRM CTO Yoav Kutner Presents at Meet Magento
Puppet Camp Germany 2020 - Puppet Control Repo and GIT
Matomo: Your data compass
Agile cymru Slicing Stories July 2015
easy_install digipy &amp; mlboost
Dive into Pinkoi 2013
Rat Pack Remote Control - a technical Internet of Things (tm) basics primer
Roadmap monthly newsletter - June 2011
iPhone Apps with HTML5
Lean Thinking in IT by Marie-Pia Ignace, Lean IT Summit 2014
Building a winning video marketing strategy - #MozCon 2013
Ad

More from Matt Hamilton (16)

PDF
Ceci n’est pas un canard - Machine Learning and Generative Adversarial Networks
PDF
Ceci N'est Pas Un Canard – and Other Machine Learning Stories
PDF
Intro to Machine Learning and AI
PDF
Open Source, The Natural Fit for Content Management in the Enterprise
PDF
Supercharge Your Career with Open Source
PDF
How to get started with the Pluggable Authentication System
PDF
Plone and Single-Sign On - Active Directory and the Holy Grail
PDF
Mistakes Made and Lessons Learnt Scaling Plone post-Launch
PDF
Plone Symposium East 2011 Keynote: Plone, A Solution not a Product
PDF
Mountain Tops to Archipelagos - The People Behind Plone (+AUDIO)
PDF
The Flexibility of Open Source - Plone in the Public Sector
PDF
Plone - Revised Roadmap: Plone 3,4,5 and beyond - Dutch Plone Users Day (+AUDIO)
ODP
Lipstick on a Pig - European Plone Symposium 2009
PPTX
Kent Connects: Harnessing Open Source for Shared Services and Partnership Wor...
PDF
NextGen Roadshow Bmex Case Study
PDF
Open Source and Content Management (+audio)
Ceci n’est pas un canard - Machine Learning and Generative Adversarial Networks
Ceci N'est Pas Un Canard – and Other Machine Learning Stories
Intro to Machine Learning and AI
Open Source, The Natural Fit for Content Management in the Enterprise
Supercharge Your Career with Open Source
How to get started with the Pluggable Authentication System
Plone and Single-Sign On - Active Directory and the Holy Grail
Mistakes Made and Lessons Learnt Scaling Plone post-Launch
Plone Symposium East 2011 Keynote: Plone, A Solution not a Product
Mountain Tops to Archipelagos - The People Behind Plone (+AUDIO)
The Flexibility of Open Source - Plone in the Public Sector
Plone - Revised Roadmap: Plone 3,4,5 and beyond - Dutch Plone Users Day (+AUDIO)
Lipstick on a Pig - European Plone Symposium 2009
Kent Connects: Harnessing Open Source for Shared Services and Partnership Wor...
NextGen Roadshow Bmex Case Study
Open Source and Content Management (+audio)
Ad

Recently uploaded (20)

PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Encapsulation theory and applications.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Machine learning based COVID-19 study performance prediction
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
cuic standard and advanced reporting.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Big Data Technologies - Introduction.pptx
PDF
Assigned Numbers - 2025 - Bluetooth® Document
Diabetes mellitus diagnosis method based random forest with bat algorithm
Reach Out and Touch Someone: Haptics and Empathic Computing
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Agricultural_Statistics_at_a_Glance_2022_0.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Encapsulation theory and applications.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Machine learning based COVID-19 study performance prediction
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
The Rise and Fall of 3GPP – Time for a Sabbatical?
cuic standard and advanced reporting.pdf
Unlocking AI with Model Context Protocol (MCP)
A comparative analysis of optical character recognition models for extracting...
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Network Security Unit 5.pdf for BCA BBA.
Dropbox Q2 2025 Financial Results & Investor Presentation
Big Data Technologies - Introduction.pptx
Assigned Numbers - 2025 - Bluetooth® Document

Plone: Event Driven Programming

  • 1. Event Driven Programming in Plone Matt Hamilton ...or how to extend Plone the lazy way Matt Hamilton Technical Director, Netsight
  • 2. Who am I? - Matt Hamilton - Technical Director of Netsight Internet Solutions - A Plone ‘integrator’ matth@netsight.co.uk @hammertoe Matt Hamilton European Plone Symposium 2010, Sorrento 2
  • 3. Who is this talk for? - Integrators - Those newish to Plone, they can assemble together a site from a number of products, but don't really want to alter them - I consider myself 'experienced' but this was a bit of an epiphany for me Matt Hamilton European Plone Symposium 2010, Sorrento 3
  • 4. What is the problem? ? Matt Hamilton European Plone Symposium 2010, Sorrento 4
  • 5. What is the problem? I want to change the functionality of an existing product, but don't want to change the guts of it. Matt Hamilton European Plone Symposium 2010, Sorrento 5
  • 6. What is the problem? Came from a real life problem. Developing Netsight's new website. Wanted to use plone.app.discussion, but needed to add spam checking on comments Matt Hamilton European Plone Symposium 2010, Sorrento 6
  • 7. What is the problem? Matt Hamilton European Plone Symposium 2010, Sorrento 7
  • 8. What is the problem? plone.app.discussion has captcha support already, but I wanted to add Akismet support, but no easy extension point Matt Hamilton European Plone Symposium 2010, Sorrento 8
  • 9. Admittedly, I could have offered to refactor the whole p.a.discussion code ;) Matt Hamilton European Plone Symposium 2010, Sorrento 9
  • 10. Considered Approaches - I could subclass the product and override it ➡ A lot of boiler-plate for small change - I could use an adapter and adapt the behaviour ➡ No adapter lookup where I needed it - I could 'just hack it in the original code' ➡ Yuck! Maintainability nightmare Matt Hamilton European Plone Symposium 2010, Sorrento 10
  • 11. Eureka! Matt Hamilton European Plone Symposium 2010, Sorrento 11
  • 12. Eureka! Use Events! Matt Hamilton European Plone Symposium 2010, Sorrento 12
  • 13. Eureka! - I realised I could leave p.a.discussion alone, and just listen for an event for when a comment is added and then check it for spam - I can listen for an event from Plone and then do the behaviour afterwards Matt Hamilton European Plone Symposium 2010, Sorrento 13
  • 14. Advantages - Leave the existing code alone - Work around lack of suitable extension point - Very little boilerplate code - All happens in same transaction still Matt Hamilton European Plone Symposium 2010, Sorrento 14
  • 15. Zope's Event System - Events - Subscribers Matt Hamilton European Plone Symposium 2010, Sorrento 15
  • 16. A Simple Event in configure.zcml: <subscriber for=".interfaces.IMyObject .interfaces.IMyEvent" handler=".events.myEventHandler" /> in events.py: def myEventHandler( object, event): object.doSomeThing() Matt Hamilton European Plone Symposium 2010, Sorrento 16
  • 17. Event Simpler Event in events.py: from five import grok from interfaces import IMyObject, IMyEvent @@grok.subscribe(IMyObject, IMyEvent) def myEventHandler( object, event): object.doSomeThing() Matt Hamilton European Plone Symposium 2010, Sorrento 17
  • 18. Example - Spam Checking in events.py: from five import grok from plone.app.discussion.interfaces import IComment from zope.lifecycleevent.interfaces import IObjectAddedEvent @@grok.subscribe(IComment, IObjectAddedEvent) def checkForSpam( comment, event): wf = getToolByName(comment, 'portal_workflow') if is_spam(comment.text): wf.doActionFor(comment, ‘spam’) Matt Hamilton European Plone Symposium 2010, Sorrento 18
  • 19. Next Example - GetPaid GetPaid is an eCommerce add-on to Plone ➡ Allows you to mark any piece of content as ‘buyable’ Matt Hamilton European Plone Symposium 2010, Sorrento 19
  • 20. PloneConf 2010 Registration User clicks ‘register’ User fills in ‘add attendee’ form, and hits submit Event fired indicating object added to container Event subscriber marks item as buyable, adds to shopping cart, and then redirects to cart view Matt Hamilton European Plone Symposium 2010, Sorrento 20
  • 21. GetPaid Example from Products.CMFCore.utils import getToolByName from getpaid.core.interfaces import workflow_states import interfaces def handlePaymentReceived( order, event ):     if event.destination !=workflow_states.order.finance.CHARGED:         return             for item in order.shopping_cart.values():         ob = item.resolve()         workflow = getToolByName( ob, 'portal_workflow')         state = workflow.getInfoFor( ob, 'review_state' )                   if state == 'published':             return         workflow.doActionFor( ob, 'publish') Matt Hamilton European Plone Symposium 2010, Sorrento 21
  • 22. Other Ideas - Whenever a Folder is created, add some default content to it - When a Page is added, set some metadata fields - When an Event is added, check that an expiry date has been set no more than 12 months in the future Matt Hamilton European Plone Symposium 2010, Sorrento 22
  • 23. Questions? Matt Hamilton matth@netsight.co.uk