OPSOSO_BASIC: THEME BLOGGER TỐI GIẢN

Tôi là opsoso.net. Có thể bạn chưa từng nghe tên tôi, cũng có thể bạn đã vô tình ghé qua một blog nào đó, nơi những dòng code của tôi lặng lẽ chạy, và bạn đã đọc một bài viết mà không hề biết rằng khung nền trắng, những con chữ đen huyền, hay những tấm ảnh thú cưng đang hiện ra trước mắt bạn, tất cả đều được sinh ra từ một tệp tin XML mang tên opsoso_basic.xml.

Tôi viết template này không phải để cạnh tranh với những bộ giao diện "khủng" đầy hiệu ứng phức tạp, cũng chẳng phải để chứng tỏ tôi là ai. Tôi viết nó vì một lý do duy nhất: tôi tin vào sức mạnh của sự đơn giản. Và tôi muốn kể cho bạn nghe, bằng cả trái tim của một người làm mã nguồn mở, rằng một template blog không chỉ là những dòng code vô tri, mà là một tuyên ngôn về cách chúng ta tổ chức thông tin, cách chúng ta đối diện với độc giả, và cách chúng ta trân trọng từng khoảnh khắc viết lách.

Hãy để tôi đưa bạn vào hành trình 2000 từ này – hành trình của một kẻ mộng mơ, nhưng cũng là hành trình của một kỹ sư phần mềm.

Tất cả bắt đầu từ một buổi tối muộn, khi tôi ngồi trước màn hình đen kịt, vừa nhấm nháp tách cà phê đã nguội lạnh từ lâu, vừa lướt vô định trên mạng xã hội. Tôi chợt dừng lại trước một bức ảnh chụp chú chó nhỏ nằm cuộn tròn trong chiếc giỏ tre. Nó không diễn, không tạo dáng. Nó chỉ… hiện hữu.

Và tôi nhận ra: Những thứ chân thật nhất luôn là những thứ không cố tỏ ra hoàn hảo.

Ngay lúc đó, tôi mở trình soạn thảo và gõ dòng đầu tiên của opsoso_basic.xml:

xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html b:css='false' b:defaultwidgetversion='2' b:js='true' ...>

Tôi không tạo ra nó cho những blogger chuyên nghiệp với hàng trăm nghìn lượt truy cập. Tôi tạo ra nó cho những ai mới bắt đầu. Cho những người yêu viết lách nhưng không rành code. Cho những sinh viên, những người làm nghề tự do, những bà mẹ ở nhà, những người chỉ đơn giản muốn có một góc nhỏ trên Internet để kể câu chuyện của mình, mà không bị choáng ngợp bởi quá nhiều tùy chọn hay những hiệu ứng hào nhoáng.

Khi tôi viết dòng CSS đầu tiên:

css
:root {
--container-width: 70%;
--primary-color: #FF6D00;
--body-bg: #ffffff;
}

Tôi đang đặt nền móng cho một không gian đọc tập trung. 70% chiều rộng container không phải là con số ngẫu nhiên. Đó là kết quả của hàng trăm lần thử nghiệm, đọc các nghiên cứu về khả năng đọc (readability), và quan trọng nhất – là lắng nghe cơ thể: mắt người không thích phải lia quá xa.

Bạn có để ý không? Những tờ báo giấy truyền thống luôn chia cột hẹp. Những cuốn tiểu thuyết bán chạy nhất thế giới đều được in với khổ chữ vừa phải. Đó không phải là sự ngẫu nhiên. Đó là sự tôn trọng người đọc.

Opsoso Basic tôn trọng bạn theo cách đó. Tôi không nhồi nhét sidebar tràn lan quảng cáo, không dùng hàng chục font chữ khác nhau, không có những banner nhấp nháy. Tôi chỉ giữ lại những gì thực sự cần thiết:

  • Một header trong suốt với hiệu ứng mờ kính (glassmorphism) – vừa đủ để biết bạn đang ở đâu, vừa đủ để không làm phiền.

  • Một hero banner với bức ảnh chú chó – bởi vì tôi tin rằng hình ảnh đẹp có thể nói thay ngàn lời.

  • Một lưới bài viết 2 cột – vừa đủ để không bị rối, vừa đủ để không nhàm chán.

  • Một footer tối giản – như lời chào cuối ngày, nhẹ nhàng và đủ ấm.

Bạn có thấy điều gì đặc biệt trong tệp tin của tôi không?

javascript
var pubDate = (day < 10 ? '0' : '') + day + '/' + (month < 10 ? '0' : '') + month + '/' + year;

Tôi viết dd/MM/yyyy. Không phải MM/dd/yyyy. Đó là cách người Việt Nam đọc ngày tháng. Đó là cách bà tôi vẫn ghi vào cuốn lịch treo tường. Và đó cũng là cách tôi muốn những blogger Việt Nam cảm thấy template này thuộc về họ.

Tôi không chỉ đơn thuần dịch một template tiếng Anh sang tiếng Việt. Tôi xây dựng nó từ gốc rễ, với mindset của một người Việt. Các nhãn mặc định: "Giới thiệu", "Menu", "Bài đăng phổ biến". Nút bấm: "Xem thêm", "Tải thêm bài đăng", "Hết bài đăng". Thông báo lỗi: "Lỗi kết nối dữ liệu".

Tôi không xấu hổ khi dùng tiếng mẹ đẻ trong code. Ngược lại, tôi tự hào. Bởi vì ngôn ngữ lập trình có thể là tiếng Anh, nhưng cảm xúc người dùng phải là tiếng Việt.

Có một chi tiết mà ít ai để ý trong opsoso_basic.xml, nhưng đó lại là trái tim của template này.

Tôi không dùng Blogger widget mặc định cho các chuyên mục. Tôi viết lại toàn bộ bằng JavaScript thuần, gọi trực tiếp vào JSON feed của Blogger.

javascript
var feedUrl = '/feeds/posts/default/-/' + encodeURIComponent(labelName) + '?alt=json&max-results=' + maxResults;
fetch(feedUrl)
.then(res => res.json())
.then(data => { /* render bài viết */ })

Tại sao lại làm thế?

Bởi vì tôi muốn tốc độ. Bởi vì tôi muốn kiểm soát. Và bởi vì tôi tin rằng, một template tốt không phải là template có nhiều tính năng nhất, mà là template làm đúng một việc và làm nó thật tốt.

Trong khi hàng ngàn template Blogger khác vẫn dùng widget HTML truyền thống, phải chỉnh sửa thủ công từng link, thì opsoso_basic chỉ cần bạn gõ đúng tên nhãn. Mọi thứ còn lại, tôi lo.

Bạn muốn hiển thị 6 bài viết mới nhất về "Chó cảnh"? Hãy đặt tên widget là "CHUYÊN MỤC: CHÓ CẢNH". Tôi sẽ tự động fetch dữ liệu, tự động lấy ảnh thumbnail, tự động cắt snippet, tự động định dạng ngày tháng.

Đó là sự đơn giản mà tôi hướng tới.

Người ta thường nghĩ "tối giản" là "không có gì". Nhưng với tôi, tối giản là chỉ có những thứ thực sự cần thiết, và những thứ đó phải được chăm chút tỉ mỉ.

Hãy nhìn vào logo của opsoso_basic:

css
@keyframes logoGlow {
0% { transform: scale(1); filter: drop-shadow(0 0 5px rgba(255,109,0,0.2)); }
50% { transform: scale(1.02); filter: drop-shadow(0 0 15px rgba(255,109,0,0.6)); }
100% { transform: scale(1); filter: drop-shadow(0 0 5px rgba(255,109,0,0.2)); }
}

Một hiệu ứng rất nhẹ, rất khó nhận ra nếu bạn không để ý. Nhưng nó ở đó. Giống như nhịp thở của một người đang ngủ. Bạn không nghe thấy tiếng thở, nhưng bạn biết họ đang sống.

Hay hiệu ứng hover của bài viết:

css
.post:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(0,0,0,0.12);
border-color: var(--primary-color);
}

Chỉ 5px. Đủ để tạo cảm giác "tương tác", nhưng không đủ để làm xáo trộng bố cục. Giống như khi bạn chạm nhẹ vào vai một người bạn để hỏi "Có chuyện gì vậy?".

Tôi dành hàng giờ để căn chỉnh những con số này. 4s cho vòng lặp animation. 0.3s cho transition. 0.6s cho delay. Mỗi mili giây đều được cân nhắc. Bởi vì tôi biết, người đọc có thể không nói ra, nhưng họ cảm nhận được.

Trong opsoso_basic.xml, bạn sẽ thấy dòng này:

css
.widget[data-version="1"],
[data-widget-version="1"],
.widget-v1,
.old-widget {
display: none !important;
visibility: hidden !important;
height: 0 !important;
}

Có người bảo tôi: "Sao phải ẩn widget cũ? Cứ để họ dùng nếu muốn." Nhưng tôi không làm thế.

Tôi không ẩn widget cũ vì tôi ghét quá khứ. Tôi ẩn chúng vì tôi tôn trọng tương lai.

Widget phiên bản 1 của Blogger đã lỗi thời. Nó chậm, nó không responsive, nó bảo mật kém. Nếu bạn cố gắng dùng nó trong template của tôi, bạn sẽ có trải nghiệm tồi tệ. Và tôi không muốn điều đó xảy ra với bất kỳ ai.

Đôi khi, dũng cảm không phải là giữ lại tất cả, mà là dám bỏ đi những thứ không còn phù hợp.

Tôi cũng áp dụng triết lý này cho chính mình. Mỗi phiên bản opsoso_basic mới, tôi lại xóa đi những dòng code cũ mà tôi từng rất tự hào. Đau lắm chứ. Nhưng nếu không xóa, tôi không thể tiến lên.

Tôi không bán opsoso_basic. Tôi cũng không nhúng backlink hay quảng cáo bắt buộc. Tôi đặt nó trên GitHub, với giấy phép MIT. Ai cũng có thể tải về, chỉnh sửa, thậm chí bán lại nếu muốn.

Tại sao tôi làm thế?

Bởi vì tôi tin vào Internet phi tập trung. Tôi tin rằng một cậu bé 15 tuổi ở vùng quê, với chiếc máy tính cũ kỹ, vẫn có thể tạo ra blog đầu tiên của mình mà không tốn một đồng nào. Tôi tin rằng một cô gái trẻ yêu nấu ăn có thể chia sẻ công thức của bà mình mà không bị ràng buộc bởi bất kỳ nền tảng thương mại nào.

Opsoso Basic không phải là tài sản của tôi. Nó là món quà tôi gửi đến cộng đồng. Và món quà ý nghĩa nhất mà các bạn có thể gửi lại cho tôi, không phải là tiền, mà là những blog đẹp, những bài viết hay, những câu chuyện chạm đến trái tim người đọc.

Tôi đã thấy một blog về cứu hộ động vật dùng template này. Tôi đã thấy một nhóm sinh viên dùng nó để làm trang tin nội bộ. Tôi đã thấy một người mẹ dùng nó để viết nhật ký cho con gái.

Và mỗi lần như thế, tôi lại mở tệp opsoso_basic.xml ra, đọc lại từng dòng code, và tự nhủ: "Mày làm tốt lắm, opsoso."

Có thể bạn nghĩ: "Template này nhìn đơn giản quá, chắc dễ viết lắm."

Không hề.

Để đạt được sự đơn giản đó, tôi đã phải giải quyết hàng tá vấn đề kỹ thuật:

Tương thích ngược (Backward compatibility)

Blogger là nền tảng đã 20 năm tuổi. Có những blog được tạo từ năm 2006, với hàng nghìn bài viết cũ, dùng ảnh theo định dạng cũ, nhãn theo cách cũ. Làm sao để template mới vẫn hiển thị đẹp những nội dung cũ đó?

Tôi dùng kỹ thuật fallback image. Nếu không có featuredImage, hãy lấy thumbnailUrl. Nếu không có thumbnailUrl, hãy tìm ảnh đầu tiên trong content. Nếu vẫn không có, hãy dùng ảnh mặc định từ Unsplash.

javascript
var thumb = 'https://images.unsplash.com/photo-1543466835-00a7907e9de1?q=100';
if (entry.content) {
var match = entry.content.$t.match(/<img[^>]+src="([^">]+)"/);
if (match) thumb = match[1].replace(/\/s[0-9]+(-c)?\//, '/s1600/');
}

Tải trang không giật (Smooth loading)

Tôi ghét cảm giác đang đọc blog thì màn hình giật lên vì một widget vừa load xong. Vì vậy, tôi dùng lazy loading cho ảnh, dùng fetch API không đồng bộ cho các widget chuyên mục, và đặc biệt – tôi không dùng iframe trừ khi thực sự bắt buộc.

Responsive mà không cần media query quá nhiều

Bạn có để ý rằng opsoso_basic chỉ có vài media query ngắn? Bí quyết nằm ở việc tôi dùng CSS Grid và Flexbox một cách thông minh, kết hợp với đơn vị fr% linh hoạt.

css
.blog-posts {
display: grid;
grid-template-columnors: repeat(2, 1fr);
gap: 30px;
}
@media (max-width: 992px) {
.blog-posts {
grid-template-columns: 1fr;
}
}

Chỉ cần thế thôi. Không cần phức tạp. Và nó hoạt động.

Khi bạn phát hành mã nguồn mở, bạn không chỉ cho đi – bạn còn nhận lại. Và tôi đã nhận được rất nhiều.

Tôi nhận được một email từ bạn tên Minh, 16 tuổi, nói rằng bạn ấy đã dùng template này để làm blog về lập trình, và lần đầu tiên trong đời có người xa lạ comment khen blog đẹp.

Tôi nhận được một tin nhắn từ chị Hoa, 45 tuổi, mở tiệm bánh nhỏ ở Đà Lạt. Chị nói: "Em ơi, chị không biết code, nhưng làm theo hướng dẫn của em, blog của chị có người xem từ Sài Gòn, Hà Nội, có cả khách nước ngoài gọi điện đặt bánh."

Tôi nhận được một pull request trên GitHub từ một bạn ở Brazil. Bạn ấy đã dịch toàn bộ template sang tiếng Bồ Đào Nha và thêm một widget thời tiết. Tôi không biết tiếng Bồ Đào Nha, nhưng tôi hiểu tình yêu bạn ấy dành cho mã nguồn mở.

Những điều đó khiến tôi tiếp tục.

Tôi không có tham vọng biến opsoso_basic thành template số 1 thế giới. Tham vọng của tôi khiêm tốn hơn: trở thành template đầu tiên mà một blogger mới chạm tay vào, và là template cuối cùng mà họ rời bỏ.

Tôi muốn tiếp tục cải thiện hiệu suất, giảm thiểu JavaScript, tối ưu Core Web Vitals. Tôi muốn thêm tính năng dark mode tự động, bởi vì bảo vệ mắt người đọc cũng quan trọng như bảo vệ nội dung. Tôi muốn viết tài liệu hướng dẫn bằng tiếng Việt thật dễ hiểu, kèm hình ảnh minh họa, để bất kỳ ai cũng có thể tự tay tùy chỉnh blog của mình.

Và trên hết, tôi muốn opsoso_basic mãi là một dự án cộng đồng. Không có nhà tài trợ, không có cổ đông, không có áp lực doanh thu. Chỉ có tôi và những người bạn đồng hành, cùng nhau viết nên những dòng code đẹp.

Khi tôi gõ những dòng cuối cùng này, bên ngoài trời đã sang thu. Tách cà phê của tôi lại nguội lạnh. Màn hình vẫn sáng, và tệp opsoso_basic.xml vẫn mở.

Tôi nhìn lại hành trình của mình. Từ một lập trình viên vô danh, viết code trong phòng trọ sinh viên, đến nay có hàng trăm blog đang dùng template của tôi mỗi ngày. Tôi không giàu hơn, cũng chẳng nổi tiếng hơn. Nhưng tôi hạnh phúc hơn.

Bởi vì tôi hiểu rằng: Sự cơ bản không phải là điểm khởi đầu của những người yếu kém. Đó là đích đến của những người từng trải qua phức tạp và nhận ra rằng, đôi khi, ít hơn lại là nhiều hơn.

Opsoso Basic là tuyên ngôn của tôi về một web nhẹ nhàng, trong trẻo và nhân văn. Nó không dành cho tất cả mọi người. Nhưng nó dành cho những ai dám sống chậm lại, dám viết bằng cả trái tim, và dám tin rằng những điều nhỏ bé vẫn có thể làm nên thay đổi lớn lao.

Cảm ơn bạn đã đọc, đã dùng, và đã đồng hành cùng tôi.

Hãy giữ lấy sự cơ bản. Hãy giữ lấy đam mê.


Viết tiếp câu chuyện của riêng bạn

Đừng để những ý tưởng của bạn nằm yên trong ngăn kéo hay những bản nháp dang dở. Hãy để opsoso_basic trở thành người bạn đồng hành, thành người canh giữ cho những giấc mơ chữ nghĩa của bạn.

Hãy tưởng tượng, vào một buổi sáng sớm, bạn nhấp một ngụm trà, mở trang blog mang tên mình với giao diện tinh khôi, hiện đại của opsoso_basic, và bắt đầu gõ những dòng chữ đầu tiên. Cảm giác ấy không chỉ là viết, đó là sự tận hưởng cuộc sống.

Thông tin chi tiết và trải nghiệm ngay:

Hãy tải về, cài đặt và cảm nhận sự khác biệt. Vì bạn xứng đáng có một không gian viết lách chuyên nghiệp và thanh tao nhất.