Add a bunch more contrib info (#758)

* more contrib info

Signed-off-by: Pete Lumbis <pete@upbound.io>

* expand build and netlify things

Signed-off-by: Pete Lumbis <pete@upbound.io>

* Add lots of comments

Signed-off-by: Pete Lumbis <pete@upbound.io>

* add comments

Signed-off-by: Pete Lumbis <pete@upbound.io>

* +Algolia, DocSearch, NodeJS

Signed-off-by: Pete Lumbis <pete@upbound.io>

---------

Signed-off-by: Pete Lumbis <pete@upbound.io>
This commit is contained in:
Pete Lumbis 2024-04-19 10:00:09 -04:00 committed by GitHub
parent 3e9e10671c
commit bd0f99a77f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 531 additions and 109 deletions

View File

@ -2,13 +2,20 @@ baseURL: "/"
enableRobotsTXT: True enableRobotsTXT: True
languageCode: "en-us" languageCode: "en-us"
title: "Crossplane" title: "Crossplane"
# directory name in /themes
theme: "geekboot" theme: "geekboot"
# enable Lastmod parameter for each page. Placed in an HTML meta tag.
enableGitInfo: true enableGitInfo: true
uglyurls: false
# Crossplane docs don't use the Hugo taxonomy or term page kinds.
# Disabling provides a small build speedup
disableKinds: disableKinds:
- taxonomy - taxonomy
- term - term
# Enable RSS feeds for sections
outputs: outputs:
home: home:
- html - html
@ -18,28 +25,43 @@ outputs:
taxonomy: taxonomy:
term: term:
# Don't publish the README.md file in the /public folder
ignoreFiles: ignoreFiles:
- README.md - README.md
# build.writeStats is used to optimize CSS.
# the netlify_build.sh script uncomments this.
# The default comment means users don't need Hugo extended for authoring.
build: build:
# writeStats: true # writeStats: true
markup: markup:
goldmark: goldmark:
renderer: renderer:
# Allow mixing markdown and HTML. Required for Vale and some in-line
# styling.
# Okay to run `unsafe: true` since we review .md file inputs
# More info: https://gohugo.io/getting-started/configuration-markup/#rendererunsafe
unsafe: true unsafe: true
tableOfContents: tableOfContents:
# Which heading levels to include in the right-side table of contents
startLevel: 1 startLevel: 1
endLevel: 9 endLevel: 9
highlight: highlight:
# Enable syntax styling for code fence (```) blocks
codeFences: true codeFences: true
# Use classes instead of inline HTML styles for syntax decoration
noClasses: false noClasses: false
# Include line numbers to the left of a code fence box
linenos: true linenos: true
# Make the line numbers anchor links
anchorLineNos: true anchorLineNos: true
# Don't put the line numbers in tables and only use SPAN elements. For CSS styling.
lineNumbersInTable: false lineNumbersInTable: false
module: module:
# Mounts give Hugo access to images and YAML for compile-time processing.
mounts: mounts:
- source: content - source: content
target: content target: content
@ -57,30 +79,21 @@ module:
includeFiles: includeFiles:
- "**/api/**.yaml" - "**/api/**.yaml"
# Give Hugo access to environmental variables matching a given regex.
# These give Hugo access to Netlify data to generate proper URLs
security: security:
funcs: funcs:
getenv: getenv:
- ^CONTEXT - ^CONTEXT
- ^REVIEW_ID - ^REVIEW_ID
# Global parameters accessible by any Page
params: params:
# The current "latest" version. Used in the version dropdown
latest: "1.15" latest: "1.15"
upboundLink: "https://www.upbound.io/"
slackLink: "https://slack.crossplane.io/"
githubLink: "https://github.com/crossplane/crossplane"
twitterLink: "https://twitter.com/crossplane_io"
forumLink: "https://groups.google.com/forum/#!forum/crossplane-dev"
youtubeLink: "https://www.youtube.com/channel/UC19FgzMBMqBro361HbE46Fw"
podcastLink: "https://www.youtube.com/playlist?list=PL510POnNVaaYFuK-B_SIUrpIonCtLVOzT"
blogLink: "https://blog.crossplane.io/"
communityMeetingLink: "https://github.com/crossplane/crossplane/#get-involved"
cncfLink: "https://www.cncf.io/"
prodFormLink: "https://docs.google.com/forms/d/e/1FAIpQLSev-5clADSdkwi_wiFqBCAECeIoAQDE91chBbeWbvyTjRCeYg/viewform"
infoMailToLink: "mailto:info@crossplane.io"
upboundGithubLink: "https://github.com/upbound"
docs: true
repoLink: "https://github.com/crossplane/crossplane"
anchors: anchors:
# Generate heading anchors for any heading between min and max
min: 2 min: 2
max: 5 max: 5
# description for search engines.
description: "Crossplane lets you build a control plane with Kubernetes-style declarative and API-driven configuration and management for anything." description: "Crossplane lets you build a control plane with Kubernetes-style declarative and API-driven configuration and management for anything."

View File

@ -9,9 +9,9 @@ for source code used in documentation.
## Use fenced code blocks ## Use fenced code blocks
Use Markdown [fenced code Use Markdown
blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) with [fenced code blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks)
three backticks (` ``` `) for with three backticks (` ``` `) for
all command examples and outputs. all command examples and outputs.
````markdown ````markdown
@ -24,6 +24,10 @@ Only use a single backtick (`` ` ``) for commands used in a sentence.
For example, the command `kubectl apply` is inside a sentence. For example, the command `kubectl apply` is inside a sentence.
{{< hint "warning" >}}
Vale doesn't validate terms inside single backtick or fenced code blocks.
{{< /hint >}}
## Use language hints for proper highlighting ## Use language hints for proper highlighting
Hugo attempts to determine the language and apply proper styling, but it's Hugo attempts to determine the language and apply proper styling, but it's
not always optimized for readability. not always optimized for readability.

View File

@ -134,6 +134,23 @@ betaVersion: "1.11"
--- ---
``` ```
#### Descriptions
Hugo uses the `description` field to populate webpage metadata for search
engines.
```yaml
---
title: Compositions
weight: 30
aliases:
- composition
description: "Compositions are a template for creating Crossplane resources"
---
```
The description text isn't displayed anywhere in the docs.
### Headings ### Headings
Use standard markdown for headings (`#`). The top level heading, a single hash Use standard markdown for headings (`#`). The top level heading, a single hash
(`#`) is for the page title. All content headings should be two hashes (`##`) or (`#`) is for the page title. All content headings should be two hashes (`##`) or

View File

@ -4,11 +4,82 @@ weight: 600
description: "Learn how the docs and our tools are built" description: "Learn how the docs and our tools are built"
--- ---
The Crossplane document website is in a unique [website GitHub The Crossplane document website is in a standalone
repository](https://github.com/crossplane/docs). [GitHub repository](https://github.com/crossplane/docs) separate from Crossplane
core.
Crossplane uses [Hugo](https://gohugo.io/), a static site generator. Hugo The Crossplane docs tools consist of:
influences the directory structure of the website repository. * [Netlify](https://netlify.com/) - web hosting and DNS provided by the CNCF.
* [Hugo](https://gohugo.io/) - to compile markdown to static HTML.
* [Bootstrap](https://getbootstrap.com/docs/5.2/) - for pre-built CSS options.
* [PostCSS](https://postcss.org/) - for CSS optimization.
* [Webpack](https://webpack.js.org/) - for Javascript optimization.
## Netlify
Builds for production deploys and PR previews are automatically done by Netlify.
{{< hint "note" >}}
The CNCF controls Netlify access.
{{< /hint >}}
Settings for Netlify are inside
[`netlify.toml`](https://github.com/crossplane/docs/blob/master/netlify.toml).
Settings inside the `netlify.toml` file override any settings in the Netlify web
interface.
The
[`build`](https://github.com/crossplane/docs/blob/3e9e10671c32e368f5381d83e406e16bc38c93bc/netlify.toml#L1)
directive defines what Netlify does to build the site.
The
[`HUGO_VERSION`](https://github.com/crossplane/docs/blob/3e9e10671c32e368f5381d83e406e16bc38c93bc/netlify.toml#L7)
settings defines which version of Hugo Netlify uses.
The
[`redirects`](https://github.com/crossplane/docs/blob/3e9e10671c32e368f5381d83e406e16bc38c93bc/netlify.toml#L9)
are server side HTTP redirects for moved pages.
The [Netlify documentation](https://docs.netlify.com/configure-builds/file-based-configuration/)
has more information about configuring `netlify.toml`.
Netlify automatically detects the
[`package.json`](https://github.com/crossplane/docs/blob/master/package.json)
file and loads the listed NodeJS dependencies.
<!-- vale off -->
### netlify_build.sh
<!-- vale on -->
During a build Netlify runs the Bash script
[`netlify_build.sh`](https://github.com/crossplane/docs/blob/master/netlify_build.sh).
The script creates a new docs section called `latest` and copies the defined
`LATEST_VER` to `/latest`.
Next the script enables `writeStats` in the Hugo configuration file.
Then, using the Netlify `$CONTEXT`
[environmental variable](https://docs.netlify.com/configure-builds/environment-variables/#build-metadata)
Hugo runs, defining the [`BaseURL`](https://gohugo.io/methods/site/baseurl/) to
use for generating internal links.
## Hugo
Crossplane uses [Hugo](https://gohugo.io/), a static site generator.
Hugo combines HTML templates, markdown content and generates static HTML
content.
{{<hint "note" >}}
The Hugo web server is only used for local development. Crossplane documentation
uses Netlify for hosting.
Hugo only acts as an HTML compiler.
{{< /hint >}}
Hugo influences the directory structure of the repository.
The `/content` directory is the root directory for all documentation content. The `/content` directory is the root directory for all documentation content.
@ -17,23 +88,33 @@ files, like HTML templates, shortcodes and global media files.
The `/utils/` directory is for JavaScript source code and files unrelated to The `/utils/` directory is for JavaScript source code and files unrelated to
Hugo used in the website. Hugo used in the website.
<!-- vale Crossplane.Spelling = NO -->
The `/themes/geekboot/assets` folder contains all (S)CSS and compiled JavaScript <!-- vale Google.Headings = NO -->
for the website.
<!-- vale Crossplane.Spelling = YES -->
## CSS ## CSS
Crossplane documentation uses [Bootstrap <!-- vale Google.Headings = YES -->
5.2](https://getbootstrap.com/docs/5.2/getting-started/introduction/).
Unmodified Bootstrap SCSS files are in Crossplane documentation uses [Bootstrap 5.2](https://getbootstrap.com/docs/5.2/getting-started/introduction/).
`/themes/geekboot/assets/scss/bootstrap/`. Any docs-specific overrides are in
per-element SCSS files located one directory higher in Bootstrap provides multiple prebuilt styles and features making CSS easier.
`/themes/geekboot/assets/scss/`.
The docs import _all_ Bootstrap SCSS files and rely on Hugo and PostCSS to
optimize the compiled CSS file.
The unmodified Bootstrap SCSS files are in
`/themes/geekboot/assets/scss/bootstrap/`.
Any docs-specific overrides are in per-element SCSS files located one directory
higher in `/themes/geekboot/assets/scss/`.
{{<hint "important" >}} {{<hint "important" >}}
Don't edit the original Bootstrap stylesheets. It makes the ability to Don't edit the original Bootstrap stylesheets. It makes the ability to
upgrade to future Bootstrap versions difficult or impossible. upgrade to future Bootstrap versions difficult or impossible.
{{< /hint >}} {{< /hint >}}
The file `/themes/geekboot/assets/scss/docs.scss` defines all the stylesheets
Hugo loads and compiles. Add any new styles to the `docs.scss` file to include
them.
### Color themes ### Color themes
Crossplane docs support a light and dark color theme that's applied via CSS Crossplane docs support a light and dark color theme that's applied via CSS
variables. variables.
@ -46,108 +127,326 @@ Universal and default variables are defined in
Provide theme specific color overrides in Provide theme specific color overrides in
`/themes/geekboot/assets/scss/light-mode.scss` or `/themes/geekboot/assets/scss/light-mode.scss` or
`/themes/geekboot/assets/scss/light-mode.scss`. `/themes/geekboot/assets/scss/dark-mode.scss`.
{{<hint "note" >}} {{<hint "note" >}}
When creating new styles rely on variables for any color function, even if both When creating new styles, use variables for any colors, even if both
themes share the color. themes share the color.
{{< /hint >}} {{< /hint >}}
<!-- vale Google.Headings = NO -->
### SCSS compilation ### SCSS compilation
<!-- vale Google.Headings = YES -->
Hugo compiles the SCSS to CSS. Local development doesn't require SCSS installed. Hugo compiles the SCSS to CSS. Local development doesn't require SCSS installed.
For local development (when using `hugo server`) Hugo compiles SCSS without For local development (when using `hugo server`) Hugo compiles SCSS without
any optimizations. any optimizations.
For production (publishing on Netlify or using `hugo server In production, when publishing on Netlify or using
--environment production`) Hugo compiles SCSS and optimizes the CSS with `hugo server --environment production`, Hugo compiles SCSS and optimizes the
[PostCSS](https://postcss.org/). The PostCSS configuration is in CSS with [PostCSS](https://postcss.org/).
`/postcss.config.js`. The optimizations includes:
The PostCSS configuration is in `/postcss.config.js`.
The optimizations includes:
* [postcss-lightningcss](https://github.com/onigoetz/postcss-lightningcss) - for * [postcss-lightningcss](https://github.com/onigoetz/postcss-lightningcss) - for
building, minimizing and generating a source map. building, minimizing and generating a source map.
* [PurgeCSS](https://purgecss.com/plugins/postcss.html) - removes unused styles * [PurgeCSS](https://purgecss.com/plugins/postcss.html) - removes unused styles
to reduce the CSS file size. to reduce the CSS file size.
* [postcss-sort-media-queries](https://github.com/yunusga/postcss-sort-media-queries)- * [postcss-sort-media-queries](https://github.com/yunusga/postcss-sort-media-queries)-
to organize and reduce CSS media queries to remove duplicate and unused to organize the output CSS for another small performance boost.
CSS.
#### How optimization works
Crossplane runs a
[different Hugo CSS command](https://github.com/crossplane/docs/blob/3e9e10671c32e368f5381d83e406e16bc38c93bc/themes/geekboot/layouts/partials/stylesheet-dynamic.html#L4)
if it's in local development or production.
Hugo is in "production" when using `hugo` to only build HTML or with
`hugo server --environment production`.
{{<hint "important" >}}
Running Hugo in `production` mode requires the Hugo _extended_ version to
support PostCSS.
Standard Hugo fails to build the documentation.
{{< /hint >}}
<!-- vale Crossplane.Spelling = NO -->
<!-- unoptimized -->
PurgeCSS relies on a JSON file of every HTML tag and CSS class used across the
website and only preserves the matching CSS styles. The resulting file is around
20x smaller than unoptimized CSS.
<!-- vale Crossplane.Spelling = YES -->
Hugo generates the JSON file with the `buildStats` (or `writeStats`)
[configuration setting](https://gohugo.io/getting-started/configuration/#configure-build)
enabled.
{{<hint "important" >}}
Some tags or classes are dynamically created or not always enabled, like light
or dark mode.
Exclude these style sheets from CSS optimization with the
`purgecss start ignore` comment.
For example, the Crossplane documentation ignores the `color-modes` style sheet.
```css
/* purgecss start ignore */
@import "color-modes";
/* purgecss end ignore */
```
{{< /hint >}}
The Crossplane documentation only enables this flag during Netlify builds.
Manually update the `config.yaml` file to enable local optimization.
Optimizing CSS locally with PostCSS requires installing extra packages. Optimizing CSS locally with PostCSS requires installing extra packages.
* [Sass](https://sass-lang.com/install) * [Sass](https://sass-lang.com/install)
* [NPM](https://www.npmjs.com/) * [NPM](https://www.npmjs.com/)
* NPM packages defined in `/package.json` with `npm install`. * NPM packages defined in `/package.json` with `npm install`.
## JavaScript ## JavaScript
A goal of the documentation website is to use as little JavaScript as possible. Unless A goal of the documentation website is to use as little JavaScript as possible.
the script provides a significant improvement in performance, capability or user Unless the script provides a significant improvement in performance, capability
experience. or user experience.
To make local development there are no run-time dependencies for Local development has no run-time JavaScript dependencies. To prevent
JavaScript. dependencies, making JavaScript changes requires compiling and committing to git.
Runtime JavaScript is in `/themes/geekboot/assets/js/`. [Webpack](https://webpack.js.org/)
has bundled, minified and compressed the JavaScript.
The source JavaScript is in `/utils/webpack/src/js` and The source JavaScript is in `/utils/webpack/src/js` and
requires [Webpack](https://webpack.js.org/) to bundle and optimize the code. requires [Webpack](https://webpack.js.org/) to bundle and optimize the code.
* `colorMode.js` provides the ability to change the light and dark mode color theme. Webpack places the compiled JavaScript in `/themes/geekboot/assets/js/` and
* `tabDeepAnchor.js` rewrites anchor links inside tabs to open a tab and present updates `/themes/geekboot/data/assets.json` to tell Hugo the new compiled
the anchor. JavaScript filename.
{{< hint "important" >}}
The JavaScript source in `/utils/webpack/src`, newly compiled JavaScript in
`/themes/geekboot/assets/js` and updated `/themes/geekboot/data/assets.json`
must be in git for production and preview deploys to use the changed JavaScript.
{{< /hint >}}
### JavaScript files
* `bootstrap/` is the entire Bootstrap JavaScript library.
* `colorMode.js` provides the ability to change the light and dark mode color
theme.
* `customClipboard.js` supports the `copy-lines` code box function.
* `globalScripts.js` is the point of entry for Webpack to determine all * `globalScripts.js` is the point of entry for Webpack to determine all
dependencies. This bundles [instant.page](https://instant.page/) and dependencies. This bundles [instant.page](https://instant.page/) and
[Bootstrap's JavaScript](https://getbootstrap.com/docs/5.2/getting-started/javascript/). [Bootstrap's JavaScript](https://getbootstrap.com/docs/5.2/getting-started/javascript/).
* `hoverHighlight.js` provides dynamic "hover to highlight" function.
* `slackNotify.js` creates the "Join Crossplane Slack" bubble on the home page.
* `tabDeepAnchor.js` rewrites anchor links inside tabs to open a tab and present
the anchor.
### Bootstrap JavaScript builder The `globalScripts.js` file is the entry point for Webpack. Any JavaScript
The entire [Bootstrap JavaScript modules or scripts must be in `globalScripts.js` to get compiled.
source](https://github.com/twbs/bootstrap/tree/main/js/src) is in
`/utils/webpack/src/js/bootstrap`. #### Building JavaScript
Requirements:
* [NodeJS](https://nodejs.org/en/download) v20.1.2 or later.
* [NPM CLI](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
From the `/utils/webpack` director use `npm` to install the NodeJS dependencies.
```shell
cd utils/webpack
npm install
```
Building JavaScript has two options:
1. `npm run dev`
2. `npm run prod`
Using the `dev` argument doesn't optimize the JavaScript, simplifying
debugging.
Using the `prod` argument optimizes the JavaScript but makes debugging more
difficult.
{{<hint "important" >}}
Always use `npm run prod` to build the compiled JavaScript to use on the
Crossplane documentation site.
{{< /hint >}}
```shell
npm run prod
> prod
> webpack --mode=production
assets by status 80.9 KiB [cached] 1 asset
asset ../../data/assets.json 158 bytes [compared for emit]
orphan modules 180 KiB [orphan] 81 modules
runtime modules 670 bytes 3 modules
cacheable modules 223 KiB
modules by path ./src/js/*.js 186 KiB
./src/js/globalScripts.js + 81 modules 181 KiB [built] [code generated]
./src/js/colorMode.js 2.69 KiB [built] [code generated]
./src/js/tabDeepAnchor.js 2.31 KiB [built] [code generated]
modules by path ./node_modules/ 37.6 KiB
./node_modules/instant.page/instantpage.js 11.4 KiB [built] [code generated]
./node_modules/clipboard/dist/clipboard.js 26.2 KiB [built] [code generated]
webpack 5.89.0 compiled successfully in 1248 ms
```
## Search
[Algolia](https://www.algolia.com/) provides search functionality through their
[DocSearch](https://docsearch.algolia.com/) program.
{{< hint note >}}
Crossplane docs don't use the Netlify Algolia plugin and relies on the
[Algolia Crawler](https://www.algolia.com/doc/tools/crawler/getting-started/overview/) to
discover new content and changes.
{{< /hint >}}
## Sitemap and robots
Hugo generates the `robots.txt`
[automatically](https://gohugo.io/templates/robots/).
For search engine discovery Crossplane uses a `sitemap.xml` file generated from
the [`sitemap.xml` template](https://github.com/crossplane/docs/blob/master/themes/geekboot/layouts/_default/sitemap.xml).
## Link checking
Crossplane checks links with Hugo and
[`htmltest`](https://github.com/wjdp/htmltest).
Hugo builds fail for any broken links in a Hugo `ref` shortcode.
To catch markdown links `htmltest` crawls rendered HTML and validates all
internal links.
On Monday a
[GitHub Action](https://github.com/crossplane/docs/blob/master/.github/workflows/weekly-link-checker.yml)
runs to validate external links with `htmltest`.
The configuration for `htmltest` is in
[`/utils/htmlstest`](https://github.com/crossplane/docs/blob/master/utils/htmltest/.htmltest.yml).
Adding a new Bootstrap feature requires importing it in `globalScripts.js`.
By importing only the necessary Bootstrap JavaScript features, reduces the
bundle size.
## Annotated website tree ## Annotated website tree
Expand the tab below to see an annotated `tree` output of the website repository. Expand the tab below to see an annotated `tree` output of the website repository.
{{<expand >}} {{<expand >}}
```shell ```shell
tree . ├── config.yaml # Hugo configuration file
├── content # Root for all page content ├── content # Root for all page content
│   ├── contribute │   ├── contribute
│   ├── knowledge-base
│   ├── master │   ├── master
│   ├── v1.12 │   ├── media # Images used in docs pages
│   ├── v1.11 │   ├── v1.13
│   └── v1.10 │   ├── v1.14
├── themes # Entry point for theme-specific designs │   └── v1.15
│   └── geekboot ├── hugo_stats.json # Generated by Hugo writeStats for PurgeCSS
│   ├── assets # JS and stylesheets ├── netlify.toml # Netlify configuration
│   │   ├── js # Bundled and optmized Javascript ├── netlify_build.sh # Custom build script for Netlify
│   │   └── scss # Bootstrap SCSS overrides ├── package-lock.json # NodeJS dependency version lock
│   │   └── bootstrap # Bootstrap original SCSS files ├── package.json # NodeJS dependencies
│   ├── data ├── postcss.config.js # PostCSS configuration
│   ├── layouts # HTML layouts and shortcodes ├── static # Legacy docs site images
│   │   ├── _default # HTML layouts for page types ├── themes
│   │   │   └── _markup # Hugo render hooks │   └── geekboot # The Hugo theme used by Crossplane
│   │   ├── partials # HTML Template elements │   ├── LICENSE-bootstrap
│   │   │   ├── icons │   ├── LICENSE-geekdoc
│   │   │   └── utils │   ├── assets
│   │   └── shortcodes # Shortcode features │   │   ├── js # Compiled JavaScript
│   └── static # Static files across the theme. │   │   └── scss # Sytlesheets
│   ├── fonts # Font files │   │   └── bootstrap # Unmodified Bootstrap 5.2 SCSS
│   └── img # Global images │   ├── data # Hugo mapping for JavaScript files. Autogenerated.
└── utils # Files unrelated to Hugo │   ├── layouts # HTML template pages
└── vale # Files related to our Vale validation rules │   │   ├── 404.html # 404 page template
└── webpack # Files managed or related to webpack │   │   ├── _default
└── src │   │   │   ├── _markup/ # Templates for rendering specific style components
└── js │   │   │   ├── baseof.html # Entrypoint template for all pages
└── bootstrap/ # Original Bootstrap JavaScript │   │   │   ├── list.html # List type pages, see partials/single-list.html
└── colorMode.js # Color theme switcher │   │   │   ├── redirect.html # Provides HTML redirect functions
└── customClipboard.js # Defines where to put a clipboard icon and what to copy │   │   │   ├── section.rss.xml # RSS feed template
└── globalScripts.js # The collection of things to load on all pages │   │   │   ├── single.html # Single type pages, see partials/single-list.html
└── hoverHighlight.js # Enables hover to highlight │   │   │   └── sitemap.xml # Sitemap template
└── slackNotify.js # Tooltip to prompt user to join the community Slack │   │   ├── partials # Template includes
└── tabDeepAnchor.js # Enable anchors inside tabs │   │   │   ├── analytics.html # Analytics and trackers
│   │   │   ├── crds.html # Entrypoint for API documentation
│   │   │   ├── docs-navbar.html # Top header links
│   │   │   ├── docs-sidebar.html # left-side navigation menu
│   │   │   ├── favicons.html # Favicons
│   │   │   ├── feature-state-alert.html # Alert box for alpha/beta features
│   │   │   ├── footer.html # Footer copyright and links
│   │   │   ├── ga-tag.html # Google Analytics
│   │   │   ├── google-analytics.html # Notice for GA release version
│   │   │   ├── header.html # <head></head> content
│   │   │   ├── icons # Icons from fontawesome and Crossplane specific
│   │   │   ├── icons.html # SVG includes common enough to be on every page
│   │   │   ├── left-nav.html # Left-hand navigation
│   │   │   ├── master-version-alert.html # Alert box for the master version
│   │   │   ├── mermaid.html # Styling and JavaScript for mermaid diagrams
│   │   │   ├── meta-common.html # <meta> tags used on all pages
│   │   │   ├── ms-clarity.html # Microsoft Clarity tags
│   │   │   ├── old-version-alert.html # Alert box for versions that aren't the latest
│   │   │   ├── redirect.html # HTML meta redirect
│   │   │   ├── release-notes.html # Release note summary page generator
│   │   │   ├── rollworks.html # Rollworks analytics tags
│   │   │   ├── scripts.html # Global JavaScript includes
│   │   │   ├── search-button.html # Algolia search button
│   │   │   ├── sidebar # Static links in the left-side nav
│   │   │   ├── single-list.html # Template used by all single and list type pages
│   │   │   ├── skippy.html # Shift the page when the target is an anchor link
│   │   │   ├── social.html # Social media data includes
│   │   │   ├── stylesheet-cached.html # Static CSS that never changes
│   │   │   ├── stylesheet-dynamic.html # Dynamic CSS that may change between pages
│   │   │   ├── toc.html # Table of contents modifications
│   │   │   ├── utils # Utils imported from Geekdoc theme
│   │   │   └── version-dropdown-menu.html # Version dropdown menu
│   │   └── shortcodes
│   │   ├── check.html # Produce and style a Checkmark
│   │   ├── editCode.html # Code box with editable field
│   │   ├── expand.html # Expand button
│   │   ├── getCRDs.html # Generate API pages
│   │   ├── hint.html # Hint boxes
│   │   ├── hover.html # Hover to highlight
│   │   ├── img.html # Image optimizer
│   │   ├── include.html # Include an external file
│   │   ├── markdown.html # Run content through the markdown engine again
│   │   ├── param.html # Import from Bootstrap theme
│   │   ├── partial.html # Import from Bootstrap theme
│   │   ├── placeholder.html # Import from Bootstrap theme
│   │   ├── propertylist.html # Import from Bootstrap theme
│   │   ├── tab.html # Individual Tab. Related to tabs.html
│   │   ├── table.html # Apply bootstrap styles to markdown tables
│   │   ├── tabs.html # Tab builder, related to tab.html
│   │   ├── url.html # Create a download link to a file. Used by the APIs
│   │   └── year.html # Print the current year
│   └── static # Static global image files
└── utils # Scripts and tools related to the docs
├── htmltest # htmltest link checker
├── vale # Vale linter
│   └── styles
│   ├── Crossplane # Crossplane spelling exceptions
│   ├── Google # Google's Vale rules
│   ├── Microsoft # Microsoft's Vale rules
│   ├── alex # Write inclusive language
│   ├── gitlab # Gitlab's Vale rules
│   ├── proselint # Write better
│   └── write-good # Write better
└── webpack # JavaScript tools
├── package-lock.json # NodeJS dependency version lock
├── package.json # NodeJS dependencies
├── src
│   └── js
│   ├── bootstrap/ # Unmodified Bootstrap JavaScript
│   ├── colorMode.js # Color mode switcher
│   ├── customClipboard.js # Custom copy-to-clipboard tool
│   ├── globalScripts.js # Point of entry for all scripts compiled by Webpack
│   ├── hoverHighlight.js # Hover to highlight
│   ├── slackNotify.js # "Join Crossplane Slack" bubble
│   └── tabDeepAnchor.js # Link inside a tab
└── webpack.config.js
``` ```
{{</expand>}} {{</expand>}}

View File

@ -52,8 +52,7 @@ Crossplane uses the following Vale styles:
* [Google](https://github.com/errata-ai/google) - for the [Google developer documentation style guide](https://developers.google.com/style). * [Google](https://github.com/errata-ai/google) - for the [Google developer documentation style guide](https://developers.google.com/style).
* [Microsoft](https://github.com/errata-ai/Microsoft) - for the [Microsoft style guide](https://learn.microsoft.com/en-us/style-guide/welcome/). * [Microsoft](https://github.com/errata-ai/Microsoft) - for the [Microsoft style guide](https://learn.microsoft.com/en-us/style-guide/welcome/).
* [proselint](https://github.com/errata-ai/proselint) - for higher quality writing. * [proselint](https://github.com/errata-ai/proselint) - for higher quality writing.
* [Upbound](https://github.com/upbound/vale/tree/main/styles/Upbound) - for * [Crossplane](https://github.com/crossplane/docs/tree/master/utils/vale/styles/Crossplane) - spelling exceptions for Kubernetes and Crossplane related words.
customized terms and preventing corporate jargon.
* [write-good](https://github.com/errata-ai/write-good) - for higher quality writing. * [write-good](https://github.com/errata-ai/write-good) - for higher quality writing.
{{<hint "warning" >}} {{<hint "warning" >}}
@ -120,7 +119,7 @@ Vale back on.
For example, For example,
```text ```plaintext
<!-- vale off --> <!-- vale off -->
<!-- turn off vale checking for this example --> <!-- turn off vale checking for this example -->
The following example will use passive voice and lowercase crossplane. Do not do this. The following example will use passive voice and lowercase crossplane. Do not do this.
@ -138,7 +137,7 @@ Do not turn off rules without good reasons.
<!-- vale Microsoft.Contractions = YES --> <!-- vale Microsoft.Contractions = YES -->
For example, For example,
```text ```plaintext
<!-- vale Microsoft.Contractions = NO --> <!-- vale Microsoft.Contractions = NO -->
<!-- turn off contractions for the example --> <!-- turn off contractions for the example -->
Do not turn off rules without good reasons. Do not turn off rules without good reasons.
@ -149,3 +148,20 @@ Do not turn off rules without good reasons.
Vale requires capitalization for `YES` and `NO` and a space around `=`. Vale requires capitalization for `YES` and `NO` and a space around `=`.
{{</hint >}} {{</hint >}}
## Vale settings
The Vale configuration for the repository is in
[utils/vale/vale.ini](https://github.com/crossplane/docs/blob/master/utils/vale/.vale.ini).
{{< hint "note" >}}
The `vale.ini` file is a Vale configuration file. Read the Vale documentation
for more information about the `vale.ini` file.
{{< /hint >}}
Some imported Vale styles don't apply or duplicate other rules. Disable
individual rules inside the `vale.ini` file.
For example Google and Microsoft rules both cover the use of first person words
like `I`. The docs `vale.ini` disables the
[Microsoft rule](https://github.com/crossplane/docs/blob/3e9e10671c32e368f5381d83e406e16bc38c93bc/utils/vale/.vale.ini#L42)
to prevent duplicate errors.

View File

@ -1,11 +1,27 @@
# Read the Netlify docs for details:
# https://docs.netlify.com/configure-builds/file-based-configuration/
#
#
# Build commands. Logic for previews vs prod are handled inside netlify_build.sh
[context.deploy-preview]
command = "bash netlify_build.sh"
[context.production]
command = "bash netlify_build.sh"
[build] [build]
base = "/" base = "/"
publish = "public/" publish = "public/"
command = "bash netlify_build.sh" command = "bash netlify_build.sh"
# The version of Hugo to use for the Netlify build.
[build.environment] [build.environment]
HUGO_VERSION = "0.119.0" HUGO_VERSION = "0.119.0"
#
# The following are Netlify redirects for moved docs pages
# https://docs.netlify.com/configure-builds/file-based-configuration/#redirects
#
[[redirects]] [[redirects]]
from = "/docs/*" from = "/docs/*"
to = "/:splat" to = "/:splat"
@ -17,7 +33,6 @@ from = "/v1.12/*"
to = "/latest/:splat" to = "/latest/:splat"
status = 302 status = 302
# Redirects for EOL versions
[[redirects]] [[redirects]]
from = "/v1.11/*" from = "/v1.11/*"
to = "/latest/:splat" to = "/latest/:splat"
@ -55,12 +70,6 @@ from = "/knowledge-base/install/**"
to = "/latest/software/" to = "/latest/software/"
status = 302 status = 302
[context.deploy-preview]
command = "bash netlify_build.sh"
[context.production]
command = "bash netlify_build.sh"
# Use [dev] to set configuration overrides for local # Use [dev] to set configuration overrides for local
# development environments run using Netlify Dev - except # development environments run using Netlify Dev - except
# for environment variables. Environment variables for Netlify # for environment variables. Environment variables for Netlify

View File

@ -1,16 +1,30 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Which which version is the "Latest"?
LATEST_VER="1.15" LATEST_VER="1.15"
# Make a copy of /content/$LATEST_VER to the directory /latest
# Search indexing only points to /latest, this prevents broken or out of date
# search results
cp -R content/v$LATEST_VER content/latest cp -R content/v$LATEST_VER content/latest
# Set the `version` front matter to prevent redirect issues with the version
# drop-down menu.
sed -i "s/^\s*version: \"$LATEST_VER\"//g" content/latest/_index.md sed -i "s/^\s*version: \"$LATEST_VER\"//g" content/latest/_index.md
# Enable Hugo writeStats to enable PurgeCSS optimizations.
# docs: https://gohugo.io/getting-started/configuration/#configure-build
sed -i 's/# writeStats: true/writeStats: true/g' config.yaml sed -i 's/# writeStats: true/writeStats: true/g' config.yaml
cat config.yaml cat config.yaml
# $CONTEXT is a Netlify environmental variable.
# https://docs.netlify.com/configure-builds/environment-variables/#build-metadata
# For production set the baseURL to be the docs URL
if [ "$CONTEXT" = "production" ]; then if [ "$CONTEXT" = "production" ]; then
hugo --minify --baseURL https://docs.crossplane.io/ hugo --minify --baseURL https://docs.crossplane.io/
# For any other context use the Netlify deploy URL.
elif [ "$CONTEXT" = "branch-deploy" ]; then elif [ "$CONTEXT" = "branch-deploy" ]; then
echo "Building branch deploy with URL $DEPLOY_PRIME_URL" echo "Building branch deploy with URL $DEPLOY_PRIME_URL"
hugo --minify --baseURL $DEPLOY_PRIME_URL hugo --minify --baseURL $DEPLOY_PRIME_URL

View File

@ -1,9 +1,17 @@
// LightningCSS settings
// https://lightningcss.dev/
//
// Support browsers with at least 0.25% usage from broswerlist: https://browserslist.dev/?q=bGFzdCAyIHZlcnNpb25z
const postcssLightningcss = require("postcss-lightningcss")({ const postcssLightningcss = require("postcss-lightningcss")({
browsers: ">= .25%", browsers: ">= .25%",
lightningcssOptions: { lightningcssOptions: {
} }
}); });
// PurgeCSS settings
// https://purgecss.com/
//
// Load hugo_stats.json to know what elements are in use
const purgecss = require('@fullhuman/postcss-purgecss')({ const purgecss = require('@fullhuman/postcss-purgecss')({
content: ['./hugo_stats.json'], content: ['./hugo_stats.json'],
variables: true, variables: true,
@ -18,6 +26,10 @@ const purgecss = require('@fullhuman/postcss-purgecss')({
safelist: [] safelist: []
}); });
// PostCSS Media sort
// https://github.com/yunusga/postcss-sort-media-queries
//
// Sort CSS to prioritize desktop users
const mediasort = require('postcss-sort-media-queries')({ const mediasort = require('postcss-sort-media-queries')({
sort: 'desktop-first' sort: 'desktop-first'
}); });

View File

@ -1,8 +1,10 @@
Algolia
Bootstrap Bootstrap
CC-BY CC-BY
CNCF CNCF
Commonmark Commonmark
DockerHub DockerHub
DocSearch
Geekdocs Geekdocs
Goldmark Goldmark
Grammarly Grammarly
@ -11,6 +13,7 @@ HashiCorp
instant.page instant.page
Kustomize Kustomize
Netlify Netlify
NodeJS
NPM NPM
OpenAPI OpenAPI
OpenAPIv3 OpenAPIv3

View File

@ -4,6 +4,12 @@
* Licensed under MIT (https://github.com/coliff/dark-mode-switch/blob/main/LICENSE) * Licensed under MIT (https://github.com/coliff/dark-mode-switch/blob/main/LICENSE)
*/ */
/*
*
* Controls the dark mode/light mode switcher and saves a cookie to remember the
* user preference.
*/
(() => { (() => {
var darkSwitch = document.getElementById("darkSwitch"); var darkSwitch = document.getElementById("darkSwitch");

View File

@ -1,6 +1,11 @@
// Customize clipboard.js // Customize clipboard.js
import * as ClipboardJS from 'clipboard'; import * as ClipboardJS from 'clipboard';
/*
* Extends clipboard.js to support passing line numbers to copy instead of a
* whole code box.
*/
// copy API links to the clipboard // copy API links to the clipboard
const crdURLCopier = new ClipboardJS('.kind-link'); const crdURLCopier = new ClipboardJS('.kind-link');

View File

@ -1,8 +1,14 @@
// The collection of things to load on all pages // The collection of things to load on all pages
// Color mode switcher
import ColorMode from './colorMode'; import ColorMode from './colorMode';
// Link pre-fetcher
// https://instant.page/
import 'instant.page'; import 'instant.page';
// Bootstrap JS libraries in use.
// IF a new Bootstrap feature requires JS, add it here.
import './bootstrap/src/base-component'; import './bootstrap/src/base-component';
import './bootstrap/src/button'; import './bootstrap/src/button';
import './bootstrap/src/collapse'; import './bootstrap/src/collapse';
@ -12,7 +18,14 @@ import './bootstrap/src/scrollspy';
import './bootstrap/src/tab'; import './bootstrap/src/tab';
import './bootstrap/src/offcanvas'; import './bootstrap/src/offcanvas';
// If a link is to an anchor inside a tab, open the tab and go to the anchor
import './tabDeepAnchor.js'; import './tabDeepAnchor.js';
// Customize the clipboard to support the `copy-lines` function
import './customClipboard.js'; import './customClipboard.js';
// Hover to highlight function
import './hoverHighlight.js'; import './hoverHighlight.js';
// "Join Slack" notification bubble
import './slackNotify.js'; import './slackNotify.js';

View File

@ -1,3 +1,10 @@
/*
* Create the hover to highlight function.
*
* Finds the code box matching the label and updates the code box to add a
* highlight function.
*/
export function getKeywords(){ export function getKeywords(){
var keywordList = document.getElementsByTagName("highlight-term") var keywordList = document.getElementsByTagName("highlight-term")

View File

@ -1,3 +1,7 @@
/*
* Create a PopperJS popover for the Join Slack notifications.
*/
import { createPopper } from '@popperjs/core'; import { createPopper } from '@popperjs/core';
const slackIcon = document.querySelector('#slack'); const slackIcon = document.querySelector('#slack');