Python for Entrepreneurs Transcripts
Chapter: Build web apps with Pyramid: Applied web development
Lecture: Shared layout demo
0:01 I hope I convinced you that this shared layout is very important for managing large real web applications. But how do we go about doing it?
0:20 And technically, in Pyramid there is a package we can add but it's not very flexible and I don't really like the way it works very much,
0:18 you'll see that we can use the concept of a Macro basically to write this functionality for ourselves. So what do we do?
0:26 Let's start by creating a new folder here, and we'll call this "shared", OK. Now the easiest thing to do is the majority of our content here
0:34 actually that we've been working in, this is just the home page, is actually all the stuff we want shared everywhere,
0:40 first of all notice this, this makes me a little crazy, I would like to make this concrete and not variable
0:46 so let's set this to be en-us for our language, now let's copy this into our shared and let's call it _layout.
0:54 This is the convention that I like that says this is not the thing that is meant to be directly requested, but is a supporting template,
1:02 to be used by things like "index" and "about", so let's come down here and we'll just, we want to keep pretty much all of this the same,
1:09 we are going to set the title but let's not worry about that for the moment, CSS, Bootstrap, everything... it gets down to the body,
1:15 we want to keep the navigation the same, it's really this little bit like just that tiny bit is all we really wanted to write for index,
1:22 so how do we go about converting this into a template? Let's go back to the top. So we can come up here and use the macro extension language for tal
1:33 so "metal", and in metal we'll say "define-macro". Oh oops, I am doing the wrong spot. Let's do it down here actually on the HTML, sorry.
1:41 "metal:define-macro=", and you make up this name, you can call it whatever you want but you have to remember what it's called,
1:48 so "layout" and then we are going to come down and here we are identify places where things would want to be punched into this field,
1:55 if we want to replace the content, so this looks like a thing we want to replace,
1:59 so we are going to put a div in here, and we are going to add another "metal" definition,
2:03 this time we are going to define the slot and let's go and just call it also a main content,
2:08 so this is where the main content of the page will be inserted into our overall thing.
2:13 We also, like I said maybe we want to allow people to insert additional CSS so up here, right at the end, let's say right there,
2:22 after our theme CSS and site CSS, we can have additional_css and down at the end, we can come down here
2:39 and "about" can optionally insert their data, so this defines the layout, shared template.
2:48 The next thing to do is convert our index to use this template, and now this is going to get much, much simpler as you will see
2:56 so let's just do like this for a minute, we are going to say we want a div on here, we are not going to put all the HTML,
3:02 because that is coming in from the layout, and then we'll say metal:use-macro=,
3:07 which one do we want to use, well, it turns out that we have to grab that macro and move it or carry it over to this particular page in a certain way,
3:16 so the way we are going to do this is we are going to store it on the view and we'll call it layout.
3:20 This name doesn't have to be consistent with what is in the page template, but for your own sanity that is recommended.
3:25 And what goes in here not any of the stuff because that's all shared, just those two lines.
3:37 How about that for a nice view, now we need to do one more thing to say which slot this goes into, remember we have three slots,
3:44 so we'll say metal:fill-slot=, we'll say main_content, and just to show you how we can use the other ones, we'll add one more spot here,
3:58 we'll say div, we'll say fill-slot and let's just say this is going to be additional_css
4:05 and in here let's just put a comment but you'll see that it gets put in the page.
4:09 Of course this would be some sort of CSS "include" if we were actually trying to augment just these pages CSS on top of the main site look and feel.
4:19 Now, if we run this, it's not going to work so well. It says home controller has no attribute called layout.
4:27 Great, why doesn't it have an attribute called layout? Because remember I said you have to grab this macro and carry it across.
4:35 That's a perfect place for the base controller to always carry the layout across to any page, basically any view or action driven by any controller.
4:44 So we'll come down here we'll say "self.layout =" well, what? Let's go up here and import this, we'll import pyramid.renderers
4:55 and we need to do just a little bit of work here, we can just say we want to get the layout_render
5:01 and the layout render is going to be this thing we've imported, get_renderer, and we have to give it a name,
5:08 and it's going to be templates/shared/_layout.pt so basically load up this template and give us access to what would be rendered from it.
5:20 And then from this layout we are going to get the implementation, like so,
5:27 and then from the implementation, we are going to be able to pull out the macros and get the one that we wrote called layout, like so.
5:37 So these three lines while not lovely or at all obvious, will grab that layout and make it available for all of our other pages to use,
5:46 let's see how we did. Oh yes, so see how it says missing template asset, templates/shared/_layout.pt this looks correct to me
6:01 but because this is a package it needs to look inside the package, and the name of the package is blue_yellow_app,
6:08 so we'll say look inside the package like so, and let's try again. Ta-da, OK so this is pretty cool, let's just take a really quick moment
6:19 and apply this to a couple of other pages like home and contact. So we just need something like this and we can actually even simplify it here
6:32 so let's go right to the top, we don't need this and then this is where our content goes, let's find it, there it is
6:47 and I'll do that for the other pages. I've applied this change to all of the pages, the three from the home controller and one from albums,
6:55 and because it's in the base controller, this bit about grabbing the layout and storing it, it means anything in our site will basically
7:01 as long as we follow this controller methodology, will have access to it and notice how simple our albums view is,
7:07 all we've got to do is to find the albums and this little bit of repeating and that is it, everything else will be carried forward, from the layout.
7:15 Let's run it and just see how those site's working now. OK, they are looking good, I click around albums, the albums are still looking good,
7:23 let's go over here and just look at the source real quick. And you can see the part that the home page added was just this,
7:30 if we go over to the albums, you can see the little part where we've added in our dynamic code but everything else is consistent,
7:41 I could show you, let's just switch the about and contact in the navigation and we'll just see that flow across the entire site
7:47 and then I think we can call this a success. So I switched home and contact and now when I go over here
7:58 you can see every page immediately picked up that change, now that's a minor change but the point is any change we want flows across the entire site,
8:06 remember, now it's so much easier to add no content and not worry about all that HTML stuff, we'll just have to basically duplicate one of these things
8:15 and fill out the main content and we're good to go.