Building data-driven web apps with Pyramid and SQLAlchemy Transcripts
Chapter: Routing and URLs
Lecture: Demo: Building a CMS in 6 minutes

Login or purchase this course to watch this video and the rest of the course contents.
0:00 For our grand finale, to do the last thing
0:03 we're going to do with the routing
0:04 now we're going to build a custom CMS.
0:07 Now that might sound hard, but we're actually going
0:10 to do this, minus the data access layer
0:13 or the editing layer, in just a couple of minutes
0:16 because routing is that powerful.
0:18 So what we'll find often when we're building
0:20 web applications is, there's some part of the site
0:23 that is very much driven out of the database
0:26 in the sense that it has lots of structure.
0:28 Like the TalkPython stuff, we have the episode
0:30 the episode has a title, it has guests, it has links
0:34 it has all these sponsors, all that kind of stuff.
0:36 And those pages are perfect to drive 100%
0:39 out of the database.
0:41 But sometimes, you want to let people
0:43 often in the marketing, create custom pages.
0:47 Like I just want to have a landing page
0:48 that tells the history of our company.
0:51 And maybe one that shows our team.
0:52 And you don't want to go create separate views
0:54 for each of that, so often, people will fall back
0:57 on to what's called a Content Management System
1:00 think Wordpress, Joomla, something like that.
1:03 It turns out that with routing, we can bring
1:06 that capability right into our Pyramid web app
1:09 with just the smallest amount of effort.
1:13 So let's see how we do that.
1:16 So you can see I've defined CMS page and a CMS controller
1:20 and we're going to pass them with a page, title, and details.
1:23 Down here, we're just going to use the same structure
1:27 but then we're going to show the title on the details
1:29 notice we're using the structure to save
1:31 but this is trusted HTML, it's okay.
1:35 So we're going to show that here.
1:37 But what we need to do is allow arbitrary URLs to map here.
1:41 So the problem, well, the fact that we can't get there
1:45 get it to run, 'cause we don't have the routing in place.
1:47 But I want to be able to just go like
1:49 company/history shows this data.
1:51 users/popular shows another.
1:56 Lets say deployments/popular
2:02 who's using our site, or whatever.
2:06 Just arbitrary stuff up here, and I want it
2:08 to map to possible entries in the database.
2:13 Basically, like Wordpress would or something.
2:15 So how do we accomplish this complicated
2:17 and difficult thing?
2:19 Turns out to be not bad at all.
2:21 So we'll go down here and we're going to say
2:24 config.add_route like that.
2:28 And then the name I said was CMS Page
2:30 but what we put here is different.
2:33 We're going to say that this is
2:37 whatever. Remember like in this example here
2:41 this doesn't capture the /
2:43 This has to be kind of basic data.
2:45 The star says, "No, no. This can be anything."
2:48 So let's go over here and lets grab that.
2:52 We'll say subpath = request.match.
2:56 We want the Import there.
3:01 Now we'll save matchdict.get('subpath')
3:05 And then let's just print out for here.
3:07 We'll just put subpath for just a second
3:08 so we can see what's happening.
3:12 We'll just run that real quick.
3:14 So if I come over here and I say company/history.
3:19 Look, we get company and history.
3:22 I'll broke them into little pieces.
3:25 So let's actually convert that into, I don't know
3:29 probably some kind of thing that looks like this.
3:33 Well, what I typed.
3:34 We want to just get that out.
3:37 So probably the easiest way we could grab the URL
3:40 but then it might have query string stuff
3:41 and all sorts of weirdness, so let's just say subtext
3:45 or suburl is going to be '/'.join('subpath')
3:52 We'll say suburl.
3:57 Now we see company/history.
3:59 Okay, you might of noticed up here
4:01 you have a little fake data, so I said
4:03 company/history so I'm going to request
4:04 that we get these details.
4:06 They ask for employees, we'll get other details.
4:08 So lets do a little bit of fake data access.
4:12 So let's say page is going to be fake_db.get('suburl')
4:19 Tell PyCharm it's spelled okay for us.
4:23 We'll say, if not page
4:25 If they ask for something that totally didn't exist, well
4:27 we still want to return a 404, so we'll say
4:30 raise HTTPNotFound from there.
4:37 Otherwise, we're going to return page.
4:42 That's the page that came out of the database.
4:43 It has the same structure that we're expecting.
4:45 Are you ready?
4:47 company/history.
4:52 Look at that!
4:53 Company history, details about company history.
4:55 How about employees?
4:59 There's our team.
5:00 Beautiful!
5:01 What about other?
5:04 Nope, there is no other.
5:06 Now, the big question of course
5:10 is does the rest of our site still work?
5:12 Yes, of course it still works.
5:14 It's beautiful.
5:16 Now, why does it still work?
5:18 This is super important.
5:20 It works because this goes at the very end.
5:25 Remember, this will match everything
5:27 so it's the last chance.
5:29 So what happens is, if it gets through all of these
5:32 and none of the data driven parts match
5:34 it'll come down here and say
5:36 "Okay, well, why don't you give it a shot?
5:38 Go to your database and see if we
5:39 have some conceptual page details for that URL.
5:44 But if we don't, we're just going to let
5:46 what would otherwise happen if this CMS wasn't here
5:48 just a 404.
5:50 But if it is, hey, let's render it!"
5:52 So this gives you a final way to sort of add on the CMS.
5:56 What do you need? You need a way to make entries and edit entries
5:58 in the database.
6:00 It's pretty much it. You got a CMS.
6:03 The trick to make it happen is that little star right there.