#+hugo_base_dir: .
#+hugo_level_offset: 0
#+seq_todo: TODO DRAFT DONE
#+startup: indent showall
* Home
:PROPERTIES:
:EXPORT_HUGO_SECTION:
:END:
** Computers are the Devil
:PROPERTIES:
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/blog.png
:EXPORT_FILE_NAME: _index
:EXPORT_HUGO_MENU: :menu "main" :weight -1 :title Blog
:END:
** DONE Using ox-hugo To Build Websites with Emacs :org:emacs:hugo:@tutorial:
CLOSED: [2018-04-19 Thu 18:06]
:PROPERTIES:
:EXPORT_FILE_NAME: ox-hugo-tutorial
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/org.png
:END:
This article explains in detail the process of setting up a bare-bones website
using Hugo and Org mode. My goal in writing this is to provide readers with a
superior understanding of the fundamentals of this workflow. It is by no means
an exhaustive explanation of Org mode or Emacs, but should give readers of any
skill level a strong foundation to apply their own knowledge and techniques to
the Emacs-Hugo toolchain.
I assume only beginner-level knowledge of Emacs.
*** Intro & Setup
[[https://github.com/kaushalmodi][Kaushal Modi]] created ox-hugo on top of his ox-blackfriday package, providing an
impressive amount of features for organizing blog text and linked data with
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
package. I will explain my own workflow here, but for an exhaustive (though
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,
which contain demonstrations and tests for all of ox-hugo's features.
After issuing the Emacs command ~M-x package-install RET ox-hugo RET~, you'll
need to ~require~ it. You can do this by running ~M-: (require 'ox-hugo)~, but
you'll want to add it to your configuration as explained [[https://ox-hugo.scripter.co/doc/usage/][here]]. Once this is
done, using ox-hugo is just a matter of making an Org file and writing
content. Org's format is very straightforward, and is designed to make sense to
the reader even if they're unfamiliar with the formal syntax. For instance,
#+begin_src org
,* My food
| Where's My Food? | Fridge | Counter | Mouth | Total |
| Oranges | 1 | 3 | 0 | :=vsum($2..$4) |
| Marshmallows | 0 | 100 | 20 | :=vsum($2..$4) |
| Brussel Sprouts | 32 | 4 | 0 | :=vsum($2..$4) |
#+end_src
Produces a dynamic spreadsheet table in Org mode that exports to HTML like this:
**** My food
| Where's My Food? | Fridge | Counter | Mouth | Total |
| Oranges | 1 | 3 | 0 | 4 |
| Marshmallows | 0 | 100 | 20 | 120 |
| Brussel Sprouts | 32 | 4 | 0 | 36 |
#+TBLFM: @2$5=vsum($2..$4)::@3$5=vsum($2..$4)::@4$5=vsum($2..$4)
If you're already familiar with Org mode, the benefits are obvious and creating
content is fairly trivial. Org mode is, however, a complex and expansive program
with many features, and its learning curve can appear daunting at first glance.
Using ox-hugo is a great way to learn the format, since it gives the author a
command-center view of their entire content hierarchy, much like a traditional
database, but in a flat format that's much easier to read and understand. Org
features present themselves naturally, and the author can easily visualize the
correspondence between the Org format and the output on their webpage.
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
cool!" and you should find this very paragraph.
Eventually you'll want to [[https://orgmode.org/manual/][read the manual]], though. You may access it in Emacs
with ~M-x org-info~.
*** Making a New Blog
Compared to a generic Org file, the only necessary data that ox-hugo needs to
properly export to Hugo is an ~:EXPORT_FILE_NAME:~ property in the
~:PROPERTIES:~ block of an Org heading. ~:PROPERTIES:~ blocks are common in Org
for defining arbitrary metadata about sections, and ox-hugo uses them to
generate Hugo's [[https://gohugo.io/content-management/front-matter/][front matter]] (used for associating a title, header, or other
custom data with the page it generates). Providing an ~:EXPORT_FILE_NAME:~
definition signals to ox-hugo that a particular heading is available for export
to Hugo. For example, the ~:PROPERTIES:~ block of the page you're currently
reading looks like this:
#+begin_src org
:PROPERTIES:
:EXPORT_FILE_NAME: ox-hugo-tutorial
:EXPORT_DESCRIPTION: Exporting to Hugo's Blackfriday Markdown from Orgmode
:EXPORT_HUGO_IMAGES: /img/org.png
:END:
#+end_src
The ~:EXPORT_HUGO_IMAGES:~ and ~:EXPORT_DESCRIPTION:~ variables are optional
definitions allowed by the Speedy theme of this website, but the filename is the
only required property for ox-hugo. Our goal here is to organize the structure
of our website as a tree using Org headers. So, as a minimal example, here's
what a new site might look like in its entirety:
#+begin_src org -n
#+hugo_base_dir: .
,* My Blog
:PROPERTIES:
:EXPORT_HUGO_SECTION:
:END:
,** Home
:PROPERTIES:
:EXPORT_FILE_NAME: _index
:END:
This is the home of my blog!
,** One Bad Night
:PROPERTIES:
:EXPORT_FILE_NAME: bad-night
:END:
Someone gave me herpes! Oh no!
#+end_src
The Org file can be placed in any directory so long as ~HUGO_BASE_DIR~ correctly
identifies the Hugo project's root directory. This path definition is required
for any valid ox-hugo file, and in the example above uses ~#+hugo_base_dir: .~
to specify that the base directory will be the same path as this Org file. If
you saved this file as hugotest.org, exported it with Org's exporter ~C-c C-e~
and selected the Hugo output ~H~ and the All Subtrees To Files option ~A~, you'd
wind up with the following files in your directory:
#+begin_src
.
├── content
│ ├── bad-night.md
│ └── _index.md
└── hugotest.org
#+end_src
Most sites will be more than a blog, though, and will want multiple sections. In
fact, many sites are made up of nothing but a slew of sections that users
navigate between with some built-in menu. So a more functional minimal example
would be the following:
#+begin_src org -n
#+hugo_base_dir: .
,* Homepage
:PROPERTIES:
:EXPORT_HUGO_SECTION:
:EXPORT_FILE_NAME: _index
:EXPORT_HUGO_MENU: :menu "main"
:END:
This is the home of my blog!
,* Blog Posts
:PROPERTIES:
:EXPORT_HUGO_SECTION: posts
:END:
,** My Blog Homepage
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu "main"
:EXPORT_FILE_NAME: _index
:END:
Man, look at all my blog posts.
,** One Bad Night
:PROPERTIES:
:EXPORT_FILE_NAME: bad-night
:END:
Someone gave me herpes! Oh no!
#+end_src
Which yields the following files on export:
#+begin_src
.
├── content
│ ├── _index.md
│ └── posts
│ ├── bad-night.md
│ └── _index.md
└── hugotest.org
#+end_src
As you might expect if you're already familiar with Hugo, this structure adheres
to the Hugo [[https://gohugo.io/content-management/organization/][content management]] scheme. Additionally, the index files have been
marked with menu metadata, which allows Hugo themes to automatically generate
navigation menus from the markdown files. Hereafter, making new blog posts is as
simple as adding new sub-headings under the "Blog Posts" heading, and
exporting. As you can see, this is suitable for defining the hierarchical
structure of any general website, not just blogs. Org mode and Hugo just make
creating new pages so simple and well-structured that providing content is all
that's required for a new page, blog entry, or entirely new site section. If you
can blog with ox-hugo, you can deftly deploy any manner of web content, or even
develop entire websites as naturally as you make blog posts. Any tool that can
turn blogging and web development into the same task is quite an achievement!
Of course, themes to style this content are another can of worms entirely, but
we'll get to that soon. It is sufficient for now to mention that Hugo makes
[[https://gohugo.io/themes/installing-and-using-themes/][using themes]] as easy as downloading one and specifying it in Hugo's config file.
**** Heading Management
One question you may ask is why the blog's homepage is not defined in the *Blog
Posts* heading. This is a fair question! Any heading with an
~:EXPORT_FILE_NAME:~ property will export /all/ of that heading's content,
/including subheadings/ beneath it. This allows Org headings to be used as part
of the content of a post, where they will be exported as markdown heading
levels, which translate to HTML heading elements ~
~, ~~, ~~,
etcetera.
Furthermore, properties other than ~:EXPORT_FILE_NAME:~ are /inherited/ by
sub-headings, including the ~:EXPORT_HUGO_MENU:~ properties. A
~:EXPORT_HUGO_MENU:~ property at the section root would cause all exported files
within that section to be added to the menu specified. This might be intended by
the content creator, but most likely you don't want every single post you make
to be in the main menu. So it makes sense to define all your pages, including
the index, as a sub-heading of the section definition (which merely specifies
which sub-directory the content will output to).
To illustrate, let's assume you want to extend the previous site definition with
a section about fishsticks. We'll do this the "wrong way" first to show how Org
handles inheritence:
#+begin_src org -n 24
,* Fishsticks
:PROPERTIES:
:EXPORT_HUGO_SECTION: fishsticks
:EXPORT_HUGO_MENU: :menu "main"
:EXPORT_FILE_NAME: _index
:END:
This section devoted to Orson Wells, R.I.P.
,** Van De Camps
:PROPERTIES:
:EXPORT_FILE_NAME: van-de-camps
:END:
If this is fish, I'll be a monkey's uncle.
,** Gortons
:PROPERTIES:
:EXPORT_FILE_NAME: gortons
:END:
I think these gave me the herpes.
#+end_src
In this example, we've defined the main homepage of the section inside the
tier-1 heading for Fishsticks. This is /technically/ valid, and produces the
expected file output:
#+begin_src
.
├── content
│ ├── fishsticks
│ │ ├── gortons.md
│ │ ├── _index.md
│ │ └── van-de-camps.md
│ ├── _index.md
│ └── posts
│ ├── bad-night.md
│ └── _index.md
└── hugotest.org
#+end_src
But on inspection of the gortons.md file, we find the anomoly mentioned above:
#+begin_src markdown -n
---
title: "Gortons"
author: ["Ken Grimes"]
draft: false
menu:
main:
weight: 2002
identifier: "gortons"
---
I think these gave me the herpes.
#+end_src
Uh oh! Not only did these fishsticks give us herpes, they are now part of the
main menu. Worse, when the index page was exported, each of the subsequent posts
became part of its content:
#+begin_src markdown -n
---
title: "Fishsticks"
author: ["Ken Grimes"]
draft: false
menu:
main:
weight: 1001
identifier: "fishsticks"
---
This section devoted to Orson Wells, R.I.P.
## Van De Camps {#van-de-camps}
If this is fish, I'll be a monkey's uncle.
## Gortons {#gortons}
I think these gave me the herpes.
#+end_src
This explains the flexibility of ox-hugo's straightforward parsing
rules. Specifically, that any headings with an ~:EXPORT_FILE_NAME:~ tag will
export everything beneath them as content. The content organization in this
erroneous example duplicates data, but might still be useful if you wanted to
create, for instance, an "all_content" page for the section. In general, though,
be sure to put your index pages in subheadings (just as you do with normal
pages) so that the tier-1 heading can be used for "global" definitions that
affect all of the pages. A /correct/ section for fishsticks should look like
this:
#+begin_src org -n 24
,* Fishsticks
:PROPERTIES:
:EXPORT_HUGO_SECTION: fishsticks
:END:
,** Fishsticks Home
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu "main"
:EXPORT_FILE_NAME: _index
:END:
This section devoted to Orson Wells, R.I.P.
,** Van De Camps
:PROPERTIES:
:EXPORT_FILE_NAME: van-de-camps
:END:
If this is fish, I'll be a monkey's uncle.
,** Gortons
:PROPERTIES:
:EXPORT_FILE_NAME: gortons
:END:
I think these gave me the herpes.
#+end_src
Now the homepage for the fishsticks section has a heading all its own, just like
any other page. That's better! Now our homepage will output the content only
from its subheading, and the other pages don't inherit the homepage's
properties. All pages inherit the ~:EXPORT_HUGO_SECTION: fishsticks~ property
though, which is what we want to ensure that these pages are exported to the
proper section.
*** Hugo Setup
At this point, setting up Hugo and publishing is simple. [[https://gohugo.io/getting-started/installing/][Installing]] Hugo is
pretty straightforward on any Unix-like system with a package manager; it is
available on most distributions at this point. Windows installation is a bigger
pain in the ass, but you should be used to that if you're still in the
stone-age.
Using ~hugo new site .~ on the command-line will create a new hugo site in the
current directory, but ~hugo~ expects to be creating a new directory with this
command and will complain if it already exists. It also provides the ~--force~
option to allow creating a new site in an extant directory, but this too will
fail if the *content* subdirectory already exists (which ox-hugo will create
when you export).
So you have three choices:
1. run ~hugo new site /path/to/some-new-dir~ and move your Org file to this new
directory
2. simply ~rm -Rf content/~ to remove the content directory ox-hugo created,
then run ~hugo new site --force .~
3. don't even bother with the ~hugo new site~ command, and make a *config.toml*
file manually (the only file really required for Hugo to run).
It's convenient to do this through the ~hugo~ command because it will create
Hugo-specific subdirectories like archetypes, layouts, themes, etcetera, in
addition to populating a basic *config.toml* file. The subdirectories it creates
aren't necessary, but help illustrate Hugo's structure. In any case, you'll want
to wind up with a directory structure something like this (created with option 2
above, extending from previous examples):
#+begin_src
.
├── archetypes
│ └── default.md
├── config.toml
├── content
├── data
├── hugotest.org
├── layouts
├── static
└── themes
#+end_src
Exporting with ox-hugo using ~C-c C-e H A~ again will, as expected, fill the
content directory with our content.
#+begin_src
.
├── archetypes
│ └── default.md
├── config.toml
├── content
│ ├── fishsticks
│ │ ├── gortons.md
│ │ ├── _index.md
│ │ └── van-de-camps.md
│ ├── _index.md
│ └── posts
│ ├── bad-night.md
│ └── _index.md
├── data
├── hugotest.org
├── layouts
├── static
└── themes
#+end_src
**** Theming
The last thing to do here is to download or create a theme for Hugo. As
mentioned before, installing a theme is very simple. This blog uses a custom
theme named Speedy that I have been developing to help myself learn Hugo's
internals, but for this example I'll be using Kaushal Modi's [[https://github.com/kaushalmodi/hugo-bare-min-theme][bare-min theme]]. The
bare-min theme is the best starting place out there for making new themes, and
outputs basic HTML pages without any need to mess with CSS or JS. It also
provides easy debugging facilities and search features.
So let's install it! You can download the theme from its github page and extract
it to the themes folder, or much more easily use git to clone it to your themes
directory. ~git clone https://github.com/kaushalmodi/hugo-bare-min-theme.git
themes/bare-min~ Then open up your *config.toml* file, and add the theme.
#+begin_src toml -n
baseURL = "http://example.org/"
languageCode = "en-us"
title = "My New Hugo Site"
# Adding a theme:
theme = "bare-min"
#+end_src
Be sure that the theme's name matches the theme directory's name in the *themes/*
directory of your project base directory. (e.g. *themes/bare-min* here). That's it
for installing the theme.
Now, running the command ~hugo~ with no subcommands will invoke the Hugo
generator on the current directory, and output finalized content in the
*public/* directory.
#+begin_src
.
├── archetypes
│ └── default.md
├── config.toml
├── content
│ ├── fishsticks
│ │ ├── gortons.md
│ │ ├── _index.md
│ │ └── van-de-camps.md
│ ├── _index.md
│ └── posts
│ ├── bad-night.md
│ └── _index.md
├── data
├── hugotest.org
├── layouts
├── public
│ ├── categories
│ │ ├── index.html
│ │ └── index.xml
│ ├── css
│ │ └── github_chroma.css
│ ├── fishsticks
│ │ ├── gortons
│ │ │ └── index.html
│ │ ├── index.html
│ │ ├── index.xml
│ │ └── van-de-camps
│ │ └── index.html
│ ├── index.html
│ ├── index.xml
│ ├── js
│ │ └── search.js
│ ├── page
│ │ └── 1
│ │ └── index.html
│ ├── posts
│ │ ├── bad-night
│ │ │ └── index.html
│ │ ├── index.html
│ │ └── index.xml
│ ├── sitemap.xml
│ └── tags
│ ├── index.html
│ └── index.xml
├── static
└── themes ...
#+end_src
Hugo, by default, generates xml files that are suitable for RSS feeds. With a
theme installed, Hugo will produce more suitable web content (usually HTML) to
be served over HTTP. The bare-min theme outputs HTML, provides CSS for doing
chroma-based syntax highlighting (in case you include code blocks), and inline
styles for basic page formatting. Generated pages also have a lot of useful
debugging information. You'll also notice that Hugo has generated folders for
"categories" and "tags". These are default organization labels for your content
called [[https://gohugo.io/content-management/taxonomies/][taxonomies]].
**** Taxonomies
The taxonomy index pages allow users to browse content by category or tag. These
taxonomies correspond to Org mode tags, and ox-hugo will automatically
associated tagged headings with the tags taxonomy, or the categories taxonomy if
prefixed with an @ symbol. You are free to define your own taxonomies, and even
disable the default "tags" and "categories" taxonomies, but since Org mode tags
directly translate to the default Hugo taxonomies, it makes sense to just use
the default taxonomies for now.
As an example of taxonomies, I'll add some tags and categories to our
*hugotest.org* file to create a complete blog structure with tags and categories:
#+begin_src org -n
#+hugo_base_dir: .
,* Homepage
:PROPERTIES:
:EXPORT_HUGO_SECTION:
:EXPORT_FILE_NAME: _index
:EXPORT_HUGO_MENU: :menu "main"
:END:
This is the home of my blog!
,* Blog Posts
:PROPERTIES:
:EXPORT_HUGO_SECTION: posts
:END:
,** My Blog Homepage
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu "main"
:EXPORT_FILE_NAME: _index
:END:
Man, look at all my blog posts.
,** One Bad Night :@updates:herpes:fear:
:PROPERTIES:
:EXPORT_FILE_NAME: bad-night
:END:
Someone gave me herpes! Oh no!
,* Fishsticks
:PROPERTIES:
:EXPORT_HUGO_SECTION: fishsticks
:END:
,** Fishsticks Home
:PROPERTIES:
:EXPORT_HUGO_MENU: :menu "main"
:EXPORT_FILE_NAME: _index
:END:
This section devoted to Orson Wells, R.I.P.
,** Van De Camps :@reviews:fear:
:PROPERTIES:
:EXPORT_FILE_NAME: van-de-camps
:END:
If this is fish, I'll be a monkey's uncle.
,** Gortons :@reviews:herpes:
:PROPERTIES:
:EXPORT_FILE_NAME: gortons
:END:
I think these gave me the herpes.
#+end_src
Exporting *hugotest.org* with ~C-c C-e H A~ and generating with ~hugo~ will yield
the same file structure as before, but this time we'll see that the categories
and tags directories have sections for our newly added taxonomies.
#+begin_src
.
└── public
├── categories
│ ├── index.html
│ ├── index.xml
│ ├── reviews
│ │ ├── index.html
│ │ └── index.xml
│ └── updates
│ ├── index.html
│ └── index.xml
└── tags
├── fear
│ ├── index.html
│ └── index.xml
├── herpes
│ ├── index.html
│ └── index.xml
├── index.html
└── index.xml
#+end_src
The index pages of taxonomies provide a list of all available taxonomies of that
type, each with list pages that show all content associated with them. This
allows themes to easily build navigation pages for browsing or querying
taxonomies. Files like these are often useful to output as JSON (done by the
theme) to allow Javascript-driven dynamic search features, but a simpler scheme
can output HTML pages to browse taxonomies just as you would posts in a section
(i.e. Org mode heading).
**** Serving Content
You can now serve the *public/* directory over an HTTP server. Hugo is packaged
with an internal [[https://gohugo.io/commands/hugo_server/][HTTP server]] to help with testing, which is quite convenient
because it can automatically refresh whenever content in its *content/* directory
is updated (so when you export from ox-hugo, you don't have to run ~hugo~
again). To use it, simply run ~hugo server~ and point your browser at
http://localhost:1313 (1313 is the default ~--port~ argument for ~hugo server~).
*** Additional Information
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
this point you've got a fully functional blog publishing workflow from start to
finish that you can view in-browser as you develop.
**** Attaching Files, Capturing Information & Automation
Once you have a basic site structured in your Org file, you're ready to start
throwing information in it. It is of course sufficient to open the Org file and
edit it, but most Org mode users prefer to automate /everything/, and being able
to use Org's capture feature to instantly populate new blog posts is extremely
convenient.
The [[https://ox-hugo.scripter.co/][ox-hugo documentation]] provides succinct explanations on how to do this,
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
exports]] when you save your Org file (so no more need to ~C-c C-e H A~ every
time, just save the file as usual with ~C-x C-s~).
**** Indexes and Page Resources
You may be wondering why our index pages are exported as *_index* rather than
*index*. Hugo uses a concept called [[https://gohugo.io/content-management/page-bundles/][Page Bundles]] to organize exported
content. The gist of this is that a file named *index* is known as a "Leaf Node"
and cannot have any children. A file named *_index* is considered a "Branch
Node" and allows nesting other bundles beneath it. In other words, an Org
heading with an exported file name of *index* will be treated as a single page
with no subfolders. This is useful for single pages, but a section index
(e.g. for a blog) with many subpages and other resources will more than likely
want to allow nested bundles beneath it.
You may export an Org heading as a Page Bundle by providing the Org property
~:EXPORT_HUGO_BUNDLE:~ with an argument (string) that will become the name of
the folder created. If you do this, you will need to set the
~:EXPORT_FILE_NAME:~ property to either *index* for Leaf Nodes, or *_index* for
Branch Nodes.
The [[https://ox-hugo.scripter.co/doc/org-capture-setup/][capture setup]] provided by Kaushal Modi above provides methods to
automatically create either a normal page, or a leaf node bundle when invoking
Org Capture.
**** Drafts and Automatic Timestamps
By default, Hugo will not build any markdown files whose front-matter properties
include ~draft: true~. This is very convenient for in-progress posts that you
leave in your Org file, or in the *content/* directory.
Ox-hugo will always fill out the draft property, and by default every exported
header will have its draft property set to *false*. However, ox-hugo also links
this behavior to the TODO feature of Org. When you cycle a heading's TODO value
with ~S-~ (that's Shift + Right Arrow Key), you will signal to ox-hugo to
export this heading as a draft (i.e. ~draft: true~), which will prevent Hugo
from building it into an HTML page.
When a heading is cycled to the DONE state in Org, it will automatically
generate a timestamp for when the heading was closed. Ox-hugo will export DONE
headings with ~draft: false~ and, better still, will use Org's timestamp to fill
out the Date property in the markdown file. This makes it trivial to manage
writing multiple posts at once, and automatically timestamp completion dates.
You may also explicitly set this date parameter with the ~:EXPORT_DATE:~
property, but the ease of using DONE-state switching is pretty hard to pass up.
**** Renaming Tags and Other Properties
If a theme you are using has any idiosyncrasies about your naming conventions
(e.g. if you export your content to more than one site using more than one
theme), ox-hugo provides a [[https://ox-hugo.scripter.co/doc/replace-front-matter-keys/][convenient way]] to automatically replace any key
values on export. This can be done on a per-heading, or a per-file basis.
To replace keys for the entire file, simply add a property to the top of your
Org file. For example:
#+begin_src org
#+hugo_front_matter_key_replace: description>summary
#+end_src
This will make any ~:EXPORT_DESCRIPTION:~ properties export, instead, to a
"summary" key in the front-matter of your output markdown file. It will also be
able to replace exported values in the Org body:
#+begin_src org
,#+begin_description
This is the description,
it has multiple lines too!
It will export as the Summary value in front-matter
,#+end_description
#+end_src
To do this on a per-heading basis, simply add the
~:EXPORT_HUGO_FRONT_MATTER_KEY_REPLACE:~ property to a heading's property block,
and the replacements will only occur within that heading.
**** Why not use Hugo's internal Org parser?
It's true that Hugo has an internal Org parser that is well maintained. It
provides this as an alternative to markdown files. You may wonder, then, why
someone would use Org mode to export to markdown instead of just letting Hugo
parse the Org files itself. The answer is two-fold:
1. Hugo's Org format is currently less feature complete than markdown, so
exporting from Org mode to the Hugo Org Format would limit potential output.
2. Org mode is a lot more than just a file format, and its integration with your
system allows all kinds of benefits you can never get out of a simple Org
file parser.
Therefore, supporting the Org format in another tool will give you a superior
text format for organizing information, but it will be crippled when compared to
an actual Org mode implementation. Ox-hugo gives you the ability to use Org mode
itself to generate content.
If Hugo's Org parser gains parity with, or eclipses, the Blackfriday Markdown
format currently used by Hugo, ox-hugo could certainly be used to output those
Org-Hugo files instead of the current markdown. This would be nice because it
would allow Org mode users to view their output content more easily, but the
advantages of ox-hugo and a real, bona fide Org mode would still remain.
So you see, Hugo's Org parser isn't really in competition with ox-hugo, it's in
competition with the /other/ Hugo parsers (e.g. markdown).
*** Thanks
Thanks to Kaushal Modi, who found this article on the googs within days of me
posting it, for reaching out to me and providing thorough feedback and error
checking.
And special thanks to me, for once again overcoming Hamhock the Laziness Demon
who has possessed me since birth and hates it when I do anything productive.
** DONE I did a blog :blog:org:emacs:hugo:
CLOSED: [2018-04-06 Fri 18:29]
:PROPERTIES:
:EXPORT_FILE_NAME: ox-hugo
:EXPORT_DESCRIPTION: "Exporting to Hugo's Blackfriday Markdown from Orgmode"
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/org.png
:END:
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
content generator [[https://gohugo.io/][Hugo]], which I use for this website. Today I integrated its
expectations about file structure into the Speedy theme for this blog, allowing
me to keep all blog contents in a single Org mode file and export [[http://en.wikipedia.org/wiki/markdown][markdown]]
content for Hugo's excellent [[https://github.com/russross/blackfriday][blackfriday markdown parser]] (a markdown format with
many added features). Hugo does support limited parsing of org files internally,
but Org mode features like inline spreadsheets and system communication are
beyond the scope of most external tools, so Org mode is best used as an
exporter. As an Emacs user, this allows me to instantly capture interesting
information I come across and publish it within seconds. Now I have no excuses!
* Forth
:PROPERTIES:
:EXPORT_FILE_NAME: _index
:EXPORT_HUGO_MENU: :menu "main"
:EXPORT_HUGO_SECTION: forth
:EXPORT_DESCRIPTION: "Highly Factored Code"
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/forth.png
:END:
This is where I post my watForth programs.
At present, my forth testbed is located at https://forth.kengrimes.com
* Code Repositories
:PROPERTIES:
:EXPORT_FILE_NAME: _index
:EXPORT_HUGO_MENU: :menu "main" :title Git
:EXPORT_HUGO_SECTION: git
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/git.png
:END:
* About
:PROPERTIES:
:EXPORT_HUGO_SECTION: about
:EXPORT_HUGO_MENU: :menu "main" :title About
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :header /img/home.png
:EXPORT_FILE_NAME: _index
:END:
#+begin_description
Ken Grimes
Computer Scientist
At Large
#+end_description
Hi! I'm Ken, a 34-year-old computer scientist currently living in Irvine,
California. This is a website I've constructed for the purpose of developing
web-facing software. I will probably blog with it once development is
complete. In the meantime, if you're curious, this is my [[file:static/cv.pdf][curriculum vitae]]