-
Notifications
You must be signed in to change notification settings - Fork 5
Home
Welcome to the plonesocial.suite wiki!
This document tries to provide a consistent roadmap for further development of the plonesocial.* suite of functionalities, based on the following principles:
- Native Plone implementation
- Full social networking experience
- Pre-integrated one-click install
- Flexible, customizable, loosely-coupled component packages
- Scale down to small installations (deployment + UX)
- Scale up to large installations (performance/deployment + UX)
The goal is to provide enhancements in such a way, that PloneSocial can be easily integrated into existing Plone projects like 4teamwork teamspace, and G24.AT.
The following lists a number of enhancement proposals, grouped by functionality type. These enhancements will be broken down into specific tasks per plonesocial component that will be tracked as issues on the respective github repositories.
-
Have not only content creation, but also content modifications in the activity stream.
There's two possible approaches to do this:
- Implement as a catalog extension (aka collective.lastmodifier) that allows query on Modified (instead of Created) and displays Modifier (instead of Creator). Drawbacks: requires extra ZCatalog "Modifier" index (else we cannot filter on "following"), will give duplicates because container objects get modified on child object modifications (Folders, plone.app.discussion context), will only show last modification.
- Log changes as status updates in the microblog tool. Drawback: some content duplication. Advantages: no ZCatalog change needed, ability to display multiple modifications on same context object, ability to filter out duplicates caused by modification events bubbling up (but: how /exactly/ to eliminate duplicates?).
- Index and query content modifications by object type. Easy in case we have ZCatalog based change log. Requires extra index on microblog in case of microblog based change log.
- (Weekly) activity summaries. Can best be done with ZCatalog.
Conclusion: if we can deduplicate changes in the ZCatalog based approach, that would probably be the best solution. It fits normal ZCatalog usage and does not overload the microblog tool with extra indexes. The microblog should not become a second ZCatalog.
Solution: both of the below:
- PLIP "Modifier" (userid) index for inclusion in plone core. AKA collective.lastmodifier. If not PLIPed, use collective.lastmodifier. [Thomas]
- In plonesocial, add a DateIndex "edited" which is like "modified" but only gets updated on real edits of the object, not on ContainerModifiedEvents triggered by child object addition. Given a document that was really edited 10 minutes ago, when adding a plone.app.discussion event to that document, then the "edited" index should return not "now" but "10 minutes ago". Implementation can use the pattern outlined in this thread: event listener marks creation event path on request, second event listener on modified checks this flag. [Thomas]
-
Have an expanded status update view that also provides change information, adapterized per source object type. [Guido] top priority
This should balance the goal of not having to click through to another page to obtain detailed information, with the goal of having a simple, uncluttered activity stream view. The Twitter pattern is attractive here: provide an onclick inline expansion of an activity update that pulls in extra information and provides extra actions on the context.
Implementation notes: currently the stream is adapterized on IStatusUpdate and IBrain. We do a getObject() on any brain anyway, so can replace this with an adapter call against the actual context object. The current implementation can be provided as a default fallthrough adapter, making it possible to provide more fine-grained adapters for specific content types.
Any rendering should be two-phased, with an outer IActivity renderer that can have a shared template across all activity updates, providing hooks for more specific per-type customization on a per-field basis. Specifically the activity_provider can call a body_provider to pull in the expanded update information.
-
Links with embed.ly page previews in status updates.
To ensure security for confidential information when deployed in an intranet setting, any such functionality should provide some blacklist that blocks internal urls from being previewed through a cloud service.
-
Make activity streams context (path) sensitive, so you can provide per-workspace isolated activity streams. [Guido]
There's multiple design solutions to do this, and they should be carefully evaluated for performance and extensability impact. Any solution should be resilient against copy/move/rename of context objects. Probably a combination of UUID reference + path index + event listeners that update the path index when the context is copied/moved/renamed.
-
Store the context (UUID or path) on the IStatusUpdate.
This is probably a good solution for the richer content following/model functionality. But it is not a good solution for activity stream queries, since that would require inefficient per-statusupdate indexing of context paths.
-
Provide multiple microblog containers as annotations on context objects.
The sitewide utility should be aware of such containers scattered throughout the site, so that the sitewide activitystream merges all of the status updates everywhare. Can be done with event listening, and keeping a mapping of the statuscontainers on the siteroot container.
-
Provide path-aware storage on the sitewide microblog container.
Store the per-context statuscontainers not on the context object, but in a structure on the sitewide microblog utility.
Conclusion: use (3)
-
-
Follow content objects in addition to follow people.
Has to be resilient against object rename/move/copy, so either some kind of UUID index or else a path index that gets updated on change events.
-
Follow tags.
This can be implemented as an extra following index, with a TreeSet.union() operation for rendering.
-
Follow groups.
This can easily be implemented by adding/removing all userids in a group to the social graph in one action. More thought is required for the design implications however. What is a group, where does it reside from a UX perspective? What is the relationship between a group of users, and a team workspace?
-
Have content 'likes' and provide some view of top liked updates, aka trending topics.
UI should clearly distinguish between liking (star) and following (on/off) content actions. Needs the same path reindexing facilities as follow content for renames and such.
-
Replies and conversation context on updates.
Since plone.app.discussion already provides this, we should look if we can port the mechanisms provided there and apply those to microblog status updates.
-
Provide community discussion and conversation/threading support. AKA G24.AT integration.
We should avoid growing status updates into full-blown content types. That doesn't scale performance wise. The question then is, given that we will set up status updates with a richer context/display model + reply/conversation (see above), what is the optimal way to provide two-way integration with a G24.AT type of content steam. Also taking into consideration the planned following/favoriting features for plonesocial. Is the G24.at dexterity instance behaviour pattern as an alternative to adapterization relevant the context of activity streams?
Conclusion: use G24.AT as a blogging engine in content. Expose the G24.AT stuff in the plonesocial activitystream. Provide "extended_info" (expansion rendering) and "reply" hooks as content providers that can be adapterized and filled in from the G24.AT side to customize plonesocial.activitystream at will. Once that works, AJAXify that stuff and make it slick. Plonesocial side: [Guido]. G24.AT side: [Johannes].
-
Two-way email integration.
Do that in the G24.AT integration, outside of plonesocial.
- Index and link @mentions.
- Provide fulltext search. Maybe the souper.plone stuff is useful for that.
- Mute/unmute following by type, by conversation, by tag, by person, by group. I.e. temporary blacklist filtering rulesets that can be reconfigured and switched on/off at will.