42 |
43 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 | Copyright (c) 2019 Julian Vossen
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 | The above copyright notice and this permission notice shall be included in all
10 | copies or substantial portions of the Software.
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17 | SOFTWARE.
18 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/julvo/tinystatic
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/yuin/goldmark v1.4.4
7 | github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01
8 | github.com/yuin/goldmark-meta v1.0.0
9 | gopkg.in/yaml.v2 v2.4.0
10 | )
11 |
12 | require (
13 | github.com/Masterminds/goutils v1.1.1 // indirect
14 | github.com/Masterminds/semver/v3 v3.1.1 // indirect
15 | github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect
16 | github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
17 | github.com/google/uuid v1.1.1 // indirect
18 | github.com/huandu/xstrings v1.3.1 // indirect
19 | github.com/imdario/mergo v0.3.11 // indirect
20 | github.com/mitchellh/copystructure v1.0.0 // indirect
21 | github.com/mitchellh/reflectwalk v1.0.0 // indirect
22 | github.com/shopspring/decimal v1.2.0 // indirect
23 | github.com/spf13/cast v1.3.1 // indirect
24 | golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 // indirect
25 | golang.org/x/text v0.3.7 // indirect
26 | )
27 |
28 | require (
29 | github.com/Masterminds/sprig/v3 v3.2.2
30 | github.com/alecthomas/chroma v0.9.4 // indirect
31 | github.com/dop251/goja v0.0.0-20220705101429-189bfeb9f530
32 | )
33 |
--------------------------------------------------------------------------------
/examples/blog/output/contact/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Contact | fineblog.com
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
81 |
82 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
2 | github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
3 | github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
4 | github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
5 | github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
6 | github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
7 | github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
8 | github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a/go.mod h1:fv5SzZPFJbwp2NXJWpFIX7DZS4HgV1K4ew4Pc2OZD9s=
9 | github.com/alecthomas/chroma v0.9.4 h1:YL7sOAE3p8HS96T9km7RgvmsZIctqbK1qJ0b7hzed44=
10 | github.com/alecthomas/chroma v0.9.4/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
11 | github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
12 | github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
13 | github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
14 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
15 | github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
16 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
17 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
18 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
19 | github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
20 | github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
21 | github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
22 | github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
23 | github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
24 | github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
25 | github.com/dop251/goja v0.0.0-20220705101429-189bfeb9f530 h1:936YSsrki8Z6H48PPFbATV674Gpmh444xXaX+O5wwFQ=
26 | github.com/dop251/goja v0.0.0-20220705101429-189bfeb9f530/go.mod h1:TQJQ+ZNyFVvUtUEtCZxBhfWiH7RJqR3EivNmvD6Waik=
27 | github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
28 | github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
29 | github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
30 | github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
31 | github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
32 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
33 | github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
34 | github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
35 | github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
36 | github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
37 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
38 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
39 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
40 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
41 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
42 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
43 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
44 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
45 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
46 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
47 | github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
48 | github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
49 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
50 | github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
51 | github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
52 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
53 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
54 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
55 | github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
56 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
57 | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
58 | github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
59 | github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
60 | github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
61 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
62 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
63 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
64 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
65 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
66 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
67 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
68 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
69 | github.com/yuin/goldmark v1.3.6/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
70 | github.com/yuin/goldmark v1.4.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs=
71 | github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
72 | github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01 h1:0SJnXjE4jDClMW6grE0xpNhwpqbPwkBTn8zpVw5C0SI=
73 | github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01/go.mod h1:TwKQPa5XkCCRC2GRZ5wtfNUTQ2+9/i19mGRijFeJ4BE=
74 | github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
75 | github.com/yuin/goldmark-meta v1.0.0/go.mod h1:zsNNOrZ4nLuyHAJeLQEZcQat8dm70SmB2kHbls092Gc=
76 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
77 | golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
78 | golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
79 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
80 | golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
81 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
82 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
83 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
84 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
85 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
86 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
87 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
88 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
89 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
90 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
91 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
92 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
93 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
94 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
95 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
96 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
97 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
98 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
99 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tinystatic
2 |
3 | 
4 |
5 | A tiny static website generator that is flexible and easy to use. It's flexible, as there is no required website structure nor any blog-specific concepts. It's easy to use, as we can start with a standard HTML site and introduce tinystatic gradually.
6 |
7 | The concept of tinystatic is simple: From every file in an input directory, create a file in an output directory which we can then use as the public directory of our webserver. How tinystatic generates an output file depends on the input file extension: Markdown is converted to HTML, while CSS, JS and images are simply copied. For markdown and HTML files, you can specify meta data at the top of a file. By specifying a template in this file meta data, and providing templates in separate directories, you can make use of Go's HTML templating engine. [Here](https://github.com/julvo/tinystatic/tree/master/examples/blog) an example of a typical blog website and for a quick start guide, see below.
8 |
9 | ## Install
10 |
11 | ### Pre-built binaries
12 | Download the tinystatic binary for your operating system:
13 | - [Linux](https://github.com/julvo/tinystatic/releases/download/v0.1.0/tinystatic_linux_amd64)
14 | - [macOS](https://github.com/julvo/tinystatic/releases/download/v0.1.0/tinystatic_macos_darwin_amd64)
15 |
16 | Optionally, add the binary to your shell path, by either placing the binary into an existing directory like `/usr/bin` or by adding the parent directory of the binary to your path variable.
17 |
18 | If you added tinystatic to your path, you should be able to call
19 | ```shell
20 | tinystatic -help
21 | ```
22 | Otherwise, you will need to specify the path to the tinystatic binary when calling it
23 | ```shell
24 | /path/to/tinystatic -help
25 | ```
26 |
27 | ### Compiling from source
28 | If you don't want to use the pre-built binaries, you will need to install the Golang compiler to compile tinystatic. Then, you can install tinystatic by running
29 | ```shell
30 | go install -u github.com/julvo/tinystatic
31 | ```
32 | or by cloning the repository and running `go install` or `go build` in the root directory of this repository.
33 |
34 | ## Quick start
35 | This is a 10-minute tutorial in which we build a small blog, starting with a single HTML page and introducing the features of tinystatic one-by-one.
36 |
37 | First, we create a folder called `routes`. Inside this folder, we create a single HTML file `index.html` with the following contents:
38 | ```html
39 |
40 |
41 |
42 | Our first tinystatic website
43 |
44 |
45 |
Welcome to our blog
46 |
47 |
48 | ```
49 |
50 | Now, we can run `tinystatic` for the first time. By default, tinystatic expects to be called in the directory containing the `routes` directory, but you can change that by using the `-routes` parameter. After running the command, you should see a folder `output` appearing next to the `routes` folder. Our file structure now looks like this:
51 | ```
52 | my-blog/
53 | routes/
54 | index.html
55 | output/
56 | index.html
57 | ```
58 | We can now run a webserver in the output directory, e.g. using Python's built-in server to open our website on `http://localhost:8000`:
59 | ```
60 | cd output
61 | python3 -m http.server
62 | ```
63 |
64 | So far, all tinystatic did was copying the `index.html` from `routes` to `output` - not all that useful, but hang in...
65 |
66 | Let's add a second HTML file to `routes`, e.g. `about.html`:
67 | ```html
68 |
69 |
70 |
71 | Our first tinystatic website
72 |
73 |
74 |
About us
75 |
76 |
77 | ```
78 |
79 | After we run `tinystatic` again, and with our webserver still running, we can now navigate to `http://localhost:8000/about`. Note how there is no `.html` in this route anymore, as tinystatic created a folder `about` with a single `index.html` in it, like so:
80 | ```
81 | output/
82 | index.html
83 | about/
84 | index.html
85 | ```
86 |
87 | What we don't like about our current pages is the duplication of all the basic HTML structure. Wouldn't it be better to use a shared template for `index.html` and `about.html`?. To do this, we create a folder called `templates` next to our `routes` folder and place an HTML file `default.html` inside it:
88 |
89 | ```
90 | my-blog/
91 | routes/
92 | index.html
93 | about.html
94 | templates/
95 | default.html
96 | ```
97 | The content of `default.html` should be:
98 | ```html
99 |
100 |
101 |
102 | Our first tinystatic website
103 |
104 |
105 | {{template "body" .}}
106 |
107 |
108 | ```
109 |
110 | Also, we change the content of `routes/index.html` to
111 | ```html
112 | ---
113 | template: default.html
114 | ---
115 | {{define "body"}}
116 |
Welcome to our blog
117 | {{end}}
118 | ```
119 |
120 | and the content of `routes/about.html` to
121 | ```html
122 | ---
123 | template: default.html
124 | ---
125 | {{define "body"}}
126 |
About us
127 | {{end}}
128 | ```
129 |
130 | When running `tinystatic` again, the output is identical to the previous output, but we consolidated the HTML skeleton into a single place.
131 |
132 | As seen just now, we can specify a template to render our content into by providing a template name in the meta data at the top of a file. We can also include other templates (see below) and use Go's template pipelines. While rendering, we have access to the meta data defined at the top of the file, a struct `Route` with fields `Route.Href`, `Route.FilePath` and `Route.Meta` which is again a map of meta data defined at the top of the file. Moreover, we can access `Routes`, which is a slice (think: array for people new to Go) of all routes, which we will learn more about further down.
133 |
134 | Let's use this meta data together with Go's templating primitives to change the page title depending on the current page. For this, we change the meta data in `routes/about.html` to
135 | ```
136 | ---
137 | template: default.html
138 | title: About
139 | ---
140 | ```
141 |
142 | and finally change `templates/default.html` to
143 | ```html
144 |
145 |
146 |
147 | {{if .title}} {{.title}} | {{end}}Our first tinystatic website
148 |
149 |
150 | {{template "body" .}}
151 |
152 |
153 | ```
154 |
155 | After regenerating the website, the browser should now display different page titles for our index and our about page.
156 |
157 | Now, let's create a few blog posts in our routes folder, e.g.
158 | ```
159 | routes/
160 | index.html
161 | about.html
162 | posts/
163 | first_post.md
164 | second_post.md
165 | ```
166 |
167 | Place some markdown inside these `.md` files with a meta data section at the top specifying the template as `default.html`, similar to how we specified the meta data in `routes/index.html` and `routes/about.html`. For `first_post.md`, this could look like this:
168 | ```markdown
169 | ---
170 | template: default.html
171 | title: First Post
172 | ---
173 |
174 | # Here could be some fine content
175 |
176 | ```
177 |
178 |
179 | Running `tinystatic` again to regenerate the output, we can now visit `http://localhost:8000/posts/first_post` and `http://localhost:8000/posts/second_post`. The markdown has been converted HTML and placed inside a template called `body` for us, so that it renders into the `{{template "body" .}}` placeholder in `templates/default.html`. Note how this is different to `.html` files, where we need to call `{{define "body"}} ... {{end}}` manually.
180 |
181 | Next, let's create a listing of our posts by using the aforementioned `Routes` slice. We change the content of `routes/index.html` to:
182 | ```html
183 | ---
184 | template: default.html
185 | ---
186 | {{define "body"}}
187 |