Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An intro to the JAMStack and Eleventy

An intro to the JAMStack and Eleventy

Static site generators and the JAMStack are all the rage right now. After trying several different tools to generate Static Sites, I recently discovered Eleventy and after building a few websites with it I feel like I am in love! In this presentation, I will try to explain why is that!

F3a6662b3cd161c3c2f13604965ed0f2?s=128

Luciano Mammino

May 20, 2021
Tweet

Transcript

  1. AN INTRO TO THE JAMSTACK & ELEVENTY Luciano Mammino (

    ) @loige loige.link/11ty-jam May 18, 19, 20 - 2021 1
  2. @loige loige.link/11ty-jam 2

  3. STATIC SITE GENERATORS... WAIT, WHAT?! content & templates static HTML

    pages & assets This is the core of a static site generator! @loige 3
  4. WHAT ARE WE TALKING ABOUT? I NEED EXAMPLES! A programming

    blog A recipes website A movie reviews website A photo book An online portfolio A podcast website ... And even single-page applications! @loige 4
  5. LET ME INTRODUCE MYSELF... @loige 5

  6. LET ME INTRODUCE MYSELF... I'm Luciano ( 🍕🍝) 👋 @loige

    5
  7. LET ME INTRODUCE MYSELF... I'm Luciano ( 🍕🍝) 👋 Senior

    Architect @loige 5
  8. LET ME INTRODUCE MYSELF... I'm Luciano ( 🍕🍝) 👋 Senior

    Architect nodejsdp.link Co-Author of Node.js Design Patterns 👉 @loige 5
  9. LET ME INTRODUCE MYSELF... I'm Luciano ( 🍕🍝) 👋 Senior

    Architect nodejsdp.link Co-Author of Node.js Design Patterns 👉 Connect with me: (blog) (twitter) (github) loige.co @loige lmammino @loige 20% eBook discount on Packt 20NODEMAY 5
  10. WE ARE BUSINESS FOCUSED TECHNOLOGISTS THAT DELIVER. | | Accelerated

    Serverless AI as a Service Platform Modernisation Do you want to ? work with us loige 6
  11. SOME STATIC SITES I BUILT loige.co open source! @loige 7

  12. fastify.io METALSMITH open source! @loige 8

  13. nodejsdp.link open source! @loige 9

  14. @loige A Java API client! 10

  15. WHY DO WE CARE? It's easy It's generally cheap It

    can scale easily It can be more secure We can build fast websites We can still use dynamic data (API, CMS, etc.) We can still add dynamic features @loige 11
  16. WHICH TOOL SHOULD I USE? jamstack.org/generators/ +350 tools listed! @loige

    12
  17. WHY DO I LIKE ELEVENTY? It's written in Node.js It's

    so simple that you don't need a "starter" (but there are if you want) Fast & lightweight Not opinionated Simple to build incrementally on top of it Makes me feel productive... many @loige 13
  18. OK. NOW, LET'S PLAY WITH ELEVENTY! Install + Hello world

    Custom config Templates, frontmatter & Layouts Live reload Copying static files Custom global data Collection API Using dynamic data Pagination API @loige 14
  19. mkdir 11ty-sample-project cd 11ty-sample-project npm init -y npm i --save-dev

    @11ty/eleventy echo "# My sample Eleventy website" > index.md node_modules/.bin/eleventy --watch --serve 1 2 3 4 5 6 7 8 9 @loige PROJECT SCAFFOLD 15
  20. mkdir 11ty-sample-project cd 11ty-sample-project npm init -y npm i --save-dev

    @11ty/eleventy echo "# My sample Eleventy website" > index.md node_modules/.bin/eleventy --watch --serve 1 2 3 4 5 6 7 8 9 mkdir 11ty-sample-project cd 11ty-sample-project npm init -y 1 2 3 4 npm i --save-dev @11ty/eleventy 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 @loige PROJECT SCAFFOLD 15
  21. mkdir 11ty-sample-project cd 11ty-sample-project npm init -y npm i --save-dev

    @11ty/eleventy echo "# My sample Eleventy website" > index.md node_modules/.bin/eleventy --watch --serve 1 2 3 4 5 6 7 8 9 mkdir 11ty-sample-project cd 11ty-sample-project npm init -y 1 2 3 4 npm i --save-dev @11ty/eleventy 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 npm i --save-dev @11ty/eleventy mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 @loige PROJECT SCAFFOLD 15
  22. mkdir 11ty-sample-project cd 11ty-sample-project npm init -y npm i --save-dev

    @11ty/eleventy echo "# My sample Eleventy website" > index.md node_modules/.bin/eleventy --watch --serve 1 2 3 4 5 6 7 8 9 mkdir 11ty-sample-project cd 11ty-sample-project npm init -y 1 2 3 4 npm i --save-dev @11ty/eleventy 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 npm i --save-dev @11ty/eleventy mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 echo "# My sample Eleventy website" > index.md mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 npm i --save-dev @11ty/eleventy 5 6 7 8 node_modules/.bin/eleventy --watch --serve 9 @loige PROJECT SCAFFOLD 15
  23. mkdir 11ty-sample-project cd 11ty-sample-project npm init -y npm i --save-dev

    @11ty/eleventy echo "# My sample Eleventy website" > index.md node_modules/.bin/eleventy --watch --serve 1 2 3 4 5 6 7 8 9 mkdir 11ty-sample-project cd 11ty-sample-project npm init -y 1 2 3 4 npm i --save-dev @11ty/eleventy 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 npm i --save-dev @11ty/eleventy mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 echo "# My sample Eleventy website" > index.md mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 npm i --save-dev @11ty/eleventy 5 6 7 8 node_modules/.bin/eleventy --watch --serve 9 node_modules/.bin/eleventy --watch --serve mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 npm i --save-dev @11ty/eleventy 5 6 echo "# My sample Eleventy website" > index.md 7 8 9 @loige PROJECT SCAFFOLD 15
  24. mkdir 11ty-sample-project cd 11ty-sample-project npm init -y npm i --save-dev

    @11ty/eleventy echo "# My sample Eleventy website" > index.md node_modules/.bin/eleventy --watch --serve 1 2 3 4 5 6 7 8 9 mkdir 11ty-sample-project cd 11ty-sample-project npm init -y 1 2 3 4 npm i --save-dev @11ty/eleventy 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 npm i --save-dev @11ty/eleventy mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 5 6 echo "# My sample Eleventy website" > index.md 7 8 node_modules/.bin/eleventy --watch --serve 9 echo "# My sample Eleventy website" > index.md mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 npm i --save-dev @11ty/eleventy 5 6 7 8 node_modules/.bin/eleventy --watch --serve 9 node_modules/.bin/eleventy --watch --serve mkdir 11ty-sample-project 1 cd 11ty-sample-project 2 npm init -y 3 4 npm i --save-dev @11ty/eleventy 5 6 echo "# My sample Eleventy website" > index.md 7 8 9 mkdir 11ty-sample-project cd 11ty-sample-project npm init -y npm i --save-dev @11ty/eleventy echo "# My sample Eleventy website" > index.md node_modules/.bin/eleventy --watch --serve 1 2 3 4 5 6 7 8 9 @loige PROJECT SCAFFOLD 15
  25. @loige 16

  26. // .eleventy.js module.exports = function (config) { return { dir:

    { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 @loige CUSTOM CONFIG 17
  27. // .eleventy.js module.exports = function (config) { return { dir:

    { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 @loige CUSTOM CONFIG 17
  28. // .eleventy.js module.exports = function (config) { return { dir:

    { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 module.exports = function (config) { // .eleventy.js 1 2 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 @loige CUSTOM CONFIG 17
  29. // .eleventy.js module.exports = function (config) { return { dir:

    { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 module.exports = function (config) { // .eleventy.js 1 2 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 return { dir: { input: './src', // default: `.` output: './build' // default: _site } } // .eleventy.js 1 2 module.exports = function (config) { 3 4 5 6 7 8 9 } 10 @loige CUSTOM CONFIG 17
  30. // .eleventy.js module.exports = function (config) { return { dir:

    { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 module.exports = function (config) { // .eleventy.js 1 2 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 return { dir: { input: './src', // default: `.` output: './build' // default: _site } } // .eleventy.js 1 2 module.exports = function (config) { 3 4 5 6 7 8 9 } 10 input: './src', // default: `.` // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 6 output: './build' // default: _site 7 } 8 } 9 } 10 @loige CUSTOM CONFIG 17
  31. // .eleventy.js module.exports = function (config) { return { dir:

    { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 module.exports = function (config) { // .eleventy.js 1 2 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 return { dir: { input: './src', // default: `.` output: './build' // default: _site } } // .eleventy.js 1 2 module.exports = function (config) { 3 4 5 6 7 8 9 } 10 input: './src', // default: `.` // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 6 output: './build' // default: _site 7 } 8 } 9 } 10 output: './build' // default: _site // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 7 } 8 } 9 } 10 @loige CUSTOM CONFIG 17
  32. // .eleventy.js module.exports = function (config) { return { dir:

    { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 module.exports = function (config) { // .eleventy.js 1 2 3 return { 4 dir: { 5 input: './src', // default: `.` 6 output: './build' // default: _site 7 } 8 } 9 } 10 return { dir: { input: './src', // default: `.` output: './build' // default: _site } } // .eleventy.js 1 2 module.exports = function (config) { 3 4 5 6 7 8 9 } 10 input: './src', // default: `.` // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 6 output: './build' // default: _site 7 } 8 } 9 } 10 output: './build' // default: _site // .eleventy.js 1 2 module.exports = function (config) { 3 return { 4 dir: { 5 input: './src', // default: `.` 6 7 } 8 } 9 } 10 // .eleventy.js module.exports = function (config) { return { dir: { input: './src', // default: `.` output: './build' // default: _site } } } 1 2 3 4 5 6 7 8 9 10 @loige CUSTOM CONFIG 17
  33. @loige TEMPLATES markdown (.md), Nunjucks (.njk) and are called templates

    These files can be used as a skeleton to generate pages Eleventy will automatically search for them in our source folder and, by default, it will generate a page for each and every one of them many other file types 18
  34. @loige FRONTMATTER frontmatter is an optional section at the top

    of a template that can be used to define additional contextual metadata. --- name: someone age: 17 --- Rest of the file 19
  35. @loige FRONTMATTER Data in the frontmatter can be referenced in

    the templates --- name: someone age: 17 --- {{ name }} is {{ age }} years old! 20
  36. @loige LAYOUTS Layouts are used to wrap the generated pages

    in a common HTML structure Especially useful for Markdown files Layouts can also have a frontmatter 21
  37. --- title: My default title --- <!DOCTYPE html> <head> <meta

    charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>{{ title }}</title> </head> <body> <main> {{ content | safe }} </main> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @loige src/_includes/base.njk 22
  38. --- title: My default title --- <!DOCTYPE html> <head> <meta

    charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>{{ title }}</title> </head> <body> <main> {{ content | safe }} </main> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- title: My default title --- 1 2 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 <title>{{ title }}</title> 8 </head> 9 <body> 10 <main> 11 {{ content | safe }} 12 </main> 13 </body> 14 </html> 15 @loige src/_includes/base.njk 22
  39. --- title: My default title --- <!DOCTYPE html> <head> <meta

    charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>{{ title }}</title> </head> <body> <main> {{ content | safe }} </main> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- title: My default title --- 1 2 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 <title>{{ title }}</title> 8 </head> 9 <body> 10 <main> 11 {{ content | safe }} 12 </main> 13 </body> 14 </html> 15 <title>{{ title }}</title> --- 1 title: My default title 2 --- 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 8 </head> 9 <body> 10 <main> 11 {{ content | safe }} 12 </main> 13 </body> 14 </html> 15 @loige src/_includes/base.njk 22
  40. --- title: My default title --- <!DOCTYPE html> <head> <meta

    charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>{{ title }}</title> </head> <body> <main> {{ content | safe }} </main> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- title: My default title --- 1 2 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 <title>{{ title }}</title> 8 </head> 9 <body> 10 <main> 11 {{ content | safe }} 12 </main> 13 </body> 14 </html> 15 <title>{{ title }}</title> --- 1 title: My default title 2 --- 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 8 </head> 9 <body> 10 <main> 11 {{ content | safe }} 12 </main> 13 </body> 14 </html> 15 {{ content | safe }} --- 1 title: My default title 2 --- 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 <title>{{ title }}</title> 8 </head> 9 <body> 10 <main> 11 12 </main> 13 </body> 14 </html> 15 @loige src/_includes/base.njk 22
  41. --- title: My default title --- <!DOCTYPE html> <head> <meta

    charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>{{ title }}</title> </head> <body> <main> {{ content | safe }} </main> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- title: My default title --- 1 2 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 <title>{{ title }}</title> 8 </head> 9 <body> 10 <main> 11 {{ content | safe }} 12 </main> 13 </body> 14 </html> 15 <title>{{ title }}</title> --- 1 title: My default title 2 --- 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 8 </head> 9 <body> 10 <main> 11 {{ content | safe }} 12 </main> 13 </body> 14 </html> 15 {{ content | safe }} --- 1 title: My default title 2 --- 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 <title>{{ title }}</title> 8 </head> 9 <body> 10 <main> 11 12 </main> 13 </body> 14 </html> 15 --- title: My default title --- <!DOCTYPE html> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>{{ title }}</title> </head> <body> <main> {{ content | safe }} </main> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @loige src/_includes/base.njk 22
  42. layout: base --- 1 2 --- 3 4 # Hello

    from Eleventy 5 6 This is a simple Eleventy demo 7 @loige To use a layout you can use the special frontmatter property "layout" in a template: 23
  43. @loige Eleventy uses to give you live-reload 🚀 BrowserSync 24

  44. @loige COPYING STATIC ASSETS src/_includes/style.css html, body { background-color: #eee;

    margin: 0; } main { box-sizing: border-box; max-width: 1024px; min-height: 100vh; padding: 2em; margin: 0 auto; background: white; } 25
  45. @loige COPYING STATIC ASSETS // .eleventy.js module.exports = function (config)

    { config.addPassthroughCopy({ './src/_includes/style.css': 'style.css' }) // ... } 1 2 3 4 5 6 7 8 9 26
  46. @loige COPYING STATIC ASSETS // .eleventy.js module.exports = function (config)

    { config.addPassthroughCopy({ './src/_includes/style.css': 'style.css' }) // ... } 1 2 3 4 5 6 7 8 9 config.addPassthroughCopy({ // .eleventy.js 1 2 module.exports = function (config) { 3 4 './src/_includes/style.css': 'style.css' 5 }) 6 7 // ... 8 } 9 26
  47. @loige COPYING STATIC ASSETS // .eleventy.js module.exports = function (config)

    { config.addPassthroughCopy({ './src/_includes/style.css': 'style.css' }) // ... } 1 2 3 4 5 6 7 8 9 config.addPassthroughCopy({ // .eleventy.js 1 2 module.exports = function (config) { 3 4 './src/_includes/style.css': 'style.css' 5 }) 6 7 // ... 8 } 9 './src/_includes/style.css': 'style.css' // .eleventy.js 1 2 module.exports = function (config) { 3 config.addPassthroughCopy({ 4 5 }) 6 7 // ... 8 } 9 26
  48. @loige COPYING STATIC ASSETS // .eleventy.js module.exports = function (config)

    { config.addPassthroughCopy({ './src/_includes/style.css': 'style.css' }) // ... } 1 2 3 4 5 6 7 8 9 config.addPassthroughCopy({ // .eleventy.js 1 2 module.exports = function (config) { 3 4 './src/_includes/style.css': 'style.css' 5 }) 6 7 // ... 8 } 9 './src/_includes/style.css': 'style.css' // .eleventy.js 1 2 module.exports = function (config) { 3 config.addPassthroughCopy({ 4 5 }) 6 7 // ... 8 } 9 // .eleventy.js module.exports = function (config) { config.addPassthroughCopy({ './src/_includes/style.css': 'style.css' }) // ... } 1 2 3 4 5 6 7 8 9 26
  49. <link rel="stylesheet" href="/style.css"/> --- 1 title: My default title 2

    --- 3 <!DOCTYPE html> 4 <head> 5 <meta charset="utf-8"/> 6 <meta name="viewport" content="width=device-width, initial-scale=1"/> 7 <title>{{ title }}</title> 8 9 </head> 10 <body> 11 <main> 12 {{ content | safe }} 13 </main> 14 </body> 15 </html> 16 @loige src/_includes/base.njk 27
  50. @loige GLOBAL DATA FILES // src/_data/site.js module.exports = { author:

    'Luciano Mammino', copyrightYear: (new Date()).getFullYear() } Define globally available data JavaScript code that gets executed before templates are rendered Can be static or dynamic (e.g. fetch data from an API or a DB) 28
  51. @loige GLOBAL DATA FILES A website by {{ site.author }}

    - &copy; {{ site.copyrightYear }} <main> 1 {{ content | safe }} 2 <hr/> 3 <small> 4 5 6 </small> 7 </main> 8 The filename defines how you access the data in templates 29
  52. @loige COLLECTION API tags: ["posts", "javascript"] --- 1 2 ---

    3 4 ## An introduction to the spread syntax 5 6 **Spread syntax** (`...`) allows an iterable such as an array 7 expression or string to be expanded in places where zero or 8 more arguments (for function calls) or elements 9 (for array literals) are expected, or an object expression 10 to be expanded in places where zero or more 11 key-value pairs (for object literals) are expected. 12 You can tag a template to be part of one or more collections Use the special frontmatter entry "tags" 30
  53. @loige COLLECTION API --- title: "All posts" layout: base ---

    <h1>All posts</h1> <ul> {% for post in collections.posts %} <li> <a href="{{ post.url }}"> {{ post.data.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Eleventy allows you to access all the metadata of templates for a given tag using the special collections.tagName global data 31
  54. @loige COLLECTION API --- title: "All posts" layout: base ---

    <h1>All posts</h1> <ul> {% for post in collections.posts %} <li> <a href="{{ post.url }}"> {{ post.data.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 {% for post in collections.posts %} --- 1 title: "All posts" 2 layout: base 3 --- 4 5 <h1>All posts</h1> 6 7 <ul> 8 9 <li> 10 <a href="{{ post.url }}"> 11 {{ post.data.title }} 12 </a> 13 </li> 14 {% endfor %} 15 </ul> 16 Eleventy allows you to access all the metadata of templates for a given tag using the special collections.tagName global data 31
  55. @loige COLLECTION API --- title: "All posts" layout: base ---

    <h1>All posts</h1> <ul> {% for post in collections.posts %} <li> <a href="{{ post.url }}"> {{ post.data.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 {% for post in collections.posts %} --- 1 title: "All posts" 2 layout: base 3 --- 4 5 <h1>All posts</h1> 6 7 <ul> 8 9 <li> 10 <a href="{{ post.url }}"> 11 {{ post.data.title }} 12 </a> 13 </li> 14 {% endfor %} 15 </ul> 16 <a href="{{ post.url }}"> {{ post.data.title }} </a> --- 1 title: "All posts" 2 layout: base 3 --- 4 5 <h1>All posts</h1> 6 7 <ul> 8 {% for post in collections.posts %} 9 <li> 10 11 12 13 </li> 14 {% endfor %} 15 </ul> 16 Eleventy allows you to access all the metadata of templates for a given tag using the special collections.tagName global data 31
  56. @loige COLLECTION API --- title: "All posts" layout: base ---

    <h1>All posts</h1> <ul> {% for post in collections.posts %} <li> <a href="{{ post.url }}"> {{ post.data.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 {% for post in collections.posts %} --- 1 title: "All posts" 2 layout: base 3 --- 4 5 <h1>All posts</h1> 6 7 <ul> 8 9 <li> 10 <a href="{{ post.url }}"> 11 {{ post.data.title }} 12 </a> 13 </li> 14 {% endfor %} 15 </ul> 16 <a href="{{ post.url }}"> {{ post.data.title }} </a> --- 1 title: "All posts" 2 layout: base 3 --- 4 5 <h1>All posts</h1> 6 7 <ul> 8 {% for post in collections.posts %} 9 <li> 10 11 12 13 </li> 14 {% endfor %} 15 </ul> 16 --- title: "All posts" layout: base --- <h1>All posts</h1> <ul> {% for post in collections.posts %} <li> <a href="{{ post.url }}"> {{ post.data.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Eleventy allows you to access all the metadata of templates for a given tag using the special collections.tagName global data 31
  57. @loige 32

  58. @loige USING DYNAMIC DATA npm i --save-dev @11ty/eleventy-cache-assets What if

    we want to build a website using data from an API? For instance this one: https://ghibliapi.herokuapp.com/films/ We don't want to fetch the data after every single change! 33
  59. @loige USING DYNAMIC DATA // src/_data/movies.js const Cache = require('@11ty/eleventy-cache-assets')

    module.exports = async function () { return Cache( 'https://ghibliapi.herokuapp.com/films/', { type: 'json' } ) } 1 2 3 4 5 6 7 8 9 10 34
  60. @loige USING DYNAMIC DATA // src/_data/movies.js const Cache = require('@11ty/eleventy-cache-assets')

    module.exports = async function () { return Cache( 'https://ghibliapi.herokuapp.com/films/', { type: 'json' } ) } 1 2 3 4 5 6 7 8 9 10 return Cache( 'https://ghibliapi.herokuapp.com/films/', { type: 'json' } ) // src/_data/movies.js 1 2 const Cache = require('@11ty/eleventy-cache-assets') 3 4 module.exports = async function () { 5 6 7 8 9 } 10 34
  61. @loige USING DYNAMIC DATA // src/_data/movies.js const Cache = require('@11ty/eleventy-cache-assets')

    module.exports = async function () { return Cache( 'https://ghibliapi.herokuapp.com/films/', { type: 'json' } ) } 1 2 3 4 5 6 7 8 9 10 return Cache( 'https://ghibliapi.herokuapp.com/films/', { type: 'json' } ) // src/_data/movies.js 1 2 const Cache = require('@11ty/eleventy-cache-assets') 3 4 module.exports = async function () { 5 6 7 8 9 } 10 // src/_data/movies.js const Cache = require('@11ty/eleventy-cache-assets') module.exports = async function () { return Cache( 'https://ghibliapi.herokuapp.com/films/', { type: 'json' } ) } 1 2 3 4 5 6 7 8 9 10 34
  62. @loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli

    movies --- <h1>Studio Ghibli movies</h1> <ul> {% for movie in movies %} <li> <a href="/movie/{{ movie.title | slug }"> {{ movie.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 35
  63. @loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli

    movies --- <h1>Studio Ghibli movies</h1> <ul> {% for movie in movies %} <li> <a href="/movie/{{ movie.title | slug }"> {{ movie.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 {% for movie in movies %} {% endfor %} --- 1 layout: base 2 title: Studio Ghibli movies 3 --- 4 5 <h1>Studio Ghibli movies</h1> 6 7 <ul> 8 9 <li> 10 <a href="/movie/{{ movie.title | slug }"> 11 {{ movie.title }} 12 </a> 13 </li> 14 15 </ul> 16 35
  64. @loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli

    movies --- <h1>Studio Ghibli movies</h1> <ul> {% for movie in movies %} <li> <a href="/movie/{{ movie.title | slug }"> {{ movie.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 {% for movie in movies %} {% endfor %} --- 1 layout: base 2 title: Studio Ghibli movies 3 --- 4 5 <h1>Studio Ghibli movies</h1> 6 7 <ul> 8 9 <li> 10 <a href="/movie/{{ movie.title | slug }"> 11 {{ movie.title }} 12 </a> 13 </li> 14 15 </ul> 16 <a href="/movie/{{ movie.title | slug }"> {{ movie.title }} </a> --- 1 layout: base 2 title: Studio Ghibli movies 3 --- 4 5 <h1>Studio Ghibli movies</h1> 6 7 <ul> 8 {% for movie in movies %} 9 <li> 10 11 12 13 </li> 14 {% endfor %} 15 </ul> 16 35
  65. @loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli

    movies --- <h1>Studio Ghibli movies</h1> <ul> {% for movie in movies %} <li> <a href="/movie/{{ movie.title | slug }"> {{ movie.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 {% for movie in movies %} {% endfor %} --- 1 layout: base 2 title: Studio Ghibli movies 3 --- 4 5 <h1>Studio Ghibli movies</h1> 6 7 <ul> 8 9 <li> 10 <a href="/movie/{{ movie.title | slug }"> 11 {{ movie.title }} 12 </a> 13 </li> 14 15 </ul> 16 <a href="/movie/{{ movie.title | slug }"> {{ movie.title }} </a> --- 1 layout: base 2 title: Studio Ghibli movies 3 --- 4 5 <h1>Studio Ghibli movies</h1> 6 7 <ul> 8 {% for movie in movies %} 9 <li> 10 11 12 13 </li> 14 {% endfor %} 15 </ul> 16 --- layout: base title: Studio Ghibli movies --- <h1>Studio Ghibli movies</h1> <ul> {% for movie in movies %} <li> <a href="/movie/{{ movie.title | slug }"> {{ movie.title }} </a> </li> {% endfor %} </ul> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 35
  66. @loige 36

  67. @loige PAGINATION API Allows to split collections into multiple pages

    But it can also be used to generate pages for dynamic content For instance, a page for every single movie 37
  68. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 38
  69. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 permalink: /movie/{{ movie.title | slug }}/ --- 1 layout: base 2 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 38
  70. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 permalink: /movie/{{ movie.title | slug }}/ --- 1 layout: base 2 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 38
  71. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 permalink: /movie/{{ movie.title | slug }}/ --- 1 layout: base 2 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 38
  72. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 permalink: /movie/{{ movie.title | slug }}/ --- 1 layout: base 2 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 38
  73. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 permalink: /movie/{{ movie.title | slug }}/ --- 1 layout: base 2 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 38
  74. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 permalink: /movie/{{ movie.title | slug }}/ --- 1 layout: base 2 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 <h2>{{ movie.title }}</h2> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> <p>{{ movie.description }}</p> --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 9 10 <ul> 11 12 13 14 </ul> 15 16 17 18 <p><a href="/movies">See all movies</a></p> 19 38
  75. @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title |

    slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 permalink: /movie/{{ movie.title | slug }}/ --- 1 layout: base 2 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 7 --- 8 <h2>{{ movie.title }}</h2> 9 10 <ul> 11 <li>Released in <strong>{{ movie.release_date }}</strong></li> 12 <li>Directed by <strong>{{ movie.director }}</strong></li> 13 <li>Produced by <strong>{{ movie.producer }}</strong></li> 14 </ul> 15 16 <p>{{ movie.description }}</p> 17 18 <p><a href="/movies">See all movies</a></p> 19 <h2>{{ movie.title }}</h2> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> <p>{{ movie.description }}</p> --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 9 10 <ul> 11 12 13 14 </ul> 15 16 17 18 <p><a href="/movies">See all movies</a></p> 19 --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie --- <h2>{{ movie.title }}</h2> <ul> <li>Released in <strong>{{ movie.release_date }}</strong></li> <li>Directed by <strong>{{ movie.director }}</strong></li> <li>Produced by <strong>{{ movie.producer }}</strong></li> </ul> <p>{{ movie.description }}</p> <p><a href="/movies">See all movies</a></p> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 38
  76. @loige 39

  77. loige.link/11ty-11min 40

  78. BONUS! AUTOMATE DEPLOYMENT Example using GitHub actions: loige.link/11ty-ci-example @loige 41

  79. THANKS! Icons by and on Freepik Zlatko Najdenovski Pixelbuddha If

    you enjoyed this talk, you might also enjoy 😛 nodejsdp.link @loige Let's connect! (blog) (twitter) (github) loige.co @loige lmammino loige.link/11ty-jam 20% eBook discount on Packt 20NODEMAY 42