favicon added
[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 ,* Homepage
136 :PROPERTIES:
137 :EXPORT_HUGO_SECTION:
138 :EXPORT_FILE_NAME: _index
139 :EXPORT_HUGO_MENU: :menu "main"
140 :END:
141 This is the home of my blog!
142 ,* Blog Posts
143 :PROPERTIES:
144 :EXPORT_HUGO_SECTION: posts
145 :END:
146 ,** My Blog Homepage
147 :PROPERTIES:
148 :EXPORT_HUGO_MENU: :menu "main"
149 :EXPORT_FILE_NAME: _index
150 :END:
151 Man, look at all my blog posts.
152 ,** One Bad Night
153 :PROPERTIES:
154 :EXPORT_FILE_NAME: bad-night
155 :END:
156 Someone gave me herpes! Oh no!
157 #+end_src
158 Which yields the following files on export:
159 #+begin_src
160 .
161 ├── content
162 │   ├── _index.md
163 │   └── posts
164 │   ├── bad-night.md
165 │   └── _index.md
166 └── hugotest.org
167 #+end_src
168 As you might expect if you're already familiar with Hugo, this structure adheres
169 to the Hugo [[https://gohugo.io/content-management/organization/][content management]] scheme. Additionally, the index files have been
170 marked with menu metadata, which allows Hugo themes to automatically generate
171 navigation menus from the markdown files. Hereafter, making new blog posts is as
172 simple as adding new sub-headings under the "Blog Posts" heading, and
173 exporting. As you can see, this is suitable for defining the hierarchical
174 structure of any general website, not just blogs. Org mode and Hugo just make
175 creating new pages so simple and well-structured that providing content is all
176 that's required for a new page, blog entry, or entirely new site section. If you
177 can blog with ox-hugo, you can deftly deploy any manner of web content, or even
178 develop entire websites as naturally as you make blog posts. Any tool that can
179 turn blogging and web development into the same task is quite an achievement!
180
181 Of course, themes to style this content are another can of worms entirely, but
182 we'll get to that soon. It is sufficient for now to mention that Hugo makes
183 [[https://gohugo.io/themes/installing-and-using-themes/][using themes]] as easy as downloading one and specifying it in Hugo's config file.
184
185 **** Heading Management
186 One question you may ask is why the blog's homepage is not defined in the *Blog
187 Posts* heading. This is a fair question! Any heading with an
188 ~:EXPORT_FILE_NAME:~ property will export /all/ of that heading's content,
189 /including subheadings/ beneath it. This allows Org headings to be used as part
190 of the content of a post, where they will be exported as markdown heading
191 levels, which translate to HTML heading elements ~<h1>~, ~<h2>~, ~<h3>~,
192 etcetera.
193
194 Furthermore, properties other than ~:EXPORT_FILE_NAME:~ are /inherited/ by
195 sub-headings, including the ~:EXPORT_HUGO_MENU:~ properties. A
196 ~:EXPORT_HUGO_MENU:~ property at the section root would cause all exported files
197 within that section to be added to the menu specified. This might be intended by
198 the content creator, but most likely you don't want every single post you make
199 to be in the main menu. So it makes sense to define all your pages, including
200 the index, as a sub-heading of the section definition (which merely specifies
201 which sub-directory the content will output to).
202
203 To illustrate, let's assume you want to extend the previous site definition with
204 a section about fishsticks. We'll do this the "wrong way" first to show how Org
205 handles inheritence:
206 #+begin_src org -n 24
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 This explains the flexibility of ox-hugo's straightforward parsing
282 rules. Specifically, that any headings with an ~:EXPORT_FILE_NAME:~ tag will
283 export everything beneath them as content. The content organization in this
284 erroneous example duplicates data, but might still be useful if you wanted to
285 create, for instance, an "all_content" page for the section. In general, though,
286 be sure to put your index pages in subheadings (just as you do with normal
287 pages) so that the tier-1 heading can be used for "global" definitions that
288 affect all of the pages. A /correct/ section for fishsticks should look like
289 this:
290 #+begin_src org -n 24
291 ,* Fishsticks
292 :PROPERTIES:
293 :EXPORT_HUGO_SECTION: fishsticks
294 :END:
295 ,** Fishsticks Home
296 :PROPERTIES:
297 :EXPORT_HUGO_MENU: :menu "main"
298 :EXPORT_FILE_NAME: _index
299 :END:
300 This section devoted to Orson Wells, R.I.P.
301 ,** Van De Camps
302 :PROPERTIES:
303 :EXPORT_FILE_NAME: van-de-camps
304 :END:
305 If this is fish, I'll be a monkey's uncle.
306 ,** Gortons
307 :PROPERTIES:
308 :EXPORT_FILE_NAME: gortons
309 :END:
310 I think these gave me the herpes.
311 #+end_src
312 Now the homepage for the fishsticks section has a heading all its own, just like
313 any other page. That's better! Now our homepage will output the content only
314 from its subheading, and the other pages don't inherit the homepage's
315 properties. All pages inherit the ~:EXPORT_HUGO_SECTION: fishsticks~ property
316 though, which is what we want to ensure that these pages are exported to the
317 proper section.
318
319 *** Hugo Setup
320 At this point, setting up Hugo and publishing is simple. [[https://gohugo.io/getting-started/installing/][Installing]] Hugo is
321 pretty straightforward on any Unix-like system with a package manager; it is
322 available on most distributions at this point. Windows installation is a bigger
323 pain in the ass, but you should be used to that if you're still in the
324 stone-age.
325
326 Using ~hugo new site .~ on the command-line will create a new hugo site in the
327 current directory, but ~hugo~ expects to be creating a new directory with this
328 command and will complain if it already exists. It also provides the ~--force~
329 option to allow creating a new site in an extant directory, but this too will
330 fail if the *content* subdirectory already exists (which ox-hugo will create
331 when you export).
332
333 So you have three choices:
334 1. run ~hugo new site /path/to/some-new-dir~ and move your Org file to this new
335 directory
336 2. simply ~rm -Rf content/~ to remove the content directory ox-hugo created,
337 then run ~hugo new site --force .~
338 3. don't even bother with the ~hugo new site~ command, and make a *config.toml*
339 file manually (the only file really required for Hugo to run).
340
341 It's convenient to do this through the ~hugo~ command because it will create
342 Hugo-specific subdirectories like archetypes, layouts, themes, etcetera, in
343 addition to populating a basic *config.toml* file. The subdirectories it creates
344 aren't necessary, but help illustrate Hugo's structure. In any case, you'll want
345 to wind up with a directory structure something like this (created with option 2
346 above, extending from previous examples):
347 #+begin_src
348 .
349 ├── archetypes
350 │   └── default.md
351 ├── config.toml
352 ├── content
353 ├── data
354 ├── hugotest.org
355 ├── layouts
356 ├── static
357 └── themes
358 #+end_src
359 Exporting with ox-hugo using ~C-c C-e H A~ again will, as expected, fill the
360 content directory with our content.
361 #+begin_src
362 .
363 ├── archetypes
364 │   └── default.md
365 ├── config.toml
366 ├── content
367 │   ├── fishsticks
368 │   │   ├── gortons.md
369 │   │   ├── _index.md
370 │   │   └── van-de-camps.md
371 │   ├── _index.md
372 │   └── posts
373 │   ├── bad-night.md
374 │   └── _index.md
375 ├── data
376 ├── hugotest.org
377 ├── layouts
378 ├── static
379 └── themes
380 #+end_src
381
382 **** Theming
383 The last thing to do here is to download or create a theme for Hugo. As
384 mentioned before, installing a theme is very simple. This blog uses a custom
385 theme named Speedy that I have been developing to help myself learn Hugo's
386 internals, but for this example I'll be using Kaushal Modi's [[https://github.com/kaushalmodi/hugo-bare-min-theme][bare-min theme]]. The
387 bare-min theme is the best starting place out there for making new themes, and
388 outputs basic HTML pages without any need to mess with CSS or JS. It also
389 provides easy debugging facilities and search features.
390
391 So let's install it! You can download the theme from its github page and extract
392 it to the themes folder, or much more easily use git to clone it to your themes
393 directory. ~git clone https://github.com/kaushalmodi/hugo-bare-min-theme.git
394 themes/bare-min~ Then open up your *config.toml* file, and add the theme.
395 #+begin_src toml -n
396 baseURL = "http://example.org/"
397 languageCode = "en-us"
398 title = "My New Hugo Site"
399 # Adding a theme:
400 theme = "bare-min"
401 #+end_src
402 Be sure that the theme's name matches the theme directory's name in the *themes/*
403 directory of your project base directory. (e.g. *themes/bare-min* here). That's it
404 for installing the theme.
405
406 Now, running the command ~hugo~ with no subcommands will invoke the Hugo
407 generator on the current directory, and output finalized content in the
408 *public/* directory.
409 #+begin_src
410 .
411 ├── archetypes
412 │   └── default.md
413 ├── config.toml
414 ├── content
415 │   ├── fishsticks
416 │   │   ├── gortons.md
417 │   │   ├── _index.md
418 │   │   └── van-de-camps.md
419 │   ├── _index.md
420 │   └── posts
421 │   ├── bad-night.md
422 │   └── _index.md
423 ├── data
424 ├── hugotest.org
425 ├── layouts
426 ├── public
427 │   ├── categories
428 │   │   ├── index.html
429 │   │   └── index.xml
430 │   ├── css
431 │   │   └── github_chroma.css
432 │   ├── fishsticks
433 │   │   ├── gortons
434 │   │   │   └── index.html
435 │   │   ├── index.html
436 │   │   ├── index.xml
437 │   │   └── van-de-camps
438 │   │   └── index.html
439 │   ├── index.html
440 │   ├── index.xml
441 │   ├── js
442 │   │   └── search.js
443 │   ├── page
444 │   │   └── 1
445 │   │   └── index.html
446 │   ├── posts
447 │   │   ├── bad-night
448 │   │   │   └── index.html
449 │   │   ├── index.html
450 │   │   └── index.xml
451 │   ├── sitemap.xml
452 │   └── tags
453 │   ├── index.html
454 │   └── index.xml
455 ├── static
456 └── themes ...
457 #+end_src
458 Hugo, by default, generates xml files that are suitable for RSS feeds. With a
459 theme installed, Hugo will produce more suitable web content (usually HTML) to
460 be served over HTTP. The bare-min theme outputs HTML, provides CSS for doing
461 chroma-based syntax highlighting (in case you include code blocks), and inline
462 styles for basic page formatting. Generated pages also have a lot of useful
463 debugging information. You'll also notice that Hugo has generated folders for
464 "categories" and "tags". These are default organization labels for your content
465 called [[https://gohugo.io/content-management/taxonomies/][taxonomies]].
466
467 **** Taxonomies
468 The taxonomy index pages allow users to browse content by category or tag. These
469 taxonomies correspond to Org mode tags, and ox-hugo will automatically
470 associated tagged headings with the tags taxonomy, or the categories taxonomy if
471 prefixed with an @ symbol. You are free to define your own taxonomies, and even
472 disable the default "tags" and "categories" taxonomies, but since Org mode tags
473 directly translate to the default Hugo taxonomies, it makes sense to just use
474 the default taxonomies for now.
475
476 As an example of taxonomies, I'll add some tags and categories to our
477 *hugotest.org* file to create a complete blog structure with tags and categories:
478 #+begin_src org -n
479 #+hugo_base_dir: .
480 ,* Homepage
481 :PROPERTIES:
482 :EXPORT_HUGO_SECTION:
483 :EXPORT_FILE_NAME: _index
484 :EXPORT_HUGO_MENU: :menu "main"
485 :END:
486 This is the home of my blog!
487 ,* Blog Posts
488 :PROPERTIES:
489 :EXPORT_HUGO_SECTION: posts
490 :END:
491 ,** My Blog Homepage
492 :PROPERTIES:
493 :EXPORT_HUGO_MENU: :menu "main"
494 :EXPORT_FILE_NAME: _index
495 :END:
496 Man, look at all my blog posts.
497 ,** One Bad Night :@updates:herpes:fear:
498 :PROPERTIES:
499 :EXPORT_FILE_NAME: bad-night
500 :END:
501 Someone gave me herpes! Oh no!
502 ,* Fishsticks
503 :PROPERTIES:
504 :EXPORT_HUGO_SECTION: fishsticks
505 :END:
506 ,** Fishsticks Home
507 :PROPERTIES:
508 :EXPORT_HUGO_MENU: :menu "main"
509 :EXPORT_FILE_NAME: _index
510 :END:
511 This section devoted to Orson Wells, R.I.P.
512 ,** Van De Camps :@reviews:fear:
513 :PROPERTIES:
514 :EXPORT_FILE_NAME: van-de-camps
515 :END:
516 If this is fish, I'll be a monkey's uncle.
517 ,** Gortons :@reviews:herpes:
518 :PROPERTIES:
519 :EXPORT_FILE_NAME: gortons
520 :END:
521 I think these gave me the herpes.
522 #+end_src
523 Exporting *hugotest.org* with ~C-c C-e H A~ and generating with ~hugo~ will yield
524 the same file structure as before, but this time we'll see that the categories
525 and tags directories have sections for our newly added taxonomies.
526 #+begin_src
527 .
528 └── public
529 ├── categories
530 │   ├── index.html
531 │   ├── index.xml
532 │   ├── reviews
533 │   │   ├── index.html
534 │   │   └── index.xml
535 │   └── updates
536 │   ├── index.html
537 │   └── index.xml
538 └── tags
539 ├── fear
540 │   ├── index.html
541 │   └── index.xml
542 ├── herpes
543 │   ├── index.html
544 │   └── index.xml
545 ├── index.html
546 └── index.xml
547 #+end_src
548 The index pages of taxonomies provide a list of all available taxonomies of that
549 type, each with list pages that show all content associated with them. This
550 allows themes to easily build navigation pages for browsing or querying
551 taxonomies. Files like these are often useful to output as JSON (done by the
552 theme) to allow Javascript-driven dynamic search features, but a simpler scheme
553 can output HTML pages to browse taxonomies just as you would posts in a section
554 (i.e. Org mode heading).
555
556 **** Serving Content
557 You can now serve the *public/* directory over an HTTP server. Hugo is packaged
558 with an internal [[https://gohugo.io/commands/hugo_server/][HTTP server]] to help with testing, which is quite convenient
559 because it can automatically refresh whenever content in its *content/* directory
560 is updated (so when you export from ox-hugo, you don't have to run ~hugo~
561 again). To use it, simply run ~hugo server~ and point your browser at
562 http://localhost:1313 (1313 is the default ~--port~ argument for ~hugo server~).
563
564 *** Additional Information
565 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
566 this point you've got a fully functional blog publishing workflow from start to
567 finish that you can view in-browser as you develop.
568
569 **** Attaching Files, Capturing Information & Automation
570 Once you have a basic site structured in your Org file, you're ready to start
571 throwing information in it. It is of course sufficient to open the Org file and
572 edit it, but most Org mode users prefer to automate /everything/, and being able
573 to use Org's capture feature to instantly populate new blog posts is extremely
574 convenient.
575
576 The [[https://ox-hugo.scripter.co/][ox-hugo documentation]] provides succinct explanations on how to do this,
577 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
578 exports]] when you save your Org file (so no more need to ~C-c C-e H A~ every
579 time, just save the file as usual with ~C-x C-s~).
580
581 **** Indexes and Page Resources
582 You may be wondering why our index pages are exported as *_index* rather than
583 *index*. Hugo uses a concept called [[https://gohugo.io/content-management/page-bundles/][Page Bundles]] to organize exported
584 content. The gist of this is that a file named *index* is known as a "Leaf Node"
585 and cannot have any children. A file named *_index* is considered a "Branch
586 Node" and allows nesting other bundles beneath it. In other words, an Org
587 heading with an exported file name of *index* will be treated as a single page
588 with no subfolders. This is useful for single pages, but a section index
589 (e.g. for a blog) with many subpages and other resources will more than likely
590 want to allow nested bundles beneath it.
591
592 You may export an Org heading as a Page Bundle by providing the Org property
593 ~:EXPORT_HUGO_BUNDLE:~ with an argument (string) that will become the name of
594 the folder created. If you do this, you will need to set the
595 ~:EXPORT_FILE_NAME:~ property to either *index* for Leaf Nodes, or *_index* for
596 Branch Nodes.
597
598 The [[https://ox-hugo.scripter.co/doc/org-capture-setup/][capture setup]] provided by Kaushal Modi above provides methods to
599 automatically create either a normal page, or a leaf node bundle when invoking
600 Org Capture.
601
602 **** Drafts and Automatic Timestamps
603 By default, Hugo will not build any markdown files whose front-matter properties
604 include ~draft: true~. This is very convenient for in-progress posts that you
605 leave in your Org file, or in the *content/* directory.
606
607 Ox-hugo will always fill out the draft property, and by default every exported
608 header will have its draft property set to *false*. However, ox-hugo also links
609 this behavior to the TODO feature of Org. When you cycle a heading's TODO value
610 with ~S-<RIGHT>~ (that's Shift + Right Arrow Key), you will signal to ox-hugo to
611 export this heading as a draft (i.e. ~draft: true~), which will prevent Hugo
612 from building it into an HTML page.
613
614 When a heading is cycled to the DONE state in Org, it will automatically
615 generate a timestamp for when the heading was closed. Ox-hugo will export DONE
616 headings with ~draft: false~ and, better still, will use Org's timestamp to fill
617 out the Date property in the markdown file. This makes it trivial to manage
618 writing multiple posts at once, and automatically timestamp completion dates.
619
620 You may also explicitly set this date parameter with the ~:EXPORT_DATE:~
621 property, but the ease of using DONE-state switching is pretty hard to pass up.
622
623 **** Renaming Tags and Other Properties
624 If a theme you are using has any idiosyncrasies about your naming conventions
625 (e.g. if you export your content to more than one site using more than one
626 theme), ox-hugo provides a [[https://ox-hugo.scripter.co/doc/replace-front-matter-keys/][convenient way]] to automatically replace any key
627 values on export. This can be done on a per-heading, or a per-file basis.
628
629 To replace keys for the entire file, simply add a property to the top of your
630 Org file. For example:
631 #+begin_src org
632 #+hugo_front_matter_key_replace: description>summary
633 #+end_src
634 This will make any ~:EXPORT_DESCRIPTION:~ properties export, instead, to a
635 "summary" key in the front-matter of your output markdown file. It will also be
636 able to replace exported values in the Org body:
637 #+begin_src org
638 ,#+begin_description
639 This is the description,
640 it has multiple lines too!
641 It will export as the Summary value in front-matter
642 ,#+end_description
643 #+end_src
644 To do this on a per-heading basis, simply add the
645 ~:EXPORT_HUGO_FRONT_MATTER_KEY_REPLACE:~ property to a heading's property block,
646 and the replacements will only occur within that heading.
647
648 **** Why not use Hugo's internal Org parser?
649 It's true that Hugo has an internal Org parser that is well maintained. It
650 provides this as an alternative to markdown files. You may wonder, then, why
651 someone would use Org mode to export to markdown instead of just letting Hugo
652 parse the Org files itself. The answer is two-fold:
653 1. Hugo's Org format is currently less feature complete than markdown, so
654 exporting from Org mode to the Hugo Org Format would limit potential output.
655 2. Org mode is a lot more than just a file format, and its integration with your
656 system allows all kinds of benefits you can never get out of a simple Org
657 file parser.
658 Therefore, supporting the Org format in another tool will give you a superior
659 text format for organizing information, but it will be crippled when compared to
660 an actual Org mode implementation. Ox-hugo gives you the ability to use Org mode
661 itself to generate content.
662
663 If Hugo's Org parser gains parity with, or eclipses, the Blackfriday Markdown
664 format currently used by Hugo, ox-hugo could certainly be used to output those
665 Org-Hugo files instead of the current markdown. This would be nice because it
666 would allow Org mode users to view their output content more easily, but the
667 advantages of ox-hugo and a real, bona fide Org mode would still remain.
668
669 So you see, Hugo's Org parser isn't really in competition with ox-hugo, it's in
670 competition with the /other/ Hugo parsers (e.g. markdown).
671
672 *** Thanks
673 Thanks to Kaushal Modi, who found this article on the googs within days of me
674 posting it, for reaching out to me and providing thorough feedback and error
675 checking.
676
677 And special thanks to me, for once again overcoming Hamhock the Laziness Demon
678 who has possessed me since birth and hates it when I do anything productive.
679
680 ** DONE I did a blog :blog:org:emacs:hugo:
681 CLOSED: [2018-04-06 Fri 18:29]
682 :PROPERTIES:
683 :EXPORT_FILE_NAME: ox-hugo
684 :EXPORT_DESCRIPTION: "Exporting to Hugo's Blackfriday Markdown from Orgmode"
685 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/org.png
686 :END:
687 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
688 content generator [[https://gohugo.io/][Hugo]], which I use for this website. Today I integrated its
689 expectations about file structure into the Speedy theme for this blog, allowing
690 me to keep all blog contents in a single Org mode file and export [[http://en.wikipedia.org/wiki/markdown][markdown]]
691 content for Hugo's excellent [[https://github.com/russross/blackfriday][blackfriday markdown parser]] (a markdown format with
692 many added features). Hugo does support limited parsing of org files internally,
693 but Org mode features like inline spreadsheets and system communication are
694 beyond the scope of most external tools, so Org mode is best used as an
695 exporter. As an Emacs user, this allows me to instantly capture interesting
696 information I come across and publish it within seconds. Now I have no excuses!
697
698 * Forth
699 :PROPERTIES:
700 :EXPORT_FILE_NAME: _index
701 :EXPORT_HUGO_MENU: :menu "main"
702 :EXPORT_HUGO_SECTION: forth
703 :EXPORT_DESCRIPTION: "Highly Factored Code"
704 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/forth.png
705 :END:
706 This is where I post my watForth programs.
707
708 At present, my forth testbed is located at https://forth.kengrimes.com
709
710 * Code Repositories
711 :PROPERTIES:
712 :EXPORT_FILE_NAME: _index
713 :EXPORT_HUGO_MENU: :menu "main" :title Git
714 :EXPORT_HUGO_SECTION: git
715 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/git.png
716 :END:
717 <iframe height="600px" width="100%" frameborder="0" scrolling="no" src="/gitweb" onload="resizeIFrame(this)">
718 <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
719 <a href="https://git.kengrimes.com">https://git.kengrimes.com</a>
720 </iframe>
721
722 * About
723 :PROPERTIES:
724 :EXPORT_HUGO_SECTION: about
725 :EXPORT_HUGO_MENU: :menu "main" :title About
726 :EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/home.png
727 :EXPORT_FILE_NAME: _index
728 :END:
729 #+begin_description
730 Ken Grimes
731
732 Computer Scientist
733
734 At Large
735 #+end_description
736 Hi! I'm Ken, a 34-year-old computer scientist currently living in Irvine,
737 California. This is a website I've constructed for the purpose of developing
738 web-facing software. I will probably blog with it once development is
739 complete. In the meantime, if you're curious, this is my [[file:static/cv.pdf][curriculum vitae]]
740