Ryan Keleti


2020-04-02 › racket, site

Whenever I make a new page on my site, I had to copy an existing page and modify the contents to avoid having to manually copy over the boilerplate header and script contents. I came across Building a Website with Scribble, which demonstrated the scribble/html language, and I decided to give it a try.

I used nanopass.github.io's templates.rkt as the basis for my redesign. I made a templates.rkt file, following the format below (some stuff omitted).

; in templates.rkt
#lang scribble/html

@(provide (all-defined-out))

@(define (header t)
  @head{
    @meta[charset: "utf-8"]
    @link[rel: "stylesheet" href: "/css/style.css"]
    @title{@t}})

@(define (scripts)
  @list{
    @script[src: "/js/katex.min.js"]
    @script[src: "/js/auto-render.min.js"
            onload: "renderMathInElement(document.body);"]})

@(define (page #:title t . content)
  @list{
    @doctype{html}
    @html[lang: "en"]{
      @header{@t}
      @body[class: "text-center"]{
        @div[class: "center-box"]{@content}
        @scripts{}}}})

Now whenever I want to make a page, say hello.html, I make a file

; in hello.rkt
#lang scribble/html

@require["templates.rkt"]

@page[#:title "Hello"]{
  @h1{Hello page}
  @p{Hey!}}

Then I would run racket hello.rkt > hello.html, and get the page with the header and scripts I defined in templates.rkt.

The scribble/html language also makes it easy to define custom shortcuts. I use Font Awesome icons, and instead of writing

<i class="fas fa-book"></i>

for a book icon, I can write

@icon{fas fa-book}

after having defined @icon by

; in templates.rkt
@(define (icon name)
  @i[class: name])

I also use the summary tag, so I rolled my own with

; in templates.rkt
@(define (summary . s)
  (make-element 'summary '() s))

While the process is not completely streamlined, it's now easier to create pages and avoid some HTML errors. It was also a fun exercise in learning about templates and Racket.

Thanks for reading :).

back to posts