# Liquid Basics
## Object Handles
Objects representing store resources (products, collections, articles, blogs) use handles to identify individual resources. Handles construct resource URLs and retrieve their properties.
### Creating and Modifying Handles
Handles follow automatic generation rules:
- Always lowercase
- Whitespace and special characters convert to hyphens
- Consecutive whitespace/special characters become a single hyphen
- Leading whitespace/special characters are removed
- Duplicates are auto-incremented (e.g., `potion` and `potion-1`)
Changing a resource title after creation doesn't update its handle. Manually modify handles through the Shopify admin in the Handle or Edit website SEO sections.
**Note:** Individual links from linklists have handles based on titles but cannot be modified directly. Settings get handles from their `id` property.
### Referencing Handles
All objects with handles have a `handle` property. Access objects by their handle using two methods:
- **Square bracket notation** `['handle-name']`: Accepts quoted handles, variables, or object references
- **Dot notation** `.handle_name`: Accepts unquoted handles
## Logical and Comparison Operators
Liquid supports basic operators for conditional tags (`if`, `unless`, `case`, `else`):
| Operator | Function |
|----------|----------|
| `==` | Equals |
| `!=` | Does not equal |
| `>` | Greater than |
| `<` | Less than |
| `>=` | Greater than or equal to |
| `<=` | Less than or equal to |
| `or` | Condition A or Condition B |
| `and` | Condition A and Condition B |
| `contains` | Check strings in strings or arrays |
### contains Operator
The `contains` operator checks for string presence within arrays or strings, but cannot verify object existence in object arrays.
### Order of Operations
Multiple operators evaluate right to left without changeable precedence. Parentheses are invalid in Liquid tags.
## Data Types
Liquid supports six data types:
**String:** Character series wrapped in single or double quotes. Check emptiness with the `blank` object.
**Number:** Numeric values including floats and integers.
**Boolean:** Binary values—`true` or `false`.
**Nil:** Undefined value. Tags returning `nil` print nothing and evaluate as `false`. A string containing "nil" differs from `nil`.
**Array:** Variable lists of any type. Access items via square bracket indexing (starting at zero). Create arrays using the `split` filter.
**Empty:** Returned when accessing defined but valueless objects (deleted pages, products, or unset settings). Compare objects with `empty` before accessing attributes.
## Truthy and Falsy Values
Data types return either `true` (truthy) or `false` (falsy):
**Falsy values:** `false`, `nil`
**Truthy values:** `true`, non-empty strings, `0`, integers, floats, arrays, pages, objects
Important distinction: Empty strings and `EmptyDrop` objects are truthy. Use `blank` for string checks and `empty` for object verification.
## Whitespace Control
Liquid tags generate output lines even without visible text. Include hyphens in tags to strip generated whitespace:
- `{%- tag -%}`: Removes whitespace on both sides
- `{%- tag %}`: Removes whitespace on the left only
- `{% tag -%}`: Removes whitespace on the right only
This prevents unwanted blank lines in rendered content while maintaining code readability.