Plone三方产品开发指南
Plone三方产品开发指南
http://www.315ok.org/blogfolder/258
http://www.315ok.org/logo.png
Plone三方产品开发指南
Plone三方产品开发指南
1. IntroductionWho this documentation is for, and some initial thoughts what makes a high quality product.
IntroductionThe Plone core is a beautiful thing. It does a lot of things, and does a lot of things well. But much of the power of Plone lies in its large and growing library of add-on products, which extend Plone in ways both large and small. Many of Plone's core components started life as add-on products, and add-on products are the primary way to share and reuse code in the Plone community.
This guide is intended to help new product developers who wish develop high quality add-on products and contribute those products to the Plone community. It will also be useful to add-on product developers wanting to future-proof their products through the use of best coding practices.
Do you even need to write a product?
Sometimes the best product is one that never gets written because the developer just contributes to something that already exists. Before you dive into writing a new product from scratch, it's worth taking a bit of time to check out the Products section of Plone.org as well as the Plone Collective (our shared SVN code repository), to see if someone else has already taken a run at solving your problem.
It's in the long-term interest of the Plone community to have fewer, higher-quality, more generalized products than many products that all solve very similar problems in slightly different ways. Most Plone add-on product developers are very open to new contributors, and would welcome your help in making an existing product better!
The Product-Developers Email Listhttp://plone.org/support#product-developers
A list for add-on product developers to get help with their Collective-hosted products - updates to newer Plone versions, migrations and general questions about Plone add-on development.
General Characteristics of High Quality Add-on ProductsAdd-on products from Plone range from the very simple to the extremely complex, which means that what makes a product "high quality" may vary quite a bit from one product to the next. That said, most high quality products will have the following general qualities.
Balancing Extensibility and SimplicityA good add-on product is designed to be customizable / extensible / adaptable, where appropriate. It should be easy to define different content types which use any custom logic or machinery in your product. It should be easy to subclass any custom content types in your Product.
At the same time, simplicity is a virtue. Good products solve the problem they're trying to solve, without going overboard creating new frameworks or making every single point of the product customizable, using a minimal number of needed methods, etc. "Does one thing, and does it well."
Using Zope 3 Development TechniquesWith the advent of Zope 3 technology, the Plone community now places a very high value on good componentization. Complex products should broken into multiple products, libraries, methods and classes, consisting of Zope 3 compoments (interfaces, views, annotations, etc.) that can be re-used by other products.
Good starting points for learning how to apply Zope 3 development techniques in add-on Products include:
A good starting point for learning more about Archetypes is:
Well Designed User Interface
Plone prides itself on being the most highly usable and accessible content management system around. Add-on product developers should pay attention to the user interface for their products. For example,
Useful starting points on security in Plone include:
Internationalization (i18n)Plone has users all over the world, and Plone's internationalization framework is one of its strongest features. But it's not worth much unless add-on Product authors make sure their products are i18n-ready. (Don't worry, you regrettably monolingual folks, it's really quite easy, and no foreign language skills are needed!).
Good starting points:
Naming your productChoosing a good name really helps people understand what your product is and what it does. Unfortunately, the Plone and Zope communities have a history of coining awkward product names. Here are some recommendations for choosing a great product name.
Renaming a product is painful because of migration hassles for later releases, so getting the project name right the first time around will save you work later.
[table]
[td][tr][td]Good
[/td][td]less good
[/td][/tr]
[tr][td]"Wicked" - a wiki product
[/td][td]ATSchemaEditorNG
[/td][/tr]
[tr][td]"Iterate" - product for document staging
[/td][td]Kukit (turned out to be a Norwegian expletive!)
[/td][/tr]
[tr][td]"Quills" - a blogging product
[/td][td]CMFSin
[/td][/tr]
[tr][td]"Bling" - a javascript product
[/td][td]mxmContacts[/td][/tr]
[/table]
2. Good coding practicesThere's a tremendous amount of wisdom in the Plone community about how to write code efficiently and effectively. Here's a summary.
General Best PracticesJoel Burton's tutorial Best Practices for Plone Development is an essential starting point for anyone new to Plone development. It covers the basics of working with filesystem code, source code management, configuration management, documentation, debugging and testing. Some parts of it (e.g. configuration management) are getting a bit out of date, but overall, it's the single best starting point for the nitty-gritty of development technique.
General coding standards
How I Learned To Stop Worrying and Love the APIOne of the cool things about Plone is its API. Anything you can do through the web interface, you can do via filesystem code that manipulates the Plone API. Of course, that raises the question of how you discover what API methods to call. The following products can help.
DocFinderTabDocFinderTab gives you instant, through-the-web access to the API for any object you can get to in the ZMI. In many ways, it's nicer than looking through the source code, since you see all the methods of the base classes, and nicer that looking in the debugger, because you get things arranged by base class. This product is dead simple to install and use. There's no excuse for not trying it out today. This really should get shipped as part of Zope. Clouseau Clouseau is an AJAX-based interactive Zope/Python prompt that lets you interact with Zope and Python directly from within Plone. It's very easy to use, has no dependencies, and is extremely handy.
Other products' Install.py filesA great way to see how to configure things is to see how other products do it, of course. Look at the Install.py for your favorite product. For example, to learn how to install new workflows from disk, see how we do this in PloneHelpCenter.For a great introduction to using the Plone API, see:
Developer Documentation
Testing and DocTestsPlone has a strong culture of test-driven software development. In fact, many folks in the Plone community often judge the quality of add-on products by looking at the tests. Good tests mean that you can prove your product works, and helps you avoid breaking your product as you (and others) develop it on an ongoing basis.
Plone/Zope 3 developer Phillip von Weitershausen (PhiliKON) offers the following advice on testing:
[indent]Just because you write doctests doesn't mean you've also written docs. Testing and documenting is hard and doing them at the same time can mean you consolidate effort, but it also means you need think hard. Writing good tests, especially writing good doctests, is much more challenging than the coding itself. Be prepared to spend more time on this than the actual coding."
[/indent]Lots more great information on testing can be found in Martin Aspeli's tutorial "Testing in Plone."
Also worth a read: Agile Documentation with doctest and epydoc
Useful Documentation Products
The following products can help you generate documentation for your add-on products.
DCWorkflowGraphDCWorkflowGraph creates graphic diagrams of your workflows.
DCWorkflowDump DCWorkflowDump exports workflows you've built via the ZMI to Python code for a filesystem based product.
EpyDocEpydoc is a smarter and more featureful version of the module that ships with Zope. It builds handsome, indexed API documentation for your product, or even for Zope and Plone itself. It can even generate this as a PDF, which impresses clients and saves you time in creating this kind of documentation. Plus, actually seeing your docstrings typeset is a good incentive to write better one.
3. "Worst Practices", Or Things To AvoidRelevant bits from Stefan's "Top Twenty Plone Pitfalls" presentation.
At Plone Conference 2006, Stefan Holek ("lurker") presented a well-received talk called "Top Twenty Plone Pitfalls." You can read his entire presentation or watch it online.
A number of his pitfalls were especially revelant to developers of add-on products, and we've adapted them here as a set of "Worst Practices" or things to avoid.
Do not develop your application logic in TALES.Templates are for presentation, and for presentation only. You should put all of your application logic into Python code (scripts, tools). If you find yourself trying to create complex conditional statements in your templates, take a moment and think about how you can push your logic down into a Python script. Don't start writing increasingly complex TALES python: expressions – they will make your application hard to maintain, hard to debug and hard for others to understand.
Stefan humorously-but-seriously suggests that you make a small donation to the Plone Foundation every time you use “python:” in a Page Template. ;-)
Do not impose a relational data model on an object database.Do not expect the ZODB to work like MySQL. It won’t. The ZODB is an object database, not a relational database. Think about how to design your application in an object oriented way, rather than as rows of data in a table. Conversely, there is nothing wrong with using an RDBMS with Plone, if your data calls for it. The most common way to do this is to use a database connector and ZSQL methods to read/write data from your RDBMS.
Useful resources on how to do this include:
Do not call getObject on catalog results.
Do not use contentValues nor objectValues.
Do not return objects from scripts, return (lists of) dictionaries.
Do not compute values at display time.
4. Launch! Product Release and Community ProcessA good product release process helps you share your product with the world. Here are some tips on how to package up a solid release, and how to best engage in the Plone community process to build a network of users, developers and supporters around your product.
Making a good product release is about more than just slapping some code up for download. Here's what you should do to help the Plone community find, learn about, get started with and help you improve your products.
Connect With Other Product DevelopersYour fellow Plone product developers can be an amazing source of advice, help, enthusiasm and support. And they hang on on the product-developers mailing list. Come join us!
Listing Your Product on Plone.orgEach released product should have an entry in plone.org/products with accurate, up-to-date information on current and past releases. There's no need to make an entry before your first public release.
Plone Software Center (which powers plone.org/products) also offers a few extremely useful features to help you maintain and improve your code. We strongly recommend that you take advantage of:
Put Your Code in the Plone CollectiveEvery publicly released product should have a public SVN repository, preferably the Plone Collective, unless there is a compelling reason to put it elsewhere. Without a public SVN repository, the Plone community won't be able to help test or contribute to your product. The Collective is the single most "accessible" place for code in the Plone community.
DocumentationProducts that expose functionality to end-users of Plone should have end-user documentation, preferably at Plone.org/products, so it is easily accessible to people who do not have filesystem access.
IntroductionThe Plone core is a beautiful thing. It does a lot of things, and does a lot of things well. But much of the power of Plone lies in its large and growing library of add-on products, which extend Plone in ways both large and small. Many of Plone's core components started life as add-on products, and add-on products are the primary way to share and reuse code in the Plone community.
This guide is intended to help new product developers who wish develop high quality add-on products and contribute those products to the Plone community. It will also be useful to add-on product developers wanting to future-proof their products through the use of best coding practices.
Do you even need to write a product?
Sometimes the best product is one that never gets written because the developer just contributes to something that already exists. Before you dive into writing a new product from scratch, it's worth taking a bit of time to check out the Products section of Plone.org as well as the Plone Collective (our shared SVN code repository), to see if someone else has already taken a run at solving your problem.
It's in the long-term interest of the Plone community to have fewer, higher-quality, more generalized products than many products that all solve very similar problems in slightly different ways. Most Plone add-on product developers are very open to new contributors, and would welcome your help in making an existing product better!
The Product-Developers Email Listhttp://plone.org/support#product-developers
A list for add-on product developers to get help with their Collective-hosted products - updates to newer Plone versions, migrations and general questions about Plone add-on development.
General Characteristics of High Quality Add-on ProductsAdd-on products from Plone range from the very simple to the extremely complex, which means that what makes a product "high quality" may vary quite a bit from one product to the next. That said, most high quality products will have the following general qualities.
Balancing Extensibility and SimplicityA good add-on product is designed to be customizable / extensible / adaptable, where appropriate. It should be easy to define different content types which use any custom logic or machinery in your product. It should be easy to subclass any custom content types in your Product.
At the same time, simplicity is a virtue. Good products solve the problem they're trying to solve, without going overboard creating new frameworks or making every single point of the product customizable, using a minimal number of needed methods, etc. "Does one thing, and does it well."
Using Zope 3 Development TechniquesWith the advent of Zope 3 technology, the Plone community now places a very high value on good componentization. Complex products should broken into multiple products, libraries, methods and classes, consisting of Zope 3 compoments (interfaces, views, annotations, etc.) that can be re-used by other products.
Good starting points for learning how to apply Zope 3 development techniques in add-on Products include:
- b-org: an in-depth tutorial from Martin Aspeli. The video of Martin's b-org presentation from Plone Conference 2006 covers similar material.
- Rocky Burt's tutorial "Developing Plone Products Using Zope 3 Technologies" from Plone Conference 2006 is also worth a look. You can read the material and also watch a video of his talk.
A good starting point for learning more about Archetypes is:
Well Designed User Interface
Plone prides itself on being the most highly usable and accessible content management system around. Add-on product developers should pay attention to the user interface for their products. For example,
- Beginning with Plone 3.0, add-on Products can take advantage of the KSS javascript framework. Effective use of javascript can help you build a much more responsive and rich user interface. However,user interfaces should degrade gracefully (with functionality intact) in browsers that lack javascript.
- Products should use appropriate Archetypes or formlib widgets for editing interfaces. See:
- The Archetypes Widgets Reference
- More fields and widgets from the Archtypes SVN repository
- Push end-user configuration options into Plone control panels. Avoid making users go into the ZMI or the filesystem to configure your add-on products.
Useful starting points on security in Plone include:
- Andy McKay's security talk
- J Cameron Cooper on security
- Mikko Ohaatma on security
- Martin Aspeli on permissions and workflows
Internationalization (i18n)Plone has users all over the world, and Plone's internationalization framework is one of its strongest features. But it's not worth much unless add-on Product authors make sure their products are i18n-ready. (Don't worry, you regrettably monolingual folks, it's really quite easy, and no foreign language skills are needed!).
Good starting points:
Naming your productChoosing a good name really helps people understand what your product is and what it does. Unfortunately, the Plone and Zope communities have a history of coining awkward product names. Here are some recommendations for choosing a great product name.
Renaming a product is painful because of migration hassles for later releases, so getting the project name right the first time around will save you work later.
- Choose a name that is unique, memorable, and not too similar to other existing products.
- A good name is memorable, and describes or suggests what your product does.
- Avoid having the word "Plone" in your product name — it's usually obvious from the context that it is a Plone product. If you really feel the need to have Plone in the product name, it's better to call it something like "XYZ for Plone". Plone® is a worldwide registered trademark of the Plone Foundation, and people very often think products that contain the word is the responsibility of the Foundation, which is confusing and unnecessary.
- Avoid jargony acronyms like "AT" "CMF" "NG" etc. and names based on the underlying technologies of your product.
- Avoiding prefixing your products with your company name, or the company you are developing it for.
- Don't lowercase your human-readable product names just because Zope 3 convention is for lowercase names in code.
[table]
[td][tr][td]Good
[/td][td]less good
[/td][/tr]
[tr][td]"Wicked" - a wiki product
[/td][td]ATSchemaEditorNG
[/td][/tr]
[tr][td]"Iterate" - product for document staging
[/td][td]Kukit (turned out to be a Norwegian expletive!)
[/td][/tr]
[tr][td]"Quills" - a blogging product
[/td][td]CMFSin
[/td][/tr]
[tr][td]"Bling" - a javascript product
[/td][td]mxmContacts[/td][/tr]
[/table]
2. Good coding practicesThere's a tremendous amount of wisdom in the Plone community about how to write code efficiently and effectively. Here's a summary.
General Best PracticesJoel Burton's tutorial Best Practices for Plone Development is an essential starting point for anyone new to Plone development. It covers the basics of working with filesystem code, source code management, configuration management, documentation, debugging and testing. Some parts of it (e.g. configuration management) are getting a bit out of date, but overall, it's the single best starting point for the nitty-gritty of development technique.
General coding standards
- Most of the logic in an add-on Product is written in Python. Following good Python coding style guidelines will help make your Product understandable and maintainable.
- The Plone community values standards compliance and accessibility, so you should use proper XHTML, TALES, and CSS syntax. We recommend that you check your HTML, CSS and RSS for compliance with the relevant W3C standards.
- Avoid using DTML in your Plone add-on Product. Although Zope contains support for the DTML scripting language, DTML has been supplanted by TAL for building page templates and Python for underlying logic.
How I Learned To Stop Worrying and Love the APIOne of the cool things about Plone is its API. Anything you can do through the web interface, you can do via filesystem code that manipulates the Plone API. Of course, that raises the question of how you discover what API methods to call. The following products can help.
DocFinderTabDocFinderTab gives you instant, through-the-web access to the API for any object you can get to in the ZMI. In many ways, it's nicer than looking through the source code, since you see all the methods of the base classes, and nicer that looking in the debugger, because you get things arranged by base class. This product is dead simple to install and use. There's no excuse for not trying it out today. This really should get shipped as part of Zope. Clouseau Clouseau is an AJAX-based interactive Zope/Python prompt that lets you interact with Zope and Python directly from within Plone. It's very easy to use, has no dependencies, and is extremely handy.
Other products' Install.py filesA great way to see how to configure things is to see how other products do it, of course. Look at the Install.py for your favorite product. For example, to learn how to install new workflows from disk, see how we do this in PloneHelpCenter.For a great introduction to using the Plone API, see:
Developer Documentation
Testing and DocTestsPlone has a strong culture of test-driven software development. In fact, many folks in the Plone community often judge the quality of add-on products by looking at the tests. Good tests mean that you can prove your product works, and helps you avoid breaking your product as you (and others) develop it on an ongoing basis.
Plone/Zope 3 developer Phillip von Weitershausen (PhiliKON) offers the following advice on testing:
- The top-level *.txt texts should be unit tests if you're writing a basic Zope 3-style component. Unit tests means you should be using DocTestSuite/DocFileSuite from zope.testing.doctest, not any of the convoluted ZopeTestCase test suites. If your test needs set-up, only load as much as you need. Avoid loading ZCML in a unit test.
- Tell a story into which you involve the reader using first person plural ("we"). Create the component, walk through its API, explain tough edge cases and why it's necessary to watch out for them (and to test them). I know, this takes time.
- If you're writing functional tests, talk to the application using the test browser (Products.Five.testbrowser.Browser, docs in zope.testbrowser/README.txt). It's a great way of testing interactive UIs in a doctest, and the result is very readable.
[indent]Just because you write doctests doesn't mean you've also written docs. Testing and documenting is hard and doing them at the same time can mean you consolidate effort, but it also means you need think hard. Writing good tests, especially writing good doctests, is much more challenging than the coding itself. Be prepared to spend more time on this than the actual coding."
[/indent]Lots more great information on testing can be found in Martin Aspeli's tutorial "Testing in Plone."
Also worth a read: Agile Documentation with doctest and epydoc
Useful Documentation Products
The following products can help you generate documentation for your add-on products.
DCWorkflowGraphDCWorkflowGraph creates graphic diagrams of your workflows.
DCWorkflowDump DCWorkflowDump exports workflows you've built via the ZMI to Python code for a filesystem based product.
EpyDocEpydoc is a smarter and more featureful version of the module that ships with Zope. It builds handsome, indexed API documentation for your product, or even for Zope and Plone itself. It can even generate this as a PDF, which impresses clients and saves you time in creating this kind of documentation. Plus, actually seeing your docstrings typeset is a good incentive to write better one.
3. "Worst Practices", Or Things To AvoidRelevant bits from Stefan's "Top Twenty Plone Pitfalls" presentation.
At Plone Conference 2006, Stefan Holek ("lurker") presented a well-received talk called "Top Twenty Plone Pitfalls." You can read his entire presentation or watch it online.
A number of his pitfalls were especially revelant to developers of add-on products, and we've adapted them here as a set of "Worst Practices" or things to avoid.
Do not develop your application logic in TALES.Templates are for presentation, and for presentation only. You should put all of your application logic into Python code (scripts, tools). If you find yourself trying to create complex conditional statements in your templates, take a moment and think about how you can push your logic down into a Python script. Don't start writing increasingly complex TALES python: expressions – they will make your application hard to maintain, hard to debug and hard for others to understand.
Stefan humorously-but-seriously suggests that you make a small donation to the Plone Foundation every time you use “python:” in a Page Template. ;-)
Do not impose a relational data model on an object database.Do not expect the ZODB to work like MySQL. It won’t. The ZODB is an object database, not a relational database. Think about how to design your application in an object oriented way, rather than as rows of data in a table. Conversely, there is nothing wrong with using an RDBMS with Plone, if your data calls for it. The most common way to do this is to use a database connector and ZSQL methods to read/write data from your RDBMS.
Useful resources on how to do this include:
- http://www.plope.com/Books/2_7Edition/RelationalDatabases.stx
- http://plone.org/documentation/how-to/add-file-system-zsql-method
- http://plone.org/documentation/how-to/mysql-connectivity-in-zope-plone
- That’s because objects and methods are protected by permissions, not roles
- Use portal_membership.checkPermission.
- AUTHENTICATED_USER is unsafe and was deprecated many winters ago.\
- Use portal_membership.getAuthenticatedUser
- Authenticated is a system-owned role.
- Add your own custom role(s).
- Proxy roles are similar to SUID scripts in *nix.
- Be very careful about what your proxied scripts do; you are poking holes into your site’s security.
- That’s because Item, which is the base class for most Zope2 objects, allows access to unprotected attributes.
- Be extra careful with tools. Methods may need to be public and perform their own security checks.
Do not call getObject on catalog results.
- getObject uses restrictedTraverse internally.
- Add everything you need as catalog metadata.
Do not use contentValues nor objectValues.
- contentValues/objectValues “wake up” subobjects, i.e. load them from disk into memory.
- objectIds is OK, incidentally, but not contentIds.
Do not return objects from scripts, return (lists of) dictionaries.
- Objects cannot be RAM-cached.
- Objects will be security checked.
- Python scripts are prime targets for RAM-caching.
Do not compute values at display time.
- Compute values at edit time and store them.
- Viewing an object must not cause a database write.
- Easy to accidentally cause a modification; watch the Undo tab.
4. Launch! Product Release and Community ProcessA good product release process helps you share your product with the world. Here are some tips on how to package up a solid release, and how to best engage in the Plone community process to build a network of users, developers and supporters around your product.
Making a good product release is about more than just slapping some code up for download. Here's what you should do to help the Plone community find, learn about, get started with and help you improve your products.
Connect With Other Product DevelopersYour fellow Plone product developers can be an amazing source of advice, help, enthusiasm and support. And they hang on on the product-developers mailing list. Come join us!
Listing Your Product on Plone.orgEach released product should have an entry in plone.org/products with accurate, up-to-date information on current and past releases. There's no need to make an entry before your first public release.
Plone Software Center (which powers plone.org/products) also offers a few extremely useful features to help you maintain and improve your code. We strongly recommend that you take advantage of:
- Issue tracker: Every product should have a public issue tracker, preferably on Plone.org/products unless there is a compelling reason to put it elsewhere. This helps users of your product report bugs and find out when they're fixed.
- Roadmap: Active products should have a roadmap for future improvements and improvement proposals.
Put Your Code in the Plone CollectiveEvery publicly released product should have a public SVN repository, preferably the Plone Collective, unless there is a compelling reason to put it elsewhere. Without a public SVN repository, the Plone community won't be able to help test or contribute to your product. The Collective is the single most "accessible" place for code in the Plone community.
DocumentationProducts that expose functionality to end-users of Plone should have end-user documentation, preferably at Plone.org/products, so it is easily accessible to people who do not have filesystem access.
- Every product should have an INSTALL or README document that clearly describes how to install and uninstall the product, and lists any dependencies on other products or libraries.
- If appropriate, a product should have documentation for integrators that describes how the product can be customized or extended.
- Your product should include an open source license (preferably GPL), credits and have an appropriate version number.
- It's appropriate to announce new add-on products on the product-developers and plone-users email lists.
- The best place to ask for help with add-on product development is the product-developers list.