{"version":"https://jsonfeed.org/version/1","title":"QuanWeb","home_page_url":"https://quan.hoabinh.vn","feed_url":"https://quan.hoabinh.vn/feeds.json","next_url":"https://quan.hoabinh.vn/feeds.json?page=2","description":"Blog about programming, culture, history","icon":null,"favicon":null,"author":null,"items":[{"id":"urn:uuid:04ebbf6a-164b-11f1-8000-dbaec97d7a8d","url":"https://quan.hoabinh.vn/post/2026/03/gleam-mot-lua-chon-moi-cho-lap-trinh-web-frontend","external_url":null,"title":"Gleam - một lựa chọn mới cho lập trình web frontend","content_html":null,"content_text":null,"summary":"Gần đây mình thử nghiệm phát triển web frontend với ngôn ngữ [Gleam][gleam], framework [Lustre][lustre] và khá ưng ý. Mình đã áp dụng luôn cho hai dự án cá nhân.\nLý do khiến mình \"đứng núi này trông núi nọ\":\n\n\nViết JavaScript hoài mà không mê nó được. JavaScript có nhiều điểm kỳ cục khiến mình không thấy thoải mái. Thật ra thì mình viết TypeScript không đó chứ. Hệ thống kiểu (type system) của TypeScript nói chung là rất tân tiến, mình nể phục người thiết kế ra nó. Tuy nhiên vì nó vẫn phải bám theo JavaScript nên thừa hưởng những thứ kì cục của JavaScript.\n\n\nCác framework bên frontend sáng tạo mạnh quá nên gây khó khăn trong việc tích hợp TypeScript. Ví dụ, VueJS sáng chế ra ngôn ngữ template của riêng nó, dựa trên HTML, thêm các directive v-if, v-for chứa code nhúng JavaScript.\n\n\n...","date_published":"2026-03-03T03:23:03.361822+00:00","date_modified":"2026-03-03T03:23:03.361822+00:00","author":{"name":"hongquan","url":null},"tags":["Web development","Rust"],"language":"vi"},{"id":"urn:uuid:46ef2b12-0fb7-11f1-ad46-272acdd3fe21","url":"https://quan.hoabinh.vn/post/2026/02/thu-vien-python-tra-cuu-phuong-xa-truoc-va-sau-sat-nhap","external_url":null,"title":"Thư viện Python tra cứu phường xã trước và sau sát nhập","content_html":null,"content_text":null,"summary":"Đã nửa năm từ sau sự thay đổi lớn về đơn vị hành chính Tháng 7 - 2025, mọi người vẫn còn khó khăn với việc đối chiếu dữ liệu trước và sau sát nhập. Vì vậy mình đã nâng cấp thư viện [vietnam-provinces][vietnam-provinces] để hỗ trợ việc này.\nTừ phiên bản 2026.2.0, bạn đã có thể truy cập dữ liệu phường xã cũ trong module [legacy][legacy], ví dụ:\n&gt;&gt;&gt; from vietnam_provinces import legacy\n&gt;&gt;&gt; from rich import print\n\n...","date_published":"2026-02-22T06:52:27.927006+00:00","date_modified":"2026-02-22T06:52:27.927006+00:00","author":{"name":"hongquan","url":null},"tags":["Web development","Python"],"language":"vi"},{"id":"urn:uuid:4f146554-ede4-11f0-ad46-f74be124df2b","url":"https://quan.hoabinh.vn/post/2026/01/api-tinh-thanh-co-du-lieu-chinh-thuc-sau-dot-sat-nhap","external_url":null,"title":"API tỉnh thành có dữ liệu chính thức sau đợt sát nhập","content_html":null,"content_text":null,"summary":"Tháng 7/2025, chính quyền có sự thay đổi mạnh về cấu trúc đơn vị hành chính, khi hủy bỏ cấp huyện và sáp nhập tỉnh với tỉnh, xã với xã. Tuy nhiên bảng mã cho các xã sau sát nhập vẫn chưa có chính thức sau nhiều tháng trời, chỉ tồn tại trong văn bản \"Dự thảo\". Cách đây mấy ngày, thì mình phát hiện dữ liệu đó đã được công bố chính thức trên website của Cục Thống kê nên đã cập nhật luôn thư viện vietnam-provinces và API Tỉnh thành Việt Nam.\nĐợt sát nhập tỉnh thành này có vẻ cũng bao gồm cả việc tổ chức lại bộ máy hành chính Trung ương. Lần trước, cơ quan cung cấp dữ liệu bảng mã tỉnh thành là\nTổng cục Thống kê\", hoạt động tại tên miền gso.gov.vn, nhưng nay cơ quan đó là \"Cục Thống kê\", hoạt động tại tên miền nso.gov.vn.\n...","date_published":"2026-01-10T07:53:05.303649+00:00","date_modified":"2026-02-19T20:27:24.527445+00:00","author":{"name":"hongquan","url":null},"tags":[],"language":"vi"},{"id":"urn:uuid:2b0ae5ec-e269-11f0-ad46-b3a4a2aec539","url":"https://quan.hoabinh.vn/post/2025/12/define-ui-comprising-listview-in-blueprint-for-modern-gtk-apps","external_url":null,"title":"Define UI comprising ListView in Blueprint for modern GTK apps","content_html":null,"content_text":null,"summary":"In a previous post, [\"Define UI comprising Dropdown in Blueprint for modern GTK apps\"][dropdown-post], I presented how to use [DropDown][dropdown] in [Blueprint][blueprint]. Now we go with a bit more complex example, with ListView widget.\nThis is the UI where ListView is used, in my [CoBang][cobang] app:\n\nIt shows a list of WiFi network config, for which user will pick to generate QR code. The list is accompanied with a search box, via which user will type part of Wi-Fi name to narrow down the list, to quickly find the needed Wi-Fi network.\n...","date_published":"2025-12-26T17:30:10.838721+00:00","date_modified":"2026-02-19T20:27:24.542378+00:00","author":{"name":"hongquan","url":null},"tags":["Programming","Linux"],"language":"en"},{"id":"urn:uuid:b1f6d576-cdaa-11f0-ad46-b7cbf2f2f250","url":"https://quan.hoabinh.vn/post/2025/11/define-ui-comprising-dropdown-in-blueprint-for-modern-gtk-apps","external_url":null,"title":"Define UI comprising Dropdown in Blueprint for modern GTK apps","content_html":null,"content_text":null,"summary":"GTK is one of the GUI toolkits for building Linux desktop apps, notable for its modern visual look, and with some advanced developer experience features, like Inspector.\nBut one of the things that is still old-fashioned is its support for declarative UI. GTK allows developer to describe the UI separately from application code, but the language is XML which is too verbose, comparing to QT's QML or Slint. Fortunately, there is an new language, Blueprint, to describe UI for GTK app, which brings the same taste of QML, Slint to the table. But Blueprint is still young, not integrated to GTK yet (the files written in Blueprint must be compiled to Gtk.Builder XML) and the documentation is not rich enough.\nThis post shows you how to use Dropdown or other list widgets (like ListView, GridView) in Blueprint. The example use case and code is drawn from my application, CoBang.\nList widgets follow Model-View-Controller pattern, to dislay a list of data with dynamic length. The widget is not used alone, but with other non-display components from GTK library:\n...","date_published":"2025-12-21T16:17:37.368086+00:00","date_modified":"2026-02-19T20:27:24.556042+00:00","author":{"name":"hongquan","url":null},"tags":["Programming","Linux"],"language":"en"},{"id":"urn:uuid:06569dd2-b7a7-11f0-ad46-733daee194c3","url":"https://quan.hoabinh.vn/post/2025/11/fix-commands-hanging-in-incus-container-when-host-os-is-ubuntu","external_url":null,"title":"Fix commands hanging in Incus container when host OS is Ubuntu","content_html":null,"content_text":null,"summary":"I have used Incus-based containers for nearly a year. From Ubuntu 25.04, somethings weird happened, many commands just hang, not return.\nThis post spot the cause: AppArmor blocks sending signals on Ubuntu 25.04 host.\nThere is no true fix yet, there are two workarounds:\n\nDisable apparmor_unconfined_restriction\n\n...","date_published":"2025-12-14T06:51:32.524816+00:00","date_modified":"2026-02-19T20:27:24.514931+00:00","author":{"name":"hongquan","url":null},"tags":["Linux"],"language":"en"},{"id":"urn:uuid:386fc366-af64-11f0-ad46-03f6c6e534df","url":"https://quan.hoabinh.vn/post/2025/10/the-trickiness-of-html-checkbox","external_url":null,"title":"The trickiness of HTML checkbox","content_html":null,"content_text":null,"summary":"I'm using Lustre framework to rebuild the Admin area of this blog. When implementing the form for editing blog post, I'm surprised how tricky to handle the checkbox, which may look simple at first.\nIn CRUD applications, people often use the checkbox to represent a boolean field. The \"checked\" status is for True and unchecked is for False. Take this form as example, when I want to publish a post, I tick the \"Published\" checkbox and save. If I want to unpublish, I untick and save.\n\nMost of people don't see any issue with this usage. When I make frontend apps with VueJS, with an edit form like this, I often bind each &lt;input&gt; element with a reactive variable, via v-model:\n...","date_published":"2025-11-03T15:17:53.740085+00:00","date_modified":"2026-02-19T20:27:24.473373+00:00","author":{"name":"hongquan","url":null},"tags":["Web development"],"language":"en"},{"id":"urn:uuid:db4849d4-adc3-11f0-ad46-cb66e9d7b9b9","url":"https://quan.hoabinh.vn/post/2025/10/diem-moi-cua-python-3-14-che-do-free-threading","external_url":null,"title":"Điểm mới của Python 3.14: Chế độ free-threading","content_html":null,"content_text":null,"summary":"Một điểm mới khác, khá quan trọng, của Python 3.14, nhưng không \"đập vào mắt người dùng\" là chế độ \"free-threading\". Đây là chế độ mà CPython tắt \"Global Interpreter Lock\" (GIL), một loại khóa trước đây dùng để ngăn chặn nhiều thread cùng truy cập, sửa đổi dữ liệu thuộc kiểu riêng của CPython. Nay với chế độ \"free-threading\" thì các thread được chạy song song thoải mái hơn (tốc độ xử lý của ứng dụng đa luồng cũng tăng lên).\nNếu bạn viết code Python, không cần phải quan tâm vì ở mức độ này không nhìn thấy GIL. Chỉ khi bạn viết extension cho Python bằng ngôn ngữ biên dịch (C, C++, Rust) thì mới phải động vào GIL. Khi CPython gỡ bỏ GIL, tương tự như ngã tư bỏ đi cảnh sát đứng phân luồng, thì tác giả các extension này phải tự đảm bảo code mình là thread-safe, tự áp dụng các phương tiện, chiêu thức khác để tránh code mình bị crash, deadlock trong môi trường đa luồng. Điều này lại là cơ hội tỏa sáng cho các extension viết bằng Rust. Một trong các điểm \"ăn tiền\" của  Rust là \"fearless concurrency\". Rust có các luật kiểm tra ownership, lifetime chặt chẽ, có các phương tiện dành cho lập trình đa luồng giúp bạn tránh tối đa các lỗi hay gặp, khó mò trong lập trình đa luồng.\n\nMình có một extension, viết bằng Rust, để làm cho nó tương thích với \"free-threading\" thì cực kỳ dễ, chỉ cần khai báo gil_used = false, vì vốn từ đầu nó đã chạy mà không cần \"xin\" GIL rồi.\n...","date_published":"2025-10-25T10:48:57.678895+00:00","date_modified":"2026-02-19T20:27:24.487491+00:00","author":{"name":"hongquan","url":null},"tags":["Programming","Rust","Python"],"language":"vi"},{"id":"urn:uuid:2b727c82-a918-11f0-ad46-d73573afb234","url":"https://quan.hoabinh.vn/post/2025/10/lustre-gleam-how-to-create-modal-popup","external_url":null,"title":"Lustre / Gleam: How to create modal popup","content_html":null,"content_text":null,"summary":"Modal dialog is a often used UI element, but in web tech, developers used to spend quite much effort to implement it, before the introduction of CSS frameworks like Bootstrap. It was tricky to position the dialog in the center of the window, to blur the content behind it. It was tricky to let user close the popup by clicking outside it.\nIt is until the HTML standard introduces the native &lt;dialog&gt; element. Now developers can create a modal popup with ease, except if their users are using Safari, which often lags behind the modern web features. Put Safari aside, now we see how to create the native modal popup in Lustre framework (Gleam language).\nMy use case is the post compose form of this blog. The original content is in Markdown. The form has a \"Preview\" button so that if I click it, a modal popup appears and loads the rendered HTML of that Markdown code.\n\n...","date_published":"2025-10-24T15:47:16.982561+00:00","date_modified":"2026-02-19T20:27:24.459359+00:00","author":{"name":"hongquan","url":null},"tags":["Programming","Web development"],"language":"en"},{"id":"urn:uuid:6bbe17f6-a85a-11f0-ad46-0bb69050bada","url":"https://quan.hoabinh.vn/post/2025/10/khi-mot-ngon-ngu-lap-trinh-khong-co-lenh-return","external_url":null,"title":"Khi một ngôn ngữ lập trình không có lệnh `return`","content_html":null,"content_text":null,"summary":"Từ khóa return quá quen thuộc khi nó có mặt trong hầu như mọi ngôn ngữ lập trình, không chỉ được dùng ở cuối hàm như một lẽ thường, nó còn được dùng ở giữa hàm khi cần dừng chạy hàm sớm khi gặp điều kiện nào đó, ví dụ:\nasync def process_mqtt_message(\n    topic: str, payload: bytes, pg_session: AsyncSession, red: Redis[str]\n) -&gt; ActuatorProcessResult | NodeProcessResult | None:\n    if m := REGEX_TOPIC_SN_ACTUATOR_STATUS.match(topic):\n\n...","date_published":"2025-10-13T17:38:38.031466+00:00","date_modified":"2026-02-19T20:27:23.007552+00:00","author":{"name":"hongquan","url":null},"tags":["Programming"],"language":"vi"}]}