#+TITLE: How to publish pages using Org Publish
#+OPTIONS: num:nil
#+DATE: <2025-11-08 Sat 10:57>
#+filetags: :website:

* How to publish web pages using ~org-publish~

This website is heavily inspired by some people who have decided to use ~org-publish~ as a way to convert ~org~ files into ~html~. I came across a few that took the plunge and decided to migrate from platforms like Wordpress and instead opted for a more transparent, text-based workflow.

The Org website[fn:1] now looks a lot better than it used to.

There is a [[https://en.wikipedia.org/wiki/Unix_philosophy][Unix philosophy]] that emphasises building simple and compact code that can be easily maintainable, and following this approach (do one thing well) aligns with this philosophy.

So how does one go about publishing web pages through Emacs's ~org-publish~? The answer is quite simple. You probably will need to have some familiarity with ~elisp~[fn:2] although it's not a must.

The first thing we will want to do is edit our ~init.el~ file, which is the *initialization* file. In this file we want to add the following:

/This is a simple and quick way of getting this setup, although there is a better and more scalable approach to this, where we have a build script that runs each time we want to generate the project. See [[file:setup.org][here]] for more details./

#+begin_src emacs-lisp

  (setq org-publish-project-alist
      '(("org-notes"
         :base-directory "~/web"
         :base-extension "org"
         :publishing-directory "~/web"
         :recursive t
         :publishing-function org-html-publish-to-html
         :with-author nil
         :with-creator nil
         :html-validation-link nil
         :with-toc t
         :section-numbers t
         :html-head "<link rel=\"stylesheet\" href=\"style.css\" />"
         )
        ("org-static"
         :base-directory "~/web"
         :base-extension "css\\|js\\|png\\|jpg\\|gif"
         :publishing-directory "~/web/output"
         :recursive t
         :publishing-function org-publish-attachment)
        ("website" :components ("org-notes" "org-static"))))

#+end_src

What this snippet of code is doing is it is telling ~org-publish~ what **configurations** we want to use when we end up running the publish command. Under ~~/web~ is where we want to include our files. Let us take a simple example and create an ~index.org~ file:

#+begin_src emacs-lisp
  
  ,#+TITLE: Website Name
  ,#+OPTIONS: toc:nil num:nil
  
  ,* Welcome!

  This is a simple website

#+end_src

There are some metadata at the very top as we can see, these help us customise each page the way we want to. Here I disabled the Table of Contents and section numbers just for this file. We can also create a simple ~styles.css~ file in the same directory.
After doing this, we can run the command:

#+begin_src emacs-lisp
  
  M-x org-publish RET website

#+end_src

This will generate a html file inside the ~~/web/output/~ directory, and we can serve this file using any static site generation tools; I recommend python due to it's simplicity:

#+begin_src bash

  cd ~/web/output
  python3 -m http.server 8000 

#+end_src

And there we go! The files are now being hosted on ~http://localhost:8000/~ and we have a fully functioning workflow for converting org files into a static website.

* Contact

Feel free to reach out on GitHub: https://github.com/zainezq


[fn:1] See: https://orgmode.org/manual/Publishing.html

[fn:2] Emacs Lisp is a Lisp dialect made for Emacs. See: https://en.wikipedia.org/wiki/Emacs_Lisp
