Laravel's secret weapon: macros (watch me code)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this this is going to be a little bit of a different video this is going to be uh kind of like watch me figure stuff out code along with me uh a few twists and turns probably I was I was working on my personal website not too long ago and I was mucking around with macros and stuff in the container and I thought this is I think this is kind of interesting and so what I'm going to show you here is the power of laravel's macro trait the container and the fact that you can figure anything out I think that's the most important thing that I want to tell you is you can just go look in the source code documentation is wonderful and amazing but you can also just dive into the source code and figure out how to do something so this is going to be a little bit uh a little bit out there I don't know if I would necessarily recommend exactly what I'm about to do but why not it's my own personal website I can do whatever I want so let me show you what we're working with here this is my website right here this is what we're going for um I've got an article here called what if you tried hard that just lives on Aaron francis.com and if you click on it it just takes you Aaron francis.com pretty basic I've got an article here that lives on github.com and if you click on it it takes you directly to github.com so I've got this concept of internal articles and external articles no problems so far but let's take a look over here and say that an internal article is an article where not null markdown file so everything's driven from markdown so if there's a markdown file then that's an internal article and we'll say that an external article is an article where null and here is where it gets tricky so if I were to return um let's just say let's just dump out route article. show of internal that should be okay okay so if I dump that out you see Aaron francis.com doest what if you tried hard good enough now if I route to the external it makes up this URL that that simply doesn't exist because it should it should link out to github.com or in this case planetscale decom not to Aaron francis.com all right so you see the problem right I just want to call rout article. show and pass the article in and have the UR I'll end up correct but larel doesn't support this out of the box that's fine we don't need to go on Twitter and complain we don't need to ask a bunch of questions we can just figure it out ourselves let's see how we do that all right I am first going to command click into route to see how this routing helper works it looks like it defers to something called app URL route and I can't click on that because I don't have laravel idea I think is what it's called installed so what I'm going to do is I'm just going to I'm just going to dump it out and we'll see that we have a URL generator so now if I come over here and I paste that in url generator now we're in here and if we look back at the helper this is the URL generator part the um the URL generator is bound into the Container under this Alias of URL so we need to look at the route method on that URL generator uh if I can spell it correctly we go down to Route there we go so this is let's confirm this is uh this is this is gold right here you always just put a DD here that's that's what you that's how you debug these things so now if we all right we're on the right track going back to the URL generator this is where I start to look in and think is there anywhere that I can hook in is there anywhere that I can um effect change from the outside so looks like this does a get route by name I think we'll probably end up in here yep we're in there and so then it defers to this two route so let's go down to two route and I think we should be we should be in here now yes we are so then this does a bunch of different stuff and then down here so this is uh collecting up the parameters resolving route model binding it's doing a bunch of stuff here so if I then dump out parameters down here what do we have we've got that article okay that makes enough sense then this defers even further to route URL 2 so if we click in on two we are now in this route URL generator class so we're we're several levels deep at this point and this is where it actually Yep this is where it actually there we go route Ur URL generator 108 so this is where that URL actually gets generated it looks like it does some query string stuff it does the domain here all right usually larel gives us a place to hook in whether that's some sort of static configuration method or something in the container or some some sort of optional method on the object that's being passed around I don't see that here I don't see that anywh here it looks like um there's nowhere to hook into there's nothing uh that is called on the actual route itself and so there's nowhere that we can sneak in uh and modify this Behavior so I think the question is where does this route URL generator this class here can we decorate it extend it hook it somehow so if we go back out here and we come down come back out here you'll see this route URL 2 so if we command click on this well shoot that's nuded up right here so it's not even pulled out of the container it's actually just a new class that's being instantiated so we can't override anything in the container here we're going to have to figure out a little bit more of a Brute Force slacky way to do this because that route URL generator is Ned up inside the class instead of being pulled out of the container we can't really touch that so we're going to go up a level and look at the URL generator so we're in this URL generator class and we know that this gets resolved out of the container so if we hop over to the app service provider we can say this app extend and we will just extend the URL we can actually just extend URL and if we come in here this should be an instance of URL gener and if we dump this out hopefully we'll have access to that so now we have access to the URL generator that is bound in the container and we can we can kind of we can kind of do whatever we want now this is where we're going to go off the beaten path a little bit I think the most proper pattern friendly solid design principles way to do this would be return a new URL decorator and pass the Gen generator in and you know sorry I just I don't want to do that my goal here is to never tell you exactly what you need to be doing but more kind of show you how I do stuff and hopefully teach you how to think about things yourself I don't want to do this you may want to use a decorator that's fine I don't like decorators because then you have to proxy everything and then anywhere where URL generator is hinted and you pass URL decorator you're hosted so I'm going to do it a different way my site my video I'm going to do it a different way you don't have to do it this way but it is kind of interesting so what I'm going to do is I'm going to return my own URL generator so let's come out here and let's create a custom custom URL generator and what I'm going to do is say that that extends laravel's URL generator okay so now if I come back here we can return new URL new custom URL generator and you see the problem now we have to pass through the Constructor args so if we come over to the Constructor we see that these arguments are passed in and they're set and are they protected bummer so we don't have access to those from the outside but look URL generator is macro one of the greatest things that larel has ever done is make almost every class macro so you can add methods from the outside so let's do something a little bit verboten which I think means bad I'm not entirely sure uh URL generator macro get Constructor this is wild I bet people do not like this get Constructor args return so what are the Constructor args I think it's this routes this uh request in this asset route this refers to URL generator so now we're inside that URL generator instance and even though it's protected we have access to that so routes request and asset route let's just make sure that that's right routes request and asset route routes asset route and request so we are good to go so now inside of here we can spread that out and say generator I'm just going to copy and paste get Constructor args and now we should we should have there we go we're working again we it is it is working again but now importantly we are using our custom URL generator which means we've got the hooks we can do whatever we want so let's do something that we want to do um what did we want to do I think we wanted Tock about with route that was probably let's do two route so if we take two route and we come back to our custom URL generator public function to Route yep yep yep and we'll do the classic aha we win we're in now let's take a look at what route actually is Route is illuminate routing route okay where where is that come from so we've got the article URI do we have parameters yet we don't have parameters yet um so where do those parameters yep yep yep we don't have parameters yet on the route but do we have parameters here we do so we have the article we have the route we're in good shape now what you could do here what we could easily do here is we could say if route um easily easily and then I can't even do it what is how do we get the name of this route it's probably routing route so let's go ahead and hint this just for now routing route and then we say uh name get name all right so does that give us article doow so we could do this I don't like this I don't like this you may like it and that's fine you do you article. show then uh we could do that okay and we could say uh if we're in here all right so if parameters instance of article then okay we could say if parameters um if let's say is null parameters which is now article if isnull parameters uh what's it called markdown file boy you can see why I don't like this return just uh parameters I think it's called external URL um I messed something there we go there we go that would work that would absolutely work so if we go back to our web you see and we can do internal and external it works it totally works we have an internal article routing internally and we have an external article routing externally this is good ah this is not great this is not great we let's make it great we always want to make it great so this right here is nonsense this is way too specific to that route so we're going to comment that out and what we're going to do instead is we're going to look at this route here um actually we can go to route down here this is the actual uh route object and yes it is macro so we can add a CL or a a method to that right here so let's say um it's actually this guy this guy so we can say what do we want to call this we can add any sort of uh any sort of method that we want let's say um generate routes using NOP not routes that seems bad generate URLs using and we can pass through a function that accepts an article that seems cool um and then we can say if well let's just go back to our let's just go back here um yes yes yes let's take that guy come out here um if well we don't need that this is now called article and generate URLs using this function function that accepts an article let's simplify fqn if it's null if the markdown file is null return the external URL otherwise return null and that's going to be our signal that we just want to fall through to laravel's uh laravel's routing so if we come back to custom isn't this fun this is why programming is so fun you can do whatever you want let's carry on all right so we're back over here this is not going to work anymore going to blow up in a couple different ways generate URLs using doesn't exist you're gosh darn right it doesn't if we come back to the app service provider and we do another little macro route macro generate URLs using function whoops function and I think this is the call back um or maybe callable I don't really know yes so that is the closure that we passed to that madeup function earlier um so now what do we do now where do we put this call back well I've got an idea let's come over here and say um I don't know um we can make a weak map we could say um public well let's just make it protected for Giggles weak map um generators does that work okay so we're still good so far and then let's do public function add let's make this oo yeah yeah yeah yeah yeah yeah yeah yep yep yep static function add generator I think callable no call back yes and Route and I think this should be yep that should be a route and then if we say DD here excited about it we can come in here and say custom URL generator add generator for this with call back hooray and did we get everything we needed over here so route and call back hooray great this is going really well honestly I thought this was going to go a lot worse okay so now in the week map if I can remember how to use weak Maps whatsoever um static generators offset set route callback did that do anything must not be accessed before initialization God I hate it when that happens it is an easy fix though so I can say um I can say static generators I think it's question question equals new week map so that's going to that's going to set it if it doesn't exist and ignore it if it does and I think this can actually just be uh array syntax I think that should work okay so we're back on track what we have done here is instead of just using an array we've used a weak map and that will allow us to set an object as the key um and it won't it won't hang on to it if if it should be garbage collected it'll let it go but it does it does allow you to set an object as a key which in this case is pretty important now the fun stuff let's come down here and say if if what if what um if static generators offset exists if the route exists then let's see if that works hooray so we have registered a call back for that route and we'll say that URL equals call user Funk uh this guy um we can at this point we know it exists so we can just call it like that call user Funk and what do we need to pass through we probably need to pass through the parameters just like that and I think we probably oh I don't know that they're guaranteed to be an array there so if we come out here null that didn't work but did our did our call back get called DD call back call back got called did it get called with an article it got called with an article um so I think it's probably because it's that guy so um I just want to Route the external one right now whoa there we go hey look at that there is the pl scale.com blog so what has actually happened in this custom URL generator we said we're going to extend this two route function and in that function we're going to see if this route has registered a custom URL generator if it has registered a custom URL generator we're going to defer to that generator and pass through the parameters now if this generator returns null we want to fall through we want to fall through to this part down here so we can just say if not is null URL return URL and that way it should still fall through for the internal so that external one works let's go back for intern internal and see if that one works internal custom URL generator we did it we freaking did it we have external URLs internal URLs everybody's routed to the same spot I like this because it keeps it all together so it's not shoved off into some corner of the custom URL generator it's right here this is how you generate URLs for this route um I like that I can just I don't have to do any sort of checking to see if it's internal or external throughout the rest of my site I can just say give me the route to that article and it's going to give me the exact correct route whether it's internal or external there are a few things that we're going to clean up here in a second but first importantly you don't have to like this you don't have to like this if you hate everything that I have done here that's okay I'm okay with that you don't actually have to tell me that but I'm okay with that I think the thing that I want you to take away from this is that you can figure anything out you can figure anything out and you can make laravel do anything you want it to do no matter how bizarre or wacky or hacky it might be in the real world I would probably add a single test for this and move on because if they changed the URL generator a bunch of my stuff is going to change I know that I'm honestly I'm not going to add a test this is this is my personal website the stakes are very low this is pleasing to me so I'm just going to leave it as is let's clean up a little bit of stuff while you think about all the things that you want to do in your app okay I think the only thing I want to clean up here is this feels a little this feels a little bit messy to me I think what I want to do is say URL equals null and then get rid of that and then just say yeah we can get rid of that comment thank you very much and then say URL well I think that should do it and also for completeness we need to pass all of the parameters in there so I think that gives me everything that I want yep that gives me everything that I want and it's a little bit cleaner and it still accepts all of the parameters that laravel is giving to us that's it hopefully you feel confident that you can explore and figure out anything that you need to do if you want to see more of these more loose form videos let me know in the comments below if you want to watch a video on how I generate selfhealing URLs that are guaranteed to work forever I'll put that video on the screen here until the next time see you
Info
Channel: Aaron Francis
Views: 19,435
Rating: undefined out of 5
Keywords:
Id: G78sN4_KEdU
Channel Id: undefined
Length: 23min 46sec (1426 seconds)
Published: Fri May 03 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.