Linking my HTML pages and their Org Mode sources


If you have tinkered with Org Mode, you know you can control the information which appears in the footer using two variables: org-html-postamble (show the footer?) and org-html-postamble-format (how does the footer look like?) 1.

Customizing the postamble

Special format strings can be used in org-html-postamble-format to insert content depending on the page. In fact, most of the information shown on the footer of my web pages, that is, author, last modification and publication date, is directly supported by Org Mode.

The link to the source code, however, requires a special handling. More in details, first I customized org-html-postamble-format, in my .emacs.el file, adding a placeholder for the source code:

(setq org-html-postamble t)

(setq org-html-postamble-format 
'(("en" "<p class=\"author\">Author: %a</p>
   <p class=\"date\">Last modified: %C (created on: %d)</p>
   <p class=\"date\">Published: %T</p>
   <p id=\"source-link\" class=\"source\"></p>")))

Unfortunately it seems that there is no tag for specifying neither the name of the generated file nor that of the source file. Therefore we need to populate the content of the source-link using Javascript, at page load time.

Linking to Git source files at run time

Include the following Javascript code in each page of the website to generate a link to the source file of the page stored in a Git repository available on the Internet:

deploy_url = ""
staging_url = "http://localhost:4567/"
source_url = ""

document.addEventListener("DOMContentLoaded", function(event) { 
    file_link_position = document.getElementById("source-link")
    url = document.URL;
    file = url.replace(deploy_url, "");
    file = file.replace(staging_url, ""); /* this is useless in production, useful in staging */
    file = file.replace(".html", ".org");
    file_link_position.innerHTML = "Link to source: <a href=\"" + source_url + file + "\">" + source_url + file + "</a>"

The code determines the link to the source code file by:

  1. Getting the URL of the current page
  2. Stripping everything from the URL, but the filename
  3. Replace the .html extension with .org
  4. Prepending the URL of the Git repository where the sources are hosted

The event listener then inserts the link computed in this way to the element in the HTML page identified by the id source-link.

Thus, at page generation time, Org Mode includes the footer with the source-link placeholder. When the page is loaded in a browser, the JavaScript inserts the link to the source code of the page in the Git repo.

Publishing Org files directly on your website

Another possibility is publishing the .org files directly on the website. This is slightly preferrable than linking from a repo for two reasons:

  1. It is not necessary to keep the Git repository in sync with the publishing activities or to have a Git repository in the first place.
  2. Org Mode has a publishing function which prettifies the .org files.

The most appropriate way to publish the .org sources on the website is with the publishing function provided by Org Mode:

:publishing-function (org-html-publish-to-html org-org-publish-to-org)
:htmlized-source t

See the Org Mode info file at the node Publishing action, for more details.

Another possibility is using the org-publish-attachment function, which copies files literally. This works fine and copies all .org files in the destination directory. However, the .org extension usually is not attached to any Mime handler and the browser would try to download the .org files, rather than displaying them in a window.

The Javascript described above is still necessary, with slight modificiations (see line 3 and line 10):

 1: deploy_url = ""
 2: staging_url = "http://localhost:4567/"
 3: source_url = "./"
 5: document.addEventListener("DOMContentLoaded", function(event) { 
 6:     file_link_position = document.getElementById("source-link")
 7:     url = document.URL;
 8:     file = url.replace(deploy_url, "");
 9:     file = file.replace(staging_url, ""); /* this is useless in production, useful in staging */
10:     file = file.replace(".html", ".org.html");
11:     file_link_position.innerHTML = "Link to source: <a href=\"" + source_url + file + "\">" + source_url + file + "</a>"
12: });



See HTML preamble and postamble for the documentation.

Author: Adolfo Villafiorita

Last modified: 2021-02-28 Sun 19:32 (created on: 2020-05-27 Wed 00:00)

Published: 2021-02-28 Sun 20:00