In a recent blog post Andrew Pruski (b|t) shared a presentation setup he put together using Github Pages and reveal.js. He had been using the soon-to-be defunct GitPitch for his presentations, and needed something new. In this post I'll share the setup I shared with Andrew that allows me to self-host my reveal presentations. I like what Andrew is using, but my own setup fits my needs and lets me host my presentations the same way I host my blog, so I thought I would share. With this setup all I have to do to create a new presentation is create a new .md file and optionally update an existing file.

Reveal.js

First off, if you haven't used Reveal.js before, you should check it out. Reveal allows you to write your presentations using Markdown (a simple to use, human-readable, mark-up language) and host them almost anywhere (even locally using a python one-liner).

Reveal supports a lot of great features like syntax highlighting and speaker notes. It makes writing presentations a breeze and makes you hate PowerPoint more than you already do.

The setup

Before we can get started you need two things:

I created a directory called /presentations in the root of my hosting directory. In that directory I have a js/ directory, an index.html file, and a file named null.md.

To get the latest copy of reveal.js, change into your presentations/js/ directory and run:

git clone https://github.com/hakimel/reveal.js.git

You only need the js,dist, and plugin directories in that repo, the rest can be deleted.

Index.html

Now that you have reveal.js installed, you need an index.html file to server the presentations. Here is mine:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>reveal.js</title>

    <link rel="stylesheet" href="js/reveal.js/dist/reset.css">
    <link rel="stylesheet" href="js/reveal.js/dist/reveal.css">
    <link rel="stylesheet" href="js/reveal.js/dist/theme/black.css" id="theme">

    <!-- Theme used for syntax highlighted code -->
    <link rel="stylesheet" href="js/reveal.js/plugin/highlight/monokai.css" id="highlight-theme">
</head>
<body>
    <div class="reveal">
        <div class="slides">
            <section    name="md_content"
                        data-markdown="slides.md"
                        data-separator="^---$"
                        data-separator-vertical="^------$"
                        data-separator-notes="^Note:"
                        data-charset="iso-8859-15">
            ></section>
        </div>
    </div>

    <script src="js/reveal.js/dist/reveal.js"></script>
    <script src="js/reveal.js/plugin/notes/notes.js"></script>
    <script src="js/reveal.js/plugin/markdown/markdown.js"></script>
    <script src="js/reveal.js/plugin/highlight/highlight.js"></script>
    <script>
        var md = document.getElementsByName('md_content')[0]
        var params = new URLSearchParams(window.location.search)
        md.dataset.markdown = "/presentations/" + params.get('p') + ".md"
        // More info about initialization & config:
        // - https://revealjs.com/initialization/
        // - https://revealjs.com/config/
        Reveal.initialize({
            hash: true,

            // Learn about plugins: https://revealjs.com/plugins/
            plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
        });
    </script>
</body>
</html>

Nothing really special is happening here. It imports all the various reveal libraries, a style sheet for syntax highlighting, and one for the presentations as a whole. We then do a little setup for reveal, and finally we do the magic part:

var md = document.getElementsByName('md_content')[0]
var params = new URLSearchParams(window.location.search)
md.dataset.markdown = "/presentations/" + params.get('p') + ".md"

The first line of code gets finds md_content element (this is where the presentation content will go). Next it grabs the value of the p URL parameter, and finally we use that value to pull information from a markdown file and render the presentation.

As an example, if I browsed to https://markw.dev/presentations/?p=hello, the code would see the ?p=hello in the URL and then find the hello.md in the presentations directory. It would then parse the markdown in that file and render the presentation. This is cool because you can just load that directory up with .md files and change the URL parameter to switch between presentations!

null.md

What about null.md though, I mentioned it earlier, but what is it for? If the p URL parameter is missing, the js code above will return null, so if I create null.md file, it will be displayed when a parameter isn't entered. I took advantage of this behavior and created links to my various presentations in that file:

### Please choose a presentation:

* [Monitoring and Alerting](/presentations/?p=alerting)
* [SQL Server CPU Scheduling](/presentations/?p=cpu)
* [Untangling Dynamic SQL](/presentations/?p=dynamic)

So, if you just browse to https://markw.dev/presentations/ without specifying p, it will show you a list of my available presentations. This is an option step of course, you could just just as easily create a file with a help message and not bother maintaining a list of your presentations:

# No presentation selected!

Use the `?p=` url parameter to choose a presentation

Thoughts

I will admit that my way is a little more complicated to get up and running, but I like being able to just drop a new .md file in that directory and I am ready to go. Local testing is dead simple as well. All I have to do is change to the presnetations/ directory locally and use a python one-liner to serve it on a local web server:

python3 -m http.server 8080

That serves the current directory on http://localhost:8080 and lets me quickly test changes before uploading it. Reveal is super flexible and results in a great looking presentation that is extremely easy to share (there is even a PDF printing option). That combined with the ease of creating presentations in markdown, and the ease of putting those presentations in source control, should really make anyone think twice about using PowerPoint ever again.