Okay. Welcome to elevate your approval processes mastering complex Workflows. I'm Bob McDonald, senior Drupal architect at Kalamuna. Just a little bit about myself. I'm originally from Idaho, but as soon as I graduated university I moved to Japan and I spent a little more than 23 years there before I decided to move to Canada to join Kalamuna last April. Which means I'm new to doing Drupal talks in North America, and I beg for your patience in case it turns out to be a terrible disaster. Um, I really love making stuff, and over the course of the past several years, I've made several approval systems in Drupal, and I've gotten fairly good at it. So that's what I'm here to talk to you about today. I really care a lot about making sure that the systems I build are focused on being empathetic to the user, kind of focused on making sure that the user experience is first. And so I hope to inject a little bit of that into this talk. So I'd like to start out by talking about the experience of workflows in core.
Um, and then move on to talking about some more advanced uses of workflow. Um, through several projects that I've worked on in Drupal over the years. We'll talk about what's important for a system like this, and the lessons I've learned from all the mistakes I made building those systems. And then we'll move on to talking about what you should be thinking about when you're planning out a system like this. We'll get into looking at some tools that I've found useful over the years, in both core and contrib. We'll take a look at some code samples and get on to Q&A. So. Core workflows. Core workflows consists of two modules Workflows and Content Moderation, and workflows sets up the framework for workflows. It sets up state transitions, default states, and then it introduces a plugin manager for our workflow type plugin. And without a workflow type plugin, workflows doesn't actually do anything in Drupal. It needs that workflows plugin or workflow type plugin to connect it with the content.
There are several workflow type plugins available in contrib, but the one that comes with core is called content moderation, and that's what we're going to focus on today. And content moderation links the workflow with revision of content entities, and that it controls whether those are public or not. Out of the box. It's basically intended to to build editorial type workflows. And so the example that we'll look at here will be one of those editorial type workflows. So let's kind of have a look at an example. Workflows consists of two key concepts, and the first one is what we're looking at here on the screen states. The states are the different stages that your requests can take as they move through their entire life cycle on the site. So here we've got five different ones. We've got draft awaiting, editorial review pending publication published and archived. And you've probably noticed here that each one of these states has two settings associated with it. Whether a revision saved into that state is considered published or not.
And whether when you save a revision into that state, that revision becomes the default revision or not. Now, speaking of saving into a state, that brings us to the second core concept with workflows the transition or the action as I think of them. So I've just enabled three of the transitions on this workflow. And you notice that they're all different colors. That's because transitions come with permissions. So each transition you can assign the different roles that are allowed to use those transitions. So here we've got the submit to editor transition that goes from draft to awaiting editorial review. And that's usable by only the author. And then we have a keep in editorial review transition which is usable by both authors and editors. And we have a published transition which is usable only by the editors. So let's just follow the content through the system real quick. So an author comes along, it creates a draft. It's ready to submit for the editor to look at. So they use the submit to editor transition.
To move it into a waiting editorial review. And at that stage, the editor or the author might make several edits to it to get it ready to publish. And they'll use the transition. Be keep an editorial review to save it back into waiting editorial review. Which brings me to the second key important concept about transitions. You need a transition for every pathway through the states that you need users to be able to use on your site, and that includes pathways from a state back to itself. So if we didn't have transition, be here once we use transition A to get into a waiting editorial review, the only possible next step given these transitions would be to publish that content. We couldn't make any changes until we were ready to publish. Speaking of publishing, let's go and do that. The editor decides the content is ready, and so they use transition C to move it into published. And then they may make several more edits, and they can use transition C again to move from published back to published.
Because you can see that transition C goes from draft awaiting editorial review pending publication and published to published. And that leads me to the last two key important things to understand about transitions. On a transition you can have any number of from states, but only one two state. And the other thing is that each from two pair has to be unique. So this published transition has from draft to published already. So I couldn't come along and create another transition that goes from draft to published. Each from two pair can only exist once. So here's a look at an over an overall, um, workflow. We won't go into any detail. I just wanted to show you what that'll look like. You can analyze it later if you'd like. But now I'd like to move on to talking about some projects that I've built using approvals. The first full Drupal project I ever worked on was in 2015, when I joined the Institute for Global Environmental Strategies as a senior web developer. I just as a climate change research institute, and so they do a lot of research, which leads to a lot of academic publishing.
And so they have a publication database. And when I joined I just their publication database was written in Xoops. It was really old, it was really buggy and the vendor didn't want to support it anymore, so they wanted it migrated over to Drupal seven. And that was a steep learning curve for me. Figuring out Drupal seven theming, Drupal seven migration, um, custom modules, understanding the data structure in Drupal and the data structure in Xoops, understanding what's important when it comes to academic publishing. It was it was a lot, but we got it done and the Institute was happy about happy with it. And so the next thing they asked me to do was to build a business travel approval system to replace an existing system they had that used an Excel sheet with some complex macros combined with email. Um, so we also built that in Drupal seven and relied heavily on the rules module. Which was great rules in Drupal seven was really powerful. I don't know if you're familiar with it, but it lets you respond to actions and take other actions behind the scenes on the system, and you program all of it using the UI.
It was great. But when once you get a complex set of rules and components, it gets really hard to maintain. And that's what I ran into with that system. But overall, the project was pretty successful. And looking back, I've realized that everything that I've identified as being key to a successful approval system existed in this, in this system. But after we got that launched, um, the institute was ready for a website redesign, and they were really happy with the content management capabilities that came with Drupal. So they wanted to build they wanted to basically move their whole website onto Drupal and combine the publication database and the overall website. And so we migrated the publication database to Drupal eight, built the the new website on there. But the the piece of that project that's relevant to this talk is that they wanted to begin enforcing a long standing publication approval policy that they had at the institute with a publication approval process. Uh, midway through the Drupal eight release cycle.
Workflows became part of Drupal core, and so we decided to build that process on top of. Um, workflows in Drupal eight. Overall this project was was successful. The institute is happy with the website. They're still using it. But if I had to identify a part of this project that was the least successful, that publication approval process was it? Um, it's the first time I build anything on Drupal eight, and it was the first time I'd used workflows, and I made a lot of mistakes. And I hope that you're going to benefit from them as we talk about lessons learned throughout building this. After we got the publication database onto Drupal off of Drupal seven, I should say was time to move the mission request system off of Drupal seven. So we migrated that to Drupal nine. And I want to pause here to explain a little bit about the flow for the mission request system, because it's going to come up on a later slide when we need to talk about how to how to deal with something. So the mission request system or requester would come in and they basically build an itinerary for their business travel.
They say, we're going to these travelers are going to be in this place from this date to this date, and then in this other place from this date to this date. And then maybe another traveler has traveled to a different place on different dates, and they build up a whole itinerary for all the travelers on the request, and then they associate budgets with that mission request. These are the budget lines that are going to be used to pay for that mission request. Night. So then on the mission request system, there are two approval stages. There's funding approval where we approve the use of those budget lines to pay for the for the travel. And then there's supervisor approval where each travelers supervisor needs to be needs to approve them being away to those places for those purposes on those days. Now you've probably realized we've got two approval stages funding approval and supervisor approval. But within that approval stage, there's actually several approvals probably taking place. And that's not something that content moderation handles out of the box.
So we need to store and manage that data and decide when we're actually taking those transitions. Outside of content moderation, so I'll talk on a later slide about how we store that data and how we manage that. But I just needed to set that baseline so we understand that when we get there. After the mission request system was migrated, we built a couple more approval systems on top of that same intranet site. We built a fundraising proposal review system to allow researchers who are working on fundraising proposals to get several more sets of eyes on their proposal to make sure it was really solid before they submitted it to a fundraising to a funding agency. And then once they got back the results of that fund fundraising effort, they would go back into the system and say whether it was successful or not. And in as far as they could tell, why or why not. And that data was fed into a proposal database to help future fundraisers kind of get a head start on their proposals and hopefully, um, increase their success rate.
And then for proposals that were marked as being successful, they automatically generated a project database entry with its own little workflow. And. A key part of that workflow was that the accounting team came in and matching up with the contract that came out of that funded project, they would create budget lines in the system, and those budget lines were then used as budget lines in the mission request system to select how that traffic is being paid for. So. Yeah, it kind of came full circle there. And now fast forward to today at Kalamna. We're getting ready to launch. A newcomer donation platform where we accept donations for newcomers to Canada in Need. Bet those donations put them on a marketplace, and then match them with support agencies that can get those donations out to the newcomers that need them. So now let's talk about all the terrible mistakes. And what's important for a for a mission or for an approval system. So the first thing that's important with an approval system, of course, is that the approvals move through the system.
If if things don't get approved or rejected, then there's no point into having a system like this. And the key thing, the key factor that's really important, I think, for making sure that things move is making sure that people know that there are actions to take and understand what impacts their actions. Have taken so that they know what's next. Um, and notifications are the key element of that. Drupal, of course, gives on screen notifications for changes to state and things like that. But you should you should modify those. Um, you should let the user know exactly what impact on the request their action has taken, and they should also know who was notified for what reason as a result of their action. Speaking of people being notified, of course, another important elephant element is notifications off site. Unless your users are on the site all the time and that's their top priority, they probably need a nudge off the site to know that there's action for them to take. And we used email for that.
And that leads me to the first real mistake I made in the publication approval process. The custom module I was using to handle all the logic around transitions and moving from state to state. Also included building up the data for the emails we were sending. Putting it together into a text body for the email and sending it. And so then later when we needed to make changes to that template. It was pretty difficult to do that, since it was kind of hard to figure out where all of that was being constructed. Later on the mission request system, we started using the message stack of contrib modules to handle building those emails, and that gives you a UI where you can build your templates in the UI and use token replacement to fill in the data. And that's that's my recommendation here, is to use some contrib module for making that those off site notifications be modular, um, to make it manageable. And the other aspect is that you probably don't want. I should say probably one notification is not enough.
If your approvers are busy or they're focused on other things, they may miss the first notification. And so in order to keep things moving, you want to send them a reminder after some number of days of inaction. And it's really useful if you can reuse those notification messages that you've already built for your original ones, and just insert a little blurb that says, this is a reminder because you haven't taken action for for several days. And that's something that's easy when you're using a contribute module like messages. And it's it's harder if you're doing it in custom code. So just back on that, that recommendation to use a modular solution. Another important element element of approval systems is that users won't use them if they can't trust it. And in order to trust a system, they need to believe that it's fair and transparent, and they need to be able to understand what's happening with the system. The first part of that first key. Key element of that is making sure that everywhere where you can see a request on the system, you can also tell at a glance what state it's in and whose action we're waiting for.
And that's what I'm highlighting there in that pink box at the top of this slide. Um, we got two proposals here. They're both awaiting supervisor approval. And then all the blurred text on these slides are people's names. Um, these are screenshots from real websites, so I've blurred out the names. Um. And this is also where I can talk about calculating these. Um. These lists of people who were waiting for. We manage all the data for those in state approvals. By building an associative array of all the data we need about each request. Um, on transition time, those transitions are going to be your triggers for almost everything. And handling this this calculation on transition allows us to focus on just one request at a time. Whereas if we were calculating them on the fly on a whole list of these elements. Um, we'd have to do several calculations. So we build out an associative array of all the data that we need, and we store it in the state API. The state API is a core API that allows you to, you know, store state data about whatever you need to.
And so we just key it by the request ID store that array in a, um, the state API stores it as a serialized array in the database. It's the same database table that config is stored in. And that's worked really well for us. And the other really nice thing about the state API is storing it there. As soon as we don't need it anymore. The approval data is not relevant to the request as a whole. It's just relevant to the process. So as soon as the process is complete and it's been rejected or approved, we can just drop that data. We don't need it anymore. Another key element to building trust in a system like that. This is having an audit log where people can see everything that has happened to the request over its entire life cycle. And so every system we approve, we build. Like this I build an approval log into each request that has data about. Who did what when throughout the entire life cycle of that request. You see an example here in the middle. And then the final thing I want to talk about here is this timeline interface that I'm showing at the bottom of the slide.
If you've got a linear workflow, I've found this to be a really successful way of making it easy for people to understand where their request is, what's already happened, what's still to come. But as an added bonus, that also gives them an understanding of the entire flow really quickly and lets people onboard to the system, um, a lot faster. Speaking of which, if you want people to adopt an approval system like this, you need to make it easy and intuitive for them to use. And. That's what this slide is about. Every system that I build like this, as soon as you log in, you get an actions dashboard that presents you a list of all requests that you can take action on with action buttons for them. And that's one key element here, is that every time there's possibly an action available for you to take, you should present the user with a button that allows them to take that action. And we're looking here at the the screenshot at the top of that actions dashboard I was talking about. There are two things here.
There's proposal 161 that's awaiting general and accounting smell reviews. And I've got a button here to review the proposal. And then we've got a project that's awaiting accounting team budget finalization. And that's got a button that says prepare project entry. But you notice these are teasers and you probably don't want your approvers making decisions on the content based on the strength of the teaser. You want them to look at the full content and then make a decision. And actually, this review proposal button doesn't change the state at all. This takes you over to the view page, where then you have buttons that allow you to actually approve or reject and do the things you need to do there. Now this project number 112. This is for the accounting team to prepare the project entry. So when they click this button, they actually get the project Edit form. The project Edit form has several fields in it. It's not just the four fields for what we need them to do. In fact, the four things we need them to do are in this screenshot at the bottom, because we found that it's really useful to add a checklist of the things you need people to do when there's a limited set of things in a larger field.
So we've we had this checklist at the bottom. And then we put validation really simple validation on it that we can't move to final confirmation until all four of those check boxes are checked. And that just gives the user just enough push to make sure that they have the opportunity to to to do the right thing before they move it on. Another issue that we came across on the mission request system, the first iteration of the mission request system. We realized that if you put in a mission request and then it gets rejected with no indication of why it got rejected, that's a really crappy experience. And that's a problem that we were having occasionally. So we wanted a way for the the reviewer to provide a reason when they rejected a request. But we didn't want to present them with the whole edit form or something to to provide that information. We just wanted a place that they are required to enter a reason when they're rejecting, but that otherwise doesn't get in the way. And we found that the Ajax dialog box API, which allowed us to put a trigger on the reject button, and when you click that, it popped up a modal with a required field that you need to enter a rejection reason.
In this particular case, that rejection reason wasn't important for the request. We didn't need to store that data anywhere. We just wanted it for the notification that we sent to the user that their request had been rejected. So we would include that rejection reason into the email notification that went out to the requester, and then we'd throw that data away. Um, but we ran into another case where we needed to gather user feedback on these transitions, and that was for an optional comment left by the reviewer. And that's what I'm showing in this screenshot at the bottom. We wanted again to provide just a single text area for for people to provide a comment. We didn't want it to get in the way and prevent them from from doing the review without leaving the comment. It's optional. So we've just got this little detail that's closed by default above the Review Complete button. If you pop that open, you can enter a comment. And then in this case, we did want to store it as part of the request.
And you can see here that the unit leader in the previous approval stage left a comment on this particular request. This is the last slide on lessons learned, and it's a lesson that I'm consistently trying and failing to learn, um, fully. And that is planning ahead before you start building and making sure you know all of the things you need to build, one key element of that, that I've consistently until this very last project failed to think about in advance, is that eventually you're probably going to need to prove the value of your system. And you're going to need to monitor metrics around how it's performing. And then likely when you introduce a new feature, you're going to want to be able to tell whether that increased the efficiency of the system made things better or whether it's actually a step backwards. In order to do that, you want to have some metrics. You want to have collected statistics about how things are working on the system, so you can tell if it's better than before you made the system.
If things are moving in the right direction as you develop the system. Capturing those statistics is really valuable. And this screenshot at the bottom of the slide is a prototype for that content or the newcomer donation platform that we're getting ready to launch where we're we have a dashboard of the different, um, statistics for the site. And that's because we've started capturing on every transition we capture the timestamp that that transition happened, which allows us to easily build computed fields to say what the what the time to approval was. And we can calculate calculate global site averages on things like that. Um, but beyond just stats. Planning ahead. For your system will pay dividends and on the mission request system when we first launched it. I presented it to senior management at aegis and the accounting manager said, oh, this is great. What's going to happen in two weeks when the fiscal year changes and all the budgets change? And what happened was that I spent the next two weeks frantically adding fiscal years to the system because I had completely missed that.
That was something we were going to need to have in there. And I would have preferred to do that at a more leisurely pace. Um, so the more legwork you can do up front, the less scrambling you'll need to do at the end. So now I'd just like to talk a little bit about what you should be thinking about when you're planning a system like this. Of course, the the major part of planning a system like this is planning out the flow. Um. And the first part of that flow is what are the different logical stages that your requests can take as they move through the system? Um, those are the states. And then. The next thing to think about is what are the actions that can people that people can take when they're in each state? I don't think I've built a system like this even once, where I got all the transitions in the beginning, it's seems to be really hard to to logic through and plan out all of those transitions, but the way to minimize having to go back and add some is to try and think about those transitions from every angle and to think about them as actions.
So I'm in this state, how did I get here? Where can I go from here? Do I need to be able to make edits and then save back into this state? Um, if you can think about it from every angle, you're likely to get most of the transitions you need. And from there you should think about who can use each of these transitions. Now, if you can identify those users by their role, then then you're golden. You've got exactly what's provided by content moderation out of the box. That's never been the case for systems that I've built. It's always been a little bit more complicated how to control access to those transitions. Mm. And you need to think about, do you have the data on your system that will allow you to identify who those users are? So just an example on the mission request system. The funding approval was easy. Um, the budgets were actually taxonomy terms in the system, and we had the funding measure that's identified through a user entity reference field on those taxonomy terms. So getting a list of the funding managers was a simple task.
But for the supervisor approval, we needed to understand Aegis's organizational hierarchy. Which meant integrating with the air system. And when we went to look at the air system, we found that the only kind of interchange ability that system had was that it could export CSV files. And so we built an importer on the Drupal system. And then every time staffing changes, the HR person uploads that CSV and the organizational structure gets updated. And then we can identify who each individual user's supervisor is. This is also a good time to think about how you're going to track those multiple approvers for each thing, and how what the data format is going to be like, and whether you want to store that in state API or whether a custom table or something makes more sense for you. State API has always worked great for us, but um, yeah, it's a good, good to plan through that at this stage. And and you're again, you're going to want to be thinking about these transitions as actions from the user's point of view.
And this is the time to think about what those actions will be called. If I'm this, if I'm the user taking this action, what is it going to make sense for that button to say that allows me to take that action? And this is the time to think about whether that button is going to be the same for every class of user that's able to use this transition. So an example where it might not be on the Donate the Newcomer donation platform that we're getting ready to launch. Donations come in, they get vetted by the site administrator. And then they move into the available state, which puts them in the marketplace where support agencies can claim them. When a support agency claims one, it goes into the claimed pending state. And there the site admin again comes along and verifies that it's a good match and either approves it or rejects it. And if they reject it, it goes from claim pending back to available and it shows up back in the marketplace. But there's another way that things can move from claim pending to available.
And that's if the support agency who claimed it comes along and says, yeah, I don't need this anymore, and they release it. And from their point of view, it doesn't make sense for them to click a button that says reject claim. We need the button to say release claim. And so in cases like that we need to do a a form alter to change the text of that button. And it's just good at this stage to kind of figure out what those alters are going to need to be. It's also a good time to think about whether there's any stages on these transitions where you need to capture more data, like in the case of the modal, we pop up for rejected mission requests. And now you've got a list of all your actions, all your transitions. These transitions are going to be the trigger point for all the logic that's happening on your site. Um, including the notifications that you put both on screen and send out to your users. And so you have a list of these actions. Now you can build up a list of what the notifications should be both on screen and off site.
Make sure you don't forget to update the requester about what happened on the request there. The person that cares most about the request on the entire site, and it's sometimes easy to forget to let them know what's happening when things change. The on screen messages are really important as well. Let people know what impact their action had on the system and who's been notified for what reason. And then once you've got a list of those notifications, now you also have a list of the templates that you need to start building for each of those reminders or each of those notifications. And when you're doing that, you should think on each of those notifications. Would it be prudent for me to be able to send this notification again if if the approver didn't take action? And that's where you come up with your list of reminders, and you should plan that template with a space for you to add a little blurb saying this is a reminder because you haven't taken action for three days or whatever your cadence is.
Other things to consider when planning a system like this are like we talked about a few minutes ago, the statistics, but specifically what are going to be the key metrics for your stakeholders and what's going to be important for you when you're trying to identify whether, um, improvements you make on this system are are being impactful or not. And the other thing to think about around the statistics are who needs to get those statistics out and what format do they need to be in. Do they need is it okay for them to export statistics for the entire lifetime of the site? Do they need to be able to filter it down by by dates or by some kind of other metric? He's planning ahead. We'll let you figure out what you need to capture and how you're going to export it. It's also a good time to think about how people should communicate about an approval that's in process. So. Um, at for some of our systems, we've asked people to use Drupal comments. In other cases, we've had people move that communication off site and do it by email or telephone.
Um, I don't think there's a right answer here. It's just a good thing to think about, because people are going to need to talk about these approvals that are in in process. And then again, just to harp on thinking ahead. Um, do as much legwork as you can up front to make sure that you know what you're going to build so that you can avoid a fiscal year debacle like I had. I'd like to just talk about some tools that I've found useful. We've talked about most of them already, so it's just going to be providing you some links to make this presentation helpful beyond the bounds of this presentation. Tools for approvals. We have the workflow buttons module, which I think if you have an approval system built on workflows, you need workflow buttons. Um, and so there's the link to that contrib module. Here's a link to the documentation for the state API. I'm sure you're all familiar with the form API, but, um. Here's also a link to the Ajax dialog Boxes documentation page. Tools for communication.
This first link is, um, documentation about how to use the message message stack to build, populate, and send out emails. And then I don't think I talked about how I implement those reminders, but basically it's a combination of state API for determining whether a reminder is needed and having the data that we need for the for the reminder cron for triggering triggering that, that logic, and then the queue API for building up a batch of emails to send out. So we already had a link for state API. So here's a link for cron and the queue APIs. And then the last link here is a contrib module that can save you a lot of time if it matches the notifications that you need to send out. So what content moderation notification allows you to do is on transition, you can send out a notification to either the content author or all users of a role. And so if you if your notifications line up with that criteria, this can save you a lot of time. It provides you the UI based templating system with token replacement.
Um. Yeah. And it it's a good module to use if you're, if your recipients match the requirements. It's never been the case for me so I haven't used it much. And then finally, these two tools are usually considered as tools that are useful during development. But I found that for an approval system, they can actually be useful during production. So I'm not sure how broadly known mail safety is, but mail safety allows you to do any combination of four things around email. You can stop all email from being sent. You can reroute all email to a specific address. You can capture all the email in a dashboard, or you can let email go out as normally. So of course, during development, probably on your local environment, you're making sure that email is captured in Mail Pitt or Mail Hog or something like that. Then once you get to your pre-production servers, you're probably either rerouting all your email to a specific address or capturing it in a dashboard, or maybe both. And then once you get to production, probably you either disable mail safety or you set mail safety to send emails out as normal.
But in a system like this where you might have a site admin who kind of needs to monitor the reminders that are going out and maybe trigger a resend if if a approver says they can't find that, that, um, notification. Setting mail safety to send messages out as normally, but also to capture them in a dashboard can be a good solution for quickly building up that kind of interface for your site admins to use. And then the masquerade module, you're probably all familiar with it. What it allows you to do is if you have the correct permissions, you can switch over to be another user, take action as that user, and then quickly switch back to the original user that you were without dealing with logging in and logging out. And what's that? What that's useful for in production on an approval system is building a rudimentary delegation system, where if someone's going to be out of range of being able to provide approvals, they can delegate to someone and say, this person is authorized to approve on my behalf.
And then that user would tell the administrator, okay, this one is approved, and that administrator could then go in and masquerade as the original approver and take that action. But allowing users to act as other users without any evidence that that's what's happened is a great way to erode trust in your approval system. And so this little code snippet at the bottom of the slide allows you to identify when you're masquerading and figure out who the original user was. And so I'd recommend that if you're going to build a delegation system like this, you update your reminders and your approval log entries to say, this user took this action on this other user's behalf so that it's crystal clear what's happening on the system, and users can still trust it. So this this repo here has all the examples and a little bit more, um, of what we're going to talk about on the current on the future slides. Looks like we got about 15 minutes left. Um, I won't go into much detail on these code samples on the future slides.
Um, they're mostly here to make this presentation useful beyond the bounds of the presentation. But like I say, there's a little bit more expanded examples of that at this, um, at this repo. So this code sample is a service that I wrote that allows you to easily get the transition ID that happens when you when you're doing a transition, it's easy to get the from state. In the two state, it's a little bit less straightforward to get the transition ID, and sometimes that's a more intuitive way to figure out what what actions you should take behind the scenes in your system. So I wrote this little service that does that. And this is just an example of creating, populating and sending out a message using the no. Sorry, this is the wrong slide. This is an example of removing a button and altering the text of a button in when you're using workflow buttons. This one is the one where we're creating, populating and sending out a message using the message stack. Oops, there was one more. And then finally, this is a really abbreviated example of using the Ajax dialog box to pop up that modal.
Uh, the top of the slide, we've got the trigger, the bottom, we've got the routing Yaml for setting that up. And then I've not included the controller here, but the controller is in that repo. That's all I had for the samples. Um, are there any questions?
>>:
Can you hear me from here? I. Uh, I kind of can. Uh, I was wondering on. Can you hear me now? Yes. Okay, great. Uh, I was wondering on one of your slides, you had a number of, like, a checklist option for. Yeah. Um, uh, creators to fill out. I was wondering what you're using for that. Are those just, like, a separate set of fields, or is it a separate module that's built into that? Or we just did a simple form alter to to add fields that add those checklists in using a form API. It's kind of a good idea for a, for a contrib module. Maybe I'll make one. But yeah, it's just custom code in this case. Okay. Thank you. Any other questions? And if I can hear the question, I'm happy to try and repeat it out. Okay? Okay, good.
>>:
Hi, my name is Wilson. Can you hear me? Um. Yes. Um. I have. Question is how? How do we assign? I'm working for a nonprofit organization that has various content, and the staff attorney is. Is in charge in different content. So the challenge part is there are times, uh. Attorney changed and then the reviewer need to be changed also. So far we are having trouble in go in and. Bulk change or the reviewer which possible. But then you create all this trigger, all this email notification. Hundreds of them. Yeah. Um, I was thinking that to add those to the user itself, um, is there a better way to go with this workflow? How can better design that? Yeah, what I've done is, um. For the calculation where we're building up the state API, um, storage for the for the approval state. I've built that into its own method. Um, which is separate from the logic for building, for sending out the email notifications and those other things. And so I'm able to trigger just the recalculation. In that case. So, um.
Then you just need to build a trigger for whether you can select all of your different content or whether you want to. Sorry, you can. You can build in like views, bulk operations or some other, other means of selecting the things that you need to update and then just running that method where you recalculate the the approval state on each one. Um, as long as they're in that case that you're talking about, there's not going to be any move between transitions. It's just updating the approval list. And so you can run that recalculation and that'll update the data for all the approvals you have. Okay. Thank you. Anything else.
>>:
Any questions coming up on the live stream on YouTube or anything?
>>:
Nope. Nothing there. Okay. We don't have any more questions. Okay. Thank. Um, in that case. I would just love to know. What you. What you thought of that. So if you have an exam. Uh. Wow. Getting tongue tied. If you have a chance, please go to this URL and provide feedback on the session. And I thank you very much for your attention. Thank you. Thanks, Rob. Thank you.