diff --git a/modules/blox/blox/cta-button-list/block.html b/modules/blox/blox/cta-button-list/block.html
index 78d72e37..fb1efbeb 100644
--- a/modules/blox/blox/cta-button-list/block.html
+++ b/modules/blox/blox/cta-button-list/block.html
@@ -5,22 +5,70 @@
{{/* Initialise */}}
{{ $page := .wcPage }}
{{ $block := .wcBlock }}
+{{ $content := $block.content }}
+{{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }}
diff --git a/modules/blox/blox/cta-image-paragraph/block.html b/modules/blox/blox/cta-image-paragraph/block.html
index c4186b5f..03901651 100644
--- a/modules/blox/blox/cta-image-paragraph/block.html
+++ b/modules/blox/blox/cta-image-paragraph/block.html
@@ -5,14 +5,34 @@
{{/* Initialise */}}
{{ $page := .wcPage }}
{{ $block := .wcBlock }}
+{{ $content := $block.content }}
+{{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }}
- {{ range $idx, $item := $block.content.items }}
- {{ $title := .title | emojify | $page.RenderString }}
- {{ $text := .text | emojify | $page.RenderString }}
- {{ $image_path := path.Join "media" .image }}
- {{ $image := resources.GetMatch $image_path }}
- {{ with $image }}
+ {{ $items_raw := index $content "items" }}
+ {{ $items := slice }}
+ {{ if reflect.IsSlice $items_raw }}
+ {{ $items = $items_raw }}
+ {{ else if and $items_raw (reflect.IsMap $items_raw) }}
+ {{ $items = slice $items_raw }}
+ {{ end }}
+
+ {{ range $idx, $item := $items }}
+ {{ if reflect.IsMap $item }}
+ {{ $title := "" }}
+ {{ $title_raw := index $item "title" }}
+ {{ if eq (printf "%T" $title_raw) "string" }}{{ $title = $title_raw | emojify | $page.RenderString }}{{ end }}
+ {{ $text := "" }}
+ {{ $text_raw := index $item "text" }}
+ {{ if eq (printf "%T" $text_raw) "string" }}{{ $text = $text_raw | emojify | $page.RenderString }}{{ end }}
+ {{ $image_name := "" }}
+ {{ $image_raw := index $item "image" }}
+ {{ if eq (printf "%T" $image_raw) "string" }}{{ $image_name = strings.TrimSpace $image_raw }}{{ end }}
+ {{ $image_path := "" }}
+ {{ if $image_name }}{{ $image_path = path.Join "media" $image_name }}{{ end }}
+ {{ $image := "" }}
+ {{ if $image_path }}{{ $image = resources.GetMatch $image_path }}{{ end }}
+ {{ if $image }}
{{ if ne $image.MediaType.SubType "gif" }}
{{ $responsive := partial "functions/process_responsive_image.html" (dict
@@ -35,29 +55,57 @@
alt="{{$title | plainify}}" {{ if (modBool $idx 2)}}style="order: 1"{{end}}>
{{ end }}
{{ else }}
- {{ errorf "%s uses the `cta-image-paragraph` blox which specifies a non-existent `image` at `assets/%s`. Please add the image to this folder and try again." $page.File.Path $image_path }}
+ {{ warnf "%s uses the `cta-image-paragraph` blox which specifies a non-existent `image` at `assets/%s`. Skipping this item." $page.File.Path $image_path }}
{{ end }}
{{ end }}
+ {{ end }}
diff --git a/modules/blox/blox/dev-hero/block.html b/modules/blox/blox/dev-hero/block.html
index 1d4a83b3..3f1be5f4 100644
--- a/modules/blox/blox/dev-hero/block.html
+++ b/modules/blox/blox/dev-hero/block.html
@@ -5,28 +5,146 @@
{{/* Initialise */}}
{{ $page := .wcPage }}
{{ $block := .wcBlock }}
+{{ $content := $block.content }}
+{{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }}
+{{ $design := $block.design }}
+{{ if not (reflect.IsMap $design) }}{{ $design = dict }}{{ end }}
{{/* Enable animations if typewriter or scroll animations are configured */}}
-{{ $typewriter := $block.content.typewriter | default dict }}
-{{ $has_animations := or $typewriter.enable $block.design.animations }}
+{{ $typewriter := index $content "typewriter" }}
+{{ if not (reflect.IsMap $typewriter) }}{{ $typewriter = dict }}{{ end }}
+{{ $typewriter_enabled := partial "functions/coerce_bool" (dict "value" (index $typewriter "enable") "default" false) }}
+{{ $animations_enabled := partial "functions/coerce_bool" (dict "value" (index $design "animations") "default" false) }}
+{{ $has_animations := or $typewriter_enabled $animations_enabled }}
{{ if $has_animations }}
{{ $page.Store.Set "has_animations" true }}
{{ $page.Store.Set "has_alpine" true }}
{{ end }}
{{/* Get author data from YAML */}}
-{{ $username := $block.content.username | default "me" }}
+{{ $username := "me" }}
+{{ $username_raw := index $content "username" }}
+{{ if eq (printf "%T" $username_raw) "string" }}
+ {{ $username = strings.TrimSpace $username_raw }}
+{{ end }}
{{ $author := partial "functions/get_author_profile" $username }}
{{/* Get avatar */}}
{{ $avatar := "" }}
-{{ $avatar_shape := $block.design.avatar_shape | default "circle" }}
+{{ $avatar_shape := "circle" }}
+{{ $avatar_shape_raw := index $design "avatar_shape" }}
+{{ if eq (printf "%T" $avatar_shape_raw) "string" }}
+ {{ $avatar_shape = lower (strings.TrimSpace $avatar_shape_raw) }}
+{{ end }}
{{ with $author.avatar }}
{{ $avatar = .Fill "300x300 webp Center" }}
{{ end }}
{{/* Layout style */}}
-{{ $style := $block.design.style | default "centered" }}
+{{ $style := "centered" }}
+{{ $style_raw := index $design "style" }}
+{{ if eq (printf "%T" $style_raw) "string" }}
+ {{ $style_candidate := lower (strings.TrimSpace $style_raw) }}
+ {{ if in (slice "centered" "split") $style_candidate }}
+ {{ $style = $style_candidate }}
+ {{ end }}
+{{ end }}
+
+{{ $show_status := partial "functions/coerce_bool" (dict "value" (index $content "show_status") "default" false) }}
+{{ $show_scroll := partial "functions/coerce_bool" (dict "value" (index $content "show_scroll_indicator") "default" false) }}
+
+{{ $scroll_target := "#projects" }}
+{{ $scroll_target_raw := index $content "scroll_target" }}
+{{ if eq (printf "%T" $scroll_target_raw) "string" }}
+ {{ $scroll_target = strings.TrimSpace $scroll_target_raw }}
+{{ end }}
+{{ if not $scroll_target }}{{ $scroll_target = "#projects" }}{{ end }}
+
+{{ $greeting := "" }}
+{{ $greeting_raw := index $content "greeting" }}
+{{ if eq (printf "%T" $greeting_raw) "string" }}{{ $greeting = $greeting_raw }}{{ end }}
+{{ $name_prefix := "" }}
+{{ $name_prefix_raw := index $content "name_prefix" }}
+{{ if eq (printf "%T" $name_prefix_raw) "string" }}{{ $name_prefix = $name_prefix_raw }}{{ end }}
+
+{{ $title_override := "" }}
+{{ $title_raw := index $content "title" }}
+{{ if eq (printf "%T" $title_raw) "string" }}{{ $title_override = strings.TrimSpace $title_raw }}{{ end }}
+
+{{ $tagline := "" }}
+{{ $tagline_raw := index $content "tagline" }}
+{{ if eq (printf "%T" $tagline_raw) "string" }}{{ $tagline = $tagline_raw }}{{ end }}
+
+{{ $bio_override := "" }}
+{{ $bio_raw := index $content "bio" }}
+{{ if eq (printf "%T" $bio_raw) "string" }}{{ $bio_override = $bio_raw }}{{ end }}
+
+{{ $role := $author.role | default $tagline }}
+{{ $bio := $author.bio | default $bio_override }}
+
+{{ $typewriter_strings := slice }}
+{{ $strings_raw := index $typewriter "strings" }}
+{{ if reflect.IsSlice $strings_raw }}
+ {{ range $strings_raw }}
+ {{ $val := strings.TrimSpace (printf "%v" .) }}
+ {{ if $val }}{{ $typewriter_strings = $typewriter_strings | append $val }}{{ end }}
+ {{ end }}
+{{ else if eq (printf "%T" $strings_raw) "string" }}
+ {{ $val := strings.TrimSpace $strings_raw }}
+ {{ if $val }}{{ $typewriter_strings = slice $val }}{{ end }}
+{{ end }}
+
+{{ $typewriter_prefix := "" }}
+{{ $typewriter_prefix_raw := index $typewriter "prefix" }}
+{{ if eq (printf "%T" $typewriter_prefix_raw) "string" }}{{ $typewriter_prefix = $typewriter_prefix_raw }}{{ end }}
+{{ $type_speed := partial "functions/coerce_int" (dict "value" (index $typewriter "type_speed") "default" 80 "min" 10 "max" 500) }}
+{{ $delete_speed := partial "functions/coerce_int" (dict "value" (index $typewriter "delete_speed") "default" 50 "min" 10 "max" 500) }}
+{{ $pause_time := partial "functions/coerce_int" (dict "value" (index $typewriter "pause_time") "default" 2000 "min" 200 "max" 10000) }}
+
+{{ $links_raw := $author.links | default (index $content "links") }}
+{{ $links := slice }}
+{{ if reflect.IsSlice $links_raw }}
+ {{ range $links_raw }}
+ {{ $url := "" }}
+ {{ $icon := "hero/link" }}
+ {{ $label := "" }}
+ {{ if reflect.IsMap . }}
+ {{ $url_raw := index . "url" | default (index . "link") }}
+ {{ if eq (printf "%T" $url_raw) "string" }}{{ $url = strings.TrimSpace $url_raw }}{{ end }}
+ {{ $icon_raw := index . "icon" }}
+ {{ if eq (printf "%T" $icon_raw) "string" }}{{ $icon = $icon_raw }}{{ end }}
+ {{ $label_raw := index . "label" | default (index . "name") }}
+ {{ if eq (printf "%T" $label_raw) "string" }}{{ $label = $label_raw }}{{ end }}
+ {{ else if eq (printf "%T" .) "string" }}
+ {{ $url = strings.TrimSpace . }}
+ {{ end }}
+ {{ if $url }}
+ {{ $links = $links | append (dict "url" $url "icon" $icon "label" $label) }}
+ {{ end }}
+ {{ end }}
+{{ else if eq (printf "%T" $links_raw) "string" }}
+ {{ $url := strings.TrimSpace $links_raw }}
+ {{ if $url }}
+ {{ $links = slice (dict "url" $url "icon" "hero/link" "label" "") }}
+ {{ end }}
+{{ end }}
+
+{{ $cta_buttons_raw := index $content "cta_buttons" }}
+{{ $cta_buttons := slice }}
+{{ if reflect.IsSlice $cta_buttons_raw }}
+ {{ $cta_buttons = $cta_buttons_raw }}
+{{ else if and $cta_buttons_raw (reflect.IsMap $cta_buttons_raw) }}
+ {{ $cta_buttons = slice $cta_buttons_raw }}
+{{ end }}
+
+{{ $status_icon := "" }}
+{{ $status := $author.status }}
+{{ if and $status (reflect.IsMap $status) }}
+ {{ $status_icon_raw := index $status "icon" }}
+ {{ if eq (printf "%T" $status_icon_raw) "string" }}
+ {{ $status_icon = $status_icon_raw }}
+ {{ end }}
+{{ end }}
{{/* Status emoji badge */}}
- {{ if $block.content.show_status }}
- {{ with $author.status.icon }}
+ {{ if $show_status }}
+ {{ with $status_icon }}
{{/* Greeting */}}
- {{ with $block.content.greeting }}
+ {{ with $greeting }}
{{ . }}
@@ -86,19 +204,18 @@
{{/* Name */}}
- {{ with $block.content.name_prefix }}{{ . }} {{ end }}
+ {{ with $name_prefix }}{{ . }} {{ end }}
- {{ $author.title | default $block.content.title | default (i18n "developer" | default "Developer") }}
+ {{ $author.title | default $title_override | default (i18n "developer" | default "Developer") }}
{{/* Role/Tagline with optional typewriter */}}
- {{ $role := $author.role | default $block.content.tagline }}
- {{ if and $typewriter.enable $typewriter.strings }}
+ {{ if and $typewriter_enabled (gt (len $typewriter_strings) 0) }}
- {{ with $typewriter.prefix }}{{ . }} {{ end }}
+ {{ with $typewriter_prefix }}{{ . }} {{ end }}
@@ -110,26 +227,34 @@
{{ end }}
{{/* Bio */}}
- {{ with $author.bio | default $block.content.bio }}
+ {{ with $bio }}
{{ . | $page.RenderString }}
{{ end }}
{{/* Social Links */}}
- {{ $links := $author.links | default $block.content.links }}
- {{ with $links }}
+ {{ if gt (len $links) 0 }}
- {{ range . }}
- {{ $icon := .icon | default "link" }}
- {{ $url := .url }}
+ {{ range $links }}
+ {{ $icon := index . "icon" | default "hero/link" }}
+ {{ $url := index . "url" }}
+ {{ $link := $url }}
+ {{ $target := "" }}
+ {{ $scheme := (urls.Parse $link).Scheme }}
+ {{ if not $scheme }}
+ {{ if not (hasPrefix $link "#") }}
+ {{ $link = $link | relLangURL }}
+ {{ end }}
+ {{ else if in (slice "http" "https") $scheme }}
+ {{ $target = "target=\"_blank\" rel=\"noopener noreferrer\"" }}
+ {{ end }}
{{ partial "functions/get_icon" (dict "name" $icon "attributes" "class=\"w-5 h-5\"") }}
@@ -138,19 +263,45 @@
{{ end }}
{{/* CTA Buttons */}}
- {{ with $block.content.cta_buttons }}
+ {{ if gt (len $cta_buttons) 0 }}
- {{ range $idx, $btn := . }}
+ {{ range $idx, $btn := $cta_buttons }}
+ {{ if reflect.IsMap $btn }}
{{ $is_primary := eq $idx 0 }}
+ {{ $btn_text := "" }}
+ {{ $btn_url := "" }}
+ {{ $btn_icon := "" }}
+ {{ $btn_new_tab := partial "functions/coerce_bool" (dict "value" (index $btn "new_tab") "default" false) }}
+ {{ with index $btn "text" }}{{ $btn_text = strings.TrimSpace (printf "%v" .) }}{{ end }}
+ {{ with index $btn "url" }}{{ $btn_url = strings.TrimSpace (printf "%v" .) }}{{ end }}
+ {{ with index $btn "icon" }}{{ $btn_icon = printf "%v" . }}{{ end }}
+ {{ if and $btn_text $btn_url }}
+ {{ $link := $btn_url }}
+ {{ $target := "" }}
+ {{ $scheme := (urls.Parse $link).Scheme }}
+ {{ if not $scheme }}
+ {{ if not (hasPrefix $link "#") }}
+ {{ $link = $link | relLangURL }}
+ {{ end }}
+ {{ if eq (path.Ext $link) ".pdf" }}{{ $btn_new_tab = true }}{{ end }}
+ {{ else if in (slice "http" "https") $scheme }}
+ {{ $btn_new_tab = true }}
+ {{ end }}
+ {{ if $btn_new_tab }}
+ {{ $target = "target=\"_blank\" rel=\"noopener\"" }}
+ {{ end }}
- {{ with .icon }}
- {{ partial "functions/get_icon" (dict "name" . "attributes" "class=\"w-5 h-5\"") }}
+ {{ if $btn_icon }}
+ {{ partial "functions/get_icon" (dict "name" $btn_icon "attributes" "class=\"w-5 h-5\"") }}
{{ end }}
- {{ .text }}
+ {{ $btn_text }}
+ {{ end }}
+ {{ end }}
{{ end }}
{{ end }}
@@ -168,8 +319,8 @@
{{/* Status emoji badge */}}
- {{ if $block.content.show_status }}
- {{ with $author.status.icon }}
+ {{ if $show_status }}
+ {{ with $status_icon }}
{{ . | emojify }}
@@ -180,7 +331,7 @@
{{ end }}
{{/* Greeting */}}
- {{ with $block.content.greeting }}
+ {{ with $greeting }}
{{ . }}
@@ -190,19 +341,18 @@
{{/* Name */}}
- {{ with $block.content.name_prefix }}{{ . }} {{ end }}
+ {{ with $name_prefix }}{{ . }} {{ end }}
- {{ $author.title | default $block.content.title | default (i18n "developer" | default "Developer") }}
+ {{ $author.title | default $title_override | default (i18n "developer" | default "Developer") }}
{{/* Role/Tagline with optional typewriter */}}
- {{ $role := $author.role | default $block.content.tagline }}
- {{ if and $typewriter.enable $typewriter.strings }}
+ {{ if and $typewriter_enabled (gt (len $typewriter_strings) 0) }}
- {{ with $typewriter.prefix }}{{ . }} {{ end }}
+ {{ with $typewriter_prefix }}{{ . }} {{ end }}
@@ -214,26 +364,34 @@
{{ end }}
{{/* Bio */}}
- {{ with $author.bio | default $block.content.bio }}
+ {{ with $bio }}
{{ . | $page.RenderString }}
{{ end }}
{{/* Social Links */}}
- {{ $links := $author.links | default $block.content.links }}
- {{ with $links }}
+ {{ if gt (len $links) 0 }}
- {{ range . }}
- {{ $icon := .icon | default "link" }}
- {{ $url := .url }}
+ {{ range $links }}
+ {{ $icon := index . "icon" | default "hero/link" }}
+ {{ $url := index . "url" }}
+ {{ $link := $url }}
+ {{ $target := "" }}
+ {{ $scheme := (urls.Parse $link).Scheme }}
+ {{ if not $scheme }}
+ {{ if not (hasPrefix $link "#") }}
+ {{ $link = $link | relLangURL }}
+ {{ end }}
+ {{ else if in (slice "http" "https") $scheme }}
+ {{ $target = "target=\"_blank\" rel=\"noopener noreferrer\"" }}
+ {{ end }}
{{ partial "functions/get_icon" (dict "name" $icon "attributes" "class=\"w-5 h-5\"") }}
@@ -242,19 +400,45 @@
{{ end }}
{{/* CTA Buttons */}}
- {{ with $block.content.cta_buttons }}
+ {{ if gt (len $cta_buttons) 0 }}
{{ end }}
@@ -262,10 +446,20 @@
{{ end }}
{{/* Scroll indicator - clicks to scroll to next section */}}
- {{ if $block.content.show_scroll_indicator }}
- {{ $scroll_target := $block.content.scroll_target | default "#projects" }}
+ {{ if $show_scroll }}
+ {{ $scroll_link := $scroll_target }}
+ {{ $scroll_target_attr := "" }}
+ {{ $scroll_scheme := (urls.Parse $scroll_link).Scheme }}
+ {{ if not $scroll_scheme }}
+ {{ if not (hasPrefix $scroll_link "#") }}
+ {{ $scroll_link = $scroll_link | relLangURL }}
+ {{ end }}
+ {{ else if in (slice "http" "https") $scroll_scheme }}
+ {{ $scroll_target_attr = "target=\"_blank\" rel=\"noopener\"" }}
+ {{ end }}
diff --git a/modules/blox/blox/faq/block.html b/modules/blox/blox/faq/block.html
index 0a7c448b..97099d91 100644
--- a/modules/blox/blox/faq/block.html
+++ b/modules/blox/blox/faq/block.html
@@ -1,27 +1,64 @@
{{- $wcPage := .wcPage -}}
{{- $wcBlock := .wcBlock -}}
{{- $wcIdentifier := .wcIdentifier -}}
+{{- $content := $wcBlock.content -}}
+{{- if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end -}}
+{{- $design := $wcBlock.design -}}
+{{- if not (reflect.IsMap $design) }}{{ $design = dict }}{{ end -}}
{{/* Enable Alpine.js for interactive accordion */}}
{{ $wcPage.Page.Store.Set "has_alpine" true }}
-{{- $st := $wcBlock.design.spacing | default dict -}}
-{{- $pad := $st.padding | default (slice "20px" "0" "20px" "0") -}}
+{{- $st := index $design "spacing" -}}
+{{- if not (reflect.IsMap $st) }}{{ $st = dict }}{{ end -}}
+{{- $pad := slice "20px" "0" "20px" "0" -}}
+{{- $pad_raw := index $st "padding" -}}
+{{- if and (reflect.IsSlice $pad_raw) (ge (len $pad_raw) 4) }}{{ $pad = $pad_raw }}{{ end -}}
{{- $pad_sm := slice "3rem" "0" -}}
-{{- $mar := $st.margin | default (slice "0" "0" "0" "0") -}}
+{{- $pad_sm_raw := index $st "padding_sm" -}}
+{{- if and (reflect.IsSlice $pad_sm_raw) (ge (len $pad_sm_raw) 2) }}{{ $pad_sm = $pad_sm_raw }}{{ end -}}
+{{- $mar := slice "0" "0" "0" "0" -}}
+{{- $mar_raw := index $st "margin" -}}
+{{- if and (reflect.IsSlice $mar_raw) (ge (len $mar_raw) 4) }}{{ $mar = $mar_raw }}{{ end -}}
-{{- $bg := $wcBlock.design.background | default dict -}}
-{{- $bg_color_val := $bg.color | default "" -}}
+{{- $bg := index $design "background" -}}
+{{- if not (reflect.IsMap $bg) }}{{ $bg = dict }}{{ end -}}
+{{- $bg_color_val := "" -}}
+{{- $bg_color_raw := index $bg "color" -}}
+{{- if eq (printf "%T" $bg_color_raw) "string" }}{{ $bg_color_val = $bg_color_raw }}{{ end -}}
+
+{{- $title := "" -}}
+{{- $title_raw := index $content "title" -}}
+{{- if eq (printf "%T" $title_raw) "string" }}{{ $title = $title_raw }}{{ end -}}
+{{- $subtitle := "" -}}
+{{- $subtitle_raw := index $content "subtitle" -}}
+{{- if eq (printf "%T" $subtitle_raw) "string" }}{{ $subtitle = $subtitle_raw }}{{ end -}}
+{{- $text := "" -}}
+{{- $text_raw := index $content "text" -}}
+{{- if eq (printf "%T" $text_raw) "string" }}{{ $text = $text_raw }}{{ end -}}
+
+{{- $items_raw := index $content "items" -}}
+{{- $items := slice -}}
+{{- if reflect.IsSlice $items_raw }}{{ $items = $items_raw }}{{ end -}}
+
+{{- $button := index $content "button" -}}
+{{- if not (reflect.IsMap $button) }}{{ $button = dict }}{{ end -}}
+{{- $button_text := "" -}}
+{{- with index $button "text" }}{{ $button_text = strings.TrimSpace (printf "%v" .) }}{{ end -}}
+{{- $button_url := "" -}}
+{{- with index $button "url" }}{{ $button_url = strings.TrimSpace (printf "%v" .) }}{{ end -}}
+{{- $button_icon := "" -}}
+{{- with index $button "icon" }}{{ $button_icon = printf "%v" . }}{{ end -}}
- {{- with $wcBlock.content.title -}}
+ {{- with $title -}}
{{ . | markdownify | emojify }}
- {{- with $wcBlock.content.subtitle -}}
+ {{- with $subtitle -}}
{{ . | markdownify | emojify }}
@@ -29,18 +66,24 @@
{{- end -}}
- {{- with $wcBlock.content.text -}}
+ {{- with $text -}}
{{ . | markdownify | emojify }}
{{- end -}}
- {{- $items := $wcBlock.content.items | default slice -}}
-
- {{- if $items -}}
+ {{- if gt (len $items) 0 -}}
{{- range $index, $item := $items -}}
+ {{- if reflect.IsMap $item -}}
+ {{- $question := "" -}}
+ {{- $question_raw := index $item "question" | default (index $item "title") -}}
+ {{- if ne $question_raw nil }}{{ $question = printf "%v" $question_raw }}{{ end -}}
+ {{- $answer := "" -}}
+ {{- $answer_raw := index $item "answer" | default (index $item "text") -}}
+ {{- if ne $answer_raw nil }}{{ $answer = printf "%v" $answer_raw }}{{ end -}}
+ {{- if or $question $answer -}}
{{- end -}}
+ {{- end -}}
+ {{- end -}}
{{- end -}}
- {{- with $wcBlock.content.button -}}
+ {{- if and $button_text $button_url -}}
+ {{- $link := $button_url -}}
+ {{- $target := "" -}}
+ {{- $scheme := (urls.Parse $link).Scheme -}}
+ {{- if not $scheme -}}
+ {{- if not (hasPrefix $link "#") -}}
+ {{- $link = $link | relLangURL -}}
+ {{- end -}}
+ {{- if eq (path.Ext $link) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end -}}
+ {{- else if in (slice "http" "https") $scheme -}}
+ {{- $target = "target=\"_blank\" rel=\"noopener\"" -}}
+ {{- end -}}
@@ -94,4 +150,3 @@
-
diff --git a/modules/blox/blox/features/block.html b/modules/blox/blox/features/block.html
index 66b7b0eb..012e9e1c 100644
--- a/modules/blox/blox/features/block.html
+++ b/modules/blox/blox/features/block.html
@@ -5,8 +5,15 @@
{{/* Initialise */}}
{{ $page := .wcPage }}
{{ $block := .wcBlock }}
-{{ $title := $block.content.title | emojify | $page.RenderString }}
-{{ $text := $block.content.text | emojify | $page.RenderString }}
+{{ $content := $block.content }}
+{{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }}
+{{ $title := "" }}
+{{ with index $content "title" }}{{ $title = printf "%v" . | emojify | $page.RenderString }}{{ end }}
+{{ $text := "" }}
+{{ with index $content "text" }}{{ $text = printf "%v" . | emojify | $page.RenderString }}{{ end }}
+{{ $items_raw := index $content "items" }}
+{{ $items := slice }}
+{{ if reflect.IsSlice $items_raw }}{{ $items = $items_raw }}{{ end }}
@@ -19,16 +26,26 @@
{{ end }}
- {{ range $block.content.items }}
+ {{ range $items }}
+ {{ if reflect.IsMap . }}
+ {{ $icon := "" }}
+ {{ with index . "icon" }}
+ {{ if eq (printf "%T" .) "string" }}{{ $icon = . }}{{ end }}
+ {{ end }}
+ {{ $name := "" }}
+ {{ with index . "name" }}{{ $name = printf "%v" . }}{{ end }}
+ {{ $description := "" }}
+ {{ with index . "description" }}{{ $description = printf "%v" . }}{{ end }}
- {{ with .icon }}
+ {{ with $icon }}
{{ partial "functions/get_icon" (dict "name" . "attributes" `class="w-5 h-5 lg:w-6 lg:h-6"`) }}
{{ end }}
-
{{ .name | $page.RenderString }}
-
{{ .description | $page.RenderString }}
+ {{ with $name }}
{{ . | $page.RenderString }}
{{ end }}
+ {{ with $description }}
{{ . | $page.RenderString }}
{{ end }}
+ {{ end }}
{{ end }}
diff --git a/modules/blox/blox/hero/block.html b/modules/blox/blox/hero/block.html
index 5b81fb38..b7ad8ea2 100644
--- a/modules/blox/blox/hero/block.html
+++ b/modules/blox/blox/hero/block.html
@@ -5,30 +5,56 @@
{{/* Initialise */}}
{{ $page := .wcPage }}
{{ $block := .wcBlock }}
+{{ $content := $block.content }}
+{{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }}
+{{ $design := $block.design }}
+{{ if not (reflect.IsMap $design) }}{{ $design = dict }}{{ end }}
+{{ $no_padding := partial "functions/coerce_bool" (dict "value" (index $design "no_padding") "default" false) }}
+
+{{ $announcement := index $content "announcement" }}
+{{ if not (reflect.IsMap $announcement) }}{{ $announcement = dict }}{{ end }}
+{{ $announcement_text := "" }}
+{{ with index $announcement "text" }}{{ $announcement_text = strings.TrimSpace (printf "%v" .) }}{{ end }}
+{{ $announcement_link := index $announcement "link" }}
+{{ if not (reflect.IsMap $announcement_link) }}{{ $announcement_link = dict }}{{ end }}
+{{ $announcement_link_text := "" }}
+{{ with index $announcement_link "text" }}{{ $announcement_link_text = strings.TrimSpace (printf "%v" .) }}{{ end }}
+{{ $announcement_link_url := "" }}
+{{ with index $announcement_link "url" }}{{ $announcement_link_url = strings.TrimSpace (printf "%v" .) }}{{ end }}
+
+{{ $primary_action := index $content "primary_action" }}
+{{ if not (reflect.IsMap $primary_action) }}{{ $primary_action = dict }}{{ end }}
+{{ $primary_text := "" }}
+{{ with index $primary_action "text" }}{{ $primary_text = strings.TrimSpace (printf "%v" .) }}{{ end }}
+{{ $primary_url := "" }}
+{{ with index $primary_action "url" }}{{ $primary_url = strings.TrimSpace (printf "%v" .) }}{{ end }}
+{{ $primary_icon := "" }}
+{{ with index $primary_action "icon" }}{{ $primary_icon = printf "%v" . }}{{ end }}
+
+{{ $secondary_action := index $content "secondary_action" }}
+{{ if not (reflect.IsMap $secondary_action) }}{{ $secondary_action = dict }}{{ end }}
+{{ $secondary_text := "" }}
+{{ with index $secondary_action "text" }}{{ $secondary_text = strings.TrimSpace (printf "%v" .) }}{{ end }}
+{{ $secondary_url := "" }}
+{{ with index $secondary_action "url" }}{{ $secondary_url = strings.TrimSpace (printf "%v" .) }}{{ end }}