Mastodon Archive

Having recently created an archive of my Mastodon posts

…these are now also part of this website. The archive isn’t yet linked in the menu; it can be accessed at /mastodon.

Implementation

The implementation is quite straightforward using a Hugo Content Adapter. This reads the archive created in the previous post (as JSON) and generates representations in Hugo’s internal page format. To do this, an empty subdirectory with a file named _content.gotmpl must be created in the Hugo content directory. The example uses the name mastodon/_content.gotmpl for this.

At the start of the file, you simply need to specify the source file ($mastodonFile) and the folder where the media is stored ($mastodonMediaPath).

{{- $mastodonFile := "mastodon/mastodon-archive.json" -}}
{{- $mastodonMediaPath := "mastodon/media/" -}}
{{- $adapter := . -}}

{{- $data := dict -}}
{{- warnf "[mastodon/_content.gotmpl] Generating content from %s" $mastodonFile -}}
{{- with resources.Get $mastodonFile -}}
  {{ $data = . | transform.Unmarshal }}
{{- else -}}
  {{- errorf "mastodon/_content.gotmpl] Failed to load %s" $mastodonFile -}}
{{- end -}}
{{- .EnableAllLanguages -}}

{{- $structures := slice "statuses" "favourites" "mentions" -}}
{{- range $structure := $structures -}}

  {{- range (index $data $structure) -}}

    {{- $account := .account.username -}}
    {{- $content := .content -}}
    {{- $createdAt := .created_at -}}
    {{- $id := .id -}}
    {{- $media_attachments := slice -}}
    {{- with .media_attachments -}}
      {{- range . -}}
        {{- $mediaType := .type -}}
        {{- $url := .url -}}
        {{- $localMedia := path.Join $mastodonMediaPath (urls.Parse .url).Path -}}
        {{- if os.FileExists (path.Join "assets" $localMedia) -}}
          {{- $url := $localMedia -}}
        {{- else -}}
          {{- warnf "[mastodon/_content.gotmpl] Local media file not found: %s" $localMedia -}}
        {{- end -}}
        {{- $previewUrl := .preview_url -}}
        {{- $localPreview := path.Join $mastodonMediaPath (urls.Parse .preview_url).Path -}}
        {{- if os.FileExists (path.Join "assets" $localPreview) -}}
          {{- $previewUrl := $localPreview -}}
        {{- else -}}
          {{- warnf "[mastodon/_content.gotmpl] Local preview file not found: %s" $localPreview -}}
        {{- end -}}
        {{- $description := .description -}}
        {{- $media_attachments = $media_attachments | append (dict "type" $mediaType "url" $url "preview_url" $previewUrl "description" $description) -}}
      {{- end -}}
    {{- end -}}
    {{- $reblog := slice -}}
    {{- with .reblog -}}
      {{- range . -}}
        {{- $reblog = $reblog | append . -}}
      {{- end -}}
    {{- end -}}
    {{- $language := .language -}}
    {{- $reblogsCount := .reblogs_count -}}
    {{- $favouritesCount := .favourites_count -}}
    {{- $card := dict -}}
    {{- with .card -}}
      {{- $url := .url -}}
      {{- $title := .title -}}
      {{- $description := .description -}}
      {{- $card = dict "url" $url "title" $title "description" $description -}}
    {{- end -}}
    {{- $url := .url -}}
    {{- $repliesCount := .replies_count -}}
    {{- $tags := slice -}}
    {{- with .tags -}}
      {{- range . -}}
        {{- $name := .name -}}
        {{- $url := .url -}}
        {{- $tags = $tags | append (dict "name" $name "url" $url) -}}
      {{- end -}}
    {{- end -}}
    {{- $mentions := .mentions -}}
    {{- $reply := dict -}}
    {{- if and (ne .in_reply_to_id nil) -}}
      {{- $reply = dict "in_reply_to_id" .in_reply_to_id "in_reply_to_account_id" .in_reply_to_account_id -}}
    {{- end -}}
    {{- $poll := .poll -}}
    {{- $pinned := .pinned -}}
    {{- $favourited := .favourited -}}
    {{- $sensitive := .sensitive -}}
    {{- $spoilerText := .spoiler_text -}}

    {{ $content := dict
      "mediaType" "text/html"
      "value" $content
    }}
    {{ $page := dict
      "content" $content
      "kind" "page"
      "date" (time.AsTime $createdAt)
      "params" (dict
        "account" $account
        "created_at" $createdAt
        "id" $id
        "media_attachments" $media_attachments
        "language" $language
        "reblogs_count" $reblogsCount
        "favourites_count" $favouritesCount
        "card" $card
        "url" $url
        "replies_count" $repliesCount
        "_tags" $tags
        "reblog" $reblog
        "mentions" $mentions
        "reply" $reply
        "poll" $poll
        "pinned" $pinned
        "favourited" $favourited
        "sensitive" $sensitive
        "type" $structure
        "spoiler_text" $spoilerText
      )
      "path" $id
    }}
    {{ $adapter.AddPage $page }}
  {{- end -}}
{{- end -}}