diff --git a/assets/icons/ansible.svg b/assets/icons/ansible.svg
new file mode 100644
index 00000000..afc3718d
--- /dev/null
+++ b/assets/icons/ansible.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/assets/js/fetch-repo.js b/assets/js/fetch-repo.js
index 61bedfd0..0ea2bf67 100644
--- a/assets/js/fetch-repo.js
+++ b/assets/js/fetch-repo.js
@@ -12,6 +12,14 @@
}
const platforms = {
+ "ansible-role": {
+ "results.0.download_count": "downloads",
+ "results.0.summary_fields.versions.0.name": "version",
+ },
+ "ansible-collection": {
+ download_count: "downloads",
+ "highest_version.version": "version",
+ },
github: {
full_name: "full_name",
description: "description",
@@ -49,12 +57,27 @@
},
};
+ const formatThousands = (value) =>
+ value == null ? value : Number(value).toLocaleString("en-US");
+
const processors = {
huggingface: {
description: (value) => value?.replace(/Dataset Card for .+?\s+Dataset Summary\s+/, "").trim() || value,
},
+ "ansible-role": {
+ "results.0.download_count": formatThousands,
+ },
+ "ansible-collection": {
+ download_count: formatThousands,
+ },
};
+ const getNested = (obj, path) =>
+ path.split(".").reduce((acc, key) => {
+ if (acc == null) return undefined;
+ return Array.isArray(acc) ? acc[Number(key)] : acc[key];
+ }, obj);
+
const platform = Object.keys(platforms).find((p) => repoId.startsWith(p)) || "github";
const mapping = platforms[platform];
@@ -77,7 +100,7 @@
Object.entries(mapping).forEach(([dataField, elementSuffix]) => {
const element = document.getElementById(`${repoId}-${elementSuffix}`);
if (element) {
- let value = data[dataField];
+ let value = getNested(data, dataField);
if (processors[platform]?.[dataField]) {
value = processors[platform][dataField](value);
}
diff --git a/exampleSite/content/docs/shortcodes/index.md b/exampleSite/content/docs/shortcodes/index.md
index 707deb26..af0a381e 100644
--- a/exampleSite/content/docs/shortcodes/index.md
+++ b/exampleSite/content/docs/shortcodes/index.md
@@ -187,6 +187,37 @@ The alert sign (`+` or `-`) is optional to control whether the admonition is fol
+## Ansible Galaxy Card
+
+`ansible` renders a card for an [Ansible Galaxy](https://galaxy.ansible.com/) entry, fetched at build time. It accepts either a `role` or a `collection` parameter, both in `namespace.name` form.
+
+
+| Parameter | Description |
+| ------------ | ------------------------------------------------------------------------------------ |
+| `role` | [String] Galaxy role in the format `namespace.name`, e.g. `geerlingguy.docker` |
+| `collection` | [String] Galaxy collection in the format `namespace.name`, e.g. `community.general` |
+
+
+Set exactly one of `role` or `collection` per call.
+
+**Example 1: Role**
+
+```md
+{{* ansible role="geerlingguy.docker" */>}}
+```
+
+{{< ansible role="geerlingguy.docker" >}}
+
+**Example 2: Collection**
+
+```md
+{{* ansible collection="community.general" */>}}
+```
+
+{{< ansible collection="community.general" >}}
+
+
+
## Article
`Article` will embed a single article into a markdown file. The `link` to the file should be the `.RelPermalink` of the file to be embedded. Note that the shortcode will not display anything if it's referencing it's parent. _Note: if you are running your website in a subfolder like Blowfish (i.e. /blowfish/) please include that path in the link._
diff --git a/layouts/shortcodes/ansible.html b/layouts/shortcodes/ansible.html
new file mode 100644
index 00000000..99c5306a
--- /dev/null
+++ b/layouts/shortcodes/ansible.html
@@ -0,0 +1,174 @@
+{{- $role := .Get "role" -}}
+{{- $collection := .Get "collection" -}}
+{{- $apiURL := "" -}}
+{{- $repoLink := "" -}}
+{{- $type := "" -}}
+{{- $namespace := "" -}}
+{{- $name := "" -}}
+
+{{- if $role -}}
+ {{- $parts := split $role "." -}}
+ {{- $namespace = index $parts 0 -}}
+ {{- $name = index $parts 1 -}}
+ {{- $apiURL = print "https://galaxy.ansible.com/api/v1/roles/?owner__username=" $namespace "&name=" $name -}}
+ {{- $repoLink = print "https://galaxy.ansible.com/ui/standalone/roles/" $namespace "/" $name "/" -}}
+ {{- $type = "role" -}}
+{{- else if $collection -}}
+ {{- $parts := split $collection "." -}}
+ {{- $namespace = index $parts 0 -}}
+ {{- $name = index $parts 1 -}}
+ {{- $apiURL = print "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/index/" $namespace "/" $name "/" -}}
+ {{- $repoLink = print "https://galaxy.ansible.com/ui/repo/published/" $namespace "/" $name "/" -}}
+ {{- $type = "collection" -}}
+{{- end -}}
+
+{{ $id := delimit (slice "ansible" $type (partial "functions/uid.html" .)) "-" }}
+
+{{- $title := "" -}}
+{{- $description := "" -}}
+{{- $downloads := 0 -}}
+{{- $version := "" -}}
+{{- $tags := slice -}}
+{{- $license := "" -}}
+{{- $dataAvailable := false -}}
+
+{{- /* Formats an integer with comma thousand separators (lang.NumFmt is unavailable in this template context). */ -}}
+{{- define "_format-int" -}}
+ {{- $n := printf "%d" (int .) -}}
+ {{- $out := "" -}}
+ {{- $len := len $n -}}
+ {{- range $i := seq $len -}}
+ {{- $idx := sub $i 1 -}}
+ {{- $c := substr $n $idx 1 -}}
+ {{- if and (gt $idx 0) (eq (mod (sub $len $idx) 3) 0) -}}
+ {{- $out = print $out "," $c -}}
+ {{- else -}}
+ {{- $out = print $out $c -}}
+ {{- end -}}
+ {{- end -}}
+ {{- $out -}}
+{{- end -}}
+
+{{- with try (resources.GetRemote $apiURL) -}}
+ {{- with .Err -}}
+ {{- warnf "ansible shortcode: failed to fetch remote resource from %q: %s" $apiURL $.Position -}}
+ {{- else with .Value -}}
+ {{- $resp := . | transform.Unmarshal -}}
+ {{- if eq $type "role" -}}
+ {{- with index ($resp.results | default slice) 0 -}}
+ {{- $title = print $namespace "." .name -}}
+ {{- $description = .description -}}
+ {{- $downloads = .download_count -}}
+ {{- with .summary_fields -}}
+ {{- with index (.versions | default slice) 0 -}}
+ {{- $version = .name -}}
+ {{- end -}}
+ {{- $tags = .tags -}}
+ {{- end -}}
+ {{- $dataAvailable = true -}}
+ {{- end -}}
+ {{- else if eq $type "collection" -}}
+ {{- $title = print $namespace "." $name -}}
+ {{- $downloads = $resp.download_count -}}
+ {{- with $resp.highest_version -}}
+ {{- $version = .version -}}
+ {{- end -}}
+ {{- if $version -}}
+ {{- $versionURL := print $apiURL "versions/" $version "/" -}}
+ {{- with try (resources.GetRemote $versionURL) -}}
+ {{- with .Value -}}
+ {{- $verResp := . | transform.Unmarshal -}}
+ {{- with $verResp.metadata -}}
+ {{- $description = .description -}}
+ {{- $tags = .tags -}}
+ {{- with .license -}}
+ {{- $license = index . 0 -}}
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+ {{- $dataAvailable = true -}}
+ {{- end -}}
+ {{- else -}}
+ {{- warnf "ansible shortcode: unable to get remote resource from %q: %s" $apiURL $.Position -}}
+ {{- end -}}
+{{- end -}}
+
+{{- if $dataAvailable -}}
+