├── LICENSE.md ├── README.md ├── archetypes └── default.md ├── exampleSite ├── config.toml └── content │ ├── about.md │ ├── archive.md │ └── posts │ ├── creating-a-new-theme.md │ └── goisforlovers.md ├── gen_lunr_index.sh ├── images ├── screenshot.png └── tn.png ├── layouts ├── 404.html ├── _default │ ├── list.html │ ├── single.html │ └── terms.html ├── archive │ └── single.html ├── index.html ├── partials │ ├── breadcrumb.html │ ├── comment.html │ ├── footer.html │ ├── header.html │ ├── msearch.html │ ├── script.html │ ├── splash.html │ └── waterfall.html └── shortcodes │ ├── admonition.html │ ├── asciinema.html │ ├── codepen.html │ ├── jsfiddle.html │ ├── music.html │ ├── shengxiang.html │ └── video.html ├── static ├── CNAME ├── css │ └── index.css ├── favicon.ico ├── fonts │ └── roboto │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-Thin.woff │ │ └── Roboto-Thin.woff2 ├── img │ ├── 20.jpg │ ├── avatar.jpg │ ├── avatar.png │ ├── bg.jpg │ ├── bg.png │ ├── iconseamless.png │ └── profile-bg.jpg ├── js │ ├── Valine.min.js │ ├── av-min.js │ ├── canvas.js │ ├── index.js │ └── polyfill.js └── svg │ └── icon.svg └── theme.toml /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 YOUR_NAME_HERE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Canoe 2 | 3 | A beautifull and powerfull theme of hugo static blog generator. 4 | 5 | [demo](https://keyin.me) 6 | 7 | ![](https://raw.githubusercontent.com/stkevintan/canoe/master/images/screenshot.png) 8 | 9 | 10 | ## Feature 11 | 12 | 1. Waterfall layout 13 | 2. Responsive layout 14 | 3. Material design 15 | 4. Table of content 16 | 5. Tiny and powerfull, no JQuery 17 | 5. Chinese keyword search(using `lunr` and `nodejieba`) 18 | 19 | 20 | ## Install 21 | 22 | ``` 23 | cd /your-blog-path/theme 24 | git clone https://github.com/stkevintan/canoe 25 | ``` 26 | 27 | then update your `config.toml` file with the help of the `exampleSite/config.toml` 28 | 29 | 30 | 31 | refer to for more info. 32 | 33 | 34 | ## Enable Search 35 | My theme use [lunr](https://lunrjs.com/) to search keywords, so you need using [hugo-lunr](https://www.npmjs.com/package/hugo-lunr) to generate lunr index file every time after building your site. If you need Chinese support, use my tool: [hugo-lunr-zh](https://www.npmjs.com/package/hugo-lunr-zh) instead. Plese refer to [official doc](https://gohugo.io/tools/search/#readout) for more info. 36 | -------------------------------------------------------------------------------- /archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .TranslationBaseName "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | toc: true 6 | --- -------------------------------------------------------------------------------- /exampleSite/config.toml: -------------------------------------------------------------------------------- 1 | baseURL = "https://example.org" 2 | languageCode = "zh-cn" 3 | title = "Hugo Canoe Theme" 4 | 5 | 6 | theme = "canoe" 7 | 8 | # last mod time support 9 | enableGitInfo = true 10 | 11 | # if true, auto-detect Chinese/Japanese/Korean Languages in the content. (.Summary and .WordCount can work properly in CJKLanguage) 12 | hasCJKLanguage = true 13 | 14 | 15 | 16 | [params] 17 | author = "Kevin Tan" 18 | description = "Tempora mutantur, nos et mutamur in illis ..." 19 | copyright = "Copyleft@Kevin Tan" 20 | # date format convert: http://fuckinggodateformat.com/ 21 | dateFormat = "2006年01月_2日" 22 | # 用户头像地址, user avatar's url 23 | logo = "/img/avatar.jpg" 24 | 25 | # 首页横幅的背景链接, home banner's background url. 26 | splash_bg = "/img/bg.jpg" 27 | 28 | # 是否使用一言, if using hitokoto(dynamic moto in splash screen) 29 | hitokoto = true 30 | 31 | # 是否使用Canvas动态背景, if using canvas dynamic background (nest.js) 32 | nest_bg = false 33 | 34 | # 是否使用动态加载效果, if using fade effect while loading (scroll-reveal.js) 35 | reveal_effect = true 36 | 37 | # comment settings, support 'valine' and 'disqus'. 38 | # more about 'valine', ref: http://valine.js.org/ 39 | [params.comment] 40 | type = "valine" # or 'disqus' 41 | 42 | [params.comment.valine] 43 | id = "< the appId >" 44 | key = "< the appKey >" 45 | placeholder = "< placeholder >" 46 | avatar = "retro" 47 | 48 | [params.comment.disqus] 49 | shortname = '< short name >' 50 | 51 | 52 | # Main menu 53 | [[menu.main]] 54 | name = "Home" 55 | # associated with displaying order. 56 | weight = 1 57 | url = "/" 58 | 59 | [[menu.main]] 60 | name = "Archive" 61 | weight = 2 62 | url = "/archive/" 63 | 64 | [[menu.main]] 65 | name = "About" 66 | weight = 6 67 | url = "/about/" 68 | 69 | 70 | 71 | # 文章归类 Taxonomy 72 | [[menu.taxonomy]] 73 | name = "Tag" 74 | identifier="tags" 75 | 76 | [[menu.taxonomy]] 77 | name = "Category" 78 | identifier="categories" 79 | 80 | # 友情链接 Your Friend's blog links 81 | [[menu.friend]] 82 | name = "Frantic1048" 83 | url = "https://frantic1048.logdown.com/" 84 | 85 | [[menu.friend]] 86 | name = "HclMaster" 87 | url = "https://hclmaster.github.io/" 88 | 89 | [[menu.friend]] 90 | name = "WANG Hsü-Tung" 91 | url = "https://whst.github.io/" 92 | 93 | 94 | # 社交账号 Social Network 95 | [[menu.social]] 96 | pre = "" 97 | name = "Github" 98 | url = "https://github.com/stkevintan" 99 | 100 | [[menu.social]] 101 | pre = "" 102 | name = "Twitter" 103 | url = "https://twitter.com/kevinsfork" 104 | 105 | [[menu.social]] 106 | pre = "" 107 | name = "Weibo" 108 | url = "http://weibo.com/kevinclasky" 109 | 110 | [blackfriday] 111 | extensions = ["laxHtmlBlocks","noEmptyLineBeforeBlock"] -------------------------------------------------------------------------------- /exampleSite/content/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "About Me" 3 | date: "2017-08-19T20:09:28+08:00" 4 | type: "about" 5 | toc: false 6 | --- 7 | 8 | ## Hello World! 9 | 10 | ```json 11 | { 12 | "Name": "Kevin Tan", 13 | "Hobbies": ["Coding", "Movie", "Piano", "Linux"], 14 | "Location": "Hangzhou", 15 | "Company": "Netease", 16 | "School": "Zhejiang University", 17 | "Contacts": { 18 | "Email": "stkevintan@zju.edu.cn", 19 | "Telegram": "@kevinsfork", 20 | "Weibo": "@kevinclasky" 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /exampleSite/content/archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Archive" 3 | date: "2017-08-19T21:37:49+08:00" 4 | type: "archive" 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /exampleSite/content/posts/goisforlovers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: (Hu)go Template Primer 3 | tags: ["go", "golang", "templates", "themes", "development"] 4 | date: 2014-07-28 5 | --- 6 | 7 | Hugo uses the excellent [go][] [html/template][gohtmltemplate] library for 8 | its template engine. It is an extremely lightweight engine that provides a very 9 | small amount of logic. In our experience that it is just the right amount of 10 | logic to be able to create a good static website. If you have used other 11 | template systems from different languages or frameworks you will find a lot of 12 | similarities in go templates. 13 | 14 | This document is a brief primer on using go templates. The [go docs][gohtmltemplate] 15 | provide more details. 16 | 17 | ## Introduction to Go Templates 18 | 19 | Go templates provide an extremely simple template language. It adheres to the 20 | belief that only the most basic of logic belongs in the template or view layer. 21 | One consequence of this simplicity is that go templates parse very quickly. 22 | 23 | A unique characteristic of go templates is they are content aware. Variables and 24 | content will be sanitized depending on the context of where they are used. More 25 | details can be found in the [go docs][gohtmltemplate]. 26 | 27 | ## Basic Syntax 28 | 29 | Go lang templates are html files with the addition of variables and 30 | functions. 31 | 32 | **Go variables and functions are accessible within {{ }}** 33 | 34 | Accessing a predefined variable "foo": 35 | 36 | {{ foo }} 37 | 38 | **Parameters are separated using spaces** 39 | 40 | Calling the add function with input of 1, 2: 41 | 42 | {{ add 1 2 }} 43 | 44 | **Methods and fields are accessed via dot notation** 45 | 46 | Accessing the Page Parameter "bar" 47 | 48 | {{ .Params.bar }} 49 | 50 | **Parentheses can be used to group items together** 51 | 52 | {{ if or (isset .Params "alt") (isset .Params "caption") }} Caption {{ end }} 53 | 54 | 55 | ## Variables 56 | 57 | Each go template has a struct (object) made available to it. In hugo each 58 | template is passed either a page or a node struct depending on which type of 59 | page you are rendering. More details are available on the 60 | [variables](/layout/variables) page. 61 | 62 | A variable is accessed by referencing the variable name. 63 | 64 | {{ .Title }} 65 | 66 | Variables can also be defined and referenced. 67 | 68 | {{ $address := "123 Main St."}} 69 | {{ $address }} 70 | 71 | 72 | ## Functions 73 | 74 | Go template ship with a few functions which provide basic functionality. The go 75 | template system also provides a mechanism for applications to extend the 76 | available functions with their own. [Hugo template 77 | functions](/layout/functions) provide some additional functionality we believe 78 | are useful for building websites. Functions are called by using their name 79 | followed by the required parameters separated by spaces. Template 80 | functions cannot be added without recompiling hugo. 81 | 82 | **Example:** 83 | 84 | {{ add 1 2 }} 85 | 86 | ## Includes 87 | 88 | When including another template you will pass to it the data it will be 89 | able to access. To pass along the current context please remember to 90 | include a trailing dot. The templates location will always be starting at 91 | the /layout/ directory within Hugo. 92 | 93 | **Example:** 94 | 95 | {{ template "chrome/header.html" . }} 96 | 97 | 98 | ## Logic 99 | 100 | Go templates provide the most basic iteration and conditional logic. 101 | 102 | ### Iteration 103 | 104 | Just like in go, the go templates make heavy use of range to iterate over 105 | a map, array or slice. The following are different examples of how to use 106 | range. 107 | 108 | **Example 1: Using Context** 109 | 110 | {{ range array }} 111 | {{ . }} 112 | {{ end }} 113 | 114 | **Example 2: Declaring value variable name** 115 | 116 | {{range $element := array}} 117 | {{ $element }} 118 | {{ end }} 119 | 120 | **Example 2: Declaring key and value variable name** 121 | 122 | {{range $index, $element := array}} 123 | {{ $index }} 124 | {{ $element }} 125 | {{ end }} 126 | 127 | ### Conditionals 128 | 129 | If, else, with, or, & and provide the framework for handling conditional 130 | logic in Go Templates. Like range, each statement is closed with `end`. 131 | 132 | 133 | Go Templates treat the following values as false: 134 | 135 | * false 136 | * 0 137 | * any array, slice, map, or string of length zero 138 | 139 | **Example 1: If** 140 | 141 | {{ if isset .Params "title" }}

{{ index .Params "title" }}

{{ end }} 142 | 143 | **Example 2: If -> Else** 144 | 145 | {{ if isset .Params "alt" }} 146 | {{ index .Params "alt" }} 147 | {{else}} 148 | {{ index .Params "caption" }} 149 | {{ end }} 150 | 151 | **Example 3: And & Or** 152 | 153 | {{ if and (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}} 154 | 155 | **Example 4: With** 156 | 157 | An alternative way of writing "if" and then referencing the same value 158 | is to use "with" instead. With rebinds the context `.` within its scope, 159 | and skips the block if the variable is absent. 160 | 161 | The first example above could be simplified as: 162 | 163 | {{ with .Params.title }}

{{ . }}

{{ end }} 164 | 165 | **Example 5: If -> Else If** 166 | 167 | {{ if isset .Params "alt" }} 168 | {{ index .Params "alt" }} 169 | {{ else if isset .Params "caption" }} 170 | {{ index .Params "caption" }} 171 | {{ end }} 172 | 173 | ## Pipes 174 | 175 | One of the most powerful components of go templates is the ability to 176 | stack actions one after another. This is done by using pipes. Borrowed 177 | from unix pipes, the concept is simple, each pipeline's output becomes the 178 | input of the following pipe. 179 | 180 | Because of the very simple syntax of go templates, the pipe is essential 181 | to being able to chain together function calls. One limitation of the 182 | pipes is that they only can work with a single value and that value 183 | becomes the last parameter of the next pipeline. 184 | 185 | A few simple examples should help convey how to use the pipe. 186 | 187 | **Example 1 :** 188 | 189 | {{ if eq 1 1 }} Same {{ end }} 190 | 191 | is the same as 192 | 193 | {{ eq 1 1 | if }} Same {{ end }} 194 | 195 | It does look odd to place the if at the end, but it does provide a good 196 | illustration of how to use the pipes. 197 | 198 | **Example 2 :** 199 | 200 | {{ index .Params "disqus_url" | html }} 201 | 202 | Access the page parameter called "disqus_url" and escape the HTML. 203 | 204 | **Example 3 :** 205 | 206 | {{ if or (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}} 207 | Stuff Here 208 | {{ end }} 209 | 210 | Could be rewritten as 211 | 212 | {{ isset .Params "caption" | or isset .Params "title" | or isset .Params "attr" | if }} 213 | Stuff Here 214 | {{ end }} 215 | 216 | 217 | ## Context (aka. the dot) 218 | 219 | The most easily overlooked concept to understand about go templates is that {{ . }} 220 | always refers to the current context. In the top level of your template this 221 | will be the data set made available to it. Inside of a iteration it will have 222 | the value of the current item. When inside of a loop the context has changed. . 223 | will no longer refer to the data available to the entire page. If you need to 224 | access this from within the loop you will likely want to set it to a variable 225 | instead of depending on the context. 226 | 227 | **Example:** 228 | 229 | {{ $title := .Site.Title }} 230 | {{ range .Params.tags }} 231 |
  • {{ . }} - {{ $title }}
  • 232 | {{ end }} 233 | 234 | Notice how once we have entered the loop the value of {{ . }} has changed. We 235 | have defined a variable outside of the loop so we have access to it from within 236 | the loop. 237 | 238 | # Hugo Parameters 239 | 240 | Hugo provides the option of passing values to the template language 241 | through the site configuration (for sitewide values), or through the meta 242 | data of each specific piece of content. You can define any values of any 243 | type (supported by your front matter/config format) and use them however 244 | you want to inside of your templates. 245 | 246 | 247 | ## Using Content (page) Parameters 248 | 249 | In each piece of content you can provide variables to be used by the 250 | templates. This happens in the [front matter](/content/front-matter). 251 | 252 | An example of this is used in this documentation site. Most of the pages 253 | benefit from having the table of contents provided. Sometimes the TOC just 254 | doesn't make a lot of sense. We've defined a variable in our front matter 255 | of some pages to turn off the TOC from being displayed. 256 | 257 | Here is the example front matter: 258 | 259 | ``` 260 | --- 261 | title: "Permalinks" 262 | date: "2013-11-18" 263 | aliases: 264 | - "/doc/permalinks/" 265 | groups: ["extras"] 266 | groups_weight: 30 267 | notoc: true 268 | --- 269 | ``` 270 | 271 | Here is the corresponding code inside of the template: 272 | 273 | {{ if not .Params.notoc }} 274 |
    275 | {{ .TableOfContents }} 276 |
    277 | {{ end }} 278 | 279 | 280 | 281 | ## Using Site (config) Parameters 282 | In your top-level configuration file (eg, `config.yaml`) you can define site 283 | parameters, which are values which will be available to you in chrome. 284 | 285 | For instance, you might declare: 286 | 287 | ```yaml 288 | params: 289 | CopyrightHTML: "Copyright © 2013 John Doe. All Rights Reserved." 290 | TwitterUser: "spf13" 291 | SidebarRecentLimit: 5 292 | ``` 293 | 294 | Within a footer layout, you might then declare a `