From f81620a20f3c7f2c66300ade16a9d00cac23c7ac Mon Sep 17 00:00:00 2001 From: George Cushen Date: Sun, 7 Sep 2025 00:38:59 +0100 Subject: [PATCH] feat: modernize card view with 2025 design trends and smart metadata - Refactor card layout with glassmorphism, improved shadows, and micro-interactions - Add structured content_meta support (content_type, difficulty, prerequisites, trending) - Implement trending overlay badge on image with i18n support - Add configurable metadata display (show_date, show_read_time, show_read_more) - Optimize for mobile with responsive metadata hiding and layout stacking - Enhance image handling with fill_image toggle and AVIF/WebP support - Unify article-grid and card views for consistency across theme - Add reading time calculation and improved accessibility (ARIA labels, focus states) - Support primary color category pills and author avatars with proper sizing --- .../blox-tailwind/blox/collection/block.html | 9 +- modules/blox-tailwind/i18n/en.yaml | 17 ++ .../layouts/_partials/views/article-grid.html | 134 +----------- .../layouts/_partials/views/card--start.html | 2 +- .../layouts/_partials/views/card.html | 207 +++++++++++++++--- modules/blox-tailwind/layouts/list.html | 15 +- starters/academic-cv/content/_index.md | 32 +-- .../content/post/get-started/index.md | 6 + starters/academic-cv/content/projects.md | 3 + 9 files changed, 231 insertions(+), 194 deletions(-) diff --git a/modules/blox-tailwind/blox/collection/block.html b/modules/blox-tailwind/blox/collection/block.html index fb2c1c80..24413a63 100644 --- a/modules/blox-tailwind/blox/collection/block.html +++ b/modules/blox-tailwind/blox/collection/block.html @@ -103,7 +103,14 @@
- {{ $config := dict "columns" ($block.design.columns | default 2) "len" (len $query) "fill_image" ($block.design.fill_image | default true) }} + {{ $config := dict + "columns" ($block.design.columns | default 2) + "len" (len $query) + "fill_image" ($block.design.fill_image | default true) + "show_date" ($block.design.show_date | default true) + "show_read_time" ($block.design.show_read_time | default true) + "show_read_more" ($block.design.show_read_more | default true) + }} {{ partial "functions/render_view" (dict "fragment" "start" "page" $block "item" . "view" $view "config" $config) }} {{ range $index, $item := $query }} diff --git a/modules/blox-tailwind/i18n/en.yaml b/modules/blox-tailwind/i18n/en.yaml index 2818eb54..afb719e8 100644 --- a/modules/blox-tailwind/i18n/en.yaml +++ b/modules/blox-tailwind/i18n/en.yaml @@ -343,3 +343,20 @@ - id: feedback_widget_answer_negative translation: 😡 No + +# AI Features + +- id: ai_insight + translation: AI Insight + +# Content Metadata +- id: content_type + translation: Content Type +- id: difficulty + translation: Difficulty +- id: prerequisites + translation: Prerequisites + +# Card metadata +- id: trending + translation: Trending diff --git a/modules/blox-tailwind/layouts/_partials/views/article-grid.html b/modules/blox-tailwind/layouts/_partials/views/article-grid.html index 72aa115d..a88b9d1d 100644 --- a/modules/blox-tailwind/layouts/_partials/views/article-grid.html +++ b/modules/blox-tailwind/layouts/_partials/views/article-grid.html @@ -1,133 +1 @@ -{{ $item := .item }} -{{ $fill_image := .config.fill_image | default true }} - -{{ $resource := partial "functions/get_featured_image.html" $item }} -{{ $anchor := $item.Params.image.focal_point | default "Center" }} - -{{ $link := $item.Params.external_link | default $item.RelPermalink }} -{{ $target := "" }} -{{ if $item.Params.external_link }} - {{ $link = $item.Params.external_link }} - {{ $target = "target=\"_blank\" rel=\"noopener\"" }} -{{ end }} - -
- - {{ with $resource }} - {{/* Skip GIF processing */}} - {{ if ne .MediaType.SubType "gif" }} - {{/* Process original image first, then create responsive variants */}} - {{ $original_image := "" }} - {{if $fill_image}} - {{ $original_image = .Fill (printf "960x540 %s" $anchor) }} - {{else}} - {{ $original_image = .Fit (printf "960x540 %s" $anchor) }} - {{end}} - - {{ $responsive := partial "functions/process_responsive_image.html" (dict - "image" $original_image - "mode" "responsive" - "sizes" (slice 480 768 960 1200 1920) - ) }} - - {{ else }} - {{/* Handle GIF without processing */}} - - {{ end }} - {{end}} -
-
-
- {{ if and $item.Params.tags (gt (len $item.Params.tags) 0) }} - {{ range $index, $value := first 1 ($item.GetTerms "tags") }} - {{ .Page.LinkTitle }} - {{end}} - {{ end }} -
- -

- {{- $item.Title -}} - {{if $target}}{{ partial "functions/get_icon" (dict "name" "arrow-top-right-on-square" "attributes" "style=\"height: 1em;\" class=\"inline-flex h-6 w-6 pl-2\"") }}{{end}} - -

- - -
-
- - {{ if $item.Params.authors }} -
- {{ if and $item.Params.authors (gt (len $item.Params.authors) 0) }} - {{ range $index, $value := first 1 ($item.GetTerms "authors") }} -
- {{ $avatar := (.Resources.ByType "image").GetMatch "*avatar*" }} - {{ if $avatar }} - {{/* Use a single 2x retina source for a 20px display */}} - {{ $avatar_40 := $avatar.Process "Fill 40x40 Center webp" }} - avatar - {{ else }} - {{ warnf "An image named `avatar` was not found in the `%s` folder" $value.Path }} - {{ end }} -
- - {{- .Page.LinkTitle -}} - -
- {{end}} - {{ end }} - - • - {{end}} - -
-
- -
-
-
+{{- partial "views/card.html" . -}} diff --git a/modules/blox-tailwind/layouts/_partials/views/card--start.html b/modules/blox-tailwind/layouts/_partials/views/card--start.html index 05817b19..f24d47cb 100644 --- a/modules/blox-tailwind/layouts/_partials/views/card--start.html +++ b/modules/blox-tailwind/layouts/_partials/views/card--start.html @@ -1 +1 @@ -
+
diff --git a/modules/blox-tailwind/layouts/_partials/views/card.html b/modules/blox-tailwind/layouts/_partials/views/card.html index 75fd1a66..324ff2b2 100644 --- a/modules/blox-tailwind/layouts/_partials/views/card.html +++ b/modules/blox-tailwind/layouts/_partials/views/card.html @@ -9,36 +9,189 @@ {{ $resource := partial "functions/get_featured_image.html" $item }} {{ $anchor := $item.Params.image.focal_point | default "Center" }} +{{ $fill_image := .config.fill_image | default true }} +{{ $showDate := .config.show_date | default true }} +{{ $showReadTime := .config.show_read_time | default true }} +{{ $showReadMore := .config.show_read_more | default true }} +{{ $hasMeta := or $showDate $showReadTime $showReadMore }} +{{ $index := .index }} - -
-
+
+ + -
-
{{ $item.Title }}
-

- {{ ($item.Params.summary | default $item.Summary) | plainify | htmlUnescape | chomp -}} -

-

- {{- $item.Date | time.Format (site.Params.locale.date_format | default ":date_long") -}} + + +

+ {{ with $item.Params.content_meta }} + {{ if or .content_type .difficulty }} +
+ {{ with .content_type }} + + {{ . }} + + {{ end }} + {{ with .difficulty }} + {{ i18n "difficulty" }}: {{ . }} + {{ end }} +
+ {{ end }} + {{ end }} + + {{ if and $item.Params.tags (gt (len $item.Params.tags) 0) }} +
+ {{ with index ($item.GetTerms "tags") 0 }} + + + {{ .Page.LinkTitle }} + + + {{ end }} +
+ {{ end }} + +

+ + {{ $item.Title }} + {{ if $item.Params.external_link }} + {{ partial "functions/get_icon" (dict "name" "arrow-top-right-on-square" "attributes" "style=\"height: 1em;\" class=\"inline-flex h-4 w-4 ml-1 align-text-top\"") }} + {{ end }} + +

+ +

+ {{ ($item.Params.summary | default $item.Summary) | plainify | htmlUnescape | truncate 180 }}

+ + {{ with $item.Params.content_meta.prerequisites }} + {{ $max := 2 }} + {{ $count := len . }} +
+ {{ i18n "prerequisites" }}: + {{ range (first $max .) }} + {{ . }} + {{ end }} + {{ if gt $count $max }} + +{{ sub $count $max }} + {{ end }} +
+ {{ end }} + + +
+
+ {{ if $item.Params.authors }} +
+ {{ with index ($item.GetTerms "authors") 0 }} +
+ {{ $avatar := (.Resources.ByType "image").GetMatch "*avatar*" }} + {{ if $avatar }} + {{ $avatar_48 := $avatar.Process "Fill 48x48 Center webp" }} + avatar + {{ end }} +
+ {{ .Page.LinkTitle }} + {{ end }} +
+ • + {{ end }} + {{ if $showDate }} + + {{ end }} + {{ if and $showDate $showReadTime }} + + {{ end }} + {{ if $showReadTime }} + {{ $content := $item.Content | plainify }} + {{ $words := len (split $content " ") }} + {{ $readTime := div $words 200 }} + {{ if lt $readTime 1 }}{{ $readTime = 1 }}{{ end }} + + {{ end }} +
+ + + {{ if $showReadMore }} + + {{ i18n "read_more" }} + + + {{ end }} +
+ + + {{ if $item.Params.ai_insights }} +
+ + + + {{ i18n "ai_insight" }}: + {{ $item.Params.ai_insights }} +
+ {{ end }}
-
- +
\ No newline at end of file diff --git a/modules/blox-tailwind/layouts/list.html b/modules/blox-tailwind/layouts/list.html index c39b9ed5..6bcacf79 100644 --- a/modules/blox-tailwind/layouts/list.html +++ b/modules/blox-tailwind/layouts/list.html @@ -10,6 +10,16 @@ {{ $view := .Params.view | default "card" }} {{ $block := . }} +{{ $paginator := .Paginate .Pages.ByDate.Reverse }} +{{ $config := dict + "columns" (.Params.columns | default 2) + "len" (len $paginator.Pages) + "fill_image" (.Params.fill_image | default true) + "show_date" (.Params.show_date | default true) + "show_read_time" (.Params.show_read_time | default true) + "show_read_more" (.Params.show_read_more | default true) +}} + {{/* Check if any pages have author_notes to enable Alpine.js */}} {{ range .Pages }} {{ if isset .Params "author_notes" }} @@ -21,11 +31,10 @@
- {{ partial "functions/render_view" (dict "fragment" "start" "page" $block "item" . "view" $view) }} + {{ partial "functions/render_view" (dict "fragment" "start" "page" $block "item" . "view" $view "config" $config) }} - {{ $paginator := .Paginate .Pages.ByDate.Reverse }} {{ range $index, $item := $paginator.Pages }} - {{ partial "functions/render_view" (dict "page" . "item" . "view" $view "index" $index) }} + {{ partial "functions/render_view" (dict "page" . "item" . "view" $view "index" $index "config" $config) }} {{end}} {{ partial "functions/render_view" (dict "fragment" "end" "page" $block "item" . "view" $view) }} diff --git a/starters/academic-cv/content/_index.md b/starters/academic-cv/content/_index.md index 983e377b..5f943d8b 100644 --- a/starters/academic-cv/content/_index.md +++ b/starters/academic-cv/content/_index.md @@ -23,37 +23,12 @@ sections: education: '' interests: '' design: + # Apply a gradient background css_class: hbx-bg-gradient # Avatar customization avatar: size: medium # Options: small (150px), medium (200px, default), large (320px), xl (400px), xxl (500px) shape: circle # Options: circle (default), square, rounded - background: - #color: black - #image: - # RECOMMENDED: Modern gradient mesh backgrounds - # Option 1: Abstract neural network visualization (perfect for AI researchers) - # filename: https://images.unsplash.com/photo-1635070041078-e363dbe005cb - - # Option 2: Dark gradient mesh (sophisticated and modern) - # filename: https://images.unsplash.com/photo-1557683316-973673baf926 - - # Option 3: Subtle tech pattern (professional) - # filename: https://images.unsplash.com/photo-1451187580459-43490279c0fa - - # Current: Generic geometric pattern (consider upgrading) - #filename: stacked-peaks.svg - - # For best 2025 results, consider: - # 1. Using a CSS gradient instead (remove image section) - # 2. Implementing particle.js for interactive background - # 3. Using a subtle video background with neural network visualization - - #filters: - #brightness: 0.7 # Darkened for better text contrast - size: cover - position: center - parallax: false - block: markdown content: title: '📚 My Research' @@ -95,8 +70,7 @@ sections: folders: - event design: - view: article-grid - columns: 1 + view: card - block: collection id: news content: @@ -122,7 +96,7 @@ sections: order: desc design: # Choose a layout view - view: date-title-summary + view: card # Reduce spacing spacing: padding: [0, 0, 0, 0] diff --git a/starters/academic-cv/content/post/get-started/index.md b/starters/academic-cv/content/post/get-started/index.md index 36a12dc8..acf80715 100644 --- a/starters/academic-cv/content/post/get-started/index.md +++ b/starters/academic-cv/content/post/get-started/index.md @@ -16,6 +16,12 @@ tags: - Academic - Hugo Blox - Markdown + +content_meta: + # content_type: 'Tutorial' + # difficulty: 'Beginner' + prerequisites: ['Markdown'] + trending: true --- Welcome 👋 diff --git a/starters/academic-cv/content/projects.md b/starters/academic-cv/content/projects.md index cda3be10..3447b6a4 100644 --- a/starters/academic-cv/content/projects.md +++ b/starters/academic-cv/content/projects.md @@ -20,4 +20,7 @@ sections: view: article-grid fill_image: false columns: 3 + show_date: false + show_read_time: false + show_read_more: false ---