So, decided to hack my own slideshow script, to dynamically turn (some of) these WP posts into slideshows…
Back to lecturing? Maybe. Twenty plus years ago, when I taught/lectured for a few years, we used mechanical/optical “transparencies” projection in class. Nu, prehistory. More recently, I used Google Slides to keep it simple, and portable. But today…
- Google Slides: cleaner than some (most fussing with styling can be avoided), but still no separation of concerns (ie, semantic content, so that styling is decoupled, uniform/consistent); portable (browser, responsive? NB: requires online); “social” (already); exportable (OpenDocument Presentation, PDF…)
- Reveal.js (~3.7MiB, 6KLOC not counting plugins — bloatware?): nested (“vertical”) slides (but only one level?), keyboard shortcuts menu, thumbnails overview, progress indicator, “fragments” (incremental slides), transition styles, iframe background, syntax highlighting (with highlight.js), URLs (eg, /#2/3/; History API), speaker notes in popup (separate browser window — Socket.IO based, shows notes, timer, preview of next slide), PDF export, API, plugins, MathJax… But, markup seems non-standard, verticals are weirdly nested <section>s?
- Bespoke.js (~50KiB, but key features in plugins): plugins, themes, API, UMD
- S5… (Bookmarked lots. Maybe later.)
- Centralized social media — an oxymoron? Sure, but, network effect, thus SMO?
The nice thing about standards is that you have so many to choose from.— Tanenbaum. Also, xkcd.
- XOXO: historical perspective. And cute name. ;o) (BTW, WP already uses
[class~=xoxo]— unrelated. WTF?)
- S5 microformat: much too noisy, I’ll only use maybe a couple of features — and why conform if I’m writing my own script? Anyway, it’s a useful thread to start pulling.
- Markup: must not break WordPress/my theme (Stencil) — keep posts rendering normally, and don’t/minimize DOM changes. And no divitis!
- Nesting: tree, flattened.
- Unique URLs: for History API.
- Keyboard shortcuts
- Nice to have?
- Wrapping each slide with
<section>is unavoidable (or is it?), but, testing in DevTools shows this doesn’t disrupt post’s layout — no CSS changes necessary. ;o)
- Can be done dynamically, in the browser. Not a trivial one-liner, pro’ly, but, “luckily”, since WP seems to force wrap text nodes (and comments!) in
<p>s, all first level (
.entry-content>*) nodes are
ELEMENT_NODEs — much nicer to handle (since
most jQuery operations don’t support text and comment nodes).
- Essentially, wrap each
<h2>heading, and following siblings up to (
.nextUntil()?) the next, or EOF, in a
<section class="slide">. And move heading’s attributes to it.
- Did I say not a trivial one-liner?! Nu:
$ '.entry-content>h2' .each (i,e)-> $ e .nextUntil 'h2' # Following siblings. .addBack() # Include self. .wrapAll '<section>'
- Don’t want to mess about with the theme (WP is dead!). Or plugins. Loading a script to dynamically patch the DOM is easy enough: added this at the bottom of single.php, right before calling
// Inject my slideshow hacks, and *modern* jQuery as dependency. wp_deregister_script('jquery'); // Just to be sure? wp_enqueue_script('jquery','https://code.jquery.com/jquery-3.4.1.slim.min.js',array(),'3.4.1',true); wp_enqueue_script('slideshow',get_template_directory_uri().'/js/slideshow.js',array('jquery'),'2.1',true);
(Didn’t even update entire theme, just uploaded files with scp, or SFTP with Thunar.)
- Even tho won’t interfere with regular posts, I’d rather only hack the DOM when necessary: given I’d tag slideshow posts anyway, and WP already inserts CSS classes for taxonomies, this becomes super easy:
unless ($ '.post.tag-slides').length then return
- I like deep trees (outlines), but they don’t render well as WP posts, so I flatten them.
- Structure/flow can be overlaid conveniently enough (especially using WPsuck now) with HTML attributes… and source ordering.
- Outline trees have equivalent (isomorphic in a sense?) binary trees; source order implicitly means sequence, so I’d only need to explicitly markup nesting. To facilitate moving slides around, while editing, I’ll go with adding
[data-parent="foo"]to every (nested under
- I won’t animate transitions. Other scripts went with a horizontal mental model/metaphor, a strip of slides going left to right. Mine’s tree structured, and needs four keys to navigate: (1) next (or down, DFS — depth first search), (2) previous, (3) skip children, going to next sibling, and (4) up to parent.
I’ll map these similar to how a file manager’s tree view does — to keyboard arrows right (also space, page down), up (and page up), down, and left, respectively.Nah, makes no sense, can’t remember these. Right/left for next/prev and up/down for, nu, up/skip, then.
- Also, map home and end to first and last slide.
which? Effing mess. Comments, instead?
- Browser already handles keys for going back/forward in history.
Nice to have?
- Might want corresponding visual controls, à la Reveal.js.
- Handle URL fragments and hyperlinks to [id]s inside slides, too?
- Hide/show controls and progress? On hover?
- Stylesheet for print.
- PHP: avoid loading script and everything altogether, if no slides.
- Firefox will load scripts referenced from local (
file:///) documents! (Don’t need Python’s
-m http.server, nor
npm i http-server. ;o) So, temporarily adding these to the end of an HTML file (WPsuck!):
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script>$('body').addClass('post tag-slides entry-content').prepend('<h1 class="entry-title">Slithy</h1>')</script> <script src="./Code/dist/slithy.js"></script> <link href="./Code/dist/slithy.css" rel="stylesheet">
$ sensible-browser ../Slithy.html
- Pro’ly should’ve done this with GreaseMonkey (et al) instead?
coffee --watchdidn’t work for me… over SFTP/gvfs mount? There are tons of alternatives…
$ stylus --out dist --compress slithy.styl
# Button to start the show. $ '<button title="Slideshow" accesskey="s">📽</button>' .insertAfter $ 'h1.entry-title' .click -> $ 'body' .toggleClass 'slideshow'
Show just one
.slideshow .slide // Only apply when in slideshow mode. display none // Show just one — .current. &.current display block position fixed top 0 bottom 0 left 0 right 0 overflow auto // fixed doesn't scroll. background white // Mask everything else.
- Alternatively, use CSS Scroll Snap? Nu, another research project.
- Slides must all have IDs: because bookmarks (of individual slides, as URL fragments, obviously).
- Also, tho History API doesn’t require URL changes, reloading won’t preserve position without them.
- So, if slides aren’t explicitly ID’ed (for internal hyperlinks), then generate dynamically: based on headings, so they’re quasi constant; abbreviated; unless identical headings. (Code’s a bit dense. Nu.)
- Bookmarks: page might’ve been loaded with fragment (hash) in URL already:
$ '<button title="Slideshow" accesskey="s">📽</button>' .click (ev)-> if ($ 'body.slideshow').length # Is view now in slideshow mode? # Show slide: indicated in URL, otherwise first. h=location.hash unless h or ($ '.current').length then slide 0 else slide h
- History API? Assigning
location.hashdoesn’t reload the page, and seems to push a new history entry — and trigger
And… It works. In like 120 lines of code.