How To

Suggestions for common tasks

Define a shared header, footer, or side bar
Define a base page template
Transform a folder of markdown into HTML
Merge one folder into another
Add an index page to a folder created with a map

You can create an Origami template that defines shared HTML elements or other content in a single file, which you can then include in other page templates for any page that needs that shared content.

In this example, you’ll create a simple navigation header.

Define a topNav.html file to hold the shared navigation elements.

<!-- topNav.html -->
<header>
  <a href="/">Home</a>
</header>

The above just defines a single link to the home page; add any other elements you want on your pages.

Define some templates for pages that will use the shared navigation. Inside each template, include a reference to ${ topNav.html }.

Examples:

// about.ori
indent`
  ${ topNav.html }
  <h2>About Us</h2>
  <p>We have fun making websites.</p>
`
// contact.ori
indent`
  ${ topNav.html }
  <h2>Contact Us</h2>
  <p>We'd love to hear from you.</p>
`

In a site.ori site definition, define HTML pages that use the above templates.

// site.ori
{
  about.html = about.ori/
  contact.html = contact.ori/
}

When Origami generates a page like about.ori, the page template incorporates the topNav.html file into the output.

$ ori site.ori/about.html
<header>
  <a href="/">Home</a>
</header>
<h2>About Us</h2>
<p>We have fun making websites.</p>

This technique can be combined with the following one.

Define a base page template for multiple pages

Most sites define a consistent structure for all their pages that includes basic HTML elements for things like links to spreadsheet, <meta> tags, and other top-level page elements. You can define this structure in a base template that will be used by other templates.

Create a page.ori template that will serve as the base template.

// page.ori
(document) => indent`
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      <title>${ document/title }</title>
    </head>
    <body>
      <h1>${ document/title }</h1>
      ${ document/@text }
    </body>
  </html>
`

This template expects to receive a document object that has a title property with the document title and a text property with the body text.

Create an about.ori template for an About page. This page will call the base page.ori template as a function, passing in the desired title and text for the About page.

// about.ori
page.ori({
  title: "About Us"
  @text: indent`
    <p>We have fun making websites.</p>
  `
})

Create a site.ori file to define your site:

// site.ori
{
  about.html = about.ori/
}

When a site visitor asks for about.html, this will invoke the about.ori template. That in turn will call the base page.ori template, which will incorporate the page title and body text into the page structure for the complete page.

$ ori site.ori/about.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>About Us</title>
  </head>
  <body>
    <h1>About Us</h1>
    <p>We have fun making websites.</p>
  </body>
</html>

As a site grows, the base page template can become quite large. For clarity, it can be helpful to separate out pieces of the base template into separate files. For example, if the top navigation area gets complex, you can separate it into a separate top navigation template; see the preceding section.

Transform a folder of markdown into HTML

You may want to use markdown format to write pages which are primarily text. You can then have Origami transform the markdown pages to HTML.

Create a folder called markdown to hold your .md markdown files:

src/
  markdown/
    about.md
    products.md
    support.md
  site.ori

Your markdown folder will have the following structure:

g markdown/ ->markdown/ markdown/ markdown/about.md # About markdown/->markdown/about.md about.md markdown/products.md # Products markdown/->markdown/products.md products.md markdown/support.md # Support markdown/->markdown/support.md support.md

In your site definition, add a line that calls the map to transform all the markdown files using the mdHtml builtin.

// site.ori
{
  pages/ = map(markdown, mdHtml)
}

The map builtin will use mdHtml to transform both the keys (names) and values (contents) of the markdown files: the file extension on the keys will change from .md to .html, and the values will change from markdown text to HTML.

g pages/ ->pages/ pages/ pages/about.html <h1 id="about">About</h1> pages/->pages/about.html about.html pages/products.html <h1 id="products">Products</h1> pages/->pages/products.html products.html pages/support.html <h1 id="support">Support</h1> pages/->pages/support.html support.html

If you want the pages to appear at a higher level of the site, you can combine this technique with the spread operator; see below.

Merge one folder into another

Sometimes you want to group a set of pages into a subfolder to keep your source content organized, but have all those pages appear as if they were direct children of some other folder.

For example, if you are an indie website author, you may want to create set of slash pages at the top level of your site for various aspects of you and your interests. You can create these pages in HTML directly (or use markdown; see the preceding section).

It may be useful to group such pages into a subfolder, but them merge them into the top level of your site so the pages have shorter URLs.

Group the pages into a subfolder called slash:

src/
  slash/
    about.html
    links.html
    now.html
  index.html
  site.ori

If you include the slash folder as a subfolder of your site:

// site.ori
{
  index.html
  slash
}

you will have the following site hierarchy:

g index.html <h1>Home</h1> ->index.html index.html slash/ ->slash/ slash/ slash/about.html <h1>About</h1> slash/->slash/about.html about.html slash/links.html <h1>Links</h1> slash/->slash/links.html links.html slash/now.html <h1>Now</h1> slash/->slash/now.html now.html

This would give you URLs like /slash/now.html.

Since you want the slash pages to appear at the top level of your site, use the spread operator to merge the contents of the slash folder into the site’s top level:

// siteSpread.ori
{
  index.html
  ...slash
}

which produces the following hierarchy:

g index.html <h1>Home</h1> ->index.html index.html about.html <h1>About</h1> ->about.html about.html links.html <h1>Links</h1> ->links.html links.html now.html <h1>Now</h1> ->now.html now.html

With this, all the pages are directly available at the root of the site and URLs like /now.html.

Add an index page to a folder created with a map

Suppose you have a folder of posts you’re create with map, perhaps to transform a folder of markdown into HTML, and you want the resulting virtual folder of HTML to have its own index.html page. You can use the same spread operator shown above.

In this situation, you’re going to be using your transformed markdown twice: once to create the HTML pages in the pages area, and a second time for the index page for the pages area. To make your map reusable, define it in a separate file called data.ori

// data.ori
map(markdown, mdHtml)

Now create a basic index page template in pagesIndex.ori:

// pagesIndex.ori
(pages) => indent`
  <ul>
    ${ map(pages, (page, name) => indent`
      <li><a href="/pages/${ name }">${ name }</a></li>
    `) }
  </ul>
`

Then define a site.ori formula to create the pages area. This expression will use the spread operator to incorporate all the individual pages. To that set of pages, the index.html formula will create the index page, passing the set of individual pages to the pagesIndex.ori template.

// site.ori
{
  pages = {
    ...data.ori
    index.html = pagesIndex.ori(data.ori)
  }
}

To visualize this operation: data.ori defines a tree that looks like this.

g markdown/ about.html <h1 id="about">About</h1> ->about.html about.html products.html <h1 id="products">Products</h1> ->products.html products.html support.html <h1 id="support">Support</h1> ->support.html support.html

The pages definition in site.ori includes all of that, plus the additional index.html page:

g about.html <h1 id="about">About</h1> ->about.html about.html products.html <h1 id="products">Products</h1> ->products.html products.html support.html <h1 id="support">Support</h1> ->support.html support.html index.html <ul> <li><a href="/pages/about.html">a… ->index.html index.html