1
2
3# Just Build Me A Fucking Page
4
5I am just so sick of all these complicated static site generators forcing you to
6care about taxonomies and shit like this. All I want is to have a bunch of
7markdown files and let them use specific templates. That is about it. Nothing
8fancy!
9
10This generator is not for people who need something more complicated. Use Hugo
11instead. But if you need a simple blog page that needs to spit out an RSS feed
12or two and have the option to define different templates for different posts,
13well then this might be useful to you.
14
15The only thing hard about this project is the spelling of its name.
16
17Some facts (will be more clear when you read the whole readme):
18
19- You can nest your markdown file under `content` folder. You can use subfolders
20 as well. Final URL will not be affected by putting markdown files in
21 subfolders.
22- `public` folder gets automatically created on `jbmafp --build`.
23- All files in `static` folder will be moved to the root of `public` folder.
24- When you provide `url` in your markdown files, this will create these files in
25 the root of `public` folder. No nesting allowed.
26- Comes with a small embedded HTTP server you can invoke with `jbmafo --server`
27 which will server contents from `public` folder. Good for testing stuff.
28- After you have made your site you can easily create new content with `jbmafp
29 --new "My new shitty title"`. This will create a new markdown file in
30 `content` folder.
31
32## Install
33
34```sh
35git clone git@github.com:mitjafelicijan/jbmafp.git
36cd jbmafp
37go install .
38```
39
40## Generate first site
41
42- Go to your projects folder or wherever you want to place the site.
43
44```sh
45mkdir my-shitty-website
46cd my-shitty-website
47jbmafp --init
48jbmafp --build
49```
50
51- Check out `public` folder and you will see a website. That is about it.
52- You can also do `jbmafp --help` to see all the option.
53
54## Understanding all this bullshit
55
56- Posts go into `content` folder.
57- Each post must have fields defined between `---` block. All of the fields are
58 required. If you have ever used Hugo, this is the same thing. Below is example
59 `content/first.md`.
60
61```md
62---
63title: "My first post"
64url: first.html
65date: 2023-06-29T14:51:39+02:00
66type: post
67draft: false
68---
69
70This is my first post. It ain't much but it's an honest post.
71```
72
73- `type` is used all over the place. It is used to define a template file of the
74 page that will be generated. If type is `post` then the program will load
75 `templates/post.html` to handle generation of the page.
76- You can use whatever name you want. I use `note`, `post` as types to separate
77 all the pages into categories.
78- `type` is also used inside templates like:
79 ```html
80 <ul>
81 {{ range .Pages }}
82 {{ if eq .Type "post" }}
83 <li><a href="/{{ .RelPermalink }}">{{ .Title }}</a></li>
84 {{ end }}
85 {{ end }}
86 </ul>
87 ```
88- This is also use for generating RSS feed. Check `templates/index.xml` to see
89 the example.
90- This opens door to quite versatile build option.
91- You can trigger additional generation of content under `extras` field in
92 `config.yaml` file. RSS feed gets generated this way. `template` field tells
93 generator which file in `templates` folder to use and `url` tells generator
94 what the file should be called when its saved.
95
96## Entities available in template
97
98### Config
99
100```txt
101Config {
102 Title string
103 Description string
104 BaseURL string
105 Language string
106 Highlighting string
107 Minify bool
108}
109```
110
111Using it inside of a template.
112
113```html
114<div>{{ .Config.Language }}</div>
115```
116
117### Page
118
119```txt
120Page {
121 Filepath string
122 Raw string
123 HTML template.HTML
124 Text string
125 Summary string
126 Meta map[string]interface{}
127 Title string
128 RelPermalink string
129 Type string
130 Created time.Time
131 Draft bool
132}
133```
134
135Using it inside of a template.
136
137```html
138{{ range .Pages }}
139 {{ if eq .Type "post" }}
140 <li>
141 <a href="/{{ .RelPermalink }}">{{ .Title }}</a>
142 <div>{{ .Created.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
143 </li>
144 {{ end }}
145{{ end }}
146```
147
148That `.Format` shenanigas are used for formatting `time.Time` type. You can read
149more about it on https://gosamples.dev/date-time-format-cheatsheet/.
150
151## Payload available on page generation
152
153```txt
154Payload {
155 Config
156 Page
157 Pages
158}
159```
160
161## Special filters
162
163- first (gets first N posts)
164- last (gets last N posts)
165- random (gets random N posts)
166- filterbytype (get just the posts with specific type)
167
168```html
169<!-- First 10 pages -->
170{{ range .Pages | first 10 }}
171 {{ if and (eq .Type "post") (not .Draft) }}
172 <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
173 {{ end }}
174{{ end }}
175
176<!-- Last 10 pages -->
177{{ range .Pages | last 10 }}
178 {{ if and (eq .Type "post") (not .Draft) }}
179 <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
180 {{ end }}
181{{ end }}
182
183<!-- Random 10 pages -->
184{{ range .Pages | random 10 }}
185 {{ if and (eq .Type "post") (not .Draft) }}
186 <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
187 {{ end }}
188{{ end }}
189
190<!-- Filter by type -->
191{{ range .Pages | filterbytype "post" }}
192 {{ if not .Draft }}
193 <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
194 {{ end }}
195{{ end }}
196
197<!-- Chain multiple together -->
198{{ range .Pages | filterbytype "post" | random 20 | first 5 }}
199 {{ if not .Draft }}
200 <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
201 {{ end }}
202{{ end }}
203```
204
205## Additional material
206
207- https://github.github.com/gfm/
208
209## License
210
211[jbmafp](https://github.com/mitjafelicijan/jbmafp) was written by [Mitja
212Felicijan](https://mitjafelicijan.com) and is released under the BSD zero-clause
213license, see the LICENSE file for more information.