Revisions support

Number of revisions should probably be in config.

Config

Only if the setting exist and is set to a number larger than 0 it should add revisions, I think.

c::set('revisions', 2);

Naming of file

_revision-{timestamp}-{name}.txt
  • Underscore for marking that it should be hidden in the panel.
  • “revision” to tell us what it is.
  • “timestamp” instead of ID tell us when it was created and makes it unique.
  • “name” tell us what template it is assigned to, just like the original txt file.

Feedback?

something like this? Versioning for the Panel

As I mentioned in the thread @Jan cited, IMHO revisioning only makes sense if the versions are accessible/comparabe via the panel, at least for all editors who only have access to the panel and not necessarily to the file system.

I have missed that thread.

Directory

I agree that it probably would be nicer to have a folder with the revisions / versions than having the files directly into the page folder.

Template name

In your post you don’t have a template name in your filename. What if they change name / template and then go back to a revision / version? I think it will need a name in the filename for it to work?

@texnixe

Totally agree.

Now I would need this feature. I got an idea for a plugin.

This could still be an option:

c::set('revisions', 2);

On save a hook is triggered, which over time creates this:

/revisions/parent/child/grandchild/2016-04-09_08-02-11/about.en.txt
/revisions/parent/child/grandchild/2016-04-10_10-04-21/about.en.txt
/revisions/parent/child/grandchild/2016-04-11_11-03-31/default.sv.txt

Maybe it reminds of the thumbs or the cache folder and yes it would be.

Additional hooks would be for deleting, renaming and changing template. That to always keep in sync.

Benefits:

  • The revisions is not a part of the content folder, which means it does not slow down your site.
  • By limit to like 2 or 10 revisions the site will not grow forever.
  • Because the folder structure is the same as in content, it’s easy to see what it is even for the human eye.
  • The dates are a human friendly kind of timestamp.
  • Multi language support.

Field

To really make this useful a field would be required to show the revisions for the current page in the panel. Clicking on a revision could bring it back, after asking the user first.

Only text

My idea is that only the text is used for revisioning. That’s the only thing you edit in the panel. Even if there are images, they are not edited in any way. It also would be much faster to just save a text file than save a whole folder complete with images.

Do you want a plugin like this? Should I build it, or some kind of collaboration? @1n3JgKl9pQ6cUMrW?

I think this goes far beyond my skills :slight_smile:

I am good in creating creative, easy solution plug-ins, like the content-backup plug-in - but altering the core of such a complex system as Kirby is, is not my cup of tea :stuck_out_tongue:

I think your backup plugin is quite advanced.

I’m not thinking to altering the core.

I was thinking hooks:

https://getkirby.com/docs/panel/developers/hooks

kirby()->hook('panel.page.update', function($page) {
  // Copy text file to /revisions/some/folder/filename.txt
});

That would be a really good feature to have. I might be able to help test and perhaps write bits of it.

You probably would need to move versions on the panel.page.move hook, because otherwise if the editor decides to rename a page’s slug… the revisions would be lost. But it might get a bit tricky.

Bastian has written previously that he had thought about versioning a few times, but it would add a lot of complexity so he’s not keen on going along with it. Writing a plugin as a proof of concept would be interesting, at the very least.

2 Likes

I think a plugin would be great. Integrating this into the core would increase complexity by a lot, but a separate plugin can’t be wrong here, so I think experimenting with this in a plugin would be cool. :slight_smile:
I’m curious what you can make.

1 Like

My guess is that moving pages could be the most critical thing in with a plugin like this, because we need to move the revisions as well. We don’t want to risk losing the data at that point.

I have some other things I need to do before I can start with it. If you want to start something right now, feel free to do so and I’ll jump into it later.

@lukasbestle It would probably be helpful if you would drop some pitfalls. You are smart and have probably calculated them already?

Your idea looks great and very doable.

One idea though: Maybe it makes sense to listen for file hooks as well. And then on every hook besides the page move hook, you just copy the whole directory (excluding subdirectories) of the page to the revisions directory so that files are backed up and versioned as well.

Also one potential issue we need to think about: What about subpages? Subpages are stored in their parent’s revision directory, so what should happen if the parent page is changed? The subpages definitely need to be preserved somehow.

All files in a folder

It would probably be simple to just copy the whole directory but if I have 30 images on a page, it needs to copy those 30 images on every save.

  • It could grow fast if every image in that page is 3MB (90MB every save).
  • It would slow down the panel.

About subpages

I’m not sure if there is a relationship between them. I don’t think a page can be moved in the panel. I don’t think it matters if a folder has a subfolder?

Every page has a uri and to think flat, don’t mind what’s parent or children.

To protect against collisions the structure could be like this:

/revisions/parent/child/revision/2016-04-11_11-03-31/default.sv.txt
/revisions/parent/child/revision/2016-04-12_11-03-31/default.sv.txt
/revisions/parent/child/grandchild/revision/2016-04-11_11-03-31/default.sv.txt

revision folder before the revision is a name protection against collisions. Else the date could theoreticly collide with a subpage.

Delete

I’m not sure what should happend on delete. Maybe the user by mistake deleted a page. Maybe not delete the revisions on delete?

If your page has a 50 MB video file, and you copy it for each text revision up to limit=20 revisions, you get 1GB of duplicate files.

I’d restrict the scope to the text part. That’s a limitation, sure, but it helps keeping things manageable.

1 Like

What is making the versioning of files an option which is turned off by default? This way, people who really need it could turn it on if they really want to…

Theoretically, you could have a subpage/child called ‘revision’, than the model would break… maybe just add an underscore before the date? This usually isn’t possible in the panel and should be safe to use. Every other key word could be used by a child otherwise and break the whole thing.

Another interesting point is definitely the user interface. Will you be able to restore single fields as well as the whole page? Or just “klick-and-restore-last-revision”? This change should also be undoable, so you also always need to store the current version as revision… and, a problem I have seen lately, was that hooks currently can’t access old data, so you’d need some kind of compare-fields. Lot’s of things to be aware of… here is @texnixe’s approach which I used (and which works like charm ;)): Listen to certain page changes in hooks

Great idea by the way, would love to test this out :wink:

Or maybe it could be .revisions, since there can be no page with a leading dot at all. Then the subpage issue is solved.

1 Like

I’m not sure about the option, not for a first version at least. It would take more time to develop and I want a first version out quite soon.

If @lukasbestle suggestion with a dot work I think that would be great.

I was thinking just a list of the 10 last revisions and go back to a restore point. But also compare them to the current.

I will try to be extra careful with old data then. Thanks!

1 Like

I agree, for a first version, I would leave files out. Would be interesting to test performance though with heavy file loads.

1 Like

I really like the revision feature with comparison/diff at Draft:

1 Like

Name

Name for it?

/revisions/some-page/.revision/2016-01-01_09-07-12/
/versions/some-page/.version/2016-01-01_09-07-12/
/history/some-page/.history/2016-01-01_09-07-12/
/backup/some-page/.backup/2016-01-01_09-07-12/
/points/some-page/.point/2016-01-01_09-07-12/

Workload

I’ve been thinking of how I would do this and came to some conclusions.

  • I will create the most basic revisison plugin possible with the aim to make it solid and well working with not anything extra than what is needed.
  • I hope that someone else than me want to build a field for it. That would be a great collaboration, I think.

Field

A simple field would be just a list of the recent savings and the possibility to restore to one of them.

Diff

This will not be of high priority, but it would be nice to have. I also think that some diff tool class would be needed. I guess it’s hard to create a diff tool from nothing.

Diff is not mandatory, but I thought sometimes we may want to revert a single field, not the whole page. Being able to display a previous version and simply copy/paste the content of a field could be useful.

1 Like