Posts preview
Add post preview for OpenGraph cards
Table of Contents
What is imagemagick
Imagemagick is a ffmpeg of the image world. You can do a lot of fun things with it. For example you can take a picture, cut corners on it, place it on top of another image, add some text and get final result. So it is looks like a good tool for making previews from code.
Basic idea of this process
I want to hook a process of rendering post. Since this function called on each run of publishing and for each post it is a good idea to cache resulting images. I gonna simply check presence of preview image and use it as guard for running image generation. After that I gonna extract #+TITLE
and #+DESCRIPTION
properties from Org file. Each Org file I have, has next header:
#+TITLE: Posts preview
#+DATE: <2024-06-28 Fri>
#+DESCRIPTION: Add post preview for OpenGraph cards
#+TAGS: @blogging @org-mode @elisp @imagemagick
So I with all these data I can generate my previews with simple script:
#!/bin/bash
magick $4/with_profile.png \
\( -size 850x150 \-background none -font Roboto-Regular -fill '#FEFEFE' label:"$1" -trim -gravity center -extent 850x150 \) \
-gravity northeast -geometry +50+75 -composite /tmp/text_main.png
magick /tmp/text_main.png \( -size 1100x300 -background none -font Roboto-Regular -pointsize 50 -fill '#FFFFFF' pango:"$2" -trim -gravity center -extent 1100x300 \) -gravity east -geometry +40+140 -composite "$3"
#
Integrate into build
As I already mention I gonna skip file generation when file already here. Here is the whole function. Pretty simple. Just prepare pathes, check some dependencies, create pathes and execute script which calls imagemagick.
(defun my/render-preview (file-name title description)
(let* ((has-imagemagick (executable-find "magick"))
(full-file-path (file-truename(format "%s%s/resources/images/preview/%s.png" script-directory my/blog-src-path file-name )))
(file-dir (file-name-directory full-file-path))
(has-dir (file-directory-p file-dir))
(has-file (file-exists-p full-file-path))
(path-to-script-root (format "%shelpers" script-directory))
(path-to-script (format "%s/og_image_gen.sh" path-to-script-root)))
(if (and has-imagemagick
(and description (not (string= description ""))))
(progn
(when (not has-file)
(progn
(when (not has-dir)
(make-directory file-dir t))
(shell-command (format "bash '%s' '%s' '%s' '%s' '%s'" path-to-script title description full-file-path path-to-script-root))
)
))
(message "Imagemagick is not installed. Preview generation skipped.")
)))
And here is the part of my/template
function related to OpenGraph meta tags.
(defun my/template (contents info)
(let* ((title-str (org-export-data (plist-get info :title) info))
(description-str (org-export-data (plist-get info :description) info))
(file-path-str (org-export-data (plist-get info :input-file) info))
(base-directory-str (org-export-data (plist-get info :base-directory) info))
(file-name-str (file-relative-name file-path-str (format "%s/%s" script-directory base-directory-str)))
(img-link-str (format "%s/resources/images/preview/%s.png" my/url file-name-str))
(my/render-preview file-name-str title-str description-str)
(set-text-properties 0 (length title-str) nil title-str)
(set-text-properties 0 (length description-str) nil description-str)
(set-text-properties 0 (length img-link-str) nil img-link-str)
...
;; OG block
(meta ((name . "description") (content . ,description-str)))
(meta ((name . "og:description") (content . ,description-str)))
(meta ((name . "twitter:description") (content . ,description-str)))
(meta ((name . "og:image") (content . ,img-link-str)))
(meta ((name . "twitter:image") (content . ,img-link-str)))
(meta ((name . "og:title") (content . ,title-str)))
(meta ((name . "twitter:title") (content . ,title-str)))
(meta ((name . "twitter:card") (content . "summary_large_image")))
You can check whole function in previous post Improve code blocks.
Whats next?
Tags
Show tags, show posts by tag. Blog index and tags automation
Post series
Dunno how, but I'll figure out something.
Adopt/fix htmlize.el
I want to highlight code during publishing step.
Show more meta on posts index page.
Creation date, preview, tags, whatever. Blog index and tags automation