@@ -0,0 +1,1538 @@
2+title = "Sail and Udon"
7+Sail is Hoon markup that’s used to render a web page with XML. But what makes it special is that you can run arbitrary Hoon code within such a web page without using a separate markup language.
9+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 Sail.
11+This document will be divided into two main sections: the Sail guide and the Udon guide. The Udon guide has two sub-sections that each walk you through a practical example. Also, you're encouraged to read the Getting Started section below, which applies to both Udon and Sail.
15+- #### [Sail: A Guide](#sail)
17+- #### [Udon: A Guide](#udon)
19+- #### [Udon: A Simple Blog](#blog)
21+- #### [Udon: A Static Site](#static)
25+Before starting with either Sail or Udon, make sure that your ship is
26+[mounted to Unix](https://urbit.org/docs/using/setup/)
28+To host that output, your ship also has a web-server, called
29+[Eyre](https://urbit.org/docs/using/web/), that can be found at
30+`http://localhost:8080/` if it’s your first ship that’s running on the a
31+machine, `http://localhost:8081/` if it’s the second ship on that same machine,
32+and so on. In the startup messages, a ship will tell you which HTTP port it's
35+The `/web` directory of the `%home` desk is served by default. You can change
36+which desk you're serving by using the command `|serve` in the Dojo. If you
37+have already created and mounted a desk named `%sandbox`, for example, you can
38+switch to serving it with this command:
44+The first time you serve a desk, `/web` will be included as default. After that,
45+you will need to explicitly append `/web` to the desk you're switching to --
46+otherwise, you'll need to write `http://localhost:8080/web` every time you
47+navigate to your web-server. Newly served desks not automatically having `/web`
48+as their root directory is a bug.
50+To switch back to your `%home` desk and set `/web` as your root directory, run:
56+We'll be serving the `%home` desk for the examples in this tutorial.
60+That server has access to source files located in `/<your-urbit>/home/web` and
61+any sub-folders thereof. For the purposes of this tutorial, we will only be
62+using files that are located in the `/<your-urbit>/home/web/pages` path.
64+There is an important distinction between these two paths. According to
65+`/ren/urb.hoon`, any file inside of `/web` or any of its sub-directories
66+is put through a tree of renderers specified at `/ren/urb/tree.hoon`
67+-- _except_ for files inside of `/web/pages`. All of the files in `/web` and
68+its non-`/pages` children directories have various operations on files, such as
69+wrapping your Sail the `html`, `head`, and `body` nodes. This rendering tool,
70+called simply **Tree**, also adds certain formatting polish, such as a sidebar
71+that lists sibling files in the same directory.
73+The `/web/pages` sub-directory is a unique case with its own rendering rules.
74+The Tree is not used when rendering files in this path. The existence of no tag
75+is inferred, and no special formatting is applied. Such simplicity is ideal for
76+introducing the basics of Sail. Any source file located in `/web/pages` must
77+produce a complete HTML node with "head" and "body" nodes as children.
79+Understanding the details of the rendering pipeline is not necessary to complete
80+this tutorial. But, if you are curious, you might find it illuminating to
81+explore the contents of the `/ren` directory.
83+So, if a Sail source file named `sailtest.hoon` is saved in your `/web/pages`
84+folder on your only running urbit process, you can view that source rendered
85+into a web-page at `localhost:8080/pages/sailtest/`.
87+## <a name="sail"></a>Sail: A Guide
89+It’s easy to see how Sail can directly translate to HTML:
96+ ;title: My first webpage
103+ ;script@"http://unsafely.tracking.you/cookiemonster.js";
113+ <title>My first webpage</title>
120+ <script src="http://unsafely.tracking.you/cookiemonster.js"></script>
125+Save the above Sail code in `/home/web/pages/firstsail.hoon`, and the above
126+HTML code in `/home/web/pages/firsth.html`. Access the resulting pages by
127+navigating to `http://localhost:8080/pages/firstsail` and
128+`http://localhost:8080/pages/firsth.html`, respectively, in your browser. The
129+resulting pages should be identical!
131+It shouldn't be hard to see the similarities here. So let's go into more
132+detail about what the differences are.
136+In Sail, tag heads are written with the tag name prepended by `;`. Unlike in
137+HTML, there are different ways on closing tags, depending on the needs of the
138+tag. One of the nice things about Hoon is that you don’t have to be constantly
139+closing expressions; Sail inherits this convenience.
143+Empty tags are closed with a `;` following the tag. Example:
157+Filled tags are closed via line-break. To fill text inside, add `:` after the
158+tag name, then insert your plain text following a space. Example:
172+To nest tags, simply create a new line. Nested tags need to be closed
173+with `==`, because they expect a list of sub-tags. If we nest a line of plain
174+text with no tag, a `<p>` is prepended.
176+Sail, like Hoon, is white-space sensitive. Unlike in Hoon, however, two spaces
177+(called a "gap") is not necessarily equivalent to a line-break in Sail.
182+ This is some good content.
191+ <p>This is some good content.</p>
196+Conversely, if we want to write a string with no tag at all, then we can prepend
197+those untagged lines with `;`.
220+Attributes are key-value pairs that go into an HTML node.
222+Adding attributes is simple: just add the desired attribute between parentheses,
223+right after the tag name without a space. We separate different attributes of
224+the same node by using `,`.
226+Attributes can be used in two forms: flat, which uses one line; and tall, which
227+uses multiple lines, when a single line would not be practical. Flat forms and
228+flat forms are two syntaxes of semantically equivalent expressions.
233+The code below produces a “Submit” button on the page.
238+;input(type "submit", value "Submit");
253+<input type="submit" value="Submit">`
265+<nav id="header">Menu</nav>
268+Add `#` after tag name to add an ID.
272+`;h1.text-blue: Title` equals `<h1 class="text-blue">Title</h1>`
274+Add `.` after tag name to add a class. However, if you want a class name that
275+contains a space, you will need to use use the syntax of a generic attribute:
277+`;div(class "logo inverse");` equals `<div class="logo inverse"></div>`
282+`;img@"example.png";`
286+`<img src="example.png"/>`
288+Add `@` after the tag name to link your source.
290+To add attributes to the image, like size specifications, add the
291+desired attribute after the `"` of the image name and before the final `;` of
296+`;img@"https://urbit.org/example.png"(width "100%");`
300+`;a/"urbit.org": A link to Urbit.org`
304+`<a href="urbit.org">A link to Urbit.org</a>`
306+Add `/` after tag name to start an href.
310+Our first example is useful to understand how Sail syntax translates to HTML
311+syntax, but Sail finds its usefulness in the fact that it can be used seamlessly
314+One place where Sail diverges from HTML is that it supports string
315+interpolation. In Sail, the contents of all tags are a string type called `tape`
316+unless otherwise designated. Tapes are delineated by the double quotes `""`.
317+That’s important, because tapes can be interpolated with Hoon expressions,
318+provided that those expressions produce something a tape as well. Interpolation
319+is done by wrapping the code to be inserted in `{}`. In your Dojo prompt, try
320+the command below (without the `>`):
323+> "I am a l{(mul 3 11)}t Urbit user."
327+Oh no! That command produced a nest-fail error, which indicates that there was
328+a problem related to Hoon type-system. We used the proper `{}` syntax for
329+interpolation, and we used the proper function-call syntax inside of it. So
332+Trying the `mul` function on its own will help answer this question. Try the
333+following command in your Dojo:
340+This should work, producing `33`, an atom. That’s our problem. The
341+interpolation expression expects a tape, but our first command tried to
342+interpolate with something that results in an atom. Try this now:
349+We get a similar result, but we know that it’s a tape because it’s wrapped in
350+`""`. Bingo! With this knowledge, let’s perform a successful interpolation:
353+> "I am a l{<(mul 3 11)>}t Urbit user."
354+"I am a l33t Urbit user."
361+The default subject of a Sail file is different from the subject that
362+expressions in the Dojo or a Hoon generator are evaluated against.
364+To see this difference, first save the code below to a file at
365+`home/web/pages/sub.hoon` and view the rendering at
366+`http://localhost:8080/pages/sub`.
377+Then enter the following command in the Dojo:
383+You'll notice that the Sail subject is like a stripped-down version of the Dojo
384+subject. Its final line should match the Dojo subject.
386+Now swap the code below into your Sail file.
398+You'll find that the resulting Sail subject is much larger. If you look closely,
399+you'll see that there's some new similarities with the Dojo subject, such as
400+containing the name of your ship. There's also some new differences, since
401+`fuel:html` contains things that are specifically useful for performing
402+web-related operations.
404+### A More Interesting Example
406+Now let’s apply knowledge of string interpolation and the Sail subject in a Sail
407+source file. The following code produces more interesting things than the
408+example we saw before.
413+=+ wid=(met 3 p.bem.gas)
415+?: (lte wid 1) "galaxy"
417+?: (lte wid 4) "planet"
418+?: (lte wid 8) "moon"
422+ ;meta(charset "utf-8");
423+ ;title: A more advanced page
426+ ;h1: This is the Title
428+ ;a/"http://urbit.org": link to Urbit.org.
429+ ;span: Check it out!
432+ ;li(style "color: green"): We're doing interesting stuff now.
433+ ;li: We're pretty-printing this sum with Hoon: {<(add 50 50)>}.
434+ ;li: The code above is shorthand for {(scow %ud (add 50 50))}.
435+ ;li: I am {(trip '~lodleb-ritrul')}.
436+ ;li: Actually, my name is {<p.bem.gas>}. I'm a {what-kind}.
438+ ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
443+Save the above Sail code in to `home/web/pages/secondsail.hoon` and access the
444+resulting page by navigating to `http://localhost:8080/pages/secondsail` in
447+There are some interesting things here. Let’s go through this code piece by
454+Later in this code we want produce the name of the ship is hosting it, something
455+that looks like ~lodleb-ritrul. In a generator, we could produce our ship name
456+by writing `our` -- try it in the Dojo. But remember that Sail is rendered
457+against its own subject, `our` is not part of the default subject. To augment
458+our subject with the information that we need, we use `/= gas /$ fuel:html`.
460+The above expression uses two Ford runes, `/=` and `/$`, to add the relevant
461+information to the current subject. We can pull the ship’s name out of this
462+augmented subject later. It's important to note that these runes are not part of
463+Hoon. They are part of Ford, our build system.
465+`/$` is used to get data from the environment, and `/=` adds that data to
466+subject in the face `gas`. The
467+[Ford user manual](https://urbit.org/docs/arvo/internals/ford/runes/) has
468+details on these and other Ford runes, but understanding these runes isn’t
469+necessary for the purposes of this tutorial.
471+`fuel:html` gets extra data from your ship’s Eyre module, which handles all
472+things HTTP, and sticks it in the subject when Eyre renders a page. This
473+includes the name of the ship, which is what we look for in the next line, but
474+it includes much more.
476+`p.bem.gas` is an expression that looks for `p` within `bem` within `gas`, the
477+face that we stored the above `fuel:html` expression in. That wing happens to
478+resolve to the name of the ship that is hosting the web-server. If we wanted to
479+access the current desk, we would use the wing expression `q.bem.gas`.
481+You can take a look at what you can access by typing `fuel:html` in the Dojo,
482+and then explore it by modifying your wing expression in your Sail file
489+The above line of code stores a variable used later for a conditional. `&` means
490+`true`, meaning that any evaluation of `show-list` will be true until changed in
494+=+ wid=(met 3 p.bem.gas)
496+ ?: (lte wid 1) "galaxy"
498+ ?: (lte wid 4) "planet"
499+ ?: (lte wid 8) "moon"
503+This code chunk is a series of conditionals that checks the host ship’s name to
504+see what its value is.
506+The first line, `=+ wid=(met 3 p.bem.gas)`, combines a new noun with the
507+subject and gives it the face `wid`. This noun is produced by the the
508+standard-library function [`met`](/docs/reference/library/2c), which measures the number of
509+[blocks](/docs/reference/library/1c/) of size `a` within `b`. Blocks are units that have a
510+bitwidth of `2^a`. So, in this case, it measures how many bytes (blocks of size
511+3 are bitwidths of 8; `2^3 = 8`) are fully contained in your ship's address.
513+Galaxies contain zero to one 3-blocks; stars contain two 3-blocks; planets
514+contain three to four 3-blocks; moons contain five to eight 3-blocks; comets
515+contain nine to sixteen 3-blocks. Each test uses `lte`, the
516+less-than-or-equal-to function, to determine if `wid` is of a given size. The
517+result of this series of tests is added to the subject and given the face
520+Ship names are simply another representation of atoms, and ship
521+categories are different ranges of possible atomic values. Because of this, we
522+perform less-than tests to see what kind of ship is running the web-server.
527+ ;meta(charset "utf-8");
528+ ;title: A more advanced page
532+Sail proper begins here. These four lines are four nodes. The `;html` node
533+indicates that the contained code should be rendered as HTML; this tag is closed
534+on the final line. The `;head` node contains metadata, and is closed three lines
535+later. The `;meta` node sets the character set to UTF-8, and the `;title` node
536+sets the title of the page that shows up in the browser tab.
540+ ;h1: This is the Title
542+ ;a/"http://urbit.org": link to Urbit.org.
543+ ;span: Check it out!
546+The first line here opens, of course, the body node. The second line creates
549+The third, fourth, and fifth lines of code here construct a single line with an
551+`; This is a` begins the rendered line with plain text.
553+`;a/"http://urbit.org": link to Urbit.org.` continues that same rendered line,
554+and creates hyperlinked text out of `link to Urbit.org.`
556+`;span: Check it out!` continues that same rendered line further. `;span:`
557+has the same use as `<span>` in HTML, and by following it with just a `:` and no
558+attributes, it continues the line without formatting. Following `;span:` with
559+**two** spaces causes there to be single space following the produced `<span>`
560+element, because one of those spaces is syntactically necessary.
562+In the following lines, we beginning to use some Hoon expressions again.
569+In the top line in the chunk above, we use the `;+` Sail rune, which
570+resolves an expression to a single node. That expression, in this case, is
571+`?:`, which tests the truth value of `show-list`, which we assigned the value
572+`&` (meaning “true”) at the beginning of the program. It’s closed by the `==` on
575+Thus, this program resolves to the first child of `show-list`, the node `;ol`.
576+That node creates an ordered list, and the items contained within that node.
579+ ;li(style "color: green"): We're doing more interesting stuff now.
582+The line above is the only element of this list that does not use
583+Hoon proper. The line renders as green, as interpreted by the browser,
584+because of the Sail attribute.
586+The next items in the list use `{}`. Recall that these braces, pronounced “lob”
587+and “rob” in Hoon-speak, allow for the interpolation of code within a string.
590+ ;li: We're pretty-printing this sum with Hoon: {<(add 50 50)>}.
593+The line above is interpolated with Hoon code that produces the sum of 50 plus
594+50, which is wrapped in `<>` to put the product in double quotes to make it a
595+tape, like the rest of the line.
599+ ;li: The code above is shorthand for {(scow %ud (add 50 50))}.
602+The `{(scow %ud (add 50 50)}` on this line is just a different way
603+writing the `{<(add 50 50)>}` expression. `scow` is a Hoon function that turns a
604+noun into a `tape`, Hoon’s string type. `%ud` tells `scow` that its argument
605+should be displayed in the form of an unsigned decimal.
609+ ;li: I am {(trip '~lodleb-ritrul')}.
612+`trip` is a function that takes a `cord` and produces a `tape`. A piece of
613+data of the cord type is one big atom formed from adjacent unicode bytes and
614+delineated by `''`. Remember that all text rendered in Sail is treated as a
615+tape. So, by converting `~lodleb-ritrul` to a tape, it can be included in the
616+tape that we are trying to insert it into without getting a type error.
619+ ;li: Actually, my name is {<p.bem.gas>}. I'm a {what-kind}.
623+The line above has interpolated code that uses a wing expression to access the
624+name of the host ship, and then accesses the face `what-kind` contains a string
625+describing what type of ship it is. We declared `gas` on the very first line so
626+that we could add that sort of information to the subject that our Sail is
627+rendered against. The wing expression `p.bem.gas` looks for `p` within `bem`
628+within `gas`, which happens to be where the name of the ship is located.
630+Note that `{what-kind}` does not have a `<>` wrapper. Why do you think this is?
633+ ;div; My name is {<p.bem.gas>}. I'm a {ship}.
638+The `;div;` node above is only rendered, as an alternative to the above list,
639+if `show-list` is evaluated as true. This means it won’t be shown with your
640+default code. To show this line, change the `&` on line 2 to `|` (“false”).
644+In the previous example, we used a few special runes that aren’t used in typical
645+Hoon code. But there are others that are worth learning about at this point.
647+`;+` is an expression that resolves to a single node. We saw this on line 20
648+in our Sail example above: `;+ ?: show-list` resolves to the node `;ol` and
649+all of that node’s children.
651+`;*` is an expression that resolves to a list of nodes. If we want to render
652+multiple nodes side-by-side, and not just the children of a single node, this
653+is the expression that we use.
655+`;=` turns a tuple of nodes into a list of nodes.
658+To see how these runes work, let’s take a chunk of our previous code starting at
659+line 20 and modify it a bit:
664+ ;li: I am {(trip '~lodleb-ritrul')}.
665+ ;li: Actually, my name is {<p.bem.gas>}.
668+ ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
674+We changed the conditional branches so that each contains two Sail nodes,
675+side-by-side -- notice that the `;ol` is absent from the first branch.
677+We begin with the `;*` rune, which resolves to a list of nodes, instead of the
678+`;+` rune, which only resolves to a single node.
680+But that’s not enough on its own. `;*` needs to resolve to a list, and a few
681+Sail nodes aren’t lists until they are explicitly made into lists. Until we wrap
682+those nodes in `;=`, the nodes treated as mere tuples. All branches must be
683+valid lists for the `;* ?: show-list` expression to resolve.
687+You should now have foundational knowledge for making web pages with Sail. There
688+is, of course, more to learn.
690+The [Ford manual](https://urbit.org/docs/arvo/internals/ford/runes/)
691+can show you how to access various ship resources for user in your pages. To
692+learn more about how the renderer works, take a look at the
693+`/home/ren/urb.hoon` file inside your urbit.
695+## <a name="udon"></a>Udon: A Guide
697+Udon is a way to write content for the web. It's a minimalist
698+markup language for creating and rendering text documents, with a
699+Markdown-inspired syntax. It's integrated with our Hoon programming language,
700+allowing it to be used as standalone prose in its own file or embedded inside a
701+Hoon source file, in which case it will be parsed into a tree of HTML nodes
702+using Hoon's XML-templating syntax, Sail.
704+This document is itself written in Udon, and its source file is of the
705+Udon `.udon` extension. As such, we use some `formatted text` to make
706+it clear what is and isn't code, and to display that code to you instead of
707+actually using its semantics for formatting.
709+There are quite a few similarities between Udon and the
710+CommonMark standard, but there are enough differences that you shouldn't rely on
711+existing knowledge of the latter. Udon generally supports only one
712+syntax for each type of HTML node it emits. Udon is also stricter than
713+Markdown: some syntax errors will prevent the file from being parsed at all.
715+We provide a few simple examples [here](#examples) of how to publish
716+Udon files using our web interface.
722+The first thing on your file is a chunk of code called the front matter. It
723+contains metadata about your page, such as date, title, and position relative
726+As an example, let's look at the front matter of this very page:
729+:- :~ navhome/'/docs/'
736+What's going on here?
738+`:-`, the Hoon rune for creating a cell, creates a cell composed of
739+the `:~` Hoon rune for creating a list, and `;>`, which is a Sail rune
742+`:~` creates a list out of the three elements: `navhome/'/docs/'`, which
743+indicates that navigating "home" will bring you to the urbit.org/docs section
744+of the website; `sort/'28',` which assigns it the 28th position of the
745+immediate section that contains it, the one you see in the sidebar;
746+and `title/'Udon'`, which gives the page its title. The `==` digraph
749+`;>` is a Sail rune that creates a node that contains everything that follows
750+it, telling the parser that that text should be interpreted as Udon.
751+It's not technically front matter, but you'll always find it following the
752+front matter, since all Udon must come after this rune.
754+The categories listed in the example above -- `navhome`, `sort`, and `title` --
755+make sense to Eyre by default, but any arbitrary category can be used. The code
756+below is valid front matter.
759+:- :~ date/~2018.9.12
760+ author/~lodleb-ritrul
765+Note that `~2018.9.12`, `~lodleb-ritrul`, and `'rad'` are all of of atom
766+types: `@da`(date), `@p` (ship name), and `@t` (cord), respectively. Only atom
767+types work here. Having `music/"rad"` would prevent the source file from
772+Headers in Udon begin the line with one or more `#` characters,
773+'followed by a single space. After that space comes the actual text to be
774+displayed. The number of leading `#`s corresponds to the resulting HTML
775+header-size element: `#` yields an `<h1>`, `##` yields an `<h2>`, and so on,
776+through `<h6>`. The header for this section is `### Headers`.
792+Enclosing text with `_` will cause that text to appear italicized, using an `<i>`
795+Enclosing text with `*` will cause that text to appear bolded, using a `<b>`
802+To get their *attention*, you need that _je ne sais quoi_.
807+To get their **attention**, you need that _je ne sais quoi_.
811+A blank line is interpreted as a line break, creating a distinct
812+paragraph. However, a newline on its own is merely interpreted as a space on
818+Here's the first line.
820+This second line is separated by two newlines, so it's a separate paragraph.
822+This line looks like a distinct paragraph, but...
823+It's only separated by a single newline, so it's included in the same paragraph.
828+Here's the first line.
830+This second line is separated by two newlines, so it's a separate paragraph.
832+This line looks like a distinct paragraph, but...
833+It's only separated by a single newline, so it's included in the same paragraph.
835+#### Backslash Line Break
837+A backslash at the end of a line inserts a line break (`<br>`)
838+after that line. This contrasts with the normal udon behavior of
839+converting newlines to spaces.
843+I wonder how long each line
844+will be if I put backslashes\
845+at the ends of the lines.
849+I wonder how long each line
850+will be if I put backslashes\
851+at the ends of the lines.
855+A backslash directly _before_ a word (with no spaces) will be interpreted
856+as an escape character, causing it to be rendered raw.
861+Here is some *bold* text.
862+Here is some \*not bold* text.
867+Here is some **bold** text.
868+Here is some \*not bold* text.
873+A line beginning with a `-` followed by a space is interpreted as an
874+element of an **unordered list** (`<ul>`). Each line in an unordered list is
875+prepended with a bullet point.
877+A line beginning with a `+` followed by a space is interpreted as an element
878+of an **ordered list** (`<ol>`). Each line in an ordered list is prepended with
879+a number corresponding to its position in that list.
881+New list elements are delineated by newlines beginning with list symbols of
882+the appropriate type (`-` or `+`).
884+Just as with non-list text, text on a bare newline will appear on line before,
885+separated by a space. A `\\` is used to create a line-break that isn't the list
886+itself and isn't a list. Both of these kinds of newlines must be indented by two
887+spaces, or else the page will not parse.
889+Indentation is also used for creating nested sub-lists. Sub-lists of one kind
890+can be used with parent lists of the other kind. Sub-lists can't be nested
891+directly after either kind of aforementioned newline that isn't a list element;
892+only lines that are themselves list elements can nest sub-lists.
894+A newline after a blank line is interpreted as a new paragraph in normal text.
895+Between to list elements, however, a blank line is semantically equivalent to
896+a bare newline. To separate two lists with blank space, create a blank line
897+followed by a `\\` on its own line.
907+ Make sure that you get enough for the barbecue
909+ + Ask the baker what's fresh
910+ + Buy the second-freshest batch
914++ First, separate eggs into a bowl.
915++ Then, add a splash of cream.
916+ - If you don't have cream, you can use milk, but cream is preferred.
917+ + If you don't have milk or cream, melt an eighth of a stick of butter on
919+ + Scrambled the eggs in the bowl.
920+ + Pour the eggs onto the skillet before the butter browns
923++ Scramble eggs and put them into skillet
937+ Make sure that you get enough for the barbecue
939+ + Ask the baker what's fresh
940+ + Buy the second-freshest batch
944++ First, separate eggs into a bowl.
945++ Then, add a splash of cream.
946+ - If you don't have cream, you can use milk, but cream is preferred.
947+ + If you don't have milk or cream, melt an eighth of a stick of butter on
949+ + Scrambled the eggs in the bowl.
950+ + Pour the eggs onto the skillet before the butter browns
953++ Scramble eggs and put them into skillet
961+There are two ways to create links, but both contain the text be hyperlinked
962+in `[]` followed by the destination in `()`.
964+The first type is an inline-style link, which simply uses the full URL as its
970+[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
975+[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
977+The second type is a reference-style link, which uses a relative path, based on
978+the current page's location. Instead of the full url, we use `..` to fill in
979+the all of the URL that the destination has in common with the origin page.
984+[I'm a reference-style link](../shell)
989+[I'm a reference-style link](../shell)
991+If this page is located at `https://www.urbit.org/docs/reference/`, then these two
992+examples should have the same destination.
996+A link to a section of the same page is in the style of
997+`[text to be linked](#the-destination)`.
999+The destination for the anchor link is designated with the HTML element `id`,
1000+so we need to use some [Sail](#sail). If there are two or more anchors with
1001+the same `id` on the page, you will arrive at the earliest instance of the the
1007+Check out this [section](#the-destination) that we want to jump to.
1009+Four score and seven years ago....
1011+It was the best of times, it was the worst of times...
1018+Check out this [section](#the-destination) that we want to jump to.
1020+Four score and seven years ago....
1022+It was the best of times, it was the worst of times...
1028+Text enclosed in double quotes (`"`) will be rendered with
1029+opening and closing quotes -- that is, `“` and `”`.
1033+"Yes," he said. "That is the way with him."
1038+"Yes," he said. "That is the way with him."
1043+There are two ways to show the literal text of code without running it: inline
1044+and block. Both highlight the contained text in another color.
1046+Note that the backslash, due to its role as the escape character, can only be
1047+displayed in a code block literal and not as inline code literal. This is a
1054+#### Inline Code Literal
1056+Enclosing some text in
1060+characters will cause it to be displayed as code,
1061+inside a `<code>` HTML element with monospace font and highlighted with a
1062+different background color.
1064+Using `` ` \`` is useful when you want to designated only part of a line as code.
1065+Since this page is written in Udon, we've been using this operation
1066+throughout this guide to `format text` to distinguish code from prose.
1070+`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
1074+`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
1076+Also, using the `++` prefix before a word will cause the word to be rendered as
1077+code with the `++` displayed, since that's the standard notation for an arm in
1083+The ++add arm is used to sum two numbers.
1088+The ++add arm is used to sum two numbers.
1090+#### Block Code Literal
1092+By enclosing a block of text in a tick on their own lines
1093+before and after the contained text, the text will be treated as a code block.
1095+Most of our examples so far have used.
1124+Hoon has several syntactic forms for literals (numbers, strings, dates, etc.)
1125+that can be used in udon as well. Udon detects such code, and so these
1126+forms will automatically appear inside a `<code>` element like inline code.
1145+Three or more hyphens, such as `---`, on their own line produce an `<hr>`
1146+element, the 'horizontal rule'. This is rendered as a horizontal line the
1147+width of its containing paragraph.
1156+And below this line, too
1166+And below this line, too
1170+A section of text with the first line beginning with `>` and a space,
1171+and each successive newline indented by two spaces yields a
1172+`<blockquote>` HTML element. This block quote can itself contain more Udon,
1173+including more block quotes to render nested levels of quotation.
1174+Inline italicization with `_` does not work, however.
1176+Blank newlines do not end the block quote, but a blank newline followed by an
1177+unindented line of text _will_ end the quote.
1182+> As Gregor Samsa awoke one morning from uneasy dreams, he
1183+ found himself transformed in his bed into a *monstrous* vermin.
1189+ He is pale and thin, he wears a thin and ragged linen shirt.
1194+> As Gregor Samsa awoke one morning from uneasy dreams
1195+ he found himself transformed in his bed into a **monstrous** vermin.
1201+ He is pale and thin, he wears a thin and ragged linen shirt.
1206+A poem is a section of text with meaningful newlines. Recall that,
1207+normally in Udon, newlines are treated as spaces and do not create a
1208+new line of text. If you want to embed text where newlines are retained, then
1209+indent the text in question with **eight spaces**.
1214+ A shape with lion body and the head of a man,
1215+ A gaze blank and pitiless as the sun,
1216+ Is moving its slow thighs, while all about it
1217+ Reel shadows of the indignant desert birds.
1221+ A shape with lion body and the head of a man,
1222+ A gaze blank and pitiless as the sun,
1223+ Is moving its slow thighs, while all about it
1224+ Reel shadows of the indignant desert birds.
1229+It's possible to use Udon as an HTML templating language akin to
1230+PHP, ERB, JSP, or Handlebars templates. This facility derives
1231+in part from the support for embedding Hoon code inside the markup.
1234+Sail is a domain-specific language within Hoon for creating XML nodes,
1235+including HTML. It can be used directly within Udon to provide
1236+scripting capability with Hoon and also to provide more precise control over the
1237+resulting HTML. The [Sail guide](../sail) is a good place to learn the
1245+ ;strong: Don't panic!
1247+ ;small: [reactive publishing intensifies]
1256+ <strong>Don't panic!</strong>
1258+ <small>[reactive publishing intensifies]</small>
1262+## <a name="blog"></a>A Simple Udon Blog
1264+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.
1266+First, let's setup a desk to serve our posts from:
1269+|merge %site ~your-urbit %home
1272+Then let's mount that desk to unix:
1278+You should now be able to find a `/site` folder inside of your pier
1279+directory (either `comet/` or `your-urbit/`).
1281+To begin serving files from this new desk use `|serve`:
1287+First let's create the landing page for our blog. Create the file
1288+`site/web/blog.udon`:
1297+This is a simple blog I built on Urbit.
1299+;list(dataType "post");
1302+Try viewing this file at `http://localhost:8080`. Note that `8080` might be
1303+`8081`, `8082`, and so on, depending if those ports were being used when you
1306+The only special thing about this page is the `anchor/'none'` front-matter
1307+which simply turns off the Tree navigation. Normally Tree gives navigation
1308+controls for walking around the filesystem, but taking them away makes
1309+the page seem more like a landing page.
1311+The page looks pretty boring now. Let's add our first post. From
1312+unix run `mkdir your-urbit/site/web/blog; touch
1313+your-urbit/site/web/blog/post-1.udon`. (Currently [there's a
1314+bug](https://github.com/urbit/urbit/issues/321) that prevents empty
1315+directories from getting created, so we have to `touch` a file inside
1316+them first.) In `blog/post-1.udon` let's add some filler content:
1319+:- :~ navhome/'/blog'
1322+ title/'My first post!'
1326+Is this a decentralized Medium? Let's find out.
1328+But first, how about a long quote from Paramenides:
1330+> True, he said; and therefore when ideas are what they are in
1331+ relation to one another, their essence is determined by a relation
1332+ among themselves, and has nothing to do with the resemblances, or
1333+ whatever they are to be termed, which are in our sphere, and from
1334+ which we receive this or that name when we partake of them. And
1335+ the things which are within our sphere and have the same names
1336+ with them, are likewise only relative to one another, and not to
1337+ the ideas which have the same names with them, but belong to
1338+ themselves and not to them.
1340+Good to get that out of the way.
1343+You should be able to view this file at:
1344+`http://localhost:8080/blog/post-1.udon`.
1346+You'll also notice that
1347+now the list of posts here: `http://localhost:8080/blog` has
1350+Here we use two pieces of front-matter worth noting: `type` and `navhome`.
1352+- `type` implies that the page has some special handling by Tree. When `type` is
1353+ `post` we automatically put in the `date`, `title` and `author` when they're
1354+ specified and add some styles.
1356+- `navhome` sets the path used by the home button (the circle in the top left).
1357+ Since we want to send people back to the root of our blog, we set this to `/blog`
1359+Adding posts is as easy as dropping Udon files into the `blog/`
1360+directory. Pretty easy!
1364+Now let's enable comments on a blog post.
1366+First, turn comments on by editing the frontmatter in `post-1.udon`. Your
1367+frontmatter should look like this:
1370+:- :~ navhome/'/blog'
1373+ title/'Blog comments'
1379+Now try loading your post here: `your-urbit.urbit.org/blog/post-1`.
1380+You should see a comments box at the bottom of the page.
1382+Try posting a comment! When you do you should see the following in
1386++ /~your-urbit/home/55/web/blog/post-1/comments/~2016.6.20..23.20.54..0b88/md
1388+~your-urbit[tree]: receiving comments, ;join %comments for details
1391+Comments are written into the filesystem in the `comments/` folder
1392+relative to the page they're enabled on. When a new comment is posted
1393+a notification is also posted to the `/comments` `:talk` channel.
1395+Use `;join` to keep up with comments as they get posted:
1398+;join ~your-urbit/comments
1403+## <a name="static"></a>A Static Site
1405+Hosting a static tree of content is easy. Let's put together a really
1406+simple site for an imaginary Urbit meetup group.
1408+We assume you have at least followed the beginning of [our first
1409+examples](#blog) and created a desk called `site` and mounted it to
1412+Note: below we use Urbit's implementation of Markdown, [Udon](#udon).
1413+This markup language allows you to use snippets of Hoon code but not HTML.
1414+In particular, we use Sail, a subset of Hoon. This Sail is rendered as HTML
1415+when the file is served to a client. To learn about Sail, head over to
1416+the [Sail](/docs/learn/arvo/arvo-internals/sail) section of the docs.
1418+In `site/web/meet.udon` put:
1421+:- :~ navhome/'/meet'
1428+# Neo-Tokyo Urbit meetup
1430+
1432+Hi there! We meet once a week at The Chat to work on Urbit projects
1435+You can find out more about the group on the [about](about) page and
1436+follow our projects in [projects](projects).
1439+This is our landing page. Here we're using a few new bits of frontmatter:
1440+`navdpad`, `navmode` and `navpath`. `navdpad` just turns off the nav
1441+arrows. `navmode` can be set to 'navbar' to switch to a horizontal top
1442+nav instead of a left bar. `navpath` sets the path to load the nav
1445+Let's create `about.udon` and `projects.udon`. From Unix use the
1446+technique from before to create a new directory: `mkdir
1447+your-urbit/site/web/meet/; touch your-urbit/site/web/meet/about.udon`.
1448+Then put the following in `site/web/about.udon`:
1451+:- :~ navhome/'/meet'
1461+## Mission statement
1463+The existing framework cannot subdue the new human force that is increasing day
1464+by day alongside the irresistible development of technology and the
1465+dissatisfaction of its possible uses in our senseless social life.
1469+Membership is open to anyone. Just send a message to `~talsur-todres`.
1478+And `site/web/projects.udon`:
1481+:- :~ navhome/'/meet'
1497+;div(class "mini-module")
1498+ ;script(src "/~/at/lib/js/urb.js");
1499+ ;script(src "https://cdn.rawgit.com/seatgeek/react-infinite/0.8.0/dist/react-infinite.js");
1500+ ;script(src "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment-with-locales.js");
1501+ ;script(src "https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.1/moment-timezone.js");
1502+ ;script(src "/talk/main.js");
1503+ ;link(href "/talk/main.css", rel "stylesheet");
1504+ ;talk(readonly "", chrono="reverse", station="comments");
1508+This page introduces a new thing: the `:talk` module. Inside of the
1509+`mini-module` div we load the scripts needed by the `;talk`
1510+component. The `;talk` component is a static component for
1511+displaying a feed from a talk channel inline. Here we're going to
1512+display the discussion from our active projects inline.
1514+We'll need a few active projects though. From unix: `mkdir
1515+your-urbit/site/web/meet/projects; touch
1516+your-urbit/site/web/meet/projects/bike.udon`.
1518+In `site/web/meet/projects/bike.udon`:
1521+:- :~ navhome/'/meet'
1525+ title/'Kaneda's Bike'
1530+# Urbit on a Motorcycle
1532+Discussion on getting urbit to power Kaneda's motorcycle.
1535+Here we just use the `comments` frontmatter to enable comments on the page.
1536+Adding other imaginary projects is left to the reader.
1538+Building a static site takes only a few minutes and a few Udon files. Have fun!