Auto save of draft content
I'm not sure of how difficult this would be technically but I do know it would benefit the user experience quite a bit. I would imagine we wouldn't be able to get rid of the save completely but it could be demoted if items are being saved for you the majority of the time.
The interface is a little action heavy so this could be a huge step.
Regarding #2; this sounds like an interesting approach. I see one minor issue with it; user's swapping machines between edits. However, if that were signalled as such in the UI when user's logged-in on a different machine than was used to create the content, then this issue could be mitigated against.
The "signal" could be based on a localStorage-cached browser-fingerprint, which was stored as a separate key=>value pair, alongside each draft-page entry.
Regardless of storage location, and even though localStorage has a ~10Mb limit AFAIK, it would be wise to obfuscate the data, to minimise its storage footprint. A basic 2-way hash could serve well or, considering edge-cases such as embargoed content drafting on public computers, the use of cryptographically signed one-way hash would reduce the size further, while also being secure.
The latter may be overcomplicating things, but due consideration of multi-user machines in a content-editing context should be factored in.
AdminIngo Schommer (Admin, SilverStripe) commented
It seems like there's two ideas here:
1. Auto-save content so it can be recovered (Patrick's version?). I'd rather keep this out of the server altogether, and rely on localstorage in the browser. It should survive most browser crashes, and scales a lot better (less calls to the server, no additional database storage).
2. Auto-save content to reduce manual user saving actions (Paul's version?). That would require server calls and additional database storage. We're definitely not adding a fourth table to each versioned record, it's already getting out of hand in terms of table count. So we'd have to figure out how to make this work in _Versions, e.g. through a separate "auto-save" flag which is separate from the remaining versions collection for a record.
I'd much rather implement #1 than #2, since it's simpler - particularly once we've rolled out React and Form Schema in all SS4 UIs, at which point it's easy to restore a view from localStorage state.
Patrick Nelson commented
This is a good idea, so I'll build on it.
Note that this could also possibly cause issues with validation (since validation still occurs on draft save, as it should). This means that an auto-save would have to be it's own separate action that would need to be able to suppress validation when executing.
Personally I'm not too worried about auto-save creating too many versions. In fact, you should probably just ensure that an auto-save (now it's own action) doesn't create multiple separate versions, but just maintains one separate record, separate from draft, _Versions and separate from _Live. I also think that another reason why auto-saved content is best kept separate from from draft is because if it's stored in the main table (the draft table) then it should be validated.
Auto-saved content is "cutting edge", it's not validated nor is it intended to be, it's only a backup in case of failure. The next step is figuring out:
- How to handle presenting auto-saved content to user (in case we think we are now in recovery).
- How to handle when user leaves page *intentionally* without saving.
Both could likely be handled in UI/UX by presenting a small but easily visible yellow banner at the top indicating that an auto-saved version which is newer than the draft version is available and can be recovered by clicking a button. If you save your current draft or continue editing the current draft, after enough changes to that current draft, the auto-saved version could be overwritten (intentionally) with the current auto-saved version.
Paul Clarke commented
I also think its overdose to create a version for every autosave so I would think a new version would be from a certain period of time eg 1-2 min and autosave would be a shorter timeframe. Perhaps if the user manually clicked save or navigated away we make that a version within its history.
The implementation would be similar to the current save as draft, system except it would be automated. Automation could be achieved using a specialised BuildTask, or perhaps better via the silverstripe-crontask module. Both would require that an appropriate crontask were setup on the CMS host.
The trigger for auto-saving would need to be invoked via client-side AJAX requests, or perhaps better, via an npm daemon using websockets. Going down the latter route means this feature being fairly specific and probably better suited to a module....hmmm there's a challenge.
I think the main issue would be versions. Each time a new Save operation is made, a new entry is always added to the SiteTree_versions table which then appears under the CMS' "History" tab. I could imagine this getting really big, really quickly.
Paul Clarke commented
No where as yet, it has been mentioned a few times but no traction. I'd love to get an idea how big of a task this would be.
Paul, did you get anywhere with this? I'd be happy to vote for this, perhaps making it an opt-in feature via CMS Settings or YML config.