Skip to content

Commit d92af90

Browse files
HeyItsGilbertclaude
andcommitted
feat(modules): add /modules/ section with reusable Module landing pages
Introduce a hybrid layout for the open-source modules PowerShell.org stewards: a generic, front-matter-driven `module` layout for new modules, with the Hugo `layout:` key as an escape hatch so flagship modules can stay bespoke (Plaster). - Add /modules/ section index (card grid over pages) and move Plaster under it at /modules/plaster/ with an alias from /plaster/ (bespoke layout unchanged). - Add PSDepend as the first generic Module, authored from its README/glossary, with its real logo imported to static/images/modules/. - Add a reusable `terminal` shortcode for Plaster-style code blocks (Prism highlighting) plus a .ps-terminal CSS reset so .prose pre doesn't fight it. - Make the top-nav dropdown generic via a childMenu param; Modules becomes a dropdown like Community, listing each module. - Add a `modules` archetype (bakes in the load-bearing `layout:` key), CONTEXT.md glossary entry for "Module", and ADR-0001 recording the decision. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T5qXD5Xg7YL1gpyhSN3WS1
1 parent 4484d83 commit d92af90

13 files changed

Lines changed: 387 additions & 6 deletions

File tree

CONTEXT.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# PowerShell.org Website
2+
3+
The community website for PowerShell.org, built with Hugo and Tailwind CSS. Hosts
4+
podcasts, summit info, learning articles, community resources, and dedicated landing
5+
pages for the open-source Modules that PowerShell.org stewards.
6+
7+
## Language
8+
9+
**Module**:
10+
A PowerShell module that PowerShell.org stewards as an open-source project (e.g.
11+
Plaster, PSDepend), given a dedicated landing page under `/modules/`. Capitalized
12+
and used as a site section, "Module" means specifically these org-stewarded projects
13+
— not the generic sense of "any PowerShell module you `Install-Module`", which is the
14+
subject of the site as a whole.
15+
_Avoid (for this concept)_: project, tool, package

archetypes/modules.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: '{{ replace .File.ContentBaseName "-" " " | title }}'
3+
description: ""
4+
layout: "module"
5+
icon: "fas fa-cube"
6+
weight: 50
7+
repo: ""
8+
gallery: ""
9+
docs: ""
10+
install:
11+
- label: "PowerShell 7+"
12+
command: ""
13+
- label: "PowerShell 5.1"
14+
command: ""
15+
features:
16+
- icon: "fas fa-star"
17+
title: ""
18+
body: ""
19+
cmdlets:
20+
- name: ""
21+
description: ""
22+
draft: true
23+
---

content/modules/_index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: "Modules"
3+
description: "Open-source PowerShell modules stewarded by the PowerShell.org community."
4+
---
5+
6+
Tools built and maintained by the PowerShell.org community. Install them from the
7+
PowerShell Gallery and dig into the source on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@
22
title: "Plaster"
33
description: "The template engine for PowerShell. Scaffold projects, modules, and files with customizable templates in XML or JSON."
44
layout: "plaster"
5+
icon: "fas fa-layer-group"
6+
weight: 10
7+
aliases:
8+
- "/plaster/"
59
---

content/modules/psdepend/_index.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
title: "PSDepend"
3+
description: "A PowerShell dependency handler. Declare your dependencies in a .psd1 file and let Invoke-PSDepend resolve, install, import, and test them."
4+
layout: "module"
5+
icon: "fas fa-sitemap"
6+
logo: "/images/modules/psdepend.svg"
7+
weight: 20
8+
repo: "https://github.com/PowerShellOrg/PSDepend"
9+
gallery: "https://www.powershellgallery.com/packages/PSDepend"
10+
docs: "https://github.com/PowerShellOrg/PSDepend/blob/main/docs/en-US/about_PSDepend.help.md"
11+
install:
12+
- label: "PowerShell 7+"
13+
command: "Install-PSResource PSDepend"
14+
- label: "PowerShell 5.1"
15+
command: "Install-Module PSDepend"
16+
features:
17+
- icon: "fas fa-file-code"
18+
title: "Declarative DependencyFiles"
19+
body: "Declare every Dependency in a simple .psd1 file. Invoke-PSDepend finds your *.depend.psd1 and requirements.psd1 files automatically — think pip install -r or bundle install for PowerShell."
20+
- icon: "fas fa-plug"
21+
title: "Pluggable DependencyTypes"
22+
body: "Each Dependency picks a DependencyType — PSGalleryModule, Git, Chocolatey, FileDownload and more — that selects the DependencyScript handling it. Register your own to extend PSDepend."
23+
- icon: "fas fa-list-check"
24+
title: "Install, Test, or Import"
25+
body: "Run a DependencyFile with any combination of the Install, Test, and Import PSDependActions — verify an environment in CI, or hydrate one from scratch."
26+
- icon: "fas fa-tags"
27+
title: "Tag-based selection"
28+
body: "Tag your Dependencies and pass -Tags to Invoke-PSDepend to resolve just the subset you need for a given task or pipeline stage."
29+
- icon: "fas fa-diagram-project"
30+
title: "Ordered Prerequisites"
31+
body: "Express ordering constraints between Dependencies with DependsOn. PSDepend resolves them into topological order before anything is installed."
32+
- icon: "fas fa-bullseye"
33+
title: "Flexible Target"
34+
body: "Send a Dependency to a scope (CurrentUser, AllUsers) or any filesystem path via Target. The DependencyScript branches on whichever you give it."
35+
cmdlets:
36+
- name: "Invoke-PSDepend"
37+
description: "The main entry point. Resolves a DependencyFile and installs, tests, and/or imports its Dependencies."
38+
- name: "Get-Dependency"
39+
description: "Parse a DependencyFile into typed Dependency objects without acting on them — handy for inspection and debugging."
40+
- name: "Get-PSDependType"
41+
description: "List the registered DependencyTypes and the DependencyScript each one maps to."
42+
- name: "Get-PSDependScript"
43+
description: "Resolve the DependencyScript that will handle a given DependencyType."
44+
- name: "Install-Dependency"
45+
description: "Run only the Install PSDependAction for a Dependency."
46+
- name: "Test-Dependency"
47+
description: "Run only the Test PSDependAction to check whether a Dependency is already satisfied."
48+
---
49+
50+
## Declare your dependencies
51+
52+
Store your Dependencies in a PowerShell data file named `*.depend.psd1` or
53+
`requirements.psd1`. The simplest form maps a module name to a version:
54+
55+
{{< terminal title="requirements.psd1" lang="powershell" >}}
56+
@{
57+
psake = 'latest'
58+
Pester = 'latest'
59+
BuildHelpers = '0.0.20'
60+
PSDeploy = '0.1.21'
61+
}
62+
{{< /terminal >}}
63+
64+
Then resolve everything in one call:
65+
66+
{{< terminal title="PowerShell" lang="powershell" >}}
67+
Import-Module PSDepend
68+
Invoke-PSDepend -Path .\requirements.psd1
69+
{{< /terminal >}}
70+
71+
Need more control? Expand any entry into a full Dependency to set its
72+
`DependencyType`, `Target`, `Tags`, or `DependsOn` ordering — and add a
73+
`PSDependOptions` block to apply defaults across the whole DependencyFile.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Module landing pages: hybrid layout under a `/modules/` section
2+
3+
We host dedicated landing pages for the open-source PowerShell modules PowerShell.org
4+
stewards (see [[Module]] in `CONTEXT.md`). Plaster's page is a hand-authored, ~430-line
5+
bespoke Hugo layout. To add more modules (PSDepend first) without copy-pasting that per
6+
module, we adopt a **hybrid**: a generic, front-matter-driven `module` layout is the
7+
default for new modules, and the standard Hugo `layout:` key is an escape hatch so a
8+
flagship module can keep a bespoke page (Plaster stays on `_default/plaster.html`).
9+
10+
The modules live under a `/modules/` section with a card-grid index (built by
11+
`layouts/modules/list.html` ranging over the child pages, mirroring the existing
12+
`community` list). A single "Modules" item replaces "Plaster" in the main nav. Plaster
13+
moves from `/plaster/` to `/modules/plaster/` with `aliases: ["/plaster/"]` to preserve
14+
the published URL.
15+
16+
## Considered options
17+
18+
- **Bespoke per module** — rejected: ~430 lines of duplicated, drifting HTML per module.
19+
- **Generic only** (convert Plaster too) — rejected: loses Plaster's bespoke showcase
20+
(ASCII hero, JSON-vs-XML comparison) for a lowest-common-denominator template.
21+
- **Hybrid** — chosen: cheap to add modules, expressive where it earns its keep.
22+
23+
We named the section **"Module"** despite the collision with PowerShell's generic sense
24+
of the word; `CONTEXT.md` carries the disambiguation.
25+
26+
## Consequences
27+
28+
- Every module page **must** set `layout:` (`module` or a bespoke name). Module pages are
29+
branch bundles under `modules/`, so without an explicit layout they would fall through
30+
to the section's `list.html`. The `modules` archetype bakes the layout key in.
31+
- Cmdlet references on generic pages are a curated 3–6 command highlight in front matter,
32+
not an ingestion of each module's platyPS docs — avoids cross-repo build coupling.

hugo.yaml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ menu:
4848
weight: 50
4949
params:
5050
hasChildren: true
51-
- name: "Plaster"
52-
url: "/plaster/"
51+
childMenu: community
52+
- name: "Modules"
53+
url: "/modules/"
5354
weight: 60
55+
params:
56+
hasChildren: true
57+
childMenu: modules
5458
community:
5559
- name: "Learning"
5660
url: "/learning/"
@@ -83,6 +87,19 @@ menu:
8387
params:
8488
icon: "fab fa-discord"
8589
description: "Searchable archive of conversations from our Discord server."
90+
modules:
91+
- name: "Plaster"
92+
url: "/modules/plaster/"
93+
weight: 10
94+
params:
95+
icon: "fas fa-layer-group"
96+
description: "The template engine for PowerShell — scaffold projects, modules, and files."
97+
- name: "PSDepend"
98+
url: "/modules/psdepend/"
99+
weight: 20
100+
params:
101+
icon: "fas fa-sitemap"
102+
description: "Declarative PowerShell dependency handler driven by a .psd1 file."
86103

87104
# Site parameters
88105
params:

static/images/modules/psdepend.svg

Lines changed: 1 addition & 0 deletions
Loading

themes/powershell-community/layouts/_default/baseof.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@
8080
font-family: 'Cascadia Code', 'Consolas', monospace;
8181
}
8282

83+
/* Neutralize .prose pre styling inside the terminal shortcode so the
84+
terminal chrome renders flush; Prism handles token colors. */
85+
.ps-terminal pre { background: transparent; color: #ccc; margin: 0; border-radius: 0; padding: 1.25rem; overflow-x: auto; }
86+
8387
.hero-pattern {
8488
background: linear-gradient(135deg, #0078D4 0%, #00BCF2 100%);
8589
position: relative;
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{{ define "main" }}
2+
3+
<!-- Hero Section -->
4+
<section class="hero-pattern py-20 lg:py-28 relative overflow-hidden">
5+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
6+
<div class="text-center text-white animate-fade-in">
7+
{{ with .Params.logo }}
8+
<div class="mb-6 flex justify-center">
9+
<span class="inline-flex items-center justify-center w-24 h-24 bg-white rounded-2xl shadow-lg p-4">
10+
<img src="{{ . }}" alt="{{ $.Title }} logo" class="w-full h-full object-contain">
11+
</span>
12+
</div>
13+
{{ else }}{{ with .Params.icon }}
14+
<div class="mb-6">
15+
<i class="{{ . }} text-5xl lg:text-6xl opacity-90"></i>
16+
</div>
17+
{{ end }}{{ end }}
18+
<h1 class="text-4xl lg:text-6xl gotham-black mb-6">{{ .Title }}</h1>
19+
{{ with .Params.description }}
20+
<p class="text-xl lg:text-2xl opacity-90 max-w-3xl mx-auto mb-10 gotham-medium">{{ . }}</p>
21+
{{ end }}
22+
<div class="flex flex-col sm:flex-row gap-4 justify-center">
23+
{{ with .Params.repo }}
24+
<a href="{{ . }}" target="_blank" rel="noopener"
25+
class="inline-flex items-center bg-white text-blue-700 px-8 py-4 rounded-lg font-bold text-lg hover:bg-gray-100 transition-all duration-200 shadow-lg hover:shadow-xl">
26+
<i class="fab fa-github mr-3"></i>View Source
27+
</a>
28+
{{ end }}
29+
{{ if .Params.install }}
30+
<a href="#install"
31+
class="inline-flex items-center bg-transparent border-2 border-white text-white px-8 py-4 rounded-lg font-bold text-lg hover:bg-white hover:bg-opacity-10 transition-all duration-200">
32+
<i class="fas fa-download mr-3"></i>Install
33+
</a>
34+
{{ end }}
35+
</div>
36+
</div>
37+
</div>
38+
</section>
39+
40+
<!-- Install Banner -->
41+
{{ with .Params.install }}
42+
<section id="install" class="powershell-dark py-12">
43+
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 space-y-4">
44+
{{ range . }}
45+
<div class="code-terminal rounded-lg p-6">
46+
<div class="flex items-center mb-3">
47+
<div class="flex space-x-2 mr-4">
48+
<div class="w-3 h-3 rounded-full bg-red-500"></div>
49+
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
50+
<div class="w-3 h-3 rounded-full bg-green-500"></div>
51+
</div>
52+
<span class="text-gray-400 text-sm font-mono">{{ with .label }}{{ . }}{{ else }}PowerShell{{ end }}</span>
53+
</div>
54+
<code class="text-green-400 font-mono text-lg">{{ .command }}</code>
55+
</div>
56+
{{ end }}
57+
</div>
58+
</section>
59+
{{ end }}
60+
61+
<!-- Feature Cards -->
62+
{{ with .Params.features }}
63+
<section class="py-20 bg-white">
64+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
65+
<div class="grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
66+
{{ range . }}
67+
<div class="bg-gray-50 rounded-xl p-8 border border-gray-200 hover:border-blue-400 hover:shadow-lg transition-all duration-300">
68+
<div class="w-14 h-14 bg-blue-100 rounded-xl flex items-center justify-center mb-6">
69+
<i class="{{ with .icon }}{{ . }}{{ else }}fas fa-star{{ end }} text-2xl text-blue-600"></i>
70+
</div>
71+
<h3 class="text-xl font-bold text-gray-900 mb-3">{{ .title }}</h3>
72+
<p class="text-gray-600 leading-relaxed">{{ .body }}</p>
73+
</div>
74+
{{ end }}
75+
</div>
76+
</div>
77+
</section>
78+
{{ end }}
79+
80+
<!-- Free-form body content -->
81+
{{ with .Content }}
82+
<section class="py-16 bg-gray-50">
83+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
84+
<div class="prose prose-lg max-w-4xl mx-auto">{{ . }}</div>
85+
</div>
86+
</section>
87+
{{ end }}
88+
89+
<!-- Cmdlet Reference -->
90+
{{ with .Params.cmdlets }}
91+
<section class="py-20 bg-white">
92+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
93+
<div class="text-center mb-16">
94+
<h2 class="text-3xl lg:text-4xl gotham-bold text-gray-900 mb-4">Commands</h2>
95+
<p class="text-xl text-gray-600 max-w-2xl mx-auto">The commands you'll reach for most.</p>
96+
</div>
97+
<div class="grid gap-6 sm:grid-cols-2">
98+
{{ range . }}
99+
<div class="bg-gray-50 rounded-xl p-8 border border-gray-200 hover:border-blue-400 hover:shadow-md transition-all duration-200">
100+
<div class="flex items-center mb-4">
101+
<code class="text-lg font-bold text-blue-700 font-mono">{{ .name }}</code>
102+
</div>
103+
<p class="text-gray-600">{{ .description }}</p>
104+
</div>
105+
{{ end }}
106+
</div>
107+
</div>
108+
</section>
109+
{{ end }}
110+
111+
<!-- CTA Section -->
112+
<section class="powershell-blue py-20">
113+
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center text-white">
114+
<h2 class="text-3xl lg:text-4xl gotham-bold mb-6">Get started with {{ .Title }}</h2>
115+
<div class="flex flex-col sm:flex-row gap-4 justify-center">
116+
{{ with .Params.gallery }}
117+
<a href="{{ . }}" target="_blank" rel="noopener"
118+
class="inline-flex items-center bg-white text-blue-700 px-8 py-4 rounded-lg font-bold text-lg hover:bg-gray-100 transition-all duration-200 shadow-lg">
119+
<i class="fas fa-box-open mr-3"></i>PowerShell Gallery
120+
</a>
121+
{{ end }}
122+
{{ with .Params.repo }}
123+
<a href="{{ . }}" target="_blank" rel="noopener"
124+
class="inline-flex items-center bg-transparent border-2 border-white text-white px-8 py-4 rounded-lg font-bold text-lg hover:bg-white hover:bg-opacity-10 transition-all duration-200">
125+
<i class="fab fa-github mr-3"></i>View Source
126+
</a>
127+
{{ end }}
128+
{{ with .Params.docs }}
129+
<a href="{{ . }}" target="_blank" rel="noopener"
130+
class="inline-flex items-center bg-transparent border-2 border-white text-white px-8 py-4 rounded-lg font-bold text-lg hover:bg-white hover:bg-opacity-10 transition-all duration-200">
131+
<i class="fas fa-book mr-3"></i>Documentation
132+
</a>
133+
{{ end }}
134+
</div>
135+
</div>
136+
</section>
137+
138+
{{ end }}

0 commit comments

Comments
 (0)