π΄ jdcard
Spartan is much simpler than markdown so it doesn't make sense to edit posts in markdown and then convert them to gemtext (like bashblog does to create HTML). We'll just write blog posts directly as new gemtext files in ~/public_spartan/blog/ and create a cgi executable called sblog in ~/public_spartan to build an index page for the blog on the fly.
Here's what it might look like:
-------------------------------------------------------------------------------
# Blog Title ## This Is My New Post I'm thrilled to have a new, simpler way to produce a blog. tags: #new #blog #simple-is-better ## All posts: => are-we-done-yet.gmi 2022-07-10 17:04 - Are We Done Yet? > tags: #older #blog #simple-is-better => have-you-seen-this-before.gmi 2022-07-11 11:04 - Have you seen this before? > tags: #improved #blog #simple-is-better => this-is-my-new-post.gmi 2022-07-12 17:04 - This Is My New Post > tags: #older #blog #simple-is-better => youll-never-guess.gmi 2022-07-13 11:01 - You'll Never Guess! > tags: #old #blog #simple-is-better
-------------------------------------------------------------------------------
Now that I have some working code I realize that some of the "requirements" above may be unrealistic.
The date processing doesn't work as I hoped it would. It can only read the mtime from the files, rather than the crtime, so we can only show the time the post was last modified, rather than when it was created. In most cases there will be little or no difference between the two timestamps.
A more significant issue is that the server reports the time using UTC rather than the local time zone specified in the user's LOCALE. It becomes obvious when running the script from the command line and comparing the timestamps to what the server sends back to a remote client. This issue may become annoying enough for me to figure out how to fix it.
I'm using the same code (with the appropriate one-line modification to the protocol-specific header) for both the Spartan server and the Gemini server.
The Gemini mirror of the blog (last update 2022-07-20)
I've decided that, at least for my blog, I want to include a date line that specifies when the post was created and when it was last edited. The creation date is easy because the helper script inserts it automatically. However, I don't know how to automatically insert a datesamp using my usual editing tools, so it remains to be seen how effective the last-edit field will be as I actually use the blog. I still consider the date-line an optional feature. I tried placing it just under the title line, but decided that I like it better just above the tags line at the bottom.
Here's the initial blog index script:
#!/usr/bin/env sh # sblog - display the most recent blog post plus links to all older ones # Each post will have its title as the first line in the file: # This Is My New Post # Each post will have a tags line as the final line of the file: tags: #this-is-a-tag, #anotherTag # All blog posts are in a single (sub)directory and are the only .gmi files in that directory ############################################################################### ## W A R N I N G ! ## ## The method used to sort and list the blog posts will only work reliably ## ## if their file names DO NOT include spaces or punctuation (except "-" ## ## or "."). Letters and numbers are OK. Do not use this script in cases ## ## where users are permitted to create non-conforming file names. ## ############################################################################### # where are the blog files (absolute path, from root) fpath="/home/_USER_/public_spartan/blog" # send the Spartan header printf "2 text/gemini\r\n" # Transmit the blog's title. printf "# This Blog Needs A Title\n\n" # find the newest file in the blog directory (mtime) newpost="$(find $fpath -type f -name "*.gmi" -print0 | xargs -r -0 ls -1 -t | head -1)" # display the newest post cat "$newpost" # ToDo: test if variable is set and if file exists printf "\n========================================\n" printf "=> blog/%s Direct link to this post\n" "${newpost##*/}" # print permalink line; strip off the path, leaving just the file name printf "========================================\n" printf "\n## All posts:\n\n" # build links to all the posts for fname in $(ls -t $fpath/*.gmi); do # using ls here is suboptimal, but we're controlling the file names via the "bp" helper script fdate="$(stat -c '%x' "$fname")" # %x is modified-date; %w is creation date, but that does not work on the tilde.team server. fdate="${fdate%:*}" # truncate everything following the final ":" to trim the seconds off the end of the string title="$(head -n 1 "$fname")" # grab the title line at the top of the file title="${title##*#}" # trim the leading "#" character(s) from the line tags="$(tail -n 1 "$fname")" # get the tags list from the bottom of the file printf "=> blog/%s %s - %s\n" "${fname##*/}" "$fdate" "$title" # print the link line; strip off the path, leaving just the file name printf "> %s\n\n" "$tags" # print the tags line and add an extra newline to separate each record done
I've also written a helper script that creates a new file in the ~/public_spartan/blog directory and populates it with a template for a new post, then it opens the file using $EDITOR for editing. Once the editor is closed, the script displays the content of the post for a final review. Here is what it currently looks like:
#!/usr/bin/bash # bp - a Spartan blog helper to create a new blog post # CONFIGURATION # Where is the blog directory? blogdir="$HOME/public_spartan/blog" # What e-mail address should blog comments go to? email="james@jdcard.com" fname=$(date -Iminutes) # get current date and time cdate="${fname/T/ }" # capture file creation date for use in the post text mail="mailto:$email?subject=Your%20Blog%20Post%20-%20${fname/:/-}" # Remove ":" character from URL fname="${fname%-*}.gmi" # create a name for the file; # Create the new file. printf "## .\n\n.\n\n=> %s π§Comment on this post (via e-mail)\nπ c: %s βοΈ e: \ntags: #new\n" "${mail%-*}" "${cdate%-*}" >> "$blogdir/$fname" # Verify that the file was created? No, if the editor opens an empty file it will be obvious something is wrong. echo "New post is at: $blogdir/$fname" # This makes it easy to re-edit the file if you need to. # Edit the new post "$EDITOR" "$blogdir/$fname" # ToDo: check whether $EDITOR is set? # Display the result so you can review it for errors. cat "$blogdir/$fname"
Finally, a blog post edit script that helps record the time the file was edited, and very importantly, adjusts file's mtime datestamp in the filesystem so that our blog indexer keeps things sorted by creation date.
#!/usr/bin/bash # be - a Spartan blog helper to edit an existing blog post # EXPECTS these command arguments # fname - filename of the post to be edited fname="$1" edtime=$(date -Iminutes) # get current date and time edtime="${edtime%-*}" # trim off the timezone offset edtime="${edtime/T/ }" # remove the "T" field separator if [ -e "$fname" ]; then echo "Editing $fname at $edtime" else echo "Error: file \"$1\" does not exist. Check the path and filename." exit fi # Find the file creation date recorded in the file itself (this will break easily if the date line has been edited improperly) fdate="$(grep "π c: " "$fname")" # retrieve the date line from the post fdate="${fdate:5:16}" # slice out the file creation date # Append the current edit time to the end of the file. Make it ugly and obvious to make sure it gets incorporated during the editing process.. printf "\n## TIME LASTED EDITED: %s MOVE THIS VALUE TO THE DATE LINE ABOVE\n" "$edtime" >> "$fname" # Edit the post "$EDITOR" "$fname" # ToDo: check whether $EDITOR is set? # Display the result so you can review it for errors. cat "$fname" # Restore the file date so that our date indexing (in sblog/gblog) will still work. printf "===================\nFixing file date...\n===================\n" touch -d "$fdate" "$fname" echo "Verify that the file date shown below matches \"$fdate\"." ls -l "$fname"
The scripts need a bunch of error-proofing, but they are functional at this stage.
β
Β©2022 π π ―ππ Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
β―