summaryrefslogtreecommitdiffstats
path: root/2023/talks/one.md
blob: d41f0acf33de465981f77213433bd3988d3f90a8 (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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
[[!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.


# Discussion

## Notes

-   Also provides a demo of Jack package
    (<https://github.com/tonyaldon/jack/>)
-   Custom function for rendering by interogating the page-tree
    -   Of use: grabbing metadata from the document/node
-   Easy menu and tab generation would also be great.

- very cool indeed 👏
- thx for the nice presentation
- Yeah, definitely a fun project that solves a problem to keep more Emacs and less external services. Static web sites are the best. :-D
- I agree. I currently use Hugo, but I think this looks great!
- I really like that `jack-html` is a separate project, as that looks nifty.
- jack-html feels like a hiccup for elisp, nice
  - A very programatically solution!
- I didn't watch the talk, but I use esxml to template pages that I generate from Org files: <https://codeberg.org/SystemCrafters/systemcrafters-site/src/commit/b9b33910e68c6a9321ee7dcd92015b8a29b260bd/publish.el#L176> - Lisp backquotes are the best templating language :)
  - To be fair, pcase DSL is not easy to remember. [some discussion on IRC about pcase], recommendation of <http://newartisans.com/2016/01/pattern-matching-with-pcase/>
    - I keep using elisp-demos with great success <https://github.com/xuchunyang/elisp-demos> - adds examples to Help buffer
- This looks like a nice setup.  My blog is still using org-page, which was abandoned years ago. 
- org-page still works though
  - I know, I'm still using it.  But it's finicky in a bunch of ways and I'd like a replacement static site generator. I don't really care if the code is elisp or not, as long as I can write in Org Mode and don't have to run Wordpress.
    - we have a bunch now.. <https://github.com/novoid/lazyblorg> <https://ox-hugo.scripter.co/>

## Questions and answers

- Q: does the "one" part of one.el refers to one source file?
- Does one.el support #+include: to add from other (org) files?
-   Q: What's the main motivation for this new package? I used to use
    ox-hugo and use github action to build the blog.  (Curious as well,
    as I use ox-hugo and have almost 1000 pages)
    -   A: Mapping from org-mode to Hugo added another system to
        understand; wanted Emacs centric approach. 
        (<https://one.tonyaldon.com/> has some rational)
    -   understand. For me, it's just org-mode, ox-hugo take care of
        the rest. And I find it is easy for me. Maybe, I am not used it
        so much. Full control definiitely requires your package.
-   Q: Is it possible to use #+include to add content from other files?
    -   A: Not included; the idea was to only have one file. It is
        possible to code what you want in elisp.
    -   Perhaps org-transclusion would play with this?
-   Q: Can this generate a single site from different sources like
    blog.org (for example.org/blog/), videos.org (for
    example.org/videos/), contact.org (for example.org/contact/), etc?
    -   A: Refer to the previous question's answer
-   Q:Do you have pre-made templates already along with the one.el
    package?
    -   A:Yes and no. There are quite a few constructs/templates in the
        one.el code, you could perhaps use them to customize to get it
        to do what you want.
-   Q: What additional features are there that you would like to add to
    one.el in the future?
    -   A: A full text search
    -   (Comment not from presenter:) I've used Lunrjs which is a JS
        package that keeps all things local; but your site generator
        does need to kick out a JSON representation of the content (e.g.
        path, text, tags/keywords).  I've been considering
        <http://elasticlunr.com/>
-   Q:Can you create navbars on a website and fancy things like
    carousels (pictures rolling/sliding from one to another) using
    one.el?
    -   A:Sidebars, navbars are already part of the package. one.el also
        generates responsive. pages. pages argument used recursively can
        manage/mimic the carousel effect.
-   Q: Would there be an automated way to convert an existing HTML
    document into jack-html form?
    -   A:
    -   One challenge is that HTML documents do not need to be
        "precise" (you don't need to close tags).  So finding a
        tree-parser for HTML (perhaps treesitter?) to build the
        conceptual tree.
-   Q: Does this or you use any other Emacs Packages for your
    package/website ex org-publish.


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

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