|Issue tags:||Spark Sprint 5|
DIscussion Summary (9/13)
- Pretty much everyone is on board conceptually with Create.js being a good path forward.
- Many people though are concerned about Create.js meeting the D8 feature freeze timeline, especially with all of the various dependencies of doing it the "right" way (JSON-LD, RDFa improvements, a de-coupled Entity Validation API)
- Even to the point where people are seriously advocating not doing inline editing functionality *at all* for D8. :(
- There are other unknowns as well, like ultimate file size / JS payload impact for mobile, how stable the underlying dependencies are, etc.
So. Here's the proposal: Treat Create.js-ification of Edit module as a *post-feature freeze* "enhancement" to Edit module / inline editing in core. (Assuming we can get it in by Dec 1) Reference: http://buytaert.net/updated-drupal-8-release-schedule
This would solve a few problems:
- We'd now have until April 1 to do this, rather than Dec 1, which helps alleviate timeline pressures causing people to question the do-ability of the entire inline editing functionality in core.
- This delay would allow TYPO3 / Symfony Full Stack Framework / other CMSes that Henri's working with to "alpha test" Create.js integration in advance of us using it in order to further flesh out and fix bugs/missing features (such as the ability to work on backend forms), rather than us having to take that on ourselves (we're already taking on a lot upstream collaboration work w/ the Aloha stuff as it is).
- Create.js's development will largely be done in December, so some of the unknowns around file sizes, dependencies, shifting library code, etc. would be nailed down at that point.
- The feature set of Drupal 8 will also be largely done in December, so we'll know the state of underlying Drupal 8 dependencies like RDFa, JSON-LD, entity validation API, etc.
Unless we hear dire cries about this plan, this is what we (the Spark team) plan to move forward with. I'll update the issue summary with this plan in a moment, and aim to close out this issue by next Friday, if not sooner so we can move forward on completing our feature enhancements for Edit module and get it on the road to D8.
Note that this should not stop anyone from working on necessary/"very" nice to have CreateJS Drupal plumbing in the meantime! A quick hit-list of at least some of those issues would be:
- #1606794: Implement new routing system
- #1778226: [META] Fix RDF module
- #1696648: [META] Untie entity validation from form validation
- #1533366: Simplify and optimize Drupal.ajax() instantiation and implementation
- #1149866: Add Backbone.js and Underscore.js to core
- The ability for CreateJS to work on back-end forms (see comment #36)
Thanks all, for the really productive discussion here!
Create.js would allow for much cleaner code and less code to maintain. There are Drupal-specific aspects that limit the extent to which we can leverage it though.
Overall, it looks like it's a good idea to use Create.js. But can we get all of it done before code freeze (December 1, 2012)?
Much like when we were selecting a WYSIWYG editor for Spark (#1580210: Figure out what WYSIWYG editor to use), we'd again like input on whether we should use Create.js or not. To be honest, I think the answer will be "Yes, we should use it." — many people including Larry Garfield, Stéphane Corlosquet, Nate Haug and others are in favor, varying from "at least in favor" to "very strongly in favor".
However, for the Edit module, the following in-place editing functionality still needs to be designed/implemented: validation, editing of teasers, ability to make multiple edits and only then publish the changes, accessibility testing.
Then there is also the minimal plumbing to make in-place editing in core possible, which means we need to help move some Drupal 8 core patches forward.
That will most likely mean that migrating everything to Create.js *and* getting the additional plumbing necessary for Create.js support in D8 all done before feature freeze is effectively impossible
So: if we add Create.js support, is it acceptable to do it during code freeze, i.e. after December 1, 2012?
Create.js relies on RDFa-annotated content to know what is editable and uses JSON-LD to communicate with the server. You can configure on a "per semantic type" basis which editing widget should be used. So, roughly, Create.js == Edit's plumbing plus a default UI, minus the ability to use server-generated widgets/forms to edit fields.
Because Drupal already has solid RDFa support, it makes for a seemingly natural match.
To properly leverage Create.js, Drupal needs to become more RESTful and ideally would provide JSON-LD support out-of-the-box. In Drupal 8, that will be possible, thanks to WSCCI. If Drupal 8 doesn't have JSON-LD, we'd have to reimplement Backbone.sync to use a different transport layer.
Create.js depends on VIE.js, Backbone.js and underscore.js. When a page is loaded with Create.js enabled, the page will be searched for RDFa annotations, populate that into Backbone.js Models and Collections and then BackBone Views will be created for the original RDFa-annotated parts of the DOM. This way, the DOM automatically stays in sync when the data changes, whether that happens because of the user editing, or through server communications (e.g. collaborative editing over WebSockets).
Create.js consists of "widgets", which each have a different responsibility and most of which are optional. The following widgets are relevant to Edit:
- Editable: the actual editing functionality/abstraction
- Storage: localStorage save/restore capability, keeps track of what should be saved to the back-end
- Workflows: retrieves workflows from the back-end and handles running them: can be simple publish/unpublish, or more complex
- Notifications: when something has been saved, if you have local modifications (i.e. stored in localStorage but not saved to the server)
Typo3 has already adopted Create.js. As has Symfony CMF.
How Create.js and Edit would interact
See ethanw's excellent write-up of case studies for use of JSON-LD, case 2.
- Much cleaner code.
- Ability to switch from one WYSIWYG editor to another without having to make server-side adjustments.
- We automatically get functionality such as localStorage and notifications. Although the notifications would then not be routed through Drupal's theme system, unless we override the default implementation.
- A boatload of external libraries that are still (rapidly) evolving in Drupal core: Create.js, VIE.js, Backbone.js, underscore.js.
- A "soft dependency" on the RDFa module. The site owner may not want RDFa output on every page, so then the RDFa module would be disabled. But it would need to be enabled for users who have the ability to do in-place editing, because Create.js needs the semantic annotation to be there! How that would work, I'm not sure.
To further complicate things in this area, not every field has a default semantic annotation (and for good reason: a "text" field can be used in many semantic ways); this implies we'd need to generate local schemas (which is really, really simple and a non-issue), but that would imply potential dual annotations. (needs confirmation)
- Create.js is only very useful on the front-end, on the back-end it is far less so. There, it would only be useful to provide abstraction for the WYSIWYG editor, and localStorage (confirmed by Henri Bergius). Create.js' Workflows is likely less useful, because we probably want that to be hook_form_alter()able etc., like it is today.
- Create.js' funding (its development is funded by the EU) ends at the end of 2012. Henri Bergius (and his company) have commercial interests to continue its development, but there is an inherent risk there that we end up having to maintain something we didn't write.
- Create.js does not explicitly support server-generated forms, which we need to use Drupal's rich ecosystem of custom widgets for fields. Otherwise, you wouldn't be able to use the same widget for e.g. selecting taxonomy terms on the back-end and on the front-end. It is possible to do this though, through a custom Create.js Editing widget for Drupal. (For the record: this was not possible back in June, it's only possible since a few weeks.)
- The ability to "just switch" WYSIWYG editors is a euphemistic simplification of reality: this assumes alternative WYSIWYG editors are equally deeply integrated with Drupal, e.g. imagine an "image caption" filter being tightly integrated with WYSIWYG editor foo and not being integrated at all with WYSIWYG editor bar, making it impossible to interact with a certain piece of content, likely displaying that content incorrectly and potentially even corrupting/deleting it, because WYSIWYG editor bar doesn't know how to deal with it.
- In Drupal 7, the most feasible way to implement Backbone.sync, is on top of Form-based saving and AJAX-commands-based loading. This is not elegant. However, that's also how the Edit module currently does it — but it's a relatively natural fit, once Backbone.sync becomes a layer of indirection, it's less of a natural fit.
- Submitting: #1606794: Implement new routing system (i.e. an essential part of WSCCI)
- Validation: #1696648: [META] Untie entity validation from form validation is necessary because we cannot trust the data Create.js is sending, just like we cannot trust any user input
Soft blockers (if these things don't happen in D8, we won't be able to optimally/cleanly implement Create.js)
- No JSON-LD in Drupal 8 would imply that we have to reimplement Backbone.sync to use whatever format *is* available. Or continue using a hacky D7 "piggy backing on forms" implementation.
At DrupalCon Munich, I sat down with Henri Bergius and we worked on migrating Edit module to use Create.js, the result is on GitHub (diff, excluding newly added files). (He did 90% of the work, FWIW — makes sense because he wrote VIE.js and Create.js, but still, impressive! :))
The code works only partially though — I was working on implementing Backbone.sync on top of the existing Form-based saving infrastructure (see the related caveat above), but was running into issues, potentially because I was exhausted at the end of DrupalCon (but certainly also because Drupal.ajax sucks — see #1533366: Simplify and optimize Drupal.ajax() instantiation and implementation to fix that).
I'm certain that I've forgotten to mention/explain some things, so I will update the above as people start pointing them out :)