egen

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2024 License: MIT Imports: 30 Imported by: 0

README

egen is an opinionated blog generator. It was created mainly to be used in https://efreitasn.dev. Some of its features are (when the word "must" appears, it means that the blog won't build if the specified condition isn't met):

  • Uses Go templates.
  • Every CSS file present in the <inPath>/assets directory becomes one single minified CSS file called style.css stored in <outPath>/assets. The order of concatenation is alphabetically, which means the content of a file named 1.css will come first in the resulting style.css than the content of a file named a.css, for example.
  • Every file stored in <outPath>/assets is renamed to <filename_base>-<md5sum(file_content)>.<filename_ext>, except JPEG and PNG images.
  • Every JPEG and PNG image file present in the <inPath>/assets directory become a directory in <outPath>/assets whose name is the md5sum of the file. The files in this directory are named <width>.<png|jpg|jpeg>.
  • Every post must have a version for each language provided in the config file.
  • Every image used in a post must have an alt attribute.
  • The icon of the blog is a file located at <inPath>/assets/icon.png.
  • Supports responsive images by the responsiveImgSizes and responsiveImgMediaQueries fields present in the config file. The former is used to generate the srcset attribute and the latter is used as the sizes attribute. From that, egen handles the creation of resized images. All of this behaviour is automatic to any image encountered in a post, but responsive images can also be used outside of a post. This is achieved through the srcSetValue template function and the TemplateData.ResponsiveImgMediaQueries value.

Terms

There are some terms used in egen that need some clarification.

  • TemplateData: a struct received by a template. To see its fields, check this page.
  • GAT: short for global assets tree. It's a tree generated from the <inPath>/assets directory.
  • PAT: short for post assets tree. It's a tree generated for each post from the <inPath>/posts/<post_slug> directory. It's composed of any file whose name doesn't match /(^content_.+\.md$)|(^data\.yaml$)|(^.*/$)/ (when buidling the tree, directory names end with a / when matching against a regular expression).
  • Invisible post: a name for posts whose config file's feed field is set to false. These posts are not present in the list provided in TemplateData and can only be "found" through the getInvisiblePost template function. This type of post serves the purpose of a page in a blog.
  • AssetRelPath: the path of an asset relative to a GAT or a PAT. If the path starts with a /, it's relative to the former, while any other character at the beginning of the string makes it relative to the latter.
  • inPath: the path used as input when building. It's the path that contains the config file.
  • outPath: the path used as output when building.

Config file

The config file is located at <inPath>/egen.yaml. An example of a config file is:

title: foobar
description:
  en: foobar in english
  pt-BR: foobar em português
url: https://foo.bar
color: "#000000"
author:
  name: John Doe
  twitter: jjjjjdoee
langs:
  - tag: en
    name: English
    default: true
  - tag: pt-BR
    name: Português do Brasil
responsiveImgSizes:
  - 425
  - 640
  - 960
  - 1280
responsiveImgMediaQueries: "(max-width: 26.5625em) 100vw, (max-width: 64em) 65vw, 50vw"
latex: true

Functions

These are the functions that can be used in a template:

  • dateISO(d time.Time) string: transforms a time.Time into an ISO 8601 string.
  • getInvisiblePost(l *Lang, slug string) *Post: returns an invisible post (feed: false) given a Lang and the post's slug.
  • assetLink(assetPath AssetRelPath) (string, error): returns the link of an asset given an AssetRelPath.
  • srcSetValue(assetPath AssetRelPath) (string, error): given an AssetRelPath, adds the sizes provided in the config file to the asset and returns a string to be used as the srcset attribute's value.
  • hasAsset(assetPath AssetRelPath) bool: returns whether there's a node in the GAT or the current PAT that has a path equal to assetPath.
  • postLinkBySlugAndLang(slug string, l *Lang) string: given the post's slug and a Lang, returns a link to the post.
  • homeLinkByLang(l *Lang) string: given a Lang, returns a link to the home of the blog.
  • relToAbsLink(link string) string: given a relative link, returns its absolute version.
  • sortPostsByDateDesc(posts []*Post) []*Post: given a list of posts, returns the list sorted by post creation date in descending order.

Posts

A post is located at <inPath>/posts/<post_slug>. The slug is like an ID, i.e. it's a unique string that each post has. Inside this directory, there's a file called data.yaml with the following structure:

feed: true
date: "2019-07-07T21:43:00Z"
lastUpdateDate: "2020-02-19T01:04:33.663Z"
img: /foo.png

img and lastUpdateDate fields are optional.

This directory also contains one or more files named content_<lang_tag>.md. The number of files matching this pattern must be equal to the number of languages provided in the config file. In other words, as said in the beginning, a post must have a version for each specified language. The content file has the following structure:

---
title: First post
excerpt: The first
imgAlt: some
---
content in markdown.

It starts with a YAML frontmatter followed by the post's content in Markdown. The title and excerpt fields are required, while the imgAlt is only required if the img field in the post's data.yaml was specified.

Templates

There are three templates that are required and they're located at: <inPath>/pages/404.html, <inPath>/pages/home.html and <inPath>/pages/post.html. Besides the required templates, there are also arbitrary templates. They are created by placing a file named <template_name>.html at <inPath>/includes. This file shouldn't start with {{ define }} and end with {{ end }}, since the template name is just the file's name and there shouldn't be more than one template per file. As a special case, if there's a template located at <inPath>/includes/head.html, this template is rendered right before the end of the head tag automatically.

<inPath> structure

<inPath> must have the following structure:

assets
includes
  <template_name>.html
pages
  404.html
  post.html
  home.html
posts
  <post_slug>
    content_<lang_tag>.md
    data.yaml
egen.yaml

Code blocks

Code blocks are automatically highlighted using chroma. By default, the style used is the swapoff style. This can be changed by providing a chroma style when calling the Build function.

Examples

package main

import (
	"fmt"
	"os"

	"github.com/efreitasn/egen"
)

func main() {
	err = egen.Build(egen.BuildConfig{
		InPath:  "./content",
		OutPath: "./dist",
	})
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}
}

There are some examples in the testdata directory, such as this one. The efreitasn.dev's repository is also a good example.

Latex

Latex can be enabled by setting latex to true in the config file. Note that Node.js >= v20.11.0 is required for generating latex images.

Documentation

Index

Constants

View Source
const (
	FILENODE assetsTreeNodeType = iota
	DIRNODE
	IMGNODE
)

Node types.

Variables

This section is empty.

Functions

func Build

func Build(bc BuildConfig) error

Build builds the blog.

Types

type AlternateLink struct {
	// URL is a relative URL.
	URL  string
	Lang *Lang
}

AlternateLink is a link to a version of the current page in another language.

type AssetRelPath

type AssetRelPath string

AssetRelPath is the path of an asset relative to the global assets tree (GAT) or to a post assets tree (PAT). The former happens when the path starts with "/", while the latter happens when the path starts with any character other than "/".

type Author

type Author struct {
	Name, Twitter string
}

Author represents an author.

type BuildConfig

type BuildConfig struct {
	InPath, OutPath string
	TemplateFuncs   template.FuncMap
	ChromaStyle     *chroma.Style
}

BuildConfig is the config used to build a blog.

type Img

type Img struct {
	Path AssetRelPath
	Alt  string
}

Img represents the image of the current page/post.

type Lang

type Lang struct {
	Name string
	// The language tag, as in RFC 5646.
	Tag     string
	Default bool
}

Lang represents a language.

type Post

type Post struct {
	Title          string
	Content        template.HTML
	Slug           string
	Excerpt        string
	Img            *Img
	Date           time.Time
	LastUpdateDate time.Time
	Lang           *Lang
	// relative
	URL string
	// contains filtered or unexported fields
}

Post is a post received by a template.

type TemplateData

type TemplateData struct {
	// Page is an identifier for the current page.
	// Home page -> home
	// Posts page -> posts
	Page        string
	Title       string
	Description string
	Author      *Author
	Img         *Img
	Color       string
	// Posts is a list of posts that are visible (feed: true)
	Posts []*Post
	// Post is equal to nil unless page == 'post'
	Post *Post
	Lang *Lang
	// URL is a relative URL.
	URL string
	// AlternateLinks is a list of alternate links to be used in meta tags.
	// It also includes the a link for the current page in the current language.
	AlternateLinks            []*AlternateLink
	ResponsiveImgMediaQueries string
}

TemplateData is the data passed to a template.

Directories

Path Synopsis
internal
latex
Package latex provides latex image generation for egen.
Package latex provides latex image generation for egen.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL