Okay guys.
So in this video I'd like to introduce the view handling in our blog application.
There will be some major differences between how we did that previously.
Previously we just had a simple function that rendered the top of the page, then the actual template
with any data and the footer.
So that was much simplified setup.
And with our new setup, we instead have the concept of layouts, and we can choose the layout for every
single view that we render.
That's useful if you have one main layout, and then you might have a different one for an admin panel,
etc..
So other differences, apart from having different layouts for different views, is that we'll have
the data available as variables.
So previously we relied on this data variable which was an array.
Now every single variable or data passed to the view will be available under the variable name.
So other thing that's important is we're going to learn how can we use the output buffering in PHP.
That's a super simple concept.
And this example should illustrate that.
We just call our start function.
That's just a function name.
And it will start buffering all the output that you echo or you return.
Essentially this means every time you will call the echo statement, this won't be directly outputted
on the screen.
It will be kept in a buffer in a temporary buffer.
And this will happen until you call OB.
Get clean.
That's another function that will just return you everything that was outputted to the buffer.
And this means that you will get this final response as a string we're going to gonna use that to render
the views effectively together with the layouts.
Okay, that's enough of an introduction.
Now let's get started implementing this in our code editor.
Okay, so we are in the code editor.
And as I've said, the router would be probably the most complicated thing in this project.
So we are adding things.
That's basically a core feature.
That's why I will be creating a Vue PHP class inside the core directory.
Let's start with defining the namespace that's core, and we're adding a class here.
Let me call this view.
And it will have some static methods.
The most important one would be called render.
So this is public static function.
Quick reminder static method means that I can call this method on the class, not on the object.
I don't need to create an instance of this class.
This is called render.
It will accept a template name that would be a string.
Optionally, it can also accept data that is initialized as an empty string and it just returns the
string the pure generated output.
So before we implement this method, I'd like to add two more.
One would be called render template.
Another one render layout.
Those are protected.
It means we can access them from this class or the child classes, but it's not publicly available.
And also they are static methods.
So first let me add the render template.
This will be rendering the template.
We're gonna do this separately.
So again here we need the template name and the data which well doesn't have to be an empty array because
we initialize the data in this place already.
And the render method will be calling this one.
So the render template returns a string.
I'm going to implement that method right away.
So it will be clear why we have a render template method, why we would have a separate render layout
method, and why a third render generic method.
So let's start with the render template.
So I've said that the data passed inside this data array would now be available as variables.
How can we do that.
So in PHP there is a function called extract.
So the description of the function is that it imports into the current symbol table from an array.
Well no one can understand that.
So essentially this means you have an array that is an associative array.
So keys from this array become variable names and values become the values of those new variables.
That's why we can call extract on the data to create some variables in the context of this function.
Next up we need to calculate the path to the template.
I'm going to use the dear name function and the dear constant that's always available, and concatenate
that with the path to the views.
Now we can make the directory of the views configurable.
For now I'm just going to keep it constant.
So I'm going to create the views folder inside the app directory.
And this is where we're going to be keeping the templates.
So to navigate from this view file to that directory I need to go one level up to the app directory
to the views directory, then I need the template name.
Don't really need this curly braces to be honest.
Dot php.
That should be the file name.
Now at this point I should be checking if this file exists using file exists function because if it
won't, we're going to be throwing an exception.
It can say template file not found at least.
Which template do we mean.
Now as a part of this project we'll also have much better error handling.
But that's for later.
And now the thing that I've mentioned about the buffering.
So we need to start the buffer that's using OB start.
Then we just simply require the path so the file the template.
And from this method we return the result of object clean.
So take a look at what we did here.
By requiring a file it might have outputted something some HTML maybe together with some data.
But instead of just directly rendering it on the screen, we started capturing the temporary buffer,
the output using OB start.
That's why we were able to capture the contents of this template, rendered together with all the data
into a variable, or to be more specific, into a string that we got from this function.
That's a super neat way to capture any kind of output in PHP.
Now we can have another method to render the layout and the contents of the template can be passed to
this layout as a variable.
Now I'm going to add the layout rendering method and I'm copy pasting this rendered template one.
And that's because this new render layout method would be super similar.
So this accepts a template.
And that's right.
We are also calling this a template because you can place the layout in any directory you want.
We won't be forcing anyone to use some specific directory for the layout.
It will also accept the data, because we're going to pass the same data that the template received.
But additionally it gets the string content, and the content is exactly what was generated by the template.
You're going to see how this would work in a second.
So the extract call here is not only working on the data.
Instead, we're going to create an array in place and copy all the elements from the data into it.
But then also I'm going to add the content key with the content variable.
So this way the layout has access to all the data that the template had access to.
So it will create the necessary variables, but also to the content that was previously generated by
the template itself.
So again we are generating this path variable making sure that the layout exists.
We are checking.
We might also say that layout file wasn't found in case anything goes wrong.
And we just normally capture the output buffer.
So in the future we might want to extract those methods into a common one because they look very very
similar.
But we shouldn't rush those things.
So for now, let's keep it this way.
So now that we have those two methods, let's see how can we implement this render, one that will be
responsible for putting everything together.
So our first job is to get the content.
So I'm calling the static method from the same class called render template.
So render template will receive the template as an argument.
And it will receive the data, at least for now because I'd like to also introduce the concept of some
global variables.
So here we just generate all the contents from the template into a string.
I've already explained that, but we're going to return the call to render layout.
And here we are passing the layout template.
Now where do we get this from?
So we can just add the layout parameter.
So this would be a string.
And we can make it null by default.
So how would this work or how could this work.
So we've got this render layout method I'm going to pass the layout as it is.
Next up we have the data and the content.
So I'm passing data and content.
And now I'm just going to make the template nullable not optional.
It's mandatory but it just can't be null.
So what we are going to do here is if the template is null, we're just going to output the content.
And this can be first thing in this method.
So if null equals the template which in the context of this method here means that someone just doesn't
want a layout.
And why not?
We might allow this.
Maybe people don't want to use a layout for certain cases.
Then we should just return the content.
Otherwise we proceed normally trying to find the layout and then passing the content variable to this
layout.
And then layout is responsible for rendering the content as well.
We're gonna see it later on.
So I think that this is not super complex at this point.
Obviously I understand we need to see how this works, and I think that it should be clear by then.
But now I think we implemented a lot and a lot of ground was covered.
That's why we should take a short break, and we're going to be adding the actual Vue templates and
trying to render them from controllers in the next video.