So our task right now is to figure out how to get this app variable, which is an app config and app
config, is nothing more than a struct that holds certain kinds of things we want to share with our
application.
We need to get that around to the parts of our application that have to have it.
And right away, I can see there are two places that are going to need this app config.
The obvious one is render.
Render is going to have to have this because we don't want to recreate the template cache every time
we build a page.
So that's one place that needs to have it.
And the other place that's going to have to have it, obviously, are the handlers and the handlers
are going to have to have access to all kinds of configuration settings for the application.
So let's do the render.
First one I'm going to do here is I'm going to create a new function inside this render template, OK?
And the render template is going to serve.
The function is going to be called func new templates and it's going to take an argument.
And the argument is going to take is a pointer.
We'll call it a for the variable.
It's going to be a pointer to config app config.
Now I need to do something with that, a variable.
So I'm going to create a new variable here called App and app is going to be a pointer to config app
config.
And when this function is called, it's just going to set that variable up equals, hey, that's it.
Pretty straightforward.
Let's give this thing a comment as we should create a new template.
Sorry, let's just do this.
Sets the config for the template package, not only the trick.
OK, so I've got this function.
I need to call it somewhere.
Let's go back to Main Dutko and think about when we should call it.
Well, we've created the app variable here.
Then we get our template cache.
Then we assign that to this.
And now we want to call that new template cache so I can call two templates.
Sorry, render create new templates, and that's going to take a pointer to app config, so I can't
just put put app in there because that's not going to work.
It wants a pointer instead.
I want a reference to that there.
So that will give our application the render component or the render package of our application access
to this app config variable.
So let's go back to our render routines and do something with this app variable right here.
Instead of creating the template cache, let's just use it.
So Tsay equals app dot template cache.
You have to of course assign that not equal and that we can get rid of this.
So if we did this properly, what should happen now is I should be able to run this application except
I still have an error log.
Fatal error.
So if not, OK, log Fadal.
Well we don't actually have an error here.
I'll just say instead, log fatele could not create a template.
You could not get a template from template cache.
We'll just do that for now.
Fixes that.
And now down here we have to assign assign the error variable.
Good.
So that should take care of it all.
Now we should be able to actually run this application and we'll create our template cache when the
application starts.
And then when we render a page, we're pulling the value from this application structure, our config.
Let's see if that works.
So we'll stop our application, go run command web Stargirl.
It started.
That's good.
Let's go over to our Web browser and reload the homepage.
And there it is.
And let's go to the about page and there it is.
Now, that is way more efficient.
We're not accessing the disk to get the template every time we load the page.
Instead, we build a map that holds all of our templates, put that in an application wide site config
and we can render our templates.
Well, that is a real improvement.
Now, there's a lot more we can do with that configuration variable and we may as well do it now because
we know that the handlers are also going to have to have access to it.
They may not use the template cache, but we are going to put things in there that will make the application
run much better because we can share configuration files.
So how are we going to do that?
Well, to start with, we're going to go to our handlers page and again create some new things.
Now, this will seem a little odd to you to begin with.
We're going to use something called we're going to use something called the repository pattern.
It's a very common pattern that allows it allows us to swap components out of our application with a
minimal changes required to the code base.
It seems a little confusing at first, but hopefully by the time I go through it a couple of times,
it will make sense to you to start with.
I'm going to create a variable or a creative type first, and this is going to be a type it's going
to we're going to have to give it a name.
I shall call it repository, because it's the repository pattern and it is a structure.
And all it's going to hold right now is an app, which is a type pointer to config app config.
All right.
So I've now imported that.
I've created my type.
So let's create a variable that uses that type VAR and I'm going to call this repo and I'm going to
give it a capital letter.
So it's visible outside of this package, which is critical.
It's a type repository.
So I've now created a variable that I'm not using with the type that I'm only using to initialize this
variable or declare this variable.
So now I need a couple of new things to start with.
This is a function and I'm going to call it new repo, and it's going to take an argument.
And the argument is I'll just give it the name of a because it is an application config.
It's a type start, a pointer to config config, and it's going to return a pointer to a repository.
All right.
So to do that, all I have to do is return a reference to repo, the variable that I haven't done anything
with yet.
And I'm going to populate that with the only thing I have to put in that that type an app.
Type of repository.
An app and a sign of the value of, hey, that I passed right here in this perimeter, so now I have
a function, new repo, OK, I'm not using it yet.
I need one more function to create new handlers, funk, new handlers.
And it's going to tape take an argument, ah, which is a type pointer to a repository and it doesn't
return anything, it just sets a variable.
And what it's going to set is the variable that I declared up here, repoll
equals Perth.
And let's give these things comments and we'll go through what they're supposed to do.
This is a new handlers.
It sets the repository for the handlers and this is new repo creates a new repository.
And this is the type.
Is the repository type and are variable.
The repository.
Used by the handlers, now, the only thing in a repository right now is actually the app config where
we're going to put more things in here.
For example, when we connect to databases, we need somewhere to share the database.
Connection pool will share that using the repository structure, and it will make our life ever so much
easier.
So what's going to happen is, first of all, in my main function.
I need to after I have declared my app variable, I need to set things up with our handlers and the
very first thing I'm going to do is create a variable called repo that's going to call that function
handler's new repo.
And I'm going to pass it a reference to my app.
OK, so that creates the repository variable.
I'm not doing anything with that yet, but I'm out to after I create that repository variable, I pass
it back to the handlers and create new handlers.
So the handlers, new handlers and I'm going to pass it repels.
And that should do the trick now, why on earth would I do this?
If you think about it logically, I create a repository.
Fine, so that calls new repoll.
New report says take this app config that you just passed, appointed to the app config and populate
the struct repository, return a new instance of this type that holds the application.
Great.
So I've done that in Maine and then I say I just take that thing I just created in handlers and I pass
it back to handlers.
So I call new handlers and new handlers actually just sets that variable repo, but I'm not using that
anywhere.
Well, actually, I'm going to and I'm going to use it in a very simple spot, one that will make sense
to you momentarily.
It does require a change to the functions themselves.
And what I'm going to do is give these functions a receiver.
And what it effectively does is links all of these functions, all of these handlers together with the
repository.
So all of the handlers have access to that repository.
So I can do that simply by always seem to function.
So far as func the keyword func that says I'm declaring a function, then the name just before the name
in parentheses, I'm going to put a new variable, which I'm going to call em.
I can call it whatever I want.
But Amasa simple one letter thing that I don't have to do a lot of typing for and it's of type pointer
to repository and then I'm going to copy that and paste it down here.
Now these these both of these handlers and any other handlers I create that have this receiver have
access to everything inside repository, which happens to be my application config.
Now there's one more change I need to make before I can compile this and make it work, and we'll demonstrate
that it does work.
Over here in Maine, my handlers, my handler funk's don't work anymore and there's no reason why they
don't work.
Seems to be my handlers.
I have a function called home.
If I go over to handlers, sure enough, I have a function called home, but now I have a function with
the receiver of type repo.
So all that means is that I need to put dot repo in front of that.
And repo in front of that, and now it should work and to demonstrate that it's going to work, let's
pull something out of that configuration and have a look at it.
Well, what do we have an app config right now?
Well, we just have a template cache.
I don't want to pull anything out of that.
Let's just add a new structure to this and a new member to this.
And I'm going to call it use cash and it's going to be of type, Wolf.
So true or false?
So now I've added this to the app config.
So everything that refers to app config now has access to it.
Let's go back to Mean Dudko.
And just before we declare a repository, let's say app use cache equals false.
I've now assigned the value of false to use cache and there's a reason for that.
And let me show you what it is.
We still have the application running, right?
Let's make sure we do well on the about page.
If I go look at the template for the about page and I'll bring up my templates here, find the templates
there's about if I make a change to this template, let's say we add P, this is a paragraph of text
and save it and then go back to the about page and reload it.
You would think that I would see that paragraph of text I just typed.
But I don't and I don't because I'm not reading it from the disk anymore.
Remember, I'm pulling it from that template cache that we created.
So what I'd like to be able to do is to say if you check the application preferences, so let's go to
the render here.
When I get the application preferences, I have access to the app here.
Now I have access to the app variable.
So let's say if I'm in development mode, not production, don't eat, don't use the template cache,
instead rebuild it on every request.
What I can do that really easily and I can do it by saying if app don't use cache, then pull the information
out of that.
Otherwise I want to read it.
So what it's going to mean of course, is that I have to see what a template cache returns.
It returns a map, string the string.
So let's declare a variable just so I can get it outside of the scope of this.
If statement var T.C. is of type that and then I'm not assigning, I'm really pulling it out.
Otherwise, if it's false, T.C. equals create template cache.
And that returns a template and a cache and an error error.
Let's just ignore the air, you know, it works right now.
OK, so what have I done now?
I'm actually going to look in the configuration file and ask myself a simple question.
First of all, I declare the variable this is going to hold my template.
Cash, if used cash is true, then read the information from the template cache.
Otherwise rebuild the template cache.
And back in Maine, I said use cash defaults.
So now if I start this up again, stop the application, start it up.
Everything compiles and we look at the about page.
It has this paragraph of text and I refresh the about page.
OK, that's what I expect.
And I would expect that whether you use cash was true or false because it's reading it right from the
template cash that it built.
But now because I'm in development mode, because I have this variable use, a used cash set defaults
and because I have access to that in render, I can test against it.
So now if I go back to my about page and add another paragraph of text and save it now, it should read
it from the disk because I'm in development mode and there it is.
All right.
So this gives us a lot of control and a lot of power.
It means that we can share information that parts of our application need really, really easily.
If I need to add something to the application config, I just go to app config struct, create a new
type, our new member for this this type, and it's immediately available to every other part of the
application that might need to have access to it.
That was a lot of work.
Finally, in the next lecture, we're going to pass some data to templates.
It's taken us a while to get here, but things are starting to shape up and they're starting to look
good.