With our initial site set up, it’s time to start adding content!
By default, Eleventy uses Markdown files to structure content on a site; throughout this chapter, I will show you how easy it is to start adding pages, navigation, and the like, to help create the structure of our site, and get it ready to receive data.
As is always the case, we need to start somewhere, so there is no better than a quick recap on the folder structure for our site. Most of it will appear pretty self-explanatory, but there are one or two quirks that are worth bearing in mind! Let’s dive in and take a look at the project structure in more detail.
Exploring the Site Structure
Cast your mind back to Chapter 1 – remember how we started to explore the site structure of our project and some of the folders we would create?
One of the most important concepts we will need to get familiar with is site structure – I know this might sound obvious at first, but trust me, there are a couple of things that could trip us up if we’re not careful! Let me explain what I mean – for this, let’s assume for the moment we’ve fast-forwarded to the end of this chapter.
We’ve started to build out our Eleventy site and created various pages. Apart from a few folders coming in later chapters, this is how our site’s structure will look.
Over and above the standard node_modules folder we see with any NPM-based project, there are two folders of particular note: the first is myblog, and the second is _site. They are the input and output folders, respectively. These folders play an essential role in generating our site output. Eleventy checks everything and generates the relevant files into the output _site folder. (The only exception is if we have any references in an .eleventyignore file, should one be present.)
The critical thing here is that although we mention the _site folder, it’s important to remember that _site is the static site output generated by Eleventy; therefore, we do not include a reference to it in URLs. For example, the _site folder contains a post1 folder (under posts), inside which you will find an index.html file. Eleventy effectively considers the base point of any URL as being the folder specified as the destination. So for us, the URL to about would be http://localhost:8080/about, even though the folder is actually in the _site folder.
Hopefully, this makes sense – it’s essential to understand, as you may find yourself in an instance where you have the correct file in what you think is the right place, but Eleventy says otherwise!
For any of you wondering what an .eleventyignore file is – it works in the same way as a .gitignore file. It tells Eleventy to ignore specific folders or files when it comes to processing, in the same way as we would for content within a Git repo.
Okay, now that we know more about how our folder structure works for Eleventy, let’s crack on and start to add that content!
Creating Pages and Blog Posts
When creating an Eleventy-driven site, it’s worth noting that content (in the strictest sense) will be one of three things: HTML, Markdown, front matter, or another templating language.
Eleventy supports a mix of different options when it comes to choosing which languages to use, so it’s essential to be clear in one’s mind which are the preferred ones so that we don’t end up mixing languages unnecessarily. For example, front matter sections support JSON, JavaScript, and YAML alone, and that’s before we get into the main content.
YAML for my front matter
Standard HTML and Nunjucks for templates
Markdown for posts (the latter of which is pretty much the standard)
We’ll explore adding HTML markup for templates later in Chapter 4, but for now, let’s begin with creating pages for our site, ready to receive content.
- 1.
We’ll start by deleting the _site folder – it contains the two test files from Chapter 1, which we no longer need.
- 2.
Next, fire up a Node.js command prompt, then go ahead and run npm run serve – this will start the compiler. It will try to compile files on the initial launch but come back with zero changes; this doesn’t matter, as it’s more important that the compiler is running and ready to compile our changes.
- 3.
We now need to start creating our site content – go ahead and create a folder at the root of our project area, called posts.
- 4.
Next, in a new file, add this code and text – save it as post1.md in the posts folder:
- 5.
Repeat this process three times; increment the file name’s number by one and change the text in the file accordingly. You should end up with four post files, similar to this:
- 6.
Next, go ahead and create the following empty placeholder files, saving all of them at the root of our project area: 404.md, about.njk, index.njk, contact.md, archive.njk, tags.njk, and tags-list.njk.
We can store all of the files at the root of our project area – we will add more to them in Chapters 4 and 5 when we create templates and configure more options within Eleventy.
- 7.
No further changes are required, so save and close any that are open.
- 8.
Go ahead and look in the _site folder – you should find Eleventy has compiled all of the files while we added them. If all is well, we should see something akin to the list shown in Figure 2-2.
- 9.
To make sure that this is the case, we can stop serving the site and restart the compiler. Switch to the terminal you started in step 2, then press Ctrl+C (or Cmd+C) to terminate the current session.
- 10.
At the prompt, enter this command and press Enter:
- 11.
If all is well, you should see a response similar to this appear, where X.X.X.X marks your IP address:
- 12.
We have one more step to perform – we should display a list of entries on the home page to prove that we can serve content. For this, add the following code to the index.njk file, at the root of the site:
- 13.
Assuming the automatic compilation process is successful, switch to your browser, then head over to http://localhost:8080 to preview the results, as shown in Figure 2-3.
It might not look much, but we've built the basic structure of our site – there will be more to add in later chapters, but hopefully, we can start to see our site take shape. We covered some key points during that last exercise, so let's pause to review the changes we made and learn a little more about the compilation process.
Breaking Apart the Code
Although we already have a blog structure in place, we start to see things take shape when we add in page and post files.
In this last exercise, we kicked off with first getting rid of the _site folder from the previous chapter before launching the development compiler. It’s important to note that this step isn’t entirely necessary, but it is helpful to ensure we have an up-to-date version of our code running. More importantly, it starts the server running, so Eleventy will automatically compile any future changes we make.
We then moved on to creating a series of post pages – at present, they won’t contain any data, but that will come later; for now, we need to have placeholder content ready for use. At the same time, we also created ancillary pages for our site – this included a 404 page and pages for About, Archives, Contact, and the main index page. To prove that the compilation process worked, we took a quick look at the contents of the _site folder, where we could see the updated folder structure. We could see that each post file we created compiles into a folder, inside of which sits an index.html file; this is standard behavior for Eleventy.
As a final step, we stopped and restarted the server before viewing the content in a browser. This restart wasn’t entirely necessary, but there were two reasons for doing it: (1) we can verify that we have an updated compiled site, and (2) it helps get used to the compilation process. Not every change in Eleventy requires us to stop and start the server – it tends to be more for changes to a template or data source where we might have to restart the server.
If you need to restart the server, then as a belt-and-braces step, you can also delete the _site folder too – this will ensure we have up-to-date content! Note though that this is meant for files that have been built but then deleted, and you don’t want to include in the _site output. It’s better to prune away single files or folders within, or use npm run build to recompile the site content.
Okay – let’s move on. There are two questions that you might want to ask, from that you might have noticed from that previous demo. Firstly, how come we’re using files of different types? And secondly, we’ve added four posts, but what about managing sites with dozens of different posts?
The first is easy to answer: those files with an extension of .njk are Nunjucks templates; we need to transform those into standard markup, whereas the other files are simple Markdown content files and do not require the same type of transformation.
We will come back to exploring templating more in Chapter 4.
The second question is a little more involved, but a perfect introduction to our next topic – how to add pagination to our site, so we don’t overwhelm the reader with too much information at once?
Adding Pagination
At the moment, our site only has a handful of posts – it makes it easy enough to work through it to find the target post. What if we were to increase the number by a factor of say 10, or even 20?
Soon, our site will become unwieldy to manage – we need some form of pagination! It all hangs around the pagination: property in the front matter – this is where we specify values such as size, data source, and sorting order. Eleventy makes this straightforward to add, using a combination of changes to our front matter and addition of markup. Let’s take a look at how starting first with setting up pagination for our post index.
Setting Up Paginating for the Post Index
The first place to update is in the main index page – this is where we add in a partial to display the details of each post and some HTML markup to render navigation links.
Partials are simply excerpts of reusable code that we can drop in at any point – we will use one here to display the various details of each post. Let’s get stuck into making those changes, starting first with setting up pagination in the main index page.
- 1.
First, we need to update index.njk – this will set the data source, page count, and two other values (alias and reverse). Go ahead and add this code at the top of the file, before the Welcome!:
- 2.
Next, crack open a new file, and add this code, saving it as postslist.njk in the _includes/partials folder:
- 3.
To help with pagination, we need to add a JSON file called posts.json – create a new file in the posts folder, and add in this code:
- 4.
Next, crack open the index.njk file, and replace
- 5.
There is one more change to make – leave a line blank after the {% include "partials/postslist.njk" %} line, then add in this code:
- 6.
We’ve updated all of the files we need to, so save and close any that are open.
- 7.
Go ahead and delete the _site folder in its entirety – this will be updated with a fresh copy when we compile our code shortly.
- 8.
Switch to a Node.js command prompt, then change the working folder to our project area. At the prompt, enter npm run serve to recompile the code and serve the site locally.
- 9.
Once done, browse to http://localhost:8080 – if all is well, we should see the site updated with links for navigating through the posts list, as shown in Figure 2-4.
Excellent – adding the navigation links will make it easier to iterate through posts as we add them over time. The changes in this last exercise are a little more detailed than previous ones, so let’s pause for a moment to review them in more detail.
Reviewing the Code Changes
In the last exercise, we added what might look like a simple change but a key one to help navigate the site. How did we implement it?
We started by specifying a pagination block in the front matter of the index.njk file – inside it, we included data as the source, size to determine how we should group data (i.e., posts), and alias and reverse. We then created a partial or fragment of code to render each post link (or what will become post tile, once styled). The partial is stored in the _includes/partials folder and is available for use anywhere on the site.
Next up, we added a posts.json file – this is a shortcut way of automatically applying a tag name to all posts. When we use the partial, we can iterate through each post {% for post in posts %} before displaying the details on the screen using the template formatting.
In the final change, we then added a pagination div block, which looks first for the pagination entry in the front matter and works out from the pagination set which links to display. We display generic links (Older Articles or Newer Articles) and enable or disable them depending on where we are in the set. Eleventy works out what the href value should be using pagination.href.next or pagination.href.previous and uses the appropriate link on the page.
Try clicking on the Newer Articles link, and watch the URL change. Eleventy automatically updates the page content without requiring a server refresh and appends a 1 in the URL.
If you did have a peek at the contents of the _site folder, you will have seen a folder called 1; this generates the 1 you would have seen in the URL during compilation. What’s the significance of this, I hear you ask?
It all hangs around how Eleventy has split the list of posts into groups based on the size value specified in the front matter. When compiling, Eleventy then creates a new index page with links to the relevant posts in each group. So, for example, if we had a total of 21 posts and divided this by 3 (size), we would end up with seven folders, each with index files pointing to groupings of seven posts (1–7, 8–14, and so on).
Okay – let’s crack on: I mentioned earlier that we could implement two forms of pagination. We’ve done the first, so let’s look at the second, adding similar links to individual posts.
Adding Pagination Links to Posts
For the second part of this change, we need to turn our attention to the individual posts. Clicking through from the index is only part of the journey; we need the means to go back to the index page!
Fortunately, Eleventy makes it very easy for us to add navigation links – we can add similar (if not near-identical) markup to the index page, which allows us to page through individual posts. There is a catch here, though: we’re using Markdown for our post content. We can’t simply add in HTML code as it will not compile correctly.
We can use HTML in Markdown files, but to do so, we need to add templateEngineOverride: njk, md as a property in the front matter of each file where we need to add HTML markup. Note, though, that this isn’t best practice, so only use it if it is really necessary!
We need to update the post to utilize a layout template file; this will hold the markup for our pagination. We will go into detail more in Chapter 4, but for now, let’s work through an example so you can get a feel for the steps required to make this change.
- 1.
First, we need to add a simple layout template, so go ahead and create a layouts folder under the _includes folder.
- 2.
Next, create a new file, and add this code – save the file as post.njk in the layouts folder:
- 3.
With our starting template in place, crack open the posts.json file in your editor (it’s at the root of the /posts folder), and amend it to include a layout section, like this:
- 4.
Go ahead, save all files and close them – we no longer need them.
- 5.
Switch to a Node.js command prompt, then change the working folder to our project area. At the prompt, enter npm run serve to recompile the code and serve the site locally. .
- 6.
Browse to http://localhost:8080/posts/post2/ – if all is well, we should see the site updated with links for navigating through the posts list, as shown in Figure 2-5.
Excellent – our navigation is in place. We’ll worry about making it look more presentable later in the book! For now, let’s take a moment to review the code in more detail: we’ve made some critical changes, so it’s worth exploring how these work and what it means for our site in more detail.
Understanding the Changes
In this last exercise, we added an important step to help complete the navigation circle – we can now navigate from the index page to a post and back again and traverse back and forth through the list of posts from the front page.
To add in the per-page navigation, we kicked off by creating a new layout – we kept this simple so as not to spoil what’s coming in Chapter 4! The template was enough to render a site title and any content we ask Eleventy to render if we specify this template within the front matter of a page in Eleventy.
Adding a layout was essential at this stage, as Markdown doesn’t support the kind of code required to navigate through the posts collection. It is possible to override, but it is not considered good practice to do so and should only be done if absolutely necessary!
Inside this template, we first check for the presence of collection.posts (i.e., do we have all of the posts present as an object). We then set nextPost and previousPost functions to get the next or previous URL within the collection of posts.
With that setup, we check to see if we have nextPost or previousPost specified; depending on the link present, we render a suitably marked-up link on the page.
We then round out the exercise by adding a back to main index link – as this doesn’t change, we can get away with hard-coding this for this exercise. We then went through the by-now-familiar process of recompiling the code files into the _site folder before viewing the results on screen.
Although this isn’t something we’ve covered in depth, it’s worth noting that items listed in the front matter do not have to be in any particular order. Eleventy will still process each during compilation.
Okay – let’s crack on: we’ve built in the navigation for posts and added a list on the home page (we will style both in a later chapter). There is one additional type of navigation we should add to our site – navigation for pages and the rest of the site. This is an essential task, which requires a fair few changes, so let’s dive in and find out how as part of the next exercise.
Implementing a Site Navigation
As a quick test, fire up your development server (npm run serve), then head over to http://localhost:8080/ – we’ve created several placeholder pages, such as about.njk and contact.njk, but how do we get to them? Sure, we can navigate directly to those pages, but that will be an issue for customers who won’t know where to go!
So – to fix that, we need to add some form of navigation. Enter the eleventy-navigation plugin – available from https://github.com/11ty/eleventy-navigation; this plugin allows us to parse specific entries in our front matter and build up navigation based on the hierarchy of those entries. It means we only need to add a one-liner to generate the menu – let’s dive in and look at how in more detail.
- 1.
The first thing we need to do is install the eleventy-navigation plugin. For this, crack open a Node.js command prompt, then change the working folder to our project area.
- 2.
At the prompt, enter this command and press Enter:
- 3.
Next, crack open the .eleventy.js file, and add this line in at the top, as highlighted:
- 4.
With the file imported, we now need to call it – go ahead and add it inside the module.exports block, as shown:
- 5.
Next, crack open index.njk at the root of our project folder, then add the following lines at the top of the file:
- 6.
Repeat the same exercise for about.njk, but this time, use these values:
- 7.
We have one more page to update – go ahead and add these values to archive.njk, in the same way:
- 8.
Next, move to index.njk that we opened in step 5, then scroll down to the line <h1>Welcome!</h1>. Go ahead and add in this block, immediately before the call to {% include partials…%}:
- 9.
Go ahead and save all editor files, then close them, as we have finished making changes; once done, revert to a Node.js command prompt.
- 10.
Change the directory to the root of our project area if it is not already there. Go ahead and enter this at the prompt and press Enter to begin serving the site locally:
- 11.
Assuming the compilation process is successful, switch to your browser, then head over to http://localhost:8080 to preview the results, as shown in Figure 2-6.
Excellent – we now have the beginnings of a working navigation in our site! The steps we took might seem a lot, particularly when we could easily have added standard markup ourselves. But – there is a tangible benefit to using this plugin that makes constructing the menu easier; let’s review the code to understand how Eleventy can do some of the manual grunt work for us.
Understanding the Code Changes
Setting up navigation is a necessary evil for any website – get it wrong, and customers will complain! Eleventy helps remove some of that pain by building the markup, leaving us to simply specify the order of where each menu entry should appear.
To achieve this, we started by installing the eleventy-navigation plugin before inserting a require reference to the plugin from within the .eleventy.js configuration file. Adding this reference imports the file into our site; to use it, we then added a call to it using Eleventy’s addPlugin() method.
With the plugin installed, we set up a configuration option for eleventyNavigation in the index.njk, about.njk, and archive.njk files. We used the same YAML format already used elsewhere; the key value specifies the text to display in the menu entry, and order controls the position of the entry in the menu system.
The last stage was to add the one-liner code that builds the markup for us – to break it down, collections.all iterates through every collection of data we have, filtered by the eleventyNavigation filter. We then use eleventyNavigationToHtml to render the markup before finishing with safe to double-escape the content for us.
So – why use the Eleventy plugin instead of hard-coding entries? The real benefit comes with changing the menu structure – Eleventy will automatically update and rebuild the markup for us. Installing the plugin now means that if we were to add to our menu, we already have the basics in place and can focus on updating Markdown files, not the markup.
Eleventy offers a host of different options to help configure and refine the setup – they are documented at https://www.11ty.dev/docs/plugins/navigation/.
Right – let’s continue with the next task: implementing a site navigation. Our current links serve a purpose but are generic, not easy to remember, and do precious little for SEO! Fortunately, it is straightforward to add in permalinks; lets’ dive in and find out how as part of the next exercise.
Configuring Links Using Permalinks
Permalinks can be something of a double-edged sword – they may be easy to set in code (and with Eleventy, it’s an absolute cinch), but get them wrong, and they can wreck your SEO rankings. Defining good SEO links can be an art to itself: it’s something best left to an expert.
That thought aside, Eleventy does at least make it very easy to add in links – let’s take a look at how in more detail, using the post2.md file as our example.
- 1.
First, go ahead and open post2.md from within the posts folder in your editor.
- 2.
Next, add in this line somewhere in the front matter – the exact order is not critical, but it must be in between the opening and closing ---, as shown in this example:
- 3.
Switch to a Node.js command prompt, and change the working folder to our project folder. At the prompt, enter npm run serve, then press Enter.
- 4.
We should be able to preview the results in a browser – head over to http://localhost:8080/posts/my-second-post/. If all is well, we should see something akin to that shown in Figure 2-8, where I’ve highlighted the change of URL in red.
- 5.
As an aside, we can now see the difference when using a permalink – take a look at the contents of the _site folder, where you will see the new folder listed, with entries similar to those shown in Figure 2-9.
For the preceding example, I deleted the _site folder to be sure we got updated content; if you use the command listed in step 3, you may see other entries present, which is OK.
I am sure you will agree that this URL change looks far more user-friendly than one of /posts/post2, right? Eleventy makes this a trivial change: so much so, the hardest part is ensuring we pick a suitable link that doesn’t affect SEO ranking and lose customers!
In this last exercise, we added a permalink: entry to one of the post files and set Eleventy to recompile the code. Okay, getting the right permalink format in place is something else, but hey – that’s a subject for a different book! Once we had recompiled the code, we verified that the updated link worked and that the change was reflected in the folder structure present in the _site folder.
One small point: Don’t forget to add /index.html when defining permalinks in front matter. Otherwise, you may get some weird effects happen once you recompile your code! We’ve only touched the surface of what Eleventy supports for permalinks; for more details, please refer to the primary documentation at https://www.11ty.dev/docs/permalinks/.
Summary
This chapter marks another significant milestone – over the last few pages, we’ve focused on setting up the correct folder structure (and placeholder) files, ready for us to add content and styling in later chapters. We covered some valuable tips and tricks in Eleventy, so let’s take a moment to review what we have covered in more detail.
We started by reviewing the current structure of our site, as left at the end of Chapter 1; we saw how although we can choose which folders to have, some are key to ensuring Eleventy compiles correctly and doesn’t deposit the final code into the wrong folder!
With that out of the way, we moved on to creating post files and folders, ready for us to start adding content in the next chapter. To help with navigating, we then learned how to add navigation before setting up pagination functionality, both on the index page and for each post.
We then rounded out the chapter with what must (so far) be the simplest change to date – adding permalinks. I say simplest, as we learned that although adding links is very easy, getting them right is a whole different subject in its own right!
Okay – let’s move on: hands up if you’ve heard of the phrase “content is king?” Yes, it is indeed – it also happens to be the subject of the next chapter, where we will look at how to add data into our new site.