Pages
  • one.el
  • Install one.el
  • Getting started
  • How does one.el work?
  • one-default render function
  • Miscellaneous
  • one-ox
  • one-ox | headline
  • one-ox | src-block
  • one-ox | quote-block
  • one-ox | fixed-width and example-block
  • one-ox | links
  • one-ox | plain-list and item
one.el
  • one.el
  • Install one.el
  • Getting started
  • How does one.el work?
  • one-default render function
  • Miscellaneous
  • one-ox
  • one-ox | headline
  • one-ox | src-block
  • one-ox | quote-block
  • one-ox | fixed-width and example-block
  • one-ox | links
  • one-ox | plain-list and item

one-default render function

Table of content
  • The org document
  • Build the website
  • Home
  • Page 1
  • Page 2
  • How was "Page 1" built?

In How does one.el work? page we saw that render functions are at the heart of one.el mechanism. They determine how pages are rendered.

We saw that

(defun hello-world (page-tree pages global)
      "<h1>Hello world!</h1>")

defines a valid render function that can be used to render pages of a one.el website by setting ONE org property to hello-world like this for instance:

* The home page
:PROPERTIES:
:ONE: hello-world
:CUSTOM_ID: /
:END:
* Blog post 1
:PROPERTIES:
:ONE: hello-world
:CUSTOM_ID: /blog/page-1/
:END:

one.el comes with several default render functions that can be used instead of the dummy hello-world function:

  • one-default-home: org content,

  • one-default-home-list-pages: org content followed by the list in reverse order of the pages of the website,

  • one-default: org content with navigation buttons at the bottom to go to the previous page, the next page or a random one,

  • one-default-with-toc: same as one-default but with a table of content at the top of the page and

  • one-default-with-sidebar: same as one-default but with a sidebar listing all the pages in the website,

  • one-default-doc: same as one-default-with-sidebar but with a table of content at the top of the page.

Those default render functions use one-ox custom org export backend and one-default-css custom CSS style sheet.

If we want to start a new project using these defaults, we can use one-default-new-project command (see Getting started).

If you plan to write your own render functions you may find the following sections interesting.

The org document

Let's consider the following org document in a file named one.org for instance:

* Home
:PROPERTIES:
:ONE: one-default-home
:CUSTOM_ID: /
:END:
* Page 1
:PROPERTIES:
:ONE: one-default
:CUSTOM_ID: /blog/page-1/
:END:
** Headline foo 1

[[#/blog/page-2/][Link to Page 2]]

** Headline foo 2
*** Headline bar

Some content.

*** Headline baz
:PROPERTIES:
:CUSTOM_ID: /blog/page-1/#baz
:END:

#+BEGIN_SRC emacs-lisp
(message "foo bar baz")
#+END_SRC

* Page 2
:PROPERTIES:
:ONE: one-default
:CUSTOM_ID: /blog/page-2/
:END:

[[#/blog/page-1/#baz][Link to Headline baz in Page 1]]

Let's generate the file ./assets/one.css that contains the content of one-default-css string by calling one-default-add-css-file command.

Our project structure is now:

.
├── assets
│   └── one.css
└── one.org

Build the website

Now, while vising the file one.org we call one-build which builds "Home", "Page 1" and "Page 2" pages under the directory ./public/ such that our project tree is now:

.
├── assets
│   └── one.css
├── one.org
└── public
    ├── blog
    │   ├── page-1
    │   │   └── index.html
    │   └── page-2
    │       └── index.html
    ├── index.html
    └── one.css

Home

The page "Home" has been generated:

  • in the file ./public/index.html respecting the path information / in CUSTOM_ID org property and

  • its HTML content has been created using one-default-home render function specified in ONE org property.

./public/index.html (pretty printed for the demonstration):

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="/one.css" />
    <title>Home</title>
  </head>
  <body>
    <div class="header">Home</div>
    <div class="content">
      <div id="home"><div></div></div>
    </div>
  </body>
</html>

Page 1

The page "Page 1" has been generated:

  • in the file ./public/blog/page-1/index.html respecting the path information /blog/page-1/ in CUSTOM_ID org property and

  • its HTML content has been created using one-default render function specified in ONE org property.

./public/blog/page-1/index.html (pretty printed for the demonstration):

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="/one.css" />
    <title>Page 1</title>
  </head>
  <body>
    <div class="header"><a href="/">Home</a></div>
    <div class="content">
      <div class="title">
        <div class="title"><h1>Page 1</h1></div>
      </div>
      <div></div>
      <div>
        <h2 id="one-df8f0f16cc">Headline foo 1</h2>
        <div>
          <p><a href="/blog/page-2/">Link to Page 2</a></p>
        </div>
      </div>

      <div>
        <h2 id="one-9c2f3b8536">Headline foo 2</h2>
        <div>
          <h3 id="one-fe469dd578">Headline bar</h3>
          <div><p>Some content.</p></div>
        </div>

        <div>
          <h3 id="baz">Headline baz</h3>
          <div>
            <pre><code class="one-hl one-hl-block">(message <span class="one-hl-string">"foo bar baz"</span>)</code></pre>
          </div>
        </div>
      </div>
      <div class="nav">
        <a href="/">PREV</a><a href="/">RANDOM</a
        ><a href="/blog/page-2/">NEXT</a>
      </div>
    </div>
  </body>
</html>

Page 2

The page "Page 2" has been generated:

  • in the file ./public/blog/page-2/index.html respecting the path information /blog/page-2/ in CUSTOM_ID org property and

  • its HTML content has been created using one-default render function specified in ONE org property.

./public/blog/page-2/index.html (pretty printed for the demonstration):

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="/one.css" />
    <title>Page 2</title>
  </head>
  <body>
    <div class="header"><a href="/">Home</a></div>
    <div class="content">
      <div class="title">
        <div class="title"><h1>Page 2</h1></div>
      </div>
      <div>
        <p><a href="/blog/page-1/#baz">Link to Headline baz in Page 1</a></p>
      </div>
      <div class="nav">
        <a href="/blog/page-1/">PREV</a><a href="/">RANDOM</a>
      </div>
    </div>
  </body>
</html>

How was "Page 1" built?

When we called one-build in one.org buffer, the whole buffer was parsed with the function one-parse-buffer and a list of pages was built from that parsed tree and looked like this:

((:one-title "Home"
  :one-path "/"
  :one-render-page-function one-default-home
  :one-page-tree (headline (:raw-value "Home" ...) ...))
 (:one-title "Page 1"
  :one-path "/blog/page-1/"
  :one-render-page-function one-default
  :one-page-tree (headline (:raw-value "Page 1" ...) ...))
 (:one-title "Page 2"
  :one-path "/blog/page-2/"
  :one-render-page-function one-default
  :one-page-tree (headline (:raw-value "Page 2" ...) ...)))

Let's call pages that list of pages.

Then for each page in pages the function one-render-page was called with page, pages and global (see one-add-to-global variable) as arguments.

Finally, in one-render-page the function one-default or one-default-home was called with the arguments page-tree, pages and global to create the HTML content of each page whom path under the directory ./public/ was determined by the value of :one-path property in page and page-tree was the value of :one-page-tree property in page.

Focusing on "Page 1", the function one-default was called with the arguments page-tree, page and global with page-tree being the following parsed tree of the headline defining "Page 1":

(headline
 (:raw-value "Page 1"
  :CUSTOM_ID "/blog/page-1/"
  :ONE "one-default"
  :parent (org-data ...)
  :one-internal-id "one-9c81c230b6"
  ...)
 (section (...) (property-drawer ...))
 (headline
  (:raw-value "Headline foo 1"
   :one-internal-id "one-4df8d962d9"
   ...)
  (section (...) (paragraph ...)))
 (headline
  (:raw-value "Headline foo 2"
   :one-internal-id "one-9d89da8271"
   ...)
  (headline
   (:raw-value "Headline bar"
    :one-internal-id "one-95fa001487"
    ...)
   (section
    (...)
    (paragraph (...) #("Some content. " 0 14 (:parent #4)))))
  (headline
   (:raw-value "Headline baz"
    :CUSTOM_ID "/blog/page-1/#baz"
    :one-internal-id "baz"
    ...)
   (section
    (...)
    (property-drawer ...)
    (src-block
     (:language "emacs-lisp"
      :value "(message \"foo bar baz\")"
      ...))))))

In one-default the org content of "Page 1" was exported into a HTML string using org-export-data-with-backend and one-ox custom org export backend. Then this HTML string was used in a data structure representing the HTML page. Finally, jack-html (see jack) transformed that data structure into a HTML string which was written on the file ./public/blog/page-1/index.html:

(defun one-default (page-tree pages _global)
  "Default render function.

See `one-is-page', `one-render-pages' and `one-default-css'."
  (let* ((title (org-element-property :raw-value page-tree))
         (path (org-element-property :CUSTOM_ID page-tree))
         (content (org-export-data-with-backend
                   (org-element-contents page-tree)
                   'one-ox nil))
         (website-name (one-default-website-name pages))
         (nav (one-default-nav path pages)))
    (jack-html
     "<!DOCTYPE html>"
     `(:html
       (:head
        (:meta (@ :name "viewport" :content "width=device-width,initial-scale=1"))
        (:link (@ :rel "stylesheet" :type "text/css" :href "/one.css"))
        (:title ,title))
       (:body
        (:div.header (:a (@ :href "/") ,website-name))
        (:div.content
         (:div.title
          ,(if (not (string= path "/"))
               `(:div.title (:h1 ,title))
             '(:div.title-empty)))
         ,content
         ,nav))))))
PREVRANDOMNEXT