Introduction to Magento's View Layer
Hello amigos, this is Joy from Codilar Technologies, Bangalore, working on my Spanish. By this time, most of you might come to the understanding that Magento is an MVC architecture, meaning it has a model, a controller, and a view. So in this video, we're going to be looking at the view part of it, which is further subdivided into layouts, blocks, and templates. What the hell are they? So let's get started.
So I've just created a very simple module called Codilar Demo. It has very basic files. If you are not familiar with how to create a module, you can go over to our website and you can see the tutorial which we have on that. So this has a very basic registration.php file and the module.xml, and it has a version of 0.0.1. All right, awesome.
Goal: Injecting HTML into a Product Page
So what we're going to try to do here is we're going to try to inject some HTML into our page. So I already created a product called 'test' and this is how it looks like. It's 100 dollars, that's pretty expensive for a product which doesn't have any image, but bear with me here.
So let's say I want to insert something here. So in between 'test' and 'be the first to review this product', I want to insert some HTML. So I haven't decided what I want to insert yet, but let's say I want to insert something. Let's go with 'hello world'. Alright, so very original, I know.
Explaining Layouts, Blocks, and Templates
For that, I create a file inside view/frontend/layout. So all our layouts is kept inside layout. Okay, I didn't explain what layout is. So first, let's see what layouts are. So this view part of Magento is divided... so let's go to the front end, that'll make things easier. The view part of Magento is divided into, or let's say further divided into, three distinct parts. One is called the layout, one is called the block, and one is called the template.
So what the layout is, is... so this page might be divided into further sub-components for easier management. Like let's say this part here is the header, this part here is the left side of the page, this part here is the right side of the page, and this part here is the information or review section. And this part is the footer, and then this part is the copyright message. So all these divisions of a page is taken care of using the layout. So the layout itself is kind of like... so it's an XML. We have to write the layout in XML, and the layout serves as sort of a skeleton for the entire page, you can see. So it's just... it doesn't actually have any data inside it. It's just a div here in the header, div here in the content, div here in the footer. Just a skeleton of it. Then what happens is the other... the HTML part along with the data is inserted into these containers which the layout has created, like the header, the footer, and so on. And these data part, which is inserting of the data inside the layout, this is taken care of by the block.
So what a block is... so even in English, if you think what a block is, a block is like a block of the page. So this header, let's say this header is a block. So this block will have all the data like the logo, the search, the sign-in, create account, blah blah blah. All these informations will be served by the block of header. So what the header block will do, it will insert itself in the layout first, and then it would insert the data here. And the block alone cannot do much because the block is a PHP file. I'm going to show you those files in some time, bear with me now. So this PHP file itself is only responsible for the logic, like what should the logo's image be, what should the name be, what should the search be, what is the total content in the customer's cart, things like that.
The actual HTML is rendered by one more part, one more division called the template. So remember this, a block and a template always go hand-in-hand. Without a template, a block is useless. Without a block, a template will not even be rendered, so it's useless. So that's the layout, block, and template in a very simplistic example.
Finding the Correct Core Layout File
What we're going to do now is, so this page obviously has a layout. We're going to have to find out that layout file and then we're going to insert this section, I mean our data in this section between the 'test', which is the name of the product, and 'be the first to review this product'. For that, let's go back to our code. So I have this frontend/layout and I have created a file called catalog_product_view.xml. And if I go inside that file, you can see inside the body tag I have created referenceContainer name="product.info.main". And inside that I have inserted my block, which is... which has a class which I'm going to show you real soon, and it has a name. So this name just has to be unique, that's all you need to take care of. You can name it anything you want, I don't care. And then inside that, I mean it also has a template because like I said, a block alone is pretty much useless. So the template is Codilar_Demo::stock_left.phtml. The reason I named them stock_left is because my plan is to show the actual stock which is left for that product at that point of time. So we'll show something like 'Only 100 left', 'Only 50 left, buy now', things like that, you know. So that should pretty much render this template. You can see I have named it stock_left.phtml. So all the templates need to be put under the templates directory, just like all the layouts needs to be put under the layout directory. It's not layouts by the way, and it's templates. I know that can be confusing, don't get confused. And then finally, block is there in the Block directory, the block with a capital B by the way. And here we have a PHP file which is pretty much empty right now. It just extends this because all blocks need to extend this. So I didn't write anything inside that, it's a very basic block, and the template also has nothing. This is just a comment to make the developer know where the block exists.
So now you might ask me, 'Joy, where the hell did you get that information from?' And I'll say, 'good question'. But then I'm also going to say that I went ahead in the vendor directory and I went to the Magento directory inside vendor. And there you can see that it's written 'module-backend', 'module-backup'... so they have a lot of modules for all the functionalities. So everything is segregated. And if I use a little bit of common sense, I might come to the understanding that the module catalog might be responsible for rendering the product, because it's a part of the catalog. So I go inside the catalog, I go inside view, I go inside front-end, I go inside layout, and we have a couple of different layouts here. Again, using common sense, we come to the understanding that catalog_product_view.xml might be the file which is responsible for rendering the view, the product thing. Makes sense. So then I open that file and I saw here that we have a container called product.info.main, and that's what I used. This is all the information I got just by looking at Magento's code. And then I use that container name here. And since I am referencing that container, I call it referenceContainer, and inside that, then I inserted my block. Makes sense? It's good.
Rendering Static Content with Block and Template
Now coming back to our code. So I'll close this for now, not a problem. In our PHTML, first let's do this, something very basic like 'Hello World'. Again, very original. And then I'm going to have to clean the cache, by the way. So I'm just cleaning the cache really fast. And I will refresh the page and... Hello World! So it came here just where we wanted. So this came here because this whole section, this whole section here is the product.info.main which we have given here. And we are inserting this. So this is getting inserted inside that, and since it's getting inserted on the top, the first thing to get inserted, so it's showing up here. Alright.
Making Content Dynamic with a PHP Block Function
So 'Hello World' is not much interesting, so let's go ahead and change that. Instead of 'Hello World', let's do something dynamic. Let's create a function: public function getDate(). And here I'm going to return, let's return something like date() and the format should be, let's see, year, month, day. So that's our function in the block. And we can use that function inside our template as well. I'm going to show you how. So in our template, we have access to a variable called $block. So we can use that variable anywhere we want to call the functions of our block. I'll show you how. $block->... we created the function and we called it getDate. Let's call it something else. Let's call it getDate because getData might be confusing. So getDate, as you can see, we have getDate and we also have another bunch of different functions here which we did not create. And that is because we extended this template which has all these functions written.
So again, coming to getDate and saving that, going and cleaning the cache. So don't forget to clean the cache, because Magento caches the product page and the category page. So if you don't clean the cache, your changes will not reflect. Alright, so we have the date here. So that is something dynamic, that is something which PHP did and which the template just showed.
Implementing the Remaining Stock Quantity Feature
And now we are going to do something even more dynamic. Like, let's rename this function getRemainingQuantity and we'll call getRemainingQuantity. So to get the remaining quantity here, let's just return 10 and see how to show it. So we're going to write something like 'Only' this 'then left' and a bunch of different exclamation marks because currently I'm very excited for that. So cleaning the cache, refreshing the page... 'Only 10 left!' Awesome. So now this 10 is again hard-coded, not very useful. So to show the actual quantity left instead of 10 right here, what we need to do is: step one, we need to fetch the product model. So remember guys, this is MVC, so the actual product information will be inside the product model. Next is we get the quantity from the model. And then finally... here, oh, it's good. All right.
Using Dependency Injection to Get the Current Product
So to get the product model, what we're going to do is we're going to create another function, and let's keep it protected: getCurrentProduct. Here we have to fetch the product model and we have to return that. So the way we will do that is we're going to go to the constructor, we will create the constructor, and we're going to inject another variable inside the constructor using dependency injection. So dependency injection is a whole different thing and it's going to take more than the scope of this video to explain, so I'll probably going to make one more video for dependency injection. For now, know this: whichever object you want, we can put it inside the constructor and using dependency injection Magento will give that to you. Pretty cool if you ask me.
So we're going to insert something called MagentoFrameworkRegistry. So this registry here is... so this registry here... and this emblem... you just can store this in a private local variable called registry. So this registry is where Magento keeps the current product when we load the product page, so that we don't have to load the product page again and again in different blocks. The more you know. Anyway, so now here we can get the current product just by doing $this->registry and inside the registry the key would be product. That would give us an object of the class MagentoCatalogModel... remember I told you it's a model... Product. So it's an object of this class. And we're going to take that here in the first step. So $product = $this->getCurrentProduct(). Next is we're going to have to return the quantity. So we do $product->getQuantity(). All right. And here we are anyway using that same variable, so everything looks good. Let's clean the cache. Never forget to clean the cache. Coming here, refresh the page... Oh, we didn't get the quantity.
Fetching Stock Data with StockRegistryInterface
The reason we don't get the quantity is the quantity is not saved here in this product model. So we need one more thing. We need the StockRegistryInterface. So I think this is pretty cool that whichever object we need, we can just insert it into the constructor and we'll get that. So we got the StockRegistryInterface which is inside the MagentoCatalogInventoryApiStockRegistryInterface. And here we are going to do something like $stock = $this->stockRegistry->getStockItem() and it takes one parameter which is the product ID. So I'm going to give it $product->getId() which is the product ID. And here I'm going to return $stock->getQuantity(). So this quantity is where the quantity is saved. So if we do $product->getQuantity(), that would not be set in this product yet because we haven't loaded its stock items. So the stock and the product are separate entities and they're saved separately. We don't need to know that for now, just know that if you want the quantity, you need to load the stock registry and get the stock item and from there we can get the quantity. All right, looks good. Let's go for round two. Cleaning the cache. Never, ever forget to clean the cache. That's clean. Refresh.
Verifying the Dynamic Stock Quantity and Conclusion
Only 100 left, because 100 is the quantity. Let's go to the back-end, and here we have set the quantity to 100. Let's change that to 56. I don't know why I chose that number, but if we save the product... said I just got logged out. No worries, I'm logging back again. And go to Catalog > Products, because that's where the products are. I'm going to go to this product which I have created. I'm going to come down and set the quantity to 56. Again, I don't know why I chose that number. I'm going to save the product. I'm going to refresh the page and see something like 'Only 56 left'. So this is fetched from here. That's pretty cool.
And that concludes this video, I think. So we have inserted one layout and we have shown some dynamic data inside that layout using a block and a template. And you can make your layouts as complicated or as simple as possible. You can use anything you want, any data you want from anywhere you want, anything, just show it on the page. We have inserted here, you might insert in the footer if you want, you might insert it somewhere, and we'll get a very dynamic page based on the layout system. So that concludes the layout system, which includes the layout, the block, and the template of Magento 2.
So if you have any doubts, please feel free to ask me the questions in the comment section below. And if you like this video, please like it, please subscribe to our channel so that I can continue making more videos. Not that I'm not going to make more videos if you don't subscribe, but please do subscribe. Thank you.