Without using SEO tags to serve metadata for social media, links will appear plainly and without much to draw the eye. I wanted to change how my blog post presents on social media, so I searched for how to add SEO tags to my existing blog. Since my blog is built on GitHub Pages and thus uses Jekyll, I was able to install the jekyll-seo-tag
plugin. Here’s how.
In the Gemfile
of the Jekyll project add the following line:
gem 'jekyll-seo-tag'
The Gemfile
is used when testing my blog locally using bundle exec jekyll serve
.
In the _config.yml
of the project, find the plugins_dir
section and add the following line:
- jekyll-seo-tag
A GitHub Actions workflow will execute builds and include the jekyll-seo-tag
plugin now configured in _config.yml
when generating the static assets during the build process.
My blog is a fork of gh-pages-blog. jekyll-seo-tag
requires frontmatter to be added to two files, located in the _includes/head
directory. I simply added the following frontmatter expression in the <head>
tags of page.html
(which represents the parent blog) and post.html
(which represents any individual post):
{ % seo % }
NOTE I added spaces on either side of the Liquid expression (the braces and percent symbol) to avoid Jekyll from replacing it with the SEO data it generates during the build process of the blog. Check out more about static files from Jekyll.
After this change in the static files, I am now able to add an image
property to any post to specify a social card. Any post without a value for image
will use a default social card, which is also the card used for the parent blog. Posts are written in Markdown (GFM) and the property values are written in a comment header. An example below is how Jekyll knows what to call this post.
---
layout : post
title : Using the jekyll-seo-tag plugin
category : social
image : "/seo/2022-01-11.png"
---
I put all this together thanks to this very helpful blog post from Meagan Waller.
These pages are useful for testing meta tags:
Swagger is a suite of tools to generate and represent RESTful APIs. It promotes the OpenAPI 2.0 spec which describes an API using JSON representation in a specification file called swagger.json
. Since YAML is a superset of JSON, the specification file can conform to YAML.
In my projects, I want to be able to generate swagger.json
from an annotated codebase to serve using Swagger UI.
go-swagger
is a CLI tool. The following is an example command for generating a Swagger spec
swagger generate spec -o ./swagger.json
Based on the installation docs Swagger UI can be served as part of an application using plain HTML/CSS/JS.
The folder /dist
includes all the HTML, CSS and JS files needed to run SwaggerUI on a static website or CMS, without requiring NPM.
/dist
folder to your server.index.html
in your HTML editor and replace “««««https://petstore.swagger.io/v2/swagger.json”»»»» with the URL for your OpenAPI 3.0 spec.Reading and writing code is a big part of my daily life and the opportunity to put things together in Go is a fun break from the enterprise application development I do at C Spire. Swagger UI is a tool we use in our Spring/Spring Boot applications to easily share our API documentation with each other and the teams which integrate with us. This post is my personal documentation for how to integrate a tool I know and love in a new programming language.
u := config.AuthCodeURL(oauthState)
prepares the URL, a call to http.Redirect()
accepts u
and the server redirects the browser).r.FormValue("code")
) via the redirection URL provided in step 1.Download the oauth2 library for import.
go get golang.org/x/oauth2
The app structure I followed is pretty simple:
main.go
use net/http
to start a servermain.go
package main
import (
"fmt"
"log"
"net/http"
"foundry-automations/handlers"
)
func main() {
server := &http.Server{
Addr: fmt.Sprintf(":8000"),
Handler: handlers.New(),
}
log.Printf("Starting HTTP Server. Listening at %q", server.Addr)
if err := server.ListenAndServe(); err != http.ErrServerClosed {
log.Printf("%v", err)
} else {
log.Println("Server closed!")
}
}
/handlers
and add two .go filesbase.go
<service>.go
where <service>
is a meaningful representation of the authorization server you are relying on (e.g., google apis)In base.go
create func New() http.Handler {}
and set up a mux
with two handlers, "/auth/<service>/login"
and "/auth/<service>/callback"
, then return mux
. The helper functions passed as the second argument of mux.HandleFunc
will live in your <service>.go
implementation
base.go
package handlers
import (
{
"net/http"
)
func New() http.Handler {
mux := http.NewServeMux()
// Root
mux.Handle("/", http.FileServer(http.Dir("templates/")))
// // OauthGoogle
// mux.HandleFunc("/auth/google/login", oauthGoogleLogin)
// mux.HandleFunc("/auth/google/callback", oauthGoogleCallback)
mux.HandleFunc("/auth/pco/login", pcoLogin)
mux.HandleFunc("/auth/pco/callback", pcoCallback)
return mux
}
}
I am continuing to learn more about Go and its history.
The language follows idioms.
One of the most important aspects of my job is writing meaningful error messages. It’s something a lot of people don’t ever stop to consider: where do error messages come from?
Software developers create tools used by others and by nature of the broad interconnected tooling systems in computers and the internet at-large it cannot be difficult to imagine how collaboration is vitally important. Error messaging is how a software developer communicates with their users about expected and unexpected behavior. I believe that software which does not provide meaningful error messages (here’s what went wrong, here’s how to fix it) is not well-written software.
Error handling is a fundamental skill for software engineering.
Review the following go
packages for an example of returning an error. Source from golang.org
greetings.go
package greetings
import (
"errors"
"fmt"
)
// Hello returns a greeting for the named person.
func Hello(name string) (string, error) {
// If no name was given, return an error with a message.
if name == "" {
return "", errors.New("empty name")
}
// If a name was received, return a value that embeds the name
// in a greeting message.
message := fmt.Sprintf("Hi, %v. Welcome!", name)
return message, nil
}
main.go
package main
import (
"fmt"
"log"
"example.com/greetings"
)
func main() {
// Set properties of the predefined Logger, including
// the log entry prefix and a flag to disable printing
// the time, source file, and line number.
log.SetPrefix("greetings: ")
log.SetFlags(0)
// Request a greeting message.
message, err := greetings.Hello("")
// If an error was returned, print it to the console and
// exit the program.
if err != nil {
log.Fatal(err)
}
// If no error was returned, print the returned message
// to the console.
fmt.Println(message)
}
log
and errors
packages are golang builtinserrors.New(UNEXPECTED_ERROR)
or errors.New(EXTERNAL_SERVICE_ERROR)
however Go does not support this pattern since it alternates between camelCase and PascalCase to denote variables which are global to a file vs. global to a package (respectively)I’m working on some automation tasks and will be using golang to consume a RESTful API and generate reports on data. I’ve already had vscode installed on my personal computer but I also had a few things to do to get my environment set up for learning and iterating. For my full-time job I work using Mac OS and my PC is a Windows machine for gaming; this is the first blog post I’ve written from my PC!
Through the powerful features offered by the git version control system (VCS) I will be able to keep a public log of my golang areas of interest as well as use private repositories to solve problems and complete tasks. I installed Git for Windows with the option to also install git bash for Windows. I’m interested in seeing how compatible all of this is with the Windows Subsystem for Linux – which I love using!
I added a new public repo called hello-go where I will document some of the tutorial code I find in a place where I can play around with it.
I also added a new private repo for code related to my automation task.
C Spire Business is bringing back its premier tech event Bytes & Bites in Birmingham, AL (and beyond!) on 21 October 2021. If you’re a business or IT leader register now for this free event.