Hello, World. This is a reboot of my personal page. I've learned a couple things since I last sunk effort into building a site.
- This doesn't have to be difficult
- If you actually want to write, don't make it difficult to write for your site
- You don't need javascript
- You don't need a framework to generate text files
- You don't need javascript to make something usable
- You don't need a spa
- You don't need analytics
- Simplicity is fun
So what you see here are the fruits of a "back to basics" approach to static sites. I'm not sure when I came to this realization, maybe it's maturity, maybe it's experience, maybe it's javascript induced burnout maybe it's some combination of all three. Either way, The code isn't generic, the code isn't well thought out, the code isn't informed by any other framework. It's organic, and I'm doing it for the "fun of it". If the code sucks, maybe I'll fix it, maybe I won't, but here, I guess there's no pressure.
This post is your introduction to a new, improved (?arguably?, ?maybe?, ?maybe not?)
beeceej.com.
First,
the code is open source, and can be found on github.
and second, here's my workflow:
λ cd output
λ python -m http.server &
λ cd ..
# Edit/Add Content, Edit/Add Templates
λ make clean all
# Open browser to localhost:8000/about.html
# verify updates and repeat the workflow.
That's all there is to it, it's simple it's quick, it's easy. The build process is reasonably easy too.
Ensures the output directory exists
path := filepath.Dir(os.Args[1])
if err := os.MkdirAll(path, 0755); err != nil && !os.IsExist(err) {
panic(err.Error())
}
looks up the RenderData for the path provided
renderData, exists := templates[path]
if !exists {
return nil
}
lazy loads content (For example, this post itself.) and set it on the current RenderData
func augmentRenderData(d *RenderData) error {
if d == nil {
return fmt.Errorf("render data is nil")
}
if d.ContentPagePath != "" {
f, err := os.Open(d.ContentPagePath)
if err != nil {
return err
}
b, err := ioutil.ReadAll(f)
if err != nil {
return err
}
postData := d.Other.(Post)
postData.Content = template.HTML(string(b))
d.Other = postData
}
return nil
}
// ...
// ...
func makeOutputFile(path string) error {
// ...
// ...
if err = augmentRenderData(&renderData); err != nil {
return err
}
// ...
// ...
}
Uses RenderData to choose which template to render
func makeOutputFile(path string) error {
// ...
// ...
if renderData.PageToRender != "" {
if f, err = os.Create(filepath.Join("output", path)); err != nil {
return err
}
defer func() {
if err = f.Close(); err != nil {
panic(err.Error())
}
}()
}
if renderData.PageToRender != "" {
tpl = template.Must(findAndParseTemplates("templates", nil))
return tpl.Lookup(renderData.PageToRender).Execute(f, renderData)
}
return nil
}
Render the template, and move on to the next
In other words, Make is the orchestrator, and the CLI is the "doer". This allows me to write minimal, simple code, and iterate more quickly.
That's all. Have a good day.