Proposal for a simple "Frontend Editor"

My working environment is Linux/Ubuntu and Firefox. I have built a simple frontend editor which allows to open the corresponding md-file in the editor directly from the local HUGO website (http://localhost:1313/):



Step 1: Edit Link

The following partial must be inserted into the templates:

edit.html

{{ if .Site.IsServer }}}<div style="float:right;"><a href="file://{{ .Site.Params.adminPath }}{{ .File.Path }}">edit</a></div>{{ end }}

and in config.toml the absolute path to the content folder is added:

[params]
  adminPath = "/absolute_path_to/my_project/content/"

(improvement see below)

Step 2: Configure Firefox

For security reasons, Firefox prohibits opening a file from an external link. The addon https://addons.mozilla.org/de/firefox/addon/local-filesystem-links/ selectively allow this. You have to add http://localhost/* in the whitelist.

If necessary you have to set in Firefox:
Settings / Files and Applications -> “simple text document”: Gedit (your prefered editor)

After that an “edit” link is shown (only locally), which opens the corresponding md-file directly in the editor. For other operating systems and working environments this has to be adjusted accordingly.

11 Likes

Is this possible? If yes, it will be more general.

env HUGO_PARAMS_adminPath="$(pwd)" hugo server

Configure with Environment Variables - Configure Hugo | Hugo

2 Likes

Great idea! Thanks @peaceiris :grinning:

If you start hugo server like you proposed, it works like this:

Step 1: Edit Link

The following partial must be inserted into the templates:

edit.html

{{ if .Site.IsServer }}<div style="float:right;"><a href="file://{{ .Site.Params.projectPath }}/content/{{ .File.Path }}">edit</a></div>{{ end }}

(Change from first version: add /content/ in the edit link path, change param name to »projectPath«)

config.toml: no changes needed

Step 2: Configure Firefox

see above

Step 3: Start hugo server

run:

env HUGO_PARAMS_projectPath=$(pwd) hugo server
1 Like

one more improvement:

edit.html

{{ if and .Site.IsServer .Site.Params.projectPath }}<div style="float:right;"><a href="file://{{ .Site.Params.projectPath }}/content/{{ .File.Path }}">edit</a></div>{{ end }}

to avoid showing the edit link by calling hugo server without environment param.

2 Likes

Interesting! I implemented something like that for our site, too.

When launching a local server via a little Python script, an additional ‘dev menu’ is shown in the bottom right corner:

This menu contains utilities which are helpful during development. E.g. a way to toggle a ‘Layout’ view (useful for debugging CSS issues in browsers):

The ‘Edit Markdown’ option opens the Markdown file corresponding to the currently viewed page in the standard editor, e.g. MacVim or Notepad++. This works by having the link actually send a little HTTP GET request to localhost:1234/open/ and the Python script used to start the Hugo server handles that request and maps the given HTML page to the matching Markdown file – and opens it. Saving the editor makes Hugo (and thus the browser) reload automatically.

In the Hugo templates, it’s a matter of having

    {{ if .Site.IsServer }}
    {{ partial "devmenu" . }}
    {{ end }}

in the baseof.html file. baseof.html then references the right CSS and includes any JavaScript and HTML to implement the menu. I.e. the menu is nicely separated from the real website.

The little Python server means that this approach works with all browsers, on all operating systems - no plugins are required. This reduces the pain for people to edit the web page.

3 Likes

Interesting! Did you publish this solution?

I am particularly interested in simple solutions that are easy to maintain and easy to understand. My target audience is people who want to build and maintain small websites, without Github, Netlify etc.

1 Like

The code isn’t published anywhere, no. There’s not much to it though:

  1. Instead of hugo server, we use this little Python script (called serve) to launch the Webserver: https://gist.github.com/frerich/b6436ec41e29307affc9c39142d21698 the script expects to be stored one level above the Hugo site directory; change the subprocess.Popen call in line 60 to suit your needs. After launching hugo server, it launches a small HTTP server on port 1314 which expects POST requests to /open?path=<filename>. This will open the given file in an editor (see the open_file function and adjust as needed). What’s important is that this Python script exports the path to the Hugo site directory via the HUGO_DIR environment variable.

  2. In Hugo, a devmenu.html partial which I mentioned in my previous comment uses this JavaScript function to issue an XMLHttpRequest to the web server:

{{ with .File }}
function openSourceFile()
{
   {{ $srcFilePath := printf "%s/content/%s" (getenv "HUGO_DIR") .Path }}

    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://localhost:1314/open?path={{ $srcFilePath }}", true );
    xhr.send(null);
}
{{ end }}

The rest is just a bit of HTML and CSS.

5 Likes

This is probably the most beautiful thread I’ve read this year.
Congratulations to all the people who contributed!

1 Like