DEV Community

Tyler Smith
Tyler Smith

Posted on • Updated on

Build an "Edit Page" button in a Hugo template

One of the downsides of using a static site generator is that the content directory can become difficult to navigate once a site has more than ten pages. Sometimes it would be easier to find a page in the browser than in a code editor.

Platforms like WordPress show "edit page" buttons to logged-in users who are viewing the site. Wouldn't it be nice if Hugo could display an edit page button that launched the current page's markdown file in VS Code?

It can.

Building an "edit page" button

Add the following to the project's config.toml file to allow Hugo to access the system's PWD environment variable:

# config.toml

[security]
  [security.funcs]
    getenv = ['^HUGO_', 'PWD']
Enter fullscreen mode Exit fullscreen mode

The following markup will display an "edit page" button (it's actually a link) when the site environment is set to development:

{{ if eq hugo.Environment "development" }}
  {{ $projectPath := or (os.Getenv "HUGO_PROJECT_PATH" ) (os.Getenv "PWD") }}
  <a 
    href="vscode://file/{{ $projectPath }}/content/{{ .File.Path }}"
    class="button"
  >
    Edit Page
  </a>
{{ end }}
Enter fullscreen mode Exit fullscreen mode

Let's break down what's happening.

Checking the environment

{{ if eq hugo.Environment "development" }}
   ...markup
{{ end }}
Enter fullscreen mode Exit fullscreen mode

This conditional will show the "edit page" link when you're running the server with hugo server. When you build the site with hugo, the site environment will be set to production so the link won't be displayed.

You can also manually set the environment from the command line by using the -e flag. If you wanted to see how the site looks in a production environment while running the development server, you could start Hugo by running hugo server -e production.

You can learn more about setting the environment by reading my post: How to check if a Hugo site is in development or production.

Getting the absolute project path

{{ $projectPath := or (os.Getenv "HUGO_PROJECT_PATH" ) (os.Getenv "PWD") }}
Enter fullscreen mode Exit fullscreen mode

The code above will set the project path to an environment variable called HUGO_PROJECT_PATH, and if it's not defined it will use the current working directory (PWD) where you ran the hugo command.

You can probably ignore the HUGO_PROJECT_PATH variable: it exists to prevent uncommon edge cases. You can read more about why I use HUGO_PROJECT_PATH in my post: Get the absolute path to the project directory in Hugo.

Using a VS Code URL handler

# Only showing the relevant segments of the href
<a
  href="vscode://file/..."
>
Enter fullscreen mode Exit fullscreen mode

VS Code has the ability to open files using URLs via its URL handling mechanism. You can read more about that in the Opening VS Code with URLs documentation.

Getting the markdown file path

# Only showing the relevant segments of the href
<a
  href=".../content/{{ .File.Path }}"
>
Enter fullscreen mode Exit fullscreen mode

The code above will display the path of the current page's markdown file relative to the project's content directory. Because the path is relative to the content directory, we explicitly include the /content/ segment in the URL path.

You can read more about this in Hugo's File Variables documentation.


I hope this post helps you manage the content in your Hugo sites. Please leave a like or comment if you found this helpful!

Discussion (0)