summaryrefslogtreecommitdiffstats
path: root/2023/talks/one.md
blob: 1198292b85fa8f9a1aa58bc5ca519450ec55d794 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
[[!meta title="one.el: the static site generator for Emacs Lisp Programmers"]]
[[!meta copyright="Copyright © 2023 Tony Aldon"]]
[[!inline pages="internal(2023/info/one-nav)" raw="yes"]]

<!-- Initially generated with emacsconf-publish-talk-page and then left alone for manual editing -->
<!-- You can manually edit this file to update the abstract, add links, etc. --->


# one.el: the static site generator for Emacs Lisp Programmers
Tony Aldon - <mailto:tony@tonyaldon.com>

[[!inline pages="internal(2023/info/one-before)" raw="yes"]]

Have you ever wanted to write a blog:

-   contained in a unique org file,
-   rendered with only one Emacs command,
-   that can be modified by writing Emacs Lisp code (and CSS too),
-   with "html templates" that are plain Emacs Lisp data,
-   with no config file,
-   and no dependencies on external static site generators?

If so, you might be interested in one.el package.

In this talk, we'll look at how to get started with one.el and write a
a simple blog as an example.

What kind of static sites can be produced with one.el? I don't know
but you can get an idea by checking those 3 websites built with
one.el:

-   <https://lnroom.live>
-   <https://tonyaldon.com>
-   <https://posts.tonyaldon.com>

Below you can see the basics of a one.el website.

In one.el, the following org file/buffer defines a website with 2
pages that we build by calling \`one-build\` command while we are visiting
it:

    *** My website
    :PROPERTIES:
    :ONE: one-default-home
    :CUSTOM_ID: /
    :END:
    
    Welcome to my website!
    
    *** Blog post 1
    :PROPERTIES:
    :ONE: one-default
    :CUSTOM_ID: /blog/page-1/
    :END:
    
    My first blog post!
    
    The path ~/~ in the first ~CUSTOM_ID~ org property tells ~one.el~ that the
    page "My website" is the home page. That page is rendered using
    ~one-default-home~ render function, value of ~ONE~ org property of the
    same headline.
    
    The path ~/blog/page-1/~ in the second ~CUSTOM_ID~ org property tells
    ~one.el~ that we want to render "Blog post 1" page in such a way
    that when we serve our website locally at ~http://localhost:3000~ for
    instance, that page is served at ~http://localhost:3000/blog/page-1/~.
    How that page is rendered is determined by the value of ~ONE~ org
    property of the same headline which is ~one-default~, a render
    function.
    
    As you might have noticed, a ~one.el~ website is an org file where the
    pages are the headlines of level 1 with the org properties ~ONE~ and
    ~CUSTOM_ID~ set. Nothing more!
    
    ~ONE~ is the only org property added by ~one.el~. Its value (an Elisp
    function which returns an HTML string) for a given page determines how
    ~one.el~ renders that page.
    
    The paths of pages are set using ~CUSTOM_ID~ org property.
    
    That's it!
    
    note: I wanted to have a blog written in org-mode that I can modify
    only by evaluating some Emacs Lisp code. This is how one.el got
    started. Down that path I found that the Org parser and exporter do an
    amazing job, in fact 95 percent of the heavy work in one.el. I just
    had to find a way to pass org data to render functions and write an
    Emacs Lisp html generator package to be used by those render
    functions. I'm having a good user experience so far and I hope its
    design will fit your workflow.



[[!inline pages="internal(2023/info/one-after)" raw="yes"]]

[[!inline pages="internal(2023/info/one-nav)" raw="yes"]]