### Overview When writing many HTML pages for the same site, you may find yourself repeating blocks of code. For example, the code below shows an excerpt of the code used to generate the Overview section of this page. </p> <pre><code class="html">&ltdiv class="row"&gt &ltdiv class="col-md-3"&gt &lth3&gt Overview &lt/h3&gt &lt/div&gt &ltdiv class="col-md-9"&gt &lth3&gt Overview &lt/h3&gt &ltp&gt When writing many HTML pages for the same site, you may find yourself repeating blocks of code. For example, the code below shows an excerpt of the code used to generate the Overview section of this page. &lt/p&gt ... &lt/div&gt &lt/div&gt </code></pre> <p>You'll see that there are some similar, repretitive elements and structures here that we might reuse across pages or within an individual page. For example, the section title and header in the main part of the page are the same, and for every section on the page we use this exact same layout with an outer <code>div</code> tag with class <code>row</code> and inner <code>div</code> tags with classes <code>col-md-3</code> and <code>col-md-9</code> for the side bar and content respectively. </p> <p>We have to repeat this boilerplate code for any new section, and if we want to change how the sections are laid out across our website, we might have to change this bit of HTML in tens or hundreds of places. A very common example of this is a site header or footer, which is the same across every page of a site.</p> <h5> Layout vs. Content </h5> <p>Static site generators are tools that eliminate some of this redundancy by generating the HTML (and sometimes CSS) files for a site. Instead of writing raw HTML files for your webpages, you define the <b>layout</b> and <b>content</b> of your website separately. Layouts are often partial HTML files called templates that define recurring HTML structures in your code. In a generic static site generator, an example template for the section code above might look something like the following:</p> <pre><code class="html">&ltdiv class="row"&gt &ltdiv class="col-md-3"&gt &lth3&gt {{ title }} &lt/h3&gt &lt/div&gt &ltdiv class="col-md-9"&gt &lth3&gt {{ header }} &lt/h3&gt {{ body }} &lt/div&gt &lt/div&gt </code></pre> <p>which would be stored in a file like <code>section.html</code>. Note that the structure that could become redundant (all of the divs) is isolated to one file that we can change in one place. The bracketed code, like <code>{{ title }}</code>, values are placeholders that change between the different sections in our site, and are defined in content files instead of layout files. </p> <p> Content for static site generators is often defined in a markdown file or similar format. The advantage of separating content from layout is that you can later easily change the layout of your site without changing the content. And when creating new content can simply write the content, instead of worrying about formatting and HTML. An example for the above might be something like: </p> <pre><code class="markdown">------ title: 'Overview' header: 'Overview' ------ When writing many HTML pages for the same site, you may find yourself repeating blocks of code. For example, the code below shows an excerpt of the code used to generate the Overview section of this page. ... </code></pre> <p>We can still change all of the content of the page, so we maintain flexibility, but don't have to repeat the HTML needed to define sections everywhere. </p> <p> There are clear benefits to this approach, but also some drawbacks compared to using raw HTML, a few upsides and downsides are listed below. </p> <b> Pros </b> <ul> <li>Layout files allow you to change the way something looks across many parts of your site in a single file.</li> <li>Content files allow you to write new content for your site without touching HTML at all.</li> <li>Minimal setup to get a nice looking site, often frameworks provide plenty of premade themes.</li> </ul> <b> Cons </b> <ul> <li>Requires knowledge of an additional language like markdown and framework specific details, in addition to an understanding of HTML and CSS.</li> <li>Need to learn a specific framework, which is not as widely as applicable as HTML.</li> <li>Lose control over individual pages (if you want to tweak a single page and keep everything else constant).</li> <li>Markdown restricts content to a subset of HTML, making it difficult to include certain tags.</li> </ul> </div> </div> <!-- END SECTION --> <!-- NEW SECTION --> <div class="row"> <!-- TITLE --> <div class="col-md-3"> <h3> Solutions </h3> </div> <!-- CONTENT --> <div class="col-md-9"> <h3> Static Site Generators </h3> <p>Here we cover a few common static site generators and similar solutions. We'll first go over how jquery can be used as a lightweight solution for things like headers and footers that ought to be the same across all parts of your site. Then we'll dive into two of the most popular true static site generators, Hugo and Jekyll.</p> <!-- <h5> JQuery + Basic Javascript Approach </h5> <p><a href="https://jquery.com/">jQuery</a> is a Javascript library that is very commonly used alongside HTML and CSS to make webpages interactive. It can respond to clicks from users, and do a whole bunch of other things. We can also use it as a pseudo static site generator by manipulating our HTML when our page loads. This approach requires minimal knowledge of <a href="https://www.javascript.com/">javascript</a>, which is the most common language for programming websites. We can use javascript in our webpages by using a <a href="https://www.w3schools.com/Tags/tag_script.asp">script</a> tag in the header of our html page. To use jQuery on our website, we can include the library with the script tag below:</p> <pre><code class="html">&ltscript src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"&gt&lt/script&gt</code></pre> <p>Put this line inside the <code>head</code> tag in your webpage's html code. This will load the javascript library at the url in the <code>src</code> attribute, which contains the source code for jQuery. Adding this line gives us access to all of the nice feature of the jQuery library in the rest of our javascript code. </p> <p> After the above line, we can insert another script tag that actually uses jQuery. The code is as follows:</p> <pre><code class="html">&ltscript&gt $(document).ready(function(){ $("#header").load("header.html"); }); &lt/script&gt </code></pre> <p> There are a few things happening here. First note the script tag that tells the file we are including javascript code in our html file. Inside the script tag we have javascript code that includes several uses of the jQuery selector <code>$()</code>. This code can be used to select various objects, including HTML elements on a page. First it is used on <code>$(document)</code>, which is corresponds to the entire page page. We can't run jQuery code safely until the entire page is ready, so we put the code we want to run inside of <code>$(document).ready()</code>, which you can learn more about <a href="https://learn.jquery.com/using-jquery-core/document-ready/">here</a>. </p> <p> The code we run when the document ready again uses the jQuery selector, this time to select HTML elements on the page. There are various types of selectors we can use with jQuery to select elements. Common ones include selecting elements by <ul> <li><a href="https://api.jquery.com/element-selector/">Tag Name</a>, e.g. <code>$("div")</code> to select all div elements</li> <li><a href="https://api.jquery.com/class-selector/">Class name</a>, e.g. <code>$(".section")</code> to select all elements with class="section"</li> <li><a href="https://api.jquery.com/id-selector/">Id</a>, e.g. <code>$("#header")</code> to select all elements with id="header"</li> </ul> There are plenty of other types of selectors as well, documented <a href="https://api.jquery.com/category/selectors/">here.</a> </p> <p> In the code above, on page load, we run the line </p> <code class="javascript">$("#header").load("header.html");</code> <p> which will load the HTML code from the file <code>header.html</code> into any element with any id of "header" in the main pages HTML code. So if we add a line </p> <code class="html">&ltdiv id="header"&gt&lt/div&gt</code> <p> in the body of each of your pages we end up being able to change the header on all pages by changing just the single header.html file. This gets us some of the benefits of a static site generator with low overhead. Unfortunately, this approach gets more complicated if you want to do something like the section example above where you want to use templating and change things like the section title for each section. If you are only looking to do something like headers or footers, this is a fine and straightforward solution, and does a good job of illustrating the ideas and advantages of static site generators. </p> --> <h5> Hugo </h5> <p> This guide presupposes some familiarity with the command line. Hugo is a static site generator that utilizes markdown for content and templated html for layout. To get started, first install Hugo (<a href="https://gohugo.io/getting-started/installing#windows">Windows</a>, <a href="https://gohugo.io/getting-started/installing#macos">MacOS</a>, <a href="https://gohugo.io/getting-started/installing#linux">Linux</a>). In your command line you can confirm that hugo is installed by running </p> <pre><code class="bash">hugo version</code></pre> <p> Once installed, use your command line to change directories to the place where you would like to create your site, if the name of your project is <code>my_first_project</code>, run </p> <pre><code class="bash">hugo new site my_first_project</code></pre> <p> This will create a new directory called my_first_project to contain your site. If you plan to use this for your course site, you should initialize this folder as your <a href="./github.html">course git repository</a>. </p> <p> To generate the HTML for your site from layout and content files, you can run <code>hugo server -D</code> from your project directory. You can then view your site, with live changes as you modify files, at <a href="http://localhost:1313/">http://localhost:1313/</a>. Unfortunately, Hugo doesn't come with any theme or content preinstalled, so you will just see a blank page at this point. </p> <p> Hugo comes with a community of developers who have made themes as starting points. You can <a href="https://gohugo.io/hugo-modules/theme-components/">create your own theme</a> if you're feeling particularly adventurous. Note that this documentation is not particularly good. Otherwise, you can use one of the many existing <a href="https://themes.gohugo.io/">themes</a> on Hugo's website. These themes are usually linked to github repositories that you can clone or download as a zip. If you put that repository into the <code>themes/</code> subfolder of your project folder, you will be able to use that theme. If you add the theme in the subfolder <code>my_first_project/themes/my_theme</code> then you can use your theme by adding it in the configuration file for your site. To do this open the file <code>my_first_project/config.toml</code> in your text editor and add the line <code>theme = "my_theme"</code> </p> <p> Each theme has documentation on its home page of what types of content + layouts it comes with built in, and depending on the theme you choose, you should read through their documentation to understand how to use the theme. Usually these themes allow for further customization through the <code>config.toml</code> file. </p> <p> That's the basics of getting Hugo up and running. More resources on the directory structure generated for a project and how to add new content or layouts can be found on the <a href="https://gohugo.io/getting-started/directory-structure/#directory-structure-explained">Hugo Website</a>. </p> <p> This <a href="https://gohugo.io/hosting-and-deployment/hosting-on-github/#put-it-into-a-script-1">script</a> might be helpful if you'd like to make pushing your site to github easier. If you put this script in you project directory, and follow the directions on the linked page, then you only need to run the linked script with <code>sh publish_to_ghpages.sh</code> to deploy your site. </p> <h5> Jekyll </h5> <p> This guide presupposes some familiarity with the command line. Jekyll is a static site generator that utilizes markdown for content and templated html for layout, and uses the Ruby language to actually generate the HTML of the static site. To get started, first follow the <a href="https://jekyllrb.com/docs/installation/#requirements">installation</a> guide for your system. </p> <p> Jekyll provides a working site out of the box, without having to install themes or add your own layouts/content like Hugo. To create a project run: </p> <pre><code>jekyll new my_first_project</code></pre> <p> To build and view the site, run the following in your project directory: </p> <pre><code>bundle exec jekyll serve --livereload</code></pre> <p> and then open the url <a href="http://localhost:4000">http://localhost:4000</a>. Adding the <code>--livereload</code> flag above makes the webpage automatically refresh whenever you change one of the source files. </p> <p> You can add new posts by adding files in the <code>_posts</code> directory, following the example post there. </p> <p> If you choose to make your site with Jekyll, you should experiment with different layouts besides the default. Given how much of the boilerplate is created for you through just the lines in the tutorial, we expect a greater level of exploration. You can modify <a href="https://jekyllrb.com/docs/themes/">themes</a> or add <a href="https://jekyllrb.com/docs/layouts/">layouts</a>. The Jekyll documentation is very robust and is a good guide for exploration. </p> <p> Finally, the Jekyll guide on deploying to <a href="https://jekyllrb.com/docs/github-pages/">Github pages</a> could be helpful if you plan to use this as your course site. </p>