Inspired by Global Diversity CFP Day, and due to an increasing involvement at my local communities, I have been thinking of building my speaker site for a while. And so I was working on it earlier this weekend.
There are existing commercial speakers sites such as noti.st and Speaker Deck. Some people have a section for speaking under their personal site.
I currently have existing slides all over the place, google presentation, slides.com, mdx-deck, spectacle, revealjs, etc. Iβm happy to put a link if itβs hosted externally somewhere. But those that I built locally, I hope to host them so that I can share them easily in the future.
I donβt have a bound choice of tech stack because I build separate sites for my projects anyway. Even my home page is a separate project. Judge me if you wish π
Directory structure
Iβm imagining this kind of structure:
.
βββ README.md
βββ ... # my site?
βββ slides
βββ 2019-03--whats-happening-30-days-css-girls
βββ year-mo--title-to-your-talk
βββ ...
βββ index.html
βββ package.json
So what about the site?
I decided to forget about static site generators and write one myself. Saturday is for writing genuine HTML, CSS, and JavaScript, join me next Sat?
Although, I would like to mention that this decision did not come quick. Iβve built three Gatsby sites recently. And I notice that that JAMStack mindset is forming something in my brain. At the end of this day I realized that the whole thing came down to less than 200 lines of code, prettier-ed, my jaw came down. The fact that I didnβt think along this plainer scratch to begin with rings a bell in me.
index.html
Here to remind myself that apart from linking the CSS and JavaScript as separate files, there is this option to inline them.
- The CSS is under a
<style />
tag - The JavaScript is under a
<script />
tag
<head>
<style>
/* CSS */
</style>
</head>
<body>
<p>Hello, this is ...</p>
<h2 class="display">Upcoming</h2>
<ul id="upcoming"></ul>
<h2 class="display">Past</h2>
<ul id="past"></ul>
<footer style="position: absolute; bottom: 0; padding-bottom: .25rem">
... built with β€
</footer>
<script>
// JavaScript
</script>
</body>
Then, the idea is that I write a separate data.js
file to include all the meta data for each talk. And I parse this data and render according to a few simple logic.
It is not very hard to write a script to read all the meta info from each slides. But I decided not to work on that for now.
There is only one feature π€
I check for date for each talk, split between past and upcoming talks, then flush them into their separate sections.
const isUpcoming = talk =>
// I put random things here if it's upcoming
new Date(talk.when) > new Date() || new Date(talk.when) == 'Invalid Date'
const isPast = talk => new Date(talk.when) <= new Date()
talks.filter(isUpcoming).map(/** renders into upcoming section */)
talks.filter(isPast).map(/** renders into past section */)
Maybe two βοΈ, if parsing template strings counts
I wrote in a mixed flavor that I picked up along the many projects Iβve been through π Iβm pretty amused by this section of the code to be honest.
const parseTalks = (elementId, talk) => {
// deconstruct talk object
const { title, when, where, slides, post, intro } = talk
const titleNode = `
<div class="topic">
<i class="fas fa-quote-left"></i>
<span class="display">${talk.title}</span>
<i class="fas fa-quote-right"></i>
</div>
`
// ... others
// create an element for each talk and append to the ul
const talkElement = document.createElement('li')
talkElement.innerHTML = [
`<base target="_blank" />`,
titleNode,
whenNode,
whereNode,
slidesNode,
postNode,
introNode,
].join('')
document.getElementById(elementId).appendChild(talkElement)
}
talks.filter(isUpcoming).map(parseTalks.bind(null, 'upcoming'))
Serving slides
I put all the slides under a directory called slides/
. They will live in each of their own directory, and have their own separate dependencies and builds. There are mainly two issues to concern: routing if applicable, and building, since I donβt want to keep built file in the repo.
This one works automatically. You write everything in the index.html, static assets are built with grunt. Unless you write your own theme, there is not even a need to build.
Spectacle is a presentation library built with and for React. It also works beautifully, although it needs a build.
Unfortunately, this one currently does not work. Because it routes by statically look up the pathname index 1. Serving mdx-deck under slash separated pathname will not work.
Iβve created an issue to hopefully resolve this in the near future.
So now the repo roughly looks like this:
.
βββ README.md
βββ data.js
βββ index.html
βββ lerna.json
βββ package.json
βββ slides
βββ 2019-03--whats-happening-30-days-css-girls
βββ 2019-04--developers-gym-gatsby
βββ revealjs-boilerplate
βββ spectacle-boilerplate
Lerna + Netlify for build and deploy
Thanks to Netlify, it takes away all the things I donβt want to concern about. The build step is so incredibly easy and without any hiccups at all.
Some of my slides needs a build for static files. Some others donβt. Netlify allows me to supply a build script to run for each build. Writing a script to go through each directory that needs build is not too much of a hassle. But why not use Lerna..
With lerna bootstrap
and lerna run build
, it automatically bootstraps (installs all dependencies, symlink if possible) all packages which, in my case slide, and runs build in all packages that specify a build command. And then Iβm done!!
Till next time
How was this site built? I give it a combined credit of kindergarten plus grown-up toys. Itβs almost therapeutic.
Will you build a speaker section to your website? And if so, how would you build it?
Top comments (4)
What about Remark JS? It's very nice and easy.
Thanks for letting me know! I shall try this :]
What project will you be working on next Saturday?
I don't know πMy life is kind of at random nowadays