 Are we good from camera people? Good from everybody else? All right, so I'll probably start off with hello everybody. I'm Benjamin Lupton. I've been doing JavaScript for a very long time and doing freelancing with web development for a very long time. And one of the projects I've ended up creating is a project called DuckPad. Now, DuckPad's a static site generator. Can I get a raise of hands of who knows what static site generators are? All right, so about half the crowd. So what's kind of happened over the past few years is things got really, really complicated with web development. Suddenly, it wasn't just about HTML, CSS, and JavaScript. It was about databases as well and back-end development. And front-end web developers needed to learn a lot about back-end development as well. And we had to set up databases just to do HTML, CSS, and JavaScript work. And static site generators solved that problem by allowing web developers, front-end web developers, to code websites, powerful websites without really having to deal with back-ends and databases and a whole lot of other dependencies. And why you should care is probably precisely for that reason. Why we should care about DuckPad is we have some things that makes us a bit different from other static site generators like Jackal. Jackal is probably the most popular one. It came up by one of the GitHub co-founders, called Tom Preston Werner, I believe. However, it's a bit limiting because it's only designed for a specific use case, which is blogging. And when I discovered all about Jackal, I was like, this is such a great idea. Like being able to do away with these back-end stuff, empowering web developers to be able to do all that stuff without back-ends. And we're like, oh, yeah, that sounds awesome. But I want to use this for more than just blogging. And it's kind of like there was an evolution of programming, or at least in web development over the years. Over in the 90s, we just had HTML, CSS, and JavaScript. And it was pretty fun, right? There was not really any dependencies, and we hacked on it, and we could see what we're doing pretty easily. Then around 2000, we started getting abstractions. We started wanting to do more. We wanted to be able to pull in content from other places. And we didn't want to have to redo our layouts every single time. So we started using technologies like PHP or like Ruby. And eventually, things got even more complicated because then we had to start using things like Rails and WordPress for blogging and Django and all these different CMSs. Front-end web developers stopped being front-end web developers and they started becoming CMS developers. And it's kind of like, why? Why do we have to do this when it's detracting so much from our actual skill level? And not only that, as we start applying these abstractions on the back-end, we also open up to security problems as well. Because back in the 90s, we just had HTML, CSS, and JavaScript. It was basically, we just served it and that was it. We just did a simple job. Then we started interacting with databases and opening us up to my score on injections and a whole bunch of other really weird things like SSSS exploits, so you're allowing people to run JavaScript on your website. So we started getting a problem of insecurity. We also got the problem of, if I want to deploy my website, I had to find a web server or a web host that actually supports the technologies I want to use. We had to start paying like $25 a month for a web server that supports PHP. And it started becoming this expensive, time-consuming, and insecure process. And that's where static site generators are like, booyah, let's do the way of the 90s where we can just focus on the core technologies, but let's do it in a way where we still have abstractions. So we still have all the power that we came out in 2000. And the way it does that is we have a process which is we have a generation step and that generation step kind of compiles our website. So often if we've worked with desktop programming languages, like say C, we have to compile C. Who here is familiar with compilation by a raise of hands? Okay, still about half the crowd, that's cool. So pretty much compilation has always been a step where we get some source input and we compile it to something else. So we get all our abstractions and we can compile it to something we can deploy a lot of places. And this happened with front-end web development quite explosively. We came out with things like CoffeeScript for JavaScript. So we could benefit from all these new technologies, like better syntax or better coding standards or more powerful abstractions, which CoffeeScript provides for JavaScript while still supporting everything JavaScript supports. So we went from CoffeeScript to JavaScript. And we saw that with CSS a lot. CSS hasn't really evolved that much in terms of the syntax over the past 10 years or 15 years. It's always been this very basic cascading style sheets and things like less CSS came on and things like SAS came out, which allowed us to do what we want with a lot more flexibility and a lot more power. So we were able to then write a lot less and do a lot more. And that got adopted incredibly widely. And static site generators are kind of like that equivalent, the SAS to CSS or the less CSS to CSS equivalent or the CoffeeScript to JavaScript equivalent, but for HTML. So we kind of compile our HTML as well as see other assets. So we get all those benefits. Now, can I get some water? Is that possible? I've run out of water. Water. Water is? Ah, is that out of the water bottles? Thanks. So from there on, let's actually, I'll skip the kitchen sink for now. And we'll go with getting started. And we'll just jump straight in, if that's okay with you. All right, so let's make a new website. So my website CD into it. And the way we installed dot pad, it's pretty easy. We installed it with the node package manager and we just write that and then I'll install it to our computer. Now this step is required because we use Node.js. Who here knows of Node.js? Why raise of hands? Cool, a lot of people. So Node.js allows us to run JavaScript on the server-side sunny. These web developers who could only do what they love in the browser are now empowered to do it on the desktop side as well. We can now interact with the file system and we can do so in a very unique way. Node allows us to do multiple things at the same time without having to worry about complicated things like threading, which is really amazing. It takes the event system we're used to on front-end web development, like jQuery on click handlers or jQuery when the DOM is ready. And it allows us to apply that same principle on desktop applications. So it allows us to accomplish a lot without that much actual code or requirements of understanding how the intricacies of desktop programming actually need to work. And Node.js exploded. It's used by Cloud9 and Mozilla, LinkedIn, tons and tons of people. Right now these are the showcases and there's so much evidence for why JavaScript on the server makes sense. And generally with PHP, we've had to go about it in a way where we serve it by our Apache and you receive a request and then it dies, right? So you do all your programming or you receive the request, it does all its work and then it just falls down and it dies. And if it gets everything and that process repeats every single time. When Node is a lot more similar to C-sharp or C-programming where we write something that stays alive the entire time. So with Node, we actually write the web server ourselves. So Node allows us to do some pretty interesting things in regards to networking, but it also allows us to do a lot of interesting things with the file system because of its abilities to do multiple things at the same time. So it can be quite fast. Now to install Node.js or to install Dockpad, we have some instructions which is just right here. This will go into how you install Node.js for Windows and Mac and things like that. It's quite simple. And there are our latest instructions on how to install Dockpad. Once we've got Dockpad installed, so if we run that, it'll go away and install it. Do you only when we want to go with a website will create a new directory for a website? We've already done that and then it's the simplest running Dockpad run. This will, great. So what it's just done is it's detected we're in an empty directory and it's asked us if we would like to start with an existing project. So there's things like Hasemore 5 boilerplate, Twitter Bootstrap, KitchenSync, my own website here and even Dockpad's website along with a whole bunch of others that have been submitted by the community. Which is quite nifty so we can get started pretty easily. Right now though, we'll probably just get started without, let's think, let's think. Actually, I won't use a skeleton in this case because we'll just get started with the very basics and I can show you how it all works. So we'll actually say no skeleton and it'll just go not create our stuff. And if we edit this directory, we'll see that it's created the source folder for us. This is where the source of our website goes. And we have three directories here. Documents, files and layouts. What on earth are these? So layouts are probably what we're quite familiar with if we've done WebProgram before. So it allows us to abstract like our header and our footer into a particular section so we don't have to keep recording it every single time. Files are just standard files that we don't want to compile. For instance, images or just a standard JS file like jQuery. We never want to compile jQuery. And documents are files we do want to compile. So for instance, mark down to HTML. So let's just get started and we'll start writing a basic Hello World page. Now generally with HTML, it's a bit ugly. We have to write all this boilerplate. So Hello World. And we can see right here that DocPads already detected that and it's regenerated our website. And we can see now we have this out directory which is where it's actually compiled the source. So it's figured, okay, we've got this source file which we just wrote. Let's compile that to our art directory. Now it hasn't needed to do anything because so far we're just writing plain HTML. But if we want to write like another page, for instance, I don't know, maybe Hello Mars, we have to start writing all of this again with the way we traditionally do things. And it's a bit ridiculous that we have to do this. No one wants to duplicate and waste their time. Emmet, this is cool. Did you know that Emmet website is done with DocPad? Ah-ha-ha. So yeah, there's a way so we can do this. How is it? It's like, I have Emmet installed. What's the actual short key for that? Yeah, see? So that's one way we can do it. We can make the process of writing this easier but we still have this duplicated stuff. We still have, okay, hey, I love that. And then, probably, isn't that nifty? So Hello Mars. But if we would change, perhaps if we add some more stuff here, like our, I don't know, what commonly goes here? Maybe our char set. Meta, I don't know, named char set. Oh, our style sheets as well. So we have all of this other stuff that goes here and we don't want to have to copy and paste that between every single page we write. And that's where layouts come in. We're probably very familiar with layouts. So let's actually go and create a layout now and find out what this will look like. Let's just call it the default layout. And as soon as we start applying abstract, I'll just copy what we wrote from index and I'll paste it into the default layout. And let's say, so this would be our page content, right? This would probably be our page title. And we would actually go about this by just adding it in this metadata section. So let's say, our title for this page is Hello World. And we want to use this layout default. And then everything inside here becomes our content. So in this case, it's Hello World. And then let's make it a bit different from the title so we can actually see. Nice to see you today. It's all good to wake up in the morning. And now in our layout, we would start using templating engines. So it becomes as easy as writing document title if I can spell correctly. And then our document content. Oh no, just content here. So let's take a look at what this now becomes. Just that. Can anyone guess why? The name is different? No. Can anyone else guess? Yeah. Can we use the VGOS? Yeah, yeah. So the way Node.js kind of works is they have a philosophy of being as minimalistic as possible. So instead of getting absolutely everything you need, you only get what you actually, no, everything you could possibly need, you only actually get what you need. So now we actually have to tell docpad to use our plugin for that. And we used the echo templating engine. We can see this by this extension here, .echo. So we have to install that plugin. And installing plugins is just like that. Now this will go to NPM, it'll download our plugin and this plugin now installs this echo dependency and echo has this dependency and this dependency and this dependency. So it's gone and installed this. Now at the currently we have to rerun docpad when we install a new plugin but perhaps it will change that in the future. So if we refresh, we now have that pretty abstraction and we can see by our title for a thing it's actually inserted it there. And if we view the source, we've got what we wanted, right? We've now got the benefit of having layouts, the abstraction of layouts. And as we can see in our out directory, it's now compiled that it's compiled our source directory into this index.hml file that we can deploy anyway because it's not doing anything special. It's not dependent on this layout engine once we've actually compiled it. So unlike say PHP where we have this which goes on PHP, we'll probably do it something like this PHP require maybe our header, right? Dot phtml. And every single time we receive this request, it goes away and it re-renders it every single time. When this way it renders it once and we can deploy that anywhere. Does everyone get that? Yes? Sweet. So yeah, docpad support as many as you want. So it's just run by plugins. So if we would jump to the, that's my company's website. If we jump to the plugin section, these are all the ones we currently support and the conversions they do. I like to use whichever one's best for the circumstance. So generally I find echo, which is what we use right there is the most beginner friendly because it's very similar to hastemill. It's very similar to eRuby or phtml, the ones we've already gone in use to. When we, yep. So I'm not sure if this applies, but so is this like I can only use it for static data or can I also use it for dynamic data? Good question. We'll jump ahead and I'll answer that right now for you. I've got that a bit later. So let's say on our layout because we've already got our layout dynamic or using a templating engine, we wanna add a dynamic thing. So let's say math.random. So echo just executes coffee script inside here. We could make it JavaScript, but then if we're starting to do if loops, we have to do all these brackets and maybe a thing like that and then it gets a bit messy. Coffee script probably allows us to just do that. So I'm a lot cleaner syntax. Or say if our document title doesn't exist, we could say all rather than doing that. So coffee script is just the nicest syntax and echo is embedded coffee script. So let's put some JavaScript code here, which is a random number. Now, DuckPad tells us by the ground notification, it's all good. So we've got a random number here, but right now it's just on a static compile. So it's gonna be the same for every time. But if we wanna make this dynamic, so re-renders on every request, it's as easy as saying, probably restarting our DuckPad instance as well. Ah, it doesn't work cause it's in the layout. Minor technical detail here. So I'll add that to the page because the pages are dynamic. It's not the layouts that are dynamic. So if we make this index file actually dynamic, we'll be able to do this. Reset our DuckPad instance. Sometimes the watching works, sometimes it doesn't. It's most of the time it works like 99%. We're going through like a rewrite of the watching run out to make it a lot better. Still a few problems here and there. So sometimes you will just have to regenerate. Like if you're renaming files, you may actually have to restart your DuckPad instance. But if you're editing files, you probably don't need to, like 99.99% of the time you don't need to. Oh, this could be, let's try it this way. I don't have a clean URLs plugin installed. So that's the reason why. But we can see here, it hasn't been added to our index.html section. I mean, to our alt, it hasn't been compiled once. Instead it compiles on every single request. So doing dynamic stuff as you would in PHP is as easy as just adding this dynamic true flag. Yeah. Yeah. So for the dynamic stuff, we use the DuckPad server, which is a ExpressJS server, which is an extended version of the Node HTTP server. So if you're doing dynamic stuff like this, then you would have to deploy to a Node.js server. You couldn't just deploy to Apache, right? Because it doesn't get generated into our alt directory. However, there's another way to do dynamic websites, or at least provide the illusion we have a dynamic website. A good example, does everyone mind this digression? Is this a cool thing to learn about? Sweet. So let's say for the BLoptim website, my website, and just hopefully the resolution supports it, it does. So right here, I've got this dynamic content. So it's pulling in my GitHub stuff. It's pulling in my Twitter stuff. My reputation here is dynamic as well. My rankings on GitHub are dynamic. My followers, all this stuff is dynamic data. So during the generation process, it pulls all this dynamic data in and parse our website. Now, the illusion here is that I actually tell DuckPad to regenerate every hour. So I can benefit from actually having it generate once, but it will generate every hour. So it gets this illusion. It's very, very, very fast because of this. That's another benefit of static site generation I didn't go by, because if we're re-rendering everything on each request, it becomes incredibly slow. When, if we're doing, actually, I've got like a benchmark, but we have benchmarks which we can see, but generally last time I tested it, DuckPad can serve 4,000 requests a second with the Node.js server. So that's pretty cool because it's just serving static content. So I'll cover this a bit later. I'll go into more detail about how we accomplish this pulling in the external data. So let's get back to our basic stuff. We'll remove this extension and we'll go back to our standard stuff and we've got rid of that dynamic tree. So again, it's compared to our art directory. And we're all good. So let's make this Mars page dynamic as well, just to showcase layouts for those who are quite new to web development. So hello Mars. Hello Mars. You are a long way from Earth. I should get some less tabs perhaps. All right. And if we go to Mars, then we get that benefit, right? We've got our layout we can see in the title bar. We've got hello Mars. So now we've got the benefit of layouts. But we can go a bit further. We can always go a bit further. And let's find out how. Probably live reload, that would probably be a good thing. So it's getting a bit annoying that when I say hello, I have to refresh my browser every single time. So I'll close you. I can just close you. So wouldn't it be nice if every single time I save it, my browser actually refreshes. We would all like that, right? And this is something where initially I was just like, this isn't that cool. I'm used to just pressing command R and refreshing my browser, but it really does make the process a lot easier. So we'll install another plugin. So the live reload plugin. I have to write the install command, which is an O. And this is another benefit of Node.js because Node.js, because it's able to do so much stuff on this networking, this Node, the web server level, we're able to do pretty nifty things. Traditionally, to do real-time abilities, we've had to talk to an external server like Pusha or open a web socket connection to a special type of server that's able to handle lots of stuff very, very quickly. Now, Node.js has this ability built in. The live reload plugin uses the thing called Socket.io, which allows us to open a web socket connection directly to the server. And in the instance of the live reload plugin, we actually open a connection from our browser directly to the dockpad server. And the dockpad server tells the browser, hey, look, I've been regenerated right now. Now, if I actually, I'll restart my dockpad server. Now, if I write stuff, it didn't work. And it's because we haven't actually told our template right now that we want to use live reload. We have to start getting a bit more advanced right now. So this then becomes get block styles. To HTML, I believe. We also have Meta and we also have Scripts. So generating these are the things that we inject into our websites all the time. Stiles are CSS, Meta, Meta tags, and Scripts are our JavaScripts. Now, the reason why we have these concepts with blocks is so plugins can inject Scripts or inject Meta or inject styles into our actual website. Otherwise, we don't have that way. Now, we could go the route of modifying the request, like modifying the HTML on the output, but that's some magic. And I'm a bit against magic because it implies that we have to know some stuff or we could go around and we could shoot our foot off eventually. At least with being explicit like this, we will never be able to shoot our foot off because we know what's going on. But it's still pretty easy. I mean, that was like three lines of additional code. So now, if we look at our HTML, if we refresh, we will see now that it's injected, this powered by dot pad thing. This is optional, you don't need it, but it's injected the script here, which is our live reload script. So now, it's actually opened the connection to our web server. And if I refresh our index page, see, we can see now that it's reloading automatically because of this live reload script. So I'm just saving and it's reloading. That's pretty nifty. That's pretty cool. So let's go to the next step, which would be, we covered blocks. Yep. Yep. Yeah, that's a great question. So live reload is taught to only run on the development environment. And dot pad has the concept environment. So there's development, there's production, and there's static. They're the three ones that dot pad Johnny knows about. So production, some pre-processes have the ability to minify directly on that. So detect, okay, we're in the production environment, minify right away. So compile, minify the outputs for our CSS JavaScript and things like that. The live reload plugin is told, so when, when on an environment that isn't development, disable it. So right now, I'll close this one. I'll get back to here. So we'll see, yeah, it's compiled it right here. So in our output, our static output, we have the script stuff. But if we were to deploy to GitHub pages or Apache, we'd actually tell dot pad, I think it's generate, generate. We'd tell it to compile for a static environment. And doing so, we don't get the live reload or any other dynamic ability. This comes into play with the clean URLs plugin as well, because if we're running on the Node.js server, then this is nifty. Because the clean URLs plugin just cares whether or not we're on Node.js or whether on a static environment. If we're on the Node.js environment, which is anything but the static environment, then it'll actually just extend the Express.js, the Node web server. So we don't have to do that much complicated. We just say, okay, we got a request coming in, is it this clean URL, serve the correct content? But if we're on a static environment, then it'll actually generate hastemill files for each of the particular pages, which will then redirect to the correct page. So nifty stuff going on there. Good question, great question. So we'll go back into our development environment. And we can see the environment right here, and we can see which plugins we're currently using. Can we generate for the Node.js server? Yeah, yeah, so the static is like, assumes Apache GitHub pages, anything static. If it's not that, then we're going to pre-assume that we're on a Node.js web server. And yeah, here's the live relay plugin saying, you know, we're listening, things like that. Any questions at this point, any confusion about what I've covered so far? Fantastic. Not that having a question would have been bad. All right, so this is okay. This is a bit boring. Oh, it's cool, but we want to get cool, all right? It's not that exciting yet. And generally the next thing we'll probably want to do is we'll probably do a blog. We're all probably pretty familiar with blogging. And while we could write our blog posts, let's say, let's say, Hi, Meta Refresh, we were there. If we write in in HTML and use the things we already know, so we've got Hi, Meta Refresh, and add our layout, so the layout default. This is just YAML data for anyone wondering. So YAML is kind of like JSON, but it's a bit more lenient. We can also pass this as coffee script by writing just coffee here, or CSUN, which is another dialect of coffee script. So we could actually start doing advanced stuff, like putting a self-executing function in here and start doing some complicated things. I'd be crazy, but we do have that support if you don't like the YAML syntax. So let's say that was such an amazing conference. Indio is awesome. And we can see now that it's generated this page in our output directory, and that's okay. But if we want to add some emphasis, and we really want to emphasize it was an amazing conference, we want to probably make it bold. And if we open that up, so localhost, blog, Hi, Meta Refresh. All right, it's like that. But if we're running a really long blog post, we don't want to be running HTML. Generally, GitHub and Stack Overflow realize this. We're programmers, we like abstractions, we like to make things pretty simple. And who's used GitHub or Stack Overflow here? We're Acer fans. Cool, sweet, everybody. Who here knows that it uses markdown for the comments? Sweet, everyone like markdown? Fantastic. So with markdown, we can write the same thing like that. It's a lot more expressive. And especially when it comes to links, instead of having to write blah, blah, blah, blah, let's say Google, that would actually become Google. And then the link here. It just allows a bit more expressive way of writing things. So I'll save that. And let's go about adding markdown. So we'll add markdown and we'll install the plugin. Now markdown has a few different varieties of the dialect. We've got the GitHub flavor and markdown. We've got like the standard Grubber one, but there's lots of implementations. The one we generally use is marked, marked supports to GitHub favor and markdown by default, but it's implemented in native JavaScript. So it's really, really fast. Originally, we just had markdown, but as the dialects continue, we added support for the different dialects. So now you just pick the dialect you actually want. Yes, a mobile blog. What do you mean? This is the advanced stuff. Yeah, I'll cover that later and how we can extend this even further. So that's when things start getting, we're on the intro to craziness right now, excitement. So, yeah. So GitHub flavor and markdown. Oh, with marked, there's two options. One is sanitized and one is without sanitization. So by default, we have sanitization turned off, which allows you to just write HTML inside it. Okay, so that's gone ahead and generated all of that. And where am I? Oh, that's the output directory. So see how we have HTML right here. So because sanitization is off, we can just write HTML as well. So we'll restart our docpad server and let's check that out. Oh, I renamed that one in the output directory, silly me. So I have to add that extension. Now, who has worked with Rails before? So one person. So a nifty thing Rails does is it's got a thing called an asset pipeline, which allows people to kind of go from markdown to HTML. So there's this conversion and just like for echo to HTML. A lot of things that other compilers do is they would just have dot markdown here and then it would compile to HTML. So it assumes there's only one way we can compile a particular language. Something like CoffeeScript can actually be compiled to HTML rather than just JavaScript. There's dialects to support that. So we're quite explicit in the way we can do things. So this goes directly from markdown to HTML. And this ability allows us to, if I add the echo extension here to go from echo to markdown to HTML, if I wanna add some more dynamic abilities to my markdown document. So right now we can see that it's now rendered on markdown. We've got that old link here, we've got the new link here, this bit here, renders to that, and we've got that rendering to that and our amazing rendering to that. So we're now starting to discover, hey, we can now have preprocessors for pretty much whatever I want. But we like to add some more dynamic stuff. No one's gonna go to my blog and then know exactly that, hey, this is the link I need to go to. I need to start adding a listing of my content. Now I could go about this, like if I was in the 90s, I'd probably say, okay, I'll now code and say, blog, hi meta refresh. But that's not that maintainable. Whenever we have to add a blog post, we have to redo it here. Now, a nifty thing DocPad does is during this generation process, the way the generation process works, is we'll go through and we'll pass all of the stuff in our source directory into an in-memory database. That database is powered by Backbone.js. So everything is added to just a Backbone.js collection. And everyone who's familiar with Backbone.js, a lot of people, that's really cool. But by default, Backbone.js doesn't really provide us with a way of curing our collections to really say, okay, find me everything that matches this or find me all of this that does that. It provides some comp, like these pragmatic ways where we can write some code to be able to do it, like add a function and things like that. But really, we like a really simple syntax to do it. And Mongo has a great syntax for this. Mongo database, like a NoSQL syntax. So let's actually make this index.hasmall page a echo. So we can start adding our listing, adding some dynamic stuff. And we'll say, okay, for post in get collection, so in our documents, find all that have the relative, actually, I think it's relative out path. Let me check. There's always good thing about having great documentation. Docs template, no, it's metadata. So all this documentation is actually written in markdown and we generate it with docpad. So we can find out the thing we actually want. So relative outer path, that's the one we want. So that's the directory, the relative directory of the relative path of the directory that blog post goes in. So we want to, whoops, wrong place, make that equal. Can I reduce the font so I can actually see what I'm doing? Can people still read that? Fantastic. How about that? Is that too small? That's, okay, so that, that's good. All right. So relative outer path blog to Jason. That's a bit odd. Let's add, oh, that is a title. Oh, it's just not formatted. I was like, okay. Maybe I should have done like a, something we probably would have done if we were writing something proper. I like it how people are paying attention. So there we go. So we've now got this listing. So we've got a few collections, which is the documents collection, the files collection, the layouts collection. There's some other predefined ones that we have, but what we're saying right now is for all the documents, let's get everything which has the output directory path of blog. We could also make it, so I can say. What exactly is documents or issues that you're putting in there? Yeah, so I just close this directory and we'll just get rid of this find all part. So we can actually see everything that's in there. And let's just say, let's make it the file name instead. So the documents directory is just everything, or the documents collection is just everything in our documents directory. Now we could do it by get database and then get everything that DocPad is aware of. Generally we don't wanna do that because we have some intelligent generation. So we only regenerate what we actually have to. And if we use get database, then if we modify anything, then DocPad's gonna think, okay, we have to re-render this page. So we always wanna be as specific as possible so that way DocPad can only re-render what we need to. I'll showcase this right now. So if I say re-render this, and we'll go back to the title. So we can see the title. And I'll put that over here. And if I re, whoa! And if I re-render, like edit this page, then DocPad's gonna regenerate that index.hasmile file because it knows that index.hasmile file references that blog post. So that's why we're able to perform regenerations in like 20 milliseconds. Pretty cool stuff. So from this, let's just add our actual link to it. So here we've used the double equals because we wanna escape that content. Here, we probably always wanna use that except for the content. We wanna output that probably as raw HTML. This is raw HTML, this is raw HTML. This we actually probably wanna sanitize. So if someone's put a title of say, math is cool. I know five is less than 10, right? Now, if we, that was actually outputted without sanitization, that would go directly in here and then would end up with in app, invalid markup, right? Because of this arrow. When really, we want that to actually be escaped correctly. So it is sanitized. The double equals will allow that, that's just the echoes approach to it. Different templating engines will have their own approach. So we've now got that pref going and now we can actually go through up different pages. Post-art HTML, that's definitely not correct. URL, there we go. So now we can go through and we felt like a link going. This is crazy because like previously we would have to do this as like a dynamic thing. We would need like some backend to re-render this every single time. Static site generation, we can just do that and compiles it for us and we can deploy this to Apache, whatever. It just does it once. So every single time I re-render, you know, it's just serving that static file. Pretty crazy, right? I think it's like, it blows my mind how we can do this today. So that's pretty nifty, I think so. But let's go back to doing our blog post. So it's what, find all relative out the path and then blog, right? Something like that. So we're just showing our blog post, cool. Now this isn't good enough because when we perform this regeneration we still have to get everything in documents then we have to get everything inside the find everything inside documents that matches that. And if we've got a website of like a thousand documents that can be a time-consuming process, right? And if we've got a lot of pages that depend on other pages it can get quite expensive. It can be quite time-consuming. So wouldn't it be great if we could already know which pages are our blog posts without having to re-query that every single time? That would be pretty cool. So DocPad provides us with the ability to specify a configuration file. And that configuration file can be JavaScript, JSON, CoffeeScript, or a dialect called CSUN. There's different reasons why we would use the different ones for it. Now we'll use just plain old CoffeeScript. And because we're in a Node.js environment we have to export our CoffeeScript object. So this is our DocPad configuration. And we like to define a collection called, I guess, post. And we like to say get the collection or rather we like to produce copy and paste, right? So now that will be able to get all our blog posts and just kind of do it once. But there is an issue here. The issue is that this find all says, okay, get everything inside documents, just give me the blog posts. And it kind of just leaves it there. We have this ability to say make it live. So that way whenever we're doing regenerations or we change things, then DocPad will know, okay, this meta refresh page, perhaps I delete that. And I want that to be reflected in this post collection. So live is always keeping this data up to date. It's always keeping this collection up to date with the latest stuff. And this is crazily fast. Because whenever a change happens, that's then when, so in the database, it would say, okay, a change has happened. Does this change reflect the criteria of our child collections? Okay, it reflects the criteria of our documents collection. Great, add it to documents. Okay, it reflects the criteria of our post collection added to post. So it allows us a way of tripping down changes and only actually querying things when things actually change, rather than querying things every single, single time. Which is quite effective. The use case of this gets a lot more important when we start doing crazy things. But this ability is actually used on a website called Bugherd. They do bug tracking, like visual bug tracking. And they kind of have like this sidebar that goes on right. I'm not sure whether they would actually have it. But ah, here's like this nice tiny little sidebar. If we can see that. So the backlog is its own collection. This is its own collection. This is its own collection. And this is a collection. This section here is a collection. So when something is added to the database, it goes to this collection and says, does this new thing match this criteria for this one? If yes, add it to this collection. And then this one says, okay, something was added here. Does it match our criteria? Maybe yes, and then we'll add it here. This one will say, okay, something was added here. Does it pass? No, it doesn't. So it doesn't add it. So that way, instead of us, whenever we click this, we have to rescan everything. It's always up to date. It's always current. This is pretty nifty. But if you don't get it, you only have to write, just add live there and it's all okay. So it's not that big of a deal. So we now say, we've now defined this custom collection called post. And now if we go back, we've still got the, cannot call it to JSON. We have to restart our docpad thing because we modify the configuration file. This is being fixed right now. So probably next week, you won't have to do that when you reload your configuration file, where we've got a bunch of contributors always match.