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

Static Site Generation for the Masses

Static Site Generation for the Masses

Static website generators are slowly rising in popularity and have been proven to be a worthy alternatives to CMSes in many cases. This talk explains what static site generators are, how they avoid the traditional problems with CMSes, and explains what technical challenges must be overcome when implementing one.

Denis Defreyne

February 03, 2013
Tweet

More Decks by Denis Defreyne

Other Decks in Technology

Transcript

  1. STATIC SITE GENERATION
    FOR THE MASSES
    Denis Defreyne
    FOSDEM 2013
    1

    View full-size slide

  2. Me
    2
    ‣ Denis Defreyne

    View full-size slide

  3. Me
    2
    ‣ Denis Defreyne
    twitter.com/ddfreyne

    View full-size slide

  4. Me
    2
    ‣ Denis Defreyne
    twitter.com/ddfreyne
    github.com/ddfreyne

    View full-size slide

  5. Me
    2
    ‣ Denis Defreyne
    twitter.com/ddfreyne
    github.com/ddfreyne
    ‣ Software Engineer

    View full-size slide

  6. Me
    2
    ‣ Denis Defreyne
    twitter.com/ddfreyne
    github.com/ddfreyne
    ‣ Software Engineer
    ‣ Author of nanoc

    View full-size slide

  7. What exactly does a
    STATIC SITE GENERATOR
    do?
    3

    View full-size slide

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

    View full-size slide

  9. 6
    Mark-
    down
    HTML
    fragment

    View full-size slide

  10. HTML from Markdown
    7
    In  exactly  one  month,  there’s  
    FOSDEM  again!  I  can  barely  control  my  
    excitement!

    First  element  of  a  list
    Second  element

    View full-size slide

  11. 8
    Mark-
    down
    HTML
    fragment

    View full-size slide

  12. 8
    Mark-
    down
    HTML
    fragment
    Layout

    View full-size slide

  13. Layout
    9



    <%=  item[:title]  %>


    <%=  yield  %>


    View full-size slide

  14. 10
    Mark-
    down
    HTML
    fragment
    Layout

    View full-size slide

  15. 10
    Mark-
    down
    HTML
    fragment
    Layout
    +
    HTML

    View full-size slide

  16. 11



    One  Month  until  FOSDEM!


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

    First  element  of  a  list
    Second  element



    View full-size slide

  17. 12
    Mark-
    down
    HTML
    fragment
    Layout
    +
    HTML

    View full-size slide

  18. VPS + 96 MB RAM + Ruby =
    TOO SLOW!
    13

    View full-size slide

  19. 14
    nanoc
    φϊοΫ

    View full-size slide

  20. 16
    CMS
    Content Management System

    View full-size slide

  21. 16
    CMS
    Content Management System

    View full-size slide

  22. 17
    SSG
    Static Site Generator

    View full-size slide

  23. Road map
    1. What are SSGs?
    18

    View full-size slide

  24. Road map
    1. What are SSGs?
    2. What are SSGs capable of?
    18

    View full-size slide

  25. Road map
    1. What are SSGs?
    2. What are SSGs capable of?
    3. Lessons Learnt & Future Work
    18

    View full-size slide

  26. 19
    What are SSGs?

    View full-size slide

  27. Tiny example – pages
    20
    content/
    about.md
    blog/
    2013-­‐01-­‐02-­‐one-­‐month-­‐until-­‐fosdem.md
    2013-­‐02-­‐03-­‐fosdem-­‐was-­‐awesome.md

    View full-size slide

  28. Tiny example – pages
    21
    -­‐-­‐-­‐
    title:  One  Month  until  FOSDEM!
    -­‐-­‐-­‐
    In  exactly  one  month,  there’s  FOSDEM  again!  
    I  can  barely  control  my  excitement!

    View full-size slide

  29. Tiny example – layouts
    22


    <%=  item[:title]  %>


    <%=  yield  %>


    View full-size slide

  30. Tiny example – result
    23


    One  Month  until  FOSDEM!


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


    View full-size slide

  31. Tiny example – result
    24
    output/
    about/index.html
    blog/2013/01/one-­‐month-­‐until-­‐fosdem/index.html
    blog/2012/02/fosdem-­‐was-­‐awesome/index.html

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  35. 37
    Why static sites?

    View full-size slide

  36. 37
    1. Fast
    Why static sites?

    View full-size slide

  37. 37
    1. Fast
    2. Secure
    Why static sites?

    View full-size slide

  38. 37
    1. Fast
    2. Secure
    3. Works with your own tools (vim!)
    Why static sites?

    View full-size slide

  39. 37
    1. Fast
    2. Secure
    3. Works with your own tools (vim!)
    4. Content is in plain text
    Why static sites?

    View full-size slide

  40. 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?

    View full-size slide

  41. 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?

    View full-size slide

  42. 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?

    View full-size slide

  43. 39
    What are SSGs capable of?

    View full-size slide

  44. Arbitrary metadata
    40

    View full-size slide

  45. Arbitrary metadata
    41
    title:      Braid
    kind:        review
    subtype:  game
    year:        2008
    rating:    5

    View full-size slide

  46. Arbitrary metadata
    42

    <%  @item.children  do  |review|  %>

    <%=  '˒'  *  review[:rating]  %>
    <%=  review[:title]  %>

    <%  end  %>

    View full-size slide

  47. Arbitrary metadata
    43

    ˒˒˒˒ˑ  Borderlands
    ˒˒˒˒˒  Braid
    ˒˒˒˒ˑ  Legend  of  Grimrock
    ˒˒˒˒˒  Max  Payne
    ˒˒˒˒ˑ  Minecraft

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  50. Filters – ERB



    <%=  item[:title]  %>


    <%=  yield  %>


    47

    View full-size slide

  51. Filters – Mustache



    {{  title  }}


    {{  yield  }}


    48

    View full-size slide

  52. Filters – Haml
    !!!
    %html
    %head
    %title=  @item[:title]
    %body
    =  yield
    49

    View full-size slide

  53. Filters – Colorize Syntax

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

    50

    View full-size slide

  54. Filters – Colorize Syntax
    def  my_function
       (1..10).map  do  |i|
           "#{i}  is  #{i  %  2  ==  1  ?  'odd'  :  'even'}"
       end
    end
    51

    View full-size slide

  55. Filters – Typogruby
    52
    "Typogruby makes HTML look
    smarter & better, don't you think?"
    “Typogruby makes HTML look
    smarter & better, don’t you think?”

    View full-size slide

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

    View full-size slide

  57. Rules
    55
    compile  '*'  do
    if  @item[:kind]  ==  'article'
    filter  :bluecloth
    end
    layout  'default'
    end

    View full-size slide

  58. Rules
    56
    compile  '/images/*/'  do
       filter  :img_optimize
    end

    View full-size slide

  59. Rules
    57
    compile  '/images/*/'  do
       filter  :img_optimize
    end
    compile  '/images/*/',  :rep  =>  :thumbnail  do
       filter  :scale,  :width  =>  140
    end

    View full-size slide

  60. Rules
    58
    compile  '/blog/*/',  :rep  =>  :mp3  do
       filter  :say
       filter  :lame
    end

    View full-size slide

  61. Rules versus Makefiles
    59

    View full-size slide

  62. Rules versus Makefiles
    59
    ‣ Push vs. pull

    View full-size slide

  63. Rules versus Makefiles
    59
    ‣ Push vs. pull
    ‣ Cleaner syntax

    View full-size slide

  64. Rules versus Makefiles
    59
    ‣ Push vs. pull
    ‣ Cleaner syntax
    ‣ Automatic dependency tracking

    View full-size slide

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

    View full-size slide

  66. Helpers – example
    62
    Tags  for  <%=  @item[:tag]  %>

    <%  items_with_tag(@item[:tag]).each  do  |i|  %>
    <%=  link_to(@item[:tag],  i)  %>
    <%  end  %>

    View full-size slide

  67. Workflow
    63
    1. Development

    View full-size slide

  68. Workflow
    63
    1. Development
    1. Version controlled

    View full-size slide

  69. Workflow
    63
    1. Development
    1. Version controlled
    2. Branched development

    View full-size slide

  70. Workflow
    63
    1. Development
    1. Version controlled
    2. Branched development
    3. Pull requests

    View full-size slide

  71. Workflow
    63
    1. Development
    1. Version controlled
    2. Branched development
    3. Pull requests
    2. Release

    View full-size slide

  72. Workflow
    63
    1. Development
    1. Version controlled
    2. Branched development
    3. Pull requests
    2. Release
    1. Preview

    View full-size slide

  73. Workflow
    63
    1. Development
    1. Version controlled
    2. Branched development
    3. Pull requests
    2. Release
    1. Preview
    2. Check

    View full-size slide

  74. Workflow
    63
    1. Development
    1. Version controlled
    2. Branched development
    3. Pull requests
    2. Release
    1. Preview
    2. Check
    3. Deploy

    View full-size slide

  75. 64
    Data Sources

    View full-size slide

  76. 65
    Data Sources – nanoc

    View full-size slide

  77. 66
    nanoc site CLI
    YARD
    FS
    {

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  81. 74
    Data Sources – FOSDEM

    View full-size slide

  82. {
    75
    FOSDEM site
    PentaBarf
    FS

    View full-size slide

  83. 78
    github.com/fosdem/website

    View full-size slide

  84. 78
    github.com/fosdem/website

    View full-size slide

  85. SSGs advantages
    79

    View full-size slide

  86. SSGs advantages
    ‣ More than Markdown + layout → HTML!
    79

    View full-size slide

  87. SSGs advantages
    ‣ More than Markdown + layout → HTML!
    ‣ Satisfactory in many cases
    79

    View full-size slide

  88. SSGs advantages
    ‣ More than Markdown + layout → HTML!
    ‣ Satisfactory in many cases
    ‣ Dynamic with JavaScript
    79

    View full-size slide

  89. SSGs advantages
    ‣ More than Markdown + layout → HTML!
    ‣ Satisfactory in many cases
    ‣ Dynamic with JavaScript
    ‣ Usable for publishing your data
    79

    View full-size slide

  90. 80
    Lessons Learnt

    View full-size slide

  91. Internal DSLs
    81

    View full-size slide

  92. Internal DSLs
    compile  '/about/'  do
    filter  :kramdown
    end
    82

    View full-size slide

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

    View full-size slide

  94. Internal DSLs – mutability
    compile  '/articles/*/'  do
       unless  @item[:layout]
    @item[:layout]  =  'article'
    end
       layout  @item[:layout]
    end
    84

    View full-size slide

  95. Incremental compilation
    86

    View full-size slide

  96. Incremental compilation
    86
    ‣ Recompile only what’s necessary

    View full-size slide

  97. Incremental compilation
    86
    ‣ Recompile only what’s necessary
    ‣ Ω (#items) → Ω(#changed-items)

    View full-size slide

  98. Incremental compilation
    86
    ‣ Recompile only what’s necessary
    ‣ Ω (#items) → Ω(#changed-items)
    ‣ Scenarios

    View full-size slide

  99. Incremental compilation
    86
    ‣ Recompile only what’s necessary
    ‣ Ω (#items) → Ω(#changed-items)
    ‣ Scenarios
    Single changed page

    View full-size slide

  100. Incremental compilation
    86
    ‣ Recompile only what’s necessary
    ‣ Ω (#items) → Ω(#changed-items)
    ‣ Scenarios
    Single changed page
    Changed page that is included elsewhere

    View full-size slide

  101. Incremental compilation
    86
    ‣ Recompile only what’s necessary
    ‣ Ω (#items) → Ω(#changed-items)
    ‣ Scenarios
    Single changed page
    Changed page that is included elsewhere
    Changed rules

    View full-size slide

  102. Pick the right libraries
    87

    View full-size slide

  103. Pick the right libraries
    ‣ RubyPants, Typogruby
    87

    View full-size slide

  104. Pick the right libraries
    ‣ RubyPants, Typogruby
    Winner: Fast Aleck
    87

    View full-size slide

  105. Pick the right libraries
    ‣ RubyPants, Typogruby
    Winner: Fast Aleck
    ‣ pygmentize, pygments.rb
    87

    View full-size slide

  106. Pick the right libraries
    ‣ RubyPants, Typogruby
    Winner: Fast Aleck
    ‣ pygmentize, pygments.rb
    Winner: pygments.rb
    87

    View full-size slide

  107. 90
    Future Work

    View full-size slide

  108. Future Work
    91

    View full-size slide

  109. Future Work
    91
    ‣ Improving speed (Parallellisation)

    View full-size slide

  110. Future Work
    91
    ‣ Improving speed (Parallellisation)
    ‣ Supporting huge sites

    View full-size slide

  111. Future Work
    91
    ‣ Improving speed (Parallellisation)
    ‣ Supporting huge sites
    ‣ Writing great documentation

    View full-size slide

  112. Future Work
    91
    ‣ Improving speed (Parallellisation)
    ‣ Supporting huge sites
    ‣ Writing great documentation
    ‣ Building an active contributors’ community

    View full-size slide

  113. Future Work
    91
    ‣ Improving speed (Parallellisation)
    ‣ Supporting huge sites
    ‣ Writing great documentation
    ‣ Building an active contributors’ community
    ‣ GUI?

    View full-size slide

  114. SSGs…
    93
    ‣ have big obvious advantages

    View full-size slide

  115. SSGs…
    93
    ‣ have big obvious advantages
    fast, secure, easy to deploy, …

    View full-size slide

  116. SSGs…
    93
    ‣ have big obvious advantages
    fast, secure, easy to deploy, …
    ‣ have big non-obvious advantages

    View full-size slide

  117. SSGs…
    93
    ‣ have big obvious advantages
    fast, secure, easy to deploy, …
    ‣ have big non-obvious advantages
    metadata, data sources, checks, …

    View full-size slide

  118. 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!

    View full-size slide

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

    View full-size slide

  120. 94
    MAIL [email protected]
    TWITTER @ddfreyne
    GITHUB github.com/ddfreyne
    WWW nanoc.ws
    GITHUB github.com/nanoc
    IRC freenode #nanoc

    View full-size slide

  121. 95
    Extra Slides!

    View full-size slide

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

    View full-size slide