STATIC SITE GENERATION FOR THE MASSES Denis Defreyne FOSDEM 2013 - - PowerPoint PPT Presentation

static site generation for the masses
SMART_READER_LITE
LIVE PREVIEW

STATIC SITE GENERATION FOR THE MASSES Denis Defreyne FOSDEM 2013 - - PowerPoint PPT Presentation

STATIC SITE GENERATION FOR THE MASSES Denis Defreyne FOSDEM 2013 1 Me 2 Me Denis Defreyne 2 Me Denis Defreyne twitter.com/ddfreyne 2 Me Denis Defreyne twitter.com/ddfreyne github.com/ddfreyne 2 Me Denis Defreyne


slide-1
SLIDE 1

STATIC SITE GENERATION FOR THE MASSES

Denis Defreyne

FOSDEM 2013 1

slide-2
SLIDE 2

Me

2

slide-3
SLIDE 3

Me

2

  • Denis Defreyne
slide-4
SLIDE 4

Me

2

  • Denis Defreyne

twitter.com/ddfreyne

slide-5
SLIDE 5

Me

2

  • Denis Defreyne

twitter.com/ddfreyne github.com/ddfreyne

slide-6
SLIDE 6

Me

2

  • Denis Defreyne

twitter.com/ddfreyne github.com/ddfreyne

  • Software Engineer
slide-7
SLIDE 7

Me

2

  • Denis Defreyne

twitter.com/ddfreyne github.com/ddfreyne

  • Software Engineer
  • Author of nanoc
slide-8
SLIDE 8

What exactly does a

STATIC SITE GENERATOR

do?

3

slide-9
SLIDE 9

4

slide-10
SLIDE 10

4

Mark- down

slide-11
SLIDE 11

Markdown

5

In ¡*exactly* ¡one ¡month, ¡there’s ¡FOSDEM ¡ again! ¡I ¡can ¡barely ¡control ¡my ¡excitement! * ¡First ¡element ¡of ¡a ¡list * ¡Second ¡element

slide-12
SLIDE 12

6

Mark- down

slide-13
SLIDE 13

6

Mark- down HTML fragment

slide-14
SLIDE 14

HTML from Markdown

7

<p>In ¡<em>exactly</em> ¡one ¡month, ¡there’s ¡ FOSDEM ¡again! ¡I ¡can ¡barely ¡control ¡my ¡ excitement!</p> <ul> <li>First ¡element ¡of ¡a ¡list</li> <li>Second ¡element</li> </ul>

slide-15
SLIDE 15

8

Mark- down HTML fragment

slide-16
SLIDE 16

8

Mark- down HTML fragment Layout

slide-17
SLIDE 17

Layout

9

<!DOCTYPE ¡html> <html> <head> <title><%= ¡item[:title] ¡%></title> </head> <body> <%= ¡yield ¡%> </body> </html>

slide-18
SLIDE 18

10

Mark- down HTML fragment Layout

slide-19
SLIDE 19

10

Mark- down HTML fragment Layout + HTML

slide-20
SLIDE 20

11

<!DOCTYPE ¡html> <html> <head> <title>One ¡Month ¡until ¡FOSDEM!</title> </head> <body> <p>In ¡<em>exactly</em> ¡one ¡month, ¡there’s ¡FOSDEM ¡ again! ¡I ¡can ¡barely ¡control ¡my ¡excitement!</p> <ul> <li>First ¡element ¡of ¡a ¡list</li> <li>Second ¡element</li> </ul> </body> </html>

slide-21
SLIDE 21

12

Mark- down HTML fragment Layout + HTML

slide-22
SLIDE 22

13

slide-23
SLIDE 23

VPS + 96 MB RAM + Ruby =

TOO SLOW!

13

slide-24
SLIDE 24

14

nanoc

ナ ノック

slide-25
SLIDE 25

15

slide-26
SLIDE 26

16

CMS

Content Management System

slide-27
SLIDE 27

16

CMS

Content Management System

slide-28
SLIDE 28

17

SSG

Static Site Generator

slide-29
SLIDE 29

Road map

18

slide-30
SLIDE 30

Road map

  • 1. What are SSGs?

18

slide-31
SLIDE 31

Road map

  • 1. What are SSGs?
  • 2. What are SSGs capable of?

18

slide-32
SLIDE 32

Road map

  • 1. What are SSGs?
  • 2. What are SSGs capable of?
  • 3. Lessons Learnt & Future Work

18

slide-33
SLIDE 33

19

What are SSGs?

slide-34
SLIDE 34

Tiny example – pages

20

content/ about.md blog/ 2013-­‑01-­‑02-­‑one-­‑month-­‑until-­‑fosdem.md 2013-­‑02-­‑03-­‑fosdem-­‑was-­‑awesome.md

slide-35
SLIDE 35

Tiny example – pages

21

  • ­‑-­‑-­‑

title: ¡One ¡Month ¡until ¡FOSDEM!

  • ­‑-­‑-­‑

In ¡exactly ¡one ¡month, ¡there’s ¡FOSDEM ¡again! ¡ I ¡can ¡barely ¡control ¡my ¡excitement!

slide-36
SLIDE 36

Tiny example – layouts

22

<html> <head> <title><%= ¡item[:title] ¡%></title> </head> <body> <%= ¡yield ¡%> </body> </html>

slide-37
SLIDE 37

Tiny example – result

23

<html> <head> <title>One ¡Month ¡until ¡FOSDEM!</title> </head> <body> In ¡exactly ¡one ¡month, ¡there’s ¡FOSDEM ¡again! ¡I ¡ can ¡barely ¡control ¡my ¡excitement! </body> </html>

slide-38
SLIDE 38

Tiny example – result

24

  • utput/

about/index.html blog/2013/01/one-­‑month-­‑until-­‑fosdem/index.html blog/2012/02/fosdem-­‑was-­‑awesome/index.html

slide-39
SLIDE 39

25

slide-40
SLIDE 40

26

slide-41
SLIDE 41

27

slide-42
SLIDE 42

28

slide-43
SLIDE 43

29

slide-44
SLIDE 44

30

slide-45
SLIDE 45

31

slide-46
SLIDE 46

32

slide-47
SLIDE 47

33

slide-48
SLIDE 48

Ace - awestruct - Blacksmith - Blogofile - Bonsai - Cactus

  • Chisel - coleslaw - Composer - cyrax - Deplot - Fairytale
  • FMPP - Frank - fugitive - Graze - Hakyll - Hammer -

Hastie - Hobix - Hyde - Jekyll - jinjet - jkl - Korma - Machined - Magneto - Markbox - Markdoc - Middleman - mynt - nanoc - Nikola - Octopress - Pagegen - Pelican - Petrify - Phrozn - PieCrust - Pilcrow - Pith - poole - Punch

  • Quill - RakeWeb - Rassmalog - Rizzo - Rog - romulus -

Rote - RubyFrontier - Ruroh - Second Crack - Socrates - Speechhub - Stasis - staticjinja - StaticMatic - StaticMatic2 - StaticWeb - Tahchee - Ultra simple Site Maker - Webby - webgen - Website Meta Language - Wintersmith - wok - yassg - yst - Yurt CMS - ZenWeb

33

slide-49
SLIDE 49

Ace - awestruct - Blacksmith - Blogofile - Bonsai - Cactus

  • Chisel - coleslaw - Composer - cyrax - Deplot - Fairytale
  • FMPP - Frank - fugitive - Graze - Hakyll - Hammer -

Hastie - Hobix - Hyde - Jekyll - jinjet - jkl - Korma - Machined - Magneto - Markbox - Markdoc - Middleman - mynt - nanoc - Nikola - Octopress - Pagegen - Pelican - Petrify - Phrozn - PieCrust - Pilcrow - Pith - poole - Punch

  • Quill - RakeWeb - Rassmalog - Rizzo - Rog - romulus -

Rote - RubyFrontier - Ruroh - Second Crack - Socrates - Speechhub - Stasis - staticjinja - StaticMatic - StaticMatic2 - StaticWeb - Tahchee - Ultra simple Site Maker - Webby - webgen - Website Meta Language - Wintersmith - wok - yassg - yst - Yurt CMS - ZenWeb

33

slide-50
SLIDE 50

Ace - awestruct - Blacksmith - Blogofile - Bonsai - Cactus

  • Chisel - coleslaw - Composer - cyrax - Deplot - Fairytale
  • FMPP - Frank - fugitive - Graze - Hakyll - Hammer -

Hastie - Hobix - Hyde - Jekyll - jinjet - jkl - Korma - Machined - Magneto - Markbox - Markdoc - Middleman - mynt - nanoc - Nikola - Octopress - Pagegen - Pelican - Petrify - Phrozn - PieCrust - Pilcrow - Pith - poole - Punch

  • Quill - RakeWeb - Rassmalog - Rizzo - Rog - romulus -

Rote - RubyFrontier - Ruroh - Second Crack - Socrates - Speechhub - Stasis - staticjinja - StaticMatic - StaticMatic2 - StaticWeb - Tahchee - Ultra simple Site Maker - Webby - webgen - Website Meta Language - Wintersmith - wok - yassg - yst - Yurt CMS - ZenWeb

33

INCOMPLETE

slide-51
SLIDE 51

34

slide-52
SLIDE 52

35

slide-53
SLIDE 53

36

slide-54
SLIDE 54

37

Why static sites?

slide-55
SLIDE 55

37

  • 1. Fast

Why static sites?

slide-56
SLIDE 56

37

  • 1. Fast
  • 2. Secure

Why static sites?

slide-57
SLIDE 57

37

  • 1. Fast
  • 2. Secure
  • 3. Works with your own tools (vim!)

Why static sites?

slide-58
SLIDE 58

37

  • 1. Fast
  • 2. Secure
  • 3. Works with your own tools (vim!)
  • 4. Content is in plain text

Why static sites?

slide-59
SLIDE 59

37

  • 1. Fast
  • 2. Secure
  • 3. Works with your own tools (vim!)
  • 4. Content is in plain text
  • 5. Easy to deploy

Why static sites?

slide-60
SLIDE 60

37

  • 1. Fast
  • 2. Secure
  • 3. Works with your own tools (vim!)
  • 4. Content is in plain text
  • 5. Easy to deploy
  • 6. Easy to preview

Why static sites?

slide-61
SLIDE 61

37

  • 1. Fast
  • 2. Secure
  • 3. Works with your own tools (vim!)
  • 4. Content is in plain text
  • 5. Easy to deploy
  • 6. Easy to preview
  • 7. Makes collaboration easy

Why static sites?

slide-62
SLIDE 62

38

slide-63
SLIDE 63

39

What are SSGs capable of?

slide-64
SLIDE 64

Arbitrary metadata

40

slide-65
SLIDE 65

Arbitrary metadata

41

title: ¡ ¡ ¡Braid kind: ¡ ¡ ¡ ¡review subtype: ¡game year: ¡ ¡ ¡ ¡2008 rating: ¡ ¡5

slide-66
SLIDE 66

Arbitrary metadata

42

<ul> <% ¡@item.children ¡do ¡|review| ¡%> <li> <%= ¡'★' ¡* ¡review[:rating] ¡%> <%= ¡review[:title] ¡%> </li> <% ¡end ¡%> </ul>

slide-67
SLIDE 67

Arbitrary metadata

43

<ul> <li>★★★★☆ ¡Borderlands</li> <li>★★★★★ ¡Braid</li> <li>★★★★☆ ¡Legend ¡of ¡Grimrock</li> <li>★★★★★ ¡Max ¡Payne</li> <li>★★★★☆ ¡Minecraft</li> </ul>

slide-68
SLIDE 68

Filters

44

slide-69
SLIDE 69

Filters – Markdown

A ¡First ¡Level ¡Header ==================== A ¡Second ¡Level ¡Header

  • ­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑-­‑

Now ¡is ¡the ¡time ¡for ¡all ¡good ¡men ¡to ¡come ¡to ¡the ¡aid ¡of ¡their ¡

  • country. ¡This ¡is ¡just ¡a ¡regular ¡paragraph.

* ¡Quick ¡brown ¡fox * ¡Lazy ¡dog

45

slide-70
SLIDE 70

Filters – Textile

  • h1. ¡Give ¡RedCloth ¡a ¡try!

A ¡*simple* ¡paragraph ¡with a ¡line ¡break, ¡some ¡_emphasis_ ¡and ¡a ¡"link":http://redcloth.org * ¡an ¡item * ¡and ¡another # ¡one # ¡two

46

slide-71
SLIDE 71

Filters – ERB

<!DOCTYPE ¡html> <html> <head> <title><%= ¡item[:title] ¡%></title> </head> <body> <%= ¡yield ¡%> </body> </html>

47

slide-72
SLIDE 72

Filters – Mustache

<!DOCTYPE ¡html> <html> <head> <title>{{ ¡title ¡}}</title> </head> <body> {{ ¡yield ¡}} </body> </html>

48

slide-73
SLIDE 73

Filters – Haml

!!! %html %head %title= ¡@item[:title] %body = ¡yield

49

slide-74
SLIDE 74

Filters – Colorize Syntax

<pre><code ¡class="language-­‑ruby"> def ¡my_function ¡ ¡(1..10).map ¡do ¡|i| ¡ ¡ ¡ ¡"#{i} ¡is ¡#{i ¡% ¡2 ¡== ¡1 ¡? ¡'odd' ¡: ¡'even'}" ¡ ¡end end </code></pre>

50

slide-75
SLIDE 75

Filters – Colorize Syntax

def ¡my_function ¡ ¡(1..10).map ¡do ¡|i| ¡ ¡ ¡ ¡"#{i} ¡is ¡#{i ¡% ¡2 ¡== ¡1 ¡? ¡'odd' ¡: ¡'even'}" ¡ ¡end end

51

slide-76
SLIDE 76

Filters – Typogruby

52

"Typogruby makes HTML look smarter & better, don't you think?" “Typogruby makes HTML look smarter & better, don’t you think?”

slide-77
SLIDE 77

Filters – Custom

class ¡CensorFilter ¡< ¡Nanoc::Filter identifier ¡:censor def ¡run(content, ¡params={}) content.gsub('nanoc ¡sucks', ¡'nanoc ¡rocks') end end

53

slide-78
SLIDE 78

Rules

54

slide-79
SLIDE 79

Rules

55

compile ¡'*' ¡do if ¡@item[:kind] ¡== ¡'article' filter ¡:bluecloth end layout ¡'default' end

slide-80
SLIDE 80

Rules

56

compile ¡'/images/*/' ¡do ¡ ¡filter ¡:img_optimize end

slide-81
SLIDE 81

Rules

57

compile ¡'/images/*/' ¡do ¡ ¡filter ¡:img_optimize end compile ¡'/images/*/', ¡:rep ¡=> ¡:thumbnail ¡do ¡ ¡filter ¡:scale, ¡:width ¡=> ¡140 end

slide-82
SLIDE 82

Rules

58

compile ¡'/blog/*/', ¡:rep ¡=> ¡:mp3 ¡do ¡ ¡filter ¡:say ¡ ¡filter ¡:lame end

slide-83
SLIDE 83

Rules versus Makefiles

59

slide-84
SLIDE 84

Rules versus Makefiles

59

  • Push vs. pull
slide-85
SLIDE 85

Rules versus Makefiles

59

  • Push vs. pull
  • Cleaner syntax
slide-86
SLIDE 86

Rules versus Makefiles

59

  • Push vs. pull
  • Cleaner syntax
  • Automatic dependency tracking
slide-87
SLIDE 87

Helpers

60

slide-88
SLIDE 88

61

module ¡Nanoc::Helpers::Tagging # ¡Find ¡all ¡items ¡with ¡the ¡given ¡tag. # # ¡@param ¡[String] ¡tag ¡The ¡tag ¡for ¡which ¡to ¡find ¡all ¡items # # ¡@return ¡[Array] ¡All ¡items ¡with ¡the ¡given ¡tag def ¡items_with_tag(tag) @items.select ¡do ¡|i| (i[:tags] ¡|| ¡[]).include?(tag) end end end

slide-89
SLIDE 89

Helpers – example

62

<h1>Tags ¡for ¡<%= ¡@item[:tag] ¡%></h1> <ul> <% ¡items_with_tag(@item[:tag]).each ¡do ¡|i| ¡%> <li><%= ¡link_to(@item[:tag], ¡i) ¡%></li> <% ¡end ¡%> </ul>

slide-90
SLIDE 90

Workflow

63

slide-91
SLIDE 91

Workflow

63

  • 1. Development
slide-92
SLIDE 92

Workflow

63

  • 1. Development

1. Version controlled

slide-93
SLIDE 93

Workflow

63

  • 1. Development

1. Version controlled 2. Branched development

slide-94
SLIDE 94

Workflow

63

  • 1. Development

1. Version controlled 2. Branched development 3. Pull requests

slide-95
SLIDE 95

Workflow

63

  • 1. Development

1. Version controlled 2. Branched development 3. Pull requests

  • 2. Release
slide-96
SLIDE 96

Workflow

63

  • 1. Development

1. Version controlled 2. Branched development 3. Pull requests

  • 2. Release

1. Preview

slide-97
SLIDE 97

Workflow

63

  • 1. Development

1. Version controlled 2. Branched development 3. Pull requests

  • 2. Release

1. Preview 2. Check

slide-98
SLIDE 98

Workflow

63

  • 1. Development

1. Version controlled 2. Branched development 3. Pull requests

  • 2. Release

1. Preview 2. Check 3. Deploy

slide-99
SLIDE 99

64

Data Sources

slide-100
SLIDE 100

65

Data Sources – nanoc

slide-101
SLIDE 101

66

nanoc site

CLI YARD FS

{

slide-102
SLIDE 102

67

nanoc CLI – definition

name ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡'dostuff' usage ¡ ¡ ¡ ¡ ¡ ¡ ¡'dostuff ¡[options]' aliases ¡ ¡ ¡ ¡ ¡:ds, ¡:stuff summary ¡ ¡ ¡ ¡ ¡'does ¡stuff' description ¡'This ¡command ¡does ¡a ¡lot!'

GITHUB.COM/DDFREYNE/CRI

slide-103
SLIDE 103

68

nanoc CLI – generated help

NAME ¡ ¡ ¡ ¡dostuff ¡-­‑ ¡does ¡stuff USAGE ¡ ¡ ¡ ¡dostuff ¡[options] DESCRIPTION ¡ ¡ ¡ ¡This ¡command ¡does ¡a ¡lot ¡of ¡stuff. ¡I ¡really ¡mean ¡a ¡lot. OPTIONS ¡ ¡ ¡ ¡-­‑h ¡-­‑-­‑help ¡ ¡ ¡ ¡ ¡ ¡show ¡help ¡for ¡this ¡command ¡ ¡ ¡ ¡-­‑m ¡-­‑-­‑more ¡ ¡ ¡ ¡ ¡ ¡do ¡even ¡more ¡stuff ¡ ¡ ¡ ¡-­‑s ¡-­‑-­‑stuff ¡ ¡ ¡ ¡ ¡specify ¡stuff ¡to ¡do

GITHUB.COM/DDFREYNE/CRI

slide-104
SLIDE 104

69

slide-105
SLIDE 105

nanoc filter

class ¡CensorFilter ¡< ¡Nanoc::Filter identifier ¡:censor # ¡Some ¡documentation ¡goes ¡here… def ¡run(content, ¡params={}) content.gsub('nanoc ¡sucks', ¡'nanoc ¡rocks') end end

70

slide-106
SLIDE 106

71

slide-107
SLIDE 107

71

slide-108
SLIDE 108

72

slide-109
SLIDE 109

72

slide-110
SLIDE 110

73

slide-111
SLIDE 111

74

Data Sources – FOSDEM

slide-112
SLIDE 112

{

75

FOSDEM site

PentaBarf FS

slide-113
SLIDE 113

76

slide-114
SLIDE 114

77

slide-115
SLIDE 115

78

github.com/fosdem/website

slide-116
SLIDE 116

78

github.com/fosdem/website

slide-117
SLIDE 117

SSGs advantages

79

slide-118
SLIDE 118

SSGs advantages

  • More than Markdown + layout → HTML!

79

slide-119
SLIDE 119

SSGs advantages

  • More than Markdown + layout → HTML!
  • Satisfactory in many cases

79

slide-120
SLIDE 120

SSGs advantages

  • More than Markdown + layout → HTML!
  • Satisfactory in many cases
  • Dynamic with JavaScript

79

slide-121
SLIDE 121

SSGs advantages

  • More than Markdown + layout → HTML!
  • Satisfactory in many cases
  • Dynamic with JavaScript
  • Usable for publishing your data

79

slide-122
SLIDE 122

80

Lessons Learnt

slide-123
SLIDE 123

Internal DSLs

81

slide-124
SLIDE 124

Internal DSLs

compile ¡'/about/' ¡do filter ¡:kramdown end

82

slide-125
SLIDE 125

Internal DSLs – side effects

compile ¡'/about/' ¡do filter ¡:kramdown File.open('output/stuff.txt', ¡'w') ¡do ¡|f| f.write(item.raw_content) end end

83

slide-126
SLIDE 126

Internal DSLs – mutability

compile ¡'/articles/*/' ¡do ¡ ¡unless ¡@item[:layout] @item[:layout] ¡= ¡'article' end ¡ ¡layout ¡@item[:layout] end

84

slide-127
SLIDE 127

Speed

85

slide-128
SLIDE 128

Incremental compilation

86

slide-129
SLIDE 129

Incremental compilation

86

  • Recompile only what’s necessary
slide-130
SLIDE 130

Incremental compilation

86

  • Recompile only what’s necessary
  • Ω (#items) → Ω(#changed-items)
slide-131
SLIDE 131

Incremental compilation

86

  • Recompile only what’s necessary
  • Ω (#items) → Ω(#changed-items)
  • Scenarios
slide-132
SLIDE 132

Incremental compilation

86

  • Recompile only what’s necessary
  • Ω (#items) → Ω(#changed-items)
  • Scenarios

Single changed page

slide-133
SLIDE 133

Incremental compilation

86

  • Recompile only what’s necessary
  • Ω (#items) → Ω(#changed-items)
  • Scenarios

Single changed page Changed page that is included elsewhere

slide-134
SLIDE 134

Incremental compilation

86

  • Recompile only what’s necessary
  • Ω (#items) → Ω(#changed-items)
  • Scenarios

Single changed page Changed page that is included elsewhere Changed rules

slide-135
SLIDE 135

Pick the right libraries

87

slide-136
SLIDE 136

Pick the right libraries

  • RubyPants, Typogruby

87

slide-137
SLIDE 137

Pick the right libraries

  • RubyPants, Typogruby

Winner: Fast Aleck

87

slide-138
SLIDE 138

Pick the right libraries

  • RubyPants, Typogruby

Winner: Fast Aleck

  • pygmentize, pygments.rb

87

slide-139
SLIDE 139

Pick the right libraries

  • RubyPants, Typogruby

Winner: Fast Aleck

  • pygmentize, pygments.rb

Winner: pygments.rb

87

slide-140
SLIDE 140

88

slide-141
SLIDE 141

89

slide-142
SLIDE 142

90

Future Work

slide-143
SLIDE 143

Future Work

91

slide-144
SLIDE 144

Future Work

91

  • Improving speed (Parallellisation)
slide-145
SLIDE 145

Future Work

91

  • Improving speed (Parallellisation)
  • Supporting huge sites
slide-146
SLIDE 146

Future Work

91

  • Improving speed (Parallellisation)
  • Supporting huge sites
  • Writing great documentation
slide-147
SLIDE 147

Future Work

91

  • Improving speed (Parallellisation)
  • Supporting huge sites
  • Writing great documentation
  • Building an active contributors’ community
slide-148
SLIDE 148

Future Work

91

  • Improving speed (Parallellisation)
  • Supporting huge sites
  • Writing great documentation
  • Building an active contributors’ community
  • GUI?
slide-149
SLIDE 149

92

Recap

slide-150
SLIDE 150

SSGs…

93

slide-151
SLIDE 151

SSGs…

93

  • have big obvious advantages
slide-152
SLIDE 152

SSGs…

93

  • have big obvious advantages

fast, secure, easy to deploy, …

slide-153
SLIDE 153

SSGs…

93

  • have big obvious advantages

fast, secure, easy to deploy, …

  • have big non-obvious advantages
slide-154
SLIDE 154

SSGs…

93

  • have big obvious advantages

fast, secure, easy to deploy, …

  • have big non-obvious advantages

metadata, data sources, checks, …

slide-155
SLIDE 155

SSGs…

93

  • have big obvious advantages

fast, secure, easy to deploy, …

  • have big non-obvious advantages

metadata, data sources, checks, …

  • turn your web site into an open-source project!
slide-156
SLIDE 156

SSGs…

93

  • have big obvious advantages

fast, secure, easy to deploy, …

  • have big non-obvious advantages

metadata, data sources, checks, …

  • turn your web site into an open-source project!

share, learn, collaborate

slide-157
SLIDE 157

94

slide-158
SLIDE 158

94 MAIL denis.defreyne@stoneship.org

TWITTER @ddfreyne GITHUB github.com/ddfreyne

WWW nanoc.ws

GITHUB github.com/nanoc

IRC freenode #nanoc

slide-159
SLIDE 159

95

Extra Slides!

slide-160
SLIDE 160

Preprocessing

96

preprocess ¡do ts ¡= ¡Set.new(@items.map ¡{ ¡|i| ¡i[:tags] ¡}.flatten) ts.each ¡do ¡|tag| @items ¡<< ¡Nanoc::Item.new( "", ¡{ ¡:tag ¡=> ¡tag ¡}, ¡"/tags/#{tag}/") end end