labnotes

Book Image Shortcode for Hugo

Lets link to bookshop

tags
hugo

HappyFunCorp helped build Bookshop.org which is an online bookstore that distributes 30% of the book profits to independent bookstores in your area. Basically it’s a place that people can link to that isn’t Amazon, and that will kick some money to your local community.

I wanted to find a way to easily create links to these product pages, and show images if needed. There’s no API to access bookshop (I asked on our internal dev channel) but I know how to write a script so I cobbled something together and made a hugo shortcode to render stuff on my blog.

{{< bookshop isbn=“9780394719856” />}}

Which will generate this, a embedded link to the product page of the book with the title pulled from the server:

The Gay Science: With a Prelude in Rhymes and an Appendix of Songs is a great book.

Or

{{< bookshop isbn="9780394719856" img="left">}}
Here are my thoughts about this book
{{< /bookshop >}}

The Gay Science: With a Prelude in Rhymes and an Appendix of Songs Here are my thoughts about this book.

We are going to use a two step process here. The first is to use a bash script to pull the data from the site and store it in json and jpg, and then a shortcode to format this in the webpage. Most of my posts are directories, so this will be part of the page bundles.

Get the book information

Since there’s no API and I want to keep this simple, our strategy is to:

  1. Hit the search page with the ISBN
  2. Use awk to pull put the link from the search results.
  3. Load the product page.
  4. Use an unholy combination of grep, sed, and awk to pull out the meta data.
  5. Store this in ${ISBN}.json
  6. Download the cover image in ${ISBN}.jpg

bookshop_lookup.sh:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/bin/bash

ISBN=$1

if [ -z "$ISBN" ]; then
    echo Usage $0 ISBN
    exit 1
fi

if [ ! -f "${ISBN}.json" ]; then
    WORKFILE=$(mktemp)

    if [ ! -f "${ISBN}_search.html" ]; then
        echo "Searching isdn from bookshop"
        wget -O ${ISBN}_search.html "https://bookshop.org/books?keywords=${ISBN}"
    fi

    if [ ! -f "${ISBN}_book.html" ]; then
        echo "Looking up book info from bookshop"
        URL=$(awk '/class="cover"/ { print $3 }' ${ISBN}_search.html | sed -E 's/href="([^"]*).*/\1/')
        
        if [ -z "${URL}" ]; then
            echo Unable to find product link in search results
            exit 2
        fi

        wget -O ${ISBN}_book.html https://bookshop.org${URL}
    fi

    grep meta ${ISBN}_book.html | awk 'BEGIN {RS="<meta "} // { print } ' > ${WORKFILE}

    IMG_URL=$(grep twitter:image\" ${WORKFILE} | sed -E 's/.*content=\"([^"]*).*/\1/')
    echo Image $IMG_URL
    DESCRIPTION=$(grep twitter:description ${WORKFILE} | sed -E 's/.*content=\"([^"]*).*/\1/')
    echo Desc $DESCRIPTION
    TITLE=$(grep og:title ${WORKFILE} | sed -E 's/.*content=\"([^"]*).*/\1/')
    echo Title $TITLE
    AUTHOR=$(awk '/\(Author\)/ {print}' ${ISBN}_book.html | sed -E 's/\s*<[^>]*>//g' | sed -E 's/<\/a.*//')
    echo Author $AUTHOR
    
    echo "{\"title\": \"${TITLE}\", \"url\": \"https://bookshop.org${URL}\", \"img\": \"${IMG_URL}\", \"author\": \"${AUTHOR}\"}" | jq -r '.' > ${ISBN}.json

    if [ -f ${WORKFILE} ]; then
        rm ${WORKFILE}
    fi
fi

if [ ! -f ${ISBN}.jpg ]; then
    wget -O ${ISBN}.jpg $(jq -r '.img' ${ISBN}.json)
fi

The shortcode

I’m not an expert in hugo shortcodes, but this is what we’re doing.

  1. Look for the file ${ISBN}.json in the page bundle.
  2. Show a message if we don’t find it.
  3. Pull in data into a map using $jsonFile.Content | unmarshal
  4. If we are showing the cover image, choose which set of bootstrap utility classes we want to use.
  5. Wrap the output in <p class="clearfix"> to deal with the overfloat. Can’t believe I’m still doing this.
  6. Link the image or the title to the bookshop product page, data pulled from the json file.
  7. Add the {{ .Inner }} content inside of the tag.

bookshop.html:

/link to bookship.html/ TODO

Example output:

Chuang Tzu: Basic Writings (Revised) Dui, id ornare arcu odio ut sem nulla pharetra diam sit amet nisl suscipit adipiscing bibendum est ultricies integer quis auctor! Odio eu feugiat pretium, nibh ipsum consequat nisl, vel. Ac tortor dignissim convallis? Tincidunt nunc pulvinar sapien et ligula ullamcorper? Egestas diam in arcu cursus euismod quis viverra nibh cras pulvinar mattis nunc, sed blandit libero volutpat sed cras ornare arcu dui vivamus?

References

  1. https://shindakun.dev/posts/adding-a-book-cover-shortcode-for-hugo/

Previously

labnotes

Styling tables with Hugo

Markdown sometimes isn’t enough

tags
bootstrap
hugo

Next

labnotes

Playing with deno

Rethinking package managers

tags
deno
typescript
javascript