{{/* Hugo Blox: Generic Preact Block Wrapper */}} {{/* Single wrapper for all Preact-based blocks */}} {{/* Documentation: https://hugoblox.com/blocks/ */}} {{/* License: https://github.com/HugoBlox/kit/blob/main/LICENSE.md */}} {{/* Initialize variables */}} {{ $page := .wcPage }} {{ $block := .wcBlock }} {{ $block_type := .wcBlockType }} {{ $block_id := .wcIdentifier | default (printf "%s-%d" $block_type (now.Unix)) }} {{/* Prepare props for the Preact component */}} {{ $props := dict "content" $block.content "design" $block.design "id" $block_id "type" $block_type }} {{/* Resolve icon for primary_action (hero, cta blocks) */}} {{ with $block.content.primary_action.icon }} {{ $icon_data := partial "functions/get_icon_data" (dict "name" .) }} {{ if $icon_data }} {{ $props = merge $props (dict "icon_svg" $icon_data) }} {{ end }} {{ end }} {{/* Resolve icon for secondary_action (hero) */}} {{ with $block.content.secondary_action.icon }} {{ $icon_data := partial "functions/get_icon_data" (dict "name" .) }} {{ if $icon_data }} {{ $props = merge $props (dict "secondary_icon_svg" $icon_data) }} {{ end }} {{ end }} {{/* Resolve hero media (single image, optional dark variant). Videos pass through unprocessed. */}} {{ with $block.content.media }} {{ if or (not .type) (eq .type "image") }} {{ with .src }} {{ $img_data := partial "functions/process_image_for_props" (dict "path" . "Page" $page) }} {{ with $img_data.src }} {{ $props = merge $props (dict "media_image" $img_data) }} {{ end }} {{ end }} {{ with .dark_src }} {{ $img_data := partial "functions/process_image_for_props" (dict "path" . "Page" $page) }} {{ with $img_data.src }} {{ $props = merge $props (dict "media_image_dark" $img_data) }} {{ end }} {{ end }} {{ end }} {{ end }} {{/* Resolve icon for single button (cta-card) */}} {{ with $block.content.button.icon }} {{ $icon_data := partial "functions/get_icon_data" (dict "name" .) }} {{ if $icon_data }} {{ $props = merge $props (dict "button_icon_svg" $icon_data) }} {{ end }} {{ end }} {{/* Resolve per-item icons (stats, features, etc.) into an icon_svgs map */}} {{ $icon_svgs := dict }} {{ with $block.content.items }} {{ range . }} {{ with .icon }} {{ if not (index $icon_svgs .) }} {{ $icon_data := partial "functions/get_icon_data" (dict "name" .) }} {{ if $icon_data }} {{ $icon_svgs = merge $icon_svgs (dict . $icon_data) }} {{ end }} {{ end }} {{ end }} {{ end }} {{ end }} {{ if gt (len $icon_svgs) 0 }} {{ $props = merge $props (dict "icon_svgs" $icon_svgs) }} {{ end }} {{/* Resolve per-item images via Hugo's image pipeline */}} {{/* Thumbnail mode (testimonials): Fill 96x96 webp */}} {{/* Responsive mode (cta-image-paragraph): srcset with breakpoints */}} {{ $item_images := dict }} {{ with $block.content.items }} {{ range $idx, $item := . }} {{ with .image }} {{ $image_path := strings.TrimSpace (printf "%v" .) }} {{ $is_remote := or (strings.HasPrefix $image_path "http://") (strings.HasPrefix $image_path "https://") }} {{/* Resolve the image resource */}} {{ $image_resource := false }} {{ $fallback_url := "" }} {{ if $is_remote }} {{ $remote := try (resources.GetRemote $image_path) }} {{ if and $remote (not $remote.Err) }} {{ $image_resource = $remote.Value }} {{ else }} {{ $fallback_url = $image_path }} {{ end }} {{ else }} {{ $normalized := $image_path }} {{ $normalized = strings.TrimPrefix "/" $normalized }} {{ $normalized = strings.TrimPrefix "./" $normalized }} {{ $normalized = strings.TrimPrefix "assets/" $normalized }} {{ $normalized = strings.TrimPrefix "media/" $normalized }} {{ $normalized = path.Clean $normalized }} {{ if and $normalized (ne $normalized ".") }} {{ with $page }} {{ $image_resource = (.Resources.ByType "image").GetMatch $normalized }} {{ end }} {{ if not $image_resource }} {{ $image_resource = resources.Get (path.Join "media" $normalized) }} {{ end }} {{ if not $image_resource }} {{ $fallback_url = printf "/media/%s" $normalized }} {{ end }} {{ end }} {{ end }} {{ $img_data := dict }} {{ if $image_resource }} {{/* Image processing gate: - reflect.IsImageResourceProcessable → false for SVG (not processable by Hugo). - GIF: processable by Hugo but we skip to preserve animation frames. */}} {{ $canProcess := and (reflect.IsImageResourceProcessable $image_resource) (ne $image_resource.MediaType.SubType "gif") }} {{ if not $canProcess }} {{/* SVG or GIF: no processing, just pass through */}} {{ $img_data = dict "src" $image_resource.RelPermalink }} {{ else if eq $block_type "cta-image-paragraph" }} {{/* Responsive mode: generate srcset via process_responsive_image */}} {{ $responsive := partial "functions/process_responsive_image.html" (dict "image" $image_resource "mode" "fit" "sizes" (slice 400 600 800 1200) ) }} {{ $img_data = dict "srcset" $responsive.srcset "src" $responsive.fallback.RelPermalink "width" $responsive.fallback.Width "height" $responsive.fallback.Height }} {{ else }} {{/* Thumbnail mode (testimonials, etc.): Fill 96x96 */}} {{ $processed := $image_resource.Process "Fill 96x96 Center webp" }} {{ $img_data = dict "src" $processed.RelPermalink }} {{ end }} {{ else if $fallback_url }} {{ $img_data = dict "src" $fallback_url }} {{ end }} {{ if $img_data }} {{ $item_images = merge $item_images (dict (printf "%d" $idx) $img_data) }} {{ end }} {{ end }} {{ end }} {{ end }} {{ if gt (len $item_images) 0 }} {{ $props = merge $props (dict "item_images" $item_images) }} {{ end }} {{/* Resolve per-item feature_icon (cta-image-paragraph) */}} {{ with $block.content.items }} {{ range . }} {{ with .feature_icon }} {{ if not (index $icon_svgs .) }} {{ $icon_data := partial "functions/get_icon_data" (dict "name" .) }} {{ if $icon_data }} {{ $icon_svgs = merge $icon_svgs (dict . $icon_data) }} {{ end }} {{ end }} {{ end }} {{ end }} {{ end }} {{ if gt (len $icon_svgs) 0 }} {{ $props = merge $props (dict "icon_svgs" $icon_svgs) }} {{ end }} {{/* Resolve per-step icons (steps block — semantic 'steps' key alias) */}} {{ with $block.content.steps }} {{ range . }} {{ with .icon }} {{ if not (index $icon_svgs .) }} {{ $icon_data := partial "functions/get_icon_data" (dict "name" .) }} {{ if $icon_data }} {{ $icon_svgs = merge $icon_svgs (dict . $icon_data) }} {{ end }} {{ end }} {{ end }} {{ end }} {{ end }} {{ if gt (len $icon_svgs) 0 }} {{ $props = merge $props (dict "icon_svgs" $icon_svgs) }} {{ end }} {{/* Resolve CTA icons from pricing tiers (content.tiers[*].cta.icon) */}} {{ with $block.content.tiers }} {{ range . }} {{ with .cta.icon }} {{ if not (index $icon_svgs .) }} {{ $icon_data := partial "functions/get_icon_data" (dict "name" .) }} {{ if $icon_data }} {{ $icon_svgs = merge $icon_svgs (dict . $icon_data) }} {{ end }} {{ end }} {{ end }} {{ end }} {{ end }} {{ if gt (len $icon_svgs) 0 }} {{ $props = merge $props (dict "icon_svgs" $icon_svgs) }} {{ end }} {{/* Gallery block: resolve items list with responsive variants + LQIP placeholders */}} {{ if eq $block_type "gallery" }} {{ $gallery := partial "functions/resolve_gallery_items.html" (dict "content" $block.content "Page" $page ) }} {{ if $gallery.items }} {{ $props = merge $props (dict "items" $gallery.items) }} {{ end }} {{ end }} {{/* Convert props to JSON for client-side rendering */}} {{ $propsJSON := $props | jsonify }} {{/* Render a container that Preact will populate */}}