1 00:00:01,020 --> 00:00:05,070 We've learned a lot about the built in tools that Django ships with, 2 00:00:05,070 --> 00:00:09,320 but sometimes you need something even more custom. 3 00:00:09,320 --> 00:00:12,964 Sometimes it's time to DIY your own template tag. 4 00:00:14,535 --> 00:00:18,485 Just like you can create templates that you can include on the fly in 5 00:00:18,485 --> 00:00:22,335 other templates, you can also write template tags 6 00:00:22,335 --> 00:00:26,730 that you can plug in to templates that will render information. 7 00:00:26,730 --> 00:00:32,420 For example, if you always wanted to display the newest items added to a store 8 00:00:32,420 --> 00:00:37,410 or the top-rated game, you can write a custom tag that will dynamically 9 00:00:37,410 --> 00:00:42,880 figure out what the newest or best item is and display that for you. 10 00:00:42,880 --> 00:00:46,320 That's exactly what we're going to do in this video. 11 00:00:46,320 --> 00:00:51,030 We're going to write a custom template tag that will always display the newest 12 00:00:51,030 --> 00:00:56,260 course available at the top of the page, so people who come to our site frequently 13 00:00:56,260 --> 00:01:00,150 can easily find courses they might not have seen before. 14 00:01:00,150 --> 00:01:01,170 So let's get started. 15 00:01:03,270 --> 00:01:07,620 Template tags are a little special in that they have to live in their own directory 16 00:01:07,620 --> 00:01:09,660 called, templatetags. 17 00:01:09,660 --> 00:01:14,540 So, we created a new directory in our courses app, called templatetags. 18 00:01:14,540 --> 00:01:18,050 Don't forget that in order for Python to recognize template 19 00:01:18,050 --> 00:01:22,510 tags as a Python package, we had to add an empty init.py file. 20 00:01:23,560 --> 00:01:29,621 So we created a new file and saved it as __init__.py. 21 00:01:29,621 --> 00:01:36,590 Then we created a second file in which we will write our custom tags and filters. 22 00:01:36,590 --> 00:01:41,010 We called that course_extras.py, since these are the extra tags for 23 00:01:41,010 --> 00:01:42,460 the course's app. 24 00:01:42,460 --> 00:01:44,180 Now we're ready to get started. 25 00:01:44,180 --> 00:01:48,830 Since this is a template tag, we need to import the template module from Django. 26 00:01:51,910 --> 00:01:55,650 That's because the template module contains the function we need to register 27 00:01:55,650 --> 00:01:57,030 our template. 28 00:01:57,030 --> 00:02:01,250 When you register your template tag, what you're doing is making it available to 29 00:02:01,250 --> 00:02:04,330 Django's template language so you can use it. 30 00:02:04,330 --> 00:02:07,470 So let's go ahead and create a variable called register, 31 00:02:07,470 --> 00:02:11,096 that calls the class we'll need later, and save ourselves some typing. 32 00:02:11,096 --> 00:02:18,120 So register equals template.library. 33 00:02:18,120 --> 00:02:22,190 This is basic Python code, but let's review what we just did. 34 00:02:22,190 --> 00:02:28,330 We instantiated an instance of the library class located in the template library and 35 00:02:28,330 --> 00:02:30,970 named that instance register. 36 00:02:30,970 --> 00:02:34,610 Okay, now we're ready to start writing our template tag. 37 00:02:34,610 --> 00:02:38,440 A template tag is just a function that does a specific thing and 38 00:02:38,440 --> 00:02:42,350 you can plug it into your template using regular template syntax. 39 00:02:42,350 --> 00:02:44,660 Like all functions, it needs to be defined. 40 00:02:47,981 --> 00:02:51,960 And then we can add a nice doc string to let us know what this function does. 41 00:02:53,030 --> 00:02:59,770 So it gets the most recent course that was added to the library. 42 00:02:59,770 --> 00:03:01,980 Now, we need to create our query. 43 00:03:01,980 --> 00:03:06,091 We know we want to return the latest course from the course model so 44 00:03:06,091 --> 00:03:09,551 we can use a method called latest to get at that like so. 45 00:03:15,650 --> 00:03:21,520 We have to pass in the field in the model that we want latest to pay attention to. 46 00:03:21,520 --> 00:03:25,020 In this case, we're concerned with the creation date, so 47 00:03:25,020 --> 00:03:29,490 we used the created_at field to get the latest course. 48 00:03:29,490 --> 00:03:31,000 Now, do you see what I see? 49 00:03:31,000 --> 00:03:34,770 We're using the course model, but we haven't imported it yet. 50 00:03:34,770 --> 00:03:38,100 So let's add that to our import statement. 51 00:03:38,100 --> 00:03:44,640 From courses.models import Course. 52 00:03:44,640 --> 00:03:47,350 The last thing we need to do is register our tag. 53 00:03:47,350 --> 00:03:51,480 There are a few different kinds of custom template tags, and 54 00:03:51,480 --> 00:03:53,540 we'll go over those later. 55 00:03:53,540 --> 00:03:57,750 This one is a simple tag, which returns its result as a string. 56 00:03:57,750 --> 00:04:01,840 There are two different ways to register your tag. 57 00:04:01,840 --> 00:04:03,114 There's the long way. 58 00:04:03,114 --> 00:04:08,840 Register.simple_tag and then you feed in 59 00:04:08,840 --> 00:04:13,730 the name of your tag, and that works fine, we just add it right below our function. 60 00:04:13,730 --> 00:04:18,060 But there's a shorter and slightly cleaner way to do this. 61 00:04:18,060 --> 00:04:24,330 We can use a decorator right before our function and 62 00:04:24,330 --> 00:04:26,820 then we don't have to feed in anything. 63 00:04:26,820 --> 00:04:29,370 Now in order for our template tag to show up, 64 00:04:29,370 --> 00:04:33,690 we have to let the template we're dropping it into know that it exists. 65 00:04:33,690 --> 00:04:38,830 Just like you have to use the extends tag to say this template will extend that 66 00:04:38,830 --> 00:04:45,160 other template, and you use the load tag to say I want to load the static files. 67 00:04:45,160 --> 00:04:50,250 You can also use the load tag, to load your template tags into a template, and 68 00:04:50,250 --> 00:04:53,200 make them more accessible to that template. 69 00:04:53,200 --> 00:04:56,840 We want this tag to appear in our layout.html template, 70 00:04:56,840 --> 00:04:59,320 so let's open that up. 71 00:04:59,320 --> 00:05:04,012 We add the load tag to the top of the page. 72 00:05:04,012 --> 00:05:07,690 Load course_extras, 73 00:05:07,690 --> 00:05:12,050 and now we can use our template tag to get the most recent course. 74 00:05:12,050 --> 00:05:16,930 So right here before the block content, we add a p tag and it can say, 75 00:05:16,930 --> 00:05:23,420 don't miss our latest course and then we just drop in our tag. 76 00:05:23,420 --> 00:05:24,900 Now let's start our server. 77 00:05:27,380 --> 00:05:31,612 So we can change directories into our learning site and 78 00:05:31,612 --> 00:05:34,740 then run python manage.py runserver. 79 00:05:39,921 --> 00:05:44,350 And now here at the top we can see don't miss our latest course, Python Testing. 80 00:05:45,520 --> 00:05:50,120 You might be wondering why we created this as a tag instead of just 81 00:05:50,120 --> 00:05:54,470 getting this information in the view and passing it in through the template. 82 00:05:54,470 --> 00:05:55,530 And we could have done that. 83 00:05:56,840 --> 00:06:00,220 But using the template tag for this makes the code more reusable. 84 00:06:01,450 --> 00:06:03,220 Once we've written that tag, 85 00:06:03,220 --> 00:06:06,530 we don't have to perform the work of calling the function, 86 00:06:06,530 --> 00:06:11,770 returning the value, and adding the template variable where we want it. 87 00:06:11,770 --> 00:06:15,690 We just drop the tag in and we're done, easy huh? 88 00:06:17,040 --> 00:06:21,760 You can also create template tags that take context, for example, that take 89 00:06:21,760 --> 00:06:26,440 a string and use it to look something up or that transform it in some way. 90 00:06:26,440 --> 00:06:28,310 We'll get to that in a later video.