 OK, so I think we'll get started. This session is about the workflow initiative. We've got a URL there for fiddy.o. That's where the plan is. This is going to be a very much an evolving plan. We've tried to put together as much as we can how we want things to work for the next two, three years. And if anyone has any suggestions, any comments, we're going to be changing that plan as we go through. We've already started making changes to it this week, so pull that up and follow along. So I'm Tim Millwood. I've been working on this kind of stuff in Contrib for the last nine months to a year. And I'll be dedicating the next two years, almost full-time, working on this core initiative. Then we've also got Dick. I'm Dickson on d.do. I'm a long-time core and Contrib developer. I'm the author of the Deploy module for Drupal 7, which is kind of related to the topic. So I've been working in this space for many, many years. I'm also the creator and co-maintainer together with Tim and Andre and Tim with these same modules in Drupal 8. And I'm also the initiative coordinator for the new workflow initiative that we'll be talking about here. So really excited. Good to see so many of you here. I'll also give a shout out to Andre. He's sat down the front here. He's working on this core initiative full-time with us as well and been working on the Contrib modules for the last two, three years. So we're going to start off talking about the Contrib modules. And what we've been doing there, it's all based on Deploy. Dick was saying Deploy's been going from Drupal 7 back to Drupal 6, Drupal 5. So we've been working on this stuff for years, for years and years, and trying to sort of perfect the workflow. And I think with Drupal 8 we've got a very good workflow. It's all based on CouchDB. So we're not actually using CouchDB, but we're using the same API protocol. This allows us to replicate content in a very robust way, a way that's been working very well with CouchDB for a number of years. So we start with multiversion. This is kind of the base module for our Contrib stuff. This makes everything revisionable. So every content entity in core and Contrib multiversion changes to be revisionable. It also adds a number of underlying storage changes, things like deleting entities. It doesn't delete them anymore. It just keeps them and archives them. We can then purge them later on. We've got a number of indexes that we store information. So this is a very sort of underlying storage stuff. We've then got the replication module. This, again, is very much sort of underlying stuff for replication. It allows us to see sort of what's changed between different workspaces. I'll come to workspaces later, but different workspaces, different sites. And we can see sort of what content changes have been made, and this allows us to replicate content. So in the workspace module, workspaces you can think of a bit like get branches, but for your content. So you have a live branch with all your live content, and you'd have a stage branch for all your stage content. You can create as many workspaces as you need, so when you're creating a new sort of content feature, whether this includes nodes, blocks, menu links, taxonomy terms, whatever, they all go into a workspace. And then you can deploy them to a different workspace on the same site, or a different workspace on a different site. And because we've based a lot of this on CouchDB, you can also replicate over to CouchDB. You can replicate to CouchDB that runs locally. So there's a lot of sort of power from using these workspaces. So talking about CouchDB, Relax Web Services is the module that we've used to implement the CouchDB API. It works off the core REST API and adds the endpoints needed to work with CouchDB. As I said earlier, this gives us a very robust API for replicating content between sites and between CouchDB and other compatible services, but it doesn't use CouchDB. We've completely sort of written it. And as Tim mentioned, just want to emphasise it. You don't necessarily need this module if you just do staging and previewing on a single site. This module comes into play when you have separate sites for your stage and production, or just want to replicate between different sites over HTTP. Just a note. So then finally, we've got Deploy. Deploy is kind of the overarching thing for all of this. As I said, it's a very old module, so we sort of worked up from the previous modules. And it gives a UI for deployment. And whether you're using relaxed module for cross-site replication or just the workspace module for single site replication, Deploy will give you a UI to deploy between things. And after the session, if we've got time, we can go through a couple of demos just to sort of see visually how the UI works and how Deploy does this. And just one note. As we go through this plan issue by issue, this is a core conversation. So please interrupt at any point if you have any questions. We don't necessarily need to take all the questions at the end. We want to keep the conversation going. It's going to be lots of details, issues, and technical details. So please step in, raise your hand, step up to the mic, and we'll keep the conversation going. OK, so let's get on to the actual initiative. As I said earlier, we've got the plan that you can take a look at and try and follow through, and do step up if you've got any questions. Each of these slides will sort of loosely relate to an issue or sort of a step within the plan. The first one here is enabling revisions by default. This is an issue that I opened last year in Drupalcon LA, and we're basically looking for that checkbox, create a new revision on nodes and blocks to always be checked. And when you create a new content type, it should always be checked. So we get into this idea that revisions are always created, and by default, we should have revisions. So that issue there is currently in needs review status. So if anyone wants to start taking a look at the sprints tomorrow or over the weekend, please review that. Maybe one day. Repeat the question. Yeah, so the question was, are we going to remove the checkbox from the UI? In this patch, it doesn't remove the checkbox. But yeah, maybe one day we can. With the contrib work, so with multi-version, we do enforce revisions. So we keep the checkbox, but you can't uncheck it. So in contrib, if you are using multi-version, everything's revisionable, and you have no choice, it's revisionable. Because we believe that's the way it should work. But in the implementation details for the rest of the initiative, we can discuss that. And a little bit more reasoning behind that. So if you do the same thing with code, if you have a workflow, if you move around, stage your code, it's not like you can turn off revisions on Git. It needs to be there for fundamental reasons to be able to move things around, to be able to merge things and solve conflicts. We sort of deal exactly in the same problem space here, really, with content. Moving content around, merging between stage and production, and needs solve conflicts. So that's why revisions is this core concept that needs to be there. Bya. So the next issue is done. This was committed to core a couple of weeks ago. So this is having base field definitions that inherit from their parents. All content entities extend the content entity base class. And in there, you have base field definitions for things like the ID field, the UUID, the revision ID, the bundle. All these kind of fields are in content entity base. But so many of the core entities weren't inheriting those. They were resetting those base field definitions. So this core patch that's now in, it will go into 8.2. We inherit. And this allows us, potentially in the future, to just kind of turn on revisions for any entity type. And it will get that revision ID field from the parent. The next one that's also been done is the node interface is now implementing the revision log interface. So in 8.1, we added a revision log interface. So you may know that on a node, you can add a revision log message on block content. You can add a revision log message. And this interface adds a number of methods for that revision log. But node interface wasn't using that interface. So we've updated that, deprecated a number of old methods that weren't in the interface and added the new methods that are in the interface. So the next one is for block content. We need to get that interface also working with block content. The issue is that we don't yet have a revision user and a revision created field on block content like we do on nodes. So this patch that's in needs review, again, if you're doing sprints this weekend, please review, it adds those two fields, the revision user and the revision created. And then it changes the block content interface to implement the revision log interface, doing the same as nodes just to keep them all consistent and all working the same. So once we've got all that in, we're going to want a way to migrate entities between entity type schemers. So this is a very complex problem and it's probably the most complex issue that we've got for our phase one. Phase one, we're planning to get it into 8.2, which is out in October. And we'd like to make everything revisionable. So users, menu link content, taxonomy terms, every content entity in core we want to make revisionable. But that means changing the schema. It means adding new tables. It means changing tables. So we need a way to migrate entities from the old schema, the non-revisionable schema to the new schema. We do this already in multiversion, in contrib. The way we do it there is with migrate module. So migrate module is in core. It's still experimental, but we use it with multiversion to basically delete all of your content, change the schema and put all your content back again. So that's probably not the best way of doing it. And the reason here is that it's built into the entity API, a assumption saying that we can change the schema for you if you have content already. Because that's the very core part of the migration problem. This is why we sort of stash away content temporarily, remove storage, create the new storage and then put the content back. But as Tim said, the approach will probably be different for when we get this into core. Yeah, so we're currently discussing ideas like update hooks that will go in and create the tables that aren't there and copy the data that needs to be copied and all these kind of things. But if anyone's got any really good ideas, then please head into the issue and share them. We'll be really interested in hearing them. And one final note on this one. It's going to be tricky depending on my great module since it's experimental, as Tim said. For a crucial part in core, we can't depend on an experimental module, so we probably need to find ways around that. So once we've got that worked out, we can make everything revisionable. I've already started working on this patch, so you've got the issue there. The patch isn't really blocked by the migrate stuff, but it can't get committed until that migrate stuff is done. So at the start of this week, I had about 350 failing tests. I'm now down to about 123, I think. So we're making fairly good progress on making everything revisionable, but as I said earlier, we're looking to make all core content entities revisionable, which I think is sort of a fundamental thing. And every time I tell people that we are looking to do this, they look at me kind of puzzled of why aren't they revisionable anyway, and why are block content revisionable, and nodes revisionable, everything else isn't. So we need to try and get this in. So that's the last part of our phase one. And as I said, phase one, we're going to try and get into a point two in October. So going on to phase two, revisions don't have UUIDs. We added UUIDs for entities in Jublates, but not for revisions. Another thing we're looking at is revision hashes. So in multi-version, in contrib, we add revision hashes. And the reason we do this is because if you add some content on your stage site and you deploy it to live, and then you make changes on live and make changes on stage, if they're the same change, we want them to create the same revision hash. So if you replicate, we know that we've already got that revision and they've got the same hash. They're the same change. We don't want to introduce a conflict when the change is the same. So a UUID won't give us that functionality, but a hash will. So do we add a UUID or a hash or both? What's the best way of doing that? So there's an issue already open here where there is a patch that's adding a UUID, but maybe we need to add another issue that adds the hash or update that patch to also add the hash because that's going to be a very important feature when we start looking at replicating content between workspaces. Yeah, so the question is, are we hashing the entity, and we are hashing the entity. It's not the final rendered entity, and we are excluding a number of fields as well, things like timestamp, because obviously if you make a change on different sites then they're going to have a different timestamp. And what's practically happening is that we're running you through the serializer. It's serialized to a JSON string, and that's what we hash. So the next issue on our phase two is parent revisions. We haven't yet got an issue open for this, and we want to know where a revision comes from. So we want to be able to log somewhere what a revision's parent is. And this makes it really useful for resolving conflicts. So if there is two revisions with the same parent, we know that they both came from the same place, but therefore they are conflicting. And we need to resolve those conflicts. We then resolve a conflict and a revision has two parents. There are two conflicting revisions and we merge or we resolve that conflict in some way and it produces a child stemming from those two parents. Very much like it, really. Every commit has a parent, and a merged commit, i.e. the fix of the conflict, has two parents. So you know what revisions you've fixed to make one. So then once we've got that in, we're going to look at a deleted flag. Again, this is something we've got a multi-version in Contrib where we flag revisions as being deleted. So when you delete any content entities, it creates a new revision and that revision is flagged as deleted. This allows us to do so many things. We can now add a trash bin into Core. There's already the trash module that we've got that works with multi-version that does all this so you can restore content after it's been deleted. This also allows us to do replication of deleted content. So if you delete something on stage and you replicate up to live, then it also deletes on live. If we properly deleted it, if we purged the content, then we'd replicate up to live and live would not really have any idea sort of what the content is, so it wouldn't get deleted. And more importantly, if we did a pull before a push like you wouldn't get, it would actually pull down the content that you deleted from live. So that content would sort of reappear. So we really need to flag things as deleted. Another key aspect here is also you won't be able to solve a conflict involving a delete if there's nothing to compare with. So it's fundamental that once we delete, it actually is not removed from the database. We can present these two new changes if they are conflicting. One might have done a change and one wants to delete the content and then we can resolve that conflict. So it's a very important aspect. Yeah, so now with this deleted flag, you can't delete things because things are just flagged as deleted, they're not actually deleted. So what we need to do is purge revisions. So currently with the trash module, you can purge things and this just runs sort of the old proper sort of core delete and it actually gets rid of and purges revisions. As we said, there's a number of reasons why you shouldn't purge things, but if there are sort of legal reasons of getting rid of content, then we need to have a way in core to sort of actually get rid of content. And so as you can see on the slides, this is phase three and this is something that we're targeting or aiming to get into 8.3. Drupal 8.3, which is sometime next year. This time next year, yeah. So once we've got these in, we can look at adding the trash module into core so you'll be able to, from the UI, restore and purge any content. So this is something that WordPress has had for years. It's something that sort of your desktop OS has had since 1984. So there's a number of reasons why we should get this into core and it's well over to you. And this would be the first point in the initiative where we actually add some significant user interface changes as well or additions, I should say. Introducing this UI that Tim just talked about. It's notated as phase four and as you can see in the plan, it's still targeting 8.3. We split up the phases so that they don't depend on each other. And that's just a target. It's still up for discussion and so on. And yeah. So the next phase, phase five, we're going to start looking at moderation. So almost every site needs some kind of moderation and we've been working a lot with the Workbench Moderation team. So you can kind of see this as an effort to get Workbench Moderation into core. But again, this is still up for discussion. And the way we've been working in contrib with Workbench Moderation is you can moderate entities and you can moderate workspaces. So you can moderate an individual node, for example. Or you can moderate a whole workspace which is nodes, blocks, menu links, everything together and deploy that as sort of published. So this phase, we're just looking at the underlying API that's going to make all of that possible. So a lot of this at this stage will still live in contrib but we'll have this core API for doing moderation. And this is a step that a lot of people seem to get really excited about and really keen to get into core. And we'll talk about more APIs here down the line but I think this is gonna, for many people, for many site owners, this itself, once we add a simple UI on top of this, it's gonna cover a big, big use case that many have. Simply just moderating individual entities, as simple as that. Everyone won't need a full workspace and moderate a whole workspace but the phases and the APIs are set up in a way, as Tim said, that we can do both. So it'll be a very flexible and powerful system where we can moderate both individual entities as well as whole workspaces. So once we've got that, I'm gonna start looking at trying to get workspaces into core. So this is an initial API for workspaces and I mentioned earlier we've got the workspace module. That doesn't actually add workspaces. That's added further down the line in multi-version. So this is kind of what we're looking at doing here. We're gonna add multi-versions workspace API into core at this phase which adds the workspace as a content entity and then all content belongs to a workspace. From the UI, that will be completely invisible. You will have one default sort of live workspace. All your content will belong to there and that's sort of how it will initially work. That's how it works with multi-version at the moment until you add the workspace module that gives you that UI to create and switch workspaces. So the behavior of core would not change at this point. This is just API additions and as Tim said, it's just one default workspace. No behavior changes. Right. So we've got a number of indexes, also a multi-version module and this allows us to do so much stuff. But a UI, a UID index is probably the first place that we're gonna look at for the core work and we've already started an issue on that and just started looking at how this is gonna work. In multi-version we use a key value store and we store all UUIDs and then against that we store the entity type, the entity ID, the revision ID and sort of a load of other information about that UUID. So that given a UUID, you know what it is because at the moment we have unique identifiers, UUIDs for content but given that unique identifier you have no idea what it identifies. You don't know if it's a node or a block or a menu link. You know nothing about it. So this index will give us a place to look up and find out what these things are and this becomes important when we start to look at replicating content because we're gonna have to use UUIDs for everything because local IDs are gonna be different on different workspaces, on different sites. We have to use UUIDs for everything. So once we've got an index for entity UUIDs we can add an index for revision UUIDs or revision hashes or both, whatever we'd go down the road of looking at for them and they're gonna do exactly the same as the entity UUID indexes but just for revision UUIDs. So given a revision UUID you'll know exactly what entity type it is, what entity it is and what revision that points to. So we've then got another index. This is a sequence index and this is a real big index of everything that's going on in your site. Again it's something we do in multi-version and it's a key value store which is ordered by the sequence ID and we know everything that you do on the site. Whether you add, update, delete content, we know what entity type it is, we know what entity idea it is, we know what revision idea it is and they're all ordered so that when we do the replication we can play it back just like when you do a sort of a rebase with git you play back every commit. You could almost compare it to a MySQL binary log or a git commit log almost. A way of replaying changes. It also allows us to compare sites and we can look at what sequence ID one site is compared to another site so when we are replicating you know what needs to be replicated if anything at all. So once we've got that in we can look at replication services. We've got two services, the changes and revision diff services that are part of the replication module and these allow us to know first of all with the changes service we know what has changed on the site and this uses the sequence ID as well so you can know what's changed since a certain sequence ID and then we've got the revisions diff service so once you have a number of changes you can look at those changes compared to another workspace or another site and know what revisions are different on each site so when we come to do the replication we only replicate the revisions that are different between the two sites. So the question is does the revision diff use the UUID in the hash? Yes at the moment we use the hash so we have the entity UUID and then under that a number of revision hashes so we know the entity and the revisions that relate to that entity. So the question is about conflicts do we get a three-way merge for conflicts? We'll come to that in the future. Later on in the plan we do look at conflicts. We are flagging conflicts and as I said with the parent revisions we know that there are conflicts so we can tell if two revisions have the same parent that they are conflicting but there's currently no way to merge or resolve those conflicts even in Contrib there's no way to do that yet. At the moment we just pick one or the two conflicting. We have a Google Summer of Code project so we've got a student who's going to be working on a conflict tool for this and hopefully it's something that we can put out to the wider PHP community and it's not sort of Drupal specific for resolving conflicts. The APIs are structured in a way that a full three-way merge is possible so we can implement the most complicated merge algorithm if we would like. A three-way merge is basically where you have your local change, your remote change and then the common ancestor of the two. You have three revisions that you can compare and a three-way merge is what Git, for instance, is using to perform its conflict solution. Once we've got these replication services we can start looking at replication and put in a replication API so there's no UI currently for this step. This is just an API so the UI will still live in Contrib like it does now. The way we have it currently working in Contrib is using tag services. So the workspace module has a replicator that replicates between local workspaces and the relaxed module has a different replicator so for the catchDB API and replicates to different sites it can also replicate to workspaces on one site but just over a sort of HTTP loop. This is then extendable to any Contrib module. You can build your own replicator and replicate however you like and using those replication services you know sort of what revisions have changed and you can do the replication however you like and just tag it as a tag service and loop around as long as it applies it will run. Just to be clear within the scope of this initiative it's only going to be targeting replication for local workspaces. Again the API we're using tag services so Contrib can swap it in but for the initiative we're targeting the 80% use case which is going to be single site replication between local workspaces. We've got a way to replicate content between workspaces and we can start looking at conflicts. As I said currently in Contrib we just pick one of the conflicting revisions but we'd be looking at adding the full conflict management API into core and there's still so many implementation details to work out on this but I'd like to see it as a pluggable system where you could just sort of pick revision A or revision B or you could have a full three way merge a big sort of four pane screen to sort of choose your revisions your conflicting changes so hopefully we can make this a very extendable API. So now that we've got all these APIs in we can do replication and we can set up new workspaces we'd want to put an experimental API in a UI an experimental UI to create workspaces to switch workspaces to replicate up until this point it's going to still live in Contrib so all of this that we're talking about today is possible now in Contrib it's always going to be possible we're going to try and sort of allocate time throughout our plan to update all of the Contrib modules so they work with all the core changes but at this point we'll start adding an experimental UI in and it's a key part of the plan here and the reason why we're able to lay it out like this is that this is a solution that's been developed over the past two, two and a half years and is being actively used in Contrib and working in Contrib as it's a solution that's been maturing for quite some time already all of these phases in which we can lay them out in fairly good detail so this is the end of phase 7 where we put this experimental UI in and the next phase, phase 8 we'll be looking at updating this UI and making it a lot better we've already started working with some of the UX team we've got a UX guy also on our initiative team Joseph so we're going to be working very closely with him to make sure that the UX is really good and works really easily we've even been saying with the Contrib stuff that it's starting to look a lot easier than it actually is because the UI is quite simple but it's still not sort of know any where we want it to be from a UX point of view so phase 8 is going to be full of UX work first of all the conflict management UI as I mentioned we want this to be pluggable so that there can be different ways of resolving conflicts different UIs maybe different permissions so different users view different UIs for resolving conflicts and then we want a better workspace UI we're looking at things for example a drop down or a slide in bar so you can easily switch between your workspaces and create workspaces and if you've got hundreds of workspaces search them even moderation states on workspaces so you can see a different colour or a different state change on the workspace depending on the moderation states so there's a lot of ideas for that UI and we're welcoming a lot of other ideas so if you do have any suggestions please put them forward we'd be looking at a revision moderation module so as I mentioned earlier on we're looking at adding a moderation API integral so this moderation module would use that API and provide the UI for all of this moderation and a lot of discussions and conversations that we've already had throughout this Drupalcon is that we're probably going to put the UI for the moderation earlier on in the phases because this is again sort of the 80% use case just moderating a single entity is a very common use case so we're looking perhaps to move this to earlier phases because it doesn't depend on... Yay! because it doesn't depend on everything that we've mentioned before so it's possible to move this earlier Phase 8 currently that's I think Drupal 8.5 4 which is still some time away right can we get that earlier I think that will satisfy a lot of people so if we do move this well when we do move this earlier this will just be the moderation of single entities the moderation of workspaces also it's going to have to wait until we have workspaces so this will probably still be later on and this will allow you to moderate a collection of entities as one we'd also be looking at adding a cross-site content staging this is not in our main plan we've put this as phase X a nice to have phase this is currently working in Contrib as we said it will always live in Contrib but if we do have time at the end if we have a lot of sort of consensus that this might be something nice to get in then we can look at this cross-site content staging so this is what we've been talking about using the CouchDB API there's also a lot of discussion about REST APIs in core and sort of how they're going to look evolve so this sort of might be conflicting with those it might work well with those there's still lots of discussion to go on this so that's why it's in phase X another feature that's in our nice to have is autosave this is something that a lot of people have wanted for a long time and there's been so many issues and so many patches open for this already it's such a complex problem to solve one thing that we've sort of been thinking about is whether it could use the REST API and that things autosave to your local storage on your machine and then the content is replicated from your local machine up onto the site at the end but there's so many ideas, so many discussions already and the idea there with autosaving to your local storage is that if you would be working way on your site on your laptop and you would lose an internet connection it would still keep autosaving and then once you get your internet connection back we can replicate that from local storage back to the server using the tools that we already touched on this REST API and something called PouchDB still a lot of the discussions and ideas happening here and it's sort of in the nice to have so it's not a scheduled phase at the moment in the initiative but we're happy to hear everyone's feedback on that Great, so that comes to the end of all of our plan and we're sort of welcome any questions any ideas or any discussion Yeah, go ahead Please step up to the mic and if more of you have questions, line up this is a core conversation so we'd love to have the conversation going Just a quick question about how this, if at all would how you're considering the theming system in all this in terms of moving blocks around and new regions is that something at all that you've considered in terms of tracking those at the revision level? It's not in scope for this yet as Gries mentioned on Tuesday there are other initiatives that are being talked about that might include something like that and one thing to stress with this is we're looking at content entities only so block content is a content entity but the block itself is a config entity so that's something that you'd export out to a YAML file and add into your Git workflow so there are a lot of workflow changes on this because you've got to make sure that all of your config is on the live site before your content is so yeah, there's going to be a lot of changes And just a further clarification there we're not looking at all at making it possible to have different config for different workspaces on a single site, config will remain the same across all workspaces it's only content that we sort of compartment there you go, thank you so no config here so you can't place a block in a workspace that wouldn't exist in another a block position I have two questions so one question the big problem that I've run into with revisions in the past is the way it can bloke the database and obviously if we make everything revisions I mean we've had situations where people have a thousand revisions of a single node have you thought about that? what's the solution for that? so we've started thinking about purging revisions it's nothing we've implemented even in Contribus but maybe something like every third revision gets purged or after a certain time purged all revisions maybe a UI that you can choose these kind of parameters yes, definitely something we need to think about because with both revisions and the indexes that we've talked about we're going to be adding a lot of new data so yeah, we need to really think about that and that's what we've done with update hooks in the past has been anything older than such and such a date and I was discussing with Ken Rickard yesterday and he suggested that if this turns out to be like a performance problem because it is going to be important for conflict resolution and replication of let's say older stale workspaces to have revision data so perhaps the solution could also be to in the entity API introduce like a stash or archive storage so that we move old stuff over to the secondary storage where we still store it but the main queries they like day-to-day queries if you may on the entity API would run on a sort of lighter storage and then you could join on that archive storage if you need the history because then you'd come around the performance problem you wouldn't come around the storage problem but today's storage is cheap and that's not necessarily a problem It's still an issue for some people Yeah it certainly is but it could be sort of a solution and then so my unrelated question is have you talked about scheduling because that's the other editorial thing that comes up over and over is scheduling things right Yes there has been talk about scheduling currently it's not in scope for the initiative but if people want it let's build it we have Ted Ted has been working with us in Contrib and he has built modules around scheduling so there is work ongoing in the community to sort of have scheduling work with all of these bits and pieces because it's certainly something people are asking for and if it's something we think it's a big use case that's added to the initiative if there's consensus and agreement we're all here to plan together put forward more feedback like that and we'll certainly look at it for sure Next question Thanks for the work and thanks for the presentation One of the challenges that we've had in the past with workflow may be a simple answer from you guys and it may be just kind of the ecosystem will continue to evolve but workflow has a lot of assumptions about how people actually work and I wonder if you could speak just briefly to how much control over things like whether workflow assumes people who aren't named in the workflow are excluded from access and just kind of some of those workflow assumptions that especially are in workbench and workflow So we've tried to make this as flexible as possible and when working on the contribs side it's extremely flexible but then we come to implement a UI for this and if we make something so flexible in the UI then it becomes so confusing and complicated to use so we've tried to come up with sort of sensible defaults for the UI but left the the API as flexible as we possibly can so maybe we look at adding different contrib modules that provide different UIs as you saw from earlier on in the presentation we've got quite a lot of contrib modules that make up this and a number of those are optional just because there's different workflows and you need different modules for different things sort of about a year ago we probably had maybe two or three modules that made this up and now we're up to like five or six so that's just to add this flexibility so it's definitely something that we are keeping in mind Just a nitpicky question can I opt out of revisions and new UIDs still for my content entities after these core changes I certainly think that should be an option I can see that there are use cases what we then have to make clear to developers and end users of the API is that you won't be able to move this particular content to other workspaces it'd be something that stays there we'll change it already way in with the inheriting those fields or is there a way to opt out of that so we haven't started making any assumptions around that yet so we certainly should have something and I think something it would be in the annotation of the entity type it would say opt out from replication or something or opt out from revisions it seems a little problematic in terms of backward compatibility since I just wrote a module it doesn't want those so inheriting the base fields at the moment the content entity base class uses a lot of the entity keys so if there's a uuid entity key set then it gets the uuid field and if there's not then it doesn't same with the revision and the bundle fields so it gets the fields if it's got the right annotation any more questions or does everyone want to see a demo of deploy yeah okay so let's so here we're looking at a single site content staging so you'll see up in the top toolbar we've added a number of new things that you don't get in in core and just to kind of note first that this is all contrib stuff so this is stuff that's available now you can use this today on your sites so up in the top toolbar you've got where it says stage on the top right there this is then a drop down that gives you a switcher for workspaces so you can see we've got a live and a stage workspace and down the other side you can add a new workspace then next we've got the update button that allows you to update your current workspace this is a bit like a git pull or a git rebase to pull down any changes and you've got deploy which is to push your changes so let's get playing this where we're going to add an article and so this is just kind of a standard node we're going to add a title, we're going to add a body and then we're also going to add some other entity reference type data so we're adding a menu link so a menu link is actually a separate content entity but it's just attached to this node using an entity reference and we've added three tags there as well which are also entity references taxonomy term entities so we can now switch over to live and back to stage and see that there was no content on live, there is content on stage we can create a deployment so we give each deployment a title so you can look back at a log of your deployments and now switching between live and stage the content is there the menu link is there, all the taxonomy terms are there so they all stay connected and they all get transferred over as one we're now making an edit on the live site so we're editing the node title and also the menu link so when we save that you'll see that the menu link has changed and the title have changed again they're two separate entities and back on stage they haven't changed but you can do an update and that will pull things down from live to stage so that's how it currently works in Contrib and this is kind of ideas that we're looking at when moving to core as well I think it's a quick question I messed with that a couple of months ago and was both excited but then I hit the image field and the file object didn't sync has that been addressed or is that being addressed in relative short order when everything was clearly still marked under development at the time so it wasn't shocking there were pieces missing we have been working quite a lot on file entities and that's working I believe I don't think we've had any issues for a while now and we recently had patches also for media so both file entities and media is working because those are two different entities I think we still need more test coverage here but it's certainly high up in the priority order so it was that so I've got a second demo video here for cross sites so you'll see right up in the top bar there I've got two tabs open Drupal 1 and Drupal 2 I've added a user called replicator so this is a user that we use to authenticate between the two different sites and we've got a special role and special permission to the replicator user so we're going to add that replicator user in as our default replicator user on Drupal 1 so if anyone needs access to Drupal 1 they'll use those credentials we're going to add a remote so this is where we add what Drupal 2 is we add in the URL and also what we call the API root so it's just relaxed by default and we add the replicator user that user also exists over on Drupal 2 so then we can go over to the workspace UI and edit the live workspace and we can set the upstream to the live workspace on Drupal 2 because when we added the remote it knows about all the workspaces on Drupal 2 and adds them as upstreams so we can then add an article exactly the same as in the other demo with menu links and taxonomy terms and push that over to Drupal 2 so this is using the CouchDB API for replication so this is the relaxed module and it doesn't actually use CouchDB you don't need CouchDB installed but it's exactly the same API we've built a CouchDB replicator in PHP as a Google Summer of Code project last year so it's using that PHP replicator so exactly the same UI from deploy give it a title push it over, it takes a little bit longer because it's running over HTTP to a separate site but we can now go over to Drupal 2 and we'll see that the content's there and just the same as the first demo we can make changes on Drupal 2 which is a live site and push them back to Drupal 1 so the question is can you do a pull and that's kind of what we've got with the update button and it pulls down from the upstream so that's currently how we've implemented that but as I said earlier these APIs are very flexible so if you want to build a different UI to select where you want to pull from and what you want to pull to then it's very flexible and the UIs can be very easily built for that so basically having some sort of discovery mechanism so that you wouldn't explicitly have to state a relationship between two sites it's an interesting one let's discuss it more afterwards perhaps to understand everyone want to step up to the mic so the question is about menu links and if there's a different menu structure and yeah it can be tricky the menu links currently attached with NT references I believe we switch all of those to UUID so we can attach them up but then if you've got a different URL there are different sort of node IDs between workspaces because they are in fact two different nodes so the best suggestion there is to use something like path auto and make sure that you've got the same same settings so that it generates the same URL on each workspace in general what we're looking at here conceptually is replication so it will be tricky if you move content between two sites that are different you certainly can it's nothing that stops you but we look at it as replication so we want to replicate what's in one place to the other place so that they are in the end the same if you're looking at content sharing between sites then perhaps you would choose to only replicate certain content entities and not something like menu links that are most likely going to be different between the two sites we have a concept coming of filtered replication so you could do exactly that like replicate only nodes or only terms or terms and nodes and skip the menu links if you do have that sort of use case where you want to share and something might be different between the two sites so deploy module exists for D7 it looks significantly significantly different and it's certainly not as powerful as this and will never be able to be there are some key things that are missing in the entity API for D7 so conflict management and sort of this workspace concept will never be able to be implemented in D7 what you need in D7 is then two different sites you need a dedicated stage site and a dedicated production site and then you can use deploy between the two and just in the past month or two we've actually opened up two major versions of the D7 module with a big number of improvements that Dave Hall has been working on so if you've been using or looking at deploy module for D7 before it has recently got a big overhaul with UI improvements and some stability improvements so it's certainly not anywhere close to what we're looking at here but it's a decent solution for D7 thanks