Replace the old NOTES.txt and PRINCIPLES.txt with the Sphinx versions. Fix Captcha title.
svn path=/plone.app.discussion/trunk/; revision=36998
This commit is contained in:
parent
adbe6c7db7
commit
af1a8bfacd
@ -1,59 +1 @@
|
|||||||
========================
|
.. include:: ../../plone/app/discussion/architecture.txt
|
||||||
Architectural Principles
|
|
||||||
========================
|
|
||||||
|
|
||||||
This document outlines architectural principles used in the design of
|
|
||||||
plone.app.discussion.
|
|
||||||
|
|
||||||
**Discussion items have a portal_type**
|
|
||||||
This makes it easier to search for them and manage them using existing
|
|
||||||
CMF and Plone UI constructs.
|
|
||||||
|
|
||||||
**Discussion items are cataloged**
|
|
||||||
It is possible to search for discussion items like any other type of
|
|
||||||
content.
|
|
||||||
|
|
||||||
**Discussion items are subject to workflow and permission**
|
|
||||||
Moderation, anonymous commenting, and auto approve/reject should be
|
|
||||||
handled using workflow states, automatic and manual transitions, and
|
|
||||||
permissions.
|
|
||||||
|
|
||||||
**Discussion items are light weight objects**
|
|
||||||
Discussion item objects are as light weight as possible. Ideally, a
|
|
||||||
discussion item should be as lightweight as a catalog brain. This may mean
|
|
||||||
that we forego convenience base classes and re-implement certain interfaces.
|
|
||||||
Comments should not provide the full set of dublin core metadata, though
|
|
||||||
custom indexers can be used to provide values for standard catalog indexes.
|
|
||||||
|
|
||||||
**Optimise for retrival speed**
|
|
||||||
HTML filtering and other processing should happen on save, not on render,
|
|
||||||
to make rendering quick.
|
|
||||||
|
|
||||||
**Settings are stored using plone.registry**
|
|
||||||
Any global setting should be stored in plone.registry records.
|
|
||||||
|
|
||||||
**Forms are constructed using extensible z3c.form forms**
|
|
||||||
This allows plugins (such as spam protection algorithms) to provide
|
|
||||||
additional validation. It also allows integrators to write add-ons that add
|
|
||||||
new fields to the comment form.
|
|
||||||
|
|
||||||
**Discussion items are stored in a BTree container**
|
|
||||||
This allows faster lookup and manipulation.
|
|
||||||
|
|
||||||
**Discussion items are accessed using a dict-like interface**
|
|
||||||
This makes iteration and manipulation more natural. Even if comments are
|
|
||||||
not stored threaded, the dict interface should act as if they are, i.e.
|
|
||||||
calling items() on a comment should return the replies to that comment
|
|
||||||
(in order).
|
|
||||||
|
|
||||||
**Discussion items are retrieved in reverse creation date order**
|
|
||||||
Discussion items do not need to support explicit ordering. They should
|
|
||||||
always be retrieved in reverse creation date order (most recent for).
|
|
||||||
They can be stored with keys so that this is always true.
|
|
||||||
|
|
||||||
**Discussion items do not need readable ids**
|
|
||||||
Ids can be based on the creation date.
|
|
||||||
|
|
||||||
**Discussion items send events**
|
|
||||||
The usual zope.lifecycleevent and zope.container events are fired when
|
|
||||||
discussion items are added, removed, or modified.
|
|
@ -1,167 +1 @@
|
|||||||
============
|
.. include:: ../../plone/app/discussion/design.txt
|
||||||
Design Notes
|
|
||||||
============
|
|
||||||
|
|
||||||
This document contains design notes for plone.app.discussion.
|
|
||||||
|
|
||||||
Storage and traversal
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
For each content item, there is a Conversation object stored in annotations.
|
|
||||||
This can be traversed to via the ++conversation++ namespace, but also fetched
|
|
||||||
via an adapter lookup to IConversation.
|
|
||||||
|
|
||||||
The conversation stores all comments related to a content object. Each
|
|
||||||
comment has an integer id (also representable as a string, to act as an OFS
|
|
||||||
id and allow traversal). Hence, traversing to obj/++conversation++/123 retrieves
|
|
||||||
the comment with id 123.
|
|
||||||
|
|
||||||
Comments ids are assigned in order, so a comment with id N was posted before
|
|
||||||
a comment with id N + 1. However, it is not guaranteed that ids will be
|
|
||||||
incremental. Ids must be positive integers - 0 or negative numbers are not
|
|
||||||
allowed.
|
|
||||||
|
|
||||||
Threading information is stored in the conversation: we keep track of the
|
|
||||||
set of children and the parent if any comment. Top-level comments have a
|
|
||||||
parent id of 0. This information is managed by the conversation class when
|
|
||||||
comments are manipulated using a dict-like API.
|
|
||||||
|
|
||||||
Note that the __parent__/acquisition parent of an IComment is the
|
|
||||||
IConversation, and the __parent__/acquisition parent of an IConversation is
|
|
||||||
the content object.
|
|
||||||
|
|
||||||
Events
|
|
||||||
------
|
|
||||||
|
|
||||||
Manipulating the IConversation object should fire the usual IObjectAddedEvent
|
|
||||||
and IObjectRemovedEvent events. The UI may further fire IObjectCreatedEvent
|
|
||||||
and IObjectModifiedEvent for comments.
|
|
||||||
|
|
||||||
Factories
|
|
||||||
---------
|
|
||||||
|
|
||||||
Comments should always be created via the 'Discussion Item' IFactory utility.
|
|
||||||
Conversations should always be obtained via the IConversation adapter (even
|
|
||||||
the ++conversation++ namespace should use this). This makes it possible to
|
|
||||||
replace conversations and comments transparently.
|
|
||||||
|
|
||||||
The Comment class
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The inheritance tree for DiscussionItem is shown below. Classes we want to
|
|
||||||
mix in and interface we want to implement in the Comment class are marked
|
|
||||||
with [x].
|
|
||||||
|
|
||||||
[ ] DiscussionItem
|
|
||||||
[ ] Document
|
|
||||||
[ ] PortalContent = [ ] IContentish
|
|
||||||
[ ] DynamicType = [ ] IDynamicType
|
|
||||||
[ ] CMFCatalogAware = [ ] <no interface>
|
|
||||||
[ ] SimpleItem = [ ] ISimpleItem
|
|
||||||
[ ] Item [ ]
|
|
||||||
[?] Base = [ ] <no interface>
|
|
||||||
[ ] Resource = [ ] <no interface>
|
|
||||||
[ ] CopySource = [ ] ICopySource
|
|
||||||
[ ] Tabs = [ ] <no interface>
|
|
||||||
[x] Traversable = [ ] ITraversable
|
|
||||||
[ ] Element = [ ] <no interface>
|
|
||||||
[x] Owned = [ ] IOwned
|
|
||||||
[ ] UndoSupport = [ ] IUndoSupport
|
|
||||||
[ ] Persistent [ ]
|
|
||||||
[ ] Implicit [ ]
|
|
||||||
[x] RoleManager = [ ] IRoleManager
|
|
||||||
[ ] RoleManager = [ ] IPermissionMappingSupport
|
|
||||||
[ ] DefaultDublinCoreImpl = [ ] IDublinCore
|
|
||||||
[ ] ICatalogableDublinCore
|
|
||||||
[ ] IMutableDublinCore
|
|
||||||
[ ] PropertyManager = [ ] IPropertyManager
|
|
||||||
|
|
||||||
Thus, we want:
|
|
||||||
|
|
||||||
* Traversable, to get absolute_url() and friends
|
|
||||||
- this requires a good acquisition chain at all times
|
|
||||||
* Acquisition.Explicit, to support acquisition
|
|
||||||
- we do not want implicit acquisition
|
|
||||||
* Owned, to be able to track ownership
|
|
||||||
* RoleManager, to support permissions and local roles
|
|
||||||
|
|
||||||
We also want to use a number of custom indexers for most of the standard
|
|
||||||
metadata such as creator, effective date etc.
|
|
||||||
|
|
||||||
Finally, we'll need event handlers to perform the actual indexing.
|
|
||||||
|
|
||||||
Discussion settings
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Discussion can be enabled per-type and per-instance, via values in the FTI
|
|
||||||
(allow_discussion) and on the object. These will remain unchanged. The
|
|
||||||
IConversation object's 'enabled' property should consult these.
|
|
||||||
|
|
||||||
Global settings should be managed using plone.registry. A control panel
|
|
||||||
can be generated from this as well, using the helper class in
|
|
||||||
plone.app.registry.
|
|
||||||
|
|
||||||
Note that some settings, notably those to do with permissions and workflow,
|
|
||||||
will need to be wired up as custom form fields with custom data mangers
|
|
||||||
or similar.
|
|
||||||
|
|
||||||
Workflow and permissions
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
Where possible, we should use existing permissions:
|
|
||||||
|
|
||||||
* View
|
|
||||||
* Reply to Item
|
|
||||||
* Modify Portal Content
|
|
||||||
* Request Review
|
|
||||||
|
|
||||||
In addition, we'll need a 'Moderator' role and a moderation permission,
|
|
||||||
|
|
||||||
* Moderate comment
|
|
||||||
* Bypass moderation
|
|
||||||
|
|
||||||
To control whether Anonymous can post comments, we manage the 'Reply to Item'
|
|
||||||
permission. To control whether moderation is required for various roles, we
|
|
||||||
could manage the 'Bypass moderation' permission.
|
|
||||||
|
|
||||||
These could work in a workflow like this:
|
|
||||||
|
|
||||||
* --> [posted] -- {publish} --> [published]--> *
|
|
||||||
| ^
|
|
||||||
| |
|
|
||||||
+----- {auto-publish} -----+
|
|
||||||
| |
|
|
||||||
+----- {auto-moderate} ----+
|
|
||||||
|
|
||||||
The 'posted' state is the initial state. 'published' is the state where the
|
|
||||||
comment is visible to non-reviewers.
|
|
||||||
|
|
||||||
The 'publish' transition would be protected by the 'Moderate comment'
|
|
||||||
permission. We could have states and transition for 'rejected', etc, but it
|
|
||||||
is probably just as good to delete comments that are rejected.
|
|
||||||
|
|
||||||
The 'auto-publish' transition would be an automatic transition protected by
|
|
||||||
the 'Bypass moderation' permission.
|
|
||||||
|
|
||||||
The 'auto-moderate' transition would be another automatic transition protected
|
|
||||||
by an expression (e.g. calling a view) that returns True if the user is on
|
|
||||||
an auto-moderation 'white-list', e.g. by email address or username.
|
|
||||||
|
|
||||||
Forms and UI
|
|
||||||
------------
|
|
||||||
|
|
||||||
The basic commenting display/reply form is placed in a viewlet.
|
|
||||||
|
|
||||||
The reply form is dynamically created right under the comment when the user hits
|
|
||||||
the reply button. To do so, we copy the standard comment form with a jQuery
|
|
||||||
function. This function sets the form's hidden in_reply_to field to the id of
|
|
||||||
the comment the user wants to reply to. This also makes is possible to use
|
|
||||||
z3c.form validation for the reply forms, because we can uniquely identify the
|
|
||||||
a reply form request and return the reply form with validation errors.
|
|
||||||
|
|
||||||
Since we rely on JavaScript for the reply form creation, the reply button is
|
|
||||||
removed for nonJavaScript enabled browsers.
|
|
||||||
|
|
||||||
The comment form uses z3c.form and plone.z3cform's ExtensibleForm support. This
|
|
||||||
makes it possible to plug in additional fields declaratively, e.g. to include
|
|
||||||
SPAM protection.
|
|
@ -1,59 +0,0 @@
|
|||||||
=============================================
|
|
||||||
plone.app.discussion architectural principles
|
|
||||||
=============================================
|
|
||||||
|
|
||||||
This document outlines architectural principles used in the design of
|
|
||||||
plone.app.discussion.
|
|
||||||
|
|
||||||
Discussion items have a portal_type
|
|
||||||
This makes it easier to search for them and manage them using existing
|
|
||||||
CMF and Plone UI constructs.
|
|
||||||
|
|
||||||
Discussion items are cataloged
|
|
||||||
It should be possible to search for discussion items like any other
|
|
||||||
type of content.
|
|
||||||
|
|
||||||
Discussion items are subject to workflow and permission
|
|
||||||
Moderation, anonymous commenting, and auto approve/reject should be
|
|
||||||
handled using workflow states, automatic and manual transitions, and
|
|
||||||
permissions.
|
|
||||||
|
|
||||||
Discussion items are light weight objects
|
|
||||||
All discussion item objects should be as light weight as possible.
|
|
||||||
Ideally, a discussion item should be as lightweight as a catalog brain.
|
|
||||||
This may mean that we forego convenience base classes and re-implement
|
|
||||||
certain interfaces. Comments should not provide the full set of dublin
|
|
||||||
core metadata, though custom indexers can be used to provide values for
|
|
||||||
standard catalog indexes.
|
|
||||||
|
|
||||||
Optimise for retrival speed
|
|
||||||
HTML filtering and other processing should happen on save, not on render,
|
|
||||||
to make rendering quick.
|
|
||||||
|
|
||||||
Settings are stored using plone.registry
|
|
||||||
Any global setting should be stored in plone.registry records
|
|
||||||
|
|
||||||
Forms are constructed using extensible z3c.form forms
|
|
||||||
This allows plugins (such as spam protection algorithms) to provide
|
|
||||||
additional validation
|
|
||||||
|
|
||||||
Discussion items are stored in a BTree container
|
|
||||||
This allows faster lookup and manipulation
|
|
||||||
|
|
||||||
Discussion items are accessed using a dict-like interface
|
|
||||||
This makes iteration and manipulation more natural. Even if comments are
|
|
||||||
not stored threaded, the dict interface should act as if they are, i.e.
|
|
||||||
calling items() on a comment should return the replies to that comment
|
|
||||||
(in order).
|
|
||||||
|
|
||||||
Discussion items are retrieved in reverse creation date order
|
|
||||||
Discussion items do not need to support explicit ordering. They should
|
|
||||||
always be retrieved in reverse creation date order (most recent for).
|
|
||||||
They can be stored with keys so that this is always true.
|
|
||||||
|
|
||||||
Discussion items do not need readable ids
|
|
||||||
Ids can be based on the creation date.
|
|
||||||
|
|
||||||
Discussion items send events
|
|
||||||
The usual zope.lifecycleevent and zope.container events should be
|
|
||||||
fired when discussion items are added, removed, or modified.
|
|
59
plone/app/discussion/architecture.txt
Normal file
59
plone/app/discussion/architecture.txt
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
========================
|
||||||
|
Architectural Principles
|
||||||
|
========================
|
||||||
|
|
||||||
|
This document outlines architectural principles used in the design of
|
||||||
|
plone.app.discussion.
|
||||||
|
|
||||||
|
**Discussion items have a portal_type**
|
||||||
|
This makes it easier to search for them and manage them using existing
|
||||||
|
CMF and Plone UI constructs.
|
||||||
|
|
||||||
|
**Discussion items are cataloged**
|
||||||
|
It is possible to search for discussion items like any other type of
|
||||||
|
content.
|
||||||
|
|
||||||
|
**Discussion items are subject to workflow and permission**
|
||||||
|
Moderation, anonymous commenting, and auto approve/reject should be
|
||||||
|
handled using workflow states, automatic and manual transitions, and
|
||||||
|
permissions.
|
||||||
|
|
||||||
|
**Discussion items are light weight objects**
|
||||||
|
Discussion item objects are as light weight as possible. Ideally, a
|
||||||
|
discussion item should be as lightweight as a catalog brain. This may mean
|
||||||
|
that we forego convenience base classes and re-implement certain interfaces.
|
||||||
|
Comments should not provide the full set of dublin core metadata, though
|
||||||
|
custom indexers can be used to provide values for standard catalog indexes.
|
||||||
|
|
||||||
|
**Optimise for retrival speed**
|
||||||
|
HTML filtering and other processing should happen on save, not on render,
|
||||||
|
to make rendering quick.
|
||||||
|
|
||||||
|
**Settings are stored using plone.registry**
|
||||||
|
Any global setting should be stored in plone.registry records.
|
||||||
|
|
||||||
|
**Forms are constructed using extensible z3c.form forms**
|
||||||
|
This allows plugins (such as spam protection algorithms) to provide
|
||||||
|
additional validation. It also allows integrators to write add-ons that add
|
||||||
|
new fields to the comment form.
|
||||||
|
|
||||||
|
**Discussion items are stored in a BTree container**
|
||||||
|
This allows faster lookup and manipulation.
|
||||||
|
|
||||||
|
**Discussion items are accessed using a dict-like interface**
|
||||||
|
This makes iteration and manipulation more natural. Even if comments are
|
||||||
|
not stored threaded, the dict interface should act as if they are, i.e.
|
||||||
|
calling items() on a comment should return the replies to that comment
|
||||||
|
(in order).
|
||||||
|
|
||||||
|
**Discussion items are retrieved in reverse creation date order**
|
||||||
|
Discussion items do not need to support explicit ordering. They should
|
||||||
|
always be retrieved in reverse creation date order (most recent for).
|
||||||
|
They can be stored with keys so that this is always true.
|
||||||
|
|
||||||
|
**Discussion items do not need readable ids**
|
||||||
|
Ids can be based on the creation date.
|
||||||
|
|
||||||
|
**Discussion items send events**
|
||||||
|
The usual zope.lifecycleevent and zope.container events are fired when
|
||||||
|
discussion items are added, removed, or modified.
|
@ -1,5 +1,5 @@
|
|||||||
Captcha Design Notes
|
Captcha Plugin Architecture
|
||||||
====================
|
===========================
|
||||||
|
|
||||||
This document contains design notes for the plone.app.discussion Captcha plugin
|
This document contains design notes for the plone.app.discussion Captcha plugin
|
||||||
architecture.
|
architecture.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
=================================
|
============
|
||||||
plone.app.discussion design notes
|
Design Notes
|
||||||
=================================
|
============
|
||||||
|
|
||||||
This document contains design notes for plone.app.discussion.
|
This document contains design notes for plone.app.discussion.
|
||||||
|
|
||||||
@ -8,12 +8,12 @@ Storage and traversal
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
For each content item, there is a Conversation object stored in annotations.
|
For each content item, there is a Conversation object stored in annotations.
|
||||||
This can be traversed to via the ++comments++ namespace, but also fetched
|
This can be traversed to via the ++conversation++ namespace, but also fetched
|
||||||
via an adapter lookup to IConversation.
|
via an adapter lookup to IConversation.
|
||||||
|
|
||||||
The conversation stores all comments related to a content object. Each
|
The conversation stores all comments related to a content object. Each
|
||||||
comment has an integer id (also representable as a string, to act as an OFS
|
comment has an integer id (also representable as a string, to act as an OFS
|
||||||
id and allow traversal). Hence, traversing to obj/++comments++/123 retrieves
|
id and allow traversal). Hence, traversing to obj/++conversation++/123 retrieves
|
||||||
the comment with id 123.
|
the comment with id 123.
|
||||||
|
|
||||||
Comments ids are assigned in order, so a comment with id N was posted before
|
Comments ids are assigned in order, so a comment with id N was posted before
|
||||||
@ -42,8 +42,8 @@ Factories
|
|||||||
|
|
||||||
Comments should always be created via the 'Discussion Item' IFactory utility.
|
Comments should always be created via the 'Discussion Item' IFactory utility.
|
||||||
Conversations should always be obtained via the IConversation adapter (even
|
Conversations should always be obtained via the IConversation adapter (even
|
||||||
the ++comments++ namespace should use this). This makes it possible to replace
|
the ++conversation++ namespace should use this). This makes it possible to
|
||||||
conversations and comments transparently.
|
replace conversations and comments transparently.
|
||||||
|
|
||||||
The Comment class
|
The Comment class
|
||||||
-----------------
|
-----------------
|
||||||
@ -150,20 +150,18 @@ an auto-moderation 'white-list', e.g. by email address or username.
|
|||||||
Forms and UI
|
Forms and UI
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The basic commenting display/reply form should be placed in a viewlet.
|
The basic commenting display/reply form is placed in a viewlet.
|
||||||
|
|
||||||
Ideally, the reply form should be inline, perhaps revealed with JavaScript
|
The reply form is dynamically created right under the comment when the user hits
|
||||||
if enabled. This allows full contextualisation of replies. The current
|
the reply button. To do so, we copy the standard comment form with a jQuery
|
||||||
solution, with a separate form that shows some context, is brittle and
|
function. This function sets the form's hidden in_reply_to field to the id of
|
||||||
over-complicated.
|
the comment the user wants to reply to. This also makes is possible to use
|
||||||
|
z3c.form validation for the reply forms, because we can uniquely identify the
|
||||||
|
a reply form request and return the reply form with validation errors.
|
||||||
|
|
||||||
If we support quoting of comments in replies, we can load the text to quote
|
Since we rely on JavaScript for the reply form creation, the reply button is
|
||||||
using JavaScript as well.
|
removed for nonJavaScript enabled browsers.
|
||||||
|
|
||||||
As a fall-back for non-JavaScript enabled browsers, it is probably OK not to
|
The comment form uses z3c.form and plone.z3cform's ExtensibleForm support. This
|
||||||
support quoting and/or viewing of context, e.g. the user is taken to a standalone
|
makes it possible to plug in additional fields declaratively, e.g. to include
|
||||||
'comment reply' form.
|
SPAM protection.
|
||||||
|
|
||||||
All actual forms should be handled using z3c.form and plone.z3cform's
|
|
||||||
ExtensibleForm support. This makes it possible to plug in additional fields
|
|
||||||
declaratively, e.g. to include spam protection.
|
|
Loading…
Reference in New Issue
Block a user