Revela

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"
+++