Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,15 @@ RUN HUGO_VERSION="$(cat /tmp/.hugo-version)" \
&& apt-get install /tmp/hugo.deb -y \
&& rm /tmp/hugo.deb /tmp/.hugo-version

# Install Node.js (needed to `npm ci` the FontAwesome/Bootstrap build-time
# deps in themes/pydata). Version is pinned in .node-version at the repo
# root — the same file CI's actions/setup-node reads — so the devcontainer
# and GitHub Actions never drift apart.
COPY .node-version /tmp/.node-version
RUN NODE_VERSION="$(cat /tmp/.node-version)" \
&& curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" -o /tmp/node.tar.xz \
&& tar -xJf /tmp/node.tar.xz --strip-components=1 -C /usr/local \
&& rm /tmp/node.tar.xz /tmp/.node-version

# Help avoid "unsupported locale setting" in Sphinx
RUN echo "export LC_ALL=C.UTF-8" > ~/.bashrc
15 changes: 8 additions & 7 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@
},

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {
// node / npm is required for markdownlint-cli2
// By default, installs lts version
// "ghcr.io/devcontainers/features/node:1": {}
// },
// Node.js itself is installed directly in the Dockerfile (pinned via the
// root .node-version file), not via this feature — avoids two divergent
// install paths.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": ""
// Install the theme's build-time npm deps (FontAwesome/Bootstrap) after
// the workspace is mounted — a Dockerfile RUN step would get shadowed by
// the workspace bind mount, since node_modules isn't part of the repo.
"postCreateCommand": "cd themes/pydata && npm ci",

// There is also a postStartCommand that executes every time the container starts.
// The parameters behave exactly like postCreateCommand, but the commands execute on start rather than create.
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ jobs:
uses: actions/checkout@v4
- name: Install Hugo CLI
uses: ./.github/actions/setup-hugo
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: 'npm'
cache-dependency-path: themes/pydata/package-lock.json
- name: Install npm dependencies
working-directory: themes/pydata
run: npm ci
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ jobs:
uses: actions/checkout@v4
- name: Install Hugo CLI
uses: ./.github/actions/setup-hugo
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: 'npm'
cache-dependency-path: themes/pydata/package-lock.json
- name: Install npm dependencies
working-directory: themes/pydata
run: npm ci
- name: Build with Hugo
env:
HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ static/images/.DS_Store
.env.*
*.pem
*.key
sandbox/
node_modules/
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.19.2
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ This repository is for the main static site of https://saltproject.io, built wit
- The exact version pinned for this project is tracked in the root `.hugo-version` file. The devcontainer and CI both install that exact version automatically (see `.devcontainer/Dockerfile` and `.github/actions/setup-hugo`), so it only needs to be updated in one place.
- Must be the `extended` version, and at least the minimum declared in the vendored `themes/pydata` theme's `hugo.toml` (`module.hugoVersion.min`).
- This was built with the `extended` version of Hugo, which is required.
- Node.js — version pinned in the root `.node-version` file, same single-source-of-truth pattern as `.hugo-version`. Needed to install the theme's FontAwesome/Bootstrap build-time dependencies (see [FontAwesome and Bootstrap](#fontawesome-and-bootstrap-npm-at-build-time)).
- Git
- Python 3.14+ (only needed to run `scripts/validate-tags.py` locally)

### Build a local preview

```bash
# Install the theme's build-time npm dependencies (FontAwesome/Bootstrap) —
# only needs to be re-run when themes/pydata/package.json changes.
cd themes/pydata && npm ci && cd -

# Serves for viewing changes locally
# Dynamically loads updates when changes happen in repo
hugo serve
Expand Down Expand Up @@ -195,6 +200,14 @@ The `scripts` folder holds standalone helper scripts used in local development a
- `.github/workflows/gh-pages.yml` — builds the site on every push, and deploys it to GitHub Pages when the push is a tag matching `v**` (see [Push the current `main` branch to the live site](#push-the-current-main-branch-to-the-live-site)). Deploy-time (`pages`/`id-token` write) permissions are scoped to just the `deploy` job; it never triggers on `pull_request`.
- `.github/actions/setup-hugo` — local composite action shared by both workflows above to install the Hugo CLI. Defaults to the version pinned in the root `.hugo-version` file — the same file the devcontainer's `Dockerfile` reads — so the required Hugo version only needs to be maintained in that one place.

### FontAwesome and Bootstrap (npm, at build time)

`themes/pydata` doesn't vendor FontAwesome or Bootstrap as committed files. `themes/pydata/package.json` pins the exact versions (FontAwesome's JS+SVG icon kit, Bootstrap's JS bundle); Hugo's `[[module.mounts]]` (in `themes/pydata/hugo.toml`) mounts the relevant prebuilt files straight out of `node_modules` into the asset pipeline, and `themes/pydata/layouts/_partials/head/{fontawesome,bootstrap-js}.html` load them through Hugo Pipes (fingerprinted in production builds). This means:

- You need to run `npm ci` inside `themes/pydata` before `hugo build`/`hugo server` will work — the devcontainer does this automatically via `postCreateCommand`; CI does it via an `actions/setup-node` + `npm ci` step in both workflows.
- Their license text isn't duplicated anywhere in this repo — it ships inside the respective (gitignored) npm packages under `themes/pydata/node_modules/.../LICENSE*`.
- The Node.js version used for this is pinned in the root `.node-version` file, following the same single-source-of-truth pattern as `.hugo-version`.

## Credits

The `themes/pydata` theme vendored in this repository is a Hugo port of the [PyData Sphinx Theme](https://github.com/pydata/pydata-sphinx-theme) ([docs](https://pydata-sphinx-theme.readthedocs.io/en/stable/)), originally built for Sphinx documentation sites. Credit to the PyData Sphinx Theme authors and contributors for the design and functionality this port is based on.
Expand Down
14 changes: 14 additions & 0 deletions hugo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ theme = 'pydata'
image_dark = 'images/SaltProject_altlogo_teal.png'
alt_text = 'Salt Project - Home'

# ---------------------------------------------------------------------------
# External links — any link pointing off-site opens in a new tab, except
# base URLs listed under `exceptions` (matched by prefix).
# ---------------------------------------------------------------------------
[params.external_links]
new_tab = true
exceptions = ['https://docs.saltproject.io/']

[params.landing]
title = "Welcome to the Salt Project"
description = "Salt is an open-source automation framework for remote execution, configuration management, and infrastructure orchestration — used by teams to manage thousands of systems from a single control plane."
Expand All @@ -60,31 +68,37 @@ theme = 'pydata'
title = "Install Salt"
description = "Step-by-step instructions for every platform and operating system."
url = "https://docs.saltproject.io/salt/install-guide/en/latest/"
icon = "fa-solid fa-download"

[[params.landing.nav_boxes]]
title = "User Guide"
description = "Learn Salt's core concepts: states, grains, pillars, and more."
url = "https://docs.saltproject.io/salt/user-guide/en/latest/"
icon = "fa-solid fa-book"

[[params.landing.nav_boxes]]
title = "Reference Docs"
description = "Full module and API reference for Salt."
url = "https://docs.saltproject.io/en/latest/contents.html"
icon = "fa-solid fa-code"

[[params.landing.nav_boxes]]
title = "Blog"
description = "Release announcements, community updates, and Salt news."
url = "/blog/"
icon = "fa-solid fa-newspaper"

[[params.landing.nav_boxes]]
title = "Discord Community"
description = "Join the Salt Project Discord, attend events, and connect with contributors."
url = "https://discord.gg/J7b7EscrAs"
icon = "fa-brands fa-discord"

[[params.landing.nav_boxes]]
title = "GitHub"
description = "Browse the source, open issues, and contribute to Salt."
url = "https://github.com/saltstack/salt"
icon = "fa-brands fa-github"

[[params.icon_links]]
name = 'Discord'
Expand Down
3 changes: 2 additions & 1 deletion layouts/community/event-calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ <h1>{{ .Title }}</h1>
document.getElementById("calendar_container").src =
pref + encodeURIComponent(timezone.name().replace(" ", ""));
</script>
{{- $icsURL := "https://calendar.google.com/calendar/ical/salt.project%40broadcom.com/public/basic.ics" }}
<p>
<strong>Download the ics:</strong>
<a href="https://calendar.google.com/calendar/ical/salt.project%40broadcom.com/public/basic.ics">
<a href="{{ $icsURL }}"{{ partial "link-target-attrs.html" $icsURL | safeHTMLAttr }}>
Salt Project Community Calendar ics
</a>
</p>
Expand Down
3 changes: 2 additions & 1 deletion layouts/community/working-groups.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ <h1>{{ .Title }}</h1>
</thead>
<tbody>
{{ range site.Params.working_groups }}
{{ $captainURL := printf "https://github.com/%s" .captain_handle }}
<tr>
<td>{{ .title }}</td>
<td>{{ .description }}</td>
<td><a href="https://github.com/{{ .captain_handle }}">{{ .captain }}</a></td>
<td><a href="{{ $captainURL }}"{{ partial "link-target-attrs.html" $captainURL | safeHTMLAttr }}>{{ .captain }}</a></td>
<td>{{ .discord_channel }}</td>
<td><a href="{{ "community/event-calendar/" | relURL }}">Community calendar</a></td>
</tr>
Expand Down
7 changes: 6 additions & 1 deletion layouts/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@
{{- if $navBoxes -}}
{{- $body = printf "%s<div class=\"row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3 mb-4\">" $body -}}
{{- range $navBoxes -}}
{{- $body = printf "%s<div class=\"col d-flex\"><div class=\"card shadow-sm pst-nav-card w-100\"><div class=\"card-body\"><h3 class=\"card-title h6 fw-bold\">%s</h3><p class=\"card-text\">%s</p></div><a href=\"%s\" class=\"stretched-link\" aria-label=\"%s\"></a></div></div>" $body .title .description .url .title -}}
{{- $iconHTML := "" -}}
{{- with .icon -}}
{{- $iconHTML = printf "<i class=\"%s pst-nav-card-icon\" aria-hidden=\"true\"></i>" . -}}
{{- end -}}
{{- $linkAttrs := partial "link-target-attrs.html" .url -}}
{{- $body = printf "%s<div class=\"col d-flex\"><div class=\"card shadow-sm pst-nav-card w-100\"><div class=\"card-body\">%s<h3 class=\"card-title h6 fw-bold\">%s</h3><p class=\"card-text\">%s</p></div><a href=\"%s\"%s class=\"stretched-link\" aria-label=\"%s\"></a></div></div>" $body $iconHTML .title .description .url $linkAttrs .title -}}
{{- end -}}
{{- $body = printf "%s</div>" $body -}}
{{- end -}}
Expand Down
1 change: 1 addition & 0 deletions themes/pydata/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
4 changes: 0 additions & 4 deletions themes/pydata/assets/css/components/footer.css

This file was deleted.

4 changes: 0 additions & 4 deletions themes/pydata/assets/css/components/header.css

This file was deleted.

15 changes: 0 additions & 15 deletions themes/pydata/assets/css/main.css

This file was deleted.

1 change: 0 additions & 1 deletion themes/pydata/assets/js/main.js

This file was deleted.

35 changes: 35 additions & 0 deletions themes/pydata/hugo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,41 @@ title = 'My New Hugo Project'
extended = true
min = '0.162.1'

# Declaring any [[module.mounts]] disables Hugo's implicit default mounts
# for this module, so the standard component dirs must be re-declared
# explicitly alongside the new npm-sourced vendor mounts below.
[[module.mounts]]
source = "content"
target = "content"
[[module.mounts]]
source = "static"
target = "static"
[[module.mounts]]
source = "layouts"
target = "layouts"
[[module.mounts]]
source = "data"
target = "data"
[[module.mounts]]
source = "assets"
target = "assets"
[[module.mounts]]
source = "i18n"
target = "i18n"
[[module.mounts]]
source = "archetypes"
target = "archetypes"

# Build-time-only npm deps (FontAwesome JS+SVG icon kit, Bootstrap JS
# bundle). Requires `npm install` in themes/pydata before
# `hugo build`/`hugo server`. See themes/pydata/package.json.
[[module.mounts]]
source = "node_modules/@fortawesome/fontawesome-free/js/all.min.js"
target = "assets/vendor/fontawesome/all.min.js"
[[module.mounts]]
source = "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
target = "assets/vendor/bootstrap/bootstrap.bundle.min.js"

# ---------------------------------------------------------------------------
# Default menus (overridable by site hugo.toml)
# ---------------------------------------------------------------------------
Expand Down
7 changes: 7 additions & 0 deletions themes/pydata/layouts/_default/_markup/render-link.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{- /*
Markdown link render hook — applies the same external-link/new-tab rules
(see link-target-attrs.html) to every [text](url) link written in content,
site-wide, with no per-post markup needed.
*/ -}}
{{- $attrs := partial "link-target-attrs.html" .Destination | safeHTMLAttr -}}
<a href="{{ .Destination | safeURL }}"{{ $attrs }}{{ with .Title }} title="{{ . }}"{{ end }}>{{ .Text }}</a>
2 changes: 1 addition & 1 deletion themes/pydata/layouts/_partials/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
{{- end }}
<link rel="stylesheet" href="{{ "styles/pydata-sphinx-theme.css" | relURL }}">
<link rel="stylesheet" href="{{ "styles/hugo-pydata.css" | relURL }}">
<script src="{{ "scripts/fontawesome.js" | relURL }}" defer></script>
{{ partial "head/fontawesome.html" . }}
{{- if not site.Params.disable_search }}
<script>
window.DOCUMENTATION_OPTIONS = {
Expand Down
15 changes: 15 additions & 0 deletions themes/pydata/layouts/_partials/head/bootstrap-js.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- /*
Bootstrap's JS bundle (includes Popper), mounted from node_modules via
[[module.mounts]] in hugo.toml (see themes/pydata/package.json). It's
already a prebuilt minified bundle, so no js.Build step is needed — just
fingerprint it in production.
*/ -}}
{{- with resources.Get "vendor/bootstrap/bootstrap.bundle.min.js" }}
{{- if hugo.IsDevelopment }}
<script src="{{ .RelPermalink }}" defer></script>
{{- else }}
{{- with . | fingerprint }}
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous" defer></script>
{{- end }}
{{- end }}
{{- end }}
15 changes: 0 additions & 15 deletions themes/pydata/layouts/_partials/head/css.html

This file was deleted.

15 changes: 15 additions & 0 deletions themes/pydata/layouts/_partials/head/fontawesome.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- /*
FontAwesome's JS+SVG icon kit, mounted from node_modules via
[[module.mounts]] in hugo.toml (see themes/pydata/package.json). It's
already a prebuilt minified bundle, so no js.Build step is needed — just
fingerprint it in production.
*/ -}}
{{- with resources.Get "vendor/fontawesome/all.min.js" }}
{{- if hugo.IsDevelopment }}
<script src="{{ .RelPermalink }}" defer></script>
{{- else }}
{{- with . | fingerprint }}
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous" defer></script>
{{- end }}
{{- end }}
{{- end }}
15 changes: 0 additions & 15 deletions themes/pydata/layouts/_partials/head/js.html

This file was deleted.

2 changes: 1 addition & 1 deletion themes/pydata/layouts/_partials/header-links.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<ul class="bd-navbar-elements navbar-nav">
{{- range $links }}
<li class="nav-item custom-nav-item{{ if .active }} active{{ end }}">
<a class="nav-link" href="{{ .url }}">{{ .name }}</a>
<a class="nav-link" href="{{ .url }}"{{ partial "link-target-attrs.html" .url | safeHTMLAttr }}>{{ .name }}</a>
</li>
{{- end }}
</ul>
Expand Down
Loading
Loading