Exerslide
A framework to create React-based HTML presentations and tutorials.
Install / Use
/learn @facebookarchive/ExerslideREADME
exerslide
A tool to generate simple HTML slideshows/tutorials (from text files). The primary intent is to generate interactive presentations for teaching web technologies. Built on [React][] and [webpack][].
Examples
Presentations / sites built with exerslide:
Getting started
exerslide comes in two parts: A global command line interface to initialize and build presentations, and a module that contains further dependencies to build the presentation.
-
First install the
exerslide-clipackage globally:npm install -g exerslide-cli -
Initialize a new project / presentation, by creating a new folder and running
exerslide init:mkdir myPresentation cd myPresentation exerslide init myPresentation -
Create/edit slides in
slides/. -
Run
exerslide serve
to start a local webserver to view the presentation.
Concepts
Note: Most of the of the build process is handled by [webpack][].
exerslide init (or exerslide copy-defaults) copies
[exerslide.config.js][exerslide-config] and
[webpack.config.js][webpack-config] into the project. Most of the default
behavior here is defined in these files and can be customized.
Slides
Slides are defined as text files which contain content and metadata. The metadata is defined in an optional [YAML][] front matter block, followed by the content:
---
title: Title of the slide
---
This is the content
(basically just like Jekyll)
Organizing Slides
By default, exerslide determines the order of the slides by sorting the file names alphabetically. For example, if you name your slides as
slides/
00-Intro.md
01-MainTopic.md
02-End.md
exerslide will pick up the slides in that order.
Note: Aside from the order, you can name the files however you want.
Slides can be grouped as chapters by putting all slides of a chapter into a folder. For example:
slides/
00-Intro.md
01-chapter1/
00-Problem.md
01-Solution.md
02-Summary.md
Like with filenames, exerslide doesn't care about the actual name of the folder.
Metadata
exerslide provides the ability to configure certain aspects of a slide via the YAML front matter. It currently supports the following, optional, configuration options:
-
title: The value oftitlewill be rendered as an<h1>element above the content. -
toc: The name to show in the table of contents. If not present, thetitleoption will be used. If that one is not present either, it will show "Slide X" where X is the index of the slide. -
chapter: The name of the chapter this slide belongs to. It serves two purposes:- It can be used as alternative to group slides by chapter (i.e. you don't have to use folders if you don't want to).
- This name will be shown for the chapter in the progress bar / table of contents of the presentation. If you organize your slides in folders, you only have to define this key in the first slide of the folder. All other slides "inherit" the chapter name from the first slide.
-
layout: The name of the layout to use (overwrites layout inference). -
content_type: The markup language used for the content (overwrites content type inference). -
class_names: A list of CSS class names to be added to the root of page/presentation. This allows for sharing specific styles across slides. -
style: CSS style declaration, additional CSS to use on this slide. -
id: A name that is unique among the slides. This provides a "safer" way to link between slides. -
layout_data: Additional data to be sent to the layout used for this slide. -
hide_toc: The table of contents is hidden for this slide if set totrue. -
scale: Exerslide automatically adjusts the font size for different screen widths to ensure that the slides are always readable.scalelets you customize the behavior to some degree. Note: This option can only be set on the first slide.false: If set tofalse, no adjustments will be madeObject: Otherwise the value can be object with up to three properties:content_width: Specifies the content width inems. This can be thought of as how many words / characters per line should be shown.column_width: A number between 0 and 1. How much of the screen (width) should be occupied by the content.max_font_size: Don't make the font any larger than this value (in pixel).
Layouts
Layouts define how the content (and layout data) of a slide are structured. For example the Column layout renders the content in multiple columns.
Layouts are implemented as [React][] components, which allows you to create arbitrarily complex layouts. For example the JavaScriptExercise layout renders a text editor containing the content of the slide and contains logic to validate the user's solution.
The primary idea behind exerslide is to move all the behavior in reusable layouts, to keep the actual content creation simple.
Layout inference
Which layout to use for a slide is determined by the following process:
- The slide's
layoutmetadata field. - If not present, the layout is inferred from the file extension. This mapping can be configured.
- If it can't be inferred, no layout is used.
Layout file resolution
Both, the layout field and the file extension mapping expect the layout name
as value. exerslide will look for a file with the same name (ignoring the file
extension) in the layouts/ folder of the project itself or any loaded
plugin.
Example:
If the slide contains
---
layout: Columns
---
and the exerslide-plugin-columns-layout is loaded (which it is by default),
then exerslide will look for
./layouts/Column.jsexerslide-plugin-columns-layout/layouts/Columns.js.
Note: exerslide will show an error if there are multiple layouts with the
same name. If you want to specify a layout of a specific plugin, you can use
the <pluginName>:<layoutName> syntax, e.g.
---
layout: columns-layout:Columns
---
Layout data
Layouts have access to the layout_data metadata option of a slide. This
allows a slide to pass arbitrary data to the layout. What data to pass depends
on the layout. For example, the Columns layout can be configured to use a
different column divider:
---
layout: Column
layout_data:
divider: '<myDivider>'
---
This is the first column
<myDivider>
This is the second column
Master layout
As layouts define the structure of a slide, the master layout defines the structure of the whole page. The [default master layout][master layout] doesn't do much: It renders a table-of-contents/progress component and the current slide.
The default master layout is copied into the project folder so you can customize it more easily.
Content types
Layouts primarily describe how a slide is structured. While there can be
layouts that expect the content in a specific format/language (the
JavaScriptExercise layout expects the content to be JavaScript), there are
usually parts that allow you to write content in any format you like.
You can decide which markup language to use for such content, e.g. Markdown, HTML or something else. All you need is a function that can convert the content to something renderable in React (string, React component, etc).
exerslide provides support for HTML and Markdown out of the box (via plugins).
Content type inference
Which converter to use is determined by:
- The
content_typeoption in the front matter. This allows you to set the type explicitly. The value is usually a media type name. (this is not common) - The file extension. If
content_typeis not specified, the media type of the file is determined from the file extension. E.g. we gettext/x-markdownfor an*.mdfile.
Content type resolution
Like with layouts, exerslide will automatically look for matching content type
converters in the project itself and any loaded plugin. It will look for
matching files in the contentTypes folder.
E.g. if the slide contains
---
contentType: text/x-markdown
---
and the exerslide-plugin-markdown-converter plugin is loaded, it will look
for
./contentTypes/text_x-markdown.jsexerslide-plugin-markdown-converter/contentTypes/text_x-markdown.js.
Note: Just like for layouts, you can prefix the type name with a plugin
name (<pluginName>:<typeName>) to avoid conflicts.
Styles
CSS dependencies are bundled into two CSS files:
-
One file contains the CSS dependencies of React components (such as for [codemirror][]) and layouts. If a React component has CSS dependencies then usually because it doesn't function properly without it.
-
The other file bundles the CSS listed in
exerslide.config.js,stylesheets.// exerslide.config.js module.exports = { stylesheets: [ 'bootstrap/dist/css/bootstrap.css', '...', './css/style.css' ] };The default setup includes [Foundation][], [font-awesome][] and a [highlight.js][] theme.
