So we're finally at the point where we can send some data from our handlers to go line templates, and
that's not a very difficult thing to do.
It took us a while to get here, but we're finally going to do it.
So let's think about how that happens.
I have these handlers.
I mean, handlers, Dutko, I have I have two handlers right now.
One called home and one called about and inside those handlers right now, all I'm doing is rendering
a template.
I'm not doing anything with them.
I'm just reading a template from disk storing in the template cache.
And every time the appropriate handler is called, I serve the appropriate template.
And that's pretty good.
But there are a lot of situations.
For example, let's have a look at the about page.
I might perform some business logic here, which gives me some data and then I need to send the data
to the template.
I don't have anywhere to do that right now.
I have this function render template and I want to send it some data.
So if you actually look at the render template function, it only has two arguments the response rate,
which it has to have so it can actually have the somewhere to send the the finished webpage, the name
of the template, but there's nowhere to actually pass data to it.
If I had some data here, if I had a third parameter, I would actually be passing it right here on
the part where I execute those bytes stored in a bytes buffer.
I would pass the data in there and the execute function would take that data and put it in the correct
place in the actual template.
So clearly I need something to put here, but what kind of data am I going to be sending?
It might be a date.
It might be a string.
It could be a full object representing a user.
It could be anything.
I have no idea what it's going to be.
So what am I going to put here?
I can't just say, well, I might have seventy five different kinds of data, therefore I'll have seventy
five parameters to passing this in as parameters to this render template function that's really inefficient.
Instead, let's create a new type, a new type that's going to hold template data.
So right here back at handlers, I'm going to create at the top a new type and I shall call that type
template data.
And it's going to be a struct and it's going to hold whatever kinds of data I think I might need to
put in there.
So what kinds of things am I going to be sending?
I'm definitely going to be sending string information because I'm going to probably send names and email
addresses and all sorts of things that are strings.
But how many might I send?
I might send one for one template.
I might send 20 for another template.
So instead of just putting in a string type, let's put in a string that I'm going to define a type
called string map, and it's going to be nothing more than a map of string string.
So that's one thing I might be selling to templates.
Another thing is I might be sending numbers into integers.
So let's put an intermap in Intermap Map String.
And then I might be sending floats, so let's put in a float bap float map, which will be a map of
string to look things up and of type float.
I'll just use float thirty two.
There are 232 floats, float 32 and float sixty four.
But we're not going to be using huge numbers of float 32 will do the trick.
What else might I send.
Well I might send things that are not maps, not strings, not floats.
In fact they might be structures, they might be things that hold all kinds of other data.
So for that one, I'm going to have a special type, which I will call simply data.
And it's again, going to be a map and it will be a map with an index of string.
But the actual content of that map can be anything.
And in go when you're not sure what the data type is, you call it an interface.
And because I'm declaring it as a type here, I have to put the curly brackets after it.
So that's definitely something I'm going to possibly have to send and then I'm going to put some other
ones in here just for the sake of doing them right now.
So I don't have to do it later.
When we get to the forms part, when we learn how to construct and post forms and handle the forum post
in the handlers, we're actually going to have a little security token called a cross site request forgery
token.
We're not going to use it right now.
And it's just a string, but it's something I want available on every page because a page might have
a form at some point.
So I'll declare it right now.
RF token and it's just a string.
And I'm also going to have some messages I send to the user.
Some will be a success message.
Yes.
Your your submission to the site was successful.
Some will be an error message.
Oh no.
You left an important piece out of the form and have to do it over again and some might just be a warming
warning.
So I'll set those up now as well.
Flash is going to be a string.
That's a flash flash message when I'm just posting on message, a success message or whatever to the
end user warning will be a string and form will be a anot form.
Error will also be a string.
All right.
Now I have a template data and of course I have to give it a comment.
Good practice to keep these things up to date as you're doing them.
Template data holds data sent from handlers to templates.
All right.
So I've declared this data type.
So let's go back to our our render package.
And now let's import or add that as a third parameter, which I will just call data or TD for template
data.
And it's going to be of type handlers.
Dort templated.
All right, I'm not using it yet, but down here where I have nil, I probably want to use it.
So in order to do that, I have to make sure, first of all, that there is some kind of data in there,
whatever it may be.
Otherwise, I'm passing nil.
So if you think about it, when I go back to my handlers right away, I have an error.
I have an error because I'm not passing any template data and I can't pass nil because, well, I actually
need template data so I can do that simply by passing an empty template data.
And I can do that with a really simple bit of code and present template data and nothing inside of it.
And I have an error.
Let's go back over here.
Can I use that type template as type hander's template data?
Of course, I don't actually want to pass template data.
I want to pass a pointer to template data.
That's better.
Now, when I go back here, that error should go away and I can do the same thing here.
Ampersand template data with nothing.
All right.
So that should actually work.
But we actually haven't done anything with the data yet.
So let's try putting some logic in here.
Let's just put on our about page.
Let's put a string so I can say, first of all, I can't pass strings.
Remember, template data at the top here says I can pass a string map, so let's create a map.
I'll call it string map is a new make map, string string.
OK, and then we'll say string map test.
That's how I'll look it up in the template is assign the value of hello again.
All right.
Now I've created my string map.
I haven't actually used it yet and I need to pass it as part of template data and template data has
a member called String Map.
And the value I want to assign to that is the string map I just created.
So I've done that now in the template itself, and this is for the About Page, let's go to the about
page and let's see if we can write that.
Now, here's the very first time we're actually pulling any data from our handler into our template,
and we're going to do it really straightforward.
This came from the template and then because of the template directive, it's in those double curly
braces, I want to look up something in the string mat and I can't just go string map and then square
brackets.
And the name that look we are looking for, we have to use the template syntax, which may seem a little
awkward at first, but it works really well.
Index from DOT string map.
I'm looking for the value.
What did I call it in my handler.
Test, so back to the page test, so this says, I'm going to use the function index, I'm looking something
up and something that has an indices or has indices.
So index and I'm looking for string map.
And I put that dot in front of it because the dot refers to all the data that is passed to the template.
And I'm looking for one particular element, string map, and I'm looking for the index test.
So let's give it a try.
Now, the command is, of course, go run command Web Stargirl.
And I'm going to run this and I'm going to tell you right now it's not going to work.
And I have deliberately introduced an error into this project to show you the dreaded import cycle problem.
Let's run it and we'll see what happens.
Package command line arguments, imports, GitHub, Teszler, go course package handlers and render.
And then we have import cycle not allowed.
And this is what I was talking about earlier, what I told you, why I was putting the config into its
own package.
The problem here is that I have packages that are importing each other and you're not allowed to do
that and go.
You can do it in some languages like C++.
You're allowed to well, you have to put some serious hacks in place to make it work.
But you can do that.
You can't do it.
And go goes a little more strict and says, no, sorry, can't have packages that depend upon each other
like that.
And it refuses to compile.
And the irritating thing about it is no idea.
I have ever tried ever warned you about the import cycle while you're putting all the time into writing
code.
It's not until the moment you try to run it that you discover this.
Fortunately, it's not that hard to fix.
And the offending code here, let me hide this.
The offending code is found in handlers and handlers.
Yes.
Where I have this template data, I'm going to pull that right out of there.
We're not going to stick that in there.
Instead, I'm going to create a new package.
Called models, and it's where I'm going to store all the models that I'm going to use in my my application,
and that includes database models and it includes the template data model.
So here I'm going to create a new file and I'm not going to call it models ago.
Let me close that and get rid of that.
OK, I'm going to create a new model.
And file.
A new file.
Called template data go.
And I'll paste that in there.
OK, so now I have this over where it's divorced from everything else, this will never import another
package.
It will only exist to be imported by packages other than itself.
So I can handle it.
Can't be just template data down here at line 31.
I mean, move that up a bit.
Instead, it should be models, template data and this should be models, template data and then in
the handlers, which should have an error now.
So not handlers in where am I rendered render should have an error, you can't be handlers template
data.
It must be models, template data and I can get rid of this at the ID you put in for me.
And I'm not using it yet, but it should at least compile and it should compile.
And one of the thing I forgot to do is here I need to pass in my template data to the buffer.
All right.
So I had two errors.
I put one in on purpose and one that I didn't even notice.
So let's try compiling this again.
It compiled and go back to a Web browser, and now when I load the about page, there is the data that
I've posted and that's exactly what I wanted to have happen.
So I've managed to successfully pass data from my handler to this individual page so that you would
think is the end of it.
But it's not quite.
There are situations, of course, I could do it this way.
I could say every time I'm building a template or rendering a template, I can manually construct all
of the data that I need to pass to that template.
And yet, inevitably, there will be situations where you want certain kinds of data to be available
to every page in the site without adding it by yourself.
So in other words, you want to take a template, data, whatever template that is passed by a handler,
and then add to it data that you want available on every page of your site, which is a pretty straightforward
process.
We may as well do it now just to get it out of the way.
I'm going to do that by coming down to my handlers, my whereas it here, not that one to render.
When I render the page here just before I call that execute function, I'm going to create another function
and I'll put it right above it.
So up here I will call it func add default data and it's going to take one argument and the argument
will be TRD, which is of type.
Points are two models, template data, and it's going to return the same thing, models, template
data.
So that is the function I'm going to call, and right now I don't have any data to add, but I'm going
to just I'll soldiers return.
So all it's doing right now is taking the template data and returning it.
But when I discover to determine exactly what data I want to be available on every page, I can add
it here.
So we come down here and just before I execute that, I simply take I simply say TRD is assigned or
TRD equals add default data and that should work.
So let's try compiling it again.
Stop the application.
Run it.
It's running.
Go to my Web browser, reload the page.
Life is good, no warnings or errors anywhere.
So we're not going to use that ad template, a default data function for a little while.
But it's all set up and easy enough for us to add information to it as needed.
All right.
That's enough for now.
We shall move on to the next section.