developer's blog byΒ 

Back to HTML, CSS, and JavaScript and Build My Speaker Site

March 25, 2019

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?