Coding an entire website with only a few dozen lines of code

Markdown: the basic text markup language

Take a look at the raw markdown source for the pages on this website, which are more informative than stepping through a lot of examples explictly. By comparing the raw markdown with the final generated html and webpage, it is clear how compact and efficient writing in markdown can be. Each post page starts with several lines delimited by three dashes; this is the yaml header, which gives configuration options, discussed later. Everything that is translated into material that appears on the generated webpages.

Github-flavored Markdown

There is a standard version of Markdown, but Github has chosen a slightly extended version of the language with a few more formatting commands, and slightly different behavior. This dialect must be specified in the options for the Markdown converter in order for the text to be interpreted properly.

Jekyll: Building a website

Ruby and its installed option are configured by Gemfile in the root directory of the site, which is really short in this case (just make the file and everything works; there is nothing else that needs to address this):

source 'https://rubygems.org'
gem 'github-pages'

Jekyll’s configuration options are held in a configuration file, config.yml:

markdown: kramdown
kramdown:
   input: GFM
   default_lang: python

This specifies the software package Kramdown as the program (used by Github) that converts Markdown to html5 with CSS formatting, using the templates. Kramdown is configured to use the extended style conventions in Github-flavored Markdown, abbreviated GFM, and the default language for codeblocks, but at least at present, this doesn’t really affect things as presented by Github. Kramdown takes the posts in the _posts subdirectory, and converts them to html. The posts themselves cannot determine their placement and indexing, which is controlled by other files and integrated by Kramdown.

index.html

The site’s main index.html is quite brief:

---
layout: master
title: Colloid Physics on the International Space Station
---
<div class="header">
  <div class="container">
    <a class="pull-left logo col-sm-6" href="https://colloids.github.io">
      <p>Colloid Physics in Space</p>
    </a>
    <p class="pull-right tagline col-sm-6 hidden-xs">updates from ACE aboard ISS by <a href="http://www.peterlu.org/" target="_blank">Peter J Lu</a></p>
  </div> <!-- /.container -->
</div> <!-- /.header -->

<div class="ticker">
<div class="container">
  <div id="carousel-home" class="carousel slide" data-ride="carousel">
          <div class="row">
            <div class="col-sm-1 hidden-xs">
                <a class="right carousel-control" href="#carousel-home" role="button" data-slide="prev">
                <span class="glyphicon glyphicon-chevron-left"></span>
              </a>
            </div>
              <div class="col-sm-10 headline">
                  <div class="carousel-inner">
                    
                      <div class="item active">
                          <div class="carousel-content">
                              <div>
                                  <a href="/policy/2014/09/09/stop_work.html"><p>During operations, NASA eliminates our funding for the rest of the year</p></a>
                              </div>
                          </div>
                      </div>
                    
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/09/05/slow_phase_sep.html"><p>Significant science, slower phase separation in ACE than in BCAT-KP</p></a>
                              </div>
                          </div>
                      </div>
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/08/26/same_sample.html"><p>Same sample, different behavior?</p></a>
                              </div>
                          </div>
                      </div>
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/08/22/gelation_phase_sep.html"><p>Significant science, gelation and phase separation</p></a>
                              </div>
                          </div>
                      </div>
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/08/21/stabilize_images.html"><p>Image stabilization and filtering</p></a>
                              </div>
                          </div>
                      </div>
                    
                  </div> <!-- .carousel-inner -->
              </div> <!-- .col-sm-10 -->
              <div class="col-sm-1 hidden-xs">
                <a class="left carousel-control" href="#carousel-home" role="button" data-slide="next" style="margin-right:15px;">
                  <span class="glyphicon glyphicon-chevron-right"></span>
                </a>
              </div>
        </div> <!-- .row-->
    </div> <!-- .carousel-->
</div> <!-- .container-->
</div> <!-- .ticker-->


<article>
  <h1>BCAT and ACE: Colloid Physics in Space</h1>
  <ul class="posts">
    
      <li><span>09 Sep 2014</span>: <a href="/policy/2014/09/09/stop_work.html">During operations, NASA eliminates our funding for the rest of the year</a></li>
    
      <li><span>05 Sep 2014</span>: <a href="/science/operations/2014/09/05/slow_phase_sep.html">Significant science, slower phase separation in ACE than in BCAT-KP</a></li>
    
      <li><span>26 Aug 2014</span>: <a href="/science/operations/2014/08/26/same_sample.html">Same sample, different behavior?</a></li>
    
      <li><span>22 Aug 2014</span>: <a href="/science/operations/2014/08/22/gelation_phase_sep.html">Significant science, gelation and phase separation</a></li>
    
      <li><span>21 Aug 2014</span>: <a href="/science/operations/2014/08/21/stabilize_images.html">Image stabilization and filtering</a></li>
    
      <li><span>18 Aug 2014</span>: <a href="/operations/2014/08/18/lamp_problems.html">On-orbit challenges, broken LMM lamp</a></li>
    
      <li><span>03 Aug 2014</span>: <a href="/informatics/2014/08/03/markdown_latex_pdf.html">Converting the website to documents</a></li>
    
      <li><span>02 Aug 2014</span>: <a href="/informatics/2014/08/02/markdown_html.html">Building a website from a few dozen lines of code</a></li>
    
      <li><span>01 Aug 2014</span>: <a href="/informatics/2014/08/01/linux_latex.html">Collaborative writing with Linux, LaTeX, Eclipse and git</a></li>
    
      <li><span>27 Jul 2014</span>: <a href="/science/operations/2014/07/27/preparing_data.html">First look at some raw data, preliminary stabilization</a></li>
    
      <li><span>15 Jul 2014</span>: <a href="/operations/science/2014/07/15/whereis_data.html">Why is it taking so long to post data? Data organization</a></li>
    
      <li><span>14 Jul 2014</span>: <a href="/science/operations/2014/07/14/ace_m2_run4_inital.html">ACE-M2 run 4, first phase-separation images</a></li>
    
      <li><span>02 Jul 2014</span>: <a href="/science/operations/2014/07/02/ace_m2_first_round_success.html">ACE-M2 runs 1 and 2 success summary</a></li>
    
      <li><span>01 Jul 2014</span>: <a href="/operations/2014/07/01/ace_m2_ops.html">ACE-M2 first-run flight operations</a></li>
    
      <li><span>17 Jun 2014</span>: <a href="/science/operations/2014/06/17/ace_m3_samples.html">ACE M3 samples for quantitative microscopy</a></li>
    
      <li><span>04 Jun 2014</span>: <a href="/operations/science/2014/06/04/ace_first_data.html">First images of ACE-M2 samples</a></li>
    
      <li><span>04 Jun 2014</span>: <a href="/operations/2014/06/04/ace_first_ops.html">ACE-M2 starting operations</a></li>
    
      <li><span>29 May 2014</span>: <a href="/policy/2014/05/29/onion.html">Life imitates The Onion</a></li>
    
      <li><span>18 Apr 2014</span>: <a href="/operations/2014/04/18/spacex3_launch.html">ACE-M2 launched into space</a></li>
    
      <li><span>06 Mar 2014</span>: <a href="/science/operations/2014/03/06/ace_m2_sample_layout.html">ACE-M2 sample layout</a></li>
    
      <li><span>05 Mar 2014</span>: <a href="/science/2014/03/05/ace_m2_samples.html">Samples for the second ACE experiment, ACE-M2</a></li>
    
      <li><span>17 Jan 2014</span>: <a href="/policy/2014/01/17/nasa_govt_comm.html">NASA, government's role, and communicating science differently</a></li>
    
      <li><span>01 Jan 2014</span>: <a href="/policy/informatics/2014/01/01/start.html">Telling the story of science on the Space Station</a></li>
    
  </ul>
</article> 

<footer class="footer">
<div class="container">
  <div><p>This work by <a href="http://www.peterlu.org/" target="_blank">Peter J. Lu</a> is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 Intl License &nbsp;/&nbsp; <a href="http://jessicaoverbey.com/" target="_blank">Site Design</a><p></div>
</div>
</footer>

<script type="text/javascript">

   $(window).load(function(){
    var $container = $('.portfolioContainer');
    $container.isotope({
        filter: '*',
        animationOptions: {
            duration: 750,
            easing: 'linear',
            queue: false
        }

    });
 
    $('.sort a').click(function(){
        $('.sort .current').removeClass('current');
        $(this).addClass('current');
 
        var selector = $(this).attr('data-filter');
        $container.isotope({
            filter: selector,
            animationOptions: {
                duration: 750,
                easing: 'linear',
                queue: false
            }
         });
         return false;
    }); 
});

</script>


The yaml header describes which layout to use, in this case a master layout that has the core html for each page on the site. This allows consistent formatting of pages throughout the site, using the concept of templates (specifically, Liquid Templates) for this purpose.

<!DOCTYPE html>
<html>
  <head>
    <title>Peter J. Lu - Building a website from a few dozen lines of code </title>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" charset="utf-8"/>
  </head>

  <body>
      <div id='content'>
        
      </div>
  </body>
</html>

This specifies that each page uses html5, and gives the fonts and location of the CSS stylesheet, which is very simple, standard CSS for the site in its present form. The header and footer are stored as separate files in the _includes directory.

The header includes the banner and its link:

<header>
  <a href="http://www.peterlu.org">
    <img src="/images/peterlu_org_banner.png" />
  </a>
</header>

The footer includes the Creative Commons license:

<footer>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png" /></a><br />This work by <a xmlns:cc="http://creativecommons.org/ns#" href="http://www.colloids.org" property="cc:attributionName" rel="cc:attributionURL">Peter J. Lu</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.
</footer>

The code has a number of double braces, which allow some amount of control in programming, to insert various bits of small data from the original source files.

Post files

Each markdown post has a yaml header that specifies using the post template:

---
layout: master
---
<div class="header">
  <div class="container">
    <a class="pull-left logo col-sm-6" href="https://colloids.github.io">
      <p>Colloid Physics in Space</p>
    </a>
    <p class="pull-right tagline col-sm-6 hidden-xs">updates from ACE aboard ISS by <a href="http://www.peterlu.org/" target="_blank">Peter J Lu</a></p>
  </div> <!-- /.container -->
</div> <!-- /.header -->

<div class="ticker">
<div class="container">
  <div id="carousel-home" class="carousel slide" data-ride="carousel">
          <div class="row">
            <div class="col-sm-1 hidden-xs">
                <a class="right carousel-control" href="#carousel-home" role="button" data-slide="prev">
                <span class="glyphicon glyphicon-chevron-left"></span>
              </a>
            </div>
              <div class="col-sm-10 headline">
                  <div class="carousel-inner">
                    
                      <div class="item active">
                          <div class="carousel-content">
                              <div>
                                  <a href="/policy/2014/09/09/stop_work.html"><p>During operations, NASA eliminates our funding for the rest of the year</p></a>
                              </div>
                          </div>
                      </div>
                    
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/09/05/slow_phase_sep.html"><p>Significant science, slower phase separation in ACE than in BCAT-KP</p></a>
                              </div>
                          </div>
                      </div>
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/08/26/same_sample.html"><p>Same sample, different behavior?</p></a>
                              </div>
                          </div>
                      </div>
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/08/22/gelation_phase_sep.html"><p>Significant science, gelation and phase separation</p></a>
                              </div>
                          </div>
                      </div>
                    
                      <div class="item">
                          <div class="carousel-content">
                              <div>
                                  <a href="/science/operations/2014/08/21/stabilize_images.html"><p>Image stabilization and filtering</p></a>
                              </div>
                          </div>
                      </div>
                    
                  </div> <!-- .carousel-inner -->
              </div> <!-- .col-sm-10 -->
              <div class="col-sm-1 hidden-xs">
                <a class="left carousel-control" href="#carousel-home" role="button" data-slide="next" style="margin-right:15px;">
                  <span class="glyphicon glyphicon-chevron-right"></span>
                </a>
              </div>
        </div> <!-- .row-->
    </div> <!-- .carousel-->
</div> <!-- .container-->
</div> <!-- .ticker-->


<article>

</article>

<footer class="footer">
<div class="container">
  <div><p>This work by <a href="http://www.peterlu.org/" target="_blank">Peter J. Lu</a> is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 Intl License &nbsp;/&nbsp; <a href="http://jessicaoverbey.com/" target="_blank">Site Design</a><p></div>
</div>
</footer>

<script type="text/javascript">

   $(window).load(function(){
    var $container = $('.portfolioContainer');
    $container.isotope({
        filter: '*',
        animationOptions: {
            duration: 750,
            easing: 'linear',
            queue: false
        }

    });
 
    $('.sort a').click(function(){
        $('.sort .current').removeClass('current');
        $(this).addClass('current');
 
        var selector = $(this).attr('data-filter');
        $container.isotope({
            filter: selector,
            animationOptions: {
                duration: 750,
                easing: 'linear',
                queue: false
            }
         });
         return false;
    }); 
});

</script>


Once again, the same headers and footers are used, with the main body specified by the word content inside the double braces. The magic of Jekyll as a static site generator is that it knows to put the contents of the converted markdown there, and preserve all of the rest of the formatting consistently for all pages.

Publishing the website

The beautiful thing about this form us static site generator usage is that once the configuration files are set just once, they don’t really have to be changed. All of the time spent is therefore focused on content generation, and testing.

Running Jekyll locally to test the site

As this website is hosted on http://www.github.com/peterlu/peterlu.github.io, it’s easily cloned into a new repository:

git clone git@github.com:peterlu/peterlu.github.io.git

Installing Jekyll locally (assuming the system is in the state at the end of the previous post on Linux and Latex is relatively straightforward:

sudo apt-get install ruby ruby-dev nodejs
sudo gem install bundle

In the main directory, that contains the ‘Gemfile’:

bundle install
bundle update

Then to build the website, and serve it using the built-in webserver:

bundle exec jekyll serve

If this is the only website on the machine being worked on, or all of the settings of all of the websites are the same, the simpler command will suffice:

jekyll serve

Git repository on Github

Once the pages are working fine locally, they need to be pushed to the repository on http://www.github.com. Since we are not managing this in Eclipse, though in principle that would work and might have some advantages, it’s easy as before to do this from the command line.

  1. Stage any modified files that have changed:
git add -A
  1. Verify the files are the correct ones that have been modified:
git status

Sometimes extra temporary files get added, that are not supposed to be committed to the repository, and the status check will show these.

  1. Commit the change
git commit -m 'description of the commit'
  1. Finally, push the commits to the remote repository (which usually will prompt you for a password):
git push

This causes the hosted webpage to re-run Jekyll, and regenerate the entire website. When next loading the page, it should be updated with the latest committed changes.