@@ -0,0 +1,1538 @@
1++++
2+title = "Sail and Udon"
3+weight = 7
4+template = "doc.html"
5++++
6+
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.
8+
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.
10+
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.
12+
13+## Table of Contents
14+
15+- #### [Sail: A Guide](#sail)
16+
17+- #### [Udon: A Guide](#udon)
18+
19+- #### [Udon: A Simple Blog](#blog)
20+
21+- #### [Udon: A Static Site](#static)
22+
23+## Getting Started
24+
25+Before starting with either Sail or Udon, make sure that your ship is
26+[mounted to Unix](https://urbit.org/docs/using/setup/)
27+
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
33+using.
34+
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:
39+
40+```
41+|serve %sandbox
42+```
43+
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.
49+
50+To switch back to your `%home` desk and set `/web` as your root directory, run:
51+
52+```
53+|serve %/web
54+```
55+
56+We'll be serving the `%home` desk for the examples in this tutorial.
57+
58+### Rendering
59+
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.
63+
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.
72+
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.
78+
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.
82+
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/`.
86+
87+## <a name="sail"></a>Sail: A Guide
88+
89+It’s easy to see how Sail can directly translate to HTML:
90+
91+### Sail code
92+
93+```
94+;html
95+ ;head
96+ ;title: My first webpage
97+ ==
98+ ;body
99+ ;h1: Welcome!
100+ ; Hello, world!
101+ ; We're on the web.
102+ ;div;
103+ ;script@"http://unsafely.tracking.you/cookiemonster.js";
104+ ==
105+==
106+```
107+
108+### HTML code
109+
110+```
111+<html>
112+ <head>
113+ <title>My first webpage</title>
114+ </head>
115+ <body>
116+ <h1>Welcome!</h1>
117+ Hello, world!
118+ We’re on the web.
119+ <div></div>
120+ <script src="http://unsafely.tracking.you/cookiemonster.js"></script>
121+ </body>
122+</html>
123+```
124+
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!
130+
131+It shouldn't be hard to see the similarities here. So let's go into more
132+detail about what the differences are.
133+
134+### Tags and Closing
135+
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.
140+
141+#### Empty
142+
143+Empty tags are closed with a `;` following the tag. Example:
144+
145+```
146+;div;
147+```
148+
149+Equals:
150+
151+```
152+<div></div>
153+```
154+
155+#### Filled
156+
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:
159+
160+```
161+;h1: The title
162+```
163+
164+Equals:
165+
166+```
167+<h1>The title</h1>
168+```
169+
170+#### Nested
171+
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.
175+
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.
178+
179+```
180+;body
181+ ;h1: Blog title
182+ This is some good content.
183+==
184+```
185+
186+Equals:
187+
188+```
189+<body>
190+ <h1>Blog title</h1>
191+ <p>This is some good content.</p>
192+</body>
193+```
194+
195+
196+Conversely, if we want to write a string with no tag at all, then we can prepend
197+those untagged lines with `;`.
198+
199+```
200+;body
201+ ;h1: Welcome!
202+ ; Hello, world!
203+ ; We’re on the web.
204+==
205+```
206+
207+Equals:
208+
209+```
210+<body>
211+ <h1>Welcome!</h1>
212+ Hello, world!
213+ We’re on the web.
214+</body>
215+```
216+
217+
218+#### Attributes
219+
220+Attributes are key-value pairs that go into an HTML node.
221+
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 `,`.
225+
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.
229+
230+
231+#### Generic
232+
233+The code below produces a “Submit” button on the page.
234+
235+Wide-form Sail:
236+
237+```
238+;input(type "submit", value "Submit");
239+```
240+
241+Tall-form Sail:
242+
243+```
244+;input
245+ =type "submit"
246+ =value "Submit";
247+==
248+```
249+
250+Equals:
251+
252+```
253+<input type="submit" value="Submit">`
254+```
255+
256+#### IDs
257+
258+```
259+;nav#header: Menu
260+```
261+
262+Equals:
263+
264+```
265+<nav id="header">Menu</nav>
266+```
267+
268+Add `#` after tag name to add an ID.
269+
270+#### Classes
271+
272+`;h1.text-blue: Title` equals `<h1 class="text-blue">Title</h1>`
273+
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:
276+
277+`;div(class "logo inverse");` equals `<div class="logo inverse"></div>`
278+
279+
280+#### Image
281+
282+`;img@"example.png";`
283+
284+Equals
285+
286+`<img src="example.png"/>`
287+
288+Add `@` after the tag name to link your source.
289+
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
292+the `img` tag.
293+
294+For example:
295+
296+`;img@"https://urbit.org/example.png"(width "100%");`
297+
298+#### Linking
299+
300+`;a/"urbit.org": A link to Urbit.org`
301+
302+Equals
303+
304+`<a href="urbit.org">A link to Urbit.org</a>`
305+
306+Add `/` after tag name to start an href.
307+
308+### Hoon in Sail
309+
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
312+with Hoon code.
313+
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 `>`):
321+
322+```
323+> "I am a l{(mul 3 11)}t Urbit user."
324+! exit
325+```
326+
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
330+what happened?
331+
332+Trying the `mul` function on its own will help answer this question. Try the
333+following command in your Dojo:
334+
335+```
336+> (mul 3 11)
337+33
338+```
339+
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:
343+
344+```
345+> <(mul 3 11)>
346+"33"
347+```
348+
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:
351+
352+```
353+> "I am a l{<(mul 3 11)>}t Urbit user."
354+"I am a l33t Urbit user."
355+```
356+
357+Great!
358+
359+### The Subject
360+
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.
363+
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`.
367+
368+```
369+;html
370+ ;head;
371+ ;body
372+ {<.>}
373+ ==
374+==
375+```
376+
377+Then enter the following command in the Dojo:
378+
379+```
380+> .
381+```
382+
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.
385+
386+Now swap the code below into your Sail file.
387+
388+```
389+/= gas /$ fuel:html
390+;html
391+ ;head;
392+ ;body
393+ {<.>}
394+ ==
395+==
396+```
397+
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.
403+
404+### A More Interesting Example
405+
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.
409+
410+```
411+/= gas /$ fuel:html
412+=/ show-list &
413+=+ wid=(met 3 p.bem.gas)
414+=/ what-kind
415+?: (lte wid 1) "galaxy"
416+?: =(2 wid) "star"
417+?: (lte wid 4) "planet"
418+?: (lte wid 8) "moon"
419+ "comet"
420+;html
421+ ;head
422+ ;meta(charset "utf-8");
423+ ;title: A more advanced page
424+ ==
425+ ;body
426+ ;h1: This is the Title
427+ ; This is a
428+ ;a/"http://urbit.org": link to Urbit.org.
429+ ;span: Check it out!
430+ ;+ ?: show-list
431+ ;ol
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}.
437+ ==
438+ ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
439+ ==
440+==
441+```
442+
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
445+your browser.
446+
447+There are some interesting things here. Let’s go through this code piece by
448+piece.
449+
450+```
451+/= gas /$ fuel:html
452+```
453+
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`.
459+
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.
464+
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.
470+
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.
475+
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`.
480+
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
483+accordingly.
484+
485+```
486+=/ show-list &
487+```
488+
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
491+the source code.
492+
493+```
494+=+ wid=(met 3 p.bem.gas)
495+=/ what-kind
496+ ?: (lte wid 1) "galaxy"
497+ ?: =(2 wid) "star"
498+ ?: (lte wid 4) "planet"
499+ ?: (lte wid 8) "moon"
500+ "comet"
501+```
502+
503+This code chunk is a series of conditionals that checks the host ship’s name to
504+see what its value is.
505+
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.
512+
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
518+`what-kind`.
519+
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.
523+
524+```
525+;html
526+ ;head
527+ ;meta(charset "utf-8");
528+ ;title: A more advanced page
529+ ==
530+```
531+
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.
537+
538+```
539+ ;body
540+ ;h1: This is the Title
541+ ; This is a
542+ ;a/"http://urbit.org": link to Urbit.org.
543+ ;span: Check it out!
544+```
545+
546+The first line here opens, of course, the body node. The second line creates
547+header text.
548+
549+The third, fourth, and fifth lines of code here construct a single line with an
550+inline link.
551+`; This is a` begins the rendered line with plain text.
552+
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.`
555+
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.
561+
562+In the following lines, we beginning to use some Hoon expressions again.
563+
564+```
565+ ;+ ?: show-list
566+ ;ol
567+```
568+
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
573+the last line.
574+
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.
577+
578+```
579+ ;li(style "color: green"): We're doing more interesting stuff now.
580+```
581+
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.
585+
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.
588+
589+```
590+ ;li: We're pretty-printing this sum with Hoon: {<(add 50 50)>}.
591+```
592+
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.
596+
597+
598+```
599+ ;li: The code above is shorthand for {(scow %ud (add 50 50))}.
600+```
601+
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.
606+
607+
608+```
609+ ;li: I am {(trip '~lodleb-ritrul')}.
610+```
611+
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.
617+
618+```
619+ ;li: Actually, my name is {<p.bem.gas>}. I'm a {what-kind}.
620+ ==
621+```
622+
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.
629+
630+Note that `{what-kind}` does not have a `<>` wrapper. Why do you think this is?
631+
632+```
633+ ;div; My name is {<p.bem.gas>}. I'm a {ship}.
634+ ==
635+==
636+```
637+
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”).
641+
642+### Sail Runes
643+
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.
646+
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.
650+
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.
654+
655+`;=` turns a tuple of nodes into a list of nodes.
656+
657+
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:
660+
661+```
662+ ;* ?: show-list
663+ ;=
664+ ;li: I am {(trip '~lodleb-ritrul')}.
665+ ;li: Actually, my name is {<p.bem.gas>}.
666+ ==
667+ ;=
668+ ;div: My name is {<p.bem.gas>}. I'm a {what-kind}.
669+ ;div: No list here!
670+ ==
671+ ==
672+```
673+
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.
676+
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.
679+
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.
684+
685+### Further Reading
686+
687+You should now have foundational knowledge for making web pages with Sail. There
688+is, of course, more to learn.
689+
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.
694+
695+## <a name="udon"></a>Udon: A Guide
696+
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.
703+
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.
708+
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.
714+
715+We provide a few simple examples [here](#examples) of how to publish
716+Udon files using our web interface.
717+
718+## Udon Syntax
719+
720+### Front Matter
721+
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
724+to sibling pages.
725+
726+As an example, let's look at the front matter of this very page:
727+
728+```
729+:- :~ navhome/'/docs/'
730+ sort/'11'
731+ title/'Udon'
732+ ==
733+;>
734+```
735+
736+What's going on here?
737+
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
740+for Udon.
741+
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
747+terminates the list.
748+
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.
753+
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.
757+
758+```
759+:- :~ date/~2018.9.12
760+ author/~lodleb-ritrul
761+ music/'rad'
762+ ==
763+```
764+
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
768+parsing.
769+
770+### Headers
771+
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`.
777+
778+**Example:**
779+```
780+#### Header (h4)
781+
782+##### Header (h5)
783+```
784+**Produces:**
785+
786+#### Header (h4)
787+
788+##### Header (h5)
789+
790+### Italics and Bold
791+
792+Enclosing text with `_` will cause that text to appear italicized, using an `<i>`
793+element.
794+
795+Enclosing text with `*` will cause that text to appear bolded, using a `<b>`
796+element.
797+
798+
799+**Example:**
800+
801+```
802+To get their *attention*, you need that _je ne sais quoi_.
803+```
804+
805+**Produces:**
806+
807+To get their **attention**, you need that _je ne sais quoi_.
808+
809+### Line Break
810+
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
813+the _same line_.
814+
815+**Example:**
816+
817+```
818+Here's the first line.
819+
820+This second line is separated by two newlines, so it's a separate paragraph.
821+
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.
824+```
825+**Produces:**
826+
827+
828+Here's the first line.
829+
830+This second line is separated by two newlines, so it's a separate paragraph.
831+
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.
834+
835+#### Backslash Line Break
836+
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.
840+
841+**Example:**
842+```
843+I wonder how long each line
844+will be if I put backslashes\
845+at the ends of the lines.
846+```
847+**Produces:**
848+
849+I wonder how long each line
850+will be if I put backslashes\
851+at the ends of the lines.
852+
853+### Escape
854+
855+A backslash directly _before_ a word (with no spaces) will be interpreted
856+as an escape character, causing it to be rendered raw.
857+
858+**Example:**
859+
860+```
861+Here is some *bold* text.
862+Here is some \*not bold* text.
863+```
864+
865+**Produces:**
866+
867+Here is some **bold** text.
868+Here is some \*not bold* text.
869+
870+
871+### List
872+
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.
876+
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.
880+
881+New list elements are delineated by newlines beginning with list symbols of
882+the appropriate type (`-` or `+`).
883+
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.
888+
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.
893+
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.
898+
899+**Example:**
900+
901+```
902+- Eggs
903+ (cage-free)
904+- Milk
905+- Butter
906+- Chicken\
907+ Make sure that you get enough for the barbecue
908+- Bread
909+ + Ask the baker what's fresh
910+ + Buy the second-freshest batch
911+- Cereal
912+
913+\
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
918+ a skillet
919+ + Scrambled the eggs in the bowl.
920+ + Pour the eggs onto the skillet before the butter browns
921++ Heat the skillet
922+
923++ Scramble eggs and put them into skillet
924+
925+\
926++ Cool
927++ Alright
928+```
929+
930+Produces
931+
932+- Eggs
933+ (cage-free)
934+- Milk
935+- Butter
936+- Chicken\
937+ Make sure that you get enough for the barbecue
938+- Bread
939+ + Ask the baker what's fresh
940+ + Buy the second-freshest batch
941+- Cereal
942+
943+\
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
948+ a skillet
949+ + Scrambled the eggs in the bowl.
950+ + Pour the eggs onto the skillet before the butter browns
951++ Heat the skillet
952+
953++ Scramble eggs and put them into skillet
954+
955+\
956++ Cool
957++ Alright
958+
959+### Link
960+
961+There are two ways to create links, but both contain the text be hyperlinked
962+in `[]` followed by the destination in `()`.
963+
964+The first type is an inline-style link, which simply uses the full URL as its
965+destination.
966+
967+**Example:**
968+
969+```
970+[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
971+```
972+
973+**Produces:**
974+
975+[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
976+
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.
980+
981+**Example:**
982+
983+```
984+[I'm a reference-style link](../shell)
985+```
986+
987+**Produces:**
988+
989+[I'm a reference-style link](../shell)
990+
991+If this page is located at `https://www.urbit.org/docs/reference/`, then these two
992+examples should have the same destination.
993+
994+#### Anchor Link
995+
996+A link to a section of the same page is in the style of
997+`[text to be linked](#the-destination)`.
998+
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
1002+anchor.
1003+
1004+**Example:**
1005+
1006+```
1007+Check out this [section](#the-destination) that we want to jump to.
1008+
1009+Four score and seven years ago....
1010+
1011+It was the best of times, it was the worst of times...
1012+
1013+## Here we are!
1014+```
1015+
1016+**Produces:**
1017+
1018+Check out this [section](#the-destination) that we want to jump to.
1019+
1020+Four score and seven years ago....
1021+
1022+It was the best of times, it was the worst of times...
1023+
1024+## Here we are!
1025+
1026+### Double Quote
1027+
1028+Text enclosed in double quotes (`"`) will be rendered with
1029+opening and closing quotes -- that is, `“` and `”`.
1030+
1031+**Example:**
1032+```
1033+"Yes," he said. "That is the way with him."
1034+```
1035+
1036+**Produces:**
1037+
1038+"Yes," he said. "That is the way with him."
1039+
1040+
1041+### Code Literal
1042+
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.
1045+
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
1048+bug.
1049+
1050+```
1051+\
1052+```
1053+
1054+#### Inline Code Literal
1055+
1056+Enclosing some text in
1057+```
1058+`
1059+```
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.
1063+
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.
1067+
1068+**Example:**
1069+```
1070+`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
1071+```
1072+**Produces:**
1073+
1074+`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
1075+
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
1078+Hoon.
1079+
1080+**Example:**
1081+
1082+```
1083+The ++add arm is used to sum two numbers.
1084+```
1085+
1086+**Produces:**
1087+
1088+The ++add arm is used to sum two numbers.
1089+
1090+#### Block Code Literal
1091+
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.
1094+
1095+Most of our examples so far have used.
1096+
1097+**Example:**
1098+
1099+
1100+```
1101+ ```
1102+ (def Y (fn [f]
1103+ ((fn [x]
1104+ (x x))
1105+ (fn [x]
1106+ (f (fn [y]
1107+ ((x x) y)))))))
1108+ ```
1109+```
1110+
1111+**Produces:**
1112+
1113+```
1114+(def Y (fn [f]
1115+ ((fn [x]
1116+ (x x))
1117+ (fn [x]
1118+ (f (fn [y]
1119+ ((x x) y)))))))
1120+```
1121+
1122+### Hoon Constants
1123+
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.
1127+
1128+Example:
1129+
1130+```
1131+~2017.8.29 \
1132+0xdead.beef \
1133+%term
1134+```
1135+
1136+produces:\
1137+
1138+~2017.8.29 \
1139+0xdead.beef \
1140+%term
1141+
1142+
1143+### Horizontal Rule
1144+
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.
1148+
1149+**Example:**
1150+
1151+```
1152+Above the line
1153+---
1154+Below the line
1155+-----
1156+And below this line, too
1157+```
1158+
1159+**Produces:**
1160+
1161+
1162+Above the line
1163+---
1164+Below the line
1165+-----
1166+And below this line, too
1167+
1168+### Block Quote
1169+
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.
1175+
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.
1178+
1179+**Example:**
1180+
1181+```
1182+> As Gregor Samsa awoke one morning from uneasy dreams, he
1183+ found himself transformed in his bed into a *monstrous* vermin.
1184+
1185+Quote break.
1186+
1187+> _See_ the child.
1188+
1189+ He is pale and thin, he wears a thin and ragged linen shirt.
1190+```
1191+
1192+**Produces:**
1193+
1194+> As Gregor Samsa awoke one morning from uneasy dreams
1195+ he found himself transformed in his bed into a **monstrous** vermin.
1196+
1197+Quote break.
1198+
1199+> _See_ the child.
1200+
1201+ He is pale and thin, he wears a thin and ragged linen shirt.
1202+
1203+
1204+### Poem
1205+
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**.
1210+
1211+**Example:**
1212+
1213+```
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.
1218+```
1219+**Produces:**
1220+
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.
1225+
1226+
1227+## Sail Expressions
1228+
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.
1232+
1233+
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
1238+specifics.
1239+
1240+Example:
1241+
1242+```
1243+;=
1244+ ;p
1245+ ;strong: Don't panic!
1246+ <br>
1247+ ;small: [reactive publishing intensifies]
1248+ ==
1249+==
1250+```
1251+
1252+Produces:
1253+
1254+
1255+<p>
1256+ <strong>Don't panic!</strong>
1257+ <br>
1258+ <small>[reactive publishing intensifies]</small>
1259+</p>
1260+
1261+
1262+## <a name="blog"></a>A Simple Udon Blog
1263+
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.
1265+
1266+First, let's setup a desk to serve our posts from:
1267+
1268+```
1269+|merge %site ~your-urbit %home
1270+```
1271+
1272+Then let's mount that desk to unix:
1273+
1274+```
1275+|mount /=site=
1276+```
1277+
1278+You should now be able to find a `/site` folder inside of your pier
1279+directory (either `comet/` or `your-urbit/`).
1280+
1281+To begin serving files from this new desk use `|serve`:
1282+
1283+```
1284+|serve %site
1285+```
1286+
1287+First let's create the landing page for our blog. Create the file
1288+`site/web/blog.udon`:
1289+
1290+```
1291+:- :~ anchor/'none'
1292+ ==
1293+;>
1294+
1295+# Hello
1296+
1297+This is a simple blog I built on Urbit.
1298+
1299+;list(dataType "post");
1300+```
1301+
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
1304+started your urbit.
1305+
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.
1310+
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:
1317+
1318+```
1319+:- :~ navhome/'/blog'
1320+ type/'post'
1321+ date/'~2016.6.20'
1322+ title/'My first post!'
1323+ ==
1324+;>
1325+
1326+Is this a decentralized Medium? Let's find out.
1327+
1328+But first, how about a long quote from Paramenides:
1329+
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.
1339+
1340+Good to get that out of the way.
1341+```
1342+
1343+You should be able to view this file at:
1344+`http://localhost:8080/blog/post-1.udon`.
1345+
1346+You'll also notice that
1347+now the list of posts here: `http://localhost:8080/blog` has
1348+updated.
1349+
1350+Here we use two pieces of front-matter worth noting: `type` and `navhome`.
1351+
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.
1355+
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`
1358+
1359+Adding posts is as easy as dropping Udon files into the `blog/`
1360+directory. Pretty easy!
1361+
1362+### Blog comments
1363+
1364+Now let's enable comments on a blog post.
1365+
1366+First, turn comments on by editing the frontmatter in `post-1.udon`. Your
1367+frontmatter should look like this:
1368+
1369+```
1370+:- :~ navhome/'/blog'
1371+ type/'post'
1372+ date/'~2018.6.20'
1373+ title/'Blog comments'
1374+ comments/'true'
1375+ ==
1376+;>
1377+```
1378+
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.
1381+
1382+Try posting a comment! When you do you should see the following in
1383+your console:
1384+
1385+```
1386++ /~your-urbit/home/55/web/blog/post-1/comments/~2016.6.20..23.20.54..0b88/md
1387+------------[0]
1388+~your-urbit[tree]: receiving comments, ;join %comments for details
1389+```
1390+
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.
1394+
1395+Use `;join` to keep up with comments as they get posted:
1396+
1397+```
1398+;join ~your-urbit/comments
1399+```
1400+
1401+That's it! Easy.
1402+
1403+## <a name="static"></a>A Static Site
1404+
1405+Hosting a static tree of content is easy. Let's put together a really
1406+simple site for an imaginary Urbit meetup group.
1407+
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
1410+unix.
1411+
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.
1417+
1418+In `site/web/meet.udon` put:
1419+
1420+```
1421+:- :~ navhome/'/meet'
1422+ navdpad/'false'
1423+ navpath/'/meet'
1424+ navmode/'navbar'
1425+ ==
1426+;>
1427+
1428+# Neo-Tokyo Urbit meetup
1429+
1430+
1431+
1432+Hi there! We meet once a week at The Chat to work on Urbit projects
1433+together.
1434+
1435+You can find out more about the group on the [about](about) page and
1436+follow our projects in [projects](projects).
1437+```
1438+
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
1443+items from.
1444+
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`:
1449+
1450+```
1451+:- :~ navhome/'/meet'
1452+ navdpad/'false'
1453+ navpath/'/meet'
1454+ navmode/'navbar'
1455+ title/'About'
1456+ ==
1457+;>
1458+
1459+# About
1460+
1461+## Mission statement
1462+
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.
1466+
1467+## Members
1468+
1469+Membership is open to anyone. Just send a message to `~talsur-todres`.
1470+
1471+- Shōtarō Kaneda
1472+- Motoko Kusanagi
1473+- Ishikawa
1474+- Faye Valentine
1475+- Spike Spiegel
1476+```
1477+
1478+And `site/web/projects.udon`:
1479+
1480+```
1481+:- :~ navhome/'/meet'
1482+ navdpad/'false'
1483+ navpath/'/meet'
1484+ navmode/'navbar'
1485+ title/'Projects'
1486+ ==
1487+;>
1488+
1489+# Projects
1490+
1491+## Active
1492+
1493+;list;
1494+
1495+## Discussion
1496+
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");
1505+==
1506+```
1507+
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.
1513+
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`.
1517+
1518+In `site/web/meet/projects/bike.udon`:
1519+
1520+```
1521+:- :~ navhome/'/meet'
1522+ navdpad/'false'
1523+ navpath/'/meet'
1524+ navmode/'navbar'
1525+ title/'Kaneda's Bike'
1526+ comments/'true'
1527+ ==
1528+;>
1529+
1530+# Urbit on a Motorcycle
1531+
1532+Discussion on getting urbit to power Kaneda's motorcycle.
1533+```
1534+
1535+Here we just use the `comments` frontmatter to enable comments on the page.
1536+Adding other imaginary projects is left to the reader.
1537+
1538+Building a static site takes only a few minutes and a few Udon files. Have fun!