andrew

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2024 License: MIT Imports: 13 Imported by: 0

README

andrew

I wanted an http server that allows me to add a simple annotation into an index.html that is replaced with the contents of any html files that are below the current index.html in the file system hierarchy.

It's grown a little to include a small sitemap generator.

To install it

go install github.com/playtechnique/andrew/cmd/andrew

invocation

andrew -h to see the help

andrew accepts up to three arguments, in this order:

andrew [contentRoot] [address] [baseUrl]

contentRoot is the directory you're serving from, that contains your top level index.html. andrew follows apache's lead on expecting index.html in any directory as a default page.

address is the address you want to bind the server to. Specify as an address:port combination.

baseUrl is the hostname you're serving from. This is a part of sitemaps and rss feeds. It contains the protocol e.g. https://playtechnique.io

rendering the .AndrewTableOfContents

Given this file system structure:

index.html
articles/
        index.html
        article-1.html
        article-2.html
        article-2.css
        article-1.js
fanfics/
        index.html
        story-1/
                potter-and-draco.html
        story-2/
                what-if-elves-rode-mice-pt1.html
                what-if-elves-rode-mice-pt2.html

if articles/index.html contains {{ .AndrewTableOfContents }} anywhere, that will be replaced with:

    <a class="andrewtableofcontentslink" id="andrewtableofcontentslink0" href="article-1.html">article 1</a>
    <a class="andrewtableofcontentslink" id="andrewtableofcontentslink1" href="article-2.html">article 2</a>

if fanfics/index.html contains {{ .AndrewTableOfContents }}, that'll be replaced with:

    <a class="andrewtableofcontentslink" id="andrewtableofcontentslink0" href="story-1/potter-and-draco.html">Potter and Draco</a>
    <a class="andrewtableofcontentslink" id="andrewtableofcontentslink1" href="story-2/what-if-elves-rode-mice-pt1.html">what-if-elves-rode-mice-pt1.html</a>
    <a class="andrewtableofcontentslink" id="andrewtableofcontentslink2" href="story-2/what-if-elves-rode-mice-pt1.html">what-if-elves-rode-mice-pt2.html</a>

page titles

If a page contains a <title> element, Andrew picks it up and uses that as the name of a link. If the page does not contain a <title> element, then Andrew will use the file name of that file as the link name.

meta elements

Andrew parses meta tags and makes them accessible on its AndrewPage object.

For a meta element to be picked up, it must be formatted with andrew- prepending the meta element's name, like this <meta name="andrew-<rest of the name>" value="your-value">

valid meta elements

ordering of pages

If a page contains the meta element <meta name=andrew-created-on value="2024-03-12"> in its <head>, Andrew orders on these tags. If the page does not contain the meta element, it uses the mtime of the file to try and determine ordering. This means that if you edit a page that does not contain the andrew-created-on element, then you will push it back to the top of the list.

If your page contains an andrew-created-on meta element, the time must be formatted in accordance with . If your andrew-created-on contains a date but not a time, Andrew assumes the page was created at midnight.

sitemap.xml

When the endpoint baseUrl/sitemap.xml is visited, Andrew will automatically generate a sitemap containing paths to all html pages.

Documentation

Index

Constants

View Source
const (
	AndrewTableOfContentsTemplate = "AndrewTableOfContents"
	DefaultContentRoot            = "."
	DefaultAddress                = ":8080"
	DefaultBaseUrl                = "http://localhost:8080"
)

Variables

This section is empty.

Functions

func BuildAndrewTOCLinks(siblings []Page, startingPage Page) ([]byte, error)

BuildAndrewTOCLinks receives the path to a file, currently normally an index file. It traverses the file system starting at the directory containing that file, finds all html files that are _not_ index.html files and returns them as a list of html links to those pages.

func CheckPageErrors

func CheckPageErrors(err error) (string, int)

CheckPageErrors is a helper function that will convert an error handed into it into the appropriate http error code and a message. If no specific error is found, a 500 is the default value returned.

func GenerateSiteMap

func GenerateSiteMap(f fs.FS, baseUrl string) []byte

Generates and returns a sitemap.xml.

func GetMetaElements added in v0.1.0

func GetMetaElements(htmlContent []byte) (map[string]string, error)

func ListenAndServe

func ListenAndServe(contentRoot fs.FS, address string, hostname string) error

ListenAndServe creates a server in the contentRoot, listening at the address, with links on autogenerated pages to the baseUrl. contentRoot - an fs.FS at some location, whether that's a virtual fs.FS such as an fs.Testfs or an

fs.FS at a location on your file system such as os.DirFS.

contentRoot - an initialised fs.FS. Some implementation details sometimes differ amongst different fs.FS; Andrew internally uses an os.DirFS and tests with an fstest.MapFS, so those two have some code examples herein. address - an ip:port combination. The AndrewServer will bind an http server here. baseUrl - the hostname that you are hosting from.

func Main

func Main(args []string, printDest io.Writer) int

Main is the implementation of main. It's here to get main's logic into a testable package.

func ParseArgs

func ParseArgs(args []string) (string, string, string)

ParseArgs ensures command line arguments override the default settings for a new Andrew server.

Types

type Page added in v0.1.0

type Page struct {
	// Page title
	Title string
	// According to https://datatracker.ietf.org/doc/html/rfc1738#section-3.1, the subsection of a
	// URL after the procol://hostname is the UrlPath.
	UrlPath     string
	Content     string
	PublishTime time.Time
}

Page tracks the content of a specific file and various pieces of metadata about it. The Page makes creating links and serving content convenient, as it lets me offload the parsing of any elements into a constructor, so that when I need to present those elements to an end-user they're easy for me to reason about.

func NewPage added in v0.0.7

func NewPage(server Server, pageUrl string) (Page, error)

NewPage creates a Page from a URL by reading the corresponding file from the AndrewServer's SiteFiles. NewPage does this by reading the page content from disk, then parsing out various metadata that are convenient to have quick access to, such as the page title or the publish time.

func (Page) SetUrlPath added in v0.1.0

func (a Page) SetUrlPath(urlPath string) Page

SetUrlPath updates the UrlPath on a pre-existing Page.

type Server added in v0.1.0

type Server struct {
	SiteFiles                     fs.FS  // The files being served
	BaseUrl                       string // The URL used in any links generated for this website that should contain the hostname.
	Address                       string // IpAddress:Port combo to be served on.
	Andrewtableofcontentstemplate string // The string we're searching for inside a Page that should be replaced with a template. Mightn't belong in the Server.
	HTTPServer                    *http.Server
}

Server holds a reference to the paths in the fs.FS that correspond to each page that should be served. When a URL is requested, Server creates an Page for the file referenced in that URL and then serves the Page.

func NewServer added in v0.1.0

func NewServer(contentRoot fs.FS, address, baseUrl string) *Server

NewServer is a constructor. Its primary role is setting the default andrewtableofcontentstemplate. Returns an Server.

func (*Server) Close added in v0.1.0

func (a *Server) Close() error

func (Server) GetSiblingsAndChildren added in v0.1.0

func (a Server) GetSiblingsAndChildren(pagePath string) ([]Page, error)

GetSiblingsAndChildren accepts a path to a file and a filter function. It infers the directory that the file resides within, and then recurses the Server's fs.FS to return all of the files both in the same directory and further down in the directory structure.

func (*Server) ListenAndServe added in v0.1.0

func (a *Server) ListenAndServe() error

func (Server) Serve added in v0.1.0

func (a Server) Serve(w http.ResponseWriter, r *http.Request)

Serve handles requests for any URL. It checks whether the request is for an index.html page or for anything else (another page, css, javascript etc). If a directory is requested, Serve defaults to finding the index.html page within that directory. Detecting this case for

func (Server) ServeSiteMap added in v0.1.0

func (a Server) ServeSiteMap(w http.ResponseWriter, r *http.Request)

SiteMap

type TagInfo added in v0.1.0

type TagInfo struct {
	Data       string
	Attributes map[string]string
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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