This episode is for members only

Sign up to access "Build Your Own PHP Framework" right now.

Get started
Already a member? Sign in to continue
Playing
25. Creating a Twig config helper

Episodes

0%
Your progress
  • Total: 4h 45m
  • Played: 0m
  • Remaining: 4h 45m
Join or sign in to track your progress

Transcript

00:00
OK, let's take a look at how we can create our own helper functions within Twig and how this is going to be useful.
00:06
Now, the goal is to be able to do something with this piece of data here that we want to come from our config. And then later on, we can register any other Twig functions that we want to grab things like root resolving so we can add these to our navigation.
00:22
OK, so what do we want this to look like? We had a look at this earlier, but we want to do something like the following. Config, which will resolve config out of our container. And then we want to say get and then app.name.
00:35
So that's going to be a lot more convenient. If our app name changes, it will be reflected in the title. Now, obviously, at the moment, when we give this refresh, we've got unknown config function. That's where we want to register our own Twig functions.
00:50
So let's go over and do this now. Now, we're going to go over to our view service provider where, remember, we added this extension here. And there's a couple of ways that we can register functions within Twig.
01:02
What we want to do is add in a runtime loader, which will go ahead and grab a Twig extension, instantiate it with any dependencies that we need, like our container, because we know that we need our container to grab our config. And then we can define a bunch of functions.
01:18
So let's start with our runtime loader. So we're going to say Twig add runtime loader. And we're going to create out a class which instantiates a loader passing through any dependencies that we need.
01:31
So over in our view section, let's create out a PHP class called Twig runtime loader. This can be called anything that you like. And this needs to implement the runtime loader interface. So let's go ahead and pull that in here.
01:47
Into here, we want to go ahead and pull in a load method. So let's define out a load method. And we'll grab the entire signature of this, like here. And we get a class in here that needs to be accessed at runtime.
02:01
So effectively, we want to go ahead and create our extension. And then if the class that we're trying to load matches that, we'll return a new instance of the class that we're trying to access. Let's go ahead and fill this in.
02:15
And then we will run through this at the end, because this can get a little bit confusing. So I'm going to create out a new class in here, which is our Twig runtime extension, which will be responsible for holding all of our functions that we want to register. This runtime extension needs to extend the base abstract extension from here.
02:37
And then into this, we can add any helper functions that we want. So let's go and add in a function called name. And we'll just return no framework. So we'll just keep it really simple for now.
02:49
And then, of course, we'll update this to actually pull from our config. So we've got our Twig runtime extension inside of our loader. When this needs to be accessed, this will be pulled in from class just inside of here. So let's go ahead and say if the class that we're getting in matches our Twig runtime extension,
03:12
then we want to return a new instance of that class. So new class. And our Twig runtime extension for our name is going to depend on having our container in here. So let's go and pull in our constructor.
03:25
And we'll have our container passed into here. And let's go ahead and set that as a protected property. Pull this up, because we're not going to need to do anything else in here. And then we can just access our container from here to grab our name.
03:38
So now we just want to pass in our container directly into here. To do that, we need access to our container within our Twig runtime loader that we will then register within our service provider. So again, let's pull in our container within here.
03:53
So protected container interface container. And then we'll just pass that container directly into here. OK, so this will probably be a little bit confusing. That's fine.
04:06
Let's register this runtime loader and then talk about what's happening. So over in our view service provider, let's add this runtime loader directly into here. So new Twig runtime loader. Pull that in.
04:17
And when we obviously instantiate this, we need a container passed into here. So let's pass in this container or this get container. Doesn't really matter. And then that now is available in here.
04:32
And then if we are trying to access any of the extensions in here, like we're trying to access name, for example, then this will instantiate this, return a new instance of this extension passing in our container, and then we can access anything in there. Let's just give this refresh.
04:49
It still doesn't work because we don't have a config helper. Why don't we just switch that over just for now to call a name function? Now, at the moment, if we try and do this, we still have an unknown name function. Over in our view service provider, that's where we want to go ahead and add our own
05:10
custom extension, which registers the functions inside of our Twig runtime extension. So we're going to say Twig add extension. I'm going to create out a new extension here. So we're just going to call this Twig extension.
05:24
We don't have this available at the moment. So let's just create this out and then we will create this file over in here. So let's create a class called Twig extension. This needs to extend the abstract extension from Twig.
05:42
And then in here, we need to find out the functions that are available that will then be resolved with that runtime. So we'll say get functions and we'll pull the definition in here, which is going to return to us an array.
05:55
And in here, we just want to return an array of all of the functions that we want. So, for example, we want a new Twig function, which we define out like this for name, which is that function that we have inside of our runtime extension. And we reference that by referencing the Twig runtime extension here.
06:13
And we pluck out the callable, which is name. OK, so now that we've done this, Twig runtime extension has a name function. We've registered, if we head back over to our extension, this under name. So when name is called within a Twig template, it will resolve this name function from our
06:32
runtime extension, which, remember, is being instantiated here. So again, a little bit confusing, but basically we're just creating this out in the most convenient way. So we have these all nice and broken up.
06:45
OK, so now that we've got this, let's head over and give this a refresh. And yeah, we just need to make sure that we pull this in in our view service provider. There we go. And give that a refresh.
06:58
And there we go. So now at the top here, we've got no framework. That is manually being returned under our runtime extension just here. If we change this over, you can see sure enough that changes.
07:14
But now we've got access to our container, we can actually grab out the useful things that we need. Now, we're not going to call this name because we don't really want to register a function that just grabs the app name.
07:24
We want this to be config. So we want to return from our container config. So we can say return this container, get, and we can grab out the instance of our config directly from the container.
07:42
Let's change this over under our Twig extension to call this config and reference that new config function that we've just renamed or method that we've just renamed in here. And that should be enough. So over in app.twig now, we can say config.get.
07:59
Remember, inside of here, when we're accessing methods, we use dot notation. And we're going to say app.name. Let's go over, give that a refresh. And we're back to no framework.
08:10
So now if we go over and we change over our environment to be something different. So let's call this code course on the app name. Sure enough, that changes over in both places. We're accessing this directly within our controller, and we're accessing this from
08:25
our container via a Twig function. Okay, let's change this back over to no framework. And there we go. Now, any other functions that we want to create within Twig, we just head over to our Twig
08:38
runtime extension, create out a new method in here. And then we go over to our Twig extension and we create a new record for it in here. For example, if we wanted to grab out some auth stuff, we could do that, implement a method, and we can pull anything out we want.
54 episodes4 hrs 45 mins

Overview

Starting completely from scratch, build a modern PHP framework with all the features you’d expect.

Whether you’re new to PHP or not, this is a great exercise for learning what happens under the hood, arming you with knowledge you can apply anywhere you use PHP.

We’ll cover routing, controllers, views, the container, accessing the database, models, authentication, config, CSRF protection, exception handling, pagination, validation, flashing messages and much more.

Let’s dive in and build a PHP framework, step-by-step!

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!