Cùng một mẫu in, nhưng thẻ đang hiệu lực thì cần một dải xanh trấn an, thẻ hết hạn cần một dải cam nhắc gia hạn, thẻ bị khoá cần một dải đỏ cảnh báo. Bạn không làm ba mẫu in — bạn làm một mẫu biết tự đổi mặt theo dữ liệu. Công cụ là bộ ba t-if / t-elif / t-else của QWeb, cộng thêm một mẹo nhỏ nhưng quan trọng: dùng t-if để bỏ hẳn phần không có dữ liệu, thay vì in ra một khoảng trắng vô duyên.
Ba trạng thái, ba nhánh
Model thẻ có field trang_thai với các giá trị dang_dung, het_han, khoa, moi. Trong QWeb, mỗi giá trị dẫn tới một nhánh — và chỉ một nhánh khớp đầu tiên được in:

Hình 1: t-if mở chuỗi, t-elif nối các nhánh tiếp theo, t-else bắt phần còn lại. QWeb xét lần lượt và dừng ở nhánh đúng đầu tiên — giống if/elif/else của Python. t-else="" không cần điều kiện; nó là lưới hứng cho mọi giá trị chưa khớp (ở đây là moi). Lưu ý cú pháp: t-elif/t-else phải là thẻ liền kề ngay sau t-if, chen nội dung khác vào giữa là đứt chuỗi.
Dữ liệu thật của bốn thẻ quyết định banner nào hiện:

Hình 2: Bốn thẻ với ba trạng thái khác nhau (đọc thẳng từ hệ thống). VIP-0001/0003 đang dùng, VIP-0002 hết hạn, VIP-0004 bị khoá và 0 điểm. Mỗi thẻ sẽ rơi vào đúng một nhánh khi in.
In ra: ba thẻ, ba khuôn mặt
Cùng report_the_document, in ba thẻ ở ba trạng thái, cắt lấy phần đầu để so sánh:

Hình 3: Cùng một template, ba kết quả. Banner xanh/cam/đỏ do t-if/t-elif/t-elif chọn theo trang_thai. Riêng thẻ VIP-0004 còn có thêm dòng đỏ "Thẻ chưa tích điểm nào." vì nó 0 điểm — trong khi hai thẻ kia (150 và 85 điểm) không có dòng đó, và cũng không để lại khoảng trống nào ở vị trí đó.
t-if để bỏ hẳn, không phải để ẩn
Đây là điểm khác biệt với ẩn/hiện trên giao diện web (nơi phần tử vẫn tồn tại, chỉ display:none). Trong report PDF, t-if sai nghĩa là node đó không được sinh ra — không có thẻ, không có khoảng trắng, không có dòng rỗng. Nhờ vậy:
<!-- 0 điểm: đoạn này biến mất hoàn toàn, không đẩy layout xuống -->
<t t-if="o.diem == 0">
<p style="color:#c0392b; font-style:italic;">Thẻ chưa tích điểm nào.</p>
</t>
Nếu bạn dùng CSS display:none kiểu web, wkhtmltopdf vẫn có thể để lại chỗ trống hoặc tính sai chiều cao. Với report, luôn dùng t-if để không sinh phần thừa — sạch và chắc.
Ẩn theo quyền: thuộc tính groups
Ngoài điều kiện theo dữ liệu, report còn ẩn/hiện theo người xem. Thuộc tính groups trên bất kỳ node QWeb nào chỉ cho nhóm quyền tương ứng nhìn thấy:
<div groups="base.group_system">
Giá vốn nội bộ: <span t-field="o.gia_von"/> <!-- chỉ admin thấy -->
</div>
Nhân viên thường in ra sẽ không có đoạn này; admin in ra mới thấy. Rất tiện cho các con số nhạy cảm (giá vốn, chiết khấu) mà bạn muốn đưa vào bản in nội bộ nhưng giấu khỏi bản đưa khách.
Vài lưu ý
t-elif/t-elsephải liền kềt-if. Chèn một node khác vào giữa là chuỗi đứt,t-elifthành lỗi "unexpected". Nếu cần, gom cả cụm vào một thẻ bao.- So sánh đúng giá trị kỹ thuật, không phải nhãn:
o.trang_thai == 'khoa', không phải== 'Đã khoá'. Nhãn tiếng Việt là để hiển thị; điều kiện chạy trên giá trị lưu. t-ifnhận biểu thức Python bất kỳ:o.diem > 100,o.lich_su_ids,o.partner_id and o.partner_id.vip. Recordset rỗng là falsy nênt-if="o.lich_su_ids"= "có ít nhất một dòng".
Ba ý mang về
t-if/t-elif/t-elsechọn đúng một nhánh theo dữ liệu bản ghi — một mẫu in phục vụ mọi trạng thái.t-elif/t-elsephải là thẻ liền kềt-if.t-ifbỏ hẳn node khi điều kiện sai (không phảidisplay:none) — đây là cách sạch để không in ra khoảng trắng cho phần thiếu dữ liệu.groups="..."ẩn/hiện theo quyền người xem — đưa số nhạy cảm vào bản in nội bộ mà vẫn giấu khỏi bản cho khách.
Điều kiện đã điều khiển cái gì hiện ra. Phần sau lo trông thế nào: Phần sau đi vào style report bằng CSS — nhúng SCSS/CSS vào bản in, dùng class thay vì style nội tuyến, và những gì wkhtmltopdf hiểu (và không hiểu).