Initial blog setup
This commit is contained in:
106
posts/blog-server.md
Normal file
106
posts/blog-server.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Blog setup with markdown, rust & git
|
||||
|
||||
Hey everyone. This is the first post I write for the blog I'm starting, which is Coincidentally about how I've structured the software surrounding my blog.
|
||||
|
||||
First off, I've been wanting to do a lot recently:
|
||||
|
||||
- Moving away from Windows to using Linux and MacOS for development and gaming
|
||||
- Switching from VSCode/Cursor to neovim
|
||||
- Switching from working for an employer to becoming a solo dev/freelancer
|
||||
- Dedicate time to solo game development
|
||||
|
||||
Because of this, I figured it would be a good time to set up a blog, both for documenting whatever I'm working on and to get the word out about my work.
|
||||
|
||||
## The blog design
|
||||
|
||||
I wanted to have a setup that generates static html from something like markdown. Then recently I stumbled across this [https://gaultier.github.io/blog/making_my_static_blog_generator_11_times_faster.html](https://gaultier.github.io/blog/making_my_static_blog_generator_11_times_faster.html)
|
||||
|
||||
I decided to do something similar, however I used rust as it has some popular existing libraries for web servers and parsing markdown. The reason for writing an application to host the blog is that I wanted to have it automatically respond to a git webhook which would automatically pull the latest git repo and then rebuild the articles from their markdown files.
|
||||
|
||||
## Parsing the git output
|
||||
|
||||
As mentioned in [this article](https://gaultier.github.io/blog/making_my_static_blog_generator_11_times_faster.html) they use the git log command to retrieve the blog files, which I decided to also use. I found out there is a way to retreive the output from git in the following predictable format:
|
||||
|
||||
```
|
||||
c584d39 - 1761735775 - Update server post and fix post titles
|
||||
|
||||
:100644 100644 d5e614a 678eb09 M posts/blog-server.md
|
||||
9d5f86a - 1761415068 - Template
|
||||
|
||||
:000000 100644 0000000 d5e614a A posts/blog-server.md
|
||||
```
|
||||
|
||||
Retrieved with the following command line: `git log --raw --no-merges --pretty="%h - %ad - %s" --date=unix -- posts`
|
||||
Where the first entry will always be a commit hash followed by unix time stamp and then the commit name. After that it will list files affected by this commit, prefixed with a colon (:).
|
||||
|
||||
Then we can simply parse this by reading line by line and attributing the following file changes to the commit that was above it. Then I use the first encounter of a given file to determine the creation date, and the last encounter to determine the update date.
|
||||
|
||||
### (Bonus) Parsing the git version
|
||||
|
||||
There's a nice trick to retrieve the current git branch and commit hash by just reading 2 files, which I grabbed from one of my CMake scripts that uses it to inject the git version into my code on every compile. It's super fast since it doesn't actually run any git commands to retrieve this information.
|
||||
|
||||
The process is, read .git/HEAD, which will either contain just the hash, or something like `ref: refs/heads/main`.\
|
||||
In the later case, you can just read from .git/refs/heads/main which will then contain your git hash.
|
||||
|
||||
This version is inserted at the bottom of the page so I can tell which version it's at.
|
||||
|
||||
## HTML
|
||||
|
||||
Of course there is also some styling and markup required for the shell, like the navigation bar and footers.\
|
||||
I decided to go with a simple list of html templates that get included by the application and scan it for tags to inject certain magic values, like the list of posts or timestamps.
|
||||
|
||||
For example, here is what the page you're looking at looks like:
|
||||
|
||||
```html
|
||||
$<include src="header.html"/>
|
||||
<article>
|
||||
$<post-html/>
|
||||
</article>
|
||||
<p><a href="/">← Back to home</a></p>
|
||||
$<include src="footer.html"/>
|
||||
```
|
||||
|
||||
Which can be parsed very quickly by a simple scanner that triggers on $< and then reads the key and map of `<String,String>` parameters.
|
||||
|
||||
This allows me to just write template code like this:
|
||||
```html
|
||||
<title>$<title default="Guus' blog" pre="Guus - "></title>
|
||||
```
|
||||
|
||||
and process it in rust like this:
|
||||
```rs
|
||||
"title" => {
|
||||
if let Some(post_name) = current_post {
|
||||
let post = post_manager
|
||||
.get_post(post_name)
|
||||
.await
|
||||
.ok_or_else(|| format!("Post '{}' not found", post_name))?;
|
||||
|
||||
let none: String = "".to_string();
|
||||
let pre = attrs.get("pre").unwrap_or(&none);
|
||||
let postfix = attrs.get("post").unwrap_or(&none);
|
||||
|
||||
Ok(format!("{}{}{}", pre, post.title, postfix))
|
||||
} else {
|
||||
let def = attrs
|
||||
.get("default")
|
||||
.and_then(|s| Some(s.clone()))
|
||||
.unwrap_or("<title not set>".to_string());
|
||||
Ok(def.to_string())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
All the HTML code that has been generated like this is then cached until the next the blog update is triggered by my pushing a new post to git.
|
||||
|
||||
## Styling
|
||||
|
||||
For the styling, I added some minimal CSS to center the contents, limit the width and change the font sizes.\
|
||||
I wanted to keep it simple so the layout works on both a desktop browser, and on mobile phone screens. This also allows you to dock the window to a side of your screen or second vertical monitor in case you wanted to reference it for some code which I find useful.
|
||||
|
||||
## Conclusion
|
||||
|
||||
I like this design as it's easy to deploy locally for previewing, and adding new posts or making edits is as simple as `git commit && git push`. I can keep posts I'm working on in separate branches and progressively work on them like that.
|
||||
|
||||
If you're interested in the source code, or would like to use it for yourself feel free to check it out [here](https://git.bakje.coffee/guus/blog).
|
||||
|
||||
Reference in New Issue
Block a user