 Dockpad website to regenerate right then so that way we don't have to keep doing regenerate every 24 hours We just have to regenerate when changes happen Huh? Yeah, so Yeah, yeah, yeah, so yeah, we pull it in Just once and we expose that to the to the template engine Yeah, this this it's surprising how unreliable some API's are So this used to be a problem. It's no longer a problem originally like say six months ago My website would just like go down and I was just like what is this happening? And it's because like, you know when JavaScript tries to access something that wasn't actually there then JavaScript like has a panic attack, right? So but now If we have a feed that did pass like, you know, it was about adjacent. We'll just use the case copy of it However, if they change the syntax or the behavior, you have to have checks to make sure the Syntax is what you are expecting with coffee script. That's pretty easy because we could just say You know, if that tweet is actually there then go in and create it out. But right now we just assumed that It's all going to be okay It's set for this bit here. We have this all array Sometimes we could just get back an empty string or maybe like it just corrupted Jason in which case We just want to fall back to an empty array and then just not show anything And that's if it didn't already have something successful in the case Yeah well My my Twitter stuff doesn't update that much So it's just like do I want to hit the performance impact of always fetching that so often or do I want to just You know put it in once every hour and then have that real big performance hit And that's like one of the benefits that people have found with docpads They can get hit by hacking news or whatever and the website won't crash All right, which happens like so often because it's just static stuff. So that's one of the benefits there Yeah, so that's why we've gone this direction of the static side generation like you get that speed and If you need that dynamic stuff, just tell it to regenerate more or add that dynamic true header If you really want it to redo everything every single time So What's next what do we have next? Blogging we covered blogging we covered collections Often a question is how can actually do RSS and Adam and It's it's it's the same way as you would this listing here We would just add a RSS file. We can see this on the beverage website I mean the be a lupton website. We just have this Adam file So let's say this is just XML So we just define our XML structure and then we say okay go through post and just output everything that's how we would do an RSS feed now let's get into more advanced stuff and and Let's say I actually want to have a side title for my website that stays the same. So I probably want to say my awesome Website and then I would probably want to show the page title, right? That's generally how we do things So I could put it there and then we now see in the title. I now have my awesome website But this probably shouldn't go in our layout This should probably just go in one place where we can define all the special data for our website so Does everyone agree? I would agree So we can actually extend the template data ourselves So let's call this let's add site and we'll add the title my awesome website So now we've just added This so we can just say okay now expose our site title and In this case stockpad picked up that template data change and we can see we've now got my awesome website Let's just call this awesome website and yeah, it's worked So now we're actually taking stuff out of our layouts and adding it to our template data This gets quite important because we can now start adding common abstractions into our template data as well I can put functions in here as if I want and what we saw earlier with the get collection That is just a function exposed to our template data that takes in like a name something like that and then it says okay get the database collection and then I Think get child collection or something like that and actually pull in the name So we can just write functions in here Just as we would normally an interesting thing Probably worth noting with coffee script is the last statement is always returned. So this is exactly the same as writing return Which allows us to write pretty neat like one line is that a so concise Now another thing some people may be wondering is what is this at what is this at symbol I keep seeing places? It's exactly the same as just writing this. It's just a nicer convention that dot pad provides So we would have seen this in our index page We have for instance, we say okay this dot get collection. So That's fetching the get collection function from our template data and this post variable is just defined locally Inside our template data or inside our template engine as it executes. So that that's just what that's about but Let's for a jump to see how these abstractions can actually apply in like a real-world website So they're like the dot pad website. I mean the be a Lupton website. So I'll learn to type correctly at some point and Let's say for this ranking. I don't actually want like This ranking is pulled in dynamically. It could be two three five a hundred I don't really know but because that I will still want to say second. So in my coffee script file I say okay get rank and then it'll tell me which Suffix I should use for that rank and in my template data. I would have an assist like a template helper to say okay get the Get the stuff from the feeder. So this uses stuff and then Find myself in there and add the appropriate suffix if that feed fails just return what I thought I was last time, right? so we can start doing Extending the template data with our own helpers for instance get prepared title is used by a layout to say okay If our document actually has a title then display that title first and then the site title if our document title doesn't have a Document doesn't have a title then just show you the site title, right? So some pretty basic abstractions were able to move out into a template data rather than actually having in every single layout now For this be a laptop website We have multiple layouts because our posts have a different layout to our index page We probably want to show that for our post we probably sure want to show the heading and This is I just love coffee cup So here we say okay If we have the document title for this blog post or whatever is using this Then actually show you this header with the page title and then like the date this was made Output up content things like that so It's it's pretty cool stuff now Recovered collections recovered template data. So yeah, this is like all the site data I have so I've abstracted out the URL for my website the title my email things like that Now I've even abstracted out the scripts that I use on my website So rather than having that in the layout I just have it there and it would probably look just like This so I get my blog scripts. I add the site scripts to it. So jQuery Whatever else I'm using and the benefit of adding it this way is dot pad is then aware of those scripts And if we have a plug-in that can then minify our JavaScript It can then say okay get everything inside scripts and then actually minify or concatenate it in that order Scripts is probably the blog scripts is very good because we know which order it should be in so we'll probably use that for concatenation When if we were doing minification, we'll probably go to the get collection route or maybe get database find all that have the Out extension so the compiled extension JavaScript and that way we could then go through and minify everything now When we start getting to more dynamic stuff Doc pad allows us to have particular events often at times We may want to hook into something along the doc pad process and perform a specific task For instance on my website. I have multiple domains that all point to the same things For instance, if I go to lappton.cc, which is what I use on my email then this will hit the doc pad server and Say okay is our request For the Lappton.cc domain if it is and let's redirect back to be a lappton.com. So they get that redirect I See some heads popping up. So maybe I'll do it like that and I'll probably turn on word. Is word wrap on on this one? No word wrap well So it kind of looks like that this is just using the Express.js server Express.js is a Node.js project. It's quite popular Which Provides quite a nice interface for writing a web server So by use we just say we add a middleware and a concept of middleware is when we receive a request There may be certain actions we want to perform for instance Authentication is one of those actions So we would want to say okay when we get this request go to the Authentication middleware and if we need to authenticate then let's start Authenticating if we don't need to authenticate then let's continue on to the next middleware This is what we start getting into interesting node conventions which We would often see this next callback or generally the last argument to a function is this callback generally called next So next is generally does always what we want to do when we complete or the next thing we should forward on So right here this redirect says okay, let's redirect and I want to stop there I don't want to continue on when if we don't need to redirect if we are on BLR10.com then let's continue to the next thing Whatever that may be Does that make sense to everybody? Sweet so you're gonna rock up with node when you get to it. You know one of the basics to Node.js Another thing we probably want to do is you want to extend the routes and add things like If a lease is for different projects, so this a lease is all these old URLs They used to use when I used to host my jQuery plugins on my own website We're now it actually redirects to the github page for those jQuery plugins So this is great if often at times we have We're migrating our website from somewhere else and we want to support the same URL structure So we just extend the server. We just use the server extend event and we continue on other examples For the dot pad website this this is when we start getting into some pretty nifty things our products So here I require a whole bunch of node dependencies so I can do Interesting things I Specify some different configurations because I'm using a different structure here So this is our site directory that we used to before our root directory and this is where I start Abstracting a lot more stuff out. I've used this particular project structure on projects Where I've had to do extensive extending of the Node.js web server For instance writing like a Node.js API thing which handles requests from different places So I'd use server extend and then I would probably just Do something like okay require The routes The routes file you don't need the extension with require and then just pass it over our arguments and then this routes file will handle all of our extensions to the server So one of the examples here for the server extend is whenever I get a 404 So this is if we couldn't I show you so we have some special pages Which is our 404 page? We also have a 505 page So if I can't find anything it will look for a 404 document and this particular document will do an Ajax request to my push over Route which is a custom route I've written to then notify my phone that oh my god. There's a 404. Please fix this right So don't go to the doc pad website and then just like repetitively 404 it otherwise I'll get a lot of notifications on my phone and I won't be too pleased Now for the doc pad website, I didn't mention how it pulls in Our doc pad documentation so a doc pad documentation. It's just a github repo a whole bunch of markdown files That we want to do so This is our index page and this is our metadata So we say ignore this page because this isn't part of our documentation. It's just welcome to our documentation And if we want to go to the plugins, which I believe is in yep in community Then this is our plug-in listing. So it's just a markdown file and We want to pull this into our actual doc pad website So we hook into this generate before event and we pull in this doc pad Documentation repository into our source directory. So it gets pulled into this source documents docs Every single time before a particular generation and we have a little check here If we're initial generation, so if reset is true then pull it in Otherwise if we're just a regeneration then don't pull it in otherwise Regenerations will be very very slow because we're always doing a get pull request now We do some more complicated things like that, but I don't think I'd probably need to go into that because it's getting to more Advanced things. So I think at this stage We've seen probably the power of doc pads So I'm open to questions now and we'll take this wherever you want this to go Okay So just how we would put an image in to in a doc pad website All right, so that would go into our files directory. So we have a bunch of images here So files is just anything. We don't want compiled and binary files So our images just go in this files directory. That's all there is and We would just reference it. Where would we reference that maybe in our CSS? Okay, pardon references from templates Oh, okay. Yep Okay, so Let's There's a good example of this Let's say I'm pretty sure whose website is it it's Morgan Sutherland this guy's a photographer and he's used doc pad to actually pull in so these are all these different photos that he's used and The way he would probably do this is Inside 30 minutes more. Okay, that's fine So let's go back to our basic my website and let's get a a image. I don't know Let's just save that image and I hope he doesn't mind Projects This is how to skip my website. So I'll save it to files. Let's make a new directory here called images and This is called one dot JPEG. So pretty basic Now if I wanted so we can see it's there and it's already being added to the art directory Now, let's add this to the meta refresh So I could do it in just like, you know, the image source images one dot JPEG now We go back to local host we go. So we've got that image there. That's that's one way to do it If we wanted to add that into the layout, right? If we wanted to have the layout actually perform the image rendering, then we can just add it here. So like image So this metadata can be whatever you want We can add as much metadata as we want. There are special pieces of metadata that is documented in the Dockpad documentation. So for instance layout is a special metadata It performs a specific purpose, but I could just put whatever I want here and I'll be okay so I'll add this image and Let's move that out and we'll see. Okay, it's gone now whoop and Let's add that then to a layout so if The document so the current document we're rendering has image In coffee script, we have a nice notation in which is a question mark, which is does this even exist? Right. So this kind of is the same as saying is now or Something like that, but I guess here is just if we want it to be truthy. So any non-empty value So if it has an image then let's output that image URL so document dot image so That's now putting in that data from the metadata and because we have it there it's going to be there for our index page We don't have that in our metadata Yeah, yeah, so you probably do something and generate before to pull in that dynamic content expose that to your template data And then just do something like that You could download the images into your source directory and then you could do something like you know get database Find all where the relative, you know outer path is like images, right? That's like another option available to you. So the database knows of all the files that doc has to wear off. I I'll cover one of our more advanced skeletons Yeah, yeah Yeah, they will be merged they'll be merged Yeah It would just yell at you and say you were in an unknown state Please resolve this so yeah, it's because we that that's an instance that you need to fix It's like an error. It's like do I want to do this error or that error? It's still an error. So if we have a problem that we If we have a problem in the initial generation dot pad will just crash because that's when like if we're deploying to a server We want doc pad to crash on that initial generation because otherwise doc pad could be live and we're like, oh Everything's all fine. Even though there's all these errors, right? We want that website to like go down and like Make sure we know there's an error if there's an error on a regeneration It'll just output that to the console and show our ground notification before there's an error Please fix this like we're in an unknown state Do something about it? Does that answer your question? sweet, so Let's get into One of our more advanced examples so doc pad sites CD kitchen sink So the kitchen sink is one of the skeletons the community's done up to showcase a whole bunch of Advanced things so for instance one of their use things is we can click this little button And I'll show you the source code of this particular page. We're currently on and Let's get that that up. So That's this bit here. So source is one of those special Metadata properties that doc pad handles for us. So we say, okay add this You know this section for source click to view this page of source Show the relative path of that page and show the source codes to output the source code We also have a plugin to perform syntax highlighting which with HTML We can just do highlight and then the language we want if we're in markdown We can do the thing like this so coffee and then our awesome code And it would pick that up the syntax highlighting would pit that up for us So that's why that's highlighted because we've got this syntax highlighting plugin to do it for us now This is all these different markups that are available in this particular kitchen sink so We've got our custom collection So we've got these nifty section like this nifty's collection where everything inside our nifty's directory We've got this markups section, which is all these different markers. We want to render pages post whatever and in our particular page we say All right in our markup cycle through our markups convert it to basic J's like a JavaScript objects rather than the backbone collection Because otherwise if it was JavaScript if say if we got rid of this to Jason Then we would have to do get title because now we're interacting with the backbone collections So we do to Jason to just let us just do dot title So those familiar backbone that that will be quite familiar if you're not familiar backbone does know to Jason So this actually outputs what we saw what we're seeing right here So we cycle through all our markups We show you like the document URL the title and the source code here So the document file name the original extension it had output the content replace like initial spacing and Here's the output. So use the out file name use the out extension for the syntax file I mean, so this is like an example of coffee cup to HTML. So that's the source and that's the output Coffee script to JavaScript. That's the source. That's the output and just these different things now I'll just sell basic blog post section now what one of our clients have actually done Is they've used docpad for a law firm. So the law firm Has all these internal documents So it's just an internet website and they have all these documents that they want to edit and make it accessible by the web and They've actually enabled client site editing by a content editable now This kitchen sink hasn't been kept up to date. So the client site editing doesn't work But that is an option you can go if you do want to provide a client like an Ability to edit documents within doc pad for clients because as developers we like to edit files We're okay with editing files for clients. Generally, they need a GUI content editable is one way of doing that Another way which we're exploring currently, which will probably land Quite soon. So by the end of March is a way so we can pull in Tumblr data directly into our docpad database Now with our Twitter stuff for the BL upton website. We just exposed like say these tweets as Stuff to our template data, right? So our template I will say okay for all tweets output this one up with that one But if we want to give these tweets their own page Within our website So if I want to say tweet and then the actual ID of it Then it would need a presence in the doc pad database or I would need to write a custom route for it and handle that Specifically outside of doc pad. So that's the way we're going with tumblr and also with WordPress So that way we can pull in our doc our tumblr blog post and add it directly into the source directory documents post which will be pretty pretty nifty stuff and But from that We're going to um as well The ability to do that is really really special because clients are very familiar with WordPress So we can actually use WordPress as our GUI as our admin interface and render it through doc pad So we have all the security of a static site We have all the speed and we have all the abstractions of being able to use whatever pre-process we want But we're pulling in the pages in the post from WordPress Really really cool So Yeah, yeah, so mobile editing use tumblr or use use the WordPress interface and pull that in we do The doc pad core team are not going in the direction of writing our own GUI We're leaving that up to people or were you leaving that up? So like that the client use contentable and they wrote their own content editable solution Or you can use like tumblr WordPress when that stuff gets announced on next month But if we focus on that that's like a huge can of worms that may never end and our resources are better Put towards making doc pad better So Oh Where was it I Here so here's an example of a search page So this search page takes in this query string of coffee So I could change this to Hamel and I'll fetch the Hamel document. We have this is a dynamic page So we say we've added that dynamic true and when it's a dynamic page we expose the request Object to it. This is the express.js requests object. So We would know this from the express documentation and We're able to say okay for the query inside the query string Use the query object. So that's this bit is this bit here and query is anything I have in here It probably a better name like I should have probably called this like search instead, right? And then have that as search here So we fetch the query we say what we're searching for so right now we're searching for Hamel and we just in our collection Here we don't use live Does anyone know why? Because okay. Yeah Yeah, so everything's in the doc pad database already. We're creating the doc pad database The for live that stuff we have when initially doc pack gets loaded up So live is when we listen to changes. So live is when things get added and we do the query Here is when we're actually doing a rendering. So at this point in time Everything is already in the database and we want to fetch the latest data right now. So now template Engines we would use just find all because we want to query everything in our database and put it in we could do live But that has no benefit because this render is done and then it's compiled and it's output it If we were to use live here would listen to changes It would do all that but there's no need because it would forget all of that because that templates rendered So we find everything with our query and it's and that's the way it works So that's like an example of a search page And this is impossible with other static site genres because they don't have this backing of an actual server that we can extend Now native comments, this is Experimental this may work or this may not work. Well, this is an example of when We actually pull in we accept a request We extend the Node.js server to accept a post request and we add that to the docpad database and in this case It doesn't work That's experimental. That's like bleeding edge stuff. So that'll probably be stable pretty soon But it's it's nifty. So if we want to go there now I think we can probably leave it there and Take more questions soon, but I really need to go to the toilet We can probably end and the recording there. So and just ask more questions later. So Thanks Everyone enjoyed it. Yes, sweet