Có lẽ, cái duyên đưa tôi đến với thế giới mã nguồn mở cũng giống như cái duyên của một người thợ thủ công lần đầu chạm tay vào khối gỗ thô. Tôi không phải nhà văn, cũng chẳng phải một designer chuyên nghiệp với những bản vẽ hoàn hảo. Tôi chỉ là một người làm phần mềm, âm thầm ngồi hàng giờ trước màn hình, viết lên những dòng code với hy vọng tạo ra một không gian đẹp đẽ, dung dị và đầy cảm xúc cho cộng đồng Blogger Việt Nam. Và Opsoso Handmade – bản template mã nguồn mở này – chính là đứa con tinh thần mà tôi ấp ủ suốt nhiều tháng qua.
Hôm nay, ngồi trước màn hình với file opsoso_handmade.xml
đã hoàn thiện, tôi muốn viết một bài luận, không quá văn hoa, nhưng
thật lòng, để kể câu chuyện về template này. Hành trình của nó không chỉ
là chuyện code, mà là chuyện về sự trăn trở, về những đêm thức trắng,
về niềm vui khi nhìn thấy giao diện đầu tiên hiện ra trên trình duyệt
với đúng những gì mình mơ ước.
Trước khi bắt tay vào viết Opsoso Handmade, tôi đã dành rất nhiều thời gian để lướt qua hàng trăm blog cá nhân, shop bán hàng nhỏ lẻ, hay các trang giới thiệu sản phẩm thủ công mỹ nghệ. Tôi nhận ra một điều: đa số họ đang sử dụng những template đại trà, có sẵn, nhanh, gọn, nhưng thiếu vắng hoàn toàn cái hồn. Một người bán gốm sứ, một người làm nến thơm, một bạn trẻ bán tranh thêu tay… tất cả đều phải dùng chung một kiểu giao diện vuông vức, lạnh lẽo, không hề có chút “thủ công” nào trong đó.
Tôi tự hỏi: Tại sao không có một template Blogger nào thực sự tôn vinh vẻ đẹp mộc mạc, giản dị nhưng vẫn hiện đại, vẫn đủ chức năng để bán hàng, viết blog, và kể chuyện? Và câu hỏi ấy cứ lớn dần lên, ám ảnh tôi mỗi khi đi ngủ. Cuối cùng, tôi quyết định: tự mình làm một cái.
Opsoso Handmade ra đời từ chính nỗi đau ấy. Không phải nỗi đau thể xác, mà là nỗi đau của một kẻ làm nghề, nhìn thấy vẻ đẹp tiềm ẩn của những đôi bàn tay nhưng không có đủ “phần cứng” để phô diễn nó. Tôi muốn template này phải thật sự là một ngôi nhà cho những người yêu handmade. Ngôi nhà ấy phải ấm cúng, phải có ánh sáng, phải có những góc nhỏ để trưng bày sản phẩm, và quan trọng nhất, phải dễ dàng tùy biến ngay cả với người không biết gì về code.
Khi bắt đầu viết những dòng CSS đầu tiên, tôi đã xác định rõ triết lý xuyên suốt: “Trao gửi yêu thương”. Không chỉ là cái tên đặt trong biến hero.title, đó là kim chỉ nam cho mọi quyết định thiết kế.
1. Bảng màu – Chạm vào cảm xúc
Thay vì những gam màu neon chói mắt hay xanh – đỏ – tím – vàng loè loẹt, tôi chọn bảng màu trầm ấm: màu nâu đất #8b5e3c làm chủ đạo, kết hợp với nền #f8f5f0 như màu của giấy dó, của vải thô, của đất sét sau khi nung. Màu chữ #5c3d2e đủ đậm để đọc rõ, nhưng không gây mỏi mắt sau nhiều giờ lướt web.
Tôi cố tình đặt các biến màu trong thẻ <Variable>
để người dùng sau này có thể thoải mái thay đổi chỉ bằng vài cú click
trong Blogger Theme Designer. Một người bán gốm có thể muốn tông màu
xanh ngọc, một người bán đồ len có thể thích hồng pastel – tất cả đều có
thể làm được mà không cần động đến code.
2. Typography – Nét chữ cũng là nét vẽ
Tôi mê mẩn font chữ Playfair Display ngay từ lần đầu nhìn thấy nó. Những đường nét thanh mảnh ở phần serif, sự cổ điển pha chút hiện đại, tất cả đều khiến tôi nghĩ ngay đến những bức thư pháp viết tay. Vì thế, tôi dành riêng font này cho tiêu đề, cho logo, cho những điểm nhấn quan trọng. Phần nội dung còn lại, tôi dùng hệ thống font hệ thống (system-ui, -apple-system) để đảm bảo tốc độ tải trang nhanh nhất có thể.
Tôi vẫn nhớ cảm giác hồi hộp khi lần đầu tiên áp dụng hiệu ứng -webkit-background-clip: text
lên logo, để dòng chữ “OPSOSO handmade” óng ánh chuyển sắc giữa màu nâu
chủ đạo và ánh đồng. Nó đẹp một cách lặng lẽ, không phô trương, như
chính những sản phẩm thủ công vậy.
3. Bố cục – Thoáng mà không trống trải
Một trong những thách thức lớn nhất là làm sao để template vừa hiện đại (theo xu hướng Web 3.0 với nhiều khoảng trắng, card bo góc, hiệu ứng mờ kính), vừa giữ được cảm giác “handmade” ấm cúng.
Tôi đã phải viết đi viết lại phần header đến 5 lần. Ban đầu, tôi để logo bên trái, menu bên phải, nhưng cảm giác nó quá giống một template doanh nghiệp. Tôi thử đưa logo ra giữa, menu hai bên, nhưng lại rối mắt. Cuối cùng, tôi chọn giải pháp logo trái – icon trung tâm – menu phải. Icon trung tâm chính là điểm nhấn, nơi người dùng có thể upload logo shop dạng ảnh PNG/ICO với kích thước lớn, vượt ra ngoài biên giới của header, tạo hiệu ứng chồng lớp (overlap) cực kỳ tinh tế.
Có những đêm chỉ để canh chỉnh vị trí của .center-logo-wrapper sao cho nó nằm chính giữa, không bị lệch dù 1px trên màn hình 4K hay trên điện thoại iPhone SE. Tôi đặt z-index: 1020 để nó nổi trên tất cả, như một biểu tượng thiêng liêng của thương hiệu.
Nếu ai đó hỏi tôi: “Phần nào khó nhất trong template này?”, tôi sẽ trả lời không do dự: Menu. Blogger nguyên bản không hỗ trợ dropdown menu, huống chi là dropdown 3 cấp. Tôi đã phải nghĩ ra một giải pháp “độc” và “dị”.
Tôi tận dụng chính widget LinkList vốn chỉ hiển thị danh sách link đơn thuần. Bằng cách thêm tiền tố _ và __ vào tên các mục, tôi dùng JavaScript để phân tích cấu trúc và tự động xây dựng lại thành menu cha – con – cháu.
Nhìn có vẻ đơn giản, nhưng để làm được điều đó, tôi đã phải:
Viết một vòng lặp để duyệt qua từng item.
Xác định cấp độ dựa trên số lượng dấu gạch dưới.
Tạo các thẻ
<ul>động và gắn chúng vào đúng vị trí.Đảm bảo toàn bộ quá trình này không làm ảnh hưởng đến SEO.
Style lại từ A-Z để dropdown trông như những tấm card nổi, có bóng đổ, bo góc, và hiệu ứng hover mượt mà.
Tôi nhớ cái đêm tôi hoàn thành xong phần submenu cấp 3. Lúc đó là 3 giờ sáng. Tôi rê chuột vào menu “Sản phẩm” → “Quà tặng” → “Giáng sinh”, và chiếc submenu hiện ra nhẹ nhàng, đúng vị trí. Tôi đã reo lên sung sướng, dù căn phòng chỉ có một mình và màn hình máy tính. Cảm giác đó, nó giống như người thợ mộc cuối cùng cũng ráp xong cái chân bàn thứ tư, đặt nó xuống sàn và thấy nó không hề bị cập kênh.
Phần hero (phần lớn đầu trang) là thứ tôi dành nhiều tâm huyết nhất về mặt cảm xúc. Tôi muốn nó không chỉ là một cái ảnh nền với dòng chữ to đùng. Tôi muốn nó phải kể một câu chuyện.
Tôi cài sẵn một bức ảnh mặc định từ Unsplash – một bàn tay đang tỉ mẩn làm đồ gốm. Nhưng tôi cũng cho phép người dùng upload ảnh của chính họ thông qua widget Image. Ảnh sẽ được tự động gán làm background thông qua inline style, không cần động tay vào code.
Tiêu đề, phụ đề và nút kêu gọi hành động được đặt trong các biến skin, nhưng nếu người dùng nhập nội dung vào widget, nội dung đó sẽ được ưu tiên. Điều này tạo ra một luồng dữ liệu linh hoạt: người mới có thể dùng ngay mặc định, người chuyên sâu có thể tùy chỉnh.
Một điểm thú vị khác là tôi có tích hợp một đoạn JavaScript nhỏ xử lý dấu |
trong caption. Nếu người dùng viết caption có chứa dấu sổ dọc, phần bên
trái sẽ là phụ đề, phần bên phải sẽ tự động chuyển thành chữ trên nút
bấm. Ví dụ: “Sưu tập mới | Khám phá ngay”
– ngay lập tức nút bấm sẽ hiển thị “Khám phá ngay”. Đây là một “easter
egg” nho nhỏ tôi dành cho những ai chịu khó đọc document.
Một template Blogger tốt không chỉ nằm ở giao diện, mà còn ở khả năng mở rộng. Tôi đã chia bố cục thành nhiều section nhỏ, mỗi section là một <b:section> riêng biệt, cho phép người dùng thoải mái thêm, bớt, sắp xếp widget.
Shop Intro – Sự kết hợp giữa ảnh và chữ
Đây là layout 2 cột điển hình: một bên là ảnh lớn, một bên là văn bản giới thiệu. Nhưng tôi không muốn nó nhàm chán. Tôi thêm hiệu ứng phóng nhẹ khi hover vào ảnh, và một vệt gạch chân động cho tiêu đề. Chỉ một chút thôi, nhưng cảm giác “sống” và “chuyển động” đã rõ rệt hơn nhiều.
Shop Features – Những cam kết bằng cả trái tim
Ba widget HTML trong mục này thực chất là ba feature card. Tôi đã viết sẵn nội dung minh họa: “100% Thủ công”, “Vật liệu Tự nhiên”, “Quà tặng Ý nghĩa”. Icon cảm xúc (❤, 🌿, 🎁) được đặt trong một vòng tròn, và khi hover, vòng tròn ấy xoay nhẹ, đổi màu.
Tôi đã cân nhắc rất nhiều giữa việc dùng icon font và dùng emoji. Cuối cùng tôi chọn emoji, vì nó đơn giản, không cần tải thêm tài nguyên, và quan trọng nhất – nó rất “handmade”. Một trái tim màu đỏ trong icon vector có thể sắc sảo hơn, nhưng một trái tim emoji… nó thật hơn.
Main Section – Nơi blog và shop hòa quyện
Tôi đã đặt widget Blog1 trong khu vực main-section-container.
Điều này có nghĩa là trang chủ sẽ hiển thị danh sách bài viết dưới dạng
lưới (grid), mỗi bài viết là một card sản phẩm. Nếu bài viết có ảnh,
ảnh sẽ được lấy làm background; nếu không, sẽ có một mảng màu xám trung
tính.
Điều đặc biệt:
khi người dùng click vào bài viết và xem ở chế độ chi tiết (Single
Item), giao diện sẽ tự động chuyển sang một layout khác hẳn. Tiêu đề to,
nội dung rộng rãi, căn lề thoáng, và tất cả các phần “trang trí” như
hero, shop intro, features đều biến mất. Tôi dùng bộ chọn body.view-item để ẩn chúng đi, chỉ giữ lại nội dung bài viết và footer. Đây là cách tôi tôn trọng sự tập trung của độc giả.
Đây là một trong những tính năng tôi tự hào nhất. Nó giải quyết bài toán mà rất nhiều người dùng Blogger gặp phải: làm sao để lấy bài viết bất kỳ làm sản phẩm nổi bật mà không cần cài plugin?
Giải pháp của tôi: sử dụng widget LinkList ở phần "Sản phẩm nổi bật". Người dùng chỉ cần dán link bài viết vào LinkList, template sẽ tự động:
Gọi API JSON của Blogger.
Lấy tiêu đề và ảnh đại diện.
Ép ảnh về kích thước lớn (s1600) để hiển thị sắc nét.
Gắn badge “Nổi bật” lên góc phải.
Xóa hiệu ứng loading shimmer.
Tôi
biết cách làm này không phải chưa từng xuất hiện. Nhưng tôi đã tinh
chỉnh nó để hoạt động mượt mà, ít xung đột, và đặc biệt là tương thích
với cả bài viết thường (/posts/) lẫn trang tĩnh (/p/).
Lần đầu tiên tôi test thành công tính năng này, tôi cảm thấy như mình vừa tìm ra một cánh cửa bí mật. Tôi gọi nó là “cầu nối giữa blog và shop”. Bởi vì nhờ nó, một blog cá nhân hoàn toàn có thể biến thành một gian hàng xinh xắn mà không cần đến các nền tảng thương mại điện tử phức tạp.
Kỷ nguyên di động đã đến. Tôi không thể cho phép template của mình vỡ layout trên điện thoại.
Tôi
đã dành ra ba ngày chỉ để test responsive. Mỗi khi thấy một lỗi nhỏ –
ví dụ như menu bị tràn ra ngoài, hay logo trung tâm quá to so với màn
hình nhỏ – tôi lại ngồi chỉnh sửa, căn chỉnh lại @media (max-width: 992px).
Tôi quyết định ẩn toàn bộ menu trên mobile (và hy vọng trong tương lai sẽ bổ sung thêm nút hamburger), nhưng giữ lại logo trung tâm với kích thước thu nhỏ. Các card sản phẩm chuyển từ 3 cột xuống 1 cột, shop intro chuyển từ 2 cột ngang thành xếp chồng dọc.
Tôi cũng dành thời gian để tối ưu hiệu ứng backdrop-filter
trên header. Trên máy tính, hiệu ứng mờ kính (blur) rất đẹp; nhưng trên
một số trình duyệt di động cũ, nó có thể gây giật lag. Vì vậy, tôi chấp
nhận đánh đổi: mobile sẽ hiển thị màu nền trắng đục thay vì hiệu ứng
kính mờ. Quan trọng là trải nghiệm phải mượt mà.
Là một người phát triển mã nguồn mở, tôi luôn đặt câu hỏi: “Người dùng của tôi có dễ dàng sử dụng không?”
Vì thế, trong toàn bộ template, tôi cố gắng:
Đặt tên section rõ ràng:
header-logo,header-center,header-menu,shop-intro,shop-features… Bất cứ ai vào phần Layout của Blogger cũng có thể hiểu ngay vùng nào dùng để làm gì.Cung cấp nội dung mặc định: Nếu người dùng cài template lên mà chưa kịp thêm ảnh, họ vẫn có một blog đẹp với ảnh mẫu, chữ mẫu.
Giấu code phức tạp: Những phần JavaScript phức tạp (như xử lý menu, fetcher dữ liệu) tôi đặt ngay trong file XML, người dùng không cần phải copy thêm bất cứ thứ gì.
CSS động: Sử dụng biến
--scroll-widthđể tạo thanh tiến trình cuộn, vừa đẹp mắt vừa dễ bảo trì.
Tôi cũng dành thời gian để viết document. Không phải document kỹ thuật dài dòng, mà là những dòng hướng dẫn ngắn gọn trong chính file XML, dưới dạng comment. Ai mở file lên cũng có thể đọc và hiểu.
Opsoso Handmade phiên bản 1.0 này chưa hoàn hảo. Tôi biết điều đó.
Menu trên di động hiện tại bị ẩn đi, đó là một thiếu sót. Tôi đang ấp ủ ý tưởng về một nút hamburger với animation mượt mà, nhưng vì muốn release sớm để cộng đồng dùng thử, tôi tạm thời để nguyên như vậy.
Tính năng tìm kiếm cũng chưa được thiết kế riêng. Hiện tại nó vẫn là ô tìm kiếm mặc định của Blogger. Tôi hy vọng ở bản cập nhật tiếp theo, tôi có thể biến nó thành một thanh tìm kiếm floating, hiện ra khi click vào icon kính lúp.
Và một điều nữa: tôi vẫn chưa hài lòng lắm về phần hiển thị comment. Tôi muốn nó giống như một cuộc trò chuyện thực sự, với avatar tròn, khung chat bo góc, nhưng vẫn phải đảm bảo tốc độ tải trang.
Tôi sẽ không dừng lại. Template này là mã nguồn mở, và tôi sẽ tiếp tục phát triển nó cùng với những góp ý từ cộng đồng. Bất kỳ ai cũng có thể fork, cải tiến, gửi pull request. Đó là vẻ đẹp của mã nguồn mở, và cũng là vẻ đẹp của handmade – mỗi người góp một mảnh ghép, tạo nên bức tranh lớn hoàn chỉnh.
Tôi viết những dòng này khi file opsoso_handmade.xml
đã sẵn sàng để gửi lên GitHub. 5.236 dòng code, hơn 3 tháng làm việc
gián đoạn, vô số lần debug trong nước mắt, và cũng vô số lần cười một
mình khi code chạy đúng như ý muốn.
Tôi không biết template này sẽ đến được với bao nhiêu người. Có thể chỉ vài chục, vài trăm, hoặc có thể chẳng ai dùng. Nhưng tôi tin, trong số những người vô tình ghé qua kho mã nguồn của tôi, sẽ có một bạn trẻ đang muốn mở shop bán nến thơm, một cô giáo về hưu muốn viết blog về vườn rau sạch, một anh thợ mộc muốn giới thiệu những sản phẩm từ gỗ tái chế. Họ cần một nơi để kể câu chuyện của mình. Và tôi hy vọng, Opsoso Handmade sẽ là một phần nhỏ trong câu chuyện đó.
Template này tôi viết bằng tình yêu dành cho những người làm nghề thủ công, những người luôn tỉ mẩn, nhẫn nại, và trân trọng từng chi tiết nhỏ. Tôi không có xưởng gốm, không có bàn thêu, nhưng tôi có bàn phím. Và tôi đã dùng nó để tạo ra một sản phẩm thủ công theo cách của riêng mình.
Opsoso Handmade – Trao gửi yêu thương, từ những dòng code.
📥 Tải ngay và trải nghiệm
Bạn có thể xem trực tiếp bản demo và tải về sử dụng hoàn toàn miễn phí tại cộng đồng Opsoso.net. Đừng ngần ngại thay đổi diện mạo mới cho "đứa con tinh thần" của mình ngay hôm nay!
Tải tại đây hoặc tại đây
Phát hành bởi: Opsoso.net