> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# Sling Framework - Basic

## 1. Sling là gì?

**Sling** là một framework RESTful được xây dựng trên JCR Repository (nơi lưu trữ nội dung).

### 🎯 Điểm khác biệt quan trọng nhất:

| Framework thông thường                                     | Sling                                                              |
| ---------------------------------------------------------- | ------------------------------------------------------------------ |
| URL → File script (PHP, JSP) → Script tự lấy dữ liệu từ DB | URL → Resource (nội dung trong JCR) → Tìm script phù hợp để render |
| Script biết về dữ liệu                                     | Resource biết về script (thông qua `sling:resourceType`)           |

**Ví dụ cụ thể:**

```bash
# Framework thông thường (ví dụ: PHP)
https://myapp.com/product.php?id=123
→ Gọi trực tiếp file product.php
→ Trong file PHP: SELECT * FROM products WHERE id = 123

# Sling
https://mysite.com/content/products/laptop.html
→ Tìm node /content/products/laptop trong JCR
→ Đọc property sling:resourceType = "myapp/components/product"
→ Tìm script tại /apps/myapp/components/product/product.esp
→ Script nhận sẵn resource (node laptop) để render
```

**Lợi ích:**

- Tách biệt nội dung và presentation
- Mỗi resource có thể có nhiều cách render (selectors, extension)
- Dễ dàng customize từng page mà không cần thay đổi code

***

## 2. URL Decomposition (Phân tích URL)

Đây là phần quan trọng nhất để hiểu Sling hoạt động.

### Ví dụ URL:

```
https://myhost/tools/spy.printable.a4.html/a/b?x=12
```

### Phân tích từng phần:

| Phần             | Giá trị          | Ý nghĩa                                                  |
| ---------------- | ---------------- | -------------------------------------------------------- |
| **Protocol**     | `https://`       | Giao thức                                                |
| **Host**         | `myhost`         | Tên domain                                               |
| **Content Path** | `tools/spy`      | Đường dẫn đến node trong JCR                             |
| **Selectors**    | `.printable.a4.` | Cách hiển thị đặc biệt (in, mobile, json, v.v.)          |
| **Extension**    | `html`           | Định dạng output                                         |
| **Suffix**       | `/a/b`           | Thông tin bổ sung (thường dùng cho phân trang, chi tiết) |
| **Params**       | `?x=12`          | Query parameters                                         |

***

## 3. Quy trình xử lý request (Từ URL → Content → Script)

### Bước 1: Tìm Resource (Content Node)

```mermaid
graph TD
    A[HTTP Request] --> B{Tìm node tại content path}
    B -->|Có node| C[Lấy resource]
    B -->|Không có| D{Bỏ extension, tìm lại}
    D -->|Có node| C
    D -->|Không có| E[Return 404 Not Found]
```

**Ví dụ:**

```
Request: /content/corporate/jobs/developer.html

1. Tìm node tại /content/corporate/jobs/developer.html → Không có
2. Tìm node tại /content/corporate/jobs/developer → Có!
→ Resource là node /content/corporate/jobs/developer
```

### Bước 2: Lấy `sling:resourceType`

Từ node tìm được, đọc property `sling:resourceType`.

**Ví dụ:**

```xml
<!-- Node: /content/corporate/jobs/developer -->
<jcr:root>
    <jcr:primaryType>cq:Page</jcr:primaryType>
    <sling:resourceType>hr/jobs</sling:resourceType>
    <jcr:title>Developer Position</jcr:title>
    <!-- ... các properties khác ... -->
</jcr:root>
```

### Bước 3: Tìm Script phù hợp nhất

Sling sẽ tìm script dựa trên:

1. **Resource Type**: `hr/jobs`
2. **HTTP Method**: GET, POST, PUT, DELETE
3. **Extension**: html, pdf, json, v.v.
4. **Selectors**: print, a4, mobile, v.v.

**Nơi tìm script:**

- `/apps/hr/jobs/` (ưu tiên cao nhất)
- `/libs/hr/jobs/` (fallback)

***

## 4. Script Resolution (Cách Sling chọn script)

### Quy tắc ưu tiên:

Sling chọn script **cụ thể nhất** (nhiều selector match nhất).

### Ví dụ chi tiết:

**Request:**

```
/content/corporate/jobs/developer.print.a4.html
```

với `sling:resourceType = "hr/jobs"`

**Các script có thể có tại `/apps/hr/jobs/`:**

```
1. GET.esp
2. jobs.esp
3. html.esp
4. print.esp
5. print.html.esp
6. print/a4.esp
7. print/a4/html.esp
8. print/a4.html.esp
```

**Thứ tự ưu tiên (cao → thấp):**

```
(8) print/a4.html.esp    ← ✅ CHỌN (match chính xác nhất)
(7) print/a4/html.esp
(6) print/a4.esp
(5) print.html.esp
(4) print.esp
(3) html.esp
(2) jobs.esp
(1) GET.esp
```

### Cách đặt tên script:

| Loại request      | Tên script                                  | Ví dụ                    |
| ----------------- | ------------------------------------------- | ------------------------ |
| GET/HEAD mặc định | `<resourceType>.<extension>.esp`            | `jobs.html.esp`          |
| POST request      | `<resourceType>.POST.<extension>.esp`       | `jobs.POST.html.esp`     |
| Có selectors      | `<resourceType>.<selector>.<extension>.esp` | `jobs.print.html.esp`    |
| Nested selectors  | `<resourceType>/<selector>/<extension>.esp` | `jobs/print/a4.html.esp` |

***

## 5. Resource Super Type (Kế thừa script)

Đây là tính năng rất mạnh mẽ, cho phép tái sử dụng script.

### Cách hoạt động:

```xml
<!-- Node: /content/my-page -->
<jcr:root>
    <sling:resourceType>myapp/components/custom-page</sling:resourceType>
</jcr:root>

<!-- Node: /apps/myapp/components/custom-page -->
<jcr:root>
    <sling:resourceSuperType>myapp/components/base-page</sling:resourceSuperType>
</jcr:root>
```

### Hierarchy:

```
/my-page
  → resourceType = myapp/components/custom-page
    → resourceSuperType = myapp/components/base-page
      → resourceSuperType = sling/servlet/default (mặc định)
```

### Kết quả:

Khi Sling tìm script cho `/my-page`, nó sẽ tìm theo thứ tự:

1. `/apps/myapp/components/custom-page/` (của resource type)
2. `/apps/myapp/components/base-page/` (của super type)
3. Mặc định của Sling

**Lợi ích:**

- Tạo component cha (base) với logic chung
- Component con override chỉ những phần cần thay đổi
- Dễ dàng maintain và mở rộng

***

## 6. sling:include (Ghép nhiều component)

Khi bạn muốn ghép nhiều component vào một page, dùng `sling:include`.

### Cú pháp:

```jsp
<!-- JSP -->
<sling:include resourceType="geometrixx/components/image/img" />

<!-- HTL -->
<sling:include resourceType="geometrixx/components/image/img" />

<!-- Với path cụ thể -->
<sling:include path="/content/shared/footer" />
```

### Cách hoạt động:

```mermaid
graph TD
    A[Page Component] --> B{sling:include}
    B --> C[Gọi Sling engine]
    C --> D[Tìm resource tại path hoặc resourceType]
    D --> E[Render component con]
    E --> F[Trả về HTML]
    F --> G[Chèn vào page]
```

### Ví dụ thực tế:

**Page structure:**

```
/content/my-page
  /jcr:content
    /header (sling:resourceType = myapp/components/header)
    /main (sling:resourceType = myapp/components/main-content)
    /sidebar (sling:resourceType = myapp/components/sidebar)
    /footer (sling:resourceType = myapp/components/footer)
```

**Script của page:**

```jsp
<!-- /apps/myapp/components/page/page.jsp -->
<html>
    <body>
        <!-- Include header -->
        <sling:include path="header" />
        
        <!-- Include main content -->
        <sling:include path="main" />
        
        <!-- Include sidebar -->
        <sling:include path="sidebar" />
        
        <!-- Include footer -->
        <sling:include path="footer" />
    </body>
</html>
```

***

## 7. SlingPostServlet (Xử lý POST requests)

Sling cung cấp `SlingPostServlet` để xử lý các request POST với nhiều tham số ẩn mạnh mẽ.

### Các tham số đặc biệt:

| Tham số        | Chức năng                           |
| -------------- | ----------------------------------- |
| `:operation`   | `create`, `delete`, `copy`, `move`  |
| `:redirect`    | URL redirect sau khi xử lý          |
| `:status`      | Status code trả về                  |
| `:contentType` | Content type của response           |
| `:*`           | Tạo/sửa properties (prefix với `*`) |

### Ví dụ:

```html
<!-- Form tạo node mới -->
<form method="POST">
    <input name=":operation" value="create" />
    <input name="./title" value="My New Page" />
    <input name="./sling:resourceType" value="myapp/components/page" />
    <input name=":redirect" value="/content/my-page.html" />
</form>
```

```html
<!-- Form xóa node -->
<form method="POST">
    <input name=":operation" value="delete" />
</form>
```

***

## 8. Tóm tắt nhanh

| Khái niệm                   | Ý nghĩa                                     |
| --------------------------- | ------------------------------------------- |
| **Sling**                   | Framework RESTful của AEM                   |
| **Resource**                | Node trong JCR repository                   |
| **sling:resourceType**      | Đường dẫn đến script sẽ render resource     |
| **sling:resourceSuperType** | Cho phép kế thừa script từ component khác   |
| **Selectors**               | Cách render khác nhau (print, json, mobile) |
| **Extension**               | Định dạng output (html, pdf, json)          |
| **sling:include**           | Ghép component con vào page                 |
| **SlingPostServlet**        | Xử lý POST requests với tham số ẩn          |

***

## 9. Lưu ý quan trọng

1. **KHÔNG gọi script trực tiếp**: Sling không cho phép truy cập trực tiếp vào script (ví dụ: `/apps/myapp/component/page.jsp`). Luôn phải thông qua resource.

2. **Ưu tiên /apps hơn /libs**: Khi tìm script, Sling luôn tìm trong `/apps` trước, sau đó mới đến `/libs`.

3. **HTL được khuyến nghị**: Adobe khuyến nghị sử dụng HTL (HTML Template Language) thay vì JSP cho component.

4. **Tính RESTful**: Mọi thứ đều là resource, việc tương tác với resource (GET, POST, PUT, DELETE) được xử lý tự động.
