Blog Implement

This blog was created to preserve me and my thinking. It was supposed to be written in ink, on the internet but I make so many typos, I decided to keep using the pencil. Well, not really pencil, but just an easily editable markdown that I can parse however I want to make the website that I want. I have a lot of those .mds laying around…

tech stack

This small web app is written with Go (Gin-GOnic framework as opposed to gin&tonic), templ, tailwindcss, and htmx (GoTTH stack). I realized this might just be the perfect stack for someone who wants to build a small-to-medium sized web app, loves go and wants to write more go, and thinks that a full-blown frontend would be overkill for their project (or you just think javascript is a pain and wants to write less javascript).

Go

I think everyone should try to learn Go, it’s so simple and it’s genius. You want to write a set? Oh just make use of this map of X data-type, it’s the same thing really. None of that really, really complicated metaprogramming like in some C++ codebases you might find (though admittedly, I also really enjoy those kind of programming). Though Go does have its share of metaprogramming like the Generics they released a few years back, I just see Go’s syntax as one of the best in programming languages as they’re not too confusing and can be really concise. And, don’t forget about reflection, one of my favorite type of metaprogramming, ‘cause they’re everywhere in Go. It’s the true embodiment of “If it walks like a duck, quacks like a duck, then it’s probably a duck”.

Go

With Go, you’re ‘forced’ to simplify things down. At least, that’s what I feel writing Go. When I finish writing Go I feel like everything’s where it’s supposed to be and does what it should do, no excessive bloat to do the things that I want to achieve (most of the time).

It’s also very performant, with sooo little code to write. Oh, you want to use another thread? Just put ‘go’ in front of the function you want to use (or closures) to spawn a goroutine. You want to pass information between those goroutines? Use channels, define the data you want, and wait for those stuffs to arrive from other channels. Need some form of synchronization for those goroutines you just made? Use wait groups for those types of problem.

You NEED a class? Don’t you mean structs? Nobody needs classes really, most of the times it just abstracts away the code that you WANT to read. That is unless, you’re really good at designing classes.

Writing Go is just so intuitive that I love spending my time learning more about it. Every new things I discover about Go, I just think ‘that really makes sense, yeah you should write like that’. When I write Go, I’m just very happy (this is my love letter to Go, and this letter WILL keep piling up).

Though there’s one thing that I feel like is not necessary in Go, two things really. One is the ‘unused variable and modules’, like why for the love of god can’t they just be a warning (I don’t mind excessive warnings really for this kind of matter). Every time I write something with air (essentially nodemon for Go projects), and I start debugging just a bit (using the fmt module), I always forget to remove the module dependency from the file and I keep wondering why my application doesn’t refresh… Maybe it’s a me problem, there’s probably a better way to debug code without adding a dependency to write variables in stdout. But that’s just what I’m used to. The second and biggest gripe I have is, you probably guessed it. Most of the people I talk to about Go with doesn’t seem to be a big proponent of this feature. It’s the capital letter for public functions. I’m really used to writing in snake_case for variable names, functions, and essentially everything really except for global constants and structs. This feature of Go is limiting my options to use only camelCase and PascalCase. But it’s something I have to live with and learn to love, since I’m already married to Go.

Gin

I think most people know Gin already if you’ve written in Go.

My first experience using Gin was when I wanted to build a web app, and I was tired of writing javascript with Express. At that time, I didn’t even know Go, I just looked up the most popular backend frameworks to build web applications with on the internet. The most mentioned framework at that time, was Gin. The funny name also played a factor in me trying out the framework.

Back then I thought it was very simple really, they also already have a lot of the common middlewares for external stuffs to just skip some parts of writing a web application. But, when writing this web app, I thought some things could be simpler, for example passing context. Most of the time, I don’t really need gin to optimize parts of my code by using gin’s context. Hell, most of the time I just need it for routing. Maybe I should’ve written this application with Chi instead since it seems much simpler and best suits my needs. Or I might just use Go’s built-in http routing at some point since they improved it a lot I heard. It might be interesting to just use Go as-is, no external framework dependencies, just the ones Go provided. It might be interesting to make an application work with no ‘go get x-dependency-module’ and just have it run.

But the things that I like with Gin, is that there’s a lot of people using it. And that means, more resources on the internet. I might be too lazy sometimes to go read up on the documentation to know what I’m supposed to do, instead I can just describe my problems to some search engine and have it spit out people who’ve encountered the same problems that I’m facing right now and have solved it. It’s really fast that way to output the things that you want and get it up and running online.

Templ

When I first wanted to write this application I was thinking of just utilizing Go’s html/template to write parse my markdown and generate the HTML I want. But then I found out about templ, I found out how easy it is to use, and how flexible it is. Plus, it compiles to Go functions that I can use easily.

templ

Finding this was such a godsend as it makes everything just easier. Plus, I also have some syntax highlighting when writing in my editor (I use neovim btw…). I say some, because the LSP behaves weird sometimes, I don’t know maybe I didn’t set it up properly. And it’s also really easy to set up for development, I just need a watcher to watch my .templ files and make it compile it to Go code that I can use.

Also, it’s really easy to just serve HTML or part of it from the backend and have it visible immediately on my website. When combined with htmx, I don’t ever have to create a json struct, pass it to the frontend, have it destructured by my frontend stack, and create the UI logic for it.

It’s just really easy to work with.

Tailwind

What do you want me to say? It’s tailwindcss, I love it.

HTMX

Simple and clean. Borrowing from the famous Hikaru Utada’s song, that’s just how I feel about this particular technology.

I had always used frameworks (or libraries, if React still insists on it being a library, but that’s a whole ‘nother topic) to implement most of my frontend for my web dev projects. Mostly, because I thought that’s just how you do it. Sure, I learned how to use HTML with just AJAX when I first learned on developing websites, but people and the internet often told me that to build modern websites I had to use React, Angular, Vue, or insert X javascript frontend framework here. So, I went and learned those frameworks and built websites with it. But then, I grew really tired because people kept telling me about Y framework, or telling me ‘you should actually just use functional components in React’. Learning new things sure is VERY interesting, but as someone who mostly only cares about UX when building an interface, I don’t really want to dive in too much into those new stuffs, or some other ways to express and build the same thing over and over again. Sometimes, I just want to have a working and interactive UI that suits my basic needs.

htmx

This is where htmx comes in and actually changed my view on this. It made building frontends quicker, easier, and actually more enjoyable than before. Now, I’m now not quite sure whether it’s solely because this is still pretty new to me, but I actually became really interested in building the UI itself since discovering templ and htmx. It made building frontends not a hassle to me and I really enjoy learning new stuff about it.

While htmx is new to me, I recently discovered that it’s really quite old. I think it’s only been in the past half decade that it was rebranded to htmx, and was named intercooler previously. On a sidenote, I really get why they rebranded because htmx just sounds cooler and ‘new’, yet still familiar. And ‘old’ websites used to work just like htmx, serving whole HTMLs to the client.

It basically lets me to quickly define common user events to automatically send requests to the backend and update the client’s view depending on the response data. It utilizes AJAX and makes me write less code by not defining the request one by one, wrapping it in JSON, sending it to the server, and write the UI logic based on the response. Basically, it removes most of the templates like tailwind does for css (I’m sure this is one hell of an oversimplification of this topic). And, to add htmx to my website is as easy as adding a script tag. To add more security, I just had to implement the nonces logic from the backend to make sure that the script is provided from me, not by some other external sources.

htmx is something new that I discovered, and I hope to learn a whole lot more about it.

SQLite

It’s really boring, I just had to make some tables to store some data. I know it’s enough for my website, and if it’s good enough for basically every device in the world, it’s good enough for my personal website. It’s also something that I just usually use everywhere because it’s really convenient not having to create a Docker image (usually) just to store less than 100 rows of data.

abstract syntax tree

I learned a bit about abstract syntax tree, not only when implementing the custom renderer for this project, but also through the usage of treesitter in my neovim setup. I learned that treesitter has a playground that I can just turn on to see the data structure and see how it parses my code to learn how to highlight the syntaxes. When using it in my editor, I can see how it traverses through the tree when I hover some lines in my code.

treesitter

It’s pretty fun to peek into how compilers, LSP, and other stuff that I interact with regularly work. I even thought it might be a good exercise to dive further deeper into the topic besides from implementing some nodes of the parse tree for my markdown converter. But for now, it’s pushed back into my list of projects to start…

Anyway, an abstract syntax tree is basically a tree representing the structure of some text written in a formal language. Though I’m not quite sure that markdown as a whole qualifies as a formal language (it probably does, I just don’t quite know what the exact requirements are), I’ve added some rules (or grammars) to the markdown language, specifically for my needs. One of them is to generate a gallery element in my website.

To implement this, I’m using gomarkdown which already has a complete parser for rendering markdown files to htmls.

general implementation

The website is basically just one Go codebase that converts .md files to .html files with some rules I defined for my specific needs with the help of Abstract Syntax Tree. I use predefined templates to insert the pregenerated html code and serve them to users by giving them the full html and some htmx for user interactivity.

And, here is a page that no one gets to see but me (it’s the upload page).

upload

It’s really bare-bones, and I don’t really plan on adding much more to it. And it probably contains the majority of the user interactivity of the whole website.

I’ve also trained some AI voice converter model and served it in my other device to provide TTS for my articles, if you could check that out. As of now, it’s my voice that’s reading the articles and it might be pretty janky, but I’m working on improving it, once I get my hands on some cheap SBCs with NVIDIA GPUs.

I also would like to think there’s some really fun stuff like the authorization I implemented for the website, partly because I think it’s really dumb, but funny.

I’ll probably collect my thoughts and write more on those two topics.