Filter Galleries
Revela supports virtual galleries that automatically select images from a shared pool using filter expressions. Instead of manually organizing photos into folders, you define criteria and Revela builds the gallery dynamically.
π¦ Single Source
Images stored once in _images/ folder. No duplication needed.
π Dynamic Updates
Galleries automatically update when images change or are added.
π Powerful Queries
Filter by EXIF data, filename, date, and more with a simple syntax.
Basic Setup
1. Create Shared Images Folder
Create an _images/ folder (note the underscore prefix) in your source directory:
source/
βββ _images/ # Shared images (not a gallery itself)
β βββ photo-001.jpg
β βββ photo-002.jpg
β βββ ...
βββ canon/ # Filter gallery
β βββ _index.revela
βββ sony/ # Filter gallery
β βββ _index.revela
βββ _index.revela # Homepage
2. Add Filter Expression
In each gallery's _index.revela, add a filter property:
+++
title = "Canon Photos"
filter = "exif.make == 'Canon'"
+++
All photos taken with Canon cameras.
Filter Syntax
Comparison Operators
| Operator | Description | Example |
|---|---|---|
== |
Equal | exif.make == 'Canon' |
!= |
Not equal | exif.make != 'Sony' |
< |
Less than | exif.iso < 800 |
<= |
Less than or equal | exif.focalLength <= 35 |
> |
Greater than | exif.iso > 1600 |
>= |
Greater than or equal | exif.iso >= 3200 |
Logical Operators
Combine conditions with and, or, and not:
# Both conditions must be true
filter = "exif.make == 'Canon' and exif.iso >= 800"
# Either condition can be true
filter = "exif.make == 'Canon' or exif.make == 'Sony'"
# Negate a condition
filter = "not exif.make == 'Canon'"
Precedence: and binds tighter than or. Use parentheses to change order:
# Evaluated as: (a or b) and c
filter = "(exif.make == 'Canon' or exif.make == 'Sony') and exif.iso >= 800"
Available Properties
Image Properties
| Property | Type | Description |
|---|---|---|
filename |
string | Image filename (e.g., photo-001.jpg) |
width |
int | Image width in pixels |
height |
int | Image height in pixels |
fileSize |
long | File size in bytes |
dateTaken |
DateTime | Date photo was taken |
EXIF Properties
Access via exif. prefix:
| Property | Type | Description |
|---|---|---|
exif.make |
string | Camera manufacturer |
exif.model |
string | Camera model |
exif.lensModel |
string | Lens name |
exif.fNumber |
double | Aperture (f/2.8 = 2.8) |
exif.exposureTime |
double | Shutter speed in seconds |
exif.iso |
int | ISO sensitivity |
exif.focalLength |
int | Focal length in mm |
Raw EXIF Access
Access any EXIF tag via exif.raw.TagName:
filter = "exif.raw.Software == 'Lightroom'"
filter = "exif.raw.Artist == 'John Doe'"
filter = "exif.raw.Rating >= 4"
Built-in Functions
Date Functions
| Function | Description | Example |
|---|---|---|
year(date) |
Extract year | year(dateTaken) == 2024 |
month(date) |
Extract month (1-12) | month(dateTaken) == 12 |
day(date) |
Extract day (1-31) | day(dateTaken) == 25 |
String Functions
| Function | Description | Example |
|---|---|---|
contains(str, substr) |
Check if contains | contains(filename, 'portrait') |
starts_with(str, prefix) |
Check prefix | starts_with(filename, 'IMG_') |
ends_with(str, suffix) |
Check suffix | ends_with(filename, '-edit.jpg') |
lower(str) |
To lowercase | lower(exif.make) == 'canon' |
Pipe Syntax
Chain operations using the pipe | operator:
filter_expression | sort property [asc|desc] | limit n
The all Keyword
Select all images without filtering:
filter = "all"
filter = "all | sort dateTaken desc"
filter = "all | sort dateTaken desc | limit 10"
Sort Clause
Sort results by any property:
# Newest first
filter = "all | sort dateTaken desc"
# By EXIF property
filter = "exif.make == 'Canon' | sort exif.iso desc"
Limit Clause
Restrict the number of results:
# Only 5 images
filter = "all | limit 5"
# 10 newest photos
filter = "all | sort dateTaken desc | limit 10"
Common Patterns
By Camera Brand
filter = "exif.make == 'Canon'"
filter = "exif.make == 'Sony'"
filter = "exif.make == 'Canon' or exif.make == 'Sony'"
By Year
filter = "year(dateTaken) == 2024"
filter = "year(dateTaken) >= 2020 and year(dateTaken) <= 2024"
High ISO (Low Light)
filter = "exif.iso >= 3200"
filter = "exif.iso >= 1600 | sort exif.iso desc"
Wide Angle / Telephoto
filter = "exif.focalLength <= 35" # Wide angle
filter = "exif.focalLength >= 85" # Portrait/Telephoto
Recent Photos (Homepage)
filter = "all | sort dateTaken desc | limit 5"
Best Rated
filter = "exif.raw.Rating >= 4 | sort exif.raw.Rating desc"
Filter vs Sort
| Feature | Filter (filter =) |
Sort (sort =) |
|---|---|---|
| Purpose | Select images from _images/ |
Order images in any gallery |
| Scope | Creates virtual gallery | Works on existing images |
| Use case | Dynamic collections | Custom ordering |
You can use both together:
+++
filter = "exif.make == 'Canon'"
sort = "dateTaken:desc"
+++