> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Liquid 구문 사용

> Liquid 태그, 필터, 조건문, 루프를 사용하여 이메일, 푸시, SMS, 인앱 및 Live Activity 콘텐츠를 개인화하세요 — 태그, 속성, 커스텀 데이터, Data Feeds 등 OneSignal 데이터 소스로 구동됩니다.

Liquid은 이메일, 푸시, SMS, 인앱 및 Live Activities를 포함한 채널 전반에서 메시지를 개인화하기 위해 OneSignal에서 지원하는 템플릿 언어입니다. 태그, 필터 및 조건을 사용하여 메시지 콘텐츠를 동적으로 사용자 지정합니다.

Liquid 구문에 대한 자세한 내용은 [공식 Liquid 문서](https://shopify.github.io/liquid/basics/introduction/)를 참조하세요.

***

## 기본 구문

Liquid은 두 가지 주요 구문 구조를 사용합니다:

1. **출력 태그**: `{{ ... }}` — 변수 또는 객체의 데이터를 표시합니다.
2. **로직 태그**: `{% ... %}` — 조건문 또는 루프를 실행합니다.

## 조건문

### 연산자

* `==`, `!=`, `>`, `<`, `>=`, `<=`
* `and`, `or`
* `contains` (문자열 또는 배열)

```text liquid theme={null}
{% if true or false and false %}
  This is true.
{% endif %}
```

### `if`, `elsif`, `else`

```text liquid theme={null}
{%- assign userLang = subscription.language -%}
{% if userLang == "es" -%}
Hola {{ first_name }}!
{%- elsif userLang == "fr" -%}
Bonjour {{ first_name }}!
{%- else -%}
Hello {{ first_name }}!
{%- endif %}
```

### `unless`

```text liquid theme={null}
{% unless level == "1" %}
  Great job getting past the first level!
{% endunless %}
```

***

## 필터

`{{ variable | filter }}`를 사용하여 필터를 적용하여 데이터 표시 방식을 조정합니다.

### `default`

속성이 비어 있거나 존재하지 않는 경우 기본값을 할당합니다.

```text liquid theme={null}
Hello {{ first_name | default: "there" }}.
```

### `date`

date 필터는 타임스탬프를 다른 날짜 형식으로 변환합니다. 이 구문의 형식은 [strftime](https://strftime.net/)과 동일합니다. 입력은 Ruby의 [Time.parse](https://ruby-doc.org/stdlib-2.4.1/libdoc/time/rdoc/Time.html)와 동일한 형식을 사용합니다.

태그로 날짜를 초 단위 unix 타임스탬프로 설정합니다. 이렇게 하면 liquid 구문 개인화 및 [시간 연산자](./time-operators)를 사용한 세분화를 모두 사용할 수 있습니다. 예를 들어 태그는 다음과 같을 수 있습니다: `bill_due : 1687968776`

```text liquid theme={null}
{{ bill_due | date: "%a, %b %d, %y" }}
{{ "now" | date: "%Y-%m-%d %H:%M" }}
```

```text Result theme={null}
Wed, Jun 28, 23
```

```text liquid theme={null}
{{ bill_due | date: "%Y" }}
```

```text Result theme={null}
2023
```

날짜 형식은 올바른 형식의 날짜가 포함된 경우 문자열에서 작동합니다.

```text liquid theme={null}
{{ "March 14, 2016" | date: "%b %d, %y" }}
```

```text Result theme={null}
Mar 14, 16
```

현재 시간을 가져오려면 date 필터와 함께 특수 단어 `now` (또는 `today`)를 전달합니다.

```text liquid theme={null}
This message was sent at {{ "now" | date: "%Y-%m-%d %H:%M" }}.
```

```text Result theme={null}
This message was sent at 2022-11-02 14:39.
```

<Info>
  현재 시간은 메시지가 수신자에게 전송된 시간을 기준으로 메시지에 렌더링됩니다. 메시지를 테스트하는 경우 테스트 메시지가 전송된 시간이 현재 시간으로 표시됩니다.
</Info>

### `capitalize`

이 필터는 문자열의 첫 문자를 대문자로 만들고 나머지 문자를 소문자로 변환합니다.

```text liquid theme={null}
{{ "my GREAT title" | capitalize }}
```

```text Result theme={null}
My great title
```

### `round`

이 필터는 숫자를 가장 가까운 정수로 반올림하거나 인수로 숫자가 전달된 경우 해당 소수 자릿수로 반올림합니다.

```text liquid theme={null}
{{ 1.2 | round }}
  {{ 2.7 | round }}
{{ 183.357 | round: 2 }}
```

```text Result theme={null}
1
3
183.36
```

### `pluralize`

이 필터는 주어진 숫자를 기준으로 문자열의 단수 또는 복수 형식을 반환합니다. 숫자는 정수여야 하며 문자열로 제공할 수 있습니다. 문자열의 단수 및 복수 형식을 모두 제공해야 합니다.

```text liquid theme={null}
{{ 1 | pluralize: "singular", "plural" }}
{{ 2 | pluralize: "singular", "plural" }}
1 {{ 1 | pluralize: "person", "people" }}
2 {{ 2 | pluralize: "person", "people" }}
2 {{ "2" | pluralize: "person", "people" }}
```

```text Result theme={null}
singular
plural
1 person
2 people
2 people
```

***

## 반복

### `for` 루프

코드 블록을 반복적으로 실행합니다. `for` 루프 내에서 사용 가능한 속성의 전체 목록은 [Liquid `for` 루프 문서](https://shopify.github.io/liquid/tags/iteration/)를 참조하세요.

```text liquid theme={null}
{% for product in message.custom_data.products %}
  - {{ product.name }}
  {% else %}
    Sorry, we're sold out of all products.
  {% endfor %}
```

```json Request Body theme={null}
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "custom_data": {
    "products": [
      { "name": "Sweater" },
      { "name": "Hat" },
      { "name": "Shirt" }
    ]
  }
}
```

```text Result theme={null}
- Sweater
- Hat
- Shirt

(message.custom_data.products가 비어 있는 경우)
죄송합니다, 모든 제품이 품절되었습니다.
```

<Warning>
  강력하고 유연하지만 liquid 구문에서 `for` 루프를 사용하면 특정 드문 경우에 알림 전달 성능이 저하될 수 있습니다. `for` 루프 사용에 주의하세요. 또한 일부 푸시 채널 필드(`contents`, `headings`, `subtitle`, `apns_alert` 및 `url`)에서 `for` 루프 사용을 방지한다는 점에 유의하세요.
</Warning>

### `limit` & `offset`

루프를 지정된 반복 횟수로 제한합니다. 예를 들어 메시지에 4개의 제품만 표시하려는 경우 제한 및 오프셋을 사용하여 표시되는 제품 수를 지정할 수 있습니다.

```text Data theme={null}
great_numbers = [1,2,3,4,5,6]
```

```text liquid theme={null}
{% for number in great_numbers limit:2 %}
  {{ number }}
{% endfor %}
```

```text Result theme={null}
1 2
```

지정된 인덱스에서 루프를 시작하려면 오프셋 값을 추가합니다:

```text Data theme={null}
great_numbers = [1,2,3,4,5,6]
```

```text liquid theme={null}
{% for number in great_numbers limit: 3 %}
  {{ number }}
{% endfor %}

{% for number in great_numbers limit: 3 offset: 3 %}
  {{ number }}
{% endfor %}
```

```text Result theme={null}
1 2 3
4 5 6
```

### `where`

주어진 속성 값을 가진 객체만 포함하는 배열을 생성하거나 기본적으로 참 값을 가진 객체만 포함합니다.

이 예시에서는 제품 목록이 있고 주방 제품을 별도로 표시하려고 한다고 가정합니다. `where`를 사용하면 `type`이 `kitchen`인 제품만 포함하는 배열을 만들 수 있습니다.

```text Data theme={null}
products = [
  {name:"Vacuum", type:"electronics"},
  {name:"Spatula", type:"kitchen"},
  {name:"Television", type:"electronics"},
  {name:"Garlic press", type:"kitchen"}
]
```

```text liquid theme={null}
All products:
{% for product in products %}
- {{ product.name }}
{% endfor %}

{% assign kitchen_products = products | where: "type", "kitchen" %}

Kitchen products:
{% for product in kitchen_products %}
- {{ product.name }}
{% endfor %}
```

```text Result theme={null}
All products:
  - Vacuum
  - Spatula
  - Television
  - Garlic press

Kitchen products:
- Spatula
- Garlic press
```

***

## 문자열 조작

문자열 필터를 적용하여 메시지에서 태그 값이나 인라인 문자열이 표시되는 방식을 조정합니다.

| 명령어             | 설명                                     | 예시                                                       | 예시 출력       |
| --------------- | -------------------------------------- | -------------------------------------------------------- | ----------- |
| `replace`       | 하위 문자열을 다른 문자열로 바꿉니다.                  | `{{ 'hello world' \| replace: 'world', 'there' }}`       | hello there |
| `capitalize`    | 문자열의 첫 글자를 대문자로 만듭니다.                  | `{{ 'hello' \| capitalize }}`                            | Hello       |
| `upcase`        | 문자열을 대문자로 변환합니다.                       | `{{ 'hello' \| upcase }}`                                | HELLO       |
| `downcase`      | 문자열을 소문자로 변환합니다.                       | `{{ 'HELLO' \| downcase }}`                              | hello       |
| `strip`         | 문자열에서 선행 및 후행 공백을 제거합니다.               | `{{ ' hello ' \| strip }}`                               | hello       |
| `strip_html`    | 문자열에서 모든 HTML 태그를 제거합니다.               | `{{ '<p>hello</p>' \| strip_html }}`                     | hello       |
| `truncate`      | 문자열을 지정된 길이로 줄이고 필요한 경우 줄임표(…)를 추가합니다. | `{{ 'This is a long sentence' \| truncate: 10 }}`        | This is a…  |
| `truncatewords` | 특정 단어 수 이후에 문자열을 자릅니다.                 | `{{ 'This is a long sentence' \| truncatewords: 2 }}`    | This is…    |
| `replace_first` | 하위 문자열의 첫 번째 발생을 바꿉니다.                 | `{{ 'hello world' \| replace_first: 'world', 'there' }}` | hello there |
| `prepend`       | 다른 문자열의 시작 부분에 문자열을 추가합니다.             | `{{ 'world' \| prepend: 'hello ' }}`                     | hello world |
| `append`        | 다른 문자열의 끝에 문자열을 추가합니다.                 | `{{ 'hello' \| append: ' world' }}`                      | hello world |
| `lstrip`        | 문자열에서 선행 공백을 제거합니다.                    | `{{ ' hello' \| lstrip }}`                               | hello       |
| `rstrip`        | 문자열에서 후행 공백을 제거합니다.                    | `{{ 'hello ' \| rstrip }}`                               | hello       |

***

## 자주 묻는 질문

### 대체가 작동하지 않는 이유는 무엇인가요?

* 인앱 메시지는 속성 대체를 지원하지 않습니다.
* "테스트 메시지 보내기"를 사용할 때는 태그 대체가 작동하지 않습니다.
* 태그 키는 영숫자여야 하거나 \_ 및 -를 사용해야 합니다(마침표나 공백 없음).
* 미리보기 모드에서는 대체가 표시되지 않습니다. 테스트하려면 실제 메시지를 보내세요.

### `default`와 `if/else` 중 어떤 것을 사용해야 하나요?

변수 값만 폴백이 필요하고 주변 텍스트가 동일하게 유지될 때는 **`default` 필터**를 사용하세요.

```text liquid theme={null}
Hello {{ name | default: "there" }}!
```

```text Result (name = "Jon") theme={null}
Hello Jon!
```

```text Result (name이 비어 있는 경우) theme={null}
Hello there!
```

주변 텍스트, 구두점 또는 문장 구조도 변수 존재 여부에 따라 변경되어야 할 때는 **`if/else` 조건 논리**를 사용하세요.

```text liquid theme={null}
{% if name %}{{ name }}, shop your favorites!{% else %}Shop your favorites!{% endif %}
```

```text Result (name = "Jon") theme={null}
Jon, shop your favorites!
```

```text Result (name이 비어 있는 경우) theme={null}
Shop your favorites!
```

<Warning>
  문장 구조가 변경될 때는 `default`를 사용하지 마세요. 예를 들어, `{{ name | default: "Shop your favorites" }}, shop your favorites`는 name이 비어 있을 때 "Shop your favorites, shop your favorites"로 렌더링됩니다. 폴백이 변수 이상으로 변경된다면 `if/else`를 사용하세요.
</Warning>

### 공백 및 개행을 제어하는 방법은 무엇인가요?

하이픈을 사용하세요: `{{- ... -}}`, `{%- ... -%}`는 주변 공백을 제거합니다.
자세한 내용은 [공백 제어](https://shopify.github.io/liquid/basics/whitespace/)를 참조하세요.

### 사용자 생성 콘텐츠를 처리하는 방법은 무엇인가요?

사용자 생성 텍스트를 `{% raw %}` 및 `{% endraw %}`로 래핑하여 Liquid 구문 분석을 방지하세요. ["raw" 구문](https://shopify.dev/docs/api/liquid/tags/raw)을 참조하세요.

```json theme={null}
{
  "contents": {
    "en": "{% raw %} Your user-generated content with invalid characters like {{ {% endraw %}"
  }
}
```

***

## 관련 페이지

<Columns cols={2}>
  <Card title="메시지 개인화" icon="wand-magic-sparkles" href="./message-personalization">
    Liquid, Data Feeds 및 커스텀 이벤트를 포함한 모든 개인화 옵션 개요.
  </Card>

  <Card title="Data Feeds" icon="database" href="./data-feeds">
    전송 시 API에서 메시지로 실시간 데이터를 가져옵니다.
  </Card>

  <Card title="태그" icon="tag" href="./add-user-data-tags">
    세분화 및 Liquid 개인화를 위해 사용자에 키-값 쌍을 저장합니다.
  </Card>

  <Card title="템플릿" icon="file-lines" href="./templates">
    Liquid 개인화가 내장된 재사용 가능한 메시지 템플릿을 만듭니다.
  </Card>
</Columns>
