Fundamental approach for implementing JSON-LD structured data pipeline in AEM.
Seo Ld Json
Phương pháp triển khai chung
- Backend (Java / Sling Model): Đọc các thuộc tính (properties) từ trang hiện tại (
currentPage) hoặc cấu hình (Configuration), sau đó xây dựng một object đại diện cho Schema (ví dụ:Article,BreadcrumbList,WebPage). - Serialization: Chuyển đổi Object thành chuỗi JSON (sử dụng thư viện như
GsonhoặcJackson). - Frontend (HTL / Sightly): Gọi Sling Model từ component Page (ví dụ file
customheaderlibs.htmlhoặc trực tiếp trong<head>) và in chuỗi JSON ra bên trong thẻ<script type="application/ld+json">.
Bước 1: Tạo Data Transfer Object (DTO) cho Schema
Đầu tiên, tạo các lớp Java (POJO) để cấu trúc hóa dữ liệu theo chuẩn Schema.org. Ví dụ cho loại Article.
Bước 2: Xây dựng Sling Model lấy dữ liệu từ Page
Tạo Sling Model gắn vào Page component để đọc properties và map vào Object ArticleSchema.
Bước 3: Inject chuỗi JSON vào Frontend (HTL)
Trong cấu trúc Page component của bạn (ví dụ: apps/yourproject/components/page), tìm đến vị trí render phần <head> (có thể là customheaderlibs.html, head.html hoặc headlibs.html).
Sử dụng HTL để gọi Sling Model và in dữ liệu ra một cách an toàn (tránh bị escape các ký tự JSON).
Cơ chế hoạt động: JSON-LD được sinh ra động hay lưu trữ (Persisted)?
Trong cách triển khai ở trên, chuỗi JSON-LD KHÔNG được lưu nguyên khối (persisted) trong JCR (Page Properties). Thay vào đó, nó được sinh ra động (dynamic):
- Sinh ra động (On-the-fly): Mỗi khi trang được yêu cầu render, Sling Model sẽ được gọi. Hàm
@PostConstructsẽ đọc các properties nhỏ lẻ đã lưu trong JCR của page (nhưjcr:title,cq:lastModified, tên tác giả, ảnh), sau đó tự động lắp ráp chúng thành Object Schema và parse ra chuỗi JSON. - Tối ưu hiệu năng bằng Dispatcher: Dù Sling Model gen code tự động, nhưng bạn không phải lo về hiệu năng. Mã HTML của trang (bao gồm thẻ
<script>đã chứa chuỗi JSON-LD) sẽ được AEM Dispatcher cache lại thành file HTML tĩnh trên Web Server (như Apache/Nginx). Sling Model thực chất chỉ chạy 1 lần lúc trang bị "miss cache". - Trường hợp muốn nhập tay (Manual): Nếu business yêu cầu cho phép Content Author tự copy/paste đoạn script JSON-LD tùy ý, bạn có thể tạo thêm một trường Text Area trong Page Dialog (ví dụ lưu thành property
customJsonLdtrong JCR). Khi đó, HTML chỉ việc in trực tiếp cái propertycustomJsonLdđó ra thẻ<script>mà không cần qua bước convert của Gson.
Xử lý yêu cầu nghiệp vụ nâng cao (Inherit, Auto-fill Edit, Manual Inject)
Nếu thiết kế yêu cầu một trường seoText trong Page Properties thỏa mãn 3 điều kiện:
- Nhập
"inherit": Tự động kế thừa JSON-LD từ page cha. - Tự động sinh khi mở Dialog (Auto-fill): Page thuộc loại schema được support, khi tạo page không sinh ra, nhưng lần đầu mở page lên edit thì sẽ lấy JSON cấu trúc từ model điền vào.
- Nhập tùy ý (Manual Inject): Dùng luôn giá trị nhập vào mà không query thêm.
Dưới đây là giải pháp kiến trúc để đáp ứng requirement này:
1. Xử lý Logic render ở tầng Sling Model
Sling Model sẽ đọc trường seoText và quyết định output:
2. Giải pháp cho yêu cầu "Tự động gen JSON khi mở Page Edit lần đầu"
Vì JSON cần được lưu lại (persisted) vào seoText sau khi User tương tác với Page Properties, cách tốt nhất là kết hợp Clientlibs (JavaScript) và Sling Servlet:
- Tạo một Custom Sling Servlet: Viết một Servlet (phương thức GET) nhận đường dẫn page, sau đó chạy logic sinh JSON theo model (giống Bước 1 ở phần đầu) và trả về kết quả dạng String JSON.
- Viết Clientlib bắt sự kiện Dialog: Tạo một JS Clientlib thuộc category
cq.authoring.dialog. JS này sẽ lắng nghe sự kiện khi Dialog Page Properties mở ra (foundation-contentloaded). - Logic trong JS:
- Tìm ô textarea của trường
seoText. Kiểm tra nếu nó đang trống (chưa có data) và Page này thuộc loại Schema được hỗ trợ (có thể kiểm tra qua template path hoặc resourceType). - Gọi AJAX (GET) tới Servlet vừa tạo ở trên.
- Lấy chuỗi JSON từ response và tự động điền (val) vào ô textarea
seoText.
- Tìm ô textarea của trường
- Kết quả: Ngay khi Author mở Page Properties, họ sẽ thấy ô Seo Text tự động hiện ra một cấu trúc JSON chuẩn. Họ có thể kiểm tra, chỉnh sửa (Manual Inject) hoặc gõ chữ "inherit". Sau đó nhấn "Save & Close", chuỗi JSON này chính thức được lưu thành property
seoTexttrong JCR.
Đây là phương pháp thân thiện với người dùng (UX) nhất vì Author luôn biết chính xác cái gì sắp được lưu vào page.
Một số lưu ý quan trọng
- Context = 'unsafe' trong Sightly: Mặc định HTL sẽ escape các thẻ HTML và ký tự đặc biệt để chống XSS. Khi in output JSON vào thẻ script, bạn phải sử dụng
${variable @ context='unsafe'}để nội dung JSON được giữ nguyên vẹn. - Sử dụng Core Components: Nếu bạn sử dụng AEM Core Components mới nhất, class
Pagemodel (com.adobe.cq.wcm.core.components.models.Page) đã hỗ trợ sẵn việc render một số meta tags và có thể customize thông qua tính năng Data Layer. Tuy nhiên, đối với các loại schema phức tạp (như Product, FAQPage, Event), việc tự viết custom Sling Model là cần thiết. - Thư viện Gson / Jackson: Trong AEM OSGi environment,
GsonhoặcJacksonthường được dùng để convert object sang json. Jackson thường có hiệu năng cao hơn và được đi kèm trong các version AEM mới thông qua bundle của Sling. - Validation: Sau khi publish trang, hãy sử dụng công cụ Rich Results Test hoặc Schema Markup Validator của Google để kiểm tra xem đoạn script LD+JSON được generate ra có hợp lệ hay không.