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
93 changes: 55 additions & 38 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,40 @@
include .github/build/Makefile.core.mk
include .github/build/Makefile.show-help.mk

# Changes to any main recipe in this Makefile, require a corresponding change in all other repositories subscribed to the 'meshery-academy' topic.

# htmltest is fetched and run on demand via 'go run' (no install step). Pin it for
# reproducible link checks; leave as 'latest' to always use the newest release.
HTMLTEST_VERSION ?= latest
export HTMLTEST_VERSION

# ---------------------------------------------------------------------------
# Academy
# SHARED TEMPLATE — PROPAGATE CHANGES
#
# This Makefile is a shared template. Any change to a main recipe below must be
# mirrored in the corresponding Makefile of each repository listed here:
#
# - https://github.com/layer5io/docs
# - https://github.com/meshery/meshery/tree/master/docs
# - https://github.com/topics/meshery-academy
#
# Target names, prerequisites, and the npm scripts they call form the shared
# contract; keep them identical across repositories. The Docker section,
# theme-update, the check-go implementation, and any extra check-deps guards are
# per-repository adaptations and are expected to differ. This repository is the
# theme itself and therefore has no theme-update target.
#
# MAIN TARGETS
#
# setup Install site dependencies (npm install).
# build Build locally with draft, future, and expired content.
# build-preview Build for a deploy preview (uses DEPLOY_PRIME_URL).
# build-production Build for production. Pass BASE_URL=... to set the base URL.
# site Serve locally with live reload.
# serve Serve locally once, file watcher off (no live reload).
# clean Empty the build cache, reinstall dependencies, run 'site'.
# lint / lint-fix Check or auto-fix Markdown linting issues.
# check-links Check internal links in the built site.
# check-deps Verify required commands and local dependencies.
# check-go Verify Go is installed (required by Hugo Modules).
#
# ---------------------------------------------------------------------------

# ---------------------------------------------------------------------------
# MAINTENANCE: Show help for available targets
# MAINTENANCE
# ---------------------------------------------------------------------------

## Verify required commands and local dependencies are present.
Expand All @@ -43,13 +64,20 @@ check-go:
@command -v go > /dev/null || { echo "Go is not installed. Please install it before proceeding."; exit 1; }
@echo "Go is installed."

## Update the academy-theme package to latest version
theme-update: check-go check-deps
@echo "Updating to latest academy-theme..."
npm run update:theme
## Check internal links in the built site.
check-links: check-go check-deps
npm run check:links

## Check Markdown for linting issues.
lint: check-deps
npm run lint

## Fix Markdown linting issues.
lint-fix: check-deps
npm run lint:fix

# ---------------------------------------------------------------------------
# LOCAL BUILDS: Show help for available targets
# LOCAL BUILDS
# ---------------------------------------------------------------------------

## Install site dependencies
Expand All @@ -66,50 +94,39 @@ build-preview: check-go check-deps

## Build the site for production.
build-production: check-go check-deps
npm run build:production
set -e; \
if [ -n "$(BASE_URL)" ]; then \
base_url="$(BASE_URL)"; \
base_url="$${base_url%/}/"; \
npm run build:production -- --baseURL "$$base_url"; \
else \
npm run build:production; \
fi

## Build and run the site locally with live reload (draft and future content enabled).
site: check-go check-deps
npm run site

## Build and serve the site once with the file-watcher off (no live reload).
site-no-watch: check-go check-deps
npm run site:no-watch
serve: check-go check-deps
npm run serve

## Empty the build cache, reinstall dependencies, and run the site locally.
clean:
npm run clean
$(MAKE) setup
$(MAKE) site

## Check internal links in the built site (htmltest is fetched on demand via 'go run').
check-links: check-go check-deps
npm run check:links

## Format code using Prettier
format:
npm run format

## Check formatting without writing changes.
format-check:
npm run format:check

## Fix Markdown linting issues
lint-fix:
npx --yes markdownlint-cli2 --fix "content/**/*.md"

.PHONY: \
setup \
build \
build-preview \
build-production \
site \
site-no-watch \
serve \
clean \
check-links \
format \
format-check \
lint \
lint-fix \
check-deps \
check-go \
theme-update
check-go
65 changes: 37 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ This repository offers a starter template for creating your own, dedicated acade
Before you begin, ensure you have the following installed on your system:

1. [**Go**](https://go.dev/doc/install) (use the version required by the root `go.mod` file)
2. [**Hugo**](https://gohugo.io/getting-started/installing/) (extended version, minimum `0.146.0` as defined in `hugo.yaml`)
2. [**Node.js / npm**](https://nodejs.org/) (LTS recommended)

> Hugo Extended is installed locally by `make setup` and does not need to be installed globally.

## Getting Started

Expand Down Expand Up @@ -64,7 +66,7 @@ First, create a copy of this repository under your own GitHub account.

### 3. Configure Your Organization Directories

The Academy platform uses an **Organization UID** to keep content separate and secure. You must get this ID from the Layer5 CLoud before proceeding.
The Academy platform uses an **Organization UID** to keep content separate and secure. You must get this ID from the Layer5 Cloud before proceeding.

Once you have your UID, rename the placeholder directories:

Expand Down Expand Up @@ -127,30 +129,35 @@ questions:

### 5. Add Assets (Images & Videos)

Enhance your course with images and other visual aids. To ensure compatibility with the multi-tenant Academy platform, **do not use standard Markdown image links**. Instead, use the `usestatic` shortcode, which generates the correct, tenant-aware path for your assets.
Enhance your course with images and other visual aids using the **Page Bundling** method, which keeps assets alongside the content that references them and ensures they resolve correctly for each organization.

**How to Add an Image**

1. Place your image file (e.g., `hugo-logo.png`) in your scoped static directory:
1. Place your image file directly in the same directory as your Markdown content:

```text
static/<your-organization-uid>/images/hugo-logo.png
```
2. In your `lesson-1.md` file, embed the image using the `usestatic` shortcode. The `path` is relative to your scoped static folder:
```text
content/learning-paths/<your-organization-uid>/
└── <your-course>/
└── <your-module>/
├── _index.md
└── hugo-logo.png
```

```text
![The Hugo Logo]({{</* usestatic path="images/hugo-logo.png" */>}})
```
2. In your `lesson-1.md` file, reference the image using standard Markdown syntax:

```markdown
![The Hugo Logo](hugo-logo.png)
```
Comment on lines +132 to +150

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n --hidden \
  --glob '!node_modules/**' \
  --glob '!public/**' \
  'render-image\.html|PageInner\.Parent|Parent\.Resources|Resources\.Get' .

Repository: layer5io/academy-example

Length of output: 162


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'Tracked files relevant to README/theme/config:\n'
git ls-files | rg '(^README\.md$|^config|academy-theme|themes|layouts|content|assets)$|(^themes/academy-theme|academy-theme|layouts/|content/)' | head -200

printf '\nREADME relevant section:\n'
sed -n '120,160p' README.md

printf '\nSearch for page-bundle, Parent, Resources, render hooks, and resources in repository:\n'
rg -n --hidden --glob '!node_modules/**' --glob '!public/**' 'page[- ]?bundle|PageInner\.Parent|\.Parent|Parent\.(Resources|Params)|Resources\.(GetMatch|Get|Params|Resources)|render[-_].*html|resources' . | head -300

Repository: layer5io/academy-example

Length of output: 15035


🌐 Web query:

Hugo render hooks page resources bundle context Resources.GetMatch parent resources

💡 Result:

To access page resources within a Hugo render hook, you use the.Page object available in the render hook context to call resource methods like.Resources.GetMatch [1][2][3]. Key considerations for accessing these resources include: 1. Accessing Page Resources: Inside a render hook, the.Page object represents the page currently being rendered [3]. You can access its bundled resources by calling.Page.Resources.GetMatch.Destination (or.Get) [4][5][2]. Note that.Destination contains the link or image path from the Markdown file [5][2]. 2. Bundle Context: Page resources are only available if the content file is part of a page bundle (a directory with an index.md or _index.md file) [1][6]. If the page is not a bundle, or if the resource is not correctly associated with that bundle, the lookup will fail [7][3]. 3. Branch Bundles: If you are working with a branch bundle (e.g., a sub-page within a section), you may need to access the parent page's resources if the current page itself is not a bundle or does not contain the target resource [7]. In such cases, you can use.Page.Parent.Resources.GetMatch [7]. 4. Fallback Strategy: Because render hooks are applied globally to images or links, it is a common best practice to implement a fallback mechanism [5][3]. You can attempt to find the resource in the page bundle first, and if not found, fall back to global assets using the resources.Get function [5]. Example implementation pattern: {{ $r:=.Page.Resources.GetMatch.Destination }} {{ if not $r }} {{ $r = resources.Get.Destination }} {{ end }} {{ with $r }} <img src="{{.RelPermalink }}"...> {{ end }} This ensures your render hook gracefully handles both page-local resources and global assets [5].

Citations:


🌐 Web query:

Hugo image render hook markdown image syntax Resources.GetMatch relative to markdown page

💡 Result:

In Hugo, image render hooks use the .Page context to resolve resources. To resolve an image relative to the current Markdown page (typically a leaf bundle), you use the .Page.Resources.GetMatch method within your render-image.html hook [1][2]. Key considerations for implementation: 1. Context: Use .Page to access the page-level resources [1]. Inside a render hook, the .Destination variable contains the image URL provided in your Markdown [1][3]. 2. Resolution Strategy: Because Markdown image links are treated as destinations, they are not automatically resolved to page resources by default in the same way ref or relref work unless you use a render hook [1][4]. A robust implementation typically checks for the resource in the current page bundle first, and often falls back to the global assets directory [3]: {{ $destination:=.Destination }} {{ $image:=.Page.Resources.GetMatch $destination }} {{ if not $image }} {{ $image = resources.Get $destination }} {{ end }} {{ with $image }} {{ $.Text }} {{ else }} {{ $.Text }} {{ end }} 3. Pathing: Ensure your Markdown image syntax uses a path relative to the page bundle (e.g., ![alt](image.png) or ![alt](images/photo.jpg), not an absolute path starting with /) [5][6]. If you use a leading slash, Hugo may attempt to resolve the image from the root of the site, causing GetMatch to fail because it is scoped to the page bundle [6]. 4. Advanced Note: If you are using components or nested structures where content might be included (e.g., via RenderShortcodes), you may consider using .PageInner instead of .Page to ensure the context remains consistent with the file currently being rendered [1]. Always wrap your resource access in with or if statements to handle cases where the file cannot be found, preventing your build from failing with a nil pointer error [3][6].

Citations:


Use a leaf-bundle image path for the Page Bundling example.

The example puts hugo-logo.png in <your-module>/ but then has lesson-1.md reference it. Hugo resolves Markdown images relative to the Markdown page unless the image render hook specifically searches parent resources, so place the image in the referenced page’s bundle.

Proposed documentation fix
-    └── <your-module>/
-        ├── _index.md
-        └── hugo-logo.png
+    └── <your-module>/
+        └── lesson-1/
+            ├── index.md
+            └── hugo-logo.png

-2.  In your `lesson-1.md` file, reference the image using standard Markdown syntax:
+2.  In `lesson-1/index.md`, reference the image using standard Markdown syntax:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Enhance your course with images and other visual aids using the **Page Bundling** method, which keeps assets alongside the content that references them and ensures they resolve correctly for each organization.
**How to Add an Image**
1. Place your image file (e.g., `hugo-logo.png`) in your scoped static directory:
1. Place your image file directly in the same directory as your Markdown content:
```text
static/<your-organization-uid>/images/hugo-logo.png
```
2. In your `lesson-1.md` file, embed the image using the `usestatic` shortcode. The `path` is relative to your scoped static folder:
```text
content/learning-paths/<your-organization-uid>/
└── <your-course>/
└── <your-module>/
├── _index.md
└── hugo-logo.png
```
```text
![The Hugo Logo]({{</* usestatic path="images/hugo-logo.png" */>}})
```
2. In your `lesson-1.md` file, reference the image using standard Markdown syntax:
```markdown
![The Hugo Logo](hugo-logo.png)
```
Enhance your course with images and other visual aids using the **Page Bundling** method, which keeps assets alongside the content that references them and ensures they resolve correctly for each organization.
**How to Add an Image**
1. Place your image file directly in the same directory as your Markdown content:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 132 - 150, Update the Page Bundling example so
hugo-logo.png is placed in the same leaf bundle directory as lesson-1.md, and
show lesson-1.md alongside the image in the directory tree. Keep the existing
relative Markdown reference unchanged.


Then the system will automatically convert this into the correct URL when building the site.
> **Note:** The `usestatic` shortcode is **deprecated** and should not be used in new content. Use the Page Bundling method above.

**How to Add a Video**

```text
{{</* card
{{</* card
title="Video: Example" */>}}
<video width="100%" height="100%" controls>
<source src="https://exmaple.mp4" type="video/mp4">
<source src="https://example.com/your-video.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
{{</* /card */>}}
Expand All @@ -164,38 +171,41 @@ This project includes a `Makefile` with helper targets to simplify local develop
# Install necessary tools and modules
make setup

# Start the local Hugo development server
# Start the local Hugo development server with live reload
make site

# Build the site for local consumption
# Serve the site once with the file watcher off (no live reload)
make serve

# Build the site locally with draft and future content enabled
make build

# Build the preview site with configured base URL
# Build the site for a deploy preview (honors DEPLOY_PRIME_URL)
make build-preview

# Build production site output (CI)
# Build the site for production (pass BASE_URL=... to set the base URL)
make build-production

# Clean the Hugo cache and restart local setup
# Empty the build cache, reinstall dependencies, and run the site locally
make clean

# Check Markdown for linting issues
make lint

# Fix Markdown linting issues
make lint-fix

# Check internal links in the built site
make check-links

# Verify Go is installed before starting the local site
make check-go

# Update the academy-theme package version
make theme-update
Comment on lines 204 to 205

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove or implement the unavailable make theme-update command.

The Makefile states that this repository has no theme-update target. Its .PHONY list also omits that target. package.json defines theme:update, but that npm script does not create a Makefile target. Following this README command fails.

Remove these lines or document npm run theme:update instead.

Proposed documentation fix
-# Update the academy-theme package version
-make theme-update
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Update the academy-theme package version
make theme-update
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 204 - 205, Update the README instructions for
updating the academy-theme package by replacing the unavailable make
theme-update command with the supported npm run theme:update command, or remove
the instruction if no supported update workflow exists.

```

To preview your content locally, you can also run the Hugo server directly from the project root:

```bash
hugo server
```

This will start a local server. You can view your content and check for formatting issues before publishing.
Run `make site` to view your content and check for formatting issues before publishing.

> The local preview uses basic styling. Full Academy branding and styles will be applied after your content is integrated into the cloud platform.

Expand Down Expand Up @@ -262,5 +272,4 @@ Contributors are expected to follow the [CNCF Code of Conduct](https://github.co
[figma]: https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs
[figma-invite]: https://www.figma.com/team_invite/redeem/GvB8SudhEOoq3JOvoLaoMs
[forum]: https://discuss.layer5.io
[slack]: https://slack.layer5.io

[slack]: https://slack.layer5.io
Loading
Loading