Over the past few months, we have been thoroughly improving the codebase of the Duplicate, Synchronize and Theme Install actions. This update has been live since October 2. Actually, this description is a bit too short, because at the root of the refactoring is a complete overhaul of how we handle data in Plate. I warn you in advance, this is a technical article.
I'm proud to show you the result of the energy we put into a process where we figured out a model to account for the data integrity of Plate content: PlateON.
PlateON: Plate Object Notation
The new model is based on the idea that Plate data are not stand-alone entities, but always part of one or more webs of data and relationships. For example, when you talk about a section, you are also talking about all the rows, columns, elements and related things that go with it. To put these webs into a structured format, we looked at other structured data formats like JSON. Hence, we call our own data structures PlateON (Plate Object Notation), with an engine for writing and exchanging data.
In practice, it works as follows.
Suppose you want to perform an action on Plate data, let's say duplicate a post. Then a number of steps are taken:
The PlateON of the post is generated. That is, all the relationships and underlying components (sections, rows, but also which post type, etc.) are collected, and put into the PlateON, creating a clear data structure of the post, and everything that belongs to that post in any way.
Then a mapping is generated based on the action you are performing. Because you're duplicating, the vast majority of the Plate data is mapped to "new", which means to create a new object from it. The post type does not change, so it is mapped to itself. However, it can also be mapped to another post type, which means that you are not only duplicating a post, but also moving the duplicate to another post type. Since you can map everything in PlateON to equivalents or "new", you can theoretically create infinite combinations of possible duplicate/move actions. The challenge is of course to keep the new relationships correct. But because we already have an existing web of data and relationships, plus a mapping, we can always perform these validations. Although this can be a very complex operation, because of all the different possible relationships and data layers, we can still generate a reliable outcome this way.
With the combination PlateON/mapping, a PlateON import service is called, which reads the PlateON and the mapping both, and with this data writes out all the data (creating new records, or modifying records, depending on the mapping).
This seemingly simple but powerful piece of software is the basis of all the aforementioned actions performed within Plate. Not much changes to the interface, but underwater the maps are completely different.
The biggest difference from how it worked before is that we no longer view the data with all its relationships and connections as separate entities on which we perform an action one by one. Instead, we treat a bundle of Plate data on its own as an entity, and perform the action on the whole bundle at once. In this way, we can do a much better job of ensuring that data integrity remains intact, even when complex moves or duplications with disparate references must be performed.