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