So, welcome. My name is Marco Berrocal. I am from Costa Rica. A little bit about this. I've been doing this for 12 years. It feels long sometimes, sometimes short. It depends on the day and who asks. I have to say it's been quite the ride in the sense that I never imagined myself, getting so much out of the WordPress community, being a WordPress developer, and when I started, we all have a point of entry of how we started to do things. My situation was I lost my job and I said I really like web design. I used to sort of lead projects and I really, really liked it. So, I started to investigate about which content management to use. Back then it was a matter of Joomla, Drupal and WordPress. WordPress wasn't as big as it was today. So, I started to do themes. I started to grab a theme, start editing the theme, and I said to myself, I love this HTML and CSF stuff. I did things, it worked, and I was like, whoa, this is amazing. I really liked it. But then I needed to do stuff. I needed to do stuff with WordPress. The theme that I had didn't fit the requirements of the project or I wanted to add a new feature or I wanted to do things out of the box, so to speak. So, I started to Google a lot. I started to, you know, paste stuff, and yeah, it worked. And sometimes it didn't, but eventually it did. So, that was my workflow for many, many years. Okay? And one of the things that I was really, that I read everywhere, was that you don't modify core. Like, whatever you do, don't modify core. And whenever I read tutorials online, they never mentioned anything about core. They just said, you know, just copy, paste this, put this on your functions, and you should be good to go. And that worked for the most part. So, this is also, 12 years later, a question I asked a lot when I have to give, like, I have to interview somebody and I ask them, you know, can you name me what hooks are, and what does a filter do and what does an action do? And this is, to me, a defining moment because in my WordPress development career, I think it's one of those things that you need to fully understand in order to become an even better WordPress developer. And part of the reasons why I am decided to do this workshop is because, like I said, you know, I spent many years pasting stuff without really knowing what I was doing behind the scenes. And some people get it right when I interview them. Others do not. Others have left. When I do the interviews. And it's a turning point, in my opinion. There are many, many aspects of WordPress development that are defining and I think hooks is one of them. So, I did this slide because when I asked my girlfriend, you know, I'm going to do a workshop and I'm going to do it on hooks and she was like, what are hooks? So, I gave her the analogy of a car. Whenever you request a page, you are essentially building a car and the car goes from one face to the next, okay? And in each face, it does things, okay? And hooks are a way that you can modify the car without modifying the machinery itself, like modifying the core machines themselves and that you can add extras to your car or remove them without touching the machine itself. Like you have this little thing that does the job and it does it without touching the machine. And then she said, ah, okay. Exactly. So, this is what this workshop is going to be about. We are going to build something. We're going to do stuff from scratch. I'm going to leave this repo here. I have really no preference as to whether you should type along with me or if you just want to look and follow along. Each approach is valid. I promise you by the end of this workshop there will be code in this repo. We're going to push it and you guys can just pull it and, you know, work your way from that. What else? So, going back to, let me post this a little bit so that everybody got it. Everybody got it? Okay, cool. It's empty right now because we're going to do this in the workshop. So, one of the things that this design does, it's called an event-driven design. I'm sure most of you have worked with this with JavaScript, for example. So, if I was to go and one of the things I didn't mention, I have a small theme. Like I said, in a requisites nothing major can be any theme. No specific layout, nothing out of the box. Just a local host and that's that. So, we're going to work with that if you have that on your computer, great. And one of the things that we've worked on in the past is JavaScript, right? So, we have, for example, let's say we want to do a script. We're going to do inline script over here. This is not part of the repo. It's just an example. So, we're going to work on, I think it's Athens. We'll see in a bit. Let me see if I have to select the right. It's as we, as I get older. It does say work on Athens, does it? Yeah, it does. So, I made a mistake. Cannot of no art event listener. Click. Let's see. I did a mistake, right? Let me see. What's wrong? My JavaScript is not so good. It's just that I can't see my source code. Hold on. Let me see. Well, let me just copy when I have. That did work. Maybe it's just that I'm a little nervous. I'm going fast because it's my code. Don't worry. I have it here. So, well, that kind of sucks, does it? Well, the thing is I wanted to do an event listener, but maybe it's a little nervous. But the thing is, in JavaScript, we've used this a lot. Like, we've used an event application where the user is the one that interacts with it and events are fired based on that. So, with WordPress, it's also the same. And I go back to this car analogy. It's because WordPress, as you request a page, starts sequentially to load things, to, for example, load themes, to load plugins, connect to the database, load the body content, load the authors, load the categories. Those things are run in a sequential order until the page is fully served and WordPress shuts down. So, the idea of hooks is that you can actually go into that specific moment within the page sequence of things and you can tap into it and you can overwrite the behavior. So, that is essentially what a hook is. It's your ability to go to that present moment and overwrite behavior because that is exactly what we are interested in.  So, what examples could I list? I could list, for example, that we wanted to modify the body class of the page. Or we wanted to modify, I don't know, the content. We wanted to modify the title. We wanted to, for example, if I am on the blog page, I load 10 posts, but if I am on category X, I want to load 20 posts. So, those things are all things that you can actually modify or that you can modify using hooks. And this is one of the reasons why I really, really love WordPress as a platform. It's because it has the ability for you to overwrite behavior without touching the core files. And you can do pretty much anything you can think of without doing so. And that's part of its magic, okay? So, in WordPress, it's slightly different than JavaScript because we're the ones that are interacting in JavaScript, the user is, like a mouse up, hover, mouse down, or whatever, mouse click. But in WordPress, like I said, it's the server that assembles this. Like it's the WordPress engine that's itself that fires these sequences that we can tap onto and modify its behavior. So, like I said, hooks are pretty much that. You hook into them, and you use a callback function in order to override behavior. This is how we do not modify core. So, part of the interview questions, when I ask what hooks are, they come into flavors. They come in filters and in actions. So, actions allow you to add, remove, or modify functionality. The keyword here is functionality. So, when I said, for example, I want to modify... I want to modify... What do I want to modify? I want to add a menu page, for example, to the WordPress admin. I am modifying. I'm modifying functionality. But if I want filters on the other hand, they allow you to add, remove, or modify data. So, that is the key difference between the two. So, what do I mean by data? The content, the title, an author, things that are strictly related to data. So, filters are your way of modifying that data, whereas actions are the way that you can modify functionality. So, always keep this in mind whenever you get an interview question like that. And, you know, whenever you need to do something with WordPress, okay? So, we're going to get started, and we're going to use the classical example of a, you know, custom post type. We're going to create a custom post type, and I am going to explain step-by-step how we do it with actions. So, let's go. Yeah, we can. So, what I'm going to do here is I am going into my plugin over here. I have this plugin file. I'm just going to, yeah, we're going to modify that, and we are going to, I am just going to copy that from the code that I have, because I can't prepare it. So, in here, this is a plugin, nothing standard. We go to our website over here. We go to plugins, and we do not see it. Why am I not seeing it? The wrong directory. Content. Let's see. I'm sorry. Yeah, it is there, I know. This is why I'm a little surprised it's not. Oh, my God, I'm not even on alcohol. What's wrong with me? So, it is there. So, we activate it, my God. I was like, it's not there. So, we activate it, nothing really happens, okay? So, nothing really happens. So, we are going to do, for example, a menu page, okay? So, we are, okay, but first of all, I want to show you some examples, okay? So, we are going to use the functions first to show you some quick examples of filters in action and actions. So, we are going to do is we're going to first do an action and an action in the callback is going to be WC-E-E-U function. And I am going to copy this. Sorry, okay. So, I just added a small action. This action is called the admin menu. So, actions are called by this function call over here and you specify what the action is going to be. That is the first argument that goes in here. So, in this case, it's admin menu. Now, you may ask, how do I know this? Well, I know this because I usually have worked with a lot of instances of this, but there's a ton of actions and filters that you can actually hook on. So, there's a list of that in the WordPress.org website. So, in this case, the time that I am hooking into is when the admin menu loads, okay? The second argument is the callback function, which is this one over here, I missed the C. And there's two more arguments that I am going to discuss in a little while. So, basically, this reads, when you are loading your admin menu, execute this function, which is this function that I have over here. In this case, what this function does is that it adds a submenu page to our settings file. So, if I go to my website over here, that I can't see, where is it? Where's my Firefox? Oh, it's this one, Jesus. So, if I go over here, go to settings, I should have this. Now, if I click on this, I should have an error. And the reason why I have an error is because one of the arguments of this function over here is the callback, which I have not done. So, it's going to fail. So, the callback function is what needs to execute after I add the submenu page. I mean, I can do it, but I don't know what we're going to take. But, again, to iterate, add action. When do we want to hook into this action? What is our callback? And two more parameters that I'm leaving out for now. There's one here and there's another one here. I am leaving them out for now. I'm going to explain them in a bit. So, in here, I'm, like I said, modifying functionality. I am adding a menu page to our settings menu in the WordPress dashboard. So, that is functionality that I'm modifying. And that's that. So, the error will leave it like that. Filters, on the other hand, work with the add filter words. Again, we specify when do we want to... What filter do we want to use? So, let's say, for example, I want to add a special class to my body tag when I'm loading the front page only. Because sometimes in CSS, you need that. Like, let's say you need a special class in your CSS in order to target that specifically for the homepage or any other page that you can think of, like a blog or archive, author. It doesn't really matter. So, in this case, we are going to use the filter called body class. And, again, we are going to specify the callback function. So, w-c-e-u body class. Okay, we're going to do that. And we are now going to write that function. So, two things. As you may have noticed, there's a parameter in here. And the second is that I am returning something, which is another of the key differences between filters and actions. Filters always take parameters and always need to return something. Because think about it, you are getting data that you may or may not modify, but you need to return it. So, don't say in an interview, oh, filters are things that filter and actions are things that act. Don't ever say that. The right answer is, you know, actions are things that can allow you to modify behavior, whereas filters, I can modify data. So, in here, we are going to modify the class, the class that WordPress uses to inject the body elements. Okay? So, if this is front page... So, if this is the front page, I want... I'm going to write classes because it's plural, really. Classes. Classes. Classes. Classes. So, essentially, I'm saying, if this is the front page, add to the classes, array and assistance, add a string Athens page. So, if we go over here and refresh our page, aside from this error that I don't... I want to get rid of. Why am I... Keeps doing that. I don't know. So, if I refresh over here, go to the body class. I can't see it because... I can't see it. It's not there, right? That's not nice. I'm sorry? Where? Oh, right, right, right. I'm sorry, I'm sorry. You're right. Didn't see that. So, and the body class... No. Jesus, what's wrong with me? And here we are. So, here we are. We have the class injected, and that's what filters essentially do. They... In this situation, this particular situation, I have asked for the body class filter. I'm asking if it's the front page, and if so, modify it so that you can add the class Athens baby to it. And, again, that's the difference between classes and filters. So, we are going to go back into our plugging over here, which is activated, and I didn't see. And now, we are going to add an action. Add action. In this case, it's going to be init, and in this case, we are going to add a callback function to it, which is wcu2023 register post type, okay? So, we are now way to Jesus, like that, and we are going to add the function that is called this. So, again, add action. I'm hooking now into the init hook, and I'm using this as my callback function. Okay? So, in here, I am going to modify behavior. In this case, I'm going to add a custom post type. So, first of all, we are going to I'm going to copy this just so that we can move a little bit faster. My code. Okay? So, in here, I'm using an array called session labels. WordPress needs labels in order to register a post. So, I'm going to add a post type called sessions, okay? I'm going to do that. Next up, I am going to copy and paste these arguments over here. So, this is the labels, and these are the arguments for this specific post type, okay? In this case of description, public, true, show UI, and what it supports. Next up, I need to register this post type. I'm going to register this post type. I'm going to name it session, and I'm going to use the arguments that I declared here in order to do so. So, let's go back at it again. I'm using an action called init where this is the callback function. So, this is the function that is going to execute whenever this is going to be done. So, I'm going to use the labels array, which is needed for WordPress to identify new posts, moving it to trash, et cetera, et cetera. And the second is the arguments array, which is the array that it's going to need for this particular function called register post type. So, register post type is the one that actually does, you know, create and register the post type. So, sometimes I've noticed that it really depends on which environment and which circumstances I get 404s a lot when I register post type. So, usually you can fix that by going to permalinks and then saving them so you can flush your rewrite rules, but I just added here explicitly so that I don't have to worry about that. So, I'm going to save this, this is essentially how hooks operate. So, that is that. And now, let me see. Okay. One of the cool things that also comes with WordPress is that you can create your own. So, you can use your own actions in order to do your own behavior. And that is also a very important thing. So, you can create your own actions, the same can be said about filters. You can create your own filters that they do their own thing. So, if we go, for example, to WordPress list of actions, list of actions WordPress. So, let's say, for example, we're going to go to this page over here. So, I have a colleague here when she was speaking. Yeah, she doesn't know all the commands and need it to lie. I don't know all the actions, but I usually search for something specific and usually, my searches are geared towards that, like admin menu hook, or after theme loads hook. So, I usually visualize myself where do I need to modify this honest, I'm not going to learn this and I don't if anybody knows this I would be very surprised. So this is the list of hooks and going back to my example that you can create your own, yeah if one of these hooks is not good for you and you're saying man I need to do something you know custom you can create your very own. Usually I create my own again when there's certain functionality that I need to execute throughout either the theme or the plugin itself. So I have the action to you know do that. So I add the action at a specific point in my theme and plugin and then you know if I need to override it I'll just add an override function to it but that's essentially what it is and we're gonna do that of course. So we're gonna refine our previous example because if you look at our previous example over here if you look at this this is all good but it's not very flexible right it's only limited to sessions it's only you can only do sessions with this you can't let's say for example I want to use this in my workflow in order to create custom post types for the specific project okay so let's say I have a project where I am as a developer I say okay we're gonna need sessions as a post type we're gonna need speakers we're going to need I don't know attendees things like that so this is not very flexible unless I copy them paste this three times and did it you know three separate times so I could for example create a custom action where I can define the parameters for it and it's going to execute this function and create the post types for me I don't know if what I said makes sense yeah does yeah okay cool so we're gonna do exactly that so we are going to go and we are going to create a function okay but I don't know if I should do this first or I should deviate and show you a couple of actions that I created hmm are you guys following or you guys would like me to create a basic example what's the consensus here hmm my question is do you want me to go straight into the post type and do it or do you want me to create a custom action so that you can see a display here and you can see it and I speak a little bit about it what do you guys prefer you guys are the bosses okay so we are going to create some custom actions okay so function called WC EU 2023 custom action do action I'm gonna write and then I'm going to walk through it okay we create custom actions by using the word do action and within the parentheses we use the name of that custom action that we want to use okay that's how we register that and below I am doing exactly the same as I have done previously but using WordPress list of actions but now I am using my own and this is how I can overwrite the behavior of this action whenever it is that I needed throughout the theme so I could do like this echo this is another thing in action this is another thing in action okay so if I have it over here let me see because sometimes no I need to add one more thing yeah exactly so what I'm going to do is I'm gonna move this actually because this is not this should not be part of the of the custom post type stuff that I wanted to do so I'm gonna move this into functions and just put it there like that I'm going to create two okay I'm going to create two and this of course will not work and let's say I want to go all the way down here and okay let me see I have an error here callback I did not add the callback did I no I did not but of course I didn't okay okay so let me walk you through it so I've added the custom action called W WordCamp Europe 23 custom action I'm declaring it here in my functions file and I'm using this as the callback this only echoes this is another thing in action inside my header file I am using the same action different callback but here I put two numbers okay and the callback it's this function over here where I say overriding is fun so if we go over here you'll see that they are printed out without a space I'm sorry well maybe we should do like this overriding is fun okay so I've created my custom action that only prints two things here comes the nice part so the 10 I don't know why I did that I should not don't 10 what am I doing the the 10 is called the priority so the number is the the priority or wait is it the arguments first or the priority correct me if I won't priority right okay so the 10 is the priority in WordPress the higher the number the lower priority it gets okay so the default I think it's 10 I'm not sure if it's 10 or 20 I forgot but it's one of those two if I use a number that is lower like for example one this action over here doesn't have a number so it's going to use the default one but since I specified a number that is very low this is going to run first as you can see so overriding is fun this is a thing in action so always keep that in mind when you are developing how yes there's a lot of philosophical debates like the ancient old Greeks as to how high or low that number should go because I have seen people use negative numbers which some say how can you do that to your code you are the worst person in the world where there are other people that say in the WordPress documentation it says integers and that is an integer so it's again this is now that we are in Greece here we can go to emperism versus what you recall it what's the other one the other currents where they you know Plato and Socrates they they all fought over it okay that knowledge is to be obtained whereas others say you are born with it so a lot of philosophical debates around that so personally and I'm sorry for those who don't agree I use the negative low numbers as an emergency only because sometimes when you're working everything is a priority and I'll tell you in the place that I work yeah this needs to load really fast yeah this needs to load really fast so before you know everything needs to load really fast and you as a developer like man what should I do I mean I only have 10 numbers you know so recently yeah I had to resort to a negative number as far as the priority was concerned but try to avoid it if you can if possible you know try not to go that route and you know yeah that's that's really my take on it you could you could but the thing is if you do the priorities lower so if for example I use where am I well that's when I want to go the other way the higher priority because if you use a higher number it's lower it's I know it's the you know it's a little twisted the whole WordPress way of things but like for example nine I could use nine and I could use here 10 so in the WordPress and let me put this side by side in the WordPress way of things in the WordPress way of things the one on the right gets executed before the one on the left so the things that you need to execute before it's limited because it's only 10 numbers before the other camp of people start saying you're a terrible person because you're using negative numbers so if you can use a high number if you if you don't if you don't rely on other hooks to load if you know before yours okay this only it's viable is also whenever there's a conflict of things like one is overriding the other correct so if what you are doing is it has a lower priority and there's something else that does something similar you may have overwritten behavior because of this priority number okay yes it's not the best practice but I'm just trying to give an example so that people it's not a good practice no I have to I have to be honest it is not but it's just an example so that people can actually see it in different files so to speak yeah yes the same number that's a good question that's a good question you know I don't have the answer to that what if they have the same I think it's because of the yeah because no but there's also there's in there's in a there's in a there's an object that work is uses that has the list of all the you know things that it needs to load and I think it's sorted depending on that that sort it's it gets executed I'm not a hundred percent sure that that is the problem but that's a really good question yeah yeah so like like my colleague said this is not best practice like if I go for example over here and go to the footer and do that and then do another action for example add action I'm gonna use the same action what's the name of it okay and I am going to use let me do this again so that's better footer CB function echo inside the footer and we are going to give this a priority of one so here I'm once again using another action to override one more time the hook but I'm just printing things out if I go over here it's not working because okay here we are so but now I modified that so again now I have three priorities I have one here I have nine and I have the default ten so in the wordpress way of looking at things again we're gonna look at it we have one over here we have nine and we have ten so all using the same custom action so in the wordpress way of things the one in the footer gets executed first then the header then the functions so this is another another thing in action is the last overriding fun is the middle and inside the footer is going to be the first and let's refresh that and that is exactly how it executes so always keep that in mind priority is always important especially in large projects where you have a lot of things going on so going back to our custom post type we have that again I wanted to modify this and I wanted to do something that is more flexible right I wanted to do something that allows me to create multiple custom post types using this function so it's gonna be like this factory of creating post types so what we're gonna do is we are going to create we're gonna modify this and we're gonna modify the hook for init and we are gonna create our own like this I hope I don't get confused with the names and we are going to specify the priority and now I'm gonna put a number here this number is called the number of arguments this action is going to need so in this case I'm specifying for okay so you may be wondering what about the rest of the hooks like the wordpress hooks what's the number on that one it really depends on the hook that you're working on because this for example this for example may have a different number of arguments compared to for example this so if you if you're curious about it you have to look for the specific hook in question in order to know what the default arguments is going to be so but in our situation we are going to need for now why am I going to need for because if I look at this I want to mud I want to dynamically add this here I want to use plural and I want to use singular okay so that's two arguments and I want to use a description because that's gonna be different from depending on what post type I'm using and the third is the slug the fourth is the slug so whenever I'm going to execute my custom action I'm going to need those four arguments in order for this to run and create my custom post type so I am going to define them here not surprisingly I'm going to name them singular plural slug and description okay yeah okay so in sessions I'll get rid of it sessions and oh man I'm gonna have to do this by hand singular singular this is going to be singular also singular this is going to be plural so what I'm doing here is just adding the variables that I'm going to pass along for my custom action in order to create a custom post type of any type that I want so it's going to be plural this is also plural and this is also plural and this is also plural okay that looks good I'm going to rename this array because now it's not going to be limited to sessions it's going to be custom post labels that looks better this one as well I'm going to modify this because it's not limited to sessions anymore custom arts and I am going to limit this in here I'm gonna get rid of this because I said I was going to use the description for it right and what happened to my mouse so instead of hard coding it I'm going to use it like that so description looks good and session is no longer my slug now it's going to be dynamically added using my action so slug is good let me see yes where before yes singular singular thank you which one this one right right it doesn't know no what's wrong with me no no it doesn't right I have to define that when I add the action I'm sorry about that I got carried away so when I add the action I define the priority and the number of arguments in the do action I do not do that thank you very much did not see that so again we are going to register the post type with flush and now we are going to add action what's our name of our action it's this one and our callback now it's going to be in post function is going to be this and what's the order singular session sessions slug session session description let me see hope no errors no errors okay so explaining this will be like this okay do action again we are defining our custom action called registered custom post type so whenever we call that we are going to create like a factory my my idea is to create a factory of custom post types that I want to use so I modified this function so that the parameters are going to be inserted both in the labels and in the arguments okay and again I registered a post type using the dynamic name now that I'm going to use that I'm going to pass as a parameter and I'm just gonna flush the rewrite rules and now below I'm using the hook of my custom action which is this one over here registered custom post type which is this one right it's this one and the callback function as we've previously seen it's this one which is the function below where I just make the call using the parameters that I want to use so if I want to use speakers for example I'm going to copy this I'm going to paste this and now I'm going to use speaker speaker post speakers post speaker speakers speakers speaker description and if I go over here I have the speakers here below so by using these custom actions that I've created I can now go ahead and create multiple post types just by calling this custom action that I've created now this may or may not be a very practical example of creating post types because you could do an object or something else or you know just a function and call it and that's that but what I really wanted to highlight was the emphasis of using your own actions in order to override behavior and do your own thing you could for example I don't know you could argue that okay if I have I don't know if I have this is this is not a real case scenario if I have 2,000 attendees okay then we are going to do a conference so let's add the speakers so he just you add the speakers like that because you need a different behavior compared to this one now you could again argue say oh man I could put that all in a function right yes you could but this is just another approach another different way of doing things and I think that is the key thing about using a platform such as WordPress I always when I tell people a WordPress it's like it's when it comes to development it's you know all all these things are just one blade in the giant knife that the Swiss Army knife that is WordPress so it's just one more tool for you to say ah I'm going to create my actions or I'm going to use a class or you know things like that that allow you to have flexibility when it comes to doing your own things so again we could do this copy paste over here and now we want to do attendees attendees attendee attendees attendee attendee description and I refresh that and I have my custom post type called attendee so again that's the I like to say magic I know you guys might relate to that others do not but that's one of the things that I absolutely love yes of course yes correct the arguments correct yes you're being you're being explicit about it in order to follow a convention and correct correct as far as I know no but that's why I was kind of stuck I was like man I was like I thought in the do action I needed to specify the number of parameters that I wanted to take you know that's why I was a little bit skating and it's funny because now that you mentioned that because I think that when I ran the code it actually worked let's let's let's as the previous speaker said let's break things because she I when I was preparing for this I did this you know I did this and it still worked you know I was like yeah you see I was like what when you said that I was like what and so I was like and then I said to myself I'm gonna fly without you know questioning and I'm gonna just do it and it worked and I was like why does it work you know it's like that meme I have no idea where my coat works and I know why my coat works mm-hmm I'm sorry you want to see an example of using the arguments that part I don't quite get I'm sorry okay okay yes you mean going back to the core and seeing yes but here I'm defining my own so I'm kind of stuck yeah but if you if yeah if you if you want to look at the arguments of a specified hook you need to look at the core documentation and see how many it takes and and like I like you know like him he said I don't know why my coat works and because I was sure that I had needed to specify this here but it worked with or without they I don't know you know so moving forward we've refined it we get again like I said with filters they modify data not behavior we already discussed priority and parameters here I'm gonna just mention briefly some of these functions that WordPress has that may be useful when when it comes to you know doing things so you have has action and has filter so they basically check to see if this action or filter has been registered this is good if you need to make your or if you need an action to be present within the WordPress sequential you know within the WordPress sequence of things in order to execute some code because you may create a hook that is not going to run because it you know it doesn't exist or something is not valid so this is pretty good you know validation in order to run your code against that I could have run it but I don't think how much time we have we're okay and remove action and remove filters these are really I like to use them because sometimes WordPress loads things that I really don't want like for example like for example let me give you for example like for example and I hope Matt doesn't see this but we're gonna use this example one of the one of the things I don't like much about WordPress is that whenever you search for WordPress in your source code you always see the version and I'm not really sure why we need that and it can potentially be a security you know vulnerability because you're pretty much saying this is the version that I have and if you're working on the site that's a little old or it has a vulnerability you know people can exploit that so usually within my workflow I just remove it all together and you use a precisely a filter to do that so the filter would be remove I mean I'm sorry it's a it's an action remove action WP head and we specify the thing that we want to remove generator yeah I got it so if I execute this now it's gone I have to say so though in the documentation it says that you need to run this within an action but I kind of ran it in within my functions file so I'm not really sure what it meant because as it said in the documentation you needed to you know hook into an action and in the callback execute line 695 which I really said to myself okay why does it say that if this works I don't know if what I said makes sense did it no yes if it doesn't I'll say it again okay so in the WordPress documentation it's explicitly set not to run this directly as I did in line 695 and instead it told me to do this at action some hook this is not a real hook by the way some callback in the WordPress documentation it's suggesting or it's pretty much saying that I should do this instead of what I just did why I really don't know but I just wanted to tell you guys about it in case the code doesn't really work as expected whenever you are removing actions chances are you need to execute it in this manner like you know hook into it and then call the function you call the remove action in order to do so but you know when I when I ran it it just worked and I was like okay you know that's that's that's that's really fine that's really great it works as expected yes no no no control Z or command shift Z correct correct correct correct yes since I we still have time I want to do other filters like other filters that I found I find it interesting because of the workflow of things and one of the things like for example let me scroll so that let me see this is my code okay I really when I work with projects and you all agree with me clients will be clients always clients will be clients always and one of the things I like is I like to limit some of their choices so that clients don't do what clients do and one of those things for example is for example this if I uncheck this this might open the spam you know gates and a lot of people you know are going to the comments are just gonna go straight into you know to your to your post and that's that's a little that we definitely do not want that and another thing I don't and I've seen it because clients is that they check this the reading this one and then they're like why is my SEO no working you did my project and then you log in and you see that and you're like man but I didn't click on it and it's like I sure did not you know so it's always good to reinforce this so that you know clients don't modify this inadvertently and some damage could appear so how can you do that you do that exactly you know with with with actions and filters so I am interested we're gonna do for example let's go to discussion one of the ones that I like is I'm gonna do the opposite but you guys will you guys will get the you guys will okay so we're gonna go to discussion so I always no matter what I want this checked no matter what it doesn't matter because if the client unchecked this and you have a decent site you're going to get a lot of spam and next thing you know you'll be maintaining a database and you're doing the cleanup of course you're gonna charge money but you know the objective here is for you to save work and not allow the client to uncheck this inadvertently so you might just wondering how do I do that well we can use a hook for that so we are going to filter that and I am going to copy and paste this I'm gonna use the repo even though it's not I'm gonna use the repo so we're gonna I'm gonna comment this out and I'm gonna show you two ways okay we're gonna use the first one okay pretend you don't see it but you already have so okay so adding a filter in this case I am filtering the option of comment previously approved which is this little guy over here I'm specifying the comments you know pretty we've seen this and you know I'm sorry oh I always get this wrong I always forget but I'm gonna leave it out so in case of doubt leave it out so this what it does is that what it does is that this is going to return always true because no matter if I uncheck this and save it this will always be true because I am filtering the response and I'm overriding that value so this way I can ensure that my client my beloved client who I have so much love and trust does this and saves it this will always be true so if you need some settings to be always like this you can modify the behaviors using these filters but the cool way that I wanted to show you because I learned this the other way and my boss showed me I was like man you know you know a lot so you can add the filter and this is the same if you look at it it's the same filter it's the same yeah it's the same filter but the callback it's just returned true and I was like because I did this and he was like I did I did this that I commented and he says this is too much I was like what do you mean it's too much it's yeah it's too long I'm just returning true and he says no but WordPress has a function called return true I was like no you don't and he says yes they do so so I said I doubted him so low and behold low and behold WordPress has a function that always returns true yeah so you know whenever this is a very simplified way because in one line you're pretty much executing everything and I was like man this is really really nice so again so filters are a good way for you to do that so another thing I like to have control is this personally I like the enabled and I like it to be two levels deep because the design I think from a visual perspective starts to break after you know five replies I mean how much do you need to reply to the reply to the reply the reply right I mean two two levels deep is more than enough so again we do the same by and I'm gonna copy this and paste it by doing an ad filter in this case the option thread common depth I'm using here a enclosure instead of a callback function which is also valid I wanted to show you guys that because here as you can see I'm using I am using the function itself within the call I'm not using a callback function like this so I you may see examples of that because since this is short it's it's just practical to do it like that and I'm gonna get rid of that and in here again the thread comments depth which is this value I want it to be always two you know so function option return two so if I change this to 10 and I save it this is still going to be two yes no my boss taught me that you inspect over here you look for the label and you have this and then you put the option word before on the score and that's it I was not gonna say it I was like you know a magician doesn't reveal its tricks right but that is that is how you do it yeah so it's pretty much the same so yes you could do that I mean again it's options that you have that you can think about what's best for you given the project that you're working on you know yeah yes yeah yeah and I think I have we have time for another example so one of the things also I like to work is for example the common moderation you can put words here you can put words here and if you for example put a word it will go automatically into common moderation but if you think about it why not filter the comment itself and replace you know some bad words in there for asterisk so it doesn't go into moderation and you don't need to be always looking out for the moderation because I mean it's time I mean we got other things to do you know so why go into your WordPress dashboard and check that and like what am I doing this every day you know so a good way a good example could be something that filters that so we are going to now going to add the filter in this case it's common text this is pretty straightforward it's the text of the comment so we are going to specify the callback function like this and we are going to get of course the comment comment comment and let me copy it because I think it's way way easier to just copy and paste it so I'm sorry about the words I tried to be original so we have these bad words over here in this array you know and what we're gonna do is we're gonna have them in an array we are going to and I have this wrong we are going to get the size of this array in this case it's just four elements we're gonna loop over the array and we're going to replace the naughty words with asterisks so that way we avoid doing this the same but here it goes into moderation here it just replaces it so we're going to do that we're gonna save that and we're going to reload the page or get a comment where can I get a comment like for example not here hello world I'm sorry about you know that's it hello hello so that's an easy way of doing things and I think that is the takeaway of this workshop I mean we've done some code we've done some stuff but what I really want for you guys to get out of this is to think about things that you can do and modify with WordPress using hooks and filters either your own or the ones that exist and that they become a part of your workflow in order to make your lives as developers better because we're developers we deserve a better good life and you know it's less of these tasks that can be a little bit repetitive and you can simplify things and still charge the same which is another complaint I get why do you get charged the same I was like it's because of what I know not the time it takes to me to do it so filters are that I mean hooks are that they're a way for you to to do pretty much anything you can think of and and you know when if you have an idea of a plug-in that you would like to use or anything like that I mean anything that you want to do with WordPress it's doable using your you know hooks either the ones that WordPress has which is a huge list or your own and I wanted to show this example but I don't want to complicate things further so I'm just gonna mention it remember in this example over here and the ones that we did the custom post type we specified the arguments right like for example here this could be a little long if the argument list is yeah too long so instead of that we can use this do action ref array and apply filters ref array to send an array and use the values of that array in here so that way the argument list doesn't get as long or if you need everything in an array you can use that instead of the do action so it's essentially substituting do action for do action ref array and sending an array as a parameter I think I have the code I'll paste it you guys can can can can fix it later on I think you see over here now I have the array over here whereas here I have the four arguments so now I just use the arrays within and I just pass one argument around it's just cleaner than then then then using you know the amount of parameters I think for it's at the limit but but yeah where you see it over here so this is why I don't know we need to talk later because at the at the do action I'm defining it here and I'm specifying the array that I'm gonna pass around as arguments so we need to have that discussion because that made my head spin a little seeing them all run okay I'm glad we still have time so sometimes I want to see all the actions run on a given page I want to see them I want like a man what what's running within this page right so I'm gonna show you the ugly in the nice so the ugly would be and I'm gonna copy that because I'm gonna copy that and I'm gonna put it in the plug-in and then I'll comment it out so this is the ugly let's paste it I'm gonna explain it add action in this case it's all all means all so this is going to run on absolutely all the actions out there so this callback function is going to run so this callback function over here essentially what I'm saying is that if it's not admin and you know echo the tag out so if we have that over here and we load this this is going to do this thing over here I mean it's a little big it's a little it's not I mean it's not really nice I mean if you ask me I mean yeah I see the list so what it's not it's not something I really like but again if you why guys want to see it in action I mean this is the code that does that I like to use a plug-in which I have here it's this one over here and this is why I was so confused because I thought it's this one over here I know to show hooks the reason I like it it's because it's a fork of wait it's a fork of wait let me this is not to say I like it because this this is a fork of simply show hooks which wasn't it wasn't plug-in that does the same job but it got discontinued over the past years you know how it is so these guys picked up the project again and are starting to do that and I really like the simply show hooks plug-in because what it does is that I could be on a page and it gives me all of this information that it's pretty it's pretty useful so for example as you can see I have these three this is the the actual action that I previously did the one that printed the information out wait let me get rid of this this three lines are these three that I have over here right you see the callback functions on each of them and you know no I'm sorry these are the custom post types I'm sorry I'm sorry where are the ones that I have for no I need it's on the other side right it has to be on the public side yeah and where is it let me do a little here it is so we have it we have them over here we have these are the ones that print out the inside the footer overriding blah blah blah and in here you see the action which is the action that I made and here are the priorities that I specified previously and as I and as I told you before it's from lower number to higher number so it's a really neat plug-in because you can see it inserts it right after each thing and you might be saying oh I need something before the template loads or I need something before the loop or after the loop runs for example there has to be something loop yeah here like for example loop start so you may say I need to modify the behavior before the loop starts or you know anything that you can think of and in here it has all absolutely all the the the callback functions that it has for a particular action so I love this plug-in to develop or whenever I'm stuck and I need to do something as far as you know actions is concerned so I just load this and see it and I'm like hmm maybe I need to hook here or hmm maybe I need to do that and it's you know getting those things in here going and I wanted to share that because this is so if you if you guys are going to venture with with hooks and whatnot this is this is really useful and I think I am done yeah well some more examples I before I leave one of the part of the workflows I would say one of the actions I use a lot is called the Q scripts I use it a lot to inject JavaScript you know when I started with WordPress I did like pretty much everybody else did I go to the header and put my scripts in there and see you later alligator you know but then as I got a little bit older with this I realized that you know I could use the in Q script hook use the callback function which is in this case you know load my scripts and just add them add them and here comes the good part I'm a little cheap when it comes to serving assets so if you need something on the home page why do you load it everywhere else so you in you add the scripts dynamically through the through a callback function using hooks so if it's in the front page at the script if not don't add it I mean we're not we're we're developers and we need to think also a little bit about the user experience of things you know we know we don't need to load things that aren't necessary in a page for not going to use and let's just not load them and that makes it better and people are happier so for in Cune scripts this is great I use it a lot in the workflow and another thing that I use a lot is this one over here it's it's a it's an action again I'm modifying behavior I'm gonna paste that over here and what this action is called pre-get post and my modify main query is the callback and what this essentially does is I modify you know the main query based on the type of page that I'm in because you have the setting over here you have the setting over here of of what you might call it settings reading and you have this right you have this but this is just for the blog and sometimes you need to overwrite this on a specific page like let's say let's say you have an archive page that is called news that is really good and popular but and you want to have more posts visible than compared to your blog or your recipes for example so you use a hook to modify the main query and the amount of posts per page now I want to say this is a bad practice you should never use minus one because that is not good as far as performance is concerned because yeah it's it's it's it's big on a database as far as query so I think with that I am done and I would like to thank each and everyone of you especially with the questions and the debate which is something I absolutely love even though I get cornered thank you


All right, I think we can start. Good afternoon. I hope you, hey. My name is Julien Stroker, working on Microsoft. I'm gonna try to, so I hope you're there for this session doing DevOps with DCOS. I'm gonna try to share for 45 minutes my journey around DevOps. So I used to work in the DevOps team inside Microsoft for three years now. I mean, I'm still working in this team. Doing a lot of open source technology, which is great. Microsoft pay me to do open source technologies. I have a lot of fun and I try to stay focused on DevOps practices. And when I'm seeing DevOps practices with open source, yes, we have like Microsoft products doing helping people doing DevOps. Maybe you heard about TFS, VSTS, and so on. But since I'm really focused on open source technology, I'm playing and I've been a lot of fun with the opposite, Jenkins, for example, and other open source technology, which is really great. So I'm gonna try to share a few practices. The idea is more of a challenge. During these 45 minutes, I'm gonna try to do just demos. And we're gonna try to do and implement the DevOps practices on a leader application, Java application that I'm using a lot. So I'm gonna explain that actually. So just the idea of that, it's 45 minutes doing only demos and we only code. So let's cross the finger. Let's see if it's gonna work. So quick agenda about that. So I don't know if you're about ACS, norways, guys, I'm not here. Yes, working for Microsoft and nothing to sell, right? I'm doing only technical stuff. I think I only have one marketing slide working for Microsoft. So I guess it's kind of monetary, no kidding. I'm just gonna explain ACS. Maybe you heard about that as the container services. It's just a quick, easy way to deploy like DCOS or Kubernetes or any container orchestrator on Azure. So I'm just gonna explain that for people, maybe never use it.  Depends the time that we have. I'm gonna try to add more and more practices on top of that. Make sense? All right. By the way, as you can hear, I'm French. So sometimes people cannot understand me. Don't always just raise your hand and say, can you repeat that? Or maybe if I have questions or so, don't hesitate to ask questions. So yeah, that's the only marketing slide I have ACS on Azure. Azure Container Services. This is the thing, the only preparation that I made before the presentation is just to deploy a cluster. Just a few clicks. We, Microsoft, so we like to clicks and we like interface using the portal, right? And I deploy, obviously, a DCOS cluster. But you also have the ability to deploy swarm, Kubernetes. We just announced a new services for people using Microsoft called ACS, which is a Kubernetes manager on Azure. Really exciting, but that's not the focus today. That's just the thing. I'm going to show you right at this piece on the portal, how I did that. The application that I'm going to use today, it's an application called Partium Metanomrp. If you, did you read this book? Who read it? Okay, I really, really encourage you people to read it if you're interested about DevOps practices. And the cool thing about that one is not a, I'm not going to say a growing book, it's a novel, so it's really fictions. But it's really fun because they have all the cliché inside in terms of DevOps practices, you know, the dev guys confronting all the time, the ops guy and so on and so on. That's really great. And from that, we developed this application called Partium Metanomrp, referencing to the book. This application, so it's public, it's only using open source technology. So it's Java based application, using running Tomcat, using MongoDB and so on, right? So if you go there on the link on the repo, Microsoft repo, it's kind of a monolithic application. And what I try and what I try to do here, what I'm going to try to do actually, is to split it into kind of microservices because it's trendy here. So we're going to try to do microservices from that and then deploy on DCOS and do DevOps practices around that, right? So this is what I said, we're going to try to do DevOps, DevOps everywhere, right? During this application. So obviously a CI, which is like, pretty much the base about DevOps practices, continuously integrating new features and make sure that it's built and works all the time. Then I put that here, another thing on Azure called ACR, Azure Container Registry. I don't know if you heard about that one. It just basically the ability to have a private registry for Docker image, pass base, right? On Azure, it's really simple. Again, few clicks and boom, you have it. What I'm going to try to do at the beginning and just use GitHub and then if you have time, we can implement that piece. It's really, really straightforward, you're going to see that. Then we're going to do CD, so try to deploy continuously on a cluster using VAMP. Did you already heard about that one, VAMP? It's pretty awesome actually. I discovered that one from the universe. So I just click sometimes on normally, I'm going to universe and catalog, click, deploy, see what's going on. So that was the one I discovered. I think it's really awesome, especially when you start with DCOS and Mezos in terms of networking and so on, especially for the CD piece when you want to do canary testing, happy testing and so on, that's really, really cool. So this is what I'm going to try and since we only have 45 minutes, it's going to help me, that tool is going to help me a lot to achieve that. And if you have time, yeah, telemetry, application insights and so on and so on. So wanting, it will be a live demo. I'm a huge fan of the office. I don't know if you know this series. So let's go. Let's start with fun. All right. So this is Azure. If you're the first time that you see Azure, Azure guys, guys, Azure, that's the portal. The cool thing with that, again, I'm not going to sell Azure. It's basically, and I'm going to be honest, it's the same thing that we provide in the same features that you can have on AWS or Google Cloud, right? With some extra, for sure, we have differentiation, which means with that everything that you can do from the portal you can do through the CLI. And so, yeah, that's a good question. So the question is the services that I'm going to show you right now, are there availability on all zones? Including Germany. Germany is a special one because Germany, we have a pretty nice story about that. That one is kind of silo for some legal purposes and so on. I'm not sure about that one. I can check later. Maybe Rob, you know, if you'd say, okay. I'm not sure that ACS is available because ACS, the services that introduce is at the beginning.  So I would say yes because it's just VMs with best practices installation of the frameworks or DCS on that case. But let me confirm that maybe after the conference. So yeah, that's the portal. What I did, like I said, I already done that piece because it can take like between 10 and 15 minutes to deploy the services. I do a search for ACS, right? Azure Container Services. And I click on that guy here, create. And then he's gonna ask me, remember Microsoft, we like to do have some interface click and so on. Here he's gonna ask me the name, how many nodes I want, how many masters, the size of the VMs that I want, how many CPUs and so on. It's really, really straightforward. Like, let's, I would say 10 question and then he's gonna deploy everything, right? So I already did that. And also at that set, he asked me for the public key, right, the SSH key that I want to deploy on my cluster. And after that, when it's done, this is what I have. So we're not gonna spend a lot of time on that. Like I said, it's just a bunch of resources on Azure, VM storage, networking and so on and so on. And when it's done, actually, the way that it's worked on Azure, you just have to do a SSH tunnel on the master, right? So I'm initiating a SSH connection on my master using my private key and doing a forwarding port on port 80. And when it's done, I can reach the portal, the DCOS portal from the localhost because I'm forwarding the port 80 on my master on my localhost, make sense? Now it's really straightforward. Like I said, it's a basic, basic cluster. I'm running five nodes on that one here, five node and one, a five private node and one on the public region. So our six node, totally, one master. And what we're gonna do first, just to make sure that everything works and because we're gonna use it, we're gonna deploy Jenkins, right? So I'm gonna use Jenkins as is, no configuration, don't need persistent storage and so on, just for the demos, right? So we're gonna wait that piece to deploy. In the meantime, I'm gonna show you the code that I'm gonna use. So the link that I paste on the slide at the beginning is the repo by itself with all the code, like the kind of the monolithic application by itself. What I also did before that, before that, sorry, I split it in two services. Like I said, we're gonna try to do microservices. We're gonna fake that, just two services. One for the web frontend, running Tomcat and just my, it's not Angular, but it's a whole framework, JavaScript framework. You're gonna see my UI skills, really beautiful UI skills, but it's just a way to underline some JavaScript, right? Print some screen and then the API. For the API, I'm using Spring from Java. That's my framework. So I created two different repo, right? The client one and the order one. I also have the database Mongo. That one is just a basic repo. Basically, it's just Docker file, right? And I'm injecting data on that one, feeding like mocking the database. When you run the Docker file, it's gonna inject like fake data on that, just to have data for the demo, right? But for that one, the Mongo, which is not the really goal of this talk, it just let's say a stateful piece. I'm gonna still run that on DCOS, right? But maybe there's a more better solution in terms of storage and maybe we're gonna use a past solution and so on. But just for the demo again, it's just a basic thing. We're gonna pretend that it's run and that's not the focus right now. Just gonna focus on the client and the API piece. Make sense? So that's the client repository. I'm gonna explain that after that and that's the other one. So back to the cluster here. Still deploying, which is weird. Don't like that. Oh, it's running, okay. So I have my Jenkins install. This is something that I like from DCOS. I'm using like a lot of Kubernetes and also Swamp, which is I'm really focused on containers technologies. And what I like with DCOS, it's really, really simple to start, right? Just push a button and at least you can do proof of concept and it's really easy to start, right? So we have a basic Jenkins instance here. Like you saw that. No thing fancy, no custom configuration on that, right? Like I said, we're gonna use VAMP. So for VAMP, if you go on the official documentation, VAMP.io and I think it's not on support. On developers, documentation, installation. And go on DCOS here. So it's gonna just explain how you can install VAMP. Or if you want, they also have a package, a universe package here. If you do a sort for VAMP, you can also VAMP and sell VAMP from there. I prefer to install from the official documentation. So basically what the documentation said, you have to run Elasticsearch. So it just gave you the marathon JSON file here. And then you can install VAMP from another JSON file. So what I did, I already prepared that. So that's a repo with all my script, all my, what I'm gonna do during this demo. So if people want to repose that at home, you're more than welcome to go on this repo. I'm gonna share the link after that. So inside the VAMP folder, I have just copy and paste from the official documentation, the Elasticsearch piece and the VAMP piece, right? So what I'm gonna do from the CLI here, I have the DCOS CLI installed. I think it should be already set up like authentication and so on and so on. What I'm gonna do, I'm gonna, oops, sorry. I'm gonna install the Elasticsearch piece. Oh, I changed the folder. Add, oops, add. There's a scan. VAMP. Okay, I'm gonna push that. So I create the deployment. So just to quickly make sure we have the services deploying and what are we gonna do? We're gonna do the same thing. We're gonna wait that one to run but we're gonna prepare here. Oh, actually also the thing on VAMP told you that you have the ability to store artifacts on VAMPs. So if you want to have the persistent state for the artifacts, you have to use MySQL database or I think they're supporting few of them like MySQL, Postgre and Microsoft SQL Server. What I'm gonna do also, it's supposed to work without it but I'm not gonna take a chance. Like I said, it's a live demo so I prefer to prepare everything. I'm gonna also install MySQL and let's be crazy, use the default one from the universe again. So that one's supposed to run, okay. So it's running here. That one is staging. All right, so we're gonna let him deploy actually. Okay, training. I want to start the deployment on VAMP also and I'm gonna expand also the code, the pipeline, the Jenkins pipeline that I'm gonna use. This is also something that I prepared before, the Jenkins file because it can take a while but I'm gonna explain it. Come on guys, I think it's running, right? I don't know why he say it's deploying. Yeah, it's running. It's just to have the, I think the L check. So let's deploy VAMP in the meantime. Here it's supposed to create a folder like a group and deploy a bunch of services. It's gonna deploy VAMP and then like it's a microservices application. So you have the get way, you have the workflow services and so on. So we're gonna see that after that. Okay, in the meantime, let me show you the codes for the Jenkins piece. So are you familiar with the pipeline on Jenkins? Yes, no? Okay, so if you're Jenkins, I guess, and I hope so using the pipeline which is an awesome feature actually. We used to have on Jenkins like the freestyle job. I think the name is correct for what it was, right? At the end of the day, if you have like different bunch of actions on your pipeline, like running tests, when you need testing integration tests, depends of the way that you want to deploy. It was different bunch of freestyle project and one column, the other one and so on and so on. And then since the Jenkins 2.0, I think the implement this thing called a pipeline. I like to call that like the CI as code, if I can say that. The ability to store the CI pipeline inside a file. So if using Travis for example, CircleCI and all those fancy guys, cloud-based, right? This is also the way that they work, which is very great. You just store everything, all the pipeline in the YAML file inside your repo and then when you're gonna push, it's gonna win this file and run step-by-step what you wanna write, right? Because at the end, the CI tool is just an orchestrator tools. You can say, okay, run this script first and then that one, that one, that one. Makes sense? So this is exactly how the pipeline works on Jenkins. So if I start with the API here, I don't know if you can see, yeah. So that's the code, right? Can show you. Not gonna lie here. If you go on source, main, because it was in Java, that means a lot of file everywhere. I have my controllers, model and so on. So that's really, really Java file. And if I'm gonna be back to the root here, I have this guy called the Jenkins files. And here what I'm gonna do, first I'm gonna add Jenkins to clone the repo on my node, right? Then I'm gonna run the build. So I'm gonna build the Docker image. I'm gonna push this image to, I'm using the public repository here, but if you have time, we can change to private one. So I'm gonna build and push the code. As you can see here, I'm not doing any tests. Good practices, right? But I will say maybe that one step before I want to run the unit test, right? Since I'm using Gradle to build, this is what I'm gonna do. This is what I'm doing inside, actually. To build the application, I have to run the Gradle build packaging stuff, right? But I will solve a switch for tests. But I'm not doing it here.  I'm doing sync command. You're gonna understand why. It's involve vamp at the end. And when I, basically I'm preparing some config file and when it's done, I'm gonna push those config file to the API of vamp, right? So I'm also preparing some other practices in terms of DevOps practices here. What are we gonna do? We're gonna do A-B testing. I don't know if you're familiar with that or can I be testing? So what I'm gonna do, I'm gonna push a code. So let's say my V1 code. And then let's say we have a high velocity. Maybe we're gonna push 10 times per days, which could be great. We are like Netflix or whatever. And let's say we're gonna go crazy, push 20, 30 times a day in my microservices. So I want to be able to do A-B testing. So maybe not go completely crazy and say I have a new version now. Let's already like 100% of my client or customer on this new version and see what's going on. Maybe it's not a good practices. So what are we gonna do? We're gonna easily, smoothly switch. So we're gonna keep the whole version. If I can say the current version, we're gonna de-plus the V-next version. So the version two. And thanks to vamp, we're gonna do load balancing. So we're gonna do A-B testing actually and smoothly redirect 20% of the traffic on the new services. Do some telemetry. Let's wait. And then apply to do 50, 50, 70, 30. And then 100% on my new deployment. Makes sense, right? Again, it's just for demo. Maybe in production you want to do smoothly. Here, what I'm gonna do, I'm gonna deploy, do 50, 50 and then 100. Boom. No time for go smoothly. But again, it's just for the demo that I'm doing that, right? So let's go back to DCOS here. So like I said, when you install vamp, because it's the way that it's code is to microservices also, it deploy a bunch of microservices, but the most important one is the vamp dashboard. It's that guy. So this is vamp, actually. What I'm gonna show you here, it's really like the straightforward usage of vamp. Actually I'm gonna use the API.  They have their own features, if I can say that. The blueprint, the bridge. So you can handle a lot of practices using only vamps. But me, what I'm gonna do, I'm gonna use the API. I'm just gonna call, as they call that, a deployment. So I'm gonna pass my new deployment all the time. So that's the seed command that you can see in the pipeline. This is what I'm gonna show you. So before that, what I can do, I can show you the basic hello world in vamp because I think it's interesting to know that. So what I'm gonna do here, I'm gonna add a deployment. So it's YAML base. So I'm gonna say here, I don't know if you can see in the back, that's correct. You want me to maybe to zoom. Is it good? Yeah, okay. So I'm gonna name my deployment. I'm gonna create like, they call that the cluster. So call hello world. I'm gonna, they call that the bridge. So a bridge is, let's say Docker image in my case, you can reuse this bridge for multiple deployment. Like I said, the way that it is deployed is really smart. When you're using that, it's gonna like split everything. It's like the gateway, they call that the gateway. So the way that you want to access the containers, it's called that the gateway. The bridge, it's like basically the artifacts that you want to deploy and so on and so on. Again, the documentation is really well done. But anyway, here I'm gonna deploy my hello world deployment. The deployable, which is the Docker image I want to deploy, it's geostrackr-webdebug. That's my own way to do my hello world, they said that. And then I'm gonna scale to those resources. And that guy gonna talk to DCOS and Mesos and it's gonna do all the magic for me, right? So I'm gonna save that, which means deploy. And also in the meantime, I'm gonna deploy as they call a gateway. So the gateway on vamp, it's just the way to handle the networking and also the AB testing stuff and so on.  Here I'm gonna use that service port inside my DCOS cluster. I'm gonna use a virtual host. So I have a custom DNS name called junior.work hosting on Godaddy. So it's here. On Godaddy I'm saying that the hello dash world, I want you to redirect on my virtual IP on Azure because I'm on Azure, right?  So I'm gonna reach my virtual IP for my node, my agent, my agent, right? And then vamp's gonna handle that. So basically that's kind of the Martin LB piece, right? And I'm gonna route that one to hello world, hello world. So remember on the deployment I have the name of the deployment, the cluster name, the web port so it's kind of, you have the indentation and so on. Again, it's really well explained on the documentation. And I'm gonna redirect everything 100% on the traffic on that deployment. Make sense? So I'm gonna save that guy here. So my deployment here is deploy. So if you go back on DCOS here, so you can see that my deployment dash hello world, whatever is running here. And let's see my gateway here. Also running with that virtual host. So actually let's try that guy here. And that's my hello world, right? So that's the basic, basic hello world running on them. Awesome GIF, right? Any question on that? No? Okay, I'm done. Thank you. No? Okay. Let me check the time, okay. So what I'm gonna do, I'm gonna remove my gateway. Gonna remove my deployment. Supposed to, okay. Because I like DevOps, that mean I like to automate everything, right? So now what I did manually, let's say that, copy and paste, new, et cetera, et cetera, what I want to do is kind of the same way, the same thing using Jenkins. On top of them, they have the API. So this is what I'm gonna use. And this is what I have at the bottom of my Jenkins files. So still, I didn't show you yet the ugly ML thing that I'm doing here.  But all the next step, the stage on Jenkins, it's using the VAMP API. I'm using the internal virtual IP inside my cluster. So this is on the default where VAMP is deployed. Using the API for each stuff that I wanna do, deployment, getaways, braid, et cetera, et cetera. Each feature I'm using inside, I can curl post or whatever I want to do using the API. And then I'm passing the YAML file. So the YAML piece that I show you, that I paste manually, this is what I'm doing here. This is what I'm playing with on my seat. So let me show you that inside the cluster now. So the first one I'm calling, it's PUMRPOrderDeploy.yaml. And I'm doing that twice, you can understand why. And then I have a getaway 50 and getaway 100. So like I said, it's really ugly, the way that I'm doing that. When I'm deploying, I'm doing 50-50 between the Vnex and the current one. And then 100, you can understand that. So basically I have a few files. So if I'm going back to my source folder, oh no, deploy folder here. This is where I'm hosting my file. So the first one that I'm playing with is that one. So it looks familiar, right? It's kind of the same structure that I use for the Hello World. But here what I'm doing, I'm going to tag my deployment here. Because not all the time, but it's going to happen that I'm going to have two deployments, right? The Vnex one and the current one because I want to load balance, right? So what I'm going to do, I'm going to use this ID tag. And this is the seed that I'm doing on my command line. So I'm going to do version one, version two. And then, so that's my first deployment. Let's say I want to deploy, I'm going to have two and three, three and four, four and five and so on and so on, right? And this ID tag is the one from Jenkins. So in the Jenkins files, you can call variables, right? Environmental variables. So I'm going to call the ID of the build that I'm running right now. Make sense? And then I'm just passing that all the way. So every time for the Docker image, so I'm going to build the Docker image and push with the tag of the build, right? So version one, the name of the image is going to be Docker build dash t, party limit LMRP comma one and so on, two, three, four. I'm going to push and this is the one again I'm going to pull on my cluster. Make sense? So that's the deployment by itself. Something. Also something here. It's more related about the Docker image by itself but I'm using one environment variable to the FQDN of the Mongo database. And that's actually a good reminder. I have to deploy the Mongo database. So what I'm going to do, since it's not really the focus of the talk, I'm going to deploy my Mongo database manually because I don't want to develop on that one for now. So it's a basic, basic, like I said, basic deployment. The only thing that I'm calling is my custom image but like I said, if you can go on the Docker file, it's calling the official MongoDB image but what I'm doing differently I just injecting, where did it start? I'm starting the demo and injecting like, I'm feeding the database with some data, right? This is the only thing that I'm doing. And I'm exposing on the cluster the default port of the Mongo database. And because it's going to be on the PUMRP database folder or group and the name of the container is also PUMRP database, this is why it's hard-coded, I know. But this is why here I'm calling that one. I'm using the internal load balancer, right? To reach my database. Make sense? All right. And then comes the gateway. So the 50-50 what I'm doing, still using the tag, right, on my build. I'm redirecting 50% of my traffic on the current version. So this is why you have the pre-tag and the ID tag. This is the two variables I'm using. The pre-tag is the previous version. It's the current version minus one. So if it's build number 10 is going to be nine, right? And the ID tag is the current version or the current ID of the build. Make sense? Actually I'm going to run that right now. You're going to understand. So what I'm going to do, I'm just going to copy the URL of my repo here and I'm going to go on Jenkins here. So I'm going to create a new item. Like I said, I'm going to use a pipeline project. So I'm going to call that one order API. It's a free start pipeline project. Sorry.  The Jenkins file from this repository. Since it's public, I don't have to provide any credential, right? But if you want to use a private registry, you can do it. I don't have to change that one because it's the name of the file I'm using. Also what I did or what I have to do actually, back on my Jenkins file here. As you can see, so I'm building, but when I'm going to push my image, I need credential, right? It's not anonymous. I cannot push the image on the Docker Hub like this. So I'm using the credential or vault from Jenkins. So I'm going to create, I have to do that before. I'm going to create a credential called Docker Hub. So to do that, go on credential sections. I'm going to say here I want to add credentials. I just have to use the same ID. So this is my Docker Hub username. And that way, Jenkins is going to be able to grab and use those key, right? So now I have that guy. I'm going to start the build. So the way that Jenkins works on Mesos is pretty awesome. You have the master running our containers and every time I'm going to launch a new build, it's going to trigger Mesos task, run the build inside it. So that's why the first time is going to take a while because it's going to boot, or not boot, but create the containers, pull the, for the first time the Jenkins slave image and then run everything. So build the image, pull the official Tomcat image. You can, if you're curious, you can go on the repo see my Docker file. Again, it's from the official image. So that one is Tomcat or GDK, I don't remember. So it's pretty heavy because each other is going to download everything, build my image, push to the Docker Hub. And then inside my pipeline, I also add some validation step here because I'm asking the input. So I don't want to do everything like one shot, 50, 50, 100 and so on. You're going to ask me before, are you ready to do the next step? So it's going to deploy until that stage. So it's going to deploy to my cluster. And the cool thing with the gateway that I show you actually, you're going to see that, it's going to deploy my deployment. So it's going to deploy my API in that case. And it's going to create the gateway, but the gateway, you're not going to touch the gateway until it's going to ask me, do you approve the deployment? That means the gateway is still redirect to the old deployment, right? When I'm going to say, okay, I'm ready to have the 50, 50, then it's going to do the 50, 50 load balancing, right? And so on for the 100. I can still roll back if I want. So it's supposed to build. So also in the meantime, I'm going to deploy my, yeah. So that one's going to take a while because again, you have to pull for the first time the official, not a while, I would say like two minutes, but still. What I can do, I can create another pipeline for my client, right? So I'm going to call this client here. So the client here is not the same repo, is that one? Same process from Git and save. And it's crazy. I think I clicked, yeah, clicked. Okay, let's see if at least we have logs. Makes sense, yeah. And then he's also building the image inside the container, right? Maybe not the best practices, but I can say it's demo-wise. So any question at that step? No? Okay. Okay, so the build is done. Now he's pushing. So what I can do just to show you here, you can see, I don't know if you can see well, but he pushed with the tag one, because again he's reading like the environment variable from Jenkins, right? He's the first deployment here. So it's going to be one. So because I need two deployment to do load balancing, right? What I'm going to do right after that, I'm going to kick off another release to have one and two because in that way, we're not going to have the two deployment to do the 50-50 deployment, right? So the first one is kind of fake, but in production, you're supposed to have the old version or the current version and then push the new version all the time, right? Because here I start from scratch. I'm going to need at least two deployment. So this is why I'm going to wait that one to be done. So it pushed and I'm going to, so let's forget about that. You didn't see that one, right? Okay, and we're going to rebuild the new one. Okay, perfect. So what he did, he just deployed the first one with the tag number one. Like I said, we're going to need at least two to have the 50-50 deployment, right? So he's deploying the first image order. He created the gateway with the URL that I want, the virtual host. So this is also something that I specify in the gateway if you remember, like the Hello World, right? So here what I'm going to use is api.pumrp.julian.work like my custom DNS name, but you can use your own. And for the client, for the web frontend, it's going to be the same thing but without the api on the front, right? So I'm exposing the api publicly and also the web frontend on that case. So what I'm going to do, I'm supposed to be able to do that actually, just to make sure that it works. So yeah, if I'm going on that route, the dash orders is going to reach just a good way to try and test the connection between the api and the MongoDB inside my cluster, right? So I know that this route orders I have another one for code, so you can understand why because the application by itself, it's like kind of e-commerce solution, really light. So basically I'm creating new orders in my database. I can delete, I can update and so on, right? Reaching the MongoDB database. So that's the api, the good thing it's accessible from the outside, that's great. So let's see where the frontend now is. Here's, same thing. So he's asking me for that thing here. So it's deployed and again I'm gonna kick a new one, perfect. So same thing here. The client should be P-U-M-R-P, good demo. Or maybe because the route is not, should be okay. Come on, client should be okay. Let's try with another, the awesome Safari brother. Just the cache I guess, anyway. So just to show you the UI. So that's like I said, awesome UI skill from Julien. That's my application, I have something on the left here. You can see I can reach the dealers, can do codes. You can see I have some font issues. But supposed to be add, edit, remove like the basic crud stuff, right? And everything is back on the MongoDB database, right? As you can see, I have dealers, code, orders, delivery, some settings, settings have nothing. So I open for pull request if you want. And behind the scene again is my API, right? So now if I'm on the DevOps workflow, maybe it could be fun to, on the process I would say, okay, I'm gonna add a new route because I want to have a new feature. So I want to be able to add, for example, a way to browse the catalog, for example, see all the things that we can order online. So I would say, maybe here I want a new button called catalog and then it's gonna be the same way that I code the application. It's gonna reach a special route on my API. I can do a get, a post, delete everything, right? And that mean I'm gonna need a new space on my database to store everything. A new route and a new button on my web, right? So let's do that. Actually, let's uncomment the code. Yeah, I'm okay to do live demo, but not live code. Come on. So on the order API. So let's say on the, again, the database is not the focus for this talk. Let's on the order API. What I'm gonna do on the code is gonna be really, really ugly because I'm gonna do that to the GitHub web interface. So I have this catalog controller here. So as you can see, it's commented. So what I'm gonna do, I'm gonna edit this file and yeah, beautiful, right? And let's say add catalog route. So this is what I'm gonna do. Straight to the master, boom. Really DevOps. So in the best practices, yeah, branch strategy, branch policies, even on my Jenkins, I didn't implement that but you also have the ability to trigger from new pull requests or new commits. So I'm gonna just do and continue that guy here. And then we're gonna build a new, okay. So let's say we have the, wow, we have the CI implemented and the CD. So that guy is gonna kick off automatically, right? Because it detects a new commit from my repo. So again, it's gonna build a new code, push. And this is where it's gonna be interesting, right? Sends to the gateway and everything. Here I'm doing that only on the API, right? So that means on the UI, no impact on the UI. I'm just gonna add a route. So it's a good way to test behind the scene, right? So that means I'm gonna be able to do API.Pure, I mean the FUDN, WAC catalog. This is what I implemented. Again, nothing on the UI. That means the end user not supposed to know that, not supposed to use this feature, but it's a good way to smoothly deploy my new version of my code, right? So also in the meantime, what I'm gonna do, I'm gonna also implement on the web the same thing. So it's, okay, it's here. So on the web, same thing, I'm gonna uncomment that guy here, which is the button for the catalog. And also here, this is the button on the left. And that guy is gonna read and use the API, right? So catalog, again, straight to the master. That'd be crazy. All right. So in the meantime, what I can do, and also that's the beauty of the gateway, I can start to say here, so let me finish that piece. I can start to build, deploy on VAMP. I mean deploy and run that on my DCOS cluster. And still because I'm using the gateway, you remember when he asked me, are you sure to go on the next step, right? We want to confirm that. This is the way he's gonna actually redirect my end user. Before that, there is no impact for the user since it's a lot balancing stuff, right? I'm deploying and running my both application, the current one, and the new one that I just modified here. That means I can still do internal tests if I want. On VAMP, I didn't talk about that, but you can do canary testing and flag, for example, adding some HTTP headers and say only the, I don't know, those user with this IP or this user agent can reach my application, which is really great to do canary testing. So a bunch of different ways to test and try. So let's try that here with the other API. So it's deployed in the cluster. That means here on the deployment, I have PU, MRP, order two and the three, which is still deploying, but it's gonna be deployed. And my gateway behind that, it's that one, the PU, MRP API, and that one, it's redirecting 100% of the time here, as you can see. Sorry, here, I don't know if you can see well, but only on the two, right? When I'm gonna push the button to go ahead, deploy, it's gonna switch the two and the three and I'll direct 50, 50 on both of them. And this is where you have the, I mean the impact for the user, right? But before that, just to make sure that I don't have the catalog route, what I can do here, actually I'm gonna use Postman, because Postman, I think I have no cash with Postman. Yep, here. So if I'm doing ping, that's a root code. I know that I have data, so just to make sure. So catalog, I have no found, so I have a 404 Euro written by Spring. So now let's say I want to do the 50, 50 deployment. Let's do proceed, so it's done. So if I'm going back to gateway here on my API, as you can see we have 50, 50. That means here, without any logic, okay, I should have 50, 50. So I have data and 50% of the time. And again, the cool thing here, I'm not impacting my user because we didn't touch to the client here, the web, right? So if I'm refreshing that guy here, I have nothing here, until I'm pressing the button. Again, right? So let's do that for, and let's do move full, actually. Let's do 100% of the Vnex or the new version to implement the API. And the last step here is just to make sure that remove the version two for the previous version on my VAMP to don't have like 10 different deployment on my cluster running at the same time. And go back to the client here. Here, let's say, okay, I want a 50, 50. Same concept, right? The gateway, 50, 50. So if I'm refreshing here, I know that I have to do clear story here. Let's try. Oh, I have the catalog here. So still a bug here. And I have my catalog here. And again, that one, because the API is 100% of the timer direct to my API, is supposed to work. But again, user agent, custom flags, can always testing could be implemented here. That means we can do really, really, really DevOps fun stuff here. And again, let's do, I'm agree with that. Let's do proceed here. And it's gonna switch 100% of our traffic on my getways. So, no time left, unfortunately. What I can offer you, if you're gonna download my slide, I don't know if it's too late to update it. But anyway, if you got my repo, I'm gonna just show you that here on my GitHub repo story. I'm gonna create like, I already did that, actually. This repo called democonf. You should be able to see all the, if you want to reproduce the demo, all the code is open-sourced. If you want to retry at home and so on. And I'm gonna also paste a video. I'm gonna record the video with that plus the different practices like the telemetry. I didn't talk about that and so on, so on. If you want to go further on that. So sorry, we don't have time for question, I guess. But if you have question, let me know. I mean, I'm just gonna be around. I'm gonna have another talk tomorrow about auto scaling on DCOS and mesas. Thank you very much for your time.