Slide 1

Slide 1 text

AN INTRO TO THE JAMSTACK & ELEVENTY Luciano Mammino ( ) @loige loige.link/11ty-jam May 18, 19, 20 - 2021 1

Slide 2

Slide 2 text

@loige loige.link/11ty-jam 2

Slide 3

Slide 3 text

STATIC SITE GENERATORS... WAIT, WHAT?! content & templates static HTML pages & assets This is the core of a static site generator! @loige 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

LET ME INTRODUCE MYSELF... @loige 5

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

WE ARE BUSINESS FOCUSED TECHNOLOGISTS THAT DELIVER. | | Accelerated Serverless AI as a Service Platform Modernisation Do you want to ? work with us loige 6

Slide 11

Slide 11 text

SOME STATIC SITES I BUILT loige.co open source! @loige 7

Slide 12

Slide 12 text

fastify.io METALSMITH open source! @loige 8

Slide 13

Slide 13 text

nodejsdp.link open source! @loige 9

Slide 14

Slide 14 text

@loige A Java API client! 10

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

WHICH TOOL SHOULD I USE? jamstack.org/generators/ +350 tools listed! @loige 12

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

@loige 16

Slide 26

Slide 26 text

// .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

Slide 27

Slide 27 text

// .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

Slide 28

Slide 28 text

// .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

Slide 29

Slide 29 text

// .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

Slide 30

Slide 30 text

// .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

Slide 31

Slide 31 text

// .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

Slide 32

Slide 32 text

// .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

Slide 33

Slide 33 text

@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

Slide 34

Slide 34 text

@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

Slide 35

Slide 35 text

@loige FRONTMATTER Data in the frontmatter can be referenced in the templates --- name: someone age: 17 --- {{ name }} is {{ age }} years old! 20

Slide 36

Slide 36 text

@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

Slide 37

Slide 37 text

--- title: My default title --- {{ title }} {{ content | safe }}

Slide 38

Slide 38 text

--- title: My default title --- {{ title }} {{ content | safe }} 10 11 {{ content | safe }} 12 13

Slide 39

Slide 39 text

--- title: My default title --- {{ title }} {{ content | safe }} 10 11 {{ content | safe }} 12 13 10 11 {{ content | safe }} 12 13

Slide 40

Slide 40 text

--- title: My default title --- {{ title }} {{ content | safe }} 10 11 {{ content | safe }} 12 13 10 11 {{ content | safe }} 12 13 10 11 12 13

Slide 41

Slide 41 text

--- title: My default title --- {{ title }} {{ content | safe }} 10 11 {{ content | safe }} 12 13 10 11 {{ content | safe }} 12 13 10 11 12 13 {{ content | safe }}

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

@loige Eleventy uses to give you live-reload 🚀 BrowserSync 24

Slide 44

Slide 44 text

@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

Slide 45

Slide 45 text

@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

Slide 46

Slide 46 text

@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

Slide 47

Slide 47 text

@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

Slide 48

Slide 48 text

@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

Slide 49

Slide 49 text

--- 1 title: My default title 2 --- 3 4 5 6 7 {{ title }} 8 9 10 11 12 {{ content | safe }} 13 14 15

Slide 50

Slide 50 text

@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

Slide 51

Slide 51 text

@loige GLOBAL DATA FILES A website by {{ site.author }} - © {{ site.copyrightYear }} 1 {{ content | safe }} 2
3 4 5 6 7 8 The filename defines how you access the data in templates 29

Slide 52

Slide 52 text

@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

Slide 53

Slide 53 text

@loige COLLECTION API --- title: "All posts" layout: base ---

All posts

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

Slide 54

Slide 54 text

@loige COLLECTION API --- title: "All posts" layout: base ---

All posts

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

All posts

6 7 16 Eleventy allows you to access all the metadata of templates for a given tag using the special collections.tagName global data 31

Slide 55

Slide 55 text

@loige COLLECTION API --- title: "All posts" layout: base ---

All posts

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

All posts

6 7 16 {{ post.data.title }} --- 1 title: "All posts" 2 layout: base 3 --- 4 5

All posts

6 7
    8 {% for post in collections.posts %} 9
  • 10 11 12 13
  • 14 {% endfor %} 15
16 Eleventy allows you to access all the metadata of templates for a given tag using the special collections.tagName global data 31

Slide 56

Slide 56 text

@loige COLLECTION API --- title: "All posts" layout: base ---

All posts

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

All posts

6 7 16 {{ post.data.title }} --- 1 title: "All posts" 2 layout: base 3 --- 4 5

All posts

6 7
    8 {% for post in collections.posts %} 9
  • 10 11 12 13
  • 14 {% endfor %} 15
16 --- title: "All posts" layout: base ---

All posts

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

Slide 57

Slide 57 text

@loige 32

Slide 58

Slide 58 text

@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

Slide 59

Slide 59 text

@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

Slide 60

Slide 60 text

@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

Slide 61

Slide 61 text

@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

Slide 62

Slide 62 text

@loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli movies ---

Studio Ghibli movies

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 35

Slide 63

Slide 63 text

@loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli movies ---

Studio Ghibli movies

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

Studio Ghibli movies

6 7 16 35

Slide 64

Slide 64 text

@loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli movies ---

Studio Ghibli movies

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

Studio Ghibli movies

6 7 16 {{ movie.title }} --- 1 layout: base 2 title: Studio Ghibli movies 3 --- 4 5

Studio Ghibli movies

6 7
    8 {% for movie in movies %} 9
  • 10 11 12 13
  • 14 {% endfor %} 15
16 35

Slide 65

Slide 65 text

@loige USING DYNAMIC DATA --- layout: base title: Studio Ghibli movies ---

Studio Ghibli movies

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

Studio Ghibli movies

6 7 16 {{ movie.title }} --- 1 layout: base 2 title: Studio Ghibli movies 3 --- 4 5

Studio Ghibli movies

6 7
    8 {% for movie in movies %} 9
  • 10 11 12 13
  • 14 {% endfor %} 15
16 --- layout: base title: Studio Ghibli movies ---

Studio Ghibli movies

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 35

Slide 66

Slide 66 text

@loige 36

Slide 67

Slide 67 text

@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

Slide 68

Slide 68 text

@loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}

{{ movie.description }}

See all movies

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 38

Slide 69

Slide 69 text

@loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}

{{ movie.description }}

See all movies

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

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 38

Slide 70

Slide 70 text

@loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}

{{ movie.description }}

See all movies

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

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 38

Slide 71

Slide 71 text

@loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}

{{ movie.description }}

See all movies

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

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 38

Slide 72

Slide 72 text

@loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}

{{ movie.description }}

See all movies

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

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 38

Slide 73

Slide 73 text

@loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}

{{ movie.description }}

See all movies

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

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 38

Slide 74

Slide 74 text

@loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}

{{ movie.description }}

See all movies

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

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 7 --- 8

{{ movie.title }}

9 10
    11
  • Released in {{ movie.release_date }}
  • 12
  • Directed by {{ movie.director }}
  • 13
  • Produced by {{ movie.producer }}
  • 14
15 16

{{ movie.description }}

17 18

See all movies

19

{{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}
  • {{ movie.description }}

    --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 9 10
      11 12 13 14
    15 16 17 18

    See all movies

    19 38

    Slide 75

    Slide 75 text

    @loige PAGINATION API --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

    {{ movie.title }}

    • Released in {{ movie.release_date }}
    • Directed by {{ movie.director }}
    • Produced by {{ movie.producer }}

    {{ movie.description }}

    See all movies

    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

    {{ movie.title }}

    9 10
      11
    • Released in {{ movie.release_date }}
    • 12
    • Directed by {{ movie.director }}
    • 13
    • Produced by {{ movie.producer }}
    • 14
    15 16

    {{ movie.description }}

    17 18

    See all movies

    19 pagination: data: movies size: 1 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 4 5 6 7 --- 8

    {{ movie.title }}

    9 10
      11
    • Released in {{ movie.release_date }}
    • 12
    • Directed by {{ movie.director }}
    • 13
    • Produced by {{ movie.producer }}
    • 14
    15 16

    {{ movie.description }}

    17 18

    See all movies

    19 data: movies --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 5 size: 1 6 alias: movie 7 --- 8

    {{ movie.title }}

    9 10
      11
    • Released in {{ movie.release_date }}
    • 12
    • Directed by {{ movie.director }}
    • 13
    • Produced by {{ movie.producer }}
    • 14
    15 16

    {{ movie.description }}

    17 18

    See all movies

    19 size: 1 --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 6 alias: movie 7 --- 8

    {{ movie.title }}

    9 10
      11
    • Released in {{ movie.release_date }}
    • 12
    • Directed by {{ movie.director }}
    • 13
    • Produced by {{ movie.producer }}
    • 14
    15 16

    {{ movie.description }}

    17 18

    See all movies

    19 alias: movie --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 7 --- 8

    {{ movie.title }}

    9 10
      11
    • Released in {{ movie.release_date }}
    • 12
    • Directed by {{ movie.director }}
    • 13
    • Produced by {{ movie.producer }}
    • 14
    15 16

    {{ movie.description }}

    17 18

    See all movies

    19

    {{ movie.title }}

  • Released in {{ movie.release_date }}
  • Directed by {{ movie.director }}
  • Produced by {{ movie.producer }}
  • {{ movie.description }}

    --- 1 layout: base 2 permalink: /movie/{{ movie.title | slug }}/ 3 pagination: 4 data: movies 5 size: 1 6 alias: movie 7 --- 8 9 10
      11 12 13 14
    15 16 17 18

    See all movies

    19 --- layout: base permalink: /movie/{{ movie.title | slug }}/ pagination: data: movies size: 1 alias: movie ---

    {{ movie.title }}

    • Released in {{ movie.release_date }}
    • Directed by {{ movie.director }}
    • Produced by {{ movie.producer }}

    {{ movie.description }}

    See all movies

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 38

    Slide 76

    Slide 76 text

    @loige 39

    Slide 77

    Slide 77 text

    loige.link/11ty-11min 40

    Slide 78

    Slide 78 text

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

    Slide 79

    Slide 79 text

    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