Alongslide is a layout engine extending Markdown syntax for use in Rails-based web applications
It was developed by Triple Canopy as a text-editable yet sophisticated platform for producing long-form reading content on the web.
Copyright 2013-2014 Canopy Canopy Canopy, Inc.
The Ruby backend uses Redcarpet to extract layout directives from the Markdown, Treetop to parse their grammar, and HAML to render them into templates.
The CoffeeScript/SASS frontend then scan the resulting HTML for layout cues, using a custom CSS Regions polyfill to flow the body text, skrollr to build transition animations and respond to user scrolling, plus jQuery and underscore.js as utilities.
gem install alongslide
The gem includes both the Ruby and frontend components.
The best introduction to using Alongslide is by checking out the demo Rails app:
This app demonstrates the minimum views, JS, and CSS needed to build an Alongslide site.
Creating custom templates
You may specify a directory in your application where you can specify your own
custom Alongslide templates. To do so, create an
config/initializers with the contents:
Alongslide.configure do |config| config.user_template_dir = Rails.root.join("app/views/alongslide") end
Then you may create views in that directory using the YAML frontmatter format described below.
If these template have JS/CSS components, those may go wherever you like.
Alongslide blocks override the normal Markdown behavior for code blocks. Any text indented by four spaces will be handled by Alongslide.
Within these blocks, special directives indicate which templates to render. Directives begin with a plus sign.
Flowing paragraph text... + panel BigPanel fullscreen # Huge text in a huge panel. Flowing paragraph text continues...
Templates are in
views/. While basic
section templates are closely wedded to the frontend parser, panel templates may contain other templates, which are preloaded from
Each template begins with Middleman-style YAML frontmatter. Currently only one value is read:
greedy, which refers to whether the template may contain other templates or not. If
true, the template represents a
greedy node, and can contain other templates; if
false, it is
non-greedy, and therefore cannot contain other templates.
Flowing paragraph text... + panel GalleryPanel fullscreen + gallery + image url "/one.jpg" + image url "/two.jpg" Flowing paragraph text continues...
In the above example, the two (nongreedy)
image templates will both be
contained by the
gallery template (greedy), which in turn will be contained by the
panel template (greedy).
The syntax parser accepts arbitrary key/value pairs for templates, which are handed as they are to the HAML engine.
Nongreedy templates additionally consume any arbitrary Markdown which appears below them.
+ image url "/one.jpg" position top opacity 0.5 note "A \"nice\" note" Caption for _A Very Nice Image_.
In the above example, the
image.haml template would receive variables for
note—in addition to a variable called
content, which would contain the rendered HTML from the Markdown caption below.
Each inline parameter value may optionally be enclosed in double quotation marks, with space and backslash-escaped quotes inside.
Adding panel parameters
To add functionality to the system, follow the path through the full stack, from back to front:
- Add appropriate rules to
panel.treetop(consult Treetop documentation for syntax)
- Write tests for parsing the new rules in
- Make sure the appropriate
SyntaxNodesubclass (defined in
parser.rb) puts the Treetop data into the correct param for the template (
panel.haml). By default, it'll just lump it in as a CSS class.
- Add logic to parse the param in
alongslide.coffeeadding CSS rules as necessary in
On the front end, a layout engine written in CoffeeScript parses the layout cues (typically
<div>s with special meta CSS classes) and renders the content as overlapping horizontally-scrolling frames (where one frame is one screen width).
- Pull panels out of flowing body text. Alongslide supports flowing body text and panels, which behave like sidebars. In this step, pull those panels out, and index them by ID, to be displayed later.
- Separate sections. Because Alongslide follows the CSS Regions specification, multiple text sections may not flow from a single "source" in the DOM. In this step, break up the single source element into the appopriate number of DOM elements, and register each as the source for a single NamedFlow, using CSS Regions JS integration.
- Lay out. Iterate through the NamedFlows (and their respective sections), creating flowing columns (and their respective frames) one at a time, checking each for relevant cues about panel placement. If a panel directive is found, ensure that the panel appears and is dismissed at the correct points in the piece, and that the flowing text wraps around it (by applying CSS classes). In this step, each frame, whether flowing, panel, or section background, is assigned temporary DOM
alongslide-hide-at), to be parsed in the next step.
- Apply scroll transitions. Once the positioning of every frame has been decided, convert all of the temporary
data-attributes to specific skrollr transitions, which may scroll, fade, etc.
- Clean up. Currently, this just entails resizing the frame container to fit total width of the frames (so that the scroll bar is proportional).
As the CSS Regions specification is under active development, Alongslide does not rely on correct browser implementation. Instead, it forces all browsers to use the Adobe polyfill. (And will continue to until the spec is firmed up.)