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
4 changes: 4 additions & 0 deletions content/stats/content-inventory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: "Content Inventory Emitter"
layout: "content_inventory"
---
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,77 @@
- _default/term.html
*/}}

<ads-card link="{{.learning_path.Permalink}}" class='path-card{{ if .is_pinned }} featured-path-card{{ end }}'>
{{- $lpAuthors := .learning_path.Params.author -}}
{{- if not (reflect.IsSlice $lpAuthors) -}}
{{- if $lpAuthors -}}
{{- $lpAuthors = slice $lpAuthors -}}
{{- else -}}
{{- $lpAuthors = slice -}}
{{- end -}}
{{- end -}}

{{- $lpSubjects := .learning_path.Params.subjects -}}
{{- if not (reflect.IsSlice $lpSubjects) -}}
{{- if $lpSubjects -}}
{{- $lpSubjects = slice $lpSubjects -}}
{{- else -}}
{{- $lpSubjects = slice -}}
{{- end -}}
{{- end -}}

{{- $lpArmIps := .learning_path.Params.armips -}}
{{- if not (reflect.IsSlice $lpArmIps) -}}
{{- if $lpArmIps -}}
{{- $lpArmIps = slice $lpArmIps -}}
{{- else -}}
{{- $lpArmIps = slice -}}
{{- end -}}
{{- end -}}

{{- $lpOs := .learning_path.Params.operatingsystems -}}
{{- if not (reflect.IsSlice $lpOs) -}}
{{- if $lpOs -}}
{{- $lpOs = slice $lpOs -}}
{{- else -}}
{{- $lpOs = slice -}}
{{- end -}}
{{- end -}}

{{- $lpTools := .learning_path.Params.tools_software_languages -}}
{{- if not (reflect.IsSlice $lpTools) -}}
{{- if $lpTools -}}
{{- $lpTools = slice $lpTools -}}
{{- else -}}
{{- $lpTools = slice -}}
{{- end -}}
{{- end -}}

{{- $lpSteps := slice -}}
{{- range .learning_path.Site.Pages.ByWeight -}}
{{- if and .File (eq .File.Dir $.learning_path.File.Dir) (ne .Params.hide_from_navpane true) -}}
{{- $lpSteps = $lpSteps | append (dict
"full-url" (.RelPermalink | absURL)
"weight" .Weight
"step-title" .Title
) -}}
{{- end -}}
{{- end -}}

<ads-card
link="{{.learning_path.Permalink}}"
class='path-card{{ if .is_pinned }} featured-path-card{{ end }}'
data-lp-url="{{ .learning_path.RelPermalink | absURL }}"
data-lp-title="{{ .learning_path.Title }}"
data-lp-steps="{{ $lpSteps | jsonify }}"
data-lp-author="{{ delimit $lpAuthors ", " }}"
data-lp-skill-level="{{ .learning_path.Params.skillLevels }}"
data-lp-subjects="{{ delimit $lpSubjects ", " }}"
data-lp-arm-ip="{{ delimit $lpArmIps ", " }}"
data-lp-os="{{ delimit $lpOs ", " }}"
data-lp-tools-software-languages="{{ delimit $lpTools ", " }}"
data-lp-content-category="{{ .learning_path.Parent.Title }}"
data-lp-minutes-to-complete="{{ .learning_path.Params.minutes_to_complete }}"
data-lp-last-updated-date="{{ .calculated_date.Format "02-Jan-06" }}">
<ads-card-content slot="content">
{{ if .is_pinned }}
<div class="pinned-header-row">
Expand Down
1 change: 1 addition & 0 deletions themes/arm-design-system-hugo-theme/layouts/robots.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
User-agent: *
Disallow:
Disallow: /stats/content-inventory/

# Explicitly welcome AI crawlers
User-agent: GPTBot
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
{{ define "main" }}
{{/*
Dedicated Adobe Analytics inventory emitter.
This page is intended for scheduled automation, not regular user traffic.
*/}}

{{/* Build LP step-level rows */}}
{{ $lpRows := slice }}
{{ range where .Site.Pages "Section" "learning-paths" }}
{{ $lpPage := . }}
{{ if and $lpPage.File (eq $lpPage.File.TranslationBaseName "_index") }}
{{ $authors := $lpPage.Params.author }}
{{ if not (reflect.IsSlice $authors) }}
{{ if $authors }}
{{ $authors = slice $authors }}
{{ else }}
{{ $authors = slice }}
{{ end }}
{{ end }}

{{ $subjects := $lpPage.Params.subjects }}
{{ if not (reflect.IsSlice $subjects) }}
{{ if $subjects }}
{{ $subjects = slice $subjects }}
{{ else }}
{{ $subjects = slice }}
{{ end }}
{{ end }}

{{ $armIps := $lpPage.Params.armips }}
{{ if not (reflect.IsSlice $armIps) }}
{{ if $armIps }}
{{ $armIps = slice $armIps }}
{{ else }}
{{ $armIps = slice }}
{{ end }}
{{ end }}

{{ $operatingSystems := $lpPage.Params.operatingsystems }}
{{ if not (reflect.IsSlice $operatingSystems) }}
{{ if $operatingSystems }}
{{ $operatingSystems = slice $operatingSystems }}
{{ else }}
{{ $operatingSystems = slice }}
{{ end }}
{{ end }}

{{ $tools := $lpPage.Params.tools_software_languages }}
{{ if not (reflect.IsSlice $tools) }}
{{ if $tools }}
{{ $tools = slice $tools }}
{{ else }}
{{ $tools = slice }}
{{ end }}
{{ end }}

{{ $lastUpdated := partial "server-side-processing/calculate-last-update.html" $lpPage }}
{{ $category := $lpPage.Parent.Title }}

{{ range $lpPage.Site.Pages.ByWeight }}
{{ $step := . }}
{{ if and $step.File (eq $step.File.Dir $lpPage.File.Dir) (ne $step.Params.hide_from_navpane true) }}
{{ $lpRows = $lpRows | append (dict
"full-url" ($step.RelPermalink | absURL)
"learning-path-title" $lpPage.Title
"weight" $step.Weight
"step-title" $step.Title
"author" (delimit $authors ", ")
"skill-level" $lpPage.Params.skillLevels
"subjects" (delimit $subjects ", ")
"arm-ip" (delimit $armIps ", ")
"os" (delimit $operatingSystems ", ")
"tools-software-languages" (delimit $tools ", ")
"content-category" $category
"minutes-to-complete" $lpPage.Params.minutes_to_complete
"last-updated-date" ($lastUpdated.Format "2-Jan-06")
) }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}

{{/* Build Install Guide rows */}}
{{ $installGuideRows := slice }}
{{ range where .Site.Pages "Section" "install-guides" }}
{{ $igStep := . }}
{{ if and $igStep.File (ne $igStep.RelPermalink "/install-guides/") }}
{{ $igRoot := $igStep }}
{{ if and $igStep.Parent $igStep.Parent.File (eq $igStep.Parent.File.TranslationBaseName "_index") }}
{{ $igRoot = $igStep.Parent }}
{{ end }}

{{ $igAuthors := $igRoot.Params.author }}
{{ if not (reflect.IsSlice $igAuthors) }}
{{ if $igAuthors }}
{{ $igAuthors = slice $igAuthors }}
{{ else }}
{{ $igAuthors = slice }}
{{ end }}
{{ end }}

{{ $igOperatingSystems := $igRoot.Params.operatingsystems }}
{{ if not (reflect.IsSlice $igOperatingSystems) }}
{{ if $igOperatingSystems }}
{{ $igOperatingSystems = slice $igOperatingSystems }}
{{ else }}
{{ $igOperatingSystems = slice }}
{{ end }}
{{ end }}

{{ $igTools := $igRoot.Params.tools_software_languages }}
{{ if not (reflect.IsSlice $igTools) }}
{{ if $igTools }}
{{ $igTools = slice $igTools }}
{{ else }}
{{ $igTools = slice }}
{{ end }}
{{ end }}

{{ $installGuideRows = $installGuideRows | append (dict
"full-url" ($igStep.RelPermalink | absURL)
"install-guide-title" $igRoot.Title
"weight" $igStep.Weight
"step-title" $igStep.Title
"author" (delimit $igAuthors ", ")
"os" (delimit $igOperatingSystems ", ")
"tools-software-languages" (delimit $igTools ", ")
"content-category" "Install Guides"
"minutes-to-complete" $igRoot.Params.minutes_to_complete
"last-updated-date" ($igStep.Lastmod.UTC.Format "2-Jan-06")
) }}
{{ end }}
{{ end }}

<main id="main">
<div class="content-box">
<h2>Content Inventory Emitter</h2>
<p>This page supports anonymous analytics reporting so our teams can prioritize the content developers care about most.</p>
<p>It emits Adobe Analytics inventory events only when query param <code>aa_inventory=1</code> is present.</p>
<p>Example: <code>/stats/content-inventory/?aa_inventory=1</code></p>
<p>Learning Path rows: {{ len $lpRows }} | Install Guide rows: {{ len $installGuideRows }}</p>
</div>
</main>

<script id="inventory-lp-rows" type="application/json">{{ $lpRows | jsonify }}</script>
<script id="inventory-install-guide-rows" type="application/json">{{ $installGuideRows | jsonify }}</script>

<script>
(function () {
var params = new URLSearchParams(window.location.search);
if (params.get("aa_inventory") !== "1") {
return;
}

if (!window._satellite || typeof window._satellite.track !== "function") {
console.warn("Adobe _satellite is unavailable. Inventory events were not sent.");
return;
}

function parseRows(id) {
var el = document.getElementById(id);
if (!el || !el.textContent) return [];
try {
var parsed = JSON.parse(el.textContent);
if (typeof parsed === "string") return JSON.parse(parsed);
return Array.isArray(parsed) ? parsed : [];
} catch (error) {
console.warn("Failed to parse inventory rows for", id, error);
return [];
}
}

var lpRows = parseRows("inventory-lp-rows");
var installGuideRows = parseRows("inventory-install-guide-rows");

_satellite.track("content-inventory-summary", {
"inventory-type": "all",
"inventory-run-date": new Date().toISOString(),
"learning-path-row-count": lpRows.length,
"install-guide-row-count": installGuideRows.length,
"total-row-count": lpRows.length + installGuideRows.length
});

for (var i = 0; i < lpRows.length; i++) {
_satellite.track("learning-path-row-metadata", lpRows[i]);
}

for (var j = 0; j < installGuideRows.length; j++) {
_satellite.track("install-guide-row-metadata", installGuideRows[j]);
}
})();
</script>
{{ end }}
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,66 @@ function trackHeaderInteraction(type,name){
});
}

function trackLearningPathListMetadata() {
let learning_path_cards = document.querySelectorAll('.path-card:not(.global-nav-path-card)');
if (!learning_path_cards || learning_path_cards.length === 0) {
return;
}

let total_step_rows = 0;
for (let card of learning_path_cards) {
let steps_payload = card.getAttribute('data-lp-steps') || '[]';
try {
let steps = JSON.parse(steps_payload);
total_step_rows += Array.isArray(steps) ? steps.length : 0;
} catch (error) {
// Ignore malformed payload; fallback row is emitted below.
}
}

_satellite.track('learning-path-list-metadata', {
'lp-list-category': window.location.pathname.split('/')[2] || '',
'lp-list-count': learning_path_cards.length,
'lp-step-row-count': total_step_rows
});

for (let card of learning_path_cards) {
let steps = [];
try {
steps = JSON.parse(card.getAttribute('data-lp-steps') || '[]');
} catch (error) {
steps = [];
}

// Fallback for safety if step extraction fails.
if (!Array.isArray(steps) || steps.length === 0) {
steps = [{
'full-url': card.getAttribute('data-lp-url') || '',
'weight': '',
'step-title': card.getAttribute('data-lp-title') || ''
}];
}

for (let step of steps) {
_satellite.track('learning-path-row-metadata', {
'full-url': step['full-url'] || card.getAttribute('data-lp-url') || '',
'learning-path-title': card.getAttribute('data-lp-title') || '',
'weight': step['weight'] || '',
'step-title': step['step-title'] || '',
'author': card.getAttribute('data-lp-author') || '',
'skill-level': card.getAttribute('data-lp-skill-level') || '',
'subjects': card.getAttribute('data-lp-subjects') || '',
'arm-ip': card.getAttribute('data-lp-arm-ip') || '',
'os': card.getAttribute('data-lp-os') || '',
'tools-software-languages': card.getAttribute('data-lp-tools-software-languages') || '',
'content-category': card.getAttribute('data-lp-content-category') || '',
'minutes-to-complete': card.getAttribute('data-lp-minutes-to-complete') || '',
'last-updated-date': card.getAttribute('data-lp-last-updated-date') || ''
});
}
}
}


function doneTyping(search_str) {
//console.log('send',search_str);
Expand Down
3 changes: 3 additions & 0 deletions tools/maintenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ def main():
elif "/migration" in os.path.abspath(args.instructions):
logging.info("Migration paths are not supported for maintenance tests yet.")
exit(0)
elif "/stats" in os.path.abspath(args.instructions):
logging.info("Stats paths are not supported for maintenance tests.")
exit(0)
else:
logging.error("-i/--instructions expects a .md file, a CSV with a list of files or a Learning Path directory")
if results_dict is not None:
Expand Down
Loading