SlideShare a Scribd company logo
Asko Soukka, asko.soukka@iki.fi
github.com/datakurre
Instant features with
advanced Plone themes
What if. . .
Case of the day: Wall of images
– Resource bundles
– Folderish content type
– Custom view template
for Wall of images with
Masonry.js layout
– Workflow for accepting
anonymous submissions
– Image content type for
anonymous submissions
– Add permission for
restricting anonymous
visitor submission
– Content rule for
thanking about
submission
– Review portlet for listing
the pending submissions
– i18n with l10n message
catalog
Python packages vs. theme?
Python packages
– One package for new JS
– Another for new types
– Customer specific
theming of components
in theme package
– Configuring everything in
policy package
– Restarting Plone
Advanced theme
– Everything in a single
zipped Plone theme
package
– Upload through Plone
control panel or using
npm package
plonetheme-upload
Plone customization features
– Configurable registry
– Structured content types
– Content type behaviors
– State based workflows
– Roles and permissions
– All types of portlets
– Content rules on events
– Restricted templates
– Restricted Python scripts
– Static frontend resources
– Diazo transform rules
– . . .
Plone customization features
– Configurable registry
– Structured content types
– Content type behaviors
– State based workflows
– Roles and permissions
– All types of portlets
– Content rules on events
– Restricted templates
– Restricted Python scripts
– Static frontend resources
– Diazo transform rules
– . . .
Restricted Python?
”Restricted Python provides a safety net for
programmers who don’t know the details of
the Zope/Plone security model.
It is important that you understand that the
safety net is not perfect: it is not adequate to
protect your site from coding by an untrusted
user.”
– Steve McMahon, collectice.ambidexterity README
Issues with Restricted Python
Not only ponies and unicorns...
– API is restrictedTraversed, not imported
– API is not always complete
– API is not always up-to-date
– API is scattered around the ecosystem
– plone.api is not currently designed or available by default
to be called from Restricted Python
Building instant features with advanced Plone themes
Products.DocFinderTab
”through-the-web”
=
technical debt
Advanced Plone themes
– Theme with any supported customizations
– Editable using Plone theme editor
– Rollbacks with Zope2 undo form
– Zip-exportable and importable from theme editor
– Supports ”TTW” and ”file system" development
– Exports can be version controlled
– Exports can be acceptance tested
collective.themesitesetup
Theme activation or update
– Imports GS profile steps
– Updates DX models
– Registers permissions
– Registers l10m messages
– Copies resources into
portal_resources
Theme deactivation
– Imports GS profile steps
– Unregisters added
custom permissions
– Unregisters added
custom l10n messages
After ”TTW” development
– @@export-site-setup
collective.themefragments
View templates: ./fragments/foobar.pt
– Can be injected as fragments using Diazo rules
– Can be configured as a default view for any content type
– Can be used as a local view by setting layout attribute
Python scripts: ./fragments/foobar.py
– Can provide view methods for view templates with
matching base name (tal:define="data view/getData")
Faster iterations
=
More iterations
Let’s get our hands dirty. . .
Creating Wall of images
– Initial configuration was made through Plone site setup
– Configuration was exported into a new theme using the
export view ++theme++.../@@export-site-setup
– Theme was zip-exported from theming control panel
– Content type schemas were exported from Dexterity editor
– Development was completed on a regular file system
buildout using file system resources directory
Structure of Wall of images
./bundles/
./fragments/
./install/types/
./install/workflows/
./install/
./locales/LC_MESSAGES/*/
./models/
./index.html
./manifest.cfg
./preview.png
./rules.xml
./scripts.js
./styles.css
Custom frontend bundles 1/2
./bundles/imagesloaded.pkgd.min.css
./bundles/imagesloaded.pkgd.min.js
./bundles/masonry.pkgd.min.css
./bundles/masonry.pkgd.min.js
(function() { var require, define;
// ...
// AMD packaged JS distributions must be wrapped
// so that Plone require.js define is undefined
// during their load
// ...
})();
Custom frontend bundles 2/2
./install/registry.xml
<records prefix="plone.bundles/imagesloaded-js"
interface="...interfaces.IBundleRegistry">
<value key="depends">plone</value>
<value key="jscompilation">++theme++...js</value>
<value key="csscompilation">++theme++...css</value>
<value key="last_compilation">2017-10-06 00:00:00
</value>
<value key="compile">False</value>
<value key="enabled">True</value>
</records>
Custom content types 1/2
./install/types/wall_of_images.xml
./install/types/wall_of_images_image.xml
./install/types.xml
<object name="portal_types">
<object name="wall_of_images"
meta_type="Dexterity FTI"/>
<object name="wall_of_images_image"
meta_type="Dexterity FTI"/>
</object>
./models/wall_of_images.xml
./models/wall_of_images_image.xml
Custom content types 2/2
<model xmlns:...="..." i18n:domain="plone">
<schema>
<field
name="title" type="zope.schema.TextLine">
<title i18n:translate="">Title</title>
</field>
<field
name="image"
type="plone.namedfile.field.NamedBlobImage">
<title i18n:translate="">Image</title>
</field>
</schema>
</model>
Custom views 1/3
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:...="..."
lang="en"
metal:use-macro=".../macros/master"
i18n:domain="plone">
<body>
<metal:main fill-slot="main">
<metal:content-core define-macro="content-core">
</metal:content-core>
</metal:main>
</body>
</html>
Custom views 2/3
./fragments/wall-of-images.pt
<div class="wall-of-images container-fluid"
tal:define="items context/@@contentlisting">
<tal:image tal:repeat="item items">
<img tal:define="obj item/getObject;
scale_func obj/@@images;
scaled_image python:scale_func.scale('image',
scale='preview')"→
tal:replace="structure
python:scaled_image.tag()"→
tal:on-error="string:error" />
</tal:image>
</div>
Custom views 3/3
./install/types/wall_of_images.xml
...
<property name="default_view">
++themefragment++wall-of-images</property>
<property name="view_methods">
<element value="++themefragment++wall-of-images"/>
</property>
...
Any themefragment can be configured as content object view
by manually setting layout property of the content object.
Custom l10n messages
./locales/fi/LC_MESSAGES/plone.po
./locales/en/LC_MESSAGES/plone.po
msgid "Close from submissions"
msgstr "Sulje osallistuminen"
msgid "Open for submissions"
msgstr "Avaa osallistumiselle"
When theme is developed on file system, normal i18n tools
can be used for messages extraction and catalog
synchronization (e.g. i18ndude).
Custom permissions
./manifest.cfg
[theme:genericsetup]
permissions =
demotheme.addImage Wall of Images: Add Image
./install/types/wall_of_images_image.xml
<object name="wall_of_images_image" ...="..">
...
<property name="add_permission">
demotheme.addImage</property>
...
</object>
Custom workflows
./install/workflows.xml
./install/simple_publication_with_submission_workflow/
./install/wall_of_images_workflow/
<type type_id="wall_of_images">
<bound-workflow workflow_id="..."/>
</type>
<dc-workflow workflow_id="...">
...
<permission>Wall of Images: Add Image</permission>
...
</dc-workflow>
Custom content rules
./install/contentrules.xml
<contentrules>
<rule name="rule-image-thank-you"
title="Thank visitor from submission"
cascading="False"
description="Thanks visitor after submission"
event="...IObjectAddedEvent"
stop-after="False"
enabled="True">...</rule>
<assignment
name="rule-image-thank-you" bubbles="True"
enabled="True" location=""/>
</contentrules>
Final touch with Diazo-bundles
./manifest.cfg
production-css = /++theme++demotheme/styles.css
production-js = /++theme++demotheme/scripts.js
./scripts.js
jQuery(function($) {
$('.wall-of-images').imagesLoaded(function() {
$('.wall-of-images').masonry({
itemSelector: 'img',
percentPosition: true
});
});
});
Questions?Questions?
github.com/datakurre/ploneconf2017github.com/datakurre/ploneconf2017
What about Mosaic?
– Theme site setup can populate Mosaic site and content
layout resource directories from theme
– Theme fragment tile for Plone Mosaic can render selected
fragment with
– fragment-specific readable title
– fragment-specific XML schema based configuration form
– fragment-specific view permission
– fragment-specific caching rule
What about Webpack?
– Bundles in theme can be built with Webpack
– Diazo bundle in theme can be built with Webpack
– All frontend resources can be built with Webpack
– plonetheme.webpacktemplate
– plonetheme-webpack-plugin
– plonetheme-upload
Bonus: Custom JS widgets
./models/my_content_type.xml
...
<field name="focuspoint"
type="zope.schema.BytesLine">
<form:widget
type="z3c.form.browser.text.TextFieldWidget">
<klass>text-widget pat-focuspoint-widget</klass>
</form:widget>
<title i18n:translate="">Image focus point</title>
<required>false</required>
</field>
...

More Related Content

What's hot (12)

PDF
HTML5 Server Sent Events/JSF JAX 2011 Conference
Roger Kitain
 
PDF
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Jérémy Derussé
 
PDF
Deview 2013 mobile browser internals and trends_20131022
NAVER D2
 
PDF
JWT - Sécurisez vos APIs
André Tapia
 
PPSX
Rendering engine
Dharita Chokshi
 
PPTX
What is new in Notes & Domino Deleopment V10.x
Ulrich Krause
 
PDF
JEE Programming - 01 Introduction
Danairat Thanabodithammachari
 
PDF
Spring5 hibernate5 security5 lab step by step
Rajiv Gupta
 
PDF
Utiliser Webpack dans une application Symfony
Alain Hippolyte
 
KEY
Zend_Tool: Practical use and Extending
ZendCon
 
PDF
WebKit and Blink: open development powering the HTML5 revolution
juanjosanchezpenas
 
PDF
Dandelion 0.10.0
Thibault DUCHATEAU
 
HTML5 Server Sent Events/JSF JAX 2011 Conference
Roger Kitain
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Jérémy Derussé
 
Deview 2013 mobile browser internals and trends_20131022
NAVER D2
 
JWT - Sécurisez vos APIs
André Tapia
 
Rendering engine
Dharita Chokshi
 
What is new in Notes & Domino Deleopment V10.x
Ulrich Krause
 
JEE Programming - 01 Introduction
Danairat Thanabodithammachari
 
Spring5 hibernate5 security5 lab step by step
Rajiv Gupta
 
Utiliser Webpack dans une application Symfony
Alain Hippolyte
 
Zend_Tool: Practical use and Extending
ZendCon
 
WebKit and Blink: open development powering the HTML5 revolution
juanjosanchezpenas
 
Dandelion 0.10.0
Thibault DUCHATEAU
 

Similar to Building instant features with advanced Plone themes (20)

PDF
Frequently asked questions answered frequently - but now for the last time
Andreas Jung
 
ODP
Plone Intranet under the hood
Guido Stevens
 
PPT
New in Plone 3.3. What to expect from Plone 4
Quintagroup
 
PDF
Alternative Approach to Plone Theming (PyConWeb 2019)
Stefan Antonelli
 
PDF
Resource registries plone conf 2014
Ramon Navarro
 
KEY
Plone api
Nejc Zupan
 
PDF
Plone Futures
Eric Steele
 
PDF
Plone Futures, Plone Conference 2016 Keynote by Eric Steele
T. Kim Nguyen
 
PDF
Resource Registries: Plone Conference 2014
Rob Gietema
 
PDF
Der Freitag, A Use Case
khink
 
PDF
Introduction to Plone (November 2003)
Kiran Jonnalagadda
 
ODP
Plone for python programmers
Dylan Jay
 
PDF
Plone 6 Theming from Scratch
Stefan Antonelli
 
PDF
Alternative Approach to Plone Theming
Stefan Antonelli
 
PPTX
Pragmatic plone projects
Andreas Jung
 
PDF
Plone 5 theming
sneridagh
 
PDF
Plone 5 theming
Victor De Alba
 
PPTX
Pragmatische Plone Projekte
Andreas Jung
 
PDF
Plone 5 theming unleashed
sneridagh
 
PPT
Simplifying Plone
Jeffrey Clark
 
Frequently asked questions answered frequently - but now for the last time
Andreas Jung
 
Plone Intranet under the hood
Guido Stevens
 
New in Plone 3.3. What to expect from Plone 4
Quintagroup
 
Alternative Approach to Plone Theming (PyConWeb 2019)
Stefan Antonelli
 
Resource registries plone conf 2014
Ramon Navarro
 
Plone api
Nejc Zupan
 
Plone Futures
Eric Steele
 
Plone Futures, Plone Conference 2016 Keynote by Eric Steele
T. Kim Nguyen
 
Resource Registries: Plone Conference 2014
Rob Gietema
 
Der Freitag, A Use Case
khink
 
Introduction to Plone (November 2003)
Kiran Jonnalagadda
 
Plone for python programmers
Dylan Jay
 
Plone 6 Theming from Scratch
Stefan Antonelli
 
Alternative Approach to Plone Theming
Stefan Antonelli
 
Pragmatic plone projects
Andreas Jung
 
Plone 5 theming
sneridagh
 
Plone 5 theming
Victor De Alba
 
Pragmatische Plone Projekte
Andreas Jung
 
Plone 5 theming unleashed
sneridagh
 
Simplifying Plone
Jeffrey Clark
 
Ad

More from Asko Soukka (9)

PDF
Bird eye's view on Camunda open source ecosystem
Asko Soukka
 
PDF
Embedding BPMN-driven business processes into Plone
Asko Soukka
 
PDF
Plone and Volto in a Jamstack project
Asko Soukka
 
PDF
Deploying Plone and Volto, the Hard Way
Asko Soukka
 
PDF
How Plone Excels in GatsbyJS Content Mesh
Asko Soukka
 
PDF
ZServer Reloaded with HTTP/2 and WebSocket Support
Asko Soukka
 
PDF
Nix for Python developers
Asko Soukka
 
PDF
Acceptance testing plone sites and add ons with robot framework and selenium
Asko Soukka
 
PDF
Plone, rabbit mq and messaging that just works
Asko Soukka
 
Bird eye's view on Camunda open source ecosystem
Asko Soukka
 
Embedding BPMN-driven business processes into Plone
Asko Soukka
 
Plone and Volto in a Jamstack project
Asko Soukka
 
Deploying Plone and Volto, the Hard Way
Asko Soukka
 
How Plone Excels in GatsbyJS Content Mesh
Asko Soukka
 
ZServer Reloaded with HTTP/2 and WebSocket Support
Asko Soukka
 
Nix for Python developers
Asko Soukka
 
Acceptance testing plone sites and add ons with robot framework and selenium
Asko Soukka
 
Plone, rabbit mq and messaging that just works
Asko Soukka
 
Ad

Recently uploaded (20)

PPTX
Milwaukee Marketo User Group - Summer Road Trip: Mapping and Personalizing Yo...
bbedford2
 
PDF
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PPTX
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
AI Prompts Cheat Code prompt engineering
Avijit Kumar Roy
 
PPTX
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
PDF
Simplify React app login with asgardeo-sdk
vaibhav289687
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PPTX
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PPTX
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
PPTX
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
PPTX
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Milwaukee Marketo User Group - Summer Road Trip: Mapping and Personalizing Yo...
bbedford2
 
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
AI Prompts Cheat Code prompt engineering
Avijit Kumar Roy
 
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
Simplify React app login with asgardeo-sdk
vaibhav289687
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 

Building instant features with advanced Plone themes

  • 3. Case of the day: Wall of images – Resource bundles – Folderish content type – Custom view template for Wall of images with Masonry.js layout – Workflow for accepting anonymous submissions – Image content type for anonymous submissions – Add permission for restricting anonymous visitor submission – Content rule for thanking about submission – Review portlet for listing the pending submissions – i18n with l10n message catalog
  • 4. Python packages vs. theme? Python packages – One package for new JS – Another for new types – Customer specific theming of components in theme package – Configuring everything in policy package – Restarting Plone Advanced theme – Everything in a single zipped Plone theme package – Upload through Plone control panel or using npm package plonetheme-upload
  • 5. Plone customization features – Configurable registry – Structured content types – Content type behaviors – State based workflows – Roles and permissions – All types of portlets – Content rules on events – Restricted templates – Restricted Python scripts – Static frontend resources – Diazo transform rules – . . .
  • 6. Plone customization features – Configurable registry – Structured content types – Content type behaviors – State based workflows – Roles and permissions – All types of portlets – Content rules on events – Restricted templates – Restricted Python scripts – Static frontend resources – Diazo transform rules – . . .
  • 7. Restricted Python? ”Restricted Python provides a safety net for programmers who don’t know the details of the Zope/Plone security model. It is important that you understand that the safety net is not perfect: it is not adequate to protect your site from coding by an untrusted user.” – Steve McMahon, collectice.ambidexterity README
  • 8. Issues with Restricted Python Not only ponies and unicorns... – API is restrictedTraversed, not imported – API is not always complete – API is not always up-to-date – API is scattered around the ecosystem – plone.api is not currently designed or available by default to be called from Restricted Python
  • 12. Advanced Plone themes – Theme with any supported customizations – Editable using Plone theme editor – Rollbacks with Zope2 undo form – Zip-exportable and importable from theme editor – Supports ”TTW” and ”file system" development – Exports can be version controlled – Exports can be acceptance tested
  • 13. collective.themesitesetup Theme activation or update – Imports GS profile steps – Updates DX models – Registers permissions – Registers l10m messages – Copies resources into portal_resources Theme deactivation – Imports GS profile steps – Unregisters added custom permissions – Unregisters added custom l10n messages After ”TTW” development – @@export-site-setup
  • 14. collective.themefragments View templates: ./fragments/foobar.pt – Can be injected as fragments using Diazo rules – Can be configured as a default view for any content type – Can be used as a local view by setting layout attribute Python scripts: ./fragments/foobar.py – Can provide view methods for view templates with matching base name (tal:define="data view/getData")
  • 16. Let’s get our hands dirty. . .
  • 17. Creating Wall of images – Initial configuration was made through Plone site setup – Configuration was exported into a new theme using the export view ++theme++.../@@export-site-setup – Theme was zip-exported from theming control panel – Content type schemas were exported from Dexterity editor – Development was completed on a regular file system buildout using file system resources directory
  • 18. Structure of Wall of images ./bundles/ ./fragments/ ./install/types/ ./install/workflows/ ./install/ ./locales/LC_MESSAGES/*/ ./models/ ./index.html ./manifest.cfg ./preview.png ./rules.xml ./scripts.js ./styles.css
  • 19. Custom frontend bundles 1/2 ./bundles/imagesloaded.pkgd.min.css ./bundles/imagesloaded.pkgd.min.js ./bundles/masonry.pkgd.min.css ./bundles/masonry.pkgd.min.js (function() { var require, define; // ... // AMD packaged JS distributions must be wrapped // so that Plone require.js define is undefined // during their load // ... })();
  • 20. Custom frontend bundles 2/2 ./install/registry.xml <records prefix="plone.bundles/imagesloaded-js" interface="...interfaces.IBundleRegistry"> <value key="depends">plone</value> <value key="jscompilation">++theme++...js</value> <value key="csscompilation">++theme++...css</value> <value key="last_compilation">2017-10-06 00:00:00 </value> <value key="compile">False</value> <value key="enabled">True</value> </records>
  • 21. Custom content types 1/2 ./install/types/wall_of_images.xml ./install/types/wall_of_images_image.xml ./install/types.xml <object name="portal_types"> <object name="wall_of_images" meta_type="Dexterity FTI"/> <object name="wall_of_images_image" meta_type="Dexterity FTI"/> </object> ./models/wall_of_images.xml ./models/wall_of_images_image.xml
  • 22. Custom content types 2/2 <model xmlns:...="..." i18n:domain="plone"> <schema> <field name="title" type="zope.schema.TextLine"> <title i18n:translate="">Title</title> </field> <field name="image" type="plone.namedfile.field.NamedBlobImage"> <title i18n:translate="">Image</title> </field> </schema> </model>
  • 23. Custom views 1/3 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:...="..." lang="en" metal:use-macro=".../macros/master" i18n:domain="plone"> <body> <metal:main fill-slot="main"> <metal:content-core define-macro="content-core"> </metal:content-core> </metal:main> </body> </html>
  • 24. Custom views 2/3 ./fragments/wall-of-images.pt <div class="wall-of-images container-fluid" tal:define="items context/@@contentlisting"> <tal:image tal:repeat="item items"> <img tal:define="obj item/getObject; scale_func obj/@@images; scaled_image python:scale_func.scale('image', scale='preview')"→ tal:replace="structure python:scaled_image.tag()"→ tal:on-error="string:error" /> </tal:image> </div>
  • 25. Custom views 3/3 ./install/types/wall_of_images.xml ... <property name="default_view"> ++themefragment++wall-of-images</property> <property name="view_methods"> <element value="++themefragment++wall-of-images"/> </property> ... Any themefragment can be configured as content object view by manually setting layout property of the content object.
  • 26. Custom l10n messages ./locales/fi/LC_MESSAGES/plone.po ./locales/en/LC_MESSAGES/plone.po msgid "Close from submissions" msgstr "Sulje osallistuminen" msgid "Open for submissions" msgstr "Avaa osallistumiselle" When theme is developed on file system, normal i18n tools can be used for messages extraction and catalog synchronization (e.g. i18ndude).
  • 27. Custom permissions ./manifest.cfg [theme:genericsetup] permissions = demotheme.addImage Wall of Images: Add Image ./install/types/wall_of_images_image.xml <object name="wall_of_images_image" ...=".."> ... <property name="add_permission"> demotheme.addImage</property> ... </object>
  • 28. Custom workflows ./install/workflows.xml ./install/simple_publication_with_submission_workflow/ ./install/wall_of_images_workflow/ <type type_id="wall_of_images"> <bound-workflow workflow_id="..."/> </type> <dc-workflow workflow_id="..."> ... <permission>Wall of Images: Add Image</permission> ... </dc-workflow>
  • 29. Custom content rules ./install/contentrules.xml <contentrules> <rule name="rule-image-thank-you" title="Thank visitor from submission" cascading="False" description="Thanks visitor after submission" event="...IObjectAddedEvent" stop-after="False" enabled="True">...</rule> <assignment name="rule-image-thank-you" bubbles="True" enabled="True" location=""/> </contentrules>
  • 30. Final touch with Diazo-bundles ./manifest.cfg production-css = /++theme++demotheme/styles.css production-js = /++theme++demotheme/scripts.js ./scripts.js jQuery(function($) { $('.wall-of-images').imagesLoaded(function() { $('.wall-of-images').masonry({ itemSelector: 'img', percentPosition: true }); }); });
  • 32. What about Mosaic? – Theme site setup can populate Mosaic site and content layout resource directories from theme – Theme fragment tile for Plone Mosaic can render selected fragment with – fragment-specific readable title – fragment-specific XML schema based configuration form – fragment-specific view permission – fragment-specific caching rule
  • 33. What about Webpack? – Bundles in theme can be built with Webpack – Diazo bundle in theme can be built with Webpack – All frontend resources can be built with Webpack – plonetheme.webpacktemplate – plonetheme-webpack-plugin – plonetheme-upload
  • 34. Bonus: Custom JS widgets ./models/my_content_type.xml ... <field name="focuspoint" type="zope.schema.BytesLine"> <form:widget type="z3c.form.browser.text.TextFieldWidget"> <klass>text-widget pat-focuspoint-widget</klass> </form:widget> <title i18n:translate="">Image focus point</title> <required>false</required> </field> ...