Skip to content

Commit 09eb7f7

Browse files
committed
feat: harden block inputs (batch 2)
Finished hardening the remaining blocks by guarding content/design maps, normalizing list inputs, coercing numeric/boolean values, and sanitizing links; also tightened scroll target handling in block.html. Changes Normalized portfolio tags/tech stacks/links, made archive defaults safe, and ensured filter JS uses JSON-safe tags in block.html. Validated research area layouts and item fields, added safe media/link handling, and made CTA rendering resilient in block.html. Hardened resume blocks for profile fields, buttons/links, and dates using try with time in block.html, block.html, and block.html. Improved numeric parsing and labeling for language/skill meters in block.html and block.html. Added guarded items and predictable grid classes in block.html. Sanitized badge/title/suggestions/stats rendering in block.html, normalized tech categories and made list style exclusive in block.html, and hardened testimonials’ items/image handling in block.html. Normalized dynamic/static question data, badges, and safe links in block.html.
1 parent 98f0d20 commit 09eb7f7

File tree

21 files changed

+2683
-645
lines changed

21 files changed

+2683
-645
lines changed

modules/blox/blox/contact-info/block.html

Lines changed: 270 additions & 43 deletions
Large diffs are not rendered by default.

modules/blox/blox/cta-button-list/block.html

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,70 @@
55
{{/* Initialise */}}
66
{{ $page := .wcPage }}
77
{{ $block := .wcBlock }}
8+
{{ $content := $block.content }}
9+
{{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }}
810

911
<div class="flex items-center flex-col mx-auto w-full justify-center mt-4 px-8 pb-5">
1012

11-
{{ range $index, $item := $block.content.buttons }}
12-
<a href="{{ .url }}" target="_blank" rel="noopener noreferrer" class="flex items-center p-1 w-full rounded-md hover:scale-105 transition-all bg-gray-100 mb-3 max-w-3xl">
13-
<div class="flex text-center w-full">
14-
<div class="w-10 h-10 text-gray-700">
15-
{{ with .icon }}
16-
{{ partial "functions/get_icon" (dict "name" . "attributes" "height=\"40\" width=\"40\" class=\"rounded-sm\"") }}
13+
{{ $buttons_raw := index $content "buttons" }}
14+
{{ $buttons := slice }}
15+
{{ if reflect.IsSlice $buttons_raw }}
16+
{{ $buttons = $buttons_raw }}
17+
{{ else if and $buttons_raw (reflect.IsMap $buttons_raw) }}
18+
{{ $buttons = slice $buttons_raw }}
19+
{{ else if eq (printf "%T" $buttons_raw) "string" }}
20+
{{ $buttons = slice (dict "url" $buttons_raw) }}
21+
{{ end }}
22+
23+
{{ range $index, $item := $buttons }}
24+
{{ $text := "" }}
25+
{{ $url := "" }}
26+
{{ $icon := "" }}
27+
{{ $new_tab := false }}
28+
{{ if reflect.IsMap $item }}
29+
{{ $text_raw := index $item "text" | default (index $item "label") | default (index $item "name") }}
30+
{{ if ne $text_raw nil }}{{ $text = strings.TrimSpace (printf "%v" $text_raw) }}{{ end }}
31+
{{ $url_raw := index $item "url" | default (index $item "link") }}
32+
{{ if eq (printf "%T" $url_raw) "string" }}{{ $url = strings.TrimSpace $url_raw }}{{ end }}
33+
{{ $icon_raw := index $item "icon" }}
34+
{{ if eq (printf "%T" $icon_raw) "string" }}{{ $icon = $icon_raw }}{{ end }}
35+
{{ $new_tab = partial "functions/coerce_bool" (dict "value" (index $item "new_tab") "default" false) }}
36+
{{ else if eq (printf "%T" $item) "string" }}
37+
{{ $url = strings.TrimSpace $item }}
38+
{{ end }}
39+
{{ if and (not $text) $url }}
40+
{{ $text = $url }}
41+
{{ end }}
42+
{{ if $url }}
43+
{{ $link := $url }}
44+
{{ $target := "" }}
45+
{{ $scheme := (urls.Parse $link).Scheme }}
46+
{{ if not $scheme }}
47+
{{ if not (hasPrefix $link "#") }}
48+
{{ $link = $link | relLangURL }}
49+
{{ end }}
50+
{{ if eq (path.Ext $link) ".pdf" }}
51+
{{ $new_tab = true }}
1752
{{ end }}
18-
</div>
19-
<div class="flex justify-center items-center font-semibold w-full text-gray-700 -ml-10">
20-
{{ .text | markdownify | emojify }}
21-
</div>
22-
</div>
23-
</a>
24-
{{end}}
53+
{{ else if in (slice "http" "https") $scheme }}
54+
{{ $new_tab = true }}
55+
{{ end }}
56+
{{ if $new_tab }}
57+
{{ $target = "target=\"_blank\" rel=\"noopener noreferrer\"" }}
58+
{{ end }}
59+
<a href="{{ $link | safeURL }}" {{ $target | safeHTMLAttr }} class="flex items-center p-1 w-full rounded-md hover:scale-105 transition-all bg-gray-100 mb-3 max-w-3xl">
60+
<div class="flex text-center w-full">
61+
<div class="w-10 h-10 text-gray-700">
62+
{{ with $icon }}
63+
{{ partial "functions/get_icon" (dict "name" . "attributes" "height=\"40\" width=\"40\" class=\"rounded-sm\"") }}
64+
{{ end }}
65+
</div>
66+
<div class="flex justify-center items-center font-semibold w-full text-gray-700 -ml-10">
67+
{{ $text | markdownify | emojify }}
68+
</div>
69+
</div>
70+
</a>
71+
{{ end }}
72+
{{ end }}
2573

2674
</div>

modules/blox/blox/cta-image-paragraph/block.html

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,34 @@
55
{{/* Initialise */}}
66
{{ $page := .wcPage }}
77
{{ $block := .wcBlock }}
8+
{{ $content := $block.content }}
9+
{{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }}
810

911
<div>
10-
{{ range $idx, $item := $block.content.items }}
11-
{{ $title := .title | emojify | $page.RenderString }}
12-
{{ $text := .text | emojify | $page.RenderString }}
13-
{{ $image_path := path.Join "media" .image }}
14-
{{ $image := resources.GetMatch $image_path }}
15-
{{ with $image }}
12+
{{ $items_raw := index $content "items" }}
13+
{{ $items := slice }}
14+
{{ if reflect.IsSlice $items_raw }}
15+
{{ $items = $items_raw }}
16+
{{ else if and $items_raw (reflect.IsMap $items_raw) }}
17+
{{ $items = slice $items_raw }}
18+
{{ end }}
19+
20+
{{ range $idx, $item := $items }}
21+
{{ if reflect.IsMap $item }}
22+
{{ $title := "" }}
23+
{{ $title_raw := index $item "title" }}
24+
{{ if eq (printf "%T" $title_raw) "string" }}{{ $title = $title_raw | emojify | $page.RenderString }}{{ end }}
25+
{{ $text := "" }}
26+
{{ $text_raw := index $item "text" }}
27+
{{ if eq (printf "%T" $text_raw) "string" }}{{ $text = $text_raw | emojify | $page.RenderString }}{{ end }}
28+
{{ $image_name := "" }}
29+
{{ $image_raw := index $item "image" }}
30+
{{ if eq (printf "%T" $image_raw) "string" }}{{ $image_name = strings.TrimSpace $image_raw }}{{ end }}
31+
{{ $image_path := "" }}
32+
{{ if $image_name }}{{ $image_path = path.Join "media" $image_name }}{{ end }}
33+
{{ $image := "" }}
34+
{{ if $image_path }}{{ $image = resources.GetMatch $image_path }}{{ end }}
35+
{{ if $image }}
1636
<div class="gap-8 items-center py-8 px-4 mx-auto max-w-screen-xl xl:gap-16 md:grid md:grid-cols-2 sm:py-16 lg:px-6">
1737
{{ if ne $image.MediaType.SubType "gif" }}
1838
{{ $responsive := partial "functions/process_responsive_image.html" (dict
@@ -35,29 +55,57 @@
3555
alt="{{$title | plainify}}" {{ if (modBool $idx 2)}}style="order: 1"{{end}}>
3656
{{ end }}
3757
{{ else }}
38-
{{ 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 }}
58+
{{ 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 }}
3959
{{ end }}
4060
<div class="mt-4 md:mt-0">
4161
<h2 class="mb-4 text-4xl tracking-tight font-extrabold text-gray-900 dark:text-white">{{$title}}</h2>
4262
<p class="mb-6 font-light text-gray-500 md:text-lg dark:text-gray-400">{{$text}}</p>
43-
{{ $icon := .feature_icon | default "check" }}
44-
{{ if .features }}
63+
{{ $icon := "check" }}
64+
{{ $icon_raw := index $item "feature_icon" }}
65+
{{ if eq (printf "%T" $icon_raw) "string" }}{{ $icon = $icon_raw }}{{ end }}
66+
{{ $features_raw := index $item "features" }}
67+
{{ $features := slice }}
68+
{{ if reflect.IsSlice $features_raw }}
69+
{{ $features = $features_raw }}
70+
{{ else if eq (printf "%T" $features_raw) "string" }}
71+
{{ $features = slice $features_raw }}
72+
{{ end }}
73+
{{ if gt (len $features) 0 }}
4574
<ul>
46-
{{ range .features }}
75+
{{ range $features }}
4776
<li class="relative mb-4 pl-6">
4877
{{ partial "functions/get_icon" (dict "name" $icon "attributes" `class="inline-block pr-3" style="height: 1em;"`) }}
49-
{{ . | markdownify }}
78+
{{ printf "%v" . | markdownify }}
5079
</li>
5180
{{ end }}
5281
</ul>
5382
{{ end }}
54-
{{ with .button }}
55-
<a href="{{.url}}" class="mt-3 inline-flex items-center text-white bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-primary-900">
56-
{{.text}}
83+
{{ $button_raw := index $item "button" }}
84+
{{ if and $button_raw (reflect.IsMap $button_raw) }}
85+
{{ $button_text := "" }}
86+
{{ $button_url := "" }}
87+
{{ with index $button_raw "text" }}{{ $button_text = strings.TrimSpace (printf "%v" .) }}{{ end }}
88+
{{ with index $button_raw "url" }}{{ $button_url = strings.TrimSpace (printf "%v" .) }}{{ end }}
89+
{{ if and $button_text $button_url }}
90+
{{ $link := $button_url }}
91+
{{ $target := "" }}
92+
{{ $scheme := (urls.Parse $link).Scheme }}
93+
{{ if not $scheme }}
94+
{{ if not (hasPrefix $link "#") }}
95+
{{ $link = $link | relLangURL }}
96+
{{ end }}
97+
{{ if eq (path.Ext $link) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }}
98+
{{ else if in (slice "http" "https") $scheme }}
99+
{{ $target = "target=\"_blank\" rel=\"noopener\"" }}
100+
{{ end }}
101+
<a href="{{ $link | safeURL }}" {{ $target | safeHTMLAttr }} class="mt-3 inline-flex items-center text-white bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-primary-900">
102+
{{ $button_text }}
57103
<svg class="ml-2 -mr-1 w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
58104
</a>
59105
{{ end }}
106+
{{ end }}
60107
</div>
61108
</div>
62109
{{ end }}
110+
{{ end }}
63111
</div>

0 commit comments

Comments
 (0)