diff --git a/layouts/partials/hbx/blocks/resume-biography-3/block.html b/layouts/partials/hbx/blocks/resume-biography-3/block.html new file mode 100644 index 0000000..4fb837a --- /dev/null +++ b/layouts/partials/hbx/blocks/resume-biography-3/block.html @@ -0,0 +1,529 @@ +{{/* Hugo Blox: Biography 3 */}} +{{/* Documentation: https://hugoblox.com/blocks/ */}} +{{/* License: https://github.com/HugoBlox/kit/blob/main/LICENSE.md */}} + +{{/* 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 }} + +{{ $author := "me" }} +{{ $authorRaw := index $content "username" }} +{{ if eq (printf "%T" $authorRaw) "string" }} + {{ $author = $authorRaw }} +{{ end }} +{{ $profile := partial "functions/get_author_profile" $author }} +{{ $avatar := $profile.avatar }} +{{ $headings := index $content "headings" }} +{{ if not (reflect.IsMap $headings) }}{{ $headings = dict }}{{ end }} + +{{/* Avatar customization parameters */}} +{{ $avatar_size := "large" }} +{{ $avatar_shape := "circle" }} +{{ $avatar_config := index $design "avatar" }} +{{ if and $avatar_config (reflect.IsMap $avatar_config) }} + {{ $avatar_size_raw := index $avatar_config "size" }} + {{ if eq (printf "%T" $avatar_size_raw) "string" }} + {{ $avatar_size = $avatar_size_raw }} + {{ end }} + {{ $avatar_shape_raw := index $avatar_config "shape" }} + {{ if eq (printf "%T" $avatar_shape_raw) "string" }} + {{ $avatar_shape = $avatar_shape_raw }} + {{ end }} +{{ end }} + +{{/* Profile name typography */}} +{{ $name_size := "lg" }} +{{ $name_config := index $design "name" }} +{{ if and $name_config (reflect.IsMap $name_config) }} + {{ $name_size_raw := index $name_config "size" }} + {{ if eq (printf "%T" $name_size_raw) "string" }} + {{ $name_size = $name_size_raw }} + {{ end }} +{{ end }} +{{ $name_class_map := dict + "xs" "text-xl sm:text-2xl lg:text-3xl" + "sm" "text-2xl sm:text-3xl lg:text-4xl" + "md" "text-3xl sm:text-4xl lg:text-5xl" + "lg" "text-4xl sm:text-5xl lg:text-6xl" + "xl" "text-5xl sm:text-6xl lg:text-7xl" +}} +{{ $name_class := index $name_class_map $name_size | default (index $name_class_map "lg") }} + +{{/* Size mappings optimized for 2025 standards: display_size -> [display_px, generation_px] */}} +{{ $size_map := dict "small" (slice "150" "300") "medium" (slice "200" "400") "large" (slice "320" "640") "xl" (slice "400" "800") "xxl" (slice "500" "1000") }} +{{ $size_config := index $size_map $avatar_size | default (index $size_map "large") }} +{{ $display_size := index $size_config 0 }} +{{ $generation_size := index $size_config 1 }} + +{{/* Shape class mappings */}} +{{ $shape_classes := dict "circle" "rounded-full" "square" "rounded-none" "rounded" "rounded-lg" }} +{{ $shape_class := index $shape_classes $avatar_shape | default "rounded-full" }} + +{{ $banner_filename := "" }} +{{ $banner_config := index $design "banner" }} +{{ if and $banner_config (reflect.IsMap $banner_config) }} + {{ $banner_raw := index $banner_config "filename" }} + {{ if eq (printf "%T" $banner_raw) "string" }} + {{ $banner_filename = $banner_raw }} + {{ end }} +{{ end }} + +{{ $bio_style := "" }} +{{ $bio_config := index $design "biography" }} +{{ if and $bio_config (reflect.IsMap $bio_config) }} + {{ $bio_style_raw := index $bio_config "style" }} + {{ if eq (printf "%T" $bio_style_raw) "string" }} + {{ $bio_style = $bio_style_raw }} + {{ end }} +{{ end }} + +
+ {{/* Add subtle top gradient for navbar transition */}} +
+
+ + {{/* Left Column: Flexible span */}} +
+ + {{/* Banner Image */}} + {{ $img := "" }} + {{/* Resolve image from page bundle, site assets, remote, or static URLs */}} + {{ $image_resource := false }} + {{ $image_url := "" }} + + {{ if $banner_filename }} + {{ $image_path := strings.TrimSpace (printf "%v" $banner_filename) }} + {{ $is_remote := or (strings.HasPrefix $image_path "http://") (strings.HasPrefix $image_path "https://") }} + + {{ if $is_remote }} + {{ $remote := try (resources.GetRemote $image_path) }} + {{ if and $remote (not $remote.Err) }} + {{ $image_resource = $remote.Value }} + {{ else }} + {{ $image_url = $image_path }} + {{ end }} + {{ else }} + {{ $image_path = strings.TrimPrefix "/" $image_path }} + {{ $image_path = strings.TrimPrefix "./" $image_path }} + {{ $image_path = strings.TrimPrefix "assets/" $image_path }} + {{ $image_path = strings.TrimPrefix "media/" $image_path }} + {{ $normalized := path.Clean $image_path }} + + {{ 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 }} + {{ $image_url = printf "/media/%s" $normalized }} + {{ end }} + {{ end }} + {{ end }} + {{ end }} + + {{ $img = $image_resource }} + + {{ if $img }} +
+ {{ if ne $img.MediaType.SubType "gif" }} + {{ $responsive := partial "functions/process_responsive_image.html" (dict + "image" $img + "mode" "fill" + "aspect_ratio" "16:9" + "sizes" (slice 768 1024 1366 1920 2560) + ) }} + + {{ else }} + {{- $img = $img.Process "webp" -}} + + {{ end }} +
+ {{ else if $image_url }} + {{ $is_external := or (strings.HasPrefix $image_url "http://") (strings.HasPrefix $image_url "https://") }} +
+ +
+ {{ end }} + + {{/* Avatar */}} + {{ $status_icon := "" }} + {{ $status := $profile.status }} + {{ if and $status (reflect.IsMap $status) }} + {{ $status_icon_raw := index $status "icon" }} + {{ if eq (printf "%T" $status_icon_raw) "string" }} + {{ $status_icon = strings.TrimSpace $status_icon_raw }} + {{ end }} + {{ end }} + + {{ if $avatar }} +
+ {{ $avatar_image := $avatar.Fill (printf "%sx%s Center" $generation_size $generation_size) }} + {{$profile.title}} + {{ with $status_icon }}{{ . | emojify }}{{ end }} +
+ {{ end }} + + {{/* Name and Role - Centered */}} +
+ {{/* Extract pronunciation for ruby annotation */}} + {{ $name_pronunciation := "" }} + {{ with $profile.name_pronunciation }} + {{ if eq (printf "%T" .) "string" }} + {{ $name_pronunciation = strings.TrimSpace . }} + {{ end }} + {{ end }} + + {{/* Name with optional ruby pronunciation */}} + {{ if and $profile.title $name_pronunciation }} +

+ {{ $profile.title }}{{ $name_pronunciation }} +

+ {{ else }} +

+ {{ $profile.title }} +

+ {{ end }} + + {{ $pronouns := "" }} + {{ with $profile.pronouns }} + {{ if eq (printf "%T" .) "string" }} + {{ $pronouns = . }} + {{ end }} + {{ end }} + {{ with $pronouns }} +

({{ . }})

+ {{ end }} + + {{ $role_text := "" }} + {{ with $profile.role }} + {{ if eq (printf "%T" .) "string" }} + {{ $role_text = . }} + {{ end }} + {{ end }} + {{ with $role_text }} +

{{ . | markdownify | emojify }}

+ {{ end }} + + {{ $affiliations_raw := $profile.affiliations }} + {{ $affiliations := slice }} + {{ if reflect.IsSlice $affiliations_raw }} + {{ $affiliations = $affiliations_raw }} + {{ else if eq (printf "%T" $affiliations_raw) "string" }} + {{ $affiliations = slice $affiliations_raw }} + {{ end }} + {{ range $affiliations }} + {{ $aff_name := "" }} + {{ $aff_url := "" }} + {{ if reflect.IsMap . }} + {{ $nameRaw := index . "name" | default (index . "title") }} + {{ if ne $nameRaw nil }} + {{ $aff_name = printf "%v" $nameRaw }} + {{ end }} + {{ $urlRaw := index . "url" }} + {{ if eq (printf "%T" $urlRaw) "string" }} + {{ $aff_url = $urlRaw }} + {{ end }} + {{ else if eq (printf "%T" .) "string" }} + {{ $aff_name = . }} + {{ end }} + {{ $aff_name = strings.TrimSpace $aff_name }} + {{ $aff_url = strings.TrimSpace $aff_url }} + {{ if $aff_name }} +

+ {{ if $aff_url }} + {{ $link := $aff_url }} + {{ $scheme := (urls.Parse $link).Scheme }} + {{ $target := "" }} + {{ 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 }} + {{ $aff_name }} + {{ else }} + {{ $aff_name }} + {{ end }} +

+ {{ end }} + {{ end }} +
+ + {{/* Social Icons */}} + {{ $links_raw := $profile.links }} + {{ $links := slice }} + {{ if reflect.IsSlice $links_raw }} + {{ $links = $links_raw }} + {{ else if eq (printf "%T" $links_raw) "string" }} + {{ $links = slice $links_raw }} + {{ end }} + {{ if gt (len $links) 0 }} +
+ {{ range $links }} + {{ $linkUrl := "" }} + {{ $iconName := "hero/link" }} + {{ $linkLabel := "" }} + {{ if reflect.IsMap . }} + {{ $urlRaw := index . "url" | default (index . "link") }} + {{ if eq (printf "%T" $urlRaw) "string" }} + {{ $linkUrl = $urlRaw }} + {{ end }} + {{ $iconRaw := index . "icon" }} + {{ if eq (printf "%T" $iconRaw) "string" }} + {{ $iconName = $iconRaw }} + {{ end }} + {{ $labelRaw := index . "label" }} + {{ if eq (printf "%T" $labelRaw) "string" }} + {{ $linkLabel = $labelRaw }} + {{ end }} + {{ else if eq (printf "%T" .) "string" }} + {{ $linkUrl = . }} + {{ end }} + {{ $linkUrl = strings.TrimSpace $linkUrl }} + {{ if $linkUrl }} + {{ $scheme := (urls.Parse $linkUrl).Scheme }} + {{ $target := "" }} + {{ if not $scheme }} + {{ if not (hasPrefix $linkUrl "#") }} + {{ $linkUrl = $linkUrl | relLangURL }} + {{ end }} + {{ if eq (path.Ext $linkUrl) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }} + {{ else if in (slice "http" "https") $scheme }} + {{ $target = "target=\"_blank\" rel=\"noopener\"" }} + {{ end }} + + {{ partial "functions/get_icon" (dict "name" $iconName "attributes" "class=\"w-6 h-6\"") }} + + {{ end }} + {{ end }} +
+ {{ end }} +
+ + {{/* Right Column: Flexible span */}} +
+ + {{/* Bio Section */}} + {{ $bio_content := "" }} + {{ $bio_override_raw := index $content "text" }} + {{ if ne $bio_override_raw nil }} + {{ $bio_content = printf "%v" $bio_override_raw | emojify | $page.RenderString }} + {{ end }} + {{ if not $bio_content }} + {{ with $profile.bio }}{{ $bio_content = printf "%v" . | emojify | $page.RenderString }}{{ end }} + {{ end }} + {{ with $bio_content }} +
+
+
+ {{ partial "functions/get_icon" (dict "name" "identification" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }} +
+ {{ $i18n_about := i18n "about_me" }} + {{ $about_default := cond (eq $i18n_about "about_me") "Professional Summary" $i18n_about }} + {{ $about_heading := $about_default }} + {{ $about_heading_raw := index $headings "about" }} + {{ if eq (printf "%T" $about_heading_raw) "string" }} + {{ $about_heading_raw = strings.TrimSpace $about_heading_raw }} + {{ if ne $about_heading_raw "" }} + {{ $about_heading = $about_heading_raw }} + {{ end }} + {{ end }} +

{{ $about_heading }}

+
+
+
+ {{ . }} +
+
+
+ {{ end }} + + {{/* CV Download Buttons - supports singular "button" or plural "buttons" */}} + {{ $all_buttons := slice }} + {{ $button_raw := index $content "button" }} + {{ if and $button_raw (reflect.IsMap $button_raw) }} + {{ $all_buttons = slice $button_raw }} + {{ end }} + {{ $buttons_raw := index $content "buttons" }} + {{ if and $buttons_raw (reflect.IsSlice $buttons_raw) }} + {{ $all_buttons = $buttons_raw }} + {{ end }} + {{ if gt (len $all_buttons) 0 }} +
+ {{ range $all_buttons }} + {{ if reflect.IsMap . }} + {{ $button_text := "" }} + {{ $button_url := "" }} + {{ with index . "text" }}{{ $button_text = printf "%v" . }}{{ end }} + {{ with index . "url" }}{{ $button_url = printf "%v" . }}{{ end }} + {{ $button_text = strings.TrimSpace $button_text }} + {{ $button_url = strings.TrimSpace $button_url }} + {{ if and $button_text $button_url }} + {{ $button_link := $button_url }} + {{ $scheme := (urls.Parse $button_link).Scheme }} + {{ $target := "" }} + {{ if not $scheme }} + {{ if not (hasPrefix $button_link "#") }} + {{ $button_link = $button_link | relLangURL }} + {{ end }} + {{ if eq (path.Ext $button_link) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }} + {{ else if in (slice "http" "https") $scheme }} + {{ $target = "target=\"_blank\" rel=\"noopener\"" }} + {{ end }} + + {{ partial "functions/get_icon" (dict "name" "document-arrow-down" "attributes" "class='w-5 h-5 mr-3'") }} + {{ $button_text }} + + {{ end }} + {{ end }} + {{ end }} +
+ {{ end }} + + {{/* Education Section */}} + {{ $education_raw := $profile.education }} + {{ $education := slice }} + {{ if reflect.IsSlice $education_raw }} + {{ $education = $education_raw }} + {{ end }} + {{ if gt (len $education) 0 }} +
+
+
+ {{ partial "functions/get_icon" (dict "name" "academic-cap" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }} +
+ {{ $education_heading := i18n "education" }} + {{ $education_heading_raw := index $headings "education" }} + {{ if eq (printf "%T" $education_heading_raw) "string" }} + {{ $education_heading_raw = strings.TrimSpace $education_heading_raw }} + {{ if ne $education_heading_raw "" }} + {{ $education_heading = $education_heading_raw }} + {{ end }} + {{ end }} +

{{ $education_heading | markdownify }}

+
+
+ {{ range $education }} + {{ if reflect.IsMap . }} + {{ $degree := "" }} + {{ $degreeRaw := index . "degree" | default (index . "area") }} + {{ if ne $degreeRaw nil }}{{ $degree = printf "%v" $degreeRaw }}{{ end }} + {{ $year := "" }} + {{ with index . "year" }}{{ $year = printf "%v" . }}{{ end }} + {{ $start := "" }} + {{ with index . "start" }}{{ $start = printf "%v" . }}{{ end }} + {{ $end := "" }} + {{ with index . "end" }}{{ $end = printf "%v" . }}{{ end }} + {{ $institution := "" }} + {{ with index . "institution" }}{{ $institution = printf "%v" . }}{{ end }} + {{ $icon := "" }} + {{ $iconRaw := index . "icon" }} + {{ if eq (printf "%T" $iconRaw) "string" }} + {{ $icon = $iconRaw }} + {{ end }} +
+
+
+ {{ if $icon }} + {{ partial "functions/get_icon" (dict "name" $icon "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }} + {{ else }} + {{ partial "functions/get_icon" (dict "name" "academic-cap" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }} + {{ end }} +
+
+ {{ if $degree }} +

+ {{ $degree }} +

+ {{ end }} + {{ if $year }} +

{{ $year }}

+ {{ else if $start }} +

+ {{ $start }} + {{ if $end }}
{{ $end }}{{ end }} +

+ {{ end }} + {{ if $institution }} +

{{ $institution }}

+ {{ end }} +
+
+
+ {{ end }} + {{ end }} +
+
+ {{ end }} + + {{/* Interests Section */}} + {{ $interests_raw := $profile.interests }} + {{ $interests := slice }} + {{ if reflect.IsSlice $interests_raw }} + {{ $interests = $interests_raw }} + {{ else if eq (printf "%T" $interests_raw) "string" }} + {{ $interests = slice $interests_raw }} + {{ end }} + {{ if gt (len $interests) 0 }} +
+
+
+ {{ partial "functions/get_icon" (dict "name" "sparkles" "attributes" "class='w-6 h-6 text-primary-600 dark:text-primary-400'") }} +
+ {{ $interests_heading := i18n "interests" }} + {{ $interests_heading_raw := index $headings "interests" }} + {{ if eq (printf "%T" $interests_heading_raw) "string" }} + {{ $interests_heading_raw = strings.TrimSpace $interests_heading_raw }} + {{ if ne $interests_heading_raw "" }} + {{ $interests_heading = $interests_heading_raw }} + {{ end }} + {{ end }} +

{{ $interests_heading | markdownify }}

+
+
+ {{ range $interests }} + {{ $interest := strings.TrimSpace (printf "%v" .) }} + {{ if $interest }} + + {{ $interest | markdownify | emojify }} + + {{ end }} + {{ end }} +
+
+ {{ end }} +
+
+
+