 All right, so I guess I won't walk around normally. I like to walk around because I think it's Who wants to sit in a class and just watch someone drone on about programming, you know Let's see. I will play this now. Yeah, I hope it's gonna be really hard You might have to remind me to like not walk around too much Right, so I'm I'm Ben Marks. I Am from the States. I'm here sort of by way of Europe And I work for Magento Here's my contact information if you get nothing else out of this presentation at least that will be something useful What I like to do is I Like to hear from people who are working with our system because now that we have Magento 2 out it's the developer feedback is Well, it's it's actually essential to Sort of adjusting in the early stage of release and making sure that we have something that people are happy to use right and So we regularly get feedback from people we regularly get feedback from the developers working with Magento and where we are currently currently in a big process of making some updates to to Magento 2 which was released last November and and That contact information is one of the ways to give us feedback So as was mentioned in the introduction I Started so I started out in 2008 working with Magento 1 but working for an agency I was just the very first employee of that agency blue acorn and Blue acorn is now one of the preeminent Magento agencies in the world I'm proud to say so I was a developer there for for years and eventually moved into director of development position I also at the same time was doing some training for Magento you so after a few years of Magento 1 being out Magento kind of said hey, we should probably offer education And I was lucky enough to be one of the one of the first two instructors For for Magento you so I've so the class that I was teaching mostly was the fundamentals of development There's there's some videos online from that series and Yeah, I've Taught that I think about 40 times. It's about 40 weeks of my life that I spent in classrooms with developers And now I serve as Magento's evangelists, which basically just means I'm going around and going to all the events and meeting Wonderful people like you all speaking of which How many of you are How many of you are currently working with Magento for the record one hand has gone up. Okay Wow, okay, so everyone is brand new to Magento that's That's always a challenge because so when Magento 1 Magento is just full of its own little interesting conventions and When we made Magento 2 we really added some new conventions and we held on to some of the old So I kind of have to speak sometimes I have to speak a little differently if I'm speaking with someone who is brand new to Magento or You know someone who's kind of coming at Magento 2 from a Magento 1 perspective Magento 1 has a is now in long-term support and will will actually be We will stop supporting it in 2018 so these days People are really starting to jump over to Magento 2 And the nice thing about that is that it's been Magento 2 is as you know, it's replacing It's replacing an application that was created essentially in 2007 right so if you think about where for Magento 1 context if you think about where We're programming and e-commerce have gone since you know 2007 to now That's why we had to come out with Magento 2 All right, I'm still actively resisting the urge to just jump up and walk around So Magento 2 a quick snapshot is It's open source right so the the source is actually we we openly develop we post that development on a github and We interact with our Huge worldwide community of developers. I don't know that we've quantified it But you know there are thousands and thousands and thousands of magenta developers and it's a very rich community You can you can go most places and find someone doing Magento stuff So Magento comes in well it comes now it comes in three flavors, but but but two are Two are something that you would download as an archive We have our community edition and then we have an enterprise edition, which is essentially the community edition plus More right just plus some additional functionality In terms of like commercial features as well as enhanced scalability Etc. We also have a platform as a service offering now called the enterprise cloud and That actually does use the exact same enterprise edition code base, but we just handle all the infrastructure for you Magento you should know is it's is and this goes for Magento 1 and Magento 2 one of the one of the most important things to understand right off the bat is that Magento is Its own PHP MVC framework That PHP MVC framework is used to build the commercial application so in Magento 1 there's actually a I think it's called like Magento light or mage light or something Where someone actually took all of the e-commerce stuff out of the Magento package and just made it a General PHP MVC framework or what was left was a general and PHP MVC framework So that same script was followed for Magento 2 Although in Magento 2 it's a much it's it's much more Elegant of a distinction because we were able to use Composer and and truly abstract the framework completely away from all of the commercial code So as part of our updates for Magento 2 we we string the entire system together with Composer We follow PSRs one two three and four although you'll notice there is an asterisk on two and that's because we have some style violations They're they're noted. I think in the in the dock blocks, but For and and it's silly. It's just silly things like like protected properties begin with an underscore, right? That's that's I don't I don't think that's actually 100% proscribed by PSR 2 but it's one of those things. We'd like to change but in order to change that it's a breaking change So we'll have to wait to a later date Another thing to understand by way. This is like the only slide like this. Everything else is get down and get dirty the Another thing to understand is that there are two versions in to two version numbers which apply to Magento 2 We have the marketing version and that's where we say things That's that's how we talk about Magento with merchants. We say hey Magento 2.2 features these awesome new abilities now underneath and in between those you know those marketing releases we have regular updates to the framework and There's a separate version that follows that that actually obeys follows semantic versioning So if you're working with composers of your PHP developer, you're working with composer essentially semantic versioning just has very specific rules about What you can about how version numbers work? So essentially if you you have a version number like 100 dot 0 dot 1 That's basically a patch level release for the major version 100 and If you have some kind of some kind of backwards incompatible change you then have to increment that major number And so what this does is this allows us to actually make some some changes to the underlying framework that that that might be backwards incompatible and Not have to call it Magento 3 because our marketing department wouldn't be happy with that Magenta 2 is a it's a big application There is a lot of stuff going on. It's it's highly configured. There's a lot of explicit configuration And there's a lot of there's a lot of sort of meta Level work that the that the applications doing so as a result we have to heavily cash it For a lot of the e-commerce data. We have to index that and we even actually include out of the box native full-page cache Via varnish and then we have an entire like UI component framework where if you have if you just need If you're just updating a view with data That actually is is is a pretty terse communication And it and it just works because all you're exchanging with the server once once the browser has downloaded the rendering You know the templating code the first time or a template markup Then communication between the browser and server after that point is just about the data Magenta 2 if you've if you've heard about Magento 1 one of the one of the complaints that I've been hearing like literally at every PHP conference since 2013 when I started going to PHP conferences Was that Magento is untestable? Why is it untestable? It uses a God class etc. Etc. And it's just because Magento was was created in 2007 and not many people were testing their apps in PHP in 2007 right this this class or this tutorial is Woefully insufficient to turn you into You know someone who can walk in tomorrow into an office and get a job as a Magento developer And that's just because there's a there's a good bit to learn I've seen really good developers I've hired really good good, especially Java developers who can who can Get acquainted with with the framework conventions within a week and can can It can really understand the Magento's commerce domain modeling and operations within a month and and I say Java particularly because Magento is definitely taking takes a lot of the the pages out of the playbook of like Java like a spring Yeah, any questions for that brief little introduction into Magenta 2 who here has already installed Magenta 2 Okay, that's one hands gone up All right, so I wanted to do this first so that if you want to try I'm assuming Amazon are awesome sponsors I'm assuming Amazon Has a decent connection here in the office So it can be a bit heavy to to download To get to get going One of the best ways to get up and running absolutely recommend it if you can is is by using Vagrant or Docker If you want to install Magenta 2 the the basic way of doing this You can use you can just call composer create project and we actually host our own saddus instance with At repo that Magento comm and we do that because we have an extension marketplace We actually have an app store that ties in your purchases with our repository So that line right there will be enough To get you going You can also if you want to you can also work with Magento Just by cloning our repository And I've got the basic that's not a 100% correct command right there But if if you just go to GitHub you can get the repo URL And clone it That is actually what you want to do if you want to just kind of keep track of the latest changes And if you want to like contribute to to to our development, right? So we do accept pull requests And and all you have to do is when you do a pull request you do it against the developer branch However, the caveat there is if you're working with our developer branch You have to understand that that is don't don't put that in production. It's developer, right? It's so it's it's it's going to be unstable And we do have tag releases there that you can work with as well We also offer a sample data package and and anyone who Anyone who has been developing with Magento one could tell you that sample data was a little curious You know for for Magento one Magento two we actually have a we have a nice little command line script It's been Magento just been relative to the application route and it has just comes with a lot of commands If you are doing modern PHP development, probably you have seen this kind of command line interface before It's it's we use symphony symphonies excellent command line components for that Facto No, don't I will show you There we go, so here's so if I just call Ben Magento here So I'm using I'm using a popular vagrant image for this Vagrant setup for this and you can see there are There are a lot of commands. You don't need to actually be able to read these but this is a nice extendable It's a nice extendable interface, right? So it's not just for our functionality We build everything as you know as modular as possible And so it's possible like if you have a if you want to create a module And your module has maybe some developer level stuff that it needs that might need to be doing You can provide very easily a command line interface Option here, okay, let's see And so one of those commands the sample data That'll allow you to actually deploy the application I'm sorry, but deploy sample data into your installation And then all you have to do after you do that is just run run the upgrade facility and that will what that does For those of you who want to get started with magenta to development is it is it pre-populates a ton of data? So magento has a massively a massive number of tables And just putting in putting in data to make the application look, you know, like a working store It can be actually take quite a while to mock up, you know The the products and customers and orders and all these things and sample data does that for you So it's a really great way just to have a local working installation that you can then develop against and Kind of with with a feel for what this looks like in in a production environment Now so for your development preparation There are people who are just have a, you know, fantastic vim Setup there are people with fantastic emacs setup. Although those people are always weird. I'm sorry I worked I hired one of them. He is great. But man, he was he was It's emacs, you know But so I but but you have to have a you have to have a setup that allows you to navigate the code quickly And and I have to say for php development these days, especially for magenta development php storm is is highly recommended because Well for one for the as a product php storm jetbrains really they release fast and furious, right? So they they are constantly updating that that offering It kind of puts Everything at your fingertips A lot of the tasks that you need to do are as simple usually as like alt enter And the and the ide just kind of knows what you need to do by context refactoring tools lots of other tools are Are sort of are there for you if you're using something like php storm and then of course a good step debugger Everyone here are you who's using who uses a step debugger regularly in php development? only wow, okay, only hand so I'll do a little demo and show you how this how it works Because it's it's it's awesome and when you think about an application like magento. It's got I don't know million lines of code or whatever like You need to be able that that's a really deep call stack, right? So you need to be able to Jump through and find out what's going on and in our current state with magenta 2 I will say there are a few places where You get these wonderful exceptions like, you know like invalid file Which doesn't really help you when there are thousands of files So When you are creating your installation Let's see how I want to do this when you are when you're so when you're thinking about a working setup I'll suggest that there are There are a few options at your disposal The community our community which I mentioned earlier is Fantastic the the open source spirit if you're not aware that the open source spirit is It's It is realized Profoundly in the magenta world So what you'll find is you will find some of the biggest agencies putting some of the stuff that they have spent You know hundreds of hours developing internal tools. They'll put that online And they will share it for free You know mit license with the rest of the world Um and just simply because that's how it is The number of hackathons that I get to attend that are organized by our community amazing There is an entire business a nonprofit in germany That we now partner with they put on 25 events this year So I'm in jakarta next week The end of this Yeah next week I'm in jakarta next week Attending a conference that that someone has organized and it's called meet magento indonesia, right? We don't organize those someone else does I just show up That's the kind of community that we have And in that in that spirit a lot of people have figured out Have figured out a great way for you to get going using vagrant using docker if you want actually I can recommend I can recommend let's see here Though the the instance that I'm using right now It's actually tracking a little bit behind because it's like 2.0.4. I think is mage to vagrant So if I do There we go So this one right here The read me is all you need to get going and if and all you have to do is just set up vagrant in your You know download install vagrant And then a couple of commands and you're up and running and the nice thing is especially if you're if you're handling You're doing work if you have clients and they're on like php 5 whatever For magenta 2 you really should be you really should be running php 7 Magenta 2 is made for it and the the the the speed benefits help a lot during development So that is if in fact if you want to try and follow along in this class If I don't know how quickly you can get this uh this setup, but this would be the way I would recommend or mage inferno the They have docker images on docker's hub So you have in engine x setup It's probably one to go to there now um an important developer preparation is to use the command line tool and um Check the mode that magenta is running in so magenta as an application has three modes Default production and developer Production is the mode that your magenta instance Is in wherever it is running serving your your customers And production assumes that everything has been all those static assets have been deployed that you know A lot of that all the caches have been generated etc etc Default mode means that you didn't choose one or the other And that's actually not ideal a default kind of tries to figure out what you're doing and What's going on developer mode? Allows you as a developer To visualize changes and get error messages that you wouldn't otherwise get basically magenta in production mode will suppress error messages as best as it can And that is as you know, I think one of the great things about php is it's a very friendly language say by the way I believe on line five you forgot a semicolon um not like a You know no pointer exception or something from java, but um When when you're not getting that that that immediate feedback when you are refreshing your browser when you do when you're Developing and all you see is like a white screen of death or just something that says hey something went wrong But i'm not going to tell you what that doesn't help you as a developer So enabling developer mode is is uh fairly essential Since I can't get up in point and I feel it's very important to point I will use my my laser technology There we go. All right, so the commands that you can run so you can check the running mode of magento I deploy mode show and um and actually the command line tool Again, one of the benefits of using other people's work. This is what makes like composer and the whole um the whole uh You know the the efforts of the fig psr Makes it so great when you can just pull in someone else's work and benefit from it so you get things like um You know abbreviated uh syntax. So this is this dm set is uh short for deploy deploy mode set Um, and it just does a string match Um to to find out if if if if a command is unique um And then uh, so the couple things that you want to do when you are when you're getting into developer And when you're getting into magenta development is make sure that you set developer mode And that you disable the configuration cache because as we'll see in just a moment magento really really likes um Really likes for you to be I'm sorry magento is is is caching that configuration and a lot of the work that you do as a developer is just changing xml Right in magento And then you can even uh, you can also just if you if you prefer you can just keep flushing the cache after you make a Change, but I can't I can't tell you the amount of hours that have been lost For developers for like, you know sitting there and refreshing like why isn't working? Why isn't working? I forgot to clear the cache right so my changes just weren't being picked up by the application Um and disabling there are there are multiple cache types. Um, and there are multiple cache types in magento So, uh Wish I could present this in a window Maybe I can't um anyway Let's see. So if I do this whoops So I'll do bin magento And then I uh, maybe I don't remember the the command. So I'll just do I'll say cache I know something like that and I'll get the suggestion list here. I can even make this bigger here Do that whoops all right So I get a list of possible matches so I can uh, I could maybe run cache status And I can see here are my here are my cache types Right Okay, the green laser may not be as helpful here So you can you can tell I've already turned off my configuration cache and my layout cache And then there's all these other cache types here and and in general. Oh, I've also turned off full page cache So in general What you want to do as a magento developers you want to leave As many caches enabled as possible While you're developing that keeps things moving quickly, but if you're going to be constantly changing at one area You probably just wanted to disable that cache Otherwise you have to remember to uh to clear that out every time Let's see. Oh, by the way, if you have any questions as I'm going along absolutely Happy to make this interactive. In fact, I prefer it um Just so I don't feel like I'm alone up here behind the cameras um All right Let's see Well, this isn't interesting. I was yeah, I was kind of I don't know I guess I was hoping everyone would have magento installed and We'd be walking along coding together so, um I will just walk through the stuff that I've done And try and tell you interesting uh interesting and amusing anecdotes along the way um All right, so at this point What I've tried to explain is how as a developer you get going with magento 2, right? So first you've got to get it installed however One of the great strategies for managing magento installations is to use something like vagrant or docker Especially when other people are keeping it up to date, right? Now, of course, if you are working on a client site, you will probably want to manage your own, uh, your own instances And you will come up with various strategies for how you keep your custom code Uh, how you keep your custom code stored and separate from the magento core. There's all sorts of strategies out there There's some really really good articles, uh that you can That you can check out And I'll I'll um, I'll write up a few especially if I get some questions at the end um So that you can have a reference of of who to go to all right, um Let's see All right Who is familiar with dependency injection? Anyone anyone Who here is too shy to raise their hand? See This is this is my all my results are getting skewed It's okay. You're definitely more outgoing than like Let me see when I speak in france. Oh my gosh It's like pulling teeth. Um all right, so Dependency injection. Wow That didn't even occur to me Dependency injection is a strategy for decoupling code It is not foolproof Right, you can build You can build some really terrible stuff With dependency injection. You can end up coupling yourself regardless Um, and there are lots of debates about, you know, what's the best way to do it? And you know, some some practices are outright bad Some kind of depend on how the implementation is done. So the way this works in magento There's really there's two levels to our dependency injection So what the strategies that we use is we use constructor injection. So I I guess I'll start with with with a kind of a counter example Um in magento one, let's say I have a Let's say I have a I have a block now This is a this is a php class that has some logic for displaying information about Some entity and we'll say That entity is It's a good entity to use there There's a good entity to use there All right, this is a hypothetical example because it's not quite this this straightforward in magento, but Let's say I have a php class and that php class is used with a template And it it needs some product data, right because it's got to oh, I'll take actually I'll take the Recently viewed products collection, right? So if you're on a magento site and by the way, I should mention marketing would be very disappointed with me If I didn't like the magento World is very big In terms of the business and the impact We have since there's a it's open source. We don't know how much money exactly flows through magento code but The kind of conservative estimate that we have from the market analyst is 50 billion dollars a year And commercial volume goes through magento code base And you've got over 150,000 transacting stores out there And then already already a couple thousand magenta two stores spun up so That is Basically, I just wanted to use that as my introduction for saying like the number of times I've actually gone to buy something when I wasn't buying it off of amazon Which I can say now that we're no longer part of ebay ebay sold us. So now we're owned by private equity So when I'm not buying something on magenta on an amazon, uh, just on amazon I can very often I will be checking out Buying something online. I'm like, yeah, that's that's the magento site like see all this. I know this stuff Um, I also know some hacks so I can usually get everything free just kidding. Um That would be bad. Um, and uh, if if you are on a magento site or even on I guess any other lesser commercial application site, um As you're browsing through things you may see something pop up You know as you go from page to page to page that has You know a list of the most recent products that you've viewed That is a recently viewed products blog um, the way rendering or the way View modeling works in magento Because you have an xml file That says hey on this page or on all pages in the left column Maybe after some other blocks of content you have the recently viewed products blog and that xml directive Just takes Uh identifies a php class and identifies a template most of the time and those two essentially, um a common block a common block method Is run Pulls in the template echoes into a buffer shoots the content out at you. It's very simple It's a little bit different from sort of the classical mvc modeling It's more of a view model approach um So that Recently viewed products collection. I really wish I had a Whiteboard to draw on that was on camera, but it's not I can you know, I'm gonna I'm just I'm gonna go off script here. Sorry They don't have a permanent marker I can use Do we have markers here? that is Definitely number of times I've gone into training centers and you just like you pull down the screen and you could see like someone wrote on it Um, so one of the uh, one of the things that I like to do here. I'll plan to see what we're talking about. Amazon all right um I'll do a quick little diagram for you because this is uh, this is essential This so this applies to magento one and also to magento two um in in sort of the basic level you have a A block class and that's that's just the php class and then we use um Templates makes sense and these are just phtml right so so combination of php and html um in magento one sometimes these phtml's would get really really complicated Uh, and in general you want all of the the real logical stuff to be in your class Right, you don't want a whole lot of switches and stuff in templates But I will tell you the magento one magento one um Magento one some of the templates are just the price template the thing that is literally responsible for displaying just like Yeah, $3.98 That template is 400 lines long Of html and php because there's all these conditionals because you have to uh, you have to check Well, okay, do you do you want to display? Just the regular price. What if you have a special price now? Do you need to display this with uh, do you need to display this with with tax included or do you need to display the tax separate or Do you need to include any of these other kinds of things? So, um, they were really complex in magento one magenta two We've done a lot of work to to refactor those. Uh, basically that pushed that logic up into Uh, the php world where it belongs But so imagine you just have a um, you know A php class and that class includes this template and just echoes into a buffer. All right um So and again, these things these things were married were called into scope And married together usually via xml And that is magento's famous layout xml um That that is also a page straight out of the the java book and it could be very confusing I was I hate it hate it layout xml Like the first two years of magenta development and then you start to get it and then you realize that like you can do things Like if your boss says hey, I want recently viewed products to show up on the customer account page Literally like one line of xml and it's done And the great thing is that actually saved you from having to go into a controller And invoke the collection and pass the collection to the templates and all that stuff. So it's really nice now in uh in magento one You might have your block class and i'll just Use a very poor example and just say that my block class here and it needs it needs a model instance, right? so, um, you would say you might have a a public function Yeah Get product right and we'll pretend that this this is not how it works in magento, but we'll pretend that it gets some id And then internally And then internally it just does let's see back then we have this we had this god class um That was really Yeah, this this is kind of a bear to test for Hopefully obvious reasons. Um, actually no It's been a while since I've done that more development. It's actually mage get modeled right And then that would take it off that would take a string argument to identify the class catalog product and Load id and then of course actually this would be returned here Okay, don't worry if you can't read it Doesn't work like that anyway, but this is the gist of it So what you're doing here that that's that's so there's a couple things that are less than ideal Uh, of course this got this god class thing kind of a again, it just it really complicates testing And also binds things into it kind of binds things into a big messy scope, right? It's just a it's a It's a big Object that kind of couples the whole application together Um, the other thing that's happening is you now have a direct dependency between this class And this thing here and that's not ideal Right, that's not ideal at all Because well, I mean, you know dependencies are bad. Why do we know dependencies are bad? We don't really I mean, they're not necessarily people don't die usually because of dependencies, but What it does is it is it is it makes extending the system it makes changing the system more complicated so better yet the way we do it in uh in magento two is Very blue hands for the rest of the day We just do a little little constructor magic Um public function construct And then we would say something like product product And then in here we would actually set We'd actually set the instance so it's it's a subtle just it's a subtle difference, right? We're not but the thing is this is somehow receiving a product instance when it's being created And that's the second layer of magenta twos dependency injection structure is As you can see here this class here The block class Is getting is getting the objects that it needs Via an object manager I'll come back over here All right, so this uh this object manager. So there's this entire meta environment that is operating that is grabbing That's looking at all these class definitions and then looking at some xml arguments And checking like hey, are we really getting this class or maybe there's another class You can actually configure that in magenta two Um And the nice thing here is that the object manager Handles and optimizes the the loading of all the stuff and any dependent objects. It's et cetera, et cetera It's a really big. It's a really big thing if you want to dig into it and there are some people in the community who have Alan storm is one of them. And if you've been doing any magenta development, you know his name and you Always treat it with proper respect but The gist of it is all you have to do when you look at this and when you're getting started is just realize that There is a system inside magenta two that just looks at these looks at these type hints Looks at some configuration and then figures out what needs to be there and just handles that for you automatically And that becomes uh that becomes um part of the the testing setup. This also is One of the ways to affect customizations all right I know I I knew on the one hand. I was thankful because I was getting late last night. I was thankful for the after lunch spot But it's always dangerous to do the after lunch spot. I know I could tell whenever I would teach that week-long class and like one day invariably the the the training centers would get pizza Everyone would drop like flies afterwards. So you're doing a good job staying with me so far Um, and this is what that xml looks like by the way So in in a module you can have di.xml Um and di.xml just simply says hey, uh when when when when you need this Maybe Maybe that type hint that that that that type hint is actually should should match up over here for something And uh, you can also when a constructor has I don't remember if this one has arguments or not Yeah, so at the end here array data, you can actually literally pass in You could specify hey um Here are the arguments I want to pass in so you can kind of configure those parameters via xml it's a it's a I've seen a lot of good, you know very pure Sort of pure php programmers get really put out by this by this whole mechanism but You have to understand like magento is built is built. Uh, it works out of the box So you can download it Put in the sample data or not I mean and then you've got a functioning store and you could all you have to all you may have to do is add some configuration Just to make it work for a merchant but Yeah, one of the things that that you know if anyone here is doing commercial development or you know development on commerce sites it's It's always custom like there was always custom requirement And those customizations can get pretty pretty deep and and pretty wide across the system So what we do is we build a system that has a lot of configuration options You know just via the admin But then we also have to build in a lot of configurability at the programmatic level And one of the strategies that we we use to manage that Are these files? All these xml files and there can be a lot One of the things that we did do from magento 2 is we added schema definitions. These are actual xml documents which describe What is Allowable Basically, what is what is valid for the purpose of this document? Um, and that's that actually is helpful because tool like php storm Well, actually and you'll see an example of this later php storm can actually look at these schema definitions and And and and as you're as you're actually typing up if you're creating some of this xml by hand will actually give you the right options Or tell you if you have a syntax error and that also so xml xml Errors in magento 1 are another huge cause of this of just just sort of nebulous waste of time Um, because if you if you have a typo if you have like syntactically valid, but Um, but but but um, or i'm sorry structurally valid, but but like invalid syntax for the purpose of the document In magento 1 you don't get an error message because all it does is just say hey, is this well formed Doesn't have anything to compare it against and say oh wait that that that value shouldn't even be there There shouldn't be anything at that hierarchy or at that at that level um So we have this for magento 2 so That's that's my quick little note on di and and it's you know I struggled with what to what to bring up what to bring out and in this in this tutorial because again There's so much to cover, but I think this is this is one of those things that you just have to be aware of because I'll I'll be the first to say when I when I open up magento 2 for the first time to really start working with it And I saw you know, I saw all this constructor injection And I saw you know, oh my god all this stuff in the di.xml Like wow, what is that? But that's that's all that's all there is to it is it's just it's just a strategy and an architecture um for Allowing the system to be customized I don't actually cover the customization Possibilities in here. I will probably do a little off the cuff thing on them um Yeah There are some there are some really neat options. Um Magento, I'll go ahead and mention them now, right? So that's it for dependency injection That again very high level introduction. There there is there is it's a it's a big deep architecture There are there are some great articles about it out there if you want to follow up and kind of get into it There there are a couple of ways in magenta 2 that you customize the system At a programmatic level We have events Right, so magenta 1 also has events and this is just literally A line of code that that that executes if someone adds a product to the cart There is an event that fires like that says hey basically a catalog, you know Product add to cart after Right and what that means is that that is essentially as as um as the the the execution stack Has gone down really really deep like you've hit the entry point you've gone through the controller You do basically the request has come in, you know to add a product to the cart Um and you're way down deep in this call stack Well over at Off to the side here like you just got this this thing that essentially can raise a flag To this system that's just watching the whole thing run And says this is hey product was just added to the cart and here let me give you A couple of of contextually important Um Objects like i'll give you that that that cart object. I'll give you that product object So you can you can do something with that you can consume that with something called an observer, right? So you have events and you have observers If you've done Drupal it's it's similar to hooks Uh again just a very simple way of just sort of throwing up to a kind of a global scope and say hey This is happening and here's here's the context So that that's in magenta 1 it's also in magenta 2 In magenta 2 we have this interesting thing called Interception Now this is the most uh, this is the preferred way when you can use it of doing customization What magenta 2 does is Allows you to declare Um allows you to declare Actually, you know I I have I think I have an example in another speaking at a conference in Germany two days ago and I think I have an example here Yeah interception so we'll play this really fast Um, we have these things called plugins and plugins are our our implementation of this interception pattern So what you can do is you can say like hey for um For for the this uh this object here the The layer object so this is the thing actually that in in um when you when you go into a catalog like say you're looking at A shirts category and you want to just see like black shirts Or you just want to see shirts of a certain size and you've got a little filter you can use That's what a layer is in magenta So for this thing, um, I need to Add stock status on prepare front collection. So basically I'm adding the stock status. So in magenta the the the the module The catalog module is responsible for products And there is a separate module catalog inventory responsible for tracking stock status The reason for that is that you can actually disable inventory tracking if you don't need it And that whole module just doesn't do anything and it it can do that without breaking the system So when it is enabled Basically, it needs a way to add Stock status to that that that collection of products that satisfy this filters Well, so what you're saying here is okay for Let's see magenta catalog inventory model plugin layers. So basically what's happened is we've defined a layer So we've defined a class That is going to when whenever this class here magenta catalog model layer Prepare product collection when that method runs The system will actually invoke this class here And execute this code here before that method Make sense Think of like an onion skin, right? So essentially every public method in magenta 2 literally every public method In magenta 2 modules Is a hookable Event for lack of a better term Right, so that means that that when when This method executes Magenta catalog model layer prepare product collection This this interception architecture will look and see like hey Is there anything are there any plugins defined for this and the way the plugin conventions work is you just prepend Before after or around the the original method name And gets that code to execute So if you're a developer of of commercial systems and you think hey That's the most amazing thing ever like That's okay that that's a great reaction to have If you're a developer and you say that is the scariest thing ever That's also a very correct response Because we know from experience that if you give a developer any kind of tool they will figure out a way to use it the wrong way So is there It's it's an important tool in your tool set. It gives you a kind of unparalleled access across the system But it can also Ruin your world. So imagine there's a one of the things that that happened in the magenta one days is a lot of times We did this at blue acorn. We would we would take over sites that someone else had Implemented less than optimally Right and you you have to find all the stuff that they did and this gives people a whole new way to screw things up But if you're a good developer you can use this you can use this to do some amazing things And you can do it the nice thing is you're doing this in a very extendable way You can this system can be upgraded And you've you've essentially I can I can change what happens when When stock status is being added To the product information I can I can I could get into that And actually what this is here. This is actually an example of the magento application itself doing it So magento actually uses its own extensibility tools Both events and plugins Just in its core operations So that that architecture doesn't exist just for third-party developers. This actually is part of how magento functions internally Um So you can do really cool things and you can define multiple plugins for the same For the same Methods um Right, so that's just a demonstration. It's it's it's one of the things that we have with with magento is is You know an extreme need for customization and all sorts of arbitrary customization But people have to be able to upgrade they absolutely have to be able to upgrade because we're we're building new features regularly And if they can't upgrade, they can't avail themselves of those new features All right, so those are that that's just a quick little tour of magento's um of magento's extensibility features and You can you can spend some time working on this I will I will I will just say one more thing about this Because it's another important thing to understand Can you imagine? You know the the application as it's executing and it's it's executing hundreds maybe thousands of public methods how absolutely un un performant Non-performant that would be If the application has to say wait. Oh no public method. Let me go check the configuration See if there's a plug-in. Oh, there are some plugins. Let me fire off this plugins Okay, now let me continue with the stack Or continue down the stack. Um, yes, you're right You didn't know I was a mind reader, but you're right The uh, we actually because we just really Love cool architectures. We took a page out of the aspect oriented programming playbook And we have a system that will when you go into so essentially when you're when you're in Well, sometimes when you're developing Well in general, so what we do is we actually take your dependency injection Um configuration Like this And we take these class definitions and we'll actually Can actually materialize Whole new versions of your class. So you will actually see we have a we have a in our transient folder var You will actually see a generation um a generation Thing here, let's see um I have it here in fact We can see My so I created a custom controller for this for this tutorial. Just you know, just I created a simple little module and The system has calculated that something else is consuming An event That's part of my controller So the dispatch event here is being Plugged in right this is how but by following basically by building my module according to um Magento conventions, um my controller is um Essentially having Plugins executed for it Right, um, and there are if I go into magento here. I can find all sorts of Other things in fact if I go and look at layer What was this one? Yeah I can see the effects of that dependency injection configuration right here Like literally this is materialized out of kind of out of thin air Just because because we have a plug in configured. So this is um Yeah, this is uh, this is important stuff for for for magento to be able to function with any kind of efficiency Okay, that's a deep dive if I had more time. I would say let's take a break um but I'd say it's model time module module time that's Sorry, kind of a joke Most of our development staff is ukrainian Um, and they're all fantastic and wickedly smart people But it's really it's really tough to like have a conversation about like modules and models With them because of it's you know, obviously really tough um, if you speak slavic language to then have good pronunciation and You know one of the romantic languages um or english all right, um Magento module structure. So if you have a module in magento 2, it's literally it's just a folder you follow psr naming conventions and So this is just an example of the the contact module so In magento 2 site if you click on a contact us link and you get a little form and you fill it out and it emails somebody when it's submitted That's what this is Now view Some of the view stuff is here all of your your php your class logic for presentation That's going in here the block uh controller obviously is going to house your your controller files and maybe some abstract abstract base for those files if you like and then Helpers we actually we have because we converted magento 1 from magento 2 Reverse that we've converted magento 2 from magento 1 And so there there's still some of the old architecture some of the old stuff in there Helpers are just sort of like I am developing. I don't know where the hell to put this I'm just going to bang it into a helper and there it is. It's probably awful commingled Stuff, but whatever Great utility Hard later when you need to do a couple things helpers were notorious for like Like oh, let me see. Well, I don't have I don't use newsletters. I don't use magento's newsletter system. I'll just disable that Boom people can't check out Like the hell Actually, I don't know for sure if that's a helper But a great example of helpers often just contain stuff where people don't know where else to put it So we're we helpers will should be eliminated over time in magenta 2 As we kind of go through and refactor the areas internationalization so magento comes natively with The ability to to provide translations via csv files. It's a it's a it's a it's a bit limited unfortunately because in our in our World we use English tokens English basically English as tokens Which is okay As long as you're speaking English So they get a little tricky when you have things like like the word order Because like order can apply to like a sort order or order can apply to an order Or you can have someone order something and all three of these things. It's okay to translate them similarly But only in English right as you go to a different language is just just different words One of the things we'll be addressing actually very soon as well Model is of course for your for your that's that's your your domain and kind of the crossover to your data access objects Tests so you would have unit tests under under your module structure And then there's actually a separate place to where you can put your integration tests and functional tests And then view is where you contain layout xml things like layout xml and and your your phtml templates all right now One of the things that I like to do with with when i'm when i'm teaching people new to magento When i'm teaching them magento is just say okay, so what is like the most basic module that you can have? Like what is what is the minimum that you need to do in order to really like have an effect on the system? and Really it is a a namespace Which you don't see here a namespace a module name Registration dot php, which i'll show you in just a second and then under etc This is where all your xml configuration stuff goes Everything well everything except for layout xml that goes under the view So a registration dot php and then under etc module dot xml Module registration So i being the wise marketers that i am i'm using the absolutely inventive namespace of ben marx and Ben marx brands All right, so this is a this is a brand module. Ideally it will display A list of brands or it will do things related to brands We'll see how far we get All right, um Again the ability to not get up and just jump in front of this is killing me here, um Right, so Etc module dot xml. It's very simple and structure. Uh, one of the things to get get prepared for is we have all of our schema definitions Referenced via and i can never remember what you are in stands for universal resource Something Anyway, there's a thing called google that will explain that Immediately what we have here. So this is just boilerplate So every single module dot xml will look Basically like this now they may have more information in it There are other things that this file can do can actually set a load order of configurations based on other modules But the the two essential pieces of information here are my module name So this will become a unique handle that the system is used and using internally in some places Um, and that is just my namespace plus my module name as well as a setup version So you use a setup version to to to inform the system like hey I have migration scripts essentially I need to I need to have some effect This module being this module sort of being in the file system Also has a requirement of the database to have some schema available or some data available And I do have an example of that later on Uh, so the combination of putting these two files into the system right and I'm under now in this case I'm operating under app code Um, I might explain that in a bit Um, I didn't really explain it before um Right, so registration dot php. This is a shortcut that we came up with to reduce overhead It's essentially, uh, is is a file that the application can look for To to see if a module exists at that point in the file system or not And it's a pretty consistent Syntax as well fairly boilerplate the only two thing the only thing that you need in here really is, um Your module handle Ben marks brands Now if we go over, um to here you can there are different component types that you can register But essentially let's pretend that I were making a A scaffolding tool And there are several which exist But if I'm making a scaffolding tool, um, I could or even if I just wanted to increase my development speed And I like to type stuff by hand. I could very easily create a live template in php storm That would just let me fill in this handle This handle in a setup version So One of the things about magento, um one of the complaints I hear is just like, oh my gosh It's so much to type so much xml to type so much, you know boilerplate stuff like it's the whole idea It's like all that boilerplate Just means that you you you write a you write a script you write a tool to help you with that Because literally if I want to if I want to create initial initialize a new module I really have to answer two questions like What is the module namespace and name and what is the setup version? And and and and that script or utility or whatever can create that Um, and there already are multiple scaffolding scripts for magenta 2 All right, so this is the minimum module in magenta 2. It doesn't do anything But this actually will have an effect on the system Okay now Um, if you give me just a second, so I think I I think it's going to make the most sense if I Let's see. It'll make the most sense if I do some stuff here. Let's see. All right um So I'd like to walk so I think one of the One of the things that I like to do is as a developer evangelist is Get people going like get you feeling good about about development. So let me see. Let me Uh drop table Good Now let me so, um I'm going to Try and step through this Like I'm developing live in front of you. I'm not really developing lives It's I've already got this stuff built because developing live is It's a scary business Uh in front of a class, um When you are so when you're working with the system, um As a developer, so let's say I want I want to get going so I need to create I need to I need to create a folder Or a couple folders and and and and sort of tell the system. Hey, here's a whole new area where you need to pay attention to what I'm doing So one of the first things that I'm going to do is I'm going to disable the caches Right, so I'm going to I'm going to run the command here because I know I'm going to be developing like for for today And I'm going to be doing some stuff with routes and I don't want to you know I'm going to probably make some mistakes and have some errors and so I will I will um just Disable these two caches so I just run the command Cache disable and pass the two caches that I want to disable config and full page And so if I do this now it actually won't have much of an effect because um right now they're already Um, so I could actually run, you know cache enable, but essentially just been magento cache disable Again, you can you can abbreviate as much as you think is possible Uh config and uh full underscore page And it's not going to change anything because those those two are already disabled Right and the and actually the nice thing is you get this little message backs Is there's nothing to change because those are already, you know config and full page cache already disabled All right, so that's a good important first step again. I'm because I'm developing You know, I'm going to be developing for a little while today. I don't want to have to go in and manually delete that cache By the way, another way of deleting cache is just It's a very scientific operation of going into Going into the the var folder under the application route And deleting cache you can just you can delete anything under var By sort of by implementation anything under var is transient And the nice thing about being in developer mode is very often the application will sort of regenerate things That that need to be regenerated For you If they're configured for it or in the case where The system actually has to go through the the dependency injection compilation will actually say hey, you need you need to run compilation here So right now as far as As far as my Module is concerned Let's see. What's a fun way to do this here. Let's save myself some typing. I'll tell you what I'm going to do I'm actually going to I'm going to Think things won't blow up So what I've done is I've essentially said I've essentially said hey, so I'm I'm declaring my name space And by the way, if you do this and you want to get into magenta 2 development And and and I have friends in the magento business who have literally built multi-million dollar extension companies Just identifying customer need and being the first to implement stuff So it's worth it's worth the consideration But you just you register your namespace with like packages And and away you go So my name space benchmarks They create a new folder here Actually, I'm just going to create a new file So Let's see What's that new file going to be is going to be Brands it's going to be my my module name and then Registration.php And the cool thing about php storm is it understands that like I was typing in A directory treat So I have this file here And then I uh, let's see what I want to do. I want to Open We'll see if that worked dev fagrant Then marks brands there we go And this will just save me from having to type But actually what I'm doing here is is nothing it's not that different from what you should do as a magenta developer Like when you're getting going Again, we have tools there are tools out there that can help you scaffold all this stuff But absolutely the first couple of modules that you build you should type this stuff by hand Because what's going to happen is you're going to have typos you're going to put things in the wrong place And you absolutely will learn a little bit from that, but that's critical That that learning is it's necessary to be effective down the road when you have to work on teams with other people Or work on a site that someone else has already worked on Or even just deal with someone else's extension So what I have here is my my my registration.php content And let's see So I'm going to copy that into here So what I would do if I were developing from scratch and I didn't have my own module as a reference Is I would just look up I would just look up I would find another registration file and copy it and just change the the relevant string Which in this case is just this this tiny little bit right here So I don't know how far you can see that Right and and here's something that's interesting now Um If I go and I if if I go and I Execute I'll do that down so you can see it right if I do bin magento If I spell right I spoke good. Okay, and then I do um Let's see module status I think that's the command No Oh, I may actually have to delete some stuff So sidebar This is one of those things where um Um Oh, cool. Actually. Oh, I see what's happening. So Ben magento as a as a as a script Um We'll give you some cryptic errors It's like you saw when I was trying to when I was trying to just run this command It's just like hey, there's no commands defined in the module namespace. I'm like, yeah, there are I know this There's a whole set of module commands. That's how you work with the modules, but this is the error I get So this is one of those things where we are um, so we're actually in an active actively working on Platform level stuff for the next month or two And so we're taking and one of in our big focus there is actually developer experience Right because there there are places where you get cryptic error messages like this This gives you this isn't helpful at all So this is one of those things where we would like to we do like to hear people's input And you can file issues on github. Uh, you can yell at me on twitter You can yell at me in my email and that's how that helps us prioritize what we fix One of the things that you can do though when you're when you're working with bin magento And it's giving you cryptic stuff like this is you can just actually run bin magento itself, which normally should give you a list But in this case is just uh, it's it's saying it actually gives you a little bit more verbose output So it's like hey something happened Uh probably just try clearing out these caches because they're those caches are referring to something that doesn't exist anymore or something's changed And you have a sort of less helpful error message here But then I do actually have something here that that that does give me a little bit more help and you can see the The verbosity of output between trying to issue a command and then just trying to get the list is quite different So down here I can see You know app code ben marx brands, etc. You know File get contents. It's not there Um, so that's a problem So in this case, ah, you know what? I probably need a new file and that new file Is my register is my module file Which kind of the the two of these together again are what help register Um register my my module with the application. So I'm just going to copy this You know from my I really wish development worked this way where you're like, oh, I need this and it's just there Maybe from agenta 3 will do that um and again Very simple file. All I'm doing is I'm I'm declaring a name And a version number And now let's see if this is enough. It may not be By the way breaking things is just that standard operating procedure as a magenta developer So don't ever get put out by exceptions So that works So now I have I mean by basically by works It means that I'm not breaking the system And I can't tell you as a as someone who went through the early days of so back in the days of magenta 1 There was no documentation it was a startup effort basically and They're just, you know, you know how this is a developer. You'll write the documentation later So The biggest lie developers ever tell themselves um magenta 2 What we did so of course we started building magenta 2 when we were part of ebay You know ebay really helped fund the development of magenta 2 We also hired technical writers, which we found was like it was like you're 100 percent more likely to write documentation If you have people on staff whose job it is to write documentation also like developers were More or less required to explain what they were doing to these people Our documentation by the way is also on github So we accept pull requests and all of our documentation pages have an edit this page link So you can contribute to them as well All right, so I'm not breaking the system anymore. That's good. That's happy But but like in the early days of magenta 1 like it was I can't tell you I've never had a system where I was more happy to break it because at least I knew I was working in the right area um So Cool that means that that that that is picking up my module. It's you know, it's probably getting merged in here So now I can um, I can do Something Let's see Back to my presentation All right So it looks like I could run module status and I can see if my module is actually listed there There we go back here. There's up and I'll you know, I'll do I'll move this down a little bit So it's out of the light there. There we go. All right, so I will do, uh, yeah, bin magento module status And I'll see what I get Oh, cool. It's not finding me at all App code bin marks brands. Let's see module.xml problem, let's see Well, let's just blow away everything under here We actually have a page on our documentation, which is devdocs.magento.com Actually have a pretty good page that which which goes through um which goes through actually and talks about The kinds of activities you're doing as a developer and then what you might need to uh, What you might need to change out I will delete that too. I might get the system. I complain at me now, but All right So basically what I see is I see an entire list of modules that are enabled And then I see list of disabled modules is none And it's still picking up bin marks brands, but I thought I I know yeah, so I So I did do something a little bit kind of hinky because you're not probably not going to delete a module From like I did so under app etc Yeah under app etc config Uh There is bin marks brands Now this file is actually um, it's actually Should ideally be built just via the come or updated via the command line tool, but Now we'll see here So what the system has done is it's noticed like hey, um You know, we picked up that there's a there's a module there Uh, but you know, it's not already added to this list If we go back and look at it Still the same. It's basically like pristine like I my the bin marks thing isn't listed there So now what I can do is I can say, okay. Well, I want to I want I want my module to actually work So if I have controllers under my module, I want I want those routes to be routable So what I'll do is I will call uh bin magento module enable And uh just pass in The handle Bin marks brands Ah now I get some more I get some interesting output here Uh following modules have been enabled Make sure the enable modules are properly registered runs setup upgrade So setup upgrade is what we'll go and check my module and see if it has um, and actually see if it has um Setup scripts to run which at this point it doesn't And I I'm doing that intentionally It clears the cache Generates and wants me to rerun the compile command I don't really need to do that right now because I don't have anything neat that needs compilation one of the great benefits of magenta 2's uh sort of really big meta architecture is and and and aop is that We've we've reintroduced to php the ability to say my my code's compiling All right, so next thing that we want to do I think that's that's actually interesting is to um Configure a front end route Right, so this is this is basically me going into the system Um and with a little bit of xml a little xml one php class and and actually being able to Go to a url and have that url execute my controller action So I was very happy. I finally learned how to do curved arrows and keynote So I used them frequently. Sorry So there are natively there's a there's a couple of routes that you're going to have that you regularly play with in magenta 2 they work They work a different way in in the back end in so-called admin html than they do from the front end I don't go into admin html here because I would need, you know, several more hours days But under that etc folder I can drop in front end And then routes.xml and routes.xml is you can see pretty pretty slim Again, this is something that could easily be configured with the skeleton with the skeleton app. So, uh, let's see what we have here. So um standard Stuff that's good to know but but stuff again, you could totally copy another modules Routes.xml from its front end folder and just replace with your module stuff and work So in this case here again another um xsd defining what's right for this xml document And then I have standard is is actually what the the the router that handles front end requests is called Okay The I could go go into that but again, I don't have time Um, so essentially if I'm a developer and I want to create a new front end front end You know url fragment in this case. I'm creating uh brands here So in other words, you know in order to go to my my magento site it is just mage2.dev And I just cleared out a lot of stuff. Oh, yep. So what one of this so this is an interesting thing that's happened If I were not in developer mode I wouldn't get this error message Uh, and and you can imagine sort of forgetting to run the upgrade scripts For your module after you enable it that could be a cause of of confusion You're like, why you know why why isn't it working? Um, so that's again another just an example of why it's important to enable developer mode. So for mage mage2.dev I'm getting this message like hey, you need to run this this upgrade script Now before I do well Yeah, I guess I'll go ahead and do that And again, all that's going to do is just going to look at basically all the registered modules and see if there is something If there are Uh scripts that need to be executed So in fact, I think now I should be good to go Let's see here And this may this first request may take a little while because I deleted a lot of stuff But you can see this is the sample theme that ships with magenta 2 It's all responsive and stuff Um Yeah, actually this is this is again, this is a slightly older We have 2.1 is already out and this is 2.0.4, which is an old version of 2.0 But you know like that you can add to the cart and view products You can add add to your wishlist All sorts of stuff Yeah, so this is uh working magento instance I can maybe demo the admin if I have time later On the so so what I want to do is I want to actually you can see here We'll actually here is you know push it mess in your bag But this is actually internally This is probably Let's see if I can find out What yep, so this is product id number 14. So uh magento, of course being a an application for commerce websites SEO is pretty important. So you know catalog product view id 14 is not a very good Uh way to get your stuff seen by the search engines But this is actually the internal url that's getting translated from that That that that nice seo friendly slugged url You can see I I call that and I got the same page So what we want to do and what this what what what this is what's happening internally So this is the the route that belongs to the catalog module Makes sense now And then when you see product so this is a um, yeah, this is probably a Folder and inside that folder Is a view class And that view class has an execute method and that is what is handling this request courtesy of the standard router So what we want to do or what we're trying to do here is I'm like, you know, I have stuff I want to display under Brands And right now if I go there and this will take forever because of The state. Oh, no, it's actually came up. Oh, that's right because I already generated this earlier Um, now I've got a 404 page. So magento actually has a way of handling an unhandleable Route and this is actually this is actually controlled by our cms system. So this is actually rendering a cms page So front end routes.xml and I want to use the url that an initial part of the url that initial part of the path as brands It's for the front end. So that means I'm I'm Setting it up for the standard router. I've got it under the front end folder And this route id here is just arbitrary It just needs to be unique And I recommend to follow a convention because it actually it comes into play later with layout xml And I will we'll talk about that later um The module name Ben marks brand. So what this does is this actually registers this url fragment with This path then marks brands controller That makes sense Right. So as essentially what you're doing is you've got just like any any web application like a request comes in it gets routed You know in this case to index.php bootstraps the app and kicks off the bootstrapping and does all this other stuff And then execution you can just watch it flow around to a front controller The front controller Finds out what routers exist in the system and then asks those routers like hey Can you do anything with this request? This is classic classic front controller pattern, right? um Because we've registered this with the standard router if if if the request comes in to slash brands That standard router is going to say okay. Well, all right. Let me see. So that's that that route Or that you know path resolves to this module And so I look in the controller file there or the controller folder and see see what I see Now right now it doesn't see anything because I have to create it. So I'll go here and I will create new file and that file is going to be a controller And I'm going to do something special index index.php Because essentially this you are these URLs have You know have multiple parts And by choosing index index.php um, I am Able essentially for those three parts if if Starting on the right no the other right If any part is missing index is assumed so essentially to wit This URL right here is actually internally getting mapped to brands slash index slash index And that's not an uncommon convention for for web apps either So what I've done is I've created this now. I have to actually create this class Here and so again just to save time. I get to copy it because I made it already Quite prodigious. All right now some actual honest to goodness code What are we doing here? What's going on? Again That I am staying seated so well. It's really a miracle because this is very exciting stuff Um, well, you know got my name space to find and then I'm going to pull in some things from the from the application space So I'm pulling in essentially the the action class, right? um We actually in magenta 2 are Would prefer to Limit any direct inheritance And and theoretically at some point we're going to get to a place where it's it's just interfaces everywhere We're just implementing interfaces so you can really be flexible Um, now that's architectural goals. Who knows, you know, fortunately, they're held back by by a product team Um But right now this is one of the examples where we actually do have inheritance, right? And in here we just prefer interface implementation because that just makes it a little more flexible But at some point you can you can abstract yourself into oblivion Um, so we're inheriting this thing again. This is just uh, this is a class that knows how to respond to requests We have this context object now this context object has knows how to get things like to request in the response objects Basically, it's it's the appropriate kind of stuff That is necessary for responding to requests And actually I would say that the architecture team Probably wishes they could get around that as well Um, and then I have the page factory The the view architecture in magenta 2 is is is a is a little bit bigger than in magenta 1 um But essentially what happens is for any for any action controller, which is that's what this is Or controller action Um, it will have you'll generally have two methods to implement the constructor And the execute method now the execute method is what is called when that request Brands slash index slash index is resolved to this file This file is invoked Assuming it's been built correctly and that execute method is called and that execute method needs to You know needs to return um Needs to return a page so One of the uh unfortunate, you know sort of full stops for me in this in this tutorial is not being able to Delve into the the page architecture But you can also look elsewhere in the code Uh in the core code and see how pages are returned like you can open up another Modules controller Folder and find those actions in there and and look at what they're doing I will say though that some of them actually still use kind of the old architecture. Just not ideal That's another part of our developer experience story is making sure that You know that the way one module does something is identical to the way that another module does it right because the the core should be a good reference for you All right, so I've I've I've uh, oh, I don't think I created my routes yet. So I'm gonna do that as well So friend I'm gonna spell it correctly. Hopefully So rounds around so I've I've got my route content here I'm gonna drop that in here all right So there's my route content again. This is arbitrary, but it's going to become important later Um, it's important for a couple reasons only one of which we'll see in this little tutorial and then I go, um I'm saying well, you know, I've I let me see I I don't have configuration um I'm actually let's see Let's do anything I may need to run compilation Ah perfect by perfect. I mean It's a white screen, but it's a different kind of it's a different kind of issue. See I'm trying to get up there. Um This is actually what I expect And I can prove it Because I can go to my slides And hit play and I can go See there's the code Those of you following along at home Test your route Okay, so I go to slash brands again, which is slash brands slash index slash index Why is the page blank? Well because I haven't told the application What's put on that page? So if I just simply go in and add a little layout xml Then something magic will happen Absolutely magical. Um So yep. Yep a little more xml But let me uh, let me create that So I need to have a let's see a view folder view layout And then inside layout How do I know what file to create? So this is a little bit of of of convention Over actual configuration, although I guess it involves configuration Essentially the application is going to is going to look for Some layout Directives based on the current context And this is something called a full action name. You don't really need to know this maybe until later, but What you do need to understand is how they're built So actually before I do that If if I'm trying to learn magento, I could actually Look at that. Um, you recall earlier. I went and looked at the uh, the product page And I went to catalog slash product slash view Well, if I go under the view folder for catalog Um view front end layout I can actually see That there is a catalog product view file there And that is one of the layout files that that gets pulled into scope Simply because of how it's named For magenta two Um, well actually this works the same it works similarly for magenta one So view layout File do front end front end slash In my case, I need to use benchmarks Brands index Index dot xml How do I know that? Aside from having created this already um, well The index index hopefully is obvious is apparent, right? It's my So that that that index index path that is assumed when I went to slash brands Um, and actually I can go back there Go back here and Just demonstrate that that actually works And that's what we're getting here So you can see it was it was kind of cashing that Meta title earlier so The route this route and the other route Functionally identical But by creating this this layout xml file and Copying it From here all right I'm actually not this this is Just being read it's pulling in the schema definition, but that It's fine. Uh Even though it's red. I'm actually going to comment this out for now So I have um a layout file and I have to do one more thing before that that layout file can do its magic So all I've done is I've actually said hey this page should have the one column layout which is defined elsewhere There's also like two column left two column right three column And then I just have this body element here because I believe I have to According to schema definition and then I need to do one more thing And that thing Is I need to make sure that I either need to refresh the layout cache because all of those layout instructions They get cached in the sign-teach request um Or I can calculate them on the fly every time and the way to do that is been magento Cache disable Layout, I think I've already done that so it's going to tell me hey nothing's changing But then I can go back and refresh here and fingers crossed Nothing blows up Excellent Oh, wait, I'm I let's see Do that here Do it here. Okay, I'll do that and then we'll actually do it the We'll create the proper directory structure, which would be front end Then layout That's right folks. I'm a professional Okay Get rid of this extraneous hierarchy here So uh that I actually have well now that I have the actual proper structure in place view front end layout There we go. Whoops. Um now Hopefully we will see What we should see here Look at that That is A basic page right so this this um the reason I like to demonstrate this Even though like my module isn't doing anything yet. It's just it's just serving this route. That's all it is But my code executing gives me a good chance actually Let's say things were kind of blowing up and I didn't know why I could if I wanted to um Through the magic of xd bug I can set a break point here And then I have a little browser helper here this little this little guy And all that all that's doing is it's like actually just passed in passed in a session variable Causes a cookie to get set if I remember correctly um That's funny. We use these little helpers and you forget how things actually work. Um, but what's happening is so Um xd bug is just a module that you plug into php. It's written by this great guy Derek retence Derek is part of php internals He's actually working at mongo db now But he's a he's a great guy great speaker. If you ever get a chance, I would just go to anything And once you start using xd bug for those of you who aren't you will do what we did Like when I was at blue acorn we bought him like a 500 dollar bottle of scotch because xd bug saved us I don't know how much time and money So I've set a break point here And now if I execute this request again pops open my ide Because that module is actually just streaming out a bunch of information over a separate port and my ide is configured to listen to that port and Execution has been stopped right here and you can see Look at what I get for my effort here. Well actually for his effort I get the call stack I can see everything that's happening up to that point like Let's just say this is the first time I've been doing magenta 2 development. I've made it this far through a tutorial I can see like whoa ben marx brands controller index index interceptor. I didn't write that The system created that for me on the fly The cool thing is I can actually Go there I could click on that and I could see where execution went like How it flowed through we can step back through you can also see The variables that exist Like I can look at the state of this the object that's currently being executed here this I can see what is a result page factory. It's Got okay, it's object managers got instance names and you can really dig into an architecture With x debug I'll change your life It's the way of the future all right, so I can't stress enough if you're going to do magenta development or even if you're doing development of of With with certainly with any Framework There's there's no reason to not use a step debugger X debug happens to be the one I know there's there there are one or two others out there um d b Don't anyway X debug is great. It works out of the box for me now pretty much most of the time. So this is this is I essential If I if I worked with somebody if I hired a developer Who was unable to to get things done or you know, just just wasn't growing over time If if he or she were not using any kind of step debugging in a magenta job I would you know after trying to instruct me to do that. I would probably dismiss them It's it's that important a tool to use Okay And and by the way, and so once you do that you can set multiple break points and you can play You can sort of step from point to point you can also You can also step into so I could actually like go into this thing and see what's happening Could step into the parent constructor and and and see you know I can go down you know step line by line and see how things change over time again absolutely essential stuff You should do it in fact although one one caveat is that enabling x debug will will slow down your system Because it is having to stream out all this data and if you Start doing like cash grind you can you can get a lot of real big volume of information But you'll fill up a hard drive in like 12 seconds So that is that is that All right, I'm gonna close out a lot of this noise here That's the routes don't need routes Don't need my modular registration. All right, so you can see We've gotten this far I could even Like let's say I wanted to set the page title programmatically And then I think it is page Get config set I want to say there's a title element here Um, and I could do you know grand's list And then return that page object Set title Uh, except maybe set page title No Well, another thing I can do here is I can actually go here to get config Pop open my IDE get a list of methods again if you've not seen anything like this before Really should should um Get on board with it here and I may not see Let's see Uh, I may need to include Show inherited here Don't believe I don't remember this But I know I have some code somewhere that I'll see if I've been recent Let's see. I can look in here There's another way for me to set the title that would be the way I would do it anyway, so I'll just do that um Let's see. Sorry, and I like to put this over on the Move to the right. All right. So here we are. Uh, oh, I'm still Page layout No, all right. I'll I'll give up on that. But anyway, there there is a way to set it programmatically in your controller But again, the the the thing that I like to point out here is that Where did all this come from? All I did was just say hey render a page So this is actually every module has the ability to define You know by default what it wants to add for example The uh control the the catalog module is adding this list of categories here this menu Um in the header the page header. There's all sorts of data there Um the the the appropriate metadata and so forth is being added um You know this welcome message which has come from configuration in the back end um the The customer account area Is rendering this bit right here. There's a search module that renders this all of this stuff There's a little cms block here and some other stuff and newsletter So all of this is actually being composed From xml instructions That that are being provided to the system by various modules And that's what that's sort of the end result of this So the nice thing is now I can actually you know, I can actually create Um, you know, I can start to create blocks and templates and and start to add you add those to this existing Uh standard page that the system renders What the nice thing about that of course is that then My my module um has the ability to to add to the system Add content to the system without having to redeclare all of all of this stuff for itself All right, that's what's next Okay, so Why is the page blank because we hadn't done this time to add Yeah, so again and these slides will be available Um afterwards and I'll I'll throw the code up into a repository as well Under the center my my github id that you can um you can you can check this stuff out So you can you can mess around with it and hopefully suggest some improvements For the next time. I'll be teach. I'll be doing this same tutorial at zen con in in vegas That's uh for vegas not we do our big conference of vegas every year. I'm not much of a vegas person. Um So any any any insight that you all have after the class would be much appreciated So the again what we have to do is we we have to um Um Oh, there's my Oh get title set All right, we'll just do that really fast because then I'll I feel this this I get got fig get title I actually explicitly said it this is a little this is um It's a little different from how it worked in in magenta one Uh, and then double underscore is the ubiquitous translate function in php. I have no idea why Now and if I were setting up translation, that would be the proper thing to do but again, don't have time So I could do brands list awesome And now if I refresh this we'll see brands list Setting up translation is actually pretty easy. It's just a little a little configuration And you drop in a cse file and you're good to go So all right, so you can see I'm having I'm able to affect an impact on this on on this this page content Okay, now that that embarrassment is done Quickly to our orm. Yes magento has its own orm because reasons The orm it's actually it's it's quite easy to work with you just have some boilerplate setup Um Yeah, just some boilerplate setup. There's actually uh, there is we do have a service layer architecture Um, so it is actually with a little bit of configuration And and some very simple kind of boilerplate definitions. You can actually come up with You actually get automatic like web api Just as sort of one of the benefits And and people can interact using soap or rest with that I think we did away with xml rpc because it's awful um Right The basics of our orm. Um, well actually I guess before I well I'll start at the beginning. You have a You know business object Right, that's going to have some of the the the high level like application logic For that entity Then you have a reason so that's the model Then you have a resource model and that is what that is what is responsible for Furnishing data You know sort of you know retrieving retrieving Data and handling the mapping of a request for data about an entity to its storage pattern It's a kind of a funky way of saying it I know but In magento There are actually what what we consider to be three different Patterns for storing data. There's the simple The simplest entity model where you have if you have a if if if if An object has information has a field of information that just maps to a field In the row for of that table of that entity's table, right? So if it's something has a name you would see a column in that table name You also can have complex types where you actually have data that comes from two different tables And in your resource model you would just need to Have just a little bit of Just a little bit of of you know php logic in there that says hey like okay, you know Map these two pull these two things together and then We also have eav Who knows what eav is You do Do you do you do you know it in a painful way or do you know it in an academic way? Okay, cool. You know it a painful way because you've done the jet to development eav stands for entity attribute value and it is it's a In some ways it it Is efficient from a can be normalized standpoint. It is woefully inefficient when it comes to a Oh my god, I have to join you know 14 tables together to actually get what essentially would be the you know Array of data about an entity Our orm handles Actually handles a lot of that. So if you're working with like a product a product actually has its its data Canonically stored in eav and We of course we index that into into a read table. So it's nice and flat and can be accessed quickly But the nice thing is if you're working with the product model Which has this eav storage pattern or if you're working with like this very simple brands model Which has simple storage, you know, just simple straightforward table storage Those those these at the model level you don't really know Or shouldn't know The storage pattern that's it's a just a demonstration of sort of the classic point of having this kind of architecture Where you have the resource model that just says, okay I know how to take this information that you're trying to save or I know how to load this information that you're trying to get Because I know about the store. I know and care about the storage pattern models don't care at all So your your model here is um This one is this one is super super simple because all it has is a name But there's just some boilerplate that you have to you have to do in order to set it up so essentially what you do is you um you We have this this kind of relationship where models need to know what their resource model is because they have the crud operation And the crud operation would be you know Read update and delete Right create read update and delete in magento That maps to load which is read read matches to load Create and update are just mapped to save And delete is delete So that's I I could call you know I could call brand Save And pass in you know pass in the appropriate or have passed in the appropriate data And that would go into the resource model and then the resource model would Make sure that that gets either saved into storage or update the appropriate record Um, so that's the big that's the probably the most important thing here right um And down here. I'm actually just uh in in magento. There is this Magic getters and setters Right, so you so if if a table if a column exists in a table for a simple entity You can just simply load that entity and call get whatever that column name is and it just works We're trying to shy away from that or not do that in magenta, too We want people to be explicit about things Just to eliminate some of the magic So, um the the model needs to know about its resource model The resource model You'll notice these all inherit from a particular um a particular abstract class um and That I this is actually going to go away in magenta, too It hasn't yet But but over time the plan is to actually Make those also depend on interfaces So the uh the the conventions are Sorry the I don't you already know how to do this Let's stop. Okay um, the conventions are um For how this is done is under the model folder would be your uh your model Class definition then under a model resource model folder Your class definition Um And all it needs to do is it needs to be told what the table name is In this case, I've chosen ben marx brands just as kind of a namespacing convention and it needs to know the primary key And then you have a collection and the collection is used to model groups of You know getting a record set and being able to Loop over it Oh, that did not go well at all Let's see all right so, um a Let's see So what and what a collection needs to know is it actually needs to know the resource model to use In order to retrieve the data because everything all that data retrieval goes to the resource model And it also needs to know for each row resulting row Which uh, which model To use so that's why it has to know those two things And that is the extent of the the simplest implementation of magenta's orm right model resource model collection And you could copy these three definitions and just change things as appropriate for whatever your model name is And it'll work and then the only thing I'll have to do after that Is to actually install the table to actually create that schema and by convention That exists under setup Install schema now there's also installed data. There's also Update schema update data so basically you have you have scripts which are intended to You know affect table schema And you have scripts which are intended to Effect changes in data So set up the install schema what what this does is you'll remember a moment ago I was Doing something What was I doing? Oh, yeah a moment ago when I when I when I enabled the module I um When I enabled the module I Well, I did it by setup Upgrade right and that actually just looked at my module configuration and saw the setup version zero 0.0 0.1 Now what that did Let's see what that did here is I sort of can't clear it here That's gonna not work. Um I just totally threw in a windows command um If I were to Let's see select here from setup module. So there's a table inside inside the magenta database. It is essentially the registration that like, hey If you've installed a setup script if you've actually tried to execute setup scripts for a module and what version so if I Select this record what I get is in setup module So if I just select star from setup module I get a whole list Of all the modules inside magento plus mine So you can see it's a very simple table just has the module handle And the schema version and the data version and by the way you can always tell if you if something's what has gone wrong with your with your setup scripts by The data version being different from the schema version that just means something broke those two should all actually always be Even or equal So the the I could actually I could call I could create an upgrade an update script for my module And and then run setup upgrade and get that to an increment the module version in my configuration But i'm just actively developing. I haven't released my module yet So what i'm going to do is i'm going to execute i'm going to to to do what you have to do often when you're when you're creating setup scripts and i'm going to delete That record From setup module so essentially as far as the as far as the system is concerned. It hasn't run any Any update scripts for my module yet or setup scripts? Okay, so that's done So according to this system now my module hasn't been installed And in fact it notices That by looking by basically saying like hey You know in your in your configuration here You said your mod this this this module the basically this file system for this module It's at version 0.0.1, but it didn't find that in it didn't find that in the database So then all i have to do is run bin magento setup upgrade Oh Of course it'd probably help if i put the actual It's not reading my presentation So Let me Do that again Let me copy the file system from Here See we'll actually copy i think i can do this both That paste that over here yep, so there's my my Class hierarchy for the model layer as well as my setup script just called install schema And you can see it's a very simple thing magento has a ddl data definition library So it's just taking generic table description and theoretically able to map that to different kinds of storage um In practice, i believe we're still only running on mysql and it's and and it's quellants like maria db um, all right, so in the install here, um just um Creating a table uh as appropriate for whatever the back end type is and uh, which again mysql in odb Adding the the primary column here actually That should be that's copy paste error. That should be the Brands id there we go and Yeah, and then also adding another column just a simple text column um for the name And then if i Run setup upgrade again Now i should be able to describe the table that i created uh, bend marks Brands And there it is Good stuff Let's see. I'll go ahead and come in for the bit that's wrong on the other slide Okay All right So refresh here. I should just see the same page again. Of course. I haven't done anything to say hey display a list of things Okay Go back to my presentation here You can see again. So this just walks through what I was doing before so I I just walked through the decision I haven't released my module yet. So I can just I can delete that thing if I had released my module I would have to publish a Um and an update script for this as opposed to an install script And you can see the next step here and then actually delete our roll files Hey, oh, oh the professional dime here. Here we go. Okay And that's how it's done in the Big leagues. All right. So again, uh, just as a troubleshooting note and the I did want to I did want to demonstrate that process of actually going into the database and deleting The record to essentially reset the system. So the system just says hey, there's a discrepancy. I have Files for this module and it says those files say it's at this version. But then when I look in the in the data I don't see it which tells me that you haven't run those scripts yet So the the application considers that to be an invalid state Basically, the file system is not in sync with what with with what the database schema are so Now if we were trying to render a list and this timing is actually working out Miraculously well, um, if we're trying to write render a list of things here Well, we just create a block We need to add that block reference to layout xml and refresh Just to try and see if it has an effect And as it so happens I have I have a block created I think I was planning on getting this far we go So I've got this brand list block here and and we actually too need to talk about this a little bit Uh, because this is there's some this is where a little bit of magento magic happens If you're doing it, right So other brands gonna create a new file And by convention in the block folder Brands list hp Our brand list Need to refactor here Rename is called refactoring and uh In the php storm, um So brand list is uh, just it's a pretty it's a simple block, right? It's it's it's it's inheriting from the from the template object And the template object just just essentially is a class that knows knows how to be rendered um Again this kind of this direct inheritance will probably go away and in some future version of magento 2 But for right now this is what we're what we're using But let's look at what's happening here. So we've got um, I'm saying hey, you know use my collection object And then also use a collection factory The hell's a collection factory. I haven't created a collection factory in magento 2 anything like this that ends in factory Well, that's where we get some of the famous magento magic, right? So the application is going to actually build this uh through compilation is going to build this for us It's actually and and this this just goes into um This is part of the the aop machinery the aspect oriented programming machinery of magento 2 um And this this essentially following this pattern. I mean I could just use a collection pretty sure I believe I can use a collection class directly But um by following this pattern. I actually avail myself of some of the uh customizability of the system, but This does mean I have to I have to compile stuff So what that means here is I actually have to run uh, Ben magento Set up di Compile and so this is going to then uh walk through A process of calculating all of the dependency injection and And you know looking at These looking at this block has basically looking at all the class definitions and figuring out what needs to be built And this also includes this this collection factory for this object So while that's running And we'll fingers crossed this takes a little while It's the speed of that is also something that we're working on as part of our developer improvements But while that is all that is running, uh, we'll go ahead and create the template That i'm going to use in in concert with this class um templates And I think what is that a brand List.phtml And if I go over to Here I believe I already have that Templates brand list. Yeah, this is going to be pretty simple here um Brands get name That's still compiling I'm down to 11 So the idea is that I'm gonna I'm gonna add An instruction to my layout file that says hey um That says hey Oh, sorry. I'm wrong place. Um load that Load up in the content areas So there is you have to understand that actually as part of this page definition There is a content block and that is essentially that's just a or a content container And that content container is just waiting to be have have blocks assigned to it and then those blocks will be rendered um So what I'm doing is I'm I'm assigning my brand list block here Through this directive. So I'm saying in that content container Load up this this class instance use This brand list template and that'll resolve relative to Here Anyway, we go We'll see where we are in the compilation process this You can see it takes a little while. I wasn't kidding. We've really with magenta too We have like, you know the joke like my code's compiling like When when the boss walks by and sees you playing pokemon or whatever Yeah, my code's compiling like literally php developers can can say that again when they're doing magenta 2 again We really are actually trying to um This is slow. We really want this to be Much faster Yeah So, um Once this is done though, I'll be able to refresh and hopefully Hopefully it'll work here Actually, I don't think I tested the view To see if it renders But it's very simple what in theory if it's working right what's happening is um That layout instruction gets executed. Um, it will again, it'll instantiate this class Uh, this class will include this template because it's part of a template block and and the uh the template block will um receive The data so it's going to execute this get brands and brand get name And I could even actually if I wanted to include a type hint here, I could uh Do a little at var notation, um brand his uh Ben marks Brands And then I can actually do There we go mod though Brand there we go All right, and then I actually should probably close that out. There we go Um, so you can see once I did that, uh, this this no longer was showing an error Or showing like hey, I have no idea what this function is And maybe I'll just wrap this all in a div So this is an example. This is a very simple example of phtml Again, you could literally just a mixture of php and html one of the really cool things about magento being being so decoupled Um from the framework is you can actually you can very easily Uh, and someone actually did it on a flight after one of our Beta forums literally they were flying back to australia from the states and just banged out a uh a twig template parser form agent 2 and then it was just like one line of di xml to just say hey, uh use This template processor rather than the phtml template processor. Of course, then you have to create all of the templates in twig, but just kind of proves the the flexibility of the system All right That is done We will see The effect here. Oh, I don't actually have any brands in my application, but if I did If I did, um, oh god What is the insert? Into the hell's the syntax? Insert into benchmarks brands values. Thank you Let's like wait, I would have drawn a blank here values. Let's see One all right, I should add a couple here two bars that didn't go so well Insert into benchmarks values That didn't work The danger of using a few if you use a mac you get this great program. Uh, there it is. Hey Hands off done. Perfect. It works. Oh, of course. I'm already so I'm already setting the title else where I should uh, I should remove that from my template And I wasn't translating it either so that's a bad boy. Okay That that doesn't seem right Then it just mysteriously goes away. That's great. It gives you a lot of confidence and you know working with them, too There it is. All right, um So that's the uh, that's the system and my max running out power. This is I this is this is cavalier. Um, all right Uh resources you should know some great resources. Um, and I actually as I was sitting down was like holy crap I didn't write any resources. So we'll add them right now Uh, you should go see alan storm.com. Absolutely. He is a programmers programmer He digs into he digs into not just magento like when larwell five comes out He he he went in and he he looks at it basically like he is taking over as an architect And uh, does some resources there we've got alan kent dot me alan kent is our Brilliant chief architect came to us from the actual from the search team at ebay Uh, great guy australian super friendly very effective. He's got his blog is full of magento stuff We also have uh dev docs dot magento.com that is our documentation um And I would say if you are interested in, um vms uh go to get the mage to vagrant on github There we go mage to vagrant on github and Let's see. What else do we have we have? Um Uh mage inferno lots of mage stuff in the magento world um on Docker Uh, those are just a few of the resources. There are so many resources out there There's actually a community curated list Of resources out there if you go to what is that list? github.com What's it baler on 72? Nope, I forget his name We can go to ben marx Where you will be able to find this uh you under ben marx. There's that clever guy just eating a bunch of fondue in switzerland um If we go I have this this very outdated magento resources thing here So there's a lot of stuff, but a lot of some of this is actually based on magento one And um, I know if there are A couple people here um know Who's forked this? I should update that too um Anyway, the guy that actually made these shirts, so This is me on this shirt. I don't make shirts of me The community actually did this. This was just a joke. I um just pointed at someone's camera once and then There was this always this big problem with magento one about people editing the core Right to do stuff when they didn't need to And so someone actually just made a meme and so I became a meme. It's Don't edit the core. Oh, the cool thing is now with magento two because it's on github It's sort of like don't edit the core unless you submit a pull request That's what we want. Um, I have uh, so thank you all very much. I hope it was informative. Um I think I'll try and do better next time about telling people um about telling people to um Um Getting people, you know A working installation because you really probably could have followed along with this. Okay today. That's just a matter of getting set up Um, so there is that I have stickers. I gave out some stickers earlier. I have more if you if you're into stickers um, I am contractually obliged to stick all the stickers here um It's it's like it's in my Work contract, but yeah, I have more um Always always if you have any questions, you've got my contact information. I'm actually going to remember to show that slide Here to close things out So there's some resources. Here we go Please absolutely reach out to me if you have any questions, even if it's a like, hey, how do I get going? Or i'm stuck on this thing. It's it's literally my job to help You can also go. There is a magento stacks focused stack exchange site It's one of the highest traffic sites on Stack exchange, which I don't know. We should brag about but it's a great resource It's a great community of people. Um, one of the guys on there. He's on there so much They made a website for him is mariusawake.com. Although I think it's offline right now But literally just looked at the stack api to see if he was posting because he's always up posting That's it. That's all I got. Thank you very much