A simple static site generator. Built as part of the extension section of Imperial Year 1 C Project.
This will get a copy of the project up and running on your local machine.
Tent depends on one library, cmark, which converts markdown-formatted text into html.
To install in the standard location (do this if you have root access):
cd
somewhere nice, maybe your home directory?git clone https://github.com/commonmark/cmark.git
cd
into the repo- type
make
- type
make install
You have now installed the library! If you'd like to install cmark somewhere else, for exmaple if you don't have root access, steps 1-3 are the same:
cd
somewhere nice, maybe just your home directory, or ac/
directory if you have onegit clone https://github.com/commonmark/cmark.git
cd
into the repo- type
make INSTALL_PREFIX=path/to/tent
- type
make install
You will need to set the LIBRARY_PATH environment variables so the linker will be able to find the libraries:
- type
export LD_LIBRARY_PATH=path/to/tent/lib:$LD_LIBRARY_PATH
- type
export LIBRARY_PATH=path/to/tent/lib:$LIBRARY_PATH
- Clone this repository to your computer
- type
cd arm11_11/tent
- type
make
The main program can now be found in arm11_11/tent/bin/tent
To install it to /usr/local/bin/
- type
make install
You have now installed tent and it is ready for use!
There are two tent commands:
tent create <site name>
tent build
This will create a new directory site_name/
with the following directory structure:
site_name
│ config.tent
│
└───content
│
└───theme
│
└───templates
│
└───pages
│
└───snippets
you can find a default theme directory in tent/examples/default
.
When creating a tent site, you will mainly be adding files to the content/
directory. When you tent build
your site, it will be copied to a directory public/
, which will contain all the files from your content/
directory, with all the necessary replacements made.
In your content/
directory, you can add files of any type you want. These will all be copied into your public/
directory when you build the site. Tent will only pay attention to markdown files (.md
) in your content/
directory.
A markdown file in your content/
directory, for example, on your website about condiments, content/mustard.md
should look something like this:
---
template: blog-post
title: What makes mustard so good?
date: 17/06/2020
recent-post-links: [ketchup.html, mayo.html, spices/cardamon.html]
recent-post-names: [Ketchup, Mayo, Cardamon]
---
Hi everyone! This is a subject very close to my heart!
Gordon Ramsay once said about mustard:
> It is probably one of the best condiments in the world
Here's a cool video demonstrating my thoughts:
{{ snippet.youtube-video url="https://www.youtube.com/watch?v=8ktONdU_wXU" width="560" height="315" }}
...
Here the top part of the markdown file (between the two ---
), forms the metadata associated with this page. template: blog-post
tells tent that this is a blog post, and so that it should go to theme/templates/blog-post.html
to find the correct template. The rest of the key: value
pairs in the metadata section are variables, which will subsequently be used by the templates. Variables can have string type, for example title
in the above example, or array type, for example recent-post-links
in the above example. Different templates will require different variables be set.
Suppose config.tent
looked something like this:
site-title: A site about condiments!
site-url: www.best-condiments.com
Here, theme/templates/blog-post.html
will look something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ config.site-title }} | {{ variable.title }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{ config.site-url }}/css/blog-post.css" rel="stylesheet">
</head>
<body>
{{ snippet.nav }}
{{ range variable.recent-post-links snippet.recent-posts }}
<h1>{{ variable.title }}</h1>
<p class="date">{{ variable.date }}</p>
{{ content }}
{{ snippet.footer }}
</body>
</html>
theme/snippets/youtube-video.html
will look something like this:
<iframe width="{{ args.width }}" height="{{ args.height }}" src="{{ args.url }}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
and theme/snippets/recent-posts.html
will look something like this:
<a class="recent-post" href="{{ variable.recent-post-links }}">{{ variable.recent-post-names }}</a>
Inserts:
Tent uses 'inserts' to populate templates (found in site_name/theme/templates/
) and snippets (found in site_name/theme/snippets
).
Inserts look like this: {{ insert_type.insert_name }}
Suppose the program was in the process of creating mustard.html
(from mustard.md
). This example will be used in the following.
There are a couple of insert types.
{{ variable.<var-name> }}
inserts:
These will be replaced with whatever value is associated with <var-name> in the metadata section of whatever markdown file is using the template or snippet. In our example, {{ variable.title }}
will be replaced with What makes mustard so good?
(due to the line in mustard.md
which says title: What makes mustard so good?
)
{{ config.<var-name> }}
inserts:
These will be replaced with whatever value is associated with <var-name> in the config.tent
file. So {{ config.site-title }}
will be replaced with A site about condiments!
{{ content }}
inserts:
Our program uses the library CMark to convert everything after the second ---
in your .md
file from markdown to html, and then replaces {{ content }}
with whatever comes from that conversion.
{{ range <list-variable> snippet.<snippet-name> }}
inserts:
Our program will iterate through each value in <list-variable>
(could be a config, or a metadata variable), and for each one, issue all the necessary replacements into <snippet-to-insert-into>
. The insert will then be replaced by the concatenation of all these replaced snippets
In the above example, {{ range variable.recent-post-links snippet.recent-posts }}
will be replaced with:
<a class="recent-post" href="ketchup.html">Ketchup</a>
<a class="recent-post" href="mayo.html">Mayo</a>
<a class="recent-post" href="spices/cardamon.html">Cardamon</a>
Arguments:
Any time you use an insert, you can supply it with arguments, in the form of immediate values (could be strings or arrays). These arguments can be either positional or named.
Named:
In the above example, the insert {{ snippet.youtube-video url="https://www.youtube.com/watch?v=8ktONdU_wXU" width="560" height="315" }}
makes use of named arguments. When issuing the replacements, in youtube-video.html
, {{ args.height }}
will be replaced with 560
, {{ args.height }}
will be replaced with 315
and {{ args.url }}
will be replaced with https://www.youtube.com/watch?v=8ktONdU_wXU
.
Positional:
These are very similar to named arguments, except that they are specified without the name=
which precedes the value, and they are referenced using numbers. If we were to re-write the video snipped using positional arguments, their definitions would look something like this: {{ snippet.youtube-video https://www.youtube.com/watch?v=8ktONdU_wXU 560 315 }}
, and they would be referenced like this:
<iframe width="{{ args.1 }}" height="{{ args.2 }}" src="{{ args.0 }}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Once you are happy with the state of your website directory, and you would like to build the website, and for tent to work its magic, cd path/to/<site_name>
into the directory tent created for you, and type tent build
This will create a new folder, tent/build/
, and will populate it with everything that was in your content/
directory, having issued all the replacements in the .md
files.
Alex Moraru Casey Williams Mihnea-Teodor Savin Jules Dehon