+++
title = "Udon"
weight = 8
template = "doc.html"
+++
## Table of Contents
- #### [Udon: A Guide](#guide)
- #### [A Simple Udon Blog](#blog)
- #### [A Static Site](#static)
## A Guide
Udon is a way to write content for the web. It's a minimalist
markup language for creating and rendering text documents, with a
Markdown-inspired syntax. It's integrated with our Hoon programming language,
allowing it to be used as standalone prose in its own file or embedded inside a
Hoon source file, in which case it will be parsed into a tree of HTML nodes
using Hoon's XML-templating syntax, Sail.
This document is itself written in Udon, and its source file is of the
Udon `.udon` extension. As such, we use some `formatted text` to make
it clear what is and isn't code, and to display that code to you instead of
actually using its semantics for formatting.
There are quite a few similarities between Udon and the
CommonMark standard, but there are enough differences that you shouldn't rely on
existing knowledge of the latter. Udon generally supports only one
syntax for each type of HTML node it emits. Udon is also stricter than
Markdown: some syntax errors will prevent the file from being parsed at all.
We provide a few simple examples [here](#examples) of how to publish
Udon files using our web interface.
### Getting Started
Before starting, make sure that your urbit is
[mounted to Unix](https://urbit.org/docs/using/setup/)
To host Udon and other kinds of files, your ship also has a
web-server, called [Eyre](https://urbit.org/docs/using/web/), that can be found
at `http://localhost:8080/` if it’s your first ship that’s running on the
machine, `http://localhost:8081/` if it’s the second ship on that same machine,
and so on. If you can't find your ship on one of these for some reason, try the
next one. When a ship starts, it will print a message like
`http: live (insecure, public) on 8081` to let you know what port it's using.
That server has access to source files located in `//home/web` and
any sub-folders thereof (except for `/home/web/pages`, which has special
rendering rules.) Your ship's `%home` desk is served by default. You can
[change](https://urbit.org/docs/using/web/) which desk you're serving, however.
Everything in the `//home/web/` directory, with the exception of
`/home/web/pages`, knows how to interpret and files of `.udon` type. So, to
experiment with UM, create a `.udon` file in that path, and then try to access it
at `http://localhost:8080/` in your browser -- no `.udon` required in
the URL. It's a good idea to copy-paste the following examples into your file to
see how the code works.
Make sure that you have proper syntax throughout, and check often that it
renders properly as you add more code. If you have parser-breaking syntax, then
the default renderer won't tell you much.
## Syntax
### Front Matter
The first thing on your file is a chunk of code called the front matter. It
contains metadata about your page, such as date, title, and position relative
to sibling pages.
As an example, let's look at the front matter of this very page:
```
:- :~ navhome/'/docs/'
sort/'11'
title/'Udon'
==
;>
```
What's going on here?
`:-`, the Hoon rune for creating a cell, creates a cell composed of
the `:~` Hoon rune for creating a list, and `;>`, which is a Sail rune
for Udon.
`:~` creates a list out of the three elements: `navhome/'/docs/'`, which
indicates that navigating "home" will bring you to the urbit.org/docs section
of the website; `sort/'28',` which assigns it the 28th position of the
immediate section that contains it, the one you see in the sidebar;
and `title/'Udon'`, which gives the page its title. The `==` digraph
terminates the list.
`;>` is a Sail rune that creates a node that contains everything that follows
it, telling the parser that that text should be interpreted as Udon.
It's not technically front matter, but you'll always find it following the
front matter, since all Udon must come after this rune.
The categories listed in the example above -- `navhome`, `sort`, and `title` --
make sense to Eyre by default, but any arbitrary category can be used. The code
below is valid front matter.
```
:- :~ date/~2018.9.12
author/~lodleb-ritrul
music/'rad'
==
```
Note that `~2018.9.12`, `~lodleb-ritrul`, and `'rad'` are all of of atom
types: `@da`(date), `@p` (ship name), and `@t` (cord), respectively. Only atom
types work here. Having `music/"rad"` would prevent the source file from
parsing.
### Headers
Headers in Udon begin the line with one or more `#` characters,
'followed by a single space. After that space comes the actual text to be
displayed. The number of leading `#`s corresponds to the resulting HTML
header-size element: `#` yields an ``, `##` yields an ``, and so on,
through ``. The header for this section is `### Headers`.
*Example:*
```
#### Header (h4)
##### Header (h5)
```
###### Produces:
#### Header (h4)
##### Header (h5)
### Italics and Bold
Enclosing text with `_` will cause that text to appear italicized, using an ``
element.
Enclosing text with `*` will cause that text to appear bolded, using a ``
element.
*Example:*
```
To get their *attention*, you need that _je ne sais quoi_.
```
###### Produces:
To get their *attention*, you need that _je ne sais quoi_.
### Line Break
A blank line is interpreted as a line break, creating a distinct
paragraph. However, a newline on its own is merely interpreted as a space on
the _same line_.
*Example:*
```
Here's the first line.
This second line is separated by two newlines, so it's a separate paragraph.
This line looks like a distinct paragraph, but...
It's only separated by a single newline, so it's included in the same paragraph.
```
###### Produces:
Here's the first line.
This second line is separated by two newlines, so it's a separate paragraph.
This line looks like a distinct paragraph, but...
It's only separated by a single newline, so it's included in the same paragraph.
#### Backslash Line Break
A backslash at the end of a line inserts a line break (`
`)
after that line. This contrasts with the normal udon behavior of
converting newlines to spaces.
*Example:*
```
I wonder how long each line
will be if I put backslashes\
at the ends of the lines.
```
###### Produces:
I wonder how long each line
will be if I put backslashes\
at the ends of the lines.
### Escape
A backslash directly _before_ a word (with no spaces) will be interpreted
as an escape character, causing it to be rendered raw.
*Example:*
```
Here is some *bold* text.
Here is some \*not bold* text.
```
###### Produces:
Here is some *bold* text.
Here is some \*not bold* text.
### List
A line beginning with a `-` followed by a space is interpreted as an
element of an *unordered list* (``). Each line in an unordered list is
prepended with a bullet point.
A line beginning with a `+` followed by a space is interpreted as an element
of an *ordered list* (``). Each line in an ordered list is prepended with
a number corresponding to its position in that list.
New list elements are delineated by newlines beginning with list symbols of
the appropriate type (`-` or `+`).
Just as with non-list text, text on a bare newline will appear on line before,
separated by a space. A `\\` is used to create a line-break that isn't the list
itself and isn't a list. Both of these kinds of newlines must be indented by two
spaces, or else the page will not parse.
Indentation is also used for creating nested sub-lists. Sub-lists of one kind
can be used with parent lists of the other kind. Sub-lists can't be nested
directly after either kind of aforementioned newline that isn't a list element;
only lines that are themselves list elements can nest sub-lists.
A newline after a blank line is interpreted as a new paragraph in normal text.
Between to list elements, however, a blank line is semantically equivalent to
a bare newline. To separate two lists with blank space, create a blank line
followed by a `\\` on its own line.
*Example:*
```
- Eggs
(cage-free)
- Milk
- Butter
- Chicken\
Make sure that you get enough for the barbecue
- Bread
+ Ask the baker what's fresh
+ Buy the second-freshest batch
- Cereal
\
+ First, separate eggs into a bowl.
+ Then, add a splash of cream.
- If you don't have cream, you can use milk, but cream is preferred.
+ If you don't have milk or cream, melt an eighth of a stick of butter on
a skillet
+ Scrambled the eggs in the bowl.
+ Pour the eggs onto the skillet before the butter browns
+ Heat the skillet
+ Scramble eggs and put them into skillet
\
+ Cool
+ Alright
```
Produces
- Eggs
(cage-free)
- Milk
- Butter
- Chicken\
Make sure that you get enough for the barbecue
- Bread
+ Ask the baker what's fresh
+ Buy the second-freshest batch
- Cereal
\
+ First, separate eggs into a bowl.
+ Then, add a splash of cream.
- If you don't have cream, you can use milk, but cream is preferred.
+ If you don't have milk or cream, melt an eighth of a stick of butter on
a skillet
+ Scrambled the eggs in the bowl.
+ Pour the eggs onto the skillet before the butter browns
+ Heat the skillet
+ Scramble eggs and put them into skillet
\
+ Cool
+ Alright
### Link
There are two ways to create links, but both contain the text be hyperlinked
in `[]` followed by the destination in `()`.
The first type is an inline-style link, which simply uses the full URL as its
destination.
*Example:*
```
[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
```
###### Produces:
[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
The second type is a reference-style link, which uses a relative path, based on
the current page's location. Instead of the full url, we use `..` to fill in
the all of the URL that the destination has in common with the origin page.
*Example:*
```
[I'm a reference-style link](../shell)
```
###### Produces:
[I'm a reference-style link](../shell)
If this page is located at `https://www.urbit.org/docs/reference/`, then these two
examples should have the same destination.
#### Anchor Link
A link to a section of the same page is in the style of
`[text to be linked](#the-destination)`.
The destination for the anchor link is designated with the HTML element `id`,
so we need to use some [Sail](#sail). If there are two or more anchors with
the same `id` on the page, you will arrive at the earliest instance of the the
anchor.
###### Example:
```
Check out this [section](#the-destination) that we want to jump to.
Four score and seven years ago....
It was the best of times, it was the worst of times...
## Here we are!
```
###### Produces
Check out this [section](#the-destination) that we want to jump to.
Four score and seven years ago....
It was the best of times, it was the worst of times...
## Here we are!
### Double Quote
Text enclosed in double quotes (`"`) will be rendered with
opening and closing quotes -- that is, `“` and `”`.
*Example:*
```
"Yes," he said. "That is the way with him."
```
###### Produces:
"Yes," he said. "That is the way with him."
### Code Literal
There are two ways to show the literal text of code without running it: inline
and block. Both highlight the contained text in another color.
Note that the backslash, due to its role as the escape character, can only be
displayed in a code block literal and not as inline code literal. This is a
bug.
```
\
```
##### Inline Code Literal
Enclosing some text in
```
`
```
characters will cause it to be displayed as code,
inside a `` HTML element with monospace font and highlighted with a
different background color.
Using `` ` \`` is useful when you want to designated only part of a line as code.
Since this page is written in Udon, we've been using this operation
throughout this guide to `format text` to distinguish code from prose.
*Example:*
```
`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
```
###### Produces:
`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
Also, using the `++` prefix before a word will cause the word to be rendered as
code with the `++` displayed, since that's the standard notation for an arm in
Hoon.
*Example:*
```
The ++add arm is used to sum two numbers.
```
###### Produces:
The ++add arm is used to sum two numbers.
#### Block Code Literal
By enclosing a block of text in ``` on their own lines
before and after the contained text, the text will be treated as a code block.
Most of our examples so far have used.
*Example:*
```
```
(def Y (fn [f]
((fn [x]
(x x))
(fn [x]
(f (fn [y]
((x x) y)))))))
```
```
###### Produces:
```
(def Y (fn [f]
((fn [x]
(x x))
(fn [x]
(f (fn [y]
((x x) y)))))))
```
### Hoon Constants
Hoon has several syntactic forms for literals (numbers, strings, dates, etc.)
that can be used in udon as well. Udon detects such code, and so these
forms will automatically appear inside a `` element like inline code.
Example:
```
~2017.8.29 \
0xdead.beef \
%term
```
produces:\
~2017.8.29 \
0xdead.beef \
%term
### Horizontal Rule
Three or more hyphens, such as `---`, on their own line produce an `
`
element, the 'horizontal rule'. This is rendered as a horizontal line the
width of its containing paragraph.
###### Example:
```
Above the line
---
Below the line
-----
And below this line, too
```
###### Produces:
Above the line
---
Below the line
-----
And below this line, too
### Block Quote
A section of text with the first line beginning with `>` and a space,
and each successive newline indented by two spaces yields a
`` HTML element. This block quote can itself contain more Udon,
including more block quotes to render nested levels of quotation.
Inline italicization with `_` does not work, however.
Blank newlines do not end the block quote, but a blank newline followed by an
unindented line of text _will_ end the quote.
*Example:*
```
> As Gregor Samsa awoke one morning from uneasy dreams, he
found himself transformed in his bed into a *monstrous* vermin.
Quote break.
> _See_ the child.
He is pale and thin, he wears a thin and ragged linen shirt.
```
###### Produces:
> As Gregor Samsa awoke one morning from uneasy dreams
he found himself transformed in his bed into a *monstrous* vermin.
Quote break.
> _See_ the child.
He is pale and thin, he wears a thin and ragged linen shirt.
### Poem
A poem is a section of text with meaningful newlines. Recall that,
normally in Udon, newlines are treated as spaces and do not create a
new line of text. If you want to embed text where newlines are retained, then
indent the text in question with *eight spaces*.
###### Example:
```
A shape with lion body and the head of a man,
A gaze blank and pitiless as the sun,
Is moving its slow thighs, while all about it
Reel shadows of the indignant desert birds.
```
###### Produces:
A shape with lion body and the head of a man,
A gaze blank and pitiless as the sun,
Is moving its slow thighs, while all about it
Reel shadows of the indignant desert birds.
## Sail Expressions
It's possible to use Udon as an HTML templating language akin to
PHP, ERB, JSP, or Handlebars templates. This facility derives
in part from the support for embedding Hoon code inside the markup.
Sail is a domain-specific language within Hoon for creating XML nodes,
including HTML. It can be used directly within Udon to provide
scripting capability with Hoon and also to provide more precise control over the
resulting HTML. The [Sail guide](../sail) is a good place to learn the
specifics.
Example:
```
;=
;p
;strong: Don't panic!
;small: [reactive publishing intensifies]
==
==
```
Produces:
;=
;p
;strong: Don't panic!
;small: [reactive publishing intensifies]
==
==
## A Simple Udon Blog
Publishing using Udon is really easy. It uses the file extension `.udon`. Here we'll create a very simple blog and publish our first posts.
First, let's setup a desk to serve our posts from:
```
|merge %site ~your-urbit %home
```
Then let's mount that desk to unix:
```
|mount /=site=
```
You should now be able to find a `/site` folder inside of your pier
directory (either `comet/` or `your-urbit/`).
To begin serving files from this new desk use `|serve`:
```
|serve %site
```
First let's create the landing page for our blog. Create the file
`site/web/blog.udon`:
```
:- :~ anchor/'none'
==
;>
# Hello
This is a simple blog I built on Urbit.
;list(dataType "post");
```
Try viewing this file at `http://localhost:8080`. Note that `8080` might be
`8081`, `8082`, and so on, depending if those ports were being used when you
started your urbit.
The only special thing about this page is the `anchor/'none'` front-matter
which simply turns off the Tree navigation. Normally Tree gives navigation
controls for walking around the filesystem, but taking them away makes
the page seem more like a landing page.
The page looks pretty boring now. Let's add our first post. From
unix run `mkdir your-urbit/site/web/blog; touch
your-urbit/site/web/blog/post-1.udon`. (Currently [there's a
bug](https://github.com/urbit/urbit/issues/321) that prevents empty
directories from getting created, so we have to `touch` a file inside
them first.) In `blog/post-1.udon` let's add some filler content:
```
:- :~ navhome/'/blog'
type/'post'
date/'~2016.6.20'
title/'My first post!'
==
;>
Is this a decentralized Medium? Let's find out.
But first, how about a long quote from Paramenides:
> True, he said; and therefore when ideas are what they are in
relation to one another, their essence is determined by a relation
among themselves, and has nothing to do with the resemblances, or
whatever they are to be termed, which are in our sphere, and from
which we receive this or that name when we partake of them. And
the things which are within our sphere and have the same names
with them, are likewise only relative to one another, and not to
the ideas which have the same names with them, but belong to
themselves and not to them.
Good to get that out of the way.
```
You should be able to view this file at:
`http://localhost:8080/blog/post-1.udon`.
You'll also notice that
now the list of posts here: `http://localhost:8080/blog` has
updated.
Here we use two pieces of front-matter worth noting: `type` and `navhome`.
- `type` implies that the page has some special handling by Tree. When `type` is
`post` we automatically put in the `date`, `title` and `author` when they're
specified and add some styles.
- `navhome` sets the path used by the home button (the circle in the top left).
Since we want to send people back to the root of our blog, we set this to `/blog`
Adding posts is as easy as dropping Udon files into the `blog/`
directory. Pretty easy!
### Blog comments
Now let's enable comments on a blog post.
First, turn comments on by editing the frontmatter in `post-1.udon`. Your
frontmatter should look like this:
```
:- :~ navhome/'/blog'
type/'post'
date/'~2018.6.20'
title/'Blog comments'
comments/'true'
==
;>
```
Now try loading your post here: `your-urbit.urbit.org/blog/post-1`.
You should see a comments box at the bottom of the page.
Try posting a comment! When you do you should see the following in
your console:
```
+ /~your-urbit/home/55/web/blog/post-1/comments/~2016.6.20..23.20.54..0b88/md
------------[0]
~your-urbit[tree]: receiving comments, ;join %comments for details
```
Comments are written into the filesystem in the `comments/` folder
relative to the page they're enabled on. When a new comment is posted
a notification is also posted to the `/comments` `:talk` channel.
Use `;join` to keep up with comments as they get posted:
```
;join ~your-urbit/comments
```
That's it! Easy.
## A Static Site
Hosting a static tree of content is easy. Let's put together a really
simple site for an imaginary Urbit meetup group.
We assume you have at least followed the beginning of [our first
examples](#blog) and created a desk called `site` and mounted it to
unix.
Note: below we use Urbit's implementation of Markdown, [Udon](#udon).
This markup language allows you to use snippets of Hoon code but not HTML.
In particular, we use Sail, a subset of Hoon. This Sail is rendered as HTML
when the file is served to a client. To learn about Sail, head over to
the [Sail](/docs/learn/arvo/arvo-internals/sail) section of the docs.
In `site/web/meet.udon` put:
```
:- :~ navhome/'/meet'
navdpad/'false'
navpath/'/meet'
navmode/'navbar'
==
;>
# Neo-Tokyo Urbit meetup

Hi there! We meet once a week at The Chat to work on Urbit projects
together.
You can find out more about the group on the [about](about) page and
follow our projects in [projects](projects).
```
This is our landing page. Here we're using a few new bits of frontmatter:
`navdpad`, `navmode` and `navpath`. `navdpad` just turns off the nav
arrows. `navmode` can be set to 'navbar' to switch to a horizontal top
nav instead of a left bar. `navpath` sets the path to load the nav
items from.
Let's create `about.udon` and `projects.udon`. From Unix use the
technique from before to create a new directory: `mkdir
your-urbit/site/web/meet/; touch your-urbit/site/web/meet/about.udon`.
Then put the following in `site/web/about.udon`:
```
:- :~ navhome/'/meet'
navdpad/'false'
navpath/'/meet'
navmode/'navbar'
title/'About'
==
;>
# About
## Mission statement
The existing framework cannot subdue the new human force that is increasing day
by day alongside the irresistible development of technology and the
dissatisfaction of its possible uses in our senseless social life.
## Members
Membership is open to anyone. Just send a message to `~talsur-todres`.
- Shōtarō Kaneda
- Motoko Kusanagi
- Ishikawa
- Faye Valentine
- Spike Spiegel
```
And `site/web/projects.udon`:
```
:- :~ navhome/'/meet'
navdpad/'false'
navpath/'/meet'
navmode/'navbar'
title/'Projects'
==
;>
# Projects
## Active
;list;
## Discussion
;div(class "mini-module")
;script(src "/~/at/lib/js/urb.js");
;script(src "https://cdn.rawgit.com/seatgeek/react-infinite/0.8.0/dist/react-infinite.js");
;script(src "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment-with-locales.js");
;script(src "https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.1/moment-timezone.js");
;script(src "/talk/main.js");
;link(href "/talk/main.css", rel "stylesheet");
;talk(readonly "", chrono="reverse", station="comments");
==
```
This page introduces a new thing: the `:talk` module. Inside of the
`mini-module` div we load the scripts needed by the `;talk`
component. The `;talk` component is a static component for
displaying a feed from a talk channel inline. Here we're going to
display the discussion from our active projects inline.
We'll need a few active projects though. From unix: `mkdir
your-urbit/site/web/meet/projects; touch
your-urbit/site/web/meet/projects/bike.udon`.
In `site/web/meet/projects/bike.udon`:
```
:- :~ navhome/'/meet'
navdpad/'false'
navpath/'/meet'
navmode/'navbar'
title/'Kaneda's Bike'
comments/'true'
==
;>
# Urbit on a Motorcycle
Discussion on getting urbit to power Kaneda's motorcycle.
```
Here we just use the `comments` frontmatter to enable comments on the page.
Adding other imaginary projects is left to the reader.
Building a static site takes only a few minutes and a few Udon files. Have fun!