self-hosting presentations using reveal
estimated read time: 5-7 minutesIn 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:
- A directory on your hosting setup that you can host your presentations out of
- A copy of reveal.js
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
.
js/
- A copy of reveal.js lives hereindex.html
- A skeleton file that just loads a chosen presentationnull.md
- The "default" presentation that shows when you browse to thepresentations/
directory
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
, andplugin
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.