diff options
author | Hsieh Chin Fan <typebrook@gmail.com> | 2022-02-02 13:34:47 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2024-11-30 21:09:29 +0800 |
commit | 9934dd538b0ce116e3b1600272cb46369b082246 (patch) | |
tree | 2f28c6c362201151eaf8218e566479ed7eb72070 /www |
init commit
Diffstat (limited to 'www')
-rw-r--r-- | www/.gitignore | 1 | ||||
-rw-r--r-- | www/Makefile | 14 | ||||
-rw-r--r-- | www/assets/favicon.ico | bin | 0 -> 549 bytes | |||
-rw-r--r-- | www/assets/gpg.asc | 84 | ||||
-rw-r--r-- | www/assets/robots.txt | 4 | ||||
-rw-r--r-- | www/assets/style.css | 213 | ||||
-rw-r--r-- | www/assets/wp-admin.php | 1 | ||||
-rwxr-xr-x | www/scripts/add-graph.py | 35 | ||||
-rwxr-xr-x | www/scripts/build.sh | 188 | ||||
-rw-r--r-- | www/templates/footer.html | 4 | ||||
-rw-r--r-- | www/templates/head.html | 10 | ||||
-rw-r--r-- | www/templates/header.html | 17 | ||||
-rw-r--r-- | www/templates/index.md | 1 |
13 files changed, 572 insertions, 0 deletions
diff --git a/www/.gitignore b/www/.gitignore new file mode 100644 index 0000000..364fdec --- /dev/null +++ b/www/.gitignore | |||
@@ -0,0 +1 @@ | |||
public/ | |||
diff --git a/www/Makefile b/www/Makefile new file mode 100644 index 0000000..80b9d47 --- /dev/null +++ b/www/Makefile | |||
@@ -0,0 +1,14 @@ | |||
1 | .ONESHELL: | ||
2 | ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) | ||
3 | |||
4 | # build html files for public/ | ||
5 | build: | ||
6 | @input_dir=~/log/posts \ | ||
7 | output_dir=/srv/http \ | ||
8 | assets_dir=$(ROOT_DIR)assets \ | ||
9 | template_dir=$(ROOT_DIR)templates \ | ||
10 | $(ROOT_DIR)scripts/build.sh | ||
11 | |||
12 | # Migrage frontmatter from '---' to HTML comment '<!-- -->' | ||
13 | frontmatter: | ||
14 | find content -type f -name '*.md' | xargs sed -i ':frontmatter { 1s/^---/<!--/; 1!s/^---/-->/; 1!b}; /^---/ {1b frontmatter}' | ||
diff --git a/www/assets/favicon.ico b/www/assets/favicon.ico new file mode 100644 index 0000000..5af1857 --- /dev/null +++ b/www/assets/favicon.ico | |||
Binary files differ | |||
diff --git a/www/assets/gpg.asc b/www/assets/gpg.asc new file mode 100644 index 0000000..f33181e --- /dev/null +++ b/www/assets/gpg.asc | |||
@@ -0,0 +1,84 @@ | |||
1 | -----BEGIN PGP PUBLIC KEY BLOCK----- | ||
2 | |||
3 | mQGNBGAzCdIBDACvt2iu+FTg+p3Q5p/J8Q7643g61n3kgIgDt9a5JU06nwAGDmX+ | ||
4 | hIrVy5OxsTntJzRkvV+nr0cR9Suvkci9RfJ9TixjMca+Eld3pPLhdPGmtPofjCaj | ||
5 | LpKMkPdHg+VU4B7BANwsd/on7VYLq5Ko6dj1HKrp3KJappP5njK1u39DQHjLPEjK | ||
6 | 976nyErOdKNVjswIWdLFJgWhC46mH3zW4aOtkw8UIn32fbCmpZyuVU8ooJTbIl6+ | ||
7 | YvU9BsYRgEhSjQbi+RXQZAyUqsQlZnS8/81pwanKs6NFqBSTFaryHVfbC1McXHNY | ||
8 | V3+Y/rGEmUIn2FXhHWWHb8b5oBroZQLbHVpjWV3DZgkTN0c8g+K3hQ1iLFAdWuQg | ||
9 | wxBuzkq/5AMiqJ/0gUjkT4uW12fIEQR30wvveVDq/BMWdhC4tgy+ft5QcBjA3xj2 | ||
10 | xC813/r3cvgfWaJvB5/mUH4QPv1gESG9QdjAVOBMt/TTnKJFes5iuq1q0+ZdnG0S | ||
11 | KZ1aFlfbGgZWcW8AEQEAAbQvdHlwZWJyb29rIDx0eXBlYnJvb2tAZ21haWwuY29t | ||
12 | PiAoR21haWwgQWNjb3VudCmJAdQEEwEIAD4WIQQSgUZMDGWhjNgJ9OxmRzq+mhjP | ||
13 | LQUCYEnKDgIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRBmRzq+ | ||
14 | mhjPLe7zC/9/6O4+icJc74Y/d/VhJv4k/Zc3b2ZlMrdGq/FDQTYSISPPo2k6hgcS | ||
15 | IQw2SPNb0hRkoaj7Dj3tMFzumSrGMyfGNXHThYWh3UABSTkTnYIXMNhd+on7VpfZ | ||
16 | FqkBrIfgv+Im7Gops66L7x9b3BT16yxb373uG9bhe+w/Kzk8Mix6f57M9f21f/MI | ||
17 | trOKbA50HG6scpmytJ5YHiu7qZVihhVewJDX32e9W9fpMu3Kos+SCDOzxIrLl8An | ||
18 | /8WrSTqAMh/RGYKaxL6A+JjZyhDMXjWMZfvCPfzFrfF60D3ppcDtatqYvMk76i+c | ||
19 | QW8Oiyv8CRWEK9CzSXptz/MsDwzVKn4UV4QFyoCmB4EGLB7+lbSbnNdtZeluoElG | ||
20 | +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 | ||
82 | RWr5Ni7wyLHOaHhoDLK9i+Fz | ||
83 | =DNGE | ||
84 | -----END PGP PUBLIC KEY BLOCK----- | ||
diff --git a/www/assets/robots.txt b/www/assets/robots.txt new file mode 100644 index 0000000..41f82c4 --- /dev/null +++ b/www/assets/robots.txt | |||
@@ -0,0 +1,4 @@ | |||
1 | User-agent: * | ||
2 | Allow: / | ||
3 | |||
4 | Sitemap: https://topo.tw/sitemap.xml | ||
diff --git a/www/assets/style.css b/www/assets/style.css new file mode 100644 index 0000000..2752323 --- /dev/null +++ b/www/assets/style.css | |||
@@ -0,0 +1,213 @@ | |||
1 | header { | ||
2 | display: flex; | ||
3 | justify-content: space-between; | ||
4 | margin-top: 1rem; | ||
5 | } | ||
6 | |||
7 | footer * { | ||
8 | display: inline; | ||
9 | } | ||
10 | |||
11 | blockquote { | ||
12 | color: gray; | ||
13 | font-size: 1.2rem; | ||
14 | font-style: italic; | ||
15 | |||
16 | text-align: center; | ||
17 | } | ||
18 | |||
19 | p code { | ||
20 | margin-inline: 0.2rem; | ||
21 | padding-inline: 6px; | ||
22 | } | ||
23 | |||
24 | /* Neat CSS: https://neat.joeldare.com */ | ||
25 | * { | ||
26 | box-sizing: border-box; | ||
27 | } | ||
28 | |||
29 | :root { | ||
30 | color-scheme: light dark; | ||
31 | --light: #fff; | ||
32 | /* --light: #f7f7f7; */ | ||
33 | --lesslight: #efefef; | ||
34 | --dark: #404040; | ||
35 | --moredark: #000; | ||
36 | /*--link: royalblue; */ | ||
37 | --link: #850000; | ||
38 | --link-highlight-color: #ffdcda; | ||
39 | /* border-top: 5px solid var(--dark); */ | ||
40 | line-height: 1.5em; | ||
41 | font-family: system-ui, sans-serif; | ||
42 | font-size: 16px; | ||
43 | color: var(--dark); | ||
44 | } | ||
45 | |||
46 | h1 { | ||
47 | line-height: 1em; | ||
48 | } | ||
49 | |||
50 | button, input { | ||
51 | font-size: 1em; /* Override browser default font shrinking*/ | ||
52 | } | ||
53 | |||
54 | input { | ||
55 | border: 1px solid var(--dark); | ||
56 | background-color: var(--lesslight); | ||
57 | border-radius: .25em; | ||
58 | padding: .5em; | ||
59 | } | ||
60 | |||
61 | pre { | ||
62 | background-color: var(--lesslight); | ||
63 | margin: 0.5em 0 0.5em 0; | ||
64 | padding: 0.5em; | ||
65 | overflow: auto; | ||
66 | } | ||
67 | |||
68 | code { | ||
69 | background-color: var(--lesslight); | ||
70 | } | ||
71 | |||
72 | body { | ||
73 | background-color: var(--light); | ||
74 | margin: 0; | ||
75 | max-width: 800px; | ||
76 | padding: 0 20px 20px 20px; | ||
77 | margin-left: auto; | ||
78 | margin-right: auto; | ||
79 | } | ||
80 | |||
81 | a { | ||
82 | outline: none; | ||
83 | text-decoration: underline 2px var(--link-highlight-color); | ||
84 | color: var(--link); | ||
85 | } | ||
86 | |||
87 | a:hover { | ||
88 | background: var(--link-highlight-color); | ||
89 | } | ||
90 | |||
91 | img { | ||
92 | max-width: 100%; | ||
93 | height: auto; | ||
94 | } | ||
95 | |||
96 | button, .button, input[type=submit] { | ||
97 | display: inline-block; | ||
98 | background-color: var(--dark); | ||
99 | color: var(--light); | ||
100 | text-align: center; | ||
101 | padding: .5em; | ||
102 | border-radius: .25em; | ||
103 | text-decoration: none; | ||
104 | border: none; | ||
105 | cursor: pointer; | ||
106 | } | ||
107 | |||
108 | button:hover, .button:hover, input[type=submit]:hover { | ||
109 | color: var(--lesslight); | ||
110 | background-color: var(--moredark); | ||
111 | } | ||
112 | |||
113 | /* Add a margin between side-by-side buttons */ | ||
114 | button + button, .button + .button, input[type=submit] + input[type=submit] { | ||
115 | margin-left: 1em; | ||
116 | } | ||
117 | |||
118 | .center { | ||
119 | display: block; | ||
120 | margin-left: auto; | ||
121 | margin-right: auto; | ||
122 | text-align: center; | ||
123 | } | ||
124 | |||
125 | .bordered { | ||
126 | border: 3px solid; | ||
127 | } | ||
128 | |||
129 | .home { | ||
130 | display: inline-block; | ||
131 | background-color: var(--dark); | ||
132 | color: var(--light); | ||
133 | margin-top: 20px; | ||
134 | padding: 5px 10px 5px 10px; | ||
135 | text-decoration: none; | ||
136 | font-weight: bold; | ||
137 | } | ||
138 | |||
139 | |||
140 | /* Desktop sizes */ | ||
141 | @media (min-width: 600px) { | ||
142 | ol.twocol { | ||
143 | column-count: 2; | ||
144 | } | ||
145 | |||
146 | .row { | ||
147 | display: flex; | ||
148 | flex-direction: row; | ||
149 | padding: 0; | ||
150 | width: 100%; | ||
151 | } | ||
152 | |||
153 | /* Make everything in a row a column */ | ||
154 | .row > * { | ||
155 | display: block; | ||
156 | flex: 1 1 auto; | ||
157 | max-width: 100%; | ||
158 | width: 100%; | ||
159 | } | ||
160 | |||
161 | .row > *:not(:last-child) { | ||
162 | margin-right: 10px; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /* Dark mode overrides (confusingly inverse) */ | ||
167 | @media (prefers-color-scheme: dark) { | ||
168 | :root { | ||
169 | --light: #222; | ||
170 | --lesslight: #333; | ||
171 | --dark: #eee; | ||
172 | --moredark: #fefefe; | ||
173 | } | ||
174 | /* This fixes an odd blue then white shadow on FF in dark mode */ | ||
175 | *:focus { | ||
176 | outline: var(--light); | ||
177 | box-shadow: 0 0 0 .25em var(--link); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /* Printing */ | ||
182 | @media print { | ||
183 | .home { | ||
184 | display: none; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | [data-tooltip]{ | ||
189 | display: inline-block; | ||
190 | position: relative; | ||
191 | |||
192 | &::after { | ||
193 | display: block; | ||
194 | position: absolute; | ||
195 | content: attr(data-tooltip); | ||
196 | background: var(--dark); | ||
197 | color: var(--lesslight); | ||
198 | padding: .25em; | ||
199 | cursor: default; | ||
200 | user-select: text; | ||
201 | |||
202 | transition: | ||
203 | visibility .3s ease-out, | ||
204 | opacity .3s ease-out; | ||
205 | visibility: hidden; | ||
206 | opacity: 0; | ||
207 | } | ||
208 | |||
209 | &:hover::after { | ||
210 | opacity: 1; | ||
211 | visibility: visible; | ||
212 | } | ||
213 | } | ||
diff --git a/www/assets/wp-admin.php b/www/assets/wp-admin.php new file mode 100644 index 0000000..b774c98 --- /dev/null +++ b/www/assets/wp-admin.php | |||
@@ -0,0 +1 @@ | |||
Got you! | |||
diff --git a/www/scripts/add-graph.py b/www/scripts/add-graph.py new file mode 100755 index 0000000..455b45a --- /dev/null +++ b/www/scripts/add-graph.py | |||
@@ -0,0 +1,35 @@ | |||
1 | #! /bin/python3 | ||
2 | |||
3 | import sys, subprocess | ||
4 | from datetime import date | ||
5 | from bs4 import BeautifulSoup | ||
6 | |||
7 | def handle(html): | ||
8 | soup = BeautifulSoup(html, 'html.parser') | ||
9 | for graph in soup.select('pre.language-graph'): | ||
10 | print() | ||
11 | print(date.today().strftime("%H:%M:%S")) | ||
12 | print('before:') | ||
13 | print(graph.string) | ||
14 | |||
15 | process = subprocess.Popen( | ||
16 | ["/usr/bin/vendor_perl/graph-easy", "--boxart"], | ||
17 | stdin=subprocess.PIPE, | ||
18 | stdout=subprocess.PIPE, | ||
19 | stderr=subprocess.PIPE | ||
20 | ) | ||
21 | output, error = process.communicate(input=graph.get_text().encode()) | ||
22 | graph.string = output.decode() | ||
23 | |||
24 | print('After:') | ||
25 | print(graph.string) | ||
26 | print('Error:') | ||
27 | print(error.decode()) | ||
28 | return str(soup) | ||
29 | |||
30 | for line in sys.stdin: | ||
31 | file = line.rstrip("\n") | ||
32 | with open(file, 'r') as html: | ||
33 | new_content = handle(html) | ||
34 | with open(file, 'w') as html: | ||
35 | html.write(new_content) | ||
diff --git a/www/scripts/build.sh b/www/scripts/build.sh new file mode 100755 index 0000000..9b95c99 --- /dev/null +++ b/www/scripts/build.sh | |||
@@ -0,0 +1,188 @@ | |||
1 | #! /bin/bash | ||
2 | |||
3 | set -e | ||
4 | |||
5 | # Executable command for markdown | ||
6 | markdown_bin="markdown -f fencedcode,autolink,alphalist,autolink,footnote" | ||
7 | |||
8 | # Directory for input/output | ||
9 | input_dir=${input_dir:?ENV \"input_dir\" is not set} | ||
10 | output_dir=${output_dir:?ENV \"output_dir\" is not set} | ||
11 | assets_dir=${assets_dir:?ENV \"assets_dir\" is not set} | ||
12 | template_dir=${template_dir:?ENV \"template_dir\" is not set} | ||
13 | |||
14 | # functions {{{ | ||
15 | |||
16 | # add indent for each line except <pre> | ||
17 | indent() { | ||
18 | indent="$(printf "%${1}s")" | ||
19 | sed "s/^/${indent}/; /<pre>/!b; :pre; N; /<\/pre>/!b pre" | ||
20 | } | ||
21 | |||
22 | # use heredoc to generate html from .md file and templates | ||
23 | html() { | ||
24 | <<-END_OF_HTML sed '1d;$d' | ||
25 | |||
26 | <!DOCTYPE html> | ||
27 | <html lang="en"> | ||
28 | ${head} | ||
29 | <body> | ||
30 | ${header} | ||
31 | <hr><br> | ||
32 | <main> | ||
33 | $(${markdown_bin} | indent 4) | ||
34 | </main> | ||
35 | <br><hr> | ||
36 | ${footer} | ||
37 | </body> | ||
38 | </html> | ||
39 | |||
40 | END_OF_HTML | ||
41 | } | ||
42 | |||
43 | # list of latest posts in markdown format | ||
44 | latest_posts() { | ||
45 | (IFS=$'\n'; echo "${index_list[*]}") | sort -r | head -20 | while read date path title; do | ||
46 | echo "- <time datetime="$date">$date</time> [$title](/$path)" | ||
47 | done | ||
48 | } | ||
49 | |||
50 | # print frontmatter from markdown file with format: "<key> <value>" | ||
51 | get_frontmatter() { | ||
52 | sed -n '1 {/<!--/ !q; n}; /-->/q; s/"//g; s/://p' | ||
53 | } | ||
54 | |||
55 | # process frontmatter | ||
56 | add_index() { | ||
57 | unset title public index date draft | ||
58 | |||
59 | # define local variables for frontmatter | ||
60 | while read key value; do | ||
61 | local -r $key="$value" | ||
62 | done <<<"$(get_frontmatter)" | ||
63 | |||
64 | # don't process draft after function call | ||
65 | test "$draft" != "" && return 1 | ||
66 | |||
67 | # skip making index in some cases | ||
68 | test "$public" = false && return 0 | ||
69 | test "$index" = false && return 0 | ||
70 | test "$type" = demo && return 0 | ||
71 | test "$title" = "" && return 0 | ||
72 | iso8601=$(date --iso --date "${date:-NULL}" 2>/dev/null) | ||
73 | test "$iso8601" = "" && return 0 | ||
74 | |||
75 | # put frontmatter info into variable "index" if title and date are valid | ||
76 | index_list+=("$iso8601 $path $title") | ||
77 | } | ||
78 | |||
79 | # remove SGML comments but keep the top one as frontmatter | ||
80 | ignore_comment() { | ||
81 | sed '1 !{ /^<!--$/,/^-->$/ d }' | ||
82 | } | ||
83 | |||
84 | # Generate the feed file | ||
85 | make_rss() { | ||
86 | echo -n "Making RSS " | ||
87 | |||
88 | rssfile=$blog_feed.$RANDOM | ||
89 | while [[ -f $rssfile ]]; do rssfile=$blog_feed.$RANDOM; done | ||
90 | |||
91 | { | ||
92 | pubdate=$(LC_ALL=C date +"$date_format_full") | ||
93 | cat <<-EOF | ||
94 | <?xml version="1.0" encoding="UTF-8" ?>' | ||
95 | <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">' | ||
96 | <channel><title>Dummy Website</title><link>https://topo.tw/index.xml</link>" | ||
97 | <description>$global_description</description><language>en</language>" | ||
98 | <lastBuildDate>$pubdate</lastBuildDate>" | ||
99 | <pubDate>$pubdate</pubDate>" | ||
100 | <atom:link href="$global_url/$blog_feed" rel="self" type="application/rss+xml" />" | ||
101 | EOF | ||
102 | |||
103 | n=0 | ||
104 | while IFS='' read -r i; do | ||
105 | is_boilerplate_file "$i" && continue | ||
106 | ((n >= number_of_feed_articles)) && break # max 10 items | ||
107 | echo -n "." 1>&3 | ||
108 | echo '<item><title>' | ||
109 | get_post_title "$i" | ||
110 | echo '</title><description><![CDATA[' | ||
111 | get_html_file_content 'text' 'entry' $cut_do <"$i" | ||
112 | echo "]]></description><link>$global_url/${i#./}</link>" | ||
113 | echo "<guid>$global_url/$i</guid>" | ||
114 | echo "<dc:creator>$(get_post_author "$i")</dc:creator>" | ||
115 | echo "<pubDate>$(LC_ALL=C date -r "$i" +"$date_format_full")</pubDate></item>" | ||
116 | |||
117 | n=$(( n + 1 )) | ||
118 | done < <(ls -t ./*.html) | ||
119 | |||
120 | echo '</channel></rss>' | ||
121 | } 3>&1 >"$rssfile" | ||
122 | echo "" | ||
123 | |||
124 | mv "$rssfile" "$blog_feed" | ||
125 | chmod 644 "$blog_feed" | ||
126 | } | ||
127 | |||
128 | # }}} | ||
129 | # prepare directory for outputs {{{ | ||
130 | |||
131 | mkdir -p $output_dir/ | ||
132 | rm -rf $output_dir/** | ||
133 | ln -s $assets_dir/* $output_dir/ | ||
134 | |||
135 | # }}} | ||
136 | # content of templates {{{ | ||
137 | |||
138 | head="$(cat $template_dir/head.html)" | ||
139 | header="$(cat $template_dir/header.html | indent 2)" | ||
140 | footer="$(cat $template_dir/footer.html | indent 2)" | ||
141 | index_list=() | ||
142 | index_template="$(cat $template_dir/index.md)" | ||
143 | |||
144 | # }}} | ||
145 | # for each markdown file {{{ | ||
146 | |||
147 | files="$(find "$input_dir" -type f -name '*md')" | ||
148 | total=$(wc -l <<<"$files") | ||
149 | declare -i counter | ||
150 | for file in $files; do | ||
151 | # set variables | ||
152 | path=$(<<<"$file" sed "s#^${input_dir}/##; s/\.md$//").html; mkdir -p $(dirname $output_dir/$path) | ||
153 | content="$(cat ${file} | ignore_comment)" | ||
154 | |||
155 | # use frontmatter to decide making html file or not | ||
156 | <<<"$content" add_index || continue | ||
157 | |||
158 | # log | ||
159 | echo -e "\033[1K\r$((counter+=1))/$total \t\t processing $path" | ||
160 | |||
161 | # make html file for draft | ||
162 | h1="$(<<<"$content" get_frontmatter | sed -n 's/^title *//p')" | ||
163 | echo "$content" \ | ||
164 | | tee $output_dir/${file#${input_dir}/} \ | ||
165 | | { [ -n "$h1" ] && echo "# $h1"; cat; } \ | ||
166 | | html >$output_dir/$path | ||
167 | done | ||
168 | echo | ||
169 | |||
170 | # }}} | ||
171 | # make index.html {{{ | ||
172 | |||
173 | { | ||
174 | echo "${index_template}" | ||
175 | echo -e '<br><br>\n\n' | ||
176 | latest_posts | ||
177 | } \ | ||
178 | | tee $output_dir/index.md \ | ||
179 | | html >$output_dir/index.html | ||
180 | |||
181 | echo -e index.html "\t" generated | ||
182 | |||
183 | # }}} | ||
184 | # make index.xml {{{ | ||
185 | |||
186 | |||
187 | |||
188 | # }}} | ||
diff --git a/www/templates/footer.html b/www/templates/footer.html new file mode 100644 index 0000000..9e87e02 --- /dev/null +++ b/www/templates/footer.html | |||
@@ -0,0 +1,4 @@ | |||
1 | <footer> | ||
2 | <address><a href="mailto:info@topo.tw">info@topo.tw</a></address> | | ||
3 | <a href="http://creativecommons.org/publicdomain/zero/1.0" rel="license noopener noreferrer">CC0 1.0</a> | ||
4 | </footer> | ||
diff --git a/www/templates/head.html b/www/templates/head.html new file mode 100644 index 0000000..ede99c9 --- /dev/null +++ b/www/templates/head.html | |||
@@ -0,0 +1,10 @@ | |||
1 | <head> | ||
2 | <meta charset="UTF-8"> | ||
3 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
4 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
5 | |||
6 | <title>Dummy Site</title> | ||
7 | |||
8 | <link rel="stylesheet" href="/style.css"> | ||
9 | <link rel="icon" href="/favicon.ico" type="image/x-icon"> | ||
10 | </head> | ||
diff --git a/www/templates/header.html b/www/templates/header.html new file mode 100644 index 0000000..a77079a --- /dev/null +++ b/www/templates/header.html | |||
@@ -0,0 +1,17 @@ | |||
1 | <header> | ||
2 | <nav class="left"> | ||
3 | <a href="/">Home</a> | | ||
4 | <a href="/about.html" data-tooltip="About this site">About</a> | | ||
5 | <a href="/posts/">Posts</a> | | ||
6 | <a href="/projects.html" data-tooltip="Not valid now...">Projects</a> | | ||
7 | <!-- | ||
8 | <a href="/links.html" data-tooltip="Cool sites you might be interested">Links</a> | ||
9 | --> | ||
10 | <a href="/links.html" data-tooltip="Not valid now...">Links</a> | ||
11 | </nav> | ||
12 | <nav class="right"> | ||
13 | <a href="/rss.xml" data-tooltip="Not valid now...">RSS</a> | | ||
14 | <a href="https://git.topo.tw" data-tooltip="Public Git Repos">Code</a> | | ||
15 | <a href="/gpg.asc">GPG</a> | ||
16 | </nav> | ||
17 | </header> | ||
diff --git a/www/templates/index.md b/www/templates/index.md new file mode 100644 index 0000000..5743a19 --- /dev/null +++ b/www/templates/index.md | |||
@@ -0,0 +1 @@ | |||
> There should be a intro for this site, but I cannot came up with any idea about this... | |||