feat: implement hero-style header for standard posts and add mobile-responsive sidebar hiding.

This commit is contained in:
2026-07-20 17:46:40 +07:00
parent d6d722386f
commit 7d937a71f8
4 changed files with 152 additions and 234 deletions
@@ -554,4 +554,12 @@ body, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
.lc--layout-container ol li, .lc--layout-container ul li, .sg-pattern-example ol li, .sg-pattern-example ul li {
font-weight: var(--font-weight-extrabold);
}
/* Hide widget column on mobile */
@media (max-width: 768px) {
.events-column,
.widget-sidebar-area {
display: none !important;
}
}
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{fragments/layout}">
layout:decorate="~{themes/umass/layout}">
<head>
<title th:text="${post.title} + ' | UMass Amherst'">Post Title | UMass Amherst</title>
@@ -8,35 +8,63 @@
</head>
<body>
<div layout:fragment="content">
<div id="block-umass-base-content" class="block block-system block-system-main-block tc--template-container tc--article">
<div class="t--template t--article">
<div layout:fragment="content-top">
<!-- Content Top (Banner 3 lớp kết hợp Title bài Post) -->
<div class="content-top">
<div class="lc--layout-container lc--full">
<div class="l--layout l--full">
<div class="lr--layout-region lr--main">
<div class="cc--component-container cc--homepage-hero">
<div class="c--component c--homepage-hero"
style="position: relative; overflow: hidden; height: 100vh; max-height: 38.125rem;">
<!-- Content Top (e.g. Hero Image & Title) -->
<div class="content-top">
<div class="lc--layout-container lc--full">
<div class="l--layout l--full">
<div class="lr--layout-region lr--main">
<div class="cc--component-container cc--hero-article">
<div class="c--component c--hero-article">
<div class="f--field f--image" th:if="${post.featuredImage != null and !post.featuredImage.isEmpty()}">
<img th:src="${post.featuredImage}" th:alt="${post.title}">
</div>
<div class="text-container">
<div class="f--field f--eyebrow" th:if="${post.category != null}" th:text="${post.category.name}">
University News
</div>
<div class="f--field f--page-title">
<h1 th:text="${post.title}">Post Title</h1>
<!-- ====== ẢNH NỀN (Dùng ảnh bài viết hoặc ảnh mặc định) ====== -->
<img class="static-fallback-image" th:src="${post.featuredImage != null and !post.featuredImage.isEmpty() ? post.featuredImage : 'https://res.cloudinary.com/ipufdhda/image/upload/v1784534008/BANNER-WEB-scaled_yeox4u.jpg'}" th:alt="${post.title}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1;" />
<!-- ====== TEXT OVERLAY (Nội dung chữ nằm trên ảnh, Hiển thị Tiêu đề bài viết) ====== -->
<!-- Thêm một lớp nền mờ (rgba đen) để chữ luôn hiển thị rõ ràng trên mọi hình ảnh -->
<div class="text-container centered"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 4; pointer-events: none; display: flex; align-items: center; justify-content: center; background-color: rgba(0, 0, 0, 0.4);">
<div class="slide-text-container-inner" style="pointer-events: auto; text-align: center; padding: 20px;">
<div class="f--field f--eyebrow" th:if="${post.category != null}" th:text="${post.category.name}" style="color: white; text-shadow: 0 2px 5px rgba(0,0,0,0.7); margin-bottom: 10px; font-weight: bold; text-transform: uppercase;">
University News
</div>
<div class="f--field f--page-title">
<h1 class="hero-post-title" th:text="${post.title}">Post Title</h1>
</div>
</div>
</div>
<style>
.hero-post-title {
color: white;
text-shadow: 0 2px 5px rgba(0,0,0,0.7);
line-height: 1.2;
margin: 0 auto;
max-width: 1000px;
font-size: 3.5rem;
}
@media (max-width: 1024px) {
.hero-post-title { font-size: 2.8rem; max-width: 800px; }
}
@media (max-width: 768px) {
.hero-post-title { font-size: 2.2rem; max-width: 600px; }
}
@media (max-width: 480px) {
.hero-post-title { font-size: 1.8rem; }
}
</style>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div layout:fragment="content">
<div id="block-umass-base-content" class="block block-system block-system-main-block tc--template-container tc--article">
<div class="t--template t--article">
<!-- Content Main (Two Column Layout with Sidebar) -->
<div class="content-main">
<div class="lc--layout-container lc--two-column">
@@ -57,23 +85,52 @@
</div>
<div class="cc--component-container cc--share-block ">
<div class="c--component c--share-block">
<div data-component-id="umass_base:section-title" class="f--section-title">
<h2>Share This</h2>
<div class="f--section-title">
<h2 style="color: #881c1c; font-size: 1rem; font-weight: 700; text-transform: uppercase; margin-bottom: 20px;">Share This</h2>
</div>
<ul class="social-media-links--platforms a2a_kit a2a_default_style" style="line-height: 16px;">
<style>
.custom-share-list {
list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 15px; align-items: flex-start;
}
.custom-share-list li a {
display: flex; align-items: center; justify-content: center; width: 45px; height: 45px; border-radius: 50%; border: 1px solid #111; text-decoration: none; transition: all 0.2s;
}
.custom-share-list li a:hover {
background-color: #f5f5f5;
}
.custom-share-list li a svg {
width: 18px; height: 18px;
}
</style>
<ul class="custom-share-list">
<li>
<a class="fa a2a_button_facebook facebook" aria-label="Share on Facebook" target="_blank" href="#" rel="nofollow noopener">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 19" fill="currentColor" aria-hidden="true"><path fill="#1877f2" d="M18,0H1.1C0.5,0,0,0.5,0,1.1V18c0,0.6,0.5,1,1.1,1h9.1v-7.3H7.7V8.8h2.5V6.7c0-2.5,1.5-3.8,3.7-3.8c0.7,0,1.5,0,2.2,0.1v2.6h-1.5c-1.2,0-1.4,0.6-1.4,1.4v1.8H16l-0.4,2.9h-2.5V19H18c0.6,0,1-0.5,1-1V1.1C19,0.5,18.5,0,18,0z"></path></svg>
<a href="#" aria-label="Website">
<svg viewBox="0 0 512 512" fill="#28a745"><path d="M352 256c0 22.2-1.2 43.6-3.3 64H163.3c-2.2-20.4-3.3-41.8-3.3-64s1.2-43.6 3.3-64h185.4c2.2 20.4 3.3 41.8 3.3 64zm28.8-64h123.1c5.3 20.5 8.1 41.9 8.1 64s-2.8 43.5-8.1 64H380.8c2.1-20.6 3.2-41.9 3.2-64s-1.1-43.4-3.2-64zm112.6-32H376.7c-10-63.9-29.8-117.4-55.3-151.6c78.3 20.7 142 77.5 171.9 151.6zm-149.1 0H167.7c16.1-70.4 46.2-128 88.3-128s72.2 57.6 88.3 128zM256 480c-42.1 0-72.2-57.6-88.3-128h176.6c-16.1 70.4-46.2 128-88.3 128zM144 141.6C118.5 175.8 98.7 229.3 88.7 293.2H18.6C48.5 219.1 112.2 162.3 190.5 141.6h-46.5zM18.6 325.2H88.7c10 63.9 29.8 117.4 55.3 151.6c-78.3-20.7-142-77.5-171.9-151.6zM131.2 256c0-22.1 1.1-43.4 3.2-64H11.3C6 212.5 3.2 233.9 3.2 256s2.8 43.5 8.1 64h123.1c-2.1-20.6-3.2-41.9-3.2-64z"/></svg>
</a>
</li>
<li>
<a class="fa a2a_button_x x" aria-label="Share on X" target="_blank" href="#" rel="nofollow noopener">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 -2 50 50" fill="currentColor" aria-hidden="true"><path fill="#111111" d="M5.9199219 6L20.582031 27.375L6.2304688 44h3.1796874L21.986328 29.421875L31.986328 44H44L28.681641 21.669922L42.199219 6h-3.169922L27.275391 19.617188L17.933594 6z"></path></svg>
<a aria-label="Share on Facebook" target="_blank" href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 19" fill="#1877f2"><path d="M18,0H1.1C0.5,0,0,0.5,0,1.1V18c0,0.6,0.5,1,1.1,1h9.1v-7.3H7.7V8.8h2.5V6.7c0-2.5,1.5-3.8,3.7-3.8c0.7,0,1.5,0,2.2,0.1v2.6h-1.5c-1.2,0-1.4,0.6-1.4,1.4v1.8H16l-0.4,2.9h-2.5V19H18c0.6,0,1-0.5,1-1V1.1C19,0.5,18.5,0,18,0z"></path></svg>
</a>
</li>
<li>
<a class="fa a2a_button_linkedin linkedin" aria-label="Share on LinkedIn" target="_blank" href="#" rel="nofollow noopener">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 448 512" fill="currentColor" aria-hidden="true" focusable="false"><path fill="#0a66c2" d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"></path></svg>
<a aria-label="Share on X" target="_blank" href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -2 50 50" fill="#111111"><path d="M5.9199219 6L20.582031 27.375L6.2304688 44h3.1796874L21.986328 29.421875L31.986328 44H44L28.681641 21.669922L42.199219 6h-3.169922L27.275391 19.617188L17.933594 6z"></path></svg>
</a>
</li>
<li>
<a aria-label="Share on LinkedIn" target="_blank" href="#">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" fill="#0a66c2"><path d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"></path></svg>
</a>
</li>
<li>
<a aria-label="Email" href="mailto:">
<svg viewBox="0 0 512 512" fill="#881c1c"><path d="M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0L492.8 150.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48H48zM0 176V384c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V176L294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176z"/></svg>
</a>
</li>
<li>
<a aria-label="Print" href="javascript:window.print()">
<svg viewBox="0 0 512 512" fill="#111"><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H384v96h64V64c0-35.3-28.7-64-64-64H128zM18.6 243.4c-11.7 5.1-18.6 16.6-18.6 29C0 293.7 17.3 311 38.6 311H473.4c21.3 0 38.6-17.3 38.6-38.6c0-12.4-6.9-23.9-18.6-29l-38.2-16.7C442.2 221.7 430.7 216 418.5 216H93.5c-12.2 0-23.7 5.7-29.2 15.2L18.6 243.4zM160 384h192c17.7 0 32-14.3 32-32V256c0-17.7-14.3-32-32-32H160c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32zM0 400c0 35.3 28.7 64 64 64h48v32c0 8.8 7.2 16 16 16h256c8.8 0 16-7.2 16-16v-32h48c35.3 0 64-28.7 64-64v-16H0v16z"/></svg>
</a>
</li>
</ul>
@@ -20,24 +20,34 @@
<div class="dialog-off-canvas-main-canvas" data-off-canvas-main-canvas="">
<!-- Include Header Fragment -->
<header th:replace="~{themes/__${activeTheme}__/header :: header}"></header>
<!-- Full-width top content area (e.g., Hero Banners) -->
<div layout:fragment="content-top"></div>
<main id="main-content">
<div class="l--content">
<div class="content">
<div class="region region-content r--region r--content">
<!-- Content Area -->
<div th:with="isFullWidth=${(page != null and page.layout != null and page.layout.name() == 'FULL_WIDTH') or (post != null and post.layout != null and post.layout.name() == 'FULL_WIDTH')}" th:style="${isFullWidth} ? 'min-height: 400px;' : 'display: flex; min-height: 400px; padding: 20px; max-width: 1400px; margin: 0 auto;'">
<div th:style="${isFullWidth} ? 'width: 100%;' : 'flex: 3; padding-right: 20px;'" layout:fragment="content"></div>
<aside th:unless="${isFullWidth}" style="flex: 1; padding: 15px; border-radius: 5px;">
<h4>Sidebar</h4>
<div th:each="widget : ${sidebarWidgets}" style="margin-bottom: 20px;">
<h5 th:text="${widget.title}" style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">Widget Title</h5>
<div th:if="${widget.type == 'HTML'}" th:utext="${widget.content}"></div>
<div th:if="${widget.type == 'TEXT'}" th:text="${widget.content}"></div>
</div>
<div th:if="${sidebarWidgets == null || sidebarWidgets.empty}">
<p>No widgets added to sidebar.</p>
</div>
<div class="responsive-flex-container" th:with="isFullWidth=${(page != null and page.layout != null and page.layout.name() == 'FULL_WIDTH') or (post != null and post.layout != null and post.layout.name() == 'FULL_WIDTH')}" th:style="${isFullWidth} ? 'min-height: 400px;' : 'display: flex; min-height: 400px; padding: 20px; max-width: 1400px; margin: 0 auto;'">
<div class="responsive-flex-content" th:style="${isFullWidth} ? 'width: 100%;' : 'flex: 3; padding-right: 20px;'" layout:fragment="content"></div>
<aside class="widget-sidebar-area" th:unless="${isFullWidth}" style="flex: 1; padding: 15px; border-radius: 5px;">
<th:block th:if="${sidebarWidgets != null and !sidebarWidgets.empty}">
<h4>Sidebar</h4>
<div th:each="widget : ${sidebarWidgets}" style="margin-bottom: 20px;">
<h5 th:text="${widget.title}" style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">Widget Title</h5>
<div th:if="${widget.type == 'HTML'}" th:utext="${widget.content}"></div>
<div th:if="${widget.type == 'TEXT'}" th:text="${widget.content}"></div>
</div>
</th:block>
</aside>
<style>
@media (max-width: 768px) {
.widget-sidebar-area { display: none !important; }
.responsive-flex-container { flex-direction: column !important; padding: 10px !important; }
.responsive-flex-content { padding-right: 0 !important; width: 100% !important; }
}
</style>
</div>
</div>
</div>