home

the org web stack

Table of Contents

It's often said that emacs is more of an operating system than a text editor. Well if emacs is as powerful as an operating system then why not use it to run a website? Well I tried it out and it actually works pretty well! I like to call it the ORG web stack.

Using emacs and org mode for my own website started out as a personal challenge to see how far I could push emacs. Personally, I think it works great and am currently using it. That being said, this setup isn't ideal for anything bigger than a hobby project.

1. Content Management

By content management I'm referring to generating new content, turning it into html and organizing existing content. Org Mode excels here. Let's walk through the life of an article to see how.

  1. Generating Ideas

    When I have an idea for a topic I'll use org capture to save it for later. Org capture lets you quickly save notes. You can activate it with a keybinding (ctl-c + c for me). You can then select a custom template to create your note from. For example, I have a template for notes which is pre-populated with a timestamp that it was created at and a link to the file where the note is taken from.

    org-capture-demo.gif

  2. Writing

    Org mode is a note taking program at heart which makes it an excellent tool for writing. It handles most text formatting that you would find in any word processing program like changing font color or creating bold text. It does lists, links and images too. Emacs even includes a program called ispell for spell check. But one of my favorite features is source code blocks which are great if you like to include code in your writing. More on those later…

  3. Converting to HTML

    Org has a built in function org-html-export-to-html to export to html. With a little bit of tinkering you can also rewrite some of it's builtin export functions to customize their behavior. For example, I include my own css when exporting to html to customize how the pages look.

  4. Uploading

    Once an org entry has been converted to an HTML page it needs to be uploaded to a server. We can do this using emacs remote file editing feature, TRAMP. TRAMP allows you to edit remote files as if they were on your local machine. For example, if I want to open a file on my remote server I can simply open the file at /ssh:remote:~/path/to/my/file. Using TRAMP, I can choose to save generated HTML files to my remote server.

Recap: with emacs and org mode we can easily capture ideas, write about them, convert them to html and move them to remote servers.

2. Detour: Org Babel

Before we dive into how we are serving pages we need to talk about code blocks. Most editors allow you to include blocks of code that are formatted. Org mode's code blocks are much more powerful and driven by a system called org babel.

Org babel is powerful. It allows you to run code in code blocks. It's very similar to jupyter notebooks. But it has more features. For example, you can run different languages in each block. You can even pass the output from one block into another, even if the two blocks are in different languages. For example, you can run c code in one block and use the result in another block that uses java. Here is a simple example of a code block for some python code:

#+BEGIN_SRC python
  print("Hello, world!")
#+END_SRC

And here is how it looks exported to HTML:

print("Hello, world!")

It also let's you export code blocks to files via a process called tangling. That means you can keep all of your code organized and annotated inside an org document and tangle it to files when you are ready to ship them. This approach to writing code is often called literate programming.

Remember that feature in emacs called TRAMP that let's us work with remote files? It also works with bable. It can be used to execute source blocks on remote machines or tangle the source blocks to files on remote machines.

3. Serving Content

nginx is used to serve the generated HTML. nginx is a swiss army knife that I enjoy using as a reverse proxy for load balancing but it can be used to serve static content. While nginx is not part of emacs, it's configured with a config file and can be controlled via a CLI interface. That means that we can configure and control nginx from emacs.

  1. Config

    The config file can be written in a org babel source block. Then, when we can tangle it via tramp to the remote server. Here is a basic example:

    events {
    }
    
    http {
        server {
            server_name   your.site.com;
            listen        80;
            root          /a/path/to/your/html/files/;
            location = / {
    
            }
        }
    }
    
    

    When we are done editing it we can simply tangle it to /ssh:your.server:~/path/to/your/config.

  2. Process Control

    Once again, we can use source blocks to control the nginx process. We can create a bash source block to start and restart nginx like so:

    sudo service nginx restart
    date
    
    I like to run date after running a command so we get a timestamp of when the command was last run. This way, if you aren't sure if you just ran the block you can check the output to see if it ran.
    

    And that's all you need to run a website using the ORG web stack!

4. Extra

Now that the article is online we might want to know how much traffic it's getting. Nginx logs all requests to a log file. Let's say we write a script to parse the data into a database (maybe writing code in source blocks?). You can then use org source blocks to query the database. For example, you can see how much traffic the pages are getting with the following block:

#+BEGIN_SRC sqlite :db /ssh:remote:path/to/db.sqlite
  SELECT date, page, count(*) as requests
  FROM metrics
  GROUP BY date, page;
#+END_SRC

Which we can run and get something like the following:

date page requests
2023-04-29 404 13
2023-04-29 page-a 7
2023-04-29 page-b 7
2023-04-29 page-c 7

Date: 6.26.23

Author: Zach Dingels

license