Making My Blog

#Anything is possible… Help!!

# I have been meaning to have 3 websites. What I make. What I like. And what I think. Which basically amounts to a projects gallery, a recommendation museum, and a blog.

# In theory a blog should be the simplest one to create, since people have already made many Hugo themes for that. But I think most blogs look unbearably boring. hugo-theme-papermod

# leonardo-da-vinci-cant-decide… So my absolute need to customize and decorate makes this project less straightforward, and trying to pick an overall aesthetic theme has put me in a state of analysis paralysis for a few months now. Of course since absolutely nothing is actually at stake this problem is hardly stressful, but still… it sure would be nice to make progress. I know how to make things, I just can’t decide what to make! 

#The Magazine Dead-End

# nintendo_power_brandishAt first I toyed with the idea of making it look like a Nintendo Power magazine, and I still like the idea, but I have been flip-flopping on whether to go for it. 

# It turns out that multi-column layouts can very easily become impractical in HTML if the article’s text is too long. With magazine layouts, the text has to be tailored and re-written to exactly the right length to fit inside the page / screen you’re viewing it on, otherwise you’ll end up with lots of tedious scrolling. A long multi-column layout means scrolling down to read the first column and then scrolling all the way back up just to start reading the next column. That’s bad! The whole point is to be able to see the entire article, all at once, without needing to scroll at all! But if you don’t know how big the screen is going to be you cannot design a one-screen layout. In a world where phones exist, every screen is different.

website_columns

# But if I dismiss the Nintendo Power design idea, what can I do instead??

#Random Star Fox Theme

# I know I shouldn’t let my tools do the designing for me, but without any direction I just did some aimless tinkering. Lots of websites look flat, so I wanted a background that conveys depth. A landscape can do that, so as a test I grabbed a background from Star Fox 2 on the Super Nintendo that seemed to have the effect that I wanted. Then I decided, “What the hell, let’s keep that.”

# Unlike my project website, I feel like it’s okay for my blog to present things I didn’t make. After all I will probably use it to talk about my favorite things anyway. So sure… it guess my blog is going to have a Star Fox theme. Why not?

starfox-background-adds-depth

# single-column-blogHaving abandoned the magazine-layout idea, I think I’ll mostly stick with my previous blog layout from my project website, with the content on the left and metadata on the right. A multi-column layout would have filled the entire width of the screen with the content, but stretching a single column across a potentially 4K screen would be uncomfortably wide so I have to limit its width to something that is easy to read and find other things to fill the empty space with. And the only other things that even exist on this blog are the table of contents, and the website’s navigation. 

# But a blog website barely needs any navigation. The entire website is just a single list of articles… and the articles themselves, and maybe a website logo at the top. Honestly the only “navigation” that needs to exist on the actual articles is just a single link back to the list.

# article-footer-linkblog-list

# project-geminiAnd there is something kind of appealing about a web page that contains nothing except content. A pure document. Something designed to seen on its own instead of just being part of a website. I was reminded of this concept when I read about Project Gemini, a deliberately simpler web standard that tries to encourage people to write meaningful documents, with no decorative elements like “hero images.” Just links to things that actually matter. Personally I happen to enjoy showy maximalist designs, but I also appreciate the idea of something being self-contained and useful. 

# Technically there’s no reason why my blog articles even need a website logo. But it is something that people expect to see in order to know which website they are on. The main logo is usually also also a link back to the website’s “home” page. And if nothing else it also acts as a signature showing who wrote the article or where it came from. In my case it can be both.

website-logo

#Panel Cylinders

# angular-panelsSo what should the “panels” of my website look like? I need some kind of background behind my text to “frame” it and give it places to “belong”. Continuing with the Star Fox aesthetic maybe I can use some kind of primitive 3D shape? Thinking back on it now I could have just added simple angular bezels to make things look like floating 3D panels… 

# cylinder-panels… but no I had to be ambitious and turn everything into cylinders! This did lead to some interesting (and successful) experiments. So how can you make something look like a cylinder using CSS? 

# One obvious thing to try are rounded rectangles. Just stretch the curve ALL the way to the middle to create a half-circle. And then use this at the bottom to create an ellipse to show the “bottom” of the cylinder. But… stretched rounded corners don’t quite curve enough at the edges to look “round”.

cylinder-test-1

# Okay if CSS by itself can’t do it right, maybe I can just draw the shapes using SVG vector graphics and then display those pictures on the top and bottom? This makes the CSS simpler and it looks pretty good. But I still have to manually apply the effect to the top and bottom of every single html tag that is supposed to look like this. Yes I can do this entirely in CSS using :before and :after pseudo elements, but it is still extra work.

cylinder-test-2

# border-imageIs there any other way to display a picture at the top and bottom of html elements without doing all that? Actually yes! Border images! Normally this is used to surround something with a decorative border, but it’s possible to just make the sides of your border 0 pixels wide. 

# Yes this makes the CSS much easier! No need to add extra things before or after everything. Now to just add the background gradient and… oh.
Okay right. The border is treated like something “inside” of the element so I guess I need to use some kind of mask to hide the corners.

# cylinder-test-3acylinder-test-3b

# Hmm… setting the clip-path to the SVG itself doesn’t work at all.

cylinder-test-3c

# Alternatively, setting the mask to the SVG doesn’t stretch the same way as the displayed picture does.

cylinder-test-3d

# But there are other ways to define the shape. Maybe I can just use “path()” and copy the SVG shape into it? No that always scales the shape proportionally. I actually want it to stretch!

# Maybe I can use “shape()” and manually draw the vector shape in CSS? Hmm… “arc to” doesn’t quite curve right. Maybe I should use bezier curves instead? Yes “curve to” looks perfect! Now to just add a few more lines of text and… oh. It stretches the width AND the height.

# cylinder-test-3e1cylinder-test-3e2

# Okay maybe I don’t actually need a mask? Maybe I can just vertically shrink the background color so that it doesn’t spill out above and below the curves? I just need to get the size right and… wait why does that look perfect the first time? And why doesn’t changing the measurements actually change the size?

# So, uuuuh… I didn’t actually need to change the size at all. I just needed to tell the background NOT to repeat and it defaults to stretching to fill the text area. Exactly what I needed! Apparently the solution was much simpler than I thought. Just use a border-image to add a top and bottom, and then fill the middle. No masking necessary at all.

# dohcylinder-test-4

# Now everything can look like surreal floating cylinders. One funny side-effect of this is when the table of contents it empty, the CSS still adds the top and bottom around it resulting in a mysterious floating disc. I kinda like it! And since my table of contents sticks to the top when you scroll down the page, this mystery disc will follow you down too! Fun!

# blog-list-cylinderscylinders-table-of-contents

Header Logo

# Let’s dress up the title text of the articles. If I’m using a Star Fox style then how about making them look like the Star Fox title screen?

star-fox-title-screen

# So adding a gradient to text using CSS is kind of a hack. You make the text’s background a gradient, then you make the text itself transparent so only the background is visible, and finally you mask it to the shape of the text.

# That’s a start, but it’s blending into the background. It needs an outline.

# text-gradient-how-totext-gradient-1

# But I’ve painted myself into a corner with the gradient hack. Normally I can add an outline by centering a text shadow and making it really thin, but my text is transparent so the shadow gets drawn on top of the gradient background.

# text-shadow-infotext-shadow-doesnt-work-with-gradients

# Another option is to use -webkit-text-stroke which technically works. But “webkit” features generally only work in Google Chrome and I want this to work on all browsers. Besides, it’s putting the outline along the inside of the text, making it look way too thin. The text is supposed to be bold, so I want to add the outline to the outside.

webkit-text-stroke

# A 3rd option is to use an SVG filter. You can apply features of Scalable Vector Graphics to other parts of a web page. And SVG files can do things that regular CSS can’t.

# svg-filter-text-outline-researchsvg-filter-text-outline-testsvg-filter-text-outline-result

#Signature

# plain-text-signatureThis Mainframe font fits the whole Star Fox theme perfectly, but how can I make my signature look more interesting? 

# Wait… I have an idea.

pilot-window-starfox

# pilot-style-signaturePerfect! 

#License

# Back in 2019, Europe passed Article 13 which forced search engines to hide everything on the internet that had no license information stapled to it.

# So I rolled my eyes and added permissive licenses to every square inch of my website so that people in Europe might possibly be “allowed” to see it… nevermind that their government probably blocks all my unconventional porn anyway.

# My point is… like everything on my site I wanted to make it actually look nice instead of just vomiting terms and conditions™ like everyone else does. So this design just quickly says some stuff and gets the hell out of the way as fast as possible… it’s also collapsed by default.

# I stole the whole “can” “cannot” “must” design from some open source copy-left website or something. Too bad I can’t remember where it was.

# licenselicense-collapsed


#Nearly Ready

# Okay, I have styled all the text and designed all of the widgets and things. Every shortcode widget has a general design. Although I still need to polish up the “artist recommendation” a little more. The existing blog articles should copy over seamlessly… with a few changes, because I changed my mind about how I want to write {{ <shortcode> }} tags and whisper text. A few years ago I planned for that old markdown to be future-proof but I guess I just can’t leave well enough alone.

# Meanwhile I finished adding the Sorting buttons to the list of blogs, along with a random quote thingie at the bottom. This blog website’s theoretically done and ready to upload… right?

# Okay sure but… how do I add NEW articles to it??

# With my regular website I would add blog articles using my custom website editor… which only runs in Windows. I need to figure out a way to manage this thing purely in Linux. Sure I could just manually put together a markdown file and paste some boilerplate frontmatter at the top. But one goal of my Linux transition is to make things just as easy as they were in Windows. No compromises!

# I spent a few hours today trying out a few text editors to see what plugins and tools they have. It looks like Obsidian handles front-matter surprisingly well! It’ll even keep track of previously used tags for me. So all I really need is a Hugo archetype to create new blog articles with front-matter boilerplate.

obsidian-handles-front-matter-well

# … and a keyboard shortcut to write the current date in the funky ISO standard that Hugo likes. Using a program called xdotool. Beyond that I just want to write some Hugo stuff to generate metadata and opengraph stuff for each page’s header. I could technically skip that stuff but I’m kind of a perfectionist when it comes to writing good HTML.

date-typing-shortcut

#A Dash of JSON

# heavy-rain-jasonThis sucker’s just about ready to go live, but I want to add one last extra-nerdy feature. JSON metadata. A bit of invisible data stored inside the top of every page in my blog that describes exactly what that page is about using a standard machine-readable format. It’s theoretically helpful for search engines. 

# hugo-scratch-set-get-addConstructing raw data in Hugo kind of sucks… at least if you try to follow most tutorials. Hugo’s “scratch” object tries to make it easier to append variables by using Get and Set but it completely falls apart the second you try to add another object inside of it. 

# hugo-appending-variables-sucks…And trying to add new variables into an existing object (what Hugo calls a “Dict”) is miraculously much worse! You basically have to generate a new object in-line with a single variable inside of it and then merge it with another existing object. It makes really wish I could just use JavaScript’s simple dot notation instead. Hugo doesn’t have it, and I miss it SO BAD!! 

# HOWEVER … I found a much better way to put together data for JSON. Instead of trying to add variables to an empty dict object, I’ll define the new dict object with all the variables already inside it. The trick is that you don’t have to write the entire thing on one line the way Hugo’s documentation shows you. It turns out that are actually allowed to add line-breaks ANYWHERE in the middle it! Which means… you can define each of its variables on its own line just like making an object in JavaScript. If I need to nest another object I’ll define it separately as another dict object and then assign it to one of the variables of the main object… and afterwards use | jsonify | safejs to turn the entire thing into JSON.

hugo-writing-json

# hugo-json-stepsBut generating JSON is not enough. I don’t just want it in the head of the page, I also want to store at in a separate JSON file. For hours and hours I tried and failed to figure this out. But eventually this article came to my rescue and showed me exactly what a working example looks like. 

# hugo-config-to-make-json-filesThere are 2 steps. Step 1) You have to add these magic words to Hugo’s config file. The article explains what they actually mean. 

# hugo-json-layoutStep 2) Add a layout file named after the “outputFormat” you just created. In this case I needed to name it “metadata.json”. And inside that file you create your data and convert it info JSON using | jsonify | safejs 

# … and the result is that HUGO will finally spit out JSON files next to each of your pages. Yeah I know nobody cares about doing this, but it was such a hard problem to solve that I just had to write the answer on the internet somewhere. So here it is… some poor web developer out there will find the answer that saves them… on this freakin’ porn blog! 😈

hugo-json-result

#Abstracting Away the Short-Codes

# Let’s spare my Mastodon audience. I’ve dumped more than enough nerd junk on my porn blog for one month. So let’s continue this here on my website instead.

# Hugo has funky short-codes. They’re not standard. No program on planet Earth understands them. And I don’t want my blog to be permanently married to Hugo. So instead I’ll represent them as custom XML tags and then convert those into shortcodes before running Hugo.

# I’ve written about this concept before .

# replace-using-hugoReplacing text in HugoBut I made a mistake last time. With my project website I used Hugo to convert the shortcodes using find-and-replace… on… everything! And that created massive slow-down! We’re talking over half an hour to build the website. 

#Replacing Text Slows Down HUGO


{{/* Load the .Content file,  remove the front-matter */}}
{{ $tempPath := (path.Join .this.File.Dir .file) }}
{{ $temp := $tempPath | readFile | replaceRE "^---[\\s\\S]+?---" "" }}

{{/* Convert xml tags into shortcodes */}}
{{ $temp = replace $temp `<codeFile` `{{<codeFile` | replaceRE `</codeFile>` `}}{{</codeFile>}}` }}
{{ $temp = replace $temp `<imgSource` `{{<imgSource` | replaceRE `</imgSource>` `}}{{</imgSource>}}` }}
{{ $temp = replace $temp `<imageSources>` `{{<imageSources>}}` | replaceRE `</imageSources>` `{{</imageSources>}}` }}
{{ $temp = replace $temp `<musicSrc` `{{<musicSrc` | replaceRE `</musicSrc>` `}}{{</musicSrc>}}` }}
{{ $temp = replace $temp `<musicSources>` `{{<musicSources>}}` | replaceRE `</musicSources>` `{{</musicSources>}}` }}
{{ $temp = replace $temp `<markdownFile` `{{<markdownFile` | replaceRE `</markdownFile>` `}}{{</markdownFile>}}` }}
{{ $temp = replace $temp `<textFile` `{{<textFile` | replaceRE `</textFile>` `}}{{</textFile>}}` }}
{{ $temp = replace $temp `<contact` `{{<contact` | replaceRE `</contact>` `}}{{</contact>}}` }}
{{ $temp = replace $temp `<date` `{{<date` | replaceRE `</date>` `}}{{</date>}}` }}
{{ $temp = replace $temp `<video` `{{<video` | replaceRE `</video>` `}}{{</video>}}` }}
{{ $temp = replace $temp `<embed` `{{<embed` | replaceRE `</embed>` `}}{{</embed>}}` }}
{{ $temp = replace $temp `<flashVideo` `{{<flashVideo` | replaceRE `</flashVideo>` `}}{{</flashVideo>}}` }}
{{ $temp = replace $temp `<project>` `{{<project>}}` | replaceRE `</project>` `{{</project>}}` }}
{{ $temp = replace $temp `<currentFilters` `{{<currentFilters` | replaceRE `</currentFilters>` `}}{{</currentFilters>}}` }}
{{ $temp = replace $temp `<backButton` `{{<backButton` | replaceRE `</backButton>` `}}{{</backButton>}}` }}
{{ $temp = replace $temp `<filterToggle` `{{<filterToggle` | replaceRE `</filterToggle>` `}}{{</filterToggle>}}` }}
{{ $temp = replace $temp `<adBlockContentFilter` `{{<adBlockContentFilter` | replaceRE `</adBlockContentFilter>` `}}{{</adBlockContentFilter>}}` }}
{{ $temp = replace $temp `<defaultFilters>` `{{<defaultFilters>}}` | replaceRE `</defaultFilters>` `{{</defaultFilters>}}` }}


{{/* Convert to HTML */}}
{{ $temp = .this.RenderString $temp }}

{{/* Unwrap standalone videos */}}
{{ $temp = replace $temp `<p><video` `<video` | replaceRE `</video></p>` `</video>` }}

{{/* Unwrap embed */}}
{{ $temp = replace $temp `<p><embed` `<embed` | replaceRE `</embed></p>` `</embed>` }}

{{/* Add anchors to paragraphs */}}
{{ $ret := split $temp "<p>" }}
{{ range $index, $this := $ret }}
	{{ if ne $index 0 }}
		<p>
		<a id="para-{{ $index }}" href="#para-{{ $index }}" class="anchor">#</a>
	{{end}}
	{{ $this | safeHTML }}
{{ end }}

# Thinking back on this I have realized I only need to perform the find-and-replace on an as-needed basis. If I modify one article, I just can replace the text in that one article. The rest of the articles can stay the way they already are. And since I already store 2 copies of every article as content.md and index.md, I can do this conversion when I generate the index.md file.

# In other words. I’ll write my blogs in content.md markdown files. Generate an index.md file from it. And then feed that into Hugo. The content files remain platform agnostic. And the index files are specifically for Hugo.

# But, um… how do I actually do that??

# If I don’t want to use Hugo I’ll have to use something else to perform the find-and-replace on these files. Fortunately this was figured out a million years ago in the 1950’s. Replacing text is an ancient programming problem that has already been solved multiple times over.

# sed-tutorialI decided to use the sed command. Long story short I made a .desktop file that I can drag-and-drop a content.md markdown file onto, and it’ll feed it into a bash script that will run sed a bunch of times and spit out an index.md markdown file next to it. 

# Download Example Files

#Desktop file


#!/usr/bin/env xdg-open
[Desktop Entry]
Encoding=UTF-8
Type=Application
Exec=bash -c "\\"/mnt/documents/www/blog2/Utilities/convert shortcodes/run.sh\\" %U; read"
Name[en_US]=drop-desktop-file
Hidden=false
Icon=/usr/share/icons/gnome/256x256/mimetypes/exec.png
Terminal=true



#Shell Script


#!/bin/bash
###############################################################################
#                                                                             #
# This script replaces XML codes with HUGO shortcodes and then outputs        #
# the result as a new file named "index.md" in the same folder as             #
# the source file.                                                            #
#                                                                             #
# Drag and drop a markdown file onto one of the .desktop files in this folder #
# index.md will appear next to the original file that you dragged.            #
# The original file will remain unchanged.                                    #
#                                                                             #
###############################################################################


# Check for input file
if [ ! -f "$1" ]; then
  echo No file was dropped onto this Desktop file.
  exit 1
fi
if [[ "$1" == *"index.md"* ]]; then
  echo You dropped the index.md on here file by accident!
  exit 1
fi
input="$1"


# Create a temp file
temp=$(mktemp)
cp "$input" "$temp"


# Replace text
# sed -i 's/oldtext/newtext/g' "$temp"

# <codeFile src="file.txt"></codeFile>
sed -i 's/<codeFile/{{<codeFile/g' "$temp"
sed -i 's/"><\/codeFile>/">}}{{<\/codeFile>}}/g' "$temp"

# <imgSource src="inspiration2.jpg" artist="Merunyaa" url="https://twitter.com/meru_nyaa/status/961455638382612480" text="Inspiration" caption="What_a_view"></imgSource>
sed -i 's/<imgSource/{{<imgSource/g' "$temp"
sed -i 's/><\/imgSource>/>}}{{<\/imgSource>}}/g' "$temp"

# <markdownFile src="file.md"></markdownFile>
sed -i 's/<markdownFile/{{<markdownFile/g' "$temp"
sed -i 's/><\/markdownFile>/>}}{{<\/markdownFile>}}/g' "$temp"

# <textFile src="file.txt"></textFile>
sed -i 's/<textFile/{{<textFile/g' "$temp"
sed -i 's/><\/textFile>/>}}{{<\/textFile>}}/g' "$temp"

# <date></date>
sed -i 's/<date><\/date>/{{<date>}}{{<\/date>}}/g' "$temp"

# <video src="file.mp4" controls="controls" autoplay="autoplay" loop="loop" muted="muted"></video>
sed -i 's/<video/{{<video/g' "$temp"
sed -i 's/><\/video>/>}}{{<\/video>}}/g' "$temp"

# <project>[Project name](/makes/games/platformer/)</project>
sed -i 's/<project>/{{<project>}}/g' "$temp"
sed -i 's/<\/project>/{{<\/project>}}/g' "$temp"

# convert *&nbsp;* into *&#32;*
sed -i 's/\*\&nbsp\;\*/\*\&\#32\;\*/g' "$temp"


# Copy the new modified file to the destination
outfolder=$(dirname "$input")
if [ -d "$outfolder" ]; then
  cp "$temp" "$outfolder/index.md"
fi


#######################################################
# Wait for me to debug the results
echo Done!  Press ENTER to continue
#read


# Delete temp file
if [ -f "$temp" ]; then
  rm "$temp"
fi


# End program
exit 0




drag-and-drop-text-replacement-script

#Uploading is Easy

# sftp_in_linuxThe last piece of the puzzle is uploading the website. This is ridiculously easy in Linux. I can mount a website like a USB drive. It’s built-in! No programs necessary. Just tell the explorer to connect to your website using SFTP and the website’s folder appears on your desktop. Uploading files is just drag and drop. I’ll just make a clickable icon that does this. 

# In the past I would have used WinSCP in Windows. In Linux I’ll probably use rsync to automatically add any missing files.

#Permission Hell

# didnt-say-the-magic-wordThe only drawback to connecting to a website natively in Linux is that file access permissions carry over. Which means you suddenly have to start paying attention to them, which is always a pain in the ass. If you’re not careful you might copy a bunch of files, only for the web server to not have permission to read them. 

server-permission-error

# permission-settingsAfter trying and seemingly failing to set “default” permissions on Hugo’s “public” folder using setfacl, I instead just used chmod to set basic permissions on the entire Hugo folder, and then ran Hugo to generate a completely new website in the “public” folder, which is inside the Hugo folder. My theory being that maybe Hugo was carrying over the existing permissions of the source files? Anyway, the results seemed to be good enough. 

# Connecting directly in Linux is a cool trick, but I think for most people I would recommend using Filezilla so they don’t have to think about permissions. It’ll just work. Personally I’ll keep using the direct connection because I am tying to learn Linux, and making this website is part of how I’m getting myself accustomed to its quirks. I don’t want to dodge problems, I want to overcome them.

https://filezilla-project.org

#Magazine Layouts Are Still a Possibility

# I think I’ll go with this Star Fox style for now. But I might re-attempt some magazine style layouts someday later. It still seems theoretically possible to make a layout like a Nintendo Power magazine if I design around a minimum width and height, and just gracefully fall back to a boring “mobile” stacked design if the device has a tiny screen.

# I recently mentioned this to my mother and she reminded me that she used to be a professional graphic designer who literally designed magazines for a living, and then proceeded to hand me this massive book all about the subject. If I ever get stuck, I’ll just ask the 70 year old professional I happen to live with.