diff --git a/README.md b/README.md index 2e85e42..bd17c2f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ upvoters is a basic anonymous voting system that can be added to a blog. I recently reworked my personal blog with the Hugo Bear blog theme. I came across the [creator's (Herman Martinus) blogging site](https://herman.bearblog.dev/) which had this really cool anonymous upvote system. I wanted something similar and decided to implement it myself. -The goal is maximum simplicity. +The goal is maximum simplicity so that I can use it with my Hugo static site. +It's directly integrated in [my theme]("https://forge.alexselimov.com/aselimov/hugo-bearcub") which attempts to mimic Herman Martinus' bear blog style. +I've added steps on how I set it up in my theme [at the bottom of this README](#setting-it-up-with-hugo). ## Table of Contents @@ -15,6 +17,7 @@ The goal is maximum simplicity. - [API](#api) - [Running tests](#running-tests) - [Actual deployment](#actual-deployment) +- [Setting it up with Hugo](#setting-it-up-with-hugo) - [License](#license) ## Requirements @@ -161,6 +164,112 @@ sudo systemctl enable --now upvoters curl https://example.com/api/posts/tests/votes ``` +## Setting it up with Hugo + +I set this up in my [Voting Bear Cub Theme](https://forge.alexselimov.com/aselimov/hugo-bearcub/src/branch/main). +The components are: +1. Javascript file to handle upvoting. This function is automatically called on page loads +```javascript + +(async function () { + // Define the slug + const slug = location.pathname.replace(/^\/|\/$/g, "").replaceAll("/", "-"); + const API = window.UPVOTE_API; + + const btn = document.getElementById("upvote-btn"); + const count = document.getElementById("upvote-count"); + + // On load fetch curent vote count and whether the button should be clicked on or off + const res = await fetch(`${API}/posts/${slug}/votes`, { + credentials: "include", + }); + const data = await res.json(); + + count.textContent = data.vote_count; + if (data.voted) btn.setAttribute("voted", true); + + btn.addEventListener("click", async () => { + const alreadyVoted = btn.hasAttribute("voted"); + + const method = alreadyVoted ? "DELETE" : "POST"; + const r = await fetch(`${API}/posts/${slug}/vote`, { + method, + credentials: "include", + }); + + if (r.ok) { + const updated = await fetch(`${API}/posts/${slug}/votes`, { + credentials: "include", + }); + const d = await updated.json(); + count.textContent = d.vote_count; + if (d.voted) btn.setAttribute("voted", false); + else btn.removeAttribute("voted"); + } + }); +})(); +``` +2. Button component in single.html template placed after the main post body. **Note:** I guard this behind a config check so users can use my theme without setting up upvoters. +```html +{{ if .Site.Params.upvotes }} +