revised ox-hugo tutorial for errors
[kengrimes.com/content.git] / content.org
1 #+hugo_base_dir: .
2 #+hugo_level_offset: 0
3 #+seq_todo: TODO DRAFT DONE
4 #+startup: indent showall
5
6 * Home
7 :PROPERTIES:
8 :EXPORT_HUGO_SECTION:
9 :END:
10 ** Computers are the Devil
11 :PROPERTIES:
12 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/blog.png
13 :EXPORT_FILE_NAME: _index
14 :EXPORT_HUGO_MENU: :menu "main" :weight -1 :title Blog
15 :END:
16
17 ** DONE Using ox-hugo To Build Websites with Emacs :org:emacs:hugo:@tutorial:
18 CLOSED: [2018-04-19 Thu 18:06]
19 :PROPERTIES:
20 :EXPORT_FILE_NAME: ox-hugo-tutorial
21 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/org.png
22 :END:
23 This article explains in detail the process of setting up a bare-bones website
24 using Hugo and Org mode. My goal in writing this is to provide readers with a
25 superior understanding of the fundamentals of this workflow. It is by no means
26 an exhaustive explanation of Org mode or Emacs, but should give readers of any
27 skill level a strong foundation to apply their own knowledge and techniques to
28 the Emacs-Hugo toolchain.
29
30 I assume only beginner-level knowledge of Emacs.
31
32 *** Intro & Setup
33 [[https://github.com/kaushalmodi][Kaushal Modi]] created ox-hugo on top of his ox-blackfriday package, providing an
34 impressive amount of features for organizing blog text and linked data with
35 Hugo. He maintains [[https://ox-hugo.scripter.co/][great documentation]] and ample [[https://github.com/kaushalmodi/ox-hugo/tree/master/test/site/content-org][examples]] for using the
36 package. I will explain my own workflow here, but for an exhaustive (though
37 terse) reference, I highly recommend Modi's [[https://ox-hugo.scripter.co/test/][test site]] and [[https://raw.githubusercontent.com/kaushalmodi/ox-hugo/master/test/site/content-org/all-posts.org][post source]] Org file,
38 which contain demonstrations and tests for all of ox-hugo's features.
39
40 After issuing the Emacs command ~M-x package-install RET ox-hugo RET~, you'll
41 need to ~require~ it. You can do this by running ~M-: (require 'ox-hugo)~, but
42 you'll want to add it to your configuration as explained [[https://ox-hugo.scripter.co/doc/usage/][here]]. Once this is
43 done, using ox-hugo is just a matter of making an Org file and writing
44 content. Org's format is very straightforward, and is designed to make sense to
45 the reader even if they're unfamiliar with the formal syntax. For instance,
46 #+begin_src org
47 ,* My food
48 | Where's My Food? | Fridge | Counter | Mouth | Total |
49 | Oranges | 1 | 3 | 0 | :=vsum($2..$4) |
50 | Marshmallows | 0 | 100 | 20 | :=vsum($2..$4) |
51 | Brussel Sprouts | 32 | 4 | 0 | :=vsum($2..$4) |
52 #+end_src
53 Produces a dynamic spreadsheet table in Org mode that exports to HTML like this:
54 **** My food
55 | Where's My Food? | Fridge | Counter | Mouth | Total |
56 | Oranges | 1 | 3 | 0 | 4 |
57 | Marshmallows | 0 | 100 | 20 | 120 |
58 | Brussel Sprouts | 32 | 4 | 0 | 36 |
59 #+TBLFM: @2$5=vsum($2..$4)::@3$5=vsum($2..$4)::@4$5=vsum($2..$4)
60
61 If you're already familiar with Org mode, the benefits are obvious and creating
62 content is fairly trivial. Org mode is, however, a complex and expansive program
63 with many features, and its learning curve can appear daunting at first glance.
64 Using ox-hugo is a great way to learn the format, since it gives the author a
65 command-center view of their entire content hierarchy, much like a traditional
66 database, but in a flat format that's much easier to read and understand. Org
67 features present themselves naturally, and the author can easily visualize the
68 correspondence between the Org format and the output on their webpage.
69
70 Just take a look at the [[https://www.kengrimes.com/gitweb/?p=kengrimes.com/content.git;a=blob_plain;f=content.org;hb=HEAD][Org file]] for this webpage. Search for "ox-hugo is super
71 cool!" and you should find this very paragraph.
72
73 Eventually you'll want to [[https://orgmode.org/manual/][read the manual]], though. You may access it in Emacs
74 with ~M-x org-info~.
75
76 *** Making a New Blog
77 Compared to a generic Org file, the only necessary data that ox-hugo needs to
78 properly export to Hugo is an ~:EXPORT_FILE_NAME:~ property in the
79 ~:PROPERTIES:~ block of an Org heading. ~:PROPERTIES:~ blocks are common in Org
80 for defining arbitrary metadata about sections, and ox-hugo uses them to
81 generate Hugo's [[https://gohugo.io/content-management/front-matter/][front matter]] (used for associating a title, header, or other
82 custom data with the page it generates). Providing an ~:EXPORT_FILE_NAME:~
83 definition signals to ox-hugo that a particular heading is available for export
84 to Hugo. For example, the ~:PROPERTIES:~ block of the page you're currently
85 reading looks like this:
86 #+begin_src org
87 :PROPERTIES:
88 :EXPORT_FILE_NAME: ox-hugo-tutorial
89 :EXPORT_DESCRIPTION: Exporting to Hugo's Blackfriday Markdown from Orgmode
90 :EXPORT_HUGO_IMAGES: /img/org.png
91 :END:
92 #+end_src
93 The ~:EXPORT_HUGO_IMAGES:~ and ~:EXPORT_DESCRIPTION:~ variables are optional
94 definitions allowed by the Speedy theme of this website, but the filename is the
95 only required property for ox-hugo. Our goal here is to organize the structure
96 of our website as a tree using Org headers. So, as a minimal example, here's
97 what a new site might look like in its entirety:
98 #+begin_src org -n
99 #+hugo_base_dir: .
100 ,* My Blog
101 :PROPERTIES:
102 :EXPORT_HUGO_SECTION:
103 :END:
104 ,** Home
105 :PROPERTIES:
106 :EXPORT_FILE_NAME: _index
107 :END:
108 This is the home of my blog!
109 ,** One Bad Night
110 :PROPERTIES:
111 :EXPORT_FILE_NAME: bad-night
112 :END:
113 Someone gave me herpes! Oh no!
114 #+end_src
115 The Org file can be placed in any directory so long as ~HUGO_BASE_DIR~ correctly
116 identifies the Hugo project's root directory. This path definition is required
117 for any valid ox-hugo file, and in the example above uses ~#+hugo_base_dir: .~
118 to specify that the base directory will be the same path as this Org file. If
119 you saved this file as hugotest.org, exported it with Org's exporter ~C-c C-e~
120 and selected the Hugo output ~H~ and the All Subtrees To Files option ~A~, you'd
121 wind up with the following files in your directory:
122 #+begin_src
123 .
124 ├── content
125 │   ├── bad-night.md
126 │   └── _index.md
127 └── hugotest.org
128 #+end_src
129 Most sites will be more than a blog, though, and will want multiple sections. In
130 fact, many sites are made up of nothing but a slew of sections that users
131 navigate between with some built-in menu. So a more functional minimal example
132 would be the following:
133 #+begin_src org -n
134 #+hugo_base_dir: .
135 ,* Site Root
136 ,** Homepage
137 :PROPERTIES:
138 :EXPORT_HUGO_SECTION:
139 :EXPORT_FILE_NAME: _index
140 :EXPORT_HUGO_MENU: :menu "main"
141 :END:
142 This is the home of my blog!
143 ,** Blog Posts
144 :PROPERTIES:
145 :EXPORT_HUGO_SECTION: posts
146 :END:
147 ,*** My Blog Homepage
148 :PROPERTIES:
149 :EXPORT_HUGO_MENU: :menu "main"
150 :EXPORT_FILE_NAME: _index
151 :END:
152 Man, look at all my blog posts.
153 ,*** One Bad Night
154 :PROPERTIES:
155 :EXPORT_FILE_NAME: bad-night
156 :END:
157 Someone gave me herpes! Oh no!
158 #+end_src
159 Which yields the following files on export:
160 #+begin_src
161 .
162 ├── content
163 │   ├── _index.md
164 │   └── posts
165 │   ├── bad-night.md
166 │   └── _index.md
167 └── hugotest.org
168 #+end_src
169 As you might expect if you're already familiar with Hugo, this structure adheres
170 to the Hugo [[https://gohugo.io/content-management/organization/][content management]] scheme. Additionally, the index files have been
171 marked with menu metadata, which allows Hugo themes to automatically generate
172 navigation menus from the markdown files. Hereafter, making new blog posts is as
173 simple as adding new sub-headings under the "Blog Posts" heading, and
174 exporting. As you can see, this is suitable for defining the hierarchical
175 structure of any general website, not just blogs. Org mode and Hugo just make
176 creating new pages so simple and well-structured that providing content is all
177 that's required for a new page, blog entry, or entirely new site section. If you
178 can blog with ox-hugo, you can deftly deploy any manner of web content, or even
179 develop entire websites as naturally as you make blog posts. Any tool that can
180 turn blogging and web development into the same task is quite an achievement!
181
182 Of course, themes to style this content are another can of worms entirely, but
183 we'll get to that soon. It is sufficient for now to mention that Hugo makes
184 [[https://gohugo.io/themes/installing-and-using-themes/][using themes]] as easy as downloading one and specifying it in Hugo's config file.
185
186 **** Heading Management
187 One question you may ask is why the blog's homepage is not defined in the *Blog
188 Posts* heading. This is a fair question! Any heading with an
189 ~:EXPORT_FILE_NAME:~ property will export /all/ of that heading's content,
190 /including subheadings/ beneath it. This allows Org headings to be used as part
191 of the content of a post, where they will be exported as markdown heading
192 levels, which translate to HTML heading elements ~<h1>~, ~<h2>~, ~<h3>~,
193 etcetera.
194
195 Furthermore, properties other than ~:EXPORT_FILE_NAME:~ are /inherited/ by
196 sub-headings, including the ~:EXPORT_HUGO_MENU:~ properties. A
197 ~:EXPORT_HUGO_MENU:~ property at the section root would cause all exported files
198 within that section to be added to the menu specified. This might be intended by
199 the content creator, but most likely you don't want every single post you make
200 to be in the main menu. So it makes sense to define all your pages, including
201 the index, as a sub-heading of the section definition (which merely specifies
202 which sub-directory the content will output to).
203
204 To illustrate, let's assume you want to extend the previous site definition with
205 a section about fishsticks.
206 #+begin_src org -n 25
207 ,** Fishsticks
208 :PROPERTIES:
209 :EXPORT_HUGO_SECTION: fishsticks
210 :EXPORT_HUGO_MENU: :menu "main"
211 :EXPORT_FILE_NAME: _index
212 :END:
213 This section devoted to Orson Wells, R.I.P.
214 ,*** Van De Camps
215 :PROPERTIES:
216 :EXPORT_FILE_NAME: van-de-camps
217 :END:
218 If this is fish, I'll be a monkey's uncle.
219 ,*** Gortons
220 :PROPERTIES:
221 :EXPORT_FILE_NAME: gortons
222 :END:
223 I think these gave me the herpes.
224 #+end_src
225 In this example, we've defined the main homepage of the section inside the
226 tier-1 heading for Fishsticks. This is technically valid, and produces the
227 expected file output:
228 #+begin_src
229 .
230 ├── content
231 │   ├── fishsticks
232 │   │   ├── gortons.md
233 │   │   ├── _index.md
234 │   │   └── van-de-camps.md
235 │   ├── _index.md
236 │   └── posts
237 │   ├── bad-night.md
238 │   └── _index.md
239 └── hugotest.org
240 #+end_src
241 But on inspection of the gortons.md file, we find the anomoly mentioned above:
242 #+begin_src markdown -n
243 ---
244 title: "Gortons"
245 author: ["Ken Grimes"]
246 draft: false
247 menu:
248 main:
249 weight: 2002
250 identifier: "gortons"
251 ---
252
253 I think these gave me the herpes.
254 #+end_src
255 Uh oh! Not only did these fishsticks give us herpes, they are now part of the
256 main menu. Worse, when the index page was exported, each of the subsequent posts
257 became part of its content:
258 #+begin_src markdown -n
259 ---
260 title: "Fishsticks"
261 author: ["Ken Grimes"]
262 draft: false
263 menu:
264 main:
265 weight: 1001
266 identifier: "fishsticks"
267 ---
268
269 This section devoted to Orson Wells, R.I.P.
270
271
272 ## Van De Camps {#van-de-camps}
273
274 If this is fish, I'll be a monkey's uncle.
275
276
277 ## Gortons {#gortons}
278
279 I think these gave me the herpes.
280 #+end_src
281 Tisk tisk. So be sure to put your index pages in subheadings (just as you do
282 with normal pages) so that the tier-1 heading can be used for "global"
283 definitions that affect all of the pages. A corrected section for fishsticks
284 would look like this:
285 #+begin_src org -n 25
286 ,** Fishsticks
287 :PROPERTIES:
288 :EXPORT_HUGO_SECTION: fishsticks
289 :END:
290 ,*** Fishsticks Home
291 :PROPERTIES:
292 :EXPORT_HUGO_MENU: :menu "main"
293 :EXPORT_FILE_NAME: _index
294 :END:
295 This section devoted to Orson Wells, R.I.P.
296 ,*** Van De Camps
297 :PROPERTIES:
298 :EXPORT_FILE_NAME: van-de-camps
299 :END:
300 If this is fish, I'll be a monkey's uncle.
301 ,*** Gortons
302 :PROPERTIES:
303 :EXPORT_FILE_NAME: gortons
304 :END:
305 I think these gave me the herpes.
306 #+end_src
307
308 *** Hugo Setup
309 At this point, setting up Hugo and publishing is simple. [[https://gohugo.io/getting-started/installing/][Installing]] Hugo is
310 pretty straightforward on any Unix-like system with a package manager; it is
311 available on most distributions at this point. Windows installation is a bigger
312 pain in the ass, but you should be used to that if you're still in the
313 stone-age.
314
315 Using ~hugo new site .~ on the command-line will create a new hugo site in the
316 current directory, but ~hugo~ expects to be creating a new directory with this
317 command and will complain if it already exists. It also provides the ~--force~
318 option to allow creating a new site in an extant directory, but this too will
319 fail if the *content* subdirectory already exists (which ox-hugo will create
320 when you export).
321
322 So you have three choices:
323 1. run ~hugo new site /path/to/some-new-dir~ and move your Org file to this new
324 directory
325 2. simply ~rm -Rf content/~ to remove the content directory ox-hugo created,
326 then run ~hugo new site --force .~
327 3. don't even bother with the ~hugo new site~ command, and make a *config.toml*
328 file manually (the only file really required for Hugo to run).
329
330 It's convenient to do this through the ~hugo~ command because it will create
331 Hugo-specific subdirectories like archetypes, layouts, themes, etcetera, in
332 addition to populating a basic *config.toml* file. The subdirectories it creates
333 aren't necessary, but help illustrate Hugo's structure. In any case, you'll want
334 to wind up with a directory structure something like this (created with option 2
335 above, extending from previous examples):
336 #+begin_src
337 .
338 ├── archetypes
339 │   └── default.md
340 ├── config.toml
341 ├── content
342 ├── data
343 ├── hugotest.org
344 ├── layouts
345 ├── static
346 └── themes
347 #+end_src
348 Exporting with ox-hugo using ~C-c C-e H A~ again will, as expected, fill the
349 content directory with our content.
350 #+begin_src
351 .
352 ├── archetypes
353 │   └── default.md
354 ├── config.toml
355 ├── content
356 │   ├── fishsticks
357 │   │   ├── gortons.md
358 │   │   ├── _index.md
359 │   │   └── van-de-camps.md
360 │   ├── _index.md
361 │   └── posts
362 │   ├── bad-night.md
363 │   └── _index.md
364 ├── data
365 ├── hugotest.org
366 ├── layouts
367 ├── static
368 └── themes
369 #+end_src
370
371 **** Theming
372 The last thing to do here is to download or create a theme for Hugo. As
373 mentioned before, installing a theme is very simple. This blog uses a custom
374 theme named Speedy that I have been developing to help myself learn Hugo's
375 internals, but for this example I'll be using Kaushal Modi's [[https://github.com/kaushalmodi/hugo-bare-min-theme][bare-min theme]]. The
376 bare-min theme is the best starting place out there for making new themes, and
377 outputs basic HTML pages without any need to mess with CSS or JS. It also
378 provides easy debugging facilities and search features.
379
380 So let's install it! You can download the theme from its github page and extract
381 it to the themes folder, or much more easily use git to clone it to your themes
382 directory. ~git clone https://github.com/kaushalmodi/hugo-bare-min-theme.git
383 themes/bare-min~ Then open up your *config.toml* file, and add the theme.
384 #+begin_src toml -n
385 baseURL = "http://example.org/"
386 languageCode = "en-us"
387 title = "My New Hugo Site"
388 # Adding a theme:
389 theme = "bare-min"
390 #+end_src
391 Be sure that the theme's name matches the theme directory's name in the *themes/*
392 directory of your project base directory. (e.g. *themes/bare-min* here). That's it
393 for installing the theme.
394
395 Now, running the command ~hugo~ with no subcommands will invoke the Hugo
396 generator on the current directory, and output finalized content in the
397 *public/* directory.
398 #+begin_src
399 .
400 ├── archetypes
401 │   └── default.md
402 ├── config.toml
403 ├── content
404 │   ├── fishsticks
405 │   │   ├── gortons.md
406 │   │   ├── _index.md
407 │   │   └── van-de-camps.md
408 │   ├── _index.md
409 │   └── posts
410 │   ├── bad-night.md
411 │   └── _index.md
412 ├── data
413 ├── hugotest.org
414 ├── layouts
415 ├── public
416 │   ├── categories
417 │   │   ├── index.html
418 │   │   └── index.xml
419 │   ├── css
420 │   │   └── github_chroma.css
421 │   ├── fishsticks
422 │   │   ├── gortons
423 │   │   │   └── index.html
424 │   │   ├── index.html
425 │   │   ├── index.xml
426 │   │   └── van-de-camps
427 │   │   └── index.html
428 │   ├── index.html
429 │   ├── index.xml
430 │   ├── js
431 │   │   └── search.js
432 │   ├── page
433 │   │   └── 1
434 │   │   └── index.html
435 │   ├── posts
436 │   │   ├── bad-night
437 │   │   │   └── index.html
438 │   │   ├── index.html
439 │   │   └── index.xml
440 │   ├── sitemap.xml
441 │   └── tags
442 │   ├── index.html
443 │   └── index.xml
444 ├── static
445 └── themes ...
446 #+end_src
447 Hugo, by default, generates xml files that are suitable for RSS feeds. With a
448 theme installed, Hugo will produce more suitable web content (usually HTML) to
449 be served over HTTP. The bare-min theme outputs HTML, provides CSS for doing
450 chroma-based syntax highlighting (in case you include code blocks), and inline
451 styles for basic page formatting. Generated pages also have a lot of useful
452 debugging information. You'll also notice that Hugo has generated folders for
453 "categories" and "tags". These are default organization labels for your content
454 called [[https://gohugo.io/content-management/taxonomies/][taxonomies]].
455
456 **** Taxonomies
457 The taxonomy index pages allow users to browse content by category or tag. These
458 taxonomies correspond to Org mode tags, and ox-hugo will automatically
459 associated tagged headings with the tags taxonomy, or the categories taxonomy if
460 prefixed with an @ symbol. You are free to define your own taxonomies, and even
461 disable the default "tags" and "categories" taxonomies, but since Org mode tags
462 directly translate to the default Hugo taxonomies, it makes sense to just use
463 the default taxonomies for now.
464
465 As an example of taxonomies, I'll add some tags and categories to our
466 *hugotest.org* file to create a complete blog structure with tags and categories:
467 #+begin_src org -n
468 #+hugo_base_dir: .
469 ,* Site Root
470 ,** Homepage
471 :PROPERTIES:
472 :EXPORT_HUGO_SECTION:
473 :EXPORT_FILE_NAME: _index
474 :EXPORT_HUGO_MENU: :menu "main"
475 :END:
476 This is the home of my blog!
477 ,** Blog Posts
478 :PROPERTIES:
479 :EXPORT_HUGO_SECTION: posts
480 :END:
481 ,*** My Blog Homepage
482 :PROPERTIES:
483 :EXPORT_HUGO_MENU: :menu "main"
484 :EXPORT_FILE_NAME: _index
485 :END:
486 Man, look at all my blog posts.
487 ,*** One Bad Night :@updates:herpes:fear:
488 :PROPERTIES:
489 :EXPORT_FILE_NAME: bad-night
490 :END:
491 Someone gave me herpes! Oh no!
492 ,** Fishsticks
493 :PROPERTIES:
494 :EXPORT_HUGO_SECTION: fishsticks
495 :END:
496 ,*** Fishsticks Home
497 :PROPERTIES:
498 :EXPORT_HUGO_MENU: :menu "main"
499 :EXPORT_FILE_NAME: _index
500 :END:
501 This section devoted to Orson Wells, R.I.P.
502 ,*** Van De Camps :@reviews:fear:
503 :PROPERTIES:
504 :EXPORT_FILE_NAME: van-de-camps
505 :END:
506 If this is fish, I'll be a monkey's uncle.
507 ,*** Gortons :@reviews:herpes:
508 :PROPERTIES:
509 :EXPORT_FILE_NAME: gortons
510 :END:
511 I think these gave me the herpes.
512 #+end_src
513 Exporting *hugotest.org* with ~C-c C-e H A~ and generating with ~hugo~ will yield
514 the same file structure as before, but this time we'll see that the categories
515 and tags directories have sections for our newly added taxonomies.
516 #+begin_src
517 .
518 └── public
519 ├── categories
520 │   ├── index.html
521 │   ├── index.xml
522 │   ├── reviews
523 │   │   ├── index.html
524 │   │   └── index.xml
525 │   └── updates
526 │   ├── index.html
527 │   └── index.xml
528 └── tags
529 ├── fear
530 │   ├── index.html
531 │   └── index.xml
532 ├── herpes
533 │   ├── index.html
534 │   └── index.xml
535 ├── index.html
536 └── index.xml
537 #+end_src
538 The index pages of taxonomies provide a list of all available taxonomies of that
539 type, each with list pages that show all content associated with them. This
540 allows themes to easily build navigation pages for browsing or querying
541 taxonomies. Files like these are often useful to output as JSON (done by the
542 theme) to allow Javascript-driven dynamic search features, but a simpler scheme
543 can output HTML pages to browse taxonomies just as you would posts in a section
544 (i.e. Org mode heading).
545
546 **** Serving Content
547 You can now serve the *public/* directory over an HTTP server. Hugo is packaged
548 with an internal [[https://gohugo.io/commands/hugo_server/][HTTP server]] to help with testing, which is quite convenient
549 because it can automatically refresh whenever content in its *content/* directory
550 is updated (so when you export from ox-hugo, you don't have to run ~hugo~
551 again). To use it, simply run ~hugo server~ and point your browser at
552 http://localhost:1313 (1313 is the default ~--port~ argument for ~hugo server~).
553
554 *** Additional Information
555 Eventually you'll want to move on to [[https://themes.gohugo.io/][other themes]], or [[https://gohugo.io/themes/creating/][develop your own]], but at
556 this point you've got a fully functional blog publishing workflow from start to
557 finish that you can view in-browser as you develop.
558
559 **** Attaching Files, Capturing Information & Automation
560 Once you have a basic site structured in your Org file, you're ready to start
561 throwing information in it. It is of course sufficient to open the Org file and
562 edit it, but most Org mode users prefer to automate /everything/, and being able
563 to use Org's capture feature to instantly populate new blog posts is extremely
564 convenient.
565
566 The [[https://ox-hugo.scripter.co/][ox-hugo documentation]] provides succinct explanations on how to do this,
567 including elisp snippets for [[https://ox-hugo.scripter.co/doc/org-capture-setup/][capture setup]], [[https://ox-hugo.scripter.co/doc/images-in-content/][image linking]], and [[https://ox-hugo.scripter.co/doc/auto-export-on-saving/][automating
568 exports]] when you save your Org file (so no more need to ~C-c C-e H A~ every
569 time, just save the file as usual with ~C-x C-s~).
570
571 **** Indexes and Page Resources
572 You may be wondering why our index pages are exported as *_index* rather than
573 *index*. Hugo uses a concept called [[https://gohugo.io/content-management/page-bundles/][Page Bundles]] to organize exported
574 content. The gist of this is that a file named *index* is known as a "Leaf Node"
575 and cannot have any children. A file named *_index* is considered a "Branch
576 Node" and allows nesting other bundles beneath it. In other words, an Org
577 heading with an exported file name of *index* will be treated as a single page
578 with no subfolders. This is useful for single pages, but a section index
579 (e.g. for a blog) with many subpages and other resources will more than likely
580 want to allow nested bundles beneath it.
581
582 You may export an Org heading as a Page Bundle by providing the Org property
583 ~:EXPORT_HUGO_BUNDLE:~ with an argument (string) that will become the name of
584 the folder created. If you do this, you will need to set the
585 ~:EXPORT_FILE_NAME:~ property to either *index* for Leaf Nodes, or *_index* for
586 Branch Nodes.
587
588 The [[https://ox-hugo.scripter.co/doc/org-capture-setup/][capture setup]] provided by Kaushal Modi above provides methods to
589 automatically create either a normal page, or a leaf node bundle when invoking
590 Org Capture.
591
592 **** Drafts and Automatic Timestamps
593 By default, Hugo will not build any markdown files whose front-matter properties
594 include ~draft: true~. This is very convenient for in-progress posts that you
595 leave in your Org file, or in the *content/* directory. If you are using
596 archetypes (which define default front-matter for various resource types, and
597 may include Hugo templating directives), you can see that the primary archetype
598 in *archetypes/default.md* set the draft property to true on all content unless
599 the markdown file overrides this behavior:
600 #+begin_src markdown
601 ---
602 title: "{{ replace .Name "-" " " | title }}"
603 date: {{ .Date }}
604 draft: true
605 ---
606 #+end_src
607
608 Ox-hugo will always fill out the draft property, overriding this archetype's
609 default value. By default, every exported header will have its draft property
610 set to *false*. However, ox-hugo conveniently links this behavior to the TODO
611 feature of Org. When you cycle a heading's TODO value with ~S-<RIGHT>~ (that's
612 Shift + Right Arrow Key), you will signal to ox-hugo to export this heading as
613 a draft (i.e. ~draft: true~), which will prevent Hugo from building it into an
614 HTML page.
615
616 Better still, when a heading is cycled to the DONE state in Org, it will
617 automatically generate a timestamp for when the heading was closed. Ox-hugo will
618 export DONE headings with ~draft: false~ and, better still, will use Org's
619 timestamp to fill out the Date property in the markdown file. This makes it
620 trivial to manage writing multiple posts at once, and automatically timestamp
621 completion dates.
622
623 You may also explicitly set this date parameter with the ~:EXPORT_DATE:~
624 property, but the convenience of using DONE-state switching is pretty hard to
625 pass up.
626
627 **** Renaming Tags and Other Properties
628 If a theme you are using has any idiosyncrasies about your naming conventions
629 (e.g. if you export your content to more than one site using more than one
630 theme), ox-hugo provides a [[https://ox-hugo.scripter.co/doc/replace-front-matter-keys/][convenient way]] to automatically replace any key
631 values on export. This can be done on a per-heading, or a per-file basis.
632
633 To replace keys for the entire file, simply add a property to the top of your
634 Org file. For example:
635 #+begin_src org
636 #+hugo_front_matter_key_replace: description>summary
637 #+end_src
638 This will make any ~:EXPORT_DESCRIPTION:~ properties export, instead, to a
639 "summary" key in the front-matter of your output markdown file. It will also be
640 able to replace exported values in the Org body:
641 #+begin_src org
642 ,#+begin_description
643 This is the description, but will export as the Summary value in front-matter
644 ,#+end_description
645 #+end_src
646 To do this on a per-heading basis, simply add the
647 ~:EXPORT_HUGO_FRONT_MATTER_KEY_REPLACE:~ property to a heading's property block,
648 and the replacements will only occur within that heading.
649
650 ** DONE I did a blog :blog:org:emacs:hugo:
651 CLOSED: [2018-04-06 Fri 18:29]
652 :PROPERTIES:
653 :EXPORT_FILE_NAME: ox-hugo
654 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :heading "Exporting to Hugo's Blackfriday Markdown from Orgmode"
655 :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :header /img/org.png
656 :END:
657 ox-hugo is an [[http://en.wikipedia.org/wiki/Emacs][Emacs]] package for [[http://en.wikipedia.org/wiki/org-mode][Org mode]] that produces input for the static
658 content generator [[https://gohugo.io/][Hugo]], which I use for this website. Today I integrated its
659 expectations about file structure into the Speedy theme for this blog, allowing
660 me to keep all blog contents in a single Org mode file and export [[http://en.wikipedia.org/wiki/markdown][markdown]]
661 content for Hugo's excellent [[https://github.com/russross/blackfriday][blackfriday markdown parser]] (a markdown format with
662 many added features). Hugo does support limited parsing of org files internally,
663 but Org mode features like inline spreadsheets and system communication are
664 beyond the scope of most external tools, so Org mode is best used as an
665 exporter. As an Emacs user, this allows me to instantly capture interesting
666 information I come across and publish it within seconds. Now I have no excuses!
667
668 * Forth
669 :PROPERTIES:
670 :EXPORT_FILE_NAME: _index
671 :EXPORT_HUGO_MENU: :menu "main"
672 :EXPORT_HUGO_SECTION: forth
673 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :heading "Highly Factored Code"
674 :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :header /img/forth.png
675 :END:
676 This is where I post my watForth programs.
677
678 At present, my forth testbed is located at https://forth.kengrimes.com
679
680 * Code Repositories
681 :PROPERTIES:
682 :EXPORT_FILE_NAME: _index
683 :EXPORT_HUGO_MENU: :menu "main" :title Git
684 :EXPORT_HUGO_SECTION: git
685 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/git.png
686 :END:
687 <iframe height="600px" width="100%" frameborder="0" scrolling="no" src="/gitweb" onload="resizeIFrame(this)">
688 <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
689 <a href="https://git.kengrimes.com">https://git.kengrimes.com</a>
690 </iframe>
691
692 * About
693 :PROPERTIES:
694 :EXPORT_HUGO_SECTION: about
695 :EXPORT_HUGO_MENU: :menu "main" :title About
696 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :heading '("Ken Grimes" "Computer Scientist" "At Large")
697 :EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :header /img/home.png
698 :EXPORT_FILE_NAME: _index
699 :END:
700 Hi! I'm Ken, a 34-year-old computer scientist currently living in Irvine,
701 California. This is a website I've constructed for the purpose of developing
702 web-facing software. I will probably blog with it once development is
703 complete. In the mean time, if you're curious, this is my [[file:static/cv.pdf][curriculum vitae]]
704