Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
We need to handle creating files in place using templates.
Treehouse Courses
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
We have most of the bits and
pieces for our tool done.
0:00
Now, though, we need to do something
that can be a little tricky.
0:03
We need to handle creating
files in place using templates.
0:05
Since we're using Flask and
0:08
Flask's Jinja2 templates use the same
curly braces as the placeholders for
0:10
the format method, we'll have to keep
that in mind when we create the files.
0:13
But less talk, more rock, right?
0:17
First let's make a dictionary
of final file locations and
0:19
the template that will be used for them.
0:23
And I'm gonna use the location as
the key and the template as the value.
0:25
You could switch those
around if you wanted,
0:28
whichever way makes more sense to you.
0:30
You could even do it as a two tuple or
a named tuple but I like dictionaries and
0:32
dictionaries are easy.
0:36
So let's call this files, and
it's gonna be a dictionary.
0:39
So we're gonna say '{project_slug}
/requirements.txt'.
0:45
And that's gonna be
'requirements.txt.template'.
0:52
And then we'll do '{project
_slug}/app.py' and
0:57
that will be 'app.py.template'.
1:02
And then we'll have
1:06
'{project_slug}/static/css/{project_slug.-
css}'.
1:08
And this will go to
'project.css.template'.
1:17
And then
1:21
'{project_slug}/static/js/{project_slug.-
js}'.
1:22
Actually, we should close
both of these there.
1:32
And this will be 'project.js.template'.
1:37
And lastly, we need
'{project_slug}/templates/index.html'.
1:42
And that's going to go to
'index.html.template'.
1:52
Have you noticed a trend here of
doing the .template on all of these?
1:56
So again I'm gonna use format
to toss in the project_slug.
2:00
Mostly I'm doing it this way just so
2:03
I don't have to pay too much attention
to what directory I'm working in.
2:05
If you take this further and build
some sort of larger command line tool,
2:07
you'll probably want to use chdir
to change where you're working.
2:11
I'm not gonna worry about that though.
2:14
Now I think I'll create my templates, so
2:16
I'm gonna create a new directory
here that I'm gonna call templates.
2:18
And then inside of templates
I'm gonna create some files.
2:25
So the first one I'm gonna create
will be requirements.txt.template.
2:28
And inside of that I'm
gonna put Flask 0.12.2.
2:32
Then I'm going to create another new
2:38
file inside there which I'm
gonna call project.js.template.
2:42
And I'm just gonna put a comment
in here which says JavaScript for
2:47
the {project_name} project.
2:52
Okay, nothing too special there.
2:55
I'm gonna do the same thing
with a project.css template.
2:58
And this is almost
exactly the same thing..
3:02
This is gonna be css for
the {project_name} project.
3:04
And then lastly, or not lastly,
I have two more to make,
3:11
I'm going to make app.py.template.
3:15
This one will have a bit more in it.
3:19
So we'll have from flask import Flask,
and render_template.
3:21
We'll say app = Flask(_name_).
3:29
And then we'll say @app.route('/'),
def home():.
3:34
And we'll return
render_template('index.html') and
3:41
that's it for that file.
3:46
And then we will do index.html.template.
3:48
And this one has a bit more in it so
I'm gonna copy and
3:52
paste this from my own file.
3:55
And we'll put this into the teacher's
notes, so you can copy it yourself.
3:58
This just pulls in static and
the project_slugs, things like that.
4:02
Nothing too special in these.
4:06
You'll see that some of them have
placeholders that we want to replace,
4:07
like the project_name stuff.
4:10
Now like I said earlier that
index.html.template is gonna be a trickier
4:12
beast because it has these
little things here to deal with.
4:16
Okay, so let's close these
cuz we don't need them open.
4:21
And let's work on the function that's
going to create our files for us.
4:26
I'm gonna do it down here
near the create_dirs.
4:30
So def create_files and I need to take
the root, the slug, and the project name.
4:34
So I'm going to call it root.
4:41
I'm gonna take in root, slug, and name.
4:42
So for file_name and
4:45
template_name in FILES.items().
4:48
Then I'm gonna try and
do template_file = open
4:55
(os.path.join('templates',
template_name)).
5:00
Let's see if I can make this window
a little bit wider for all of you.
5:07
There we go, that's a little bit better.
5:10
And then we're gonna say
file_content = template_file.read.
5:13
So I'm gonna read in that
whole bit of file content.
5:18
And then I'm gonna do file_content =
5:23
flask_template_prepare with
the (file_content).
5:27
And then I'm gonna say
file_content = file_content.format
5:32
where the project_name =
name that was passed in.
5:38
And the project_slug =
slug that was passed in.
5:43
And then I'm gonna revert those changes.
5:47
I'm gonna say
file_content=flask_template_repair
5:48
with the file_content.
5:54
Now, this flask_template_prepare and
flask_template_repair don't exist yet.
5:56
We're gonna make those a little bit later.
6:00
So now, let's Let's say
target_file=open(os.path.join(root,
6:03
file_name.format(project_slug=slug)).
6:11
And we're gonna open all
of these with the 'w'.
6:17
We want to delete any data that happens
to be there and replace it with our own.
6:20
There shouldn't be any though.
6:26
So then we'll do
target_file.write(file_content).
6:28
All right, so
that's all the work that we want to do.
6:34
But if there's an OS error,
6:37
then we want to print
Couldn't create something and
6:40
we wanna say file_name.format
where the project_slug= slug.
6:45
And I need to delete these
quote marks out there.
6:53
And finally, no matter whether
we have an exception or not,
6:58
we wanna call template_file.close.
7:02
And we wanna call target_file.close.
7:05
Think that was pretty straight forward.
7:10
But first of all,
we're gonna get the file_name and
7:12
the template_name from
our dictionary rather.
7:15
Then for each one of those pairs,
we're gonna try and create the template.
7:19
First we'll open up the template_file
from our templates directory.
7:21
We'll read the contents of
the template_file into a new variable.
7:23
I'm gonna write later these two
functions that make our templates safer,
7:27
if they have Jinja2 structures in them.
7:30
And then one that will
revert those changes.
7:32
I'll use their names here.
7:35
We're gonna write the functions
in the next video.
7:36
I think that flask_template_prepare and
flask_template_repair make sense for these
7:38
because we're preparing it and then we're
repairing the changes that we made to it.
7:41
So then I need to open the target_file
location which again I'm
7:46
using os.path.join.
7:50
And I'm gonna write the contents of the
template_file with placeholders filled in
7:52
and the Flask changes are then gonna
be reverted to the output file.
7:56
If any of this failed,
8:00
then we're just gonna tell user
what file we couldn't create.
8:01
Should we end the program here?
8:04
Maybe, but if we did it's kind of
annoying that we're leaving these partial
8:06
files in place.
8:09
If we're going to kill it,
we should have used temporary files.
8:10
Again though, that's something I'm
gonna let you change if you want,
8:12
to make things a little bit nicer.
8:15
And finally, no matter what,
8:17
we need to close both of those
file pointers that we opened.
8:18
Great, all we're missing now is the two
Flask translation functions and
8:21
we'll be done.
8:24
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up