diff --git a/layouts/partials/schema/collectors/comparison-table-entity.html b/layouts/partials/schema/collectors/comparison-table-entity.html new file mode 100644 index 000000000000..366b87fbfa72 --- /dev/null +++ b/layouts/partials/schema/collectors/comparison-table-entity.html @@ -0,0 +1,86 @@ +{{/* Returns ItemList entity for comparison tables found on /comparisons/ pages */}} + +{{ $entity := dict }} + +{{ if and (strings.Contains .RelPermalink "/comparisons/") (strings.Contains .RawContent "| Feature |") }} + + {{/* Extract from "| Feature |" onward, then truncate to just the first table block + so later tables on the page (e.g., Crossplane's "When to Choose") don't pollute the ItemList */}} + {{ $afterHeader := replaceRE `(?s)^.*?\| Feature \|` "| Feature |" .RawContent }} + {{ $firstTable := index (split $afterHeader "\n\n") 0 }} + + {{/* Extract all table lines */}} + {{ $allTableLines := findRE `(?m)^\|.+\|` $firstTable }} + + {{ if ge (len $allTableLines) 3 }} + + {{/* Extract column names from the table header row (always in correct column order) */}} + {{ $headerCells := split (index $allTableLines 0) "|" }} + {{ $productName := index $headerCells 2 | strings.TrimSpace }} + {{ $competitorName := index $headerCells 3 | strings.TrimSpace }} + + {{ if $competitorName }} + + {{ $dataLines := $allTableLines | after 2 }} + + {{/* Use Scratch to accumulate rows inside range */}} + {{ $.Scratch.Set "compRows" slice }} + + {{ range $dataLines }} + {{ $line := . | strings.TrimSpace }} + {{ if not (findRE `^\|[\s\-:|]+\|$` $line) }} + {{ $cells := split $line "|" }} + {{ if ge (len $cells) 4 }} + {{ $feature := index $cells 1 | strings.TrimSpace }} + {{ $feature = replaceRE `\[([^\]]+)\]\([^)]+\)` "$1" $feature }} + {{ $feature = replaceRE `\*+([^*]+)\*+` "$1" $feature }} + {{ $val1 := index $cells 2 | strings.TrimSpace }} + {{ $val2 := index $cells 3 | strings.TrimSpace }} + {{ $val1 = replaceRE `<[^>]+>` " " $val1 }} + {{ $val2 = replaceRE `<[^>]+>` " " $val2 }} + {{ $val1 = replaceRE `\[([^\]]+)\]\([^)]+\)` "$1" $val1 }} + {{ $val2 = replaceRE `\[([^\]]+)\]\([^)]+\)` "$1" $val2 }} + {{ $val1 = replaceRE `\*+([^*]+)\*+` "$1" $val1 }} + {{ $val2 = replaceRE `\*+([^*]+)\*+` "$1" $val2 }} + {{ $existing := $.Scratch.Get "compRows" }} + {{ $.Scratch.Set "compRows" ($existing | append (dict "feature" $feature "product" $val1 "competitor" $val2)) }} + {{ end }} + {{ end }} + {{ end }} + + {{ $rows := $.Scratch.Get "compRows" }} + {{ $.Scratch.Delete "compRows" }} + + {{ if len $rows }} + + {{/* Build ItemList with ListItem entries */}} + {{ $.Scratch.Set "compItems" slice }} + {{ range $i, $row := $rows }} + {{ $position := add $i 1 }} + {{ $existing := $.Scratch.Get "compItems" }} + {{ $.Scratch.Set "compItems" ($existing | append (dict + "@type" "ListItem" + "position" $position + "name" $row.feature + "description" (printf "%s: %s | %s: %s" $productName $row.product $competitorName $row.competitor) + )) }} + {{ end }} + + {{ $items := $.Scratch.Get "compItems" }} + {{ $.Scratch.Delete "compItems" }} + + {{ $entity = dict + "@type" "ItemList" + "@id" "#comparison-table" + "name" (printf "%s vs. %s Feature Comparison" $productName $competitorName) + "description" (printf "Side-by-side feature comparison of %s and %s for infrastructure as code" $productName $competitorName) + "numberOfItems" (len $items) + "itemListElement" $items + }} + + {{ end }} + {{ end }} + {{ end }} +{{ end }} + +{{ return $entity }} diff --git a/layouts/partials/schema/graph-builder.html b/layouts/partials/schema/graph-builder.html index 2cbcd3731065..7225dc6d9e14 100644 --- a/layouts/partials/schema/graph-builder.html +++ b/layouts/partials/schema/graph-builder.html @@ -29,6 +29,15 @@ {{ $webpage = merge $webpage (dict "mainEntity" (dict "@id" "#main-content")) }} {{ end }} +{{/* Collect comparison table schema before finalizing WebPage so hasPart can be wired */}} +{{ $comparisonTable := dict }} +{{ if not .IsHome }} + {{ $comparisonTable = partial "schema/collectors/comparison-table-entity.html" . }} + {{ if and $comparisonTable (ne $comparisonTable (dict)) }} + {{ $webpage = merge $webpage (dict "hasPart" (dict "@id" "#comparison-table")) }} + {{ end }} +{{ end }} + {{/* Add WebPage to graph */}} {{ $graph = $graph | append $webpage }} @@ -171,6 +180,11 @@ {{ $graph = $graph | append $software }} {{ end }} +{{/* Add comparison table to graph (collected earlier to wire hasPart into WebPage) */}} +{{ if and $comparisonTable (ne $comparisonTable (dict)) }} + {{ $graph = $graph | append $comparisonTable }} +{{ end }} + {{/* Add video schema if page contains YouTube videos */}} {{ if not .IsHome }} {{ $videoEntity := partial "schema/collectors/video-entity.html" . }}