- Markdown Based Static Site Generator
- Markdown To Static Site Online
- Markdown Static Site Generator
- Pdf To Markdown
- Markdown To Static Site Examples
- Markdown To Static Site Download
- Markdown Web
The Static Site Generator that does only one thing: compile your html and markdown. Static blog generator with simplistic configuration that aims for being dead simple. Gerablog is a simple and small static blog generator. GrazeDocs is a static site generator for creating documentation for your projects. Running an Azure Storage Static Site, protected by Azure Front Door. Although Hugo supports both HTML and MarkDown, I decided to go for MarkDown; if this is unknown to you, think of it is a web page markup language, with a specific syntax. While it might feel difficult in the beginning, it is actually rather straight forward to use once you.
Pandoc describes itself as the swiss-army knife of file/markup conversion. It’ll happily convert your Markdown files to HTML, PDF, TeX or whatever else is supported. It’s list of supported file formats is truly impressive. It’s Haskell based and packaged for most popular Linux distributions. The Arch Linux installation with all it’s dependencies weighs in at over 400MB. Personally I think it’s worth it.
What put the tool on my this video showing how to turn Markdown into PDF slides by Luke Smith. Check it out to get a taste of how easy it is to use this tool and catch a glimpse of it’s potential.
Pandoc as a website generator
Being able to create HTML files from a number of other markup sources not much is needed to create a very simple website generator. You’re reading a Pandoc generated web page at this very moment.
Markdown Based Static Site Generator
The most basic conversion looks like this:
The output isn’t just some basic HTML but also contains code highlighting tags. This isn’t always trivial to achieve.
A more advanced command would be:
As you can see Pandoc allows the use of Templates using the --template
argument. The pandoc-templates on Github contains the default templates for reference. Changing a template is easy. Variables can be added or removed at will. Values for variables are then pulled either from the --variable
argument(s) or the metadata stored in the files or a specific metadata file (see --metadata-file
).
The two variables in this example just contains the markdown file’s dates of it’s last modification and it’s creation.
Automating the process
The above example works fine for a single file. Managing an entire website requires some automation however. For this task I created two scripts. build.sh
finds all source markup files and process_md_file.sh
to process each file.
build.sh
:
The find
command just finds all Markdown files in my Site path and runs the next script for each result.
process_md_file.sh
:
All the work is done by pandoc
. Everything else is just to prepare the data for the arguments.
The site structure itself looks like this:
This directory tree is ready for deployment on any old HTTP server without modifications.
Improvements
Markdown To Static Site Online
The examples above are in practical use to create this very website. They work in the real. But of course there’s plenty of room for improvement. One thing I don’t take into account at all is navigation. This is a very simple site. The Homepage is the central hub, end of navigation. For a more complex site this doesn’t work. Nor is there some sort of template selection for different needs. Not even a simple Blog listing.
Yet none of these issues are a problem to solve.
What a I like about Pandoc compared to full featured site generators is it’s bashiness. No gems, no Python packages, no npm orgies, etc. Install the package and you’re good to go. On top of that, the logic is up to you. I wanted something dead simple and Pandoc delivered in almost no time. And all lessons learned can easily be applied to more every day Pandoc scenarios.
Why make static websites?
Static websites are so 1999. $insertYourFavoriteCSSHere with all it’s dynamicness is sooo much better. Why would anyone bother with static HTML? You still use Dreamweaver? Golive?
Yes, CMS have their place and are useufl. Larger websites managed by multiple people clearly benefit from those solutions. I used to be a die hard Typo3 user using it for absolutly everything.
But let me give you a few reasons I prefer to avoid them:
- They require a stack to run. No PHP, no database, no Wordpress. (just one example)
- Without your stack you can’t see your website. This makes archiving it hard.
- Code and content are separate. An advantage for large websites, small sites (like mine) would benefit from keeping the content directly in the git repository.
- CMS and their stacks are subject to security issues and require constant patching. Usually when you’re on holiday or in the middle of some important project.
- Performance may not be stellar.
For small sites the static approach makes sense. Interactive elements can be added through APIs and JavaScript. Think of comments or contact forms. There’s no reason to keep everything dynamic just for a few such features.
As always it’s about the right tool for the job. Yet instead of blindly dismissing the option of static HTML as 1999 I encourage you to take a look, Pandoc or otherwise.
If you’re looking for themes for your Jekyll site, you don’t have to restrict yourself to existing Jekyll themes. It’s pretty easy to convert almost any static HTML files into a Jekyll website.
In many ways, any site that is currently a static site is already a Jekyll website. Jekyll just allows you to automate parts of the site (like inserting pages into templates, rendering lists for navigation, generating feeds and sitemaps, and more) as it processes the files.
Understanding how to convert any HTML site into Jekyll templates will open your world to many more options for Jekyll themes. Instead of searching online for Jekyll themes, you can choose from the large variety of HTML templates for your site, quickly Jekyll-ize the HTML templates as you need to, and build the output with Jekyll.
Although websites can have sophisticated features and controls, we’ll keep things simple in this tutorial.
What is a Jekyll Website?
First, let’s start with a grounding in the basics. Stripping a Jekyll site down to an extremely basic level will help clarify what happens in a Jekyll site. If you haven’t already installed the jekyll gem, install it.
We’ll start with a basic Jekyll site consisting of three files:
Manually create these three files in a folder called my_jekyll_site
or whatever suits you the most, and place default.html
inside a folder named _layouts
.
Fire up your favorite editor, and populate the contents of the default.html
and index.md
files as follows:
_config.yml
_layouts/default.html
index.md
Now cd
to my_jekyll_site
and serve the site with the built-in server:
If you have a Gemfile, use Bundler by typing bundle exec jekyll serve
instead.
When you serve the site, you get a preview URL such as http://127.0.0.1:4000/
(which is the same as http://localhost:4000/
). The site’s files are built into the _site
folder by default.
This is a Jekyll site at the most basic functional level. Here’s what is happening:
- The
_config.yml
file contains settings that Jekyll uses as it processes your site. An empty config file will use default values for building a Jekyll site. For example, to convert Markdown to HTML, Jekyll will automatically use the kramdown Markdown filter, without any need to specify it. - Jekyll looks for files with front matter tags (the two sets of dashed lines
---
like those inindex.md
) and processes the files (populating site variables, rendering any Liquid, and converting Markdown to HTML). - Jekyll pushes the content from all pages and posts into the
{{ content }}
variable in the layout specified (default
) in the front matter tags. - The processed files get written as
.html
files in the_site
directory.
You can read more about how Jekyll processes the files in order of Interpretation.
With this basic understanding of how a Jekyll site works, you can convert almost any HTML theme for Jekyll. The following sections will take you through a step-by-step tutorial to do so.
1. Create a template for your default layout
Find your HTML theme and save it as a default
layout. If you’re converting or cloning an existing site, you can right-click the page and view the source code.
For example, suppose you’re cloning your company site to create a documentation site with the same branding. Or suppose you have a personal site that you built with HTML and now want to make it a Jekyll site. Get the HTML source code for your site.
Regardless of the site, do check the license and make sure you have permission to copy and use the code.
Copy and paste the source code into a file called default.html
. Put the default.html
file inside the _layouts
folder. This will be the default layout template for your pages and posts — that is, each page or post will use this layout when Jekyll builds the site.
Note that in looking for templates, you want the HTML output of the template. If the template has PHP tags or other dynamic scripts, these dynamic elements will need to be converted to HTML or to Liquid. Liquid is Jekyll templating system to retrieve dynamic content.
Open default.html
into your browser locally to ensure the site looks and behaves like it does online. You will likely need to adjust CSS, JS, and image paths so they work.
For example, if the paths were relative on the site you copied, you’ll need to either download the same assets into your Jekyll site or use absolute paths to the same assets in the cloud. (Syntax such as src='//
requires a prefix such as src='http://
to work in your local browser.)
Jekyll provides some filters to prepend a site URL before path. For example, you could preface your stylesheet like this:
The relative_url
filter will prepend the baseurl
value from your config file (as blog
for instance) to the input. This is useful if your site is hosted at a subpath rather than at the root of the domain (for example, http://mysite.com/blog/
).
You can also use an absolute_url
filter. This filter will prepend the url
andbaseurl
value to the input:
Again, both url
and baseurl
can be defined in your site’s config file, like this:
The result in the output will be http://mysite.com/blog/assets/style.css
.
Note that the url
property of any page begins with a forward slash (/
), so omit this at the end of your url
or baseurl
property.
Markdown Static Site Generator
You don’t have to prepend filters to link paths like this. You could also use relative links across your entire site. However you decide to code the paths to your assets, make sure they render correctly.
Does your local default.html
page look good in your browser? Are all images, styles, and other elements showing up correctly? If so, great. Keep going. You can use this template as the layout for all your pages and posts or create as many templates as you need.
In the next section, you’ll blank out the content of the layout and replace it with placeholder tags that get populated dynamically with your Jekyll pages.
2. Identify the content part of the layout
In default.html
, find where the page content begins (usually at h1
or h2
tags). Replace the title that appears inside these tags with {{ page.title }}
.
Remove the content part (keep everything else: navigation menu, sidebar, footer, etc.) and replace it with {{ content }}
.
Check the layout again in your browser and make sure you didn’t corrupt or alter it up by inadvertently removing a crucial div
tag or other element. The only change should be to the title and page content, which are now blanked out or showing the placeholder tag.
3. Create a couple of files with front matter tags
Create a couple of files (index.md
and about.md
) in your root directory.
In your index.md
file, add some front matter tags containing a title
and layout
property, like this:
Create another page for testing called about.md
with similar front matter tags.
If you don’t specify a layout in your pages, Jekyll will simply render that page as an unstyled basic HTML page.
4. Add a configuration file
Add a _config.yml
file in your root directory. In _config.yml
, you can optionally specify the markdown filter you want. By default, kramdown is used (without the need to specify it). If no other filter is specified, your config file will automatically apply the following as a default setting:
You can also specify some options for kramdown to make it behave more like GitHub Flavored Markdown (GFM):
5. Test your pages
Now run jekyll serve
and toggle between your index.html
and about.html
pages. The default layout should load for both pages.
You’ve now extracted your content out into separate files and defined a common layout for pages.
You could define any number of layouts you want for pages. Then just identify the layout you want that particular page to use. For example:
This page would then use the homepage.html
template in the _layouts
folder.
You can even set default front matter tags for pages, posts, or collections in your _config.yml
file so that you don’t have to specify the layout in the front matter variables. Anyways, setting defaults is beyond the scope of this tutorial, let’s get back to work.
6. Configure site variables
You already configured the page title using {{ page.title }}
tags. But there are more title
tags to populate. Pages also have a title
tag that appears in the browser tab or window. Typically you put the page title followed by the site title here.
In your default.html
layout, look for the title
tags below your head
tags:
Insert the following site variables:
Open _config.yml
and add a title
property for your site’s name.
Any properties you add in your _config.yml
file are accessible through the site
namespace. Similarly, any properties in your page’s front matter are accessible through the page
namespace. Use dot notation after site
or page
to access the value.
Stop your Jekyll server with Ctrl + C and restart it. Verify that the title
tags are populating correctly.
Every time you modify your config file, you have to restart Jekyll for the changes to take effect. When you modify other files, Jekyll automatically picks up the changes when it rebuilds.
If you have other variables to populate in your site, rinse and repeat.
7. Show posts on a page
It’s common to show a list of posts on the homepage. First, let’s create some posts so that we have something to showcase.
Add some posts in a _posts
folder following the standard YYYY-MM-DD-title.md
post format:
2017-01-02-my-first-post.md
2017-01-15-my-second-post.md
2017-02-08-my-third-post.md
In each post, add some basic content:
Now let’s create a layout that will display the posts. Create a new file in _layouts
called home.html
and add the following logic:
Create a file called blog.md
in your root directory and specify the home
layout:
In this case, contents of blog.md
will be pushed into the {{ content }}
tag in the home
layout. Then the home
layout will be pushed into the {{ content }}
tag of the default
layout.
How layouts work
When a layout specifies another layout, it means the content of the first layout will be stuffed into the {{ content }}
tag of the second layout. As an analogy, think of Russian dolls that fit into each other. Each layout fits into another layout that it specifies.
The following diagram shows how layouts work in Jekyll:
In this example, the content from a Markdown document document.md
that specifies layout: docs
gets pushed into the {{ content }}
tag of the layout file docs.html
. Because the docs
layout itself specifies layout: page
, the content from docs.html
gets pushed into the {{ content }}
tag in the layout file page.html
. Finally because the page
layout specifies layout: default
, the content from page.html
gets pushed into the {{ content }}
tag of the layout file default.html
.
You don’t need multiple layouts. You could just use one: default
. You have options for how you design your site. In general, it’s common to define one layout for pages and another layout for posts, but for both of these layouts to inherit the default
template (which usually defines the top and bottom parts of the site).
In your browser, go to blog.html
and see the list of posts.Note that you don’t have to use the method described here. You could have simply added the for
loop to any page, such as index.md
, to display these posts. But given that you may have more complex logic for other features, it can be helpful to store your logic in templates separate from the page area where you frequently type your content.
At minimum, a layout should contain {{ content }}
, which acts as a receiver for the content Mac computer games for download. to be rendered.
For loops
By the way, let’s pause here to look at the for
loop logic a little more closely. For loops in Liquid are one of the most commonly used Liquid tags. For loops let you iterate through content in your Jekyll site and build out a result. The for
loop also has certain properties available (like first or last iteration) based on the loop’s position in the loop as well.
We’ve only scratched the surface of what you can do with for
loops in retrieving posts. For example, if you wanted to display posts from a specific category, you could do so by adding a categories
property to your post’s front matter and then look in those categories. Further, you could limit the number of results by adding a limit
property. Here’s an example:
This loop would get the latest three posts that have a category called podcasts
in the front matter.
8. Configure navigation
Now that you’ve configured posts, let’s configure page navigation. Most websites have some navigation either in the sidebar or header area.
In this tutorial, we’ll assume you’ve got a simple list of pages you want to generate. If you only have a handful of pages, you could list them by using a for
loop to iterate through the site.pages
object and then order them by a front matter property.
Identify the part of your code where the list of pages appears. Usually this is a <ul>
element with various child <li>
elements. Replace the code with the following:
This example assumes each page would have front matter containing both a title
and order
property like this:
Here the order
property will define how the pages get sorted, with 1
appearing first in the list.
You could also iterate through a list of pages that you maintain in a separate data file. This might be more appropriate if you have a lot of pages, or you have other properties about the pages you want to store.
To manage page links this way, create a folder in your Jekyll project called _data
. In this folder, create a file called e.g. navigation.yml
with this content:
If you never wrote any YAML before, you’ll get quickly familiar with it. Take a look at what you can do with YAML.
You can store additional properties for each item in this data file as desired. Arrange the list items in the order you want them to appear.
To print the list of pages from the data file, use code like this:
If you have more sophisticated requirements around navigation, such as when building a documentation site, see the detailed tutorial on navigation.
9. Simplify your site with includes
Let’s suppose your default.html
file is massive and hard to work with. You can break up your layout by putting some of the HTML code in include files.
Add a folder called _includes
in your root directory. In that folder, add a file there called sidebar.html
.
Pdf To Markdown
Remove your sidebar code from your default.html
layout and insert it into the sidebar.html
file.
Where the sidebar code previously existed in default.html
, pull in your “include” like this:
You can break up other elements of your theme like this, such as your header or footer. Then you can apply these common elements to other layout files. This way you won’t have duplicate code.
10. RSS feed
Your Jekyll site needs an RSS feed. Here’s the basic RSS feed syntax. To create an RSS file in Jekyll, create a file called feed.xml
in your root directory and add the following:
Make sure your _config.yml
file has properties for title
, url
, and description
.
This code uses a for
loop to look through your last 20 posts. The content from the posts gets escaped and truncated to the last 400 characters using Liquid filters.
In your default.html
layout, look for a reference to the RSS or Atom feed in your header, and replace it with a reference to the file you just created. For example:
You can also auto-generate your posts feed by adding a gem called jekyll-feed
. This gem will also work on GitHub Pages.
11. Add a sitemap
Finally, add a site map. Create a sitemap.xml
file in your root directory and add this code:
Again, we’re using a for
loop here to iterate through all posts and pages to add them to the sitemap.
You can also auto-generate your sitemap by adding a gem called jekyll-sitemap
. This gem will also work on GitHub Pages.
12. Add external services
For other services you might need (such as contact forms, search, comments, and more), look for third-party services. We listed some integrations on our resources page but in todays’s world of SaaS and APis the list is endless.
Your Jekyll pages consist of HTML, CSS, and JavaScript, so pretty much any code you need to embed will work without a problem.
As you integrate code for these services, note that if a page in your Jekyll site doesn’t have front matter tags, Jekyll won’t process any of the content in that page. The page will just be passed to the _site
folder when you build your site.
If you do want Jekyll to process some page content (for example, to populate a variable that you define in your site’s config file), just add front matter tags to the page. If you don’t want any layout applied to the page, specify layout: null
like this:
13. Conclusion
Although websites can implement more sophisticated features and functionality, we’ve covered the basics in this tutorial. You now have a fully functional Jekyll site.
Markdown To Static Site Examples
To deploy your site, consider using GitHub Pages, Netlify, Vercel, Render, Amazon AWS S3 using the s3_website plugin, or just FTP your files to your web server.
Markdown To Static Site Download
You can also package your layouts, includes and assets into a Ruby gem
and make it a Jekyll theme.
Markdown Web
Additional resources
Here are some additional tutorials on creating Jekyll sites: