10 KiB
🧠 Smart Lists
Access through
/search
Smart Lists allow you to create saved search filters that appear as "virtual folders" in your OPDS feed.
Creating Smart Lists
Simple Filters
Add filters using the web interface:
series=Batmanyear=2024publisher=DC Comics
Advanced Filters
Create complex queries with multiple conditions:
series contains 'Scrooge McDuck'
volume equals 1953
number >= 285
number <= 297
JSON Configuration Example
For advanced users, Smart Lists are stored in /data/smartlist.json:
{
"name": "Maul + Vader (1-5)",
"slug": "maul-vader-1-5",
"groups": [
{
"rules": [
{
"not": false,
"field": "series",
"op": "contains",
"value": "Maul"
},
{
"not": false,
"field": "number",
"op": "<=",
"value": "5"
},
{
"not": false,
"field": "format",
"op": "equals",
"value": "Limited Series"
}
]
},
{
"rules": [
{
"not": false,
"field": "series",
"op": "contains",
"value": "Vader"
},
{
"not": false,
"field": "number",
"op": "<=",
"value": "5"
},
{
"not": false,
"field": "format",
"op": "equals",
"value": "Main Series"
}
]
}
],
"sort": "series_number",
"limit": 0,
"distinct_by": "",
"distinct_mode": "oldest"
}
Maul + Vader (1-5):
- Group 1:
- series contains "Maul"
- number <= 5
- format = "Limited Series"
- Group 2:
- series contains "Vader"
- number <= 5
- format = "Main Series"
- Sort:
- series_number
- limit: 0
- Distinct: no
Supported Fields
All metadata fields from ComicInfo.xml plus:
filename- File name (useful for custom naming schemes, e.g.,filename contains "[R]"for read status)name- Same as filename
Supported Operations
equals,contains,startswith,endswith=,!=,>=,<=,>,<(for numeric fields)notmodifier for any operation
"Distinct by series and volume (latest)"
When that option is enabled, a smart list will return at most one comic per series and volume. For each series, it picks the latest issue, using this tie-break:
- Newer year (cast to integer)
- If year ties: higher number (cast to integer)
- If number ties: newer file mtime (last modified time)
So you get a de-duplicated "what's the newest issue for each series?" view.
Use Cases:
- A clean "latest per series" shelf (e.g., to see what's new without 300 issues of Batman).
- Weekly pulls / backlog triage: combine with filters like
publisher=Imageoryear >= 2020.
Important details / edge cases
- Numeric casting: blank or non-numeric
year/numberare treated asNULL→ effectively0, so those won't beat entries with proper numbers (eg.16A).
Example use
- "Latest Image series":
- Rules:
publisher = "Image Comics",year >= 2018 - Distinct by series: on
- Rules:
→ One newest issue per Image series since 2018.
Dynamic Smart Lists (Auto-Grouping)
Dynamic Smart Lists automatically create sub-folders based on distinct values in a metadata field. Instead of manually creating one smart list per writer, publisher, or series, you can create a single dynamic smart list that generates them automatically.
This feature provides folder/stack view within smart lists - perfect for organizing search results by series, writer, publisher, or any other field.
How It Works
When you set the Group By field to a metadata field (e.g., series, writer, publisher, format):
- The smart list becomes a navigation folder showing all distinct values for that field
- Each value appears as a sub-folder with a count (e.g., "Batman (1940)" (127), "Batman vs. Dracula" (4))
- Clicking a sub-folder shows all comics matching both:
- Your smart list filters (if any)
- That specific field value
Example: Browse Batman Comics by Series
Instead of getting a long flat list of all Batman issues, you can create a grouped view:
Create a smart list named "Batman Comics":
- Group By:
series - Rules:
series contains "Batman" - Sort:
series_number
Result: You get folder/stack view like:
Batman Comics/
├── Batman (1940) (387)
├── Batman and Robin (2009) (26)
├── Batman vs. Dracula (4)
├── Batman: The Dark Knight (2011) (29)
└── ...
Clicking into "Batman (1940)" shows all 387 issues sorted by number.
Example: Browse by Writer
Create a smart list named "All Writers":
- Group By:
writer - Rules: (optional) Add filters to narrow down, e.g.,
year >= 2020 - Sort:
series_numberorissued_desc
Result: You get a folder structure like:
All Writers/
├── Brian K. Vaughan (47)
├── Ed Brubaker (92)
├── Grant Morrison (156)
├── Jeff Lemire (73)
└── ...
Example: Browse Trade Paperbacks by Series
Create "TPB by Series":
- Group By:
series - Rules:
format equals "TPB" - Sort:
series_number
Result: Only TPBs, organized by series name.
Supported Group By Fields
writer- Group by writer/authorpublisher- Group by publisherseries- Group by series nameformat- Group by format (TPB, Hardcover, etc.)year- Group by publication yeartags- Group by tagscharacters- Group by character appearancesteams- Group by team appearancesgenre- Group by genre
Combining with Regular Filters
Dynamic smart lists work with all regular smart list features:
- Filters: Pre-filter comics before grouping (e.g., only 2020+ or only Image Comics)
- Distinct: De-duplicate by series+volume
- Limit: Cap results per sub-folder
- Sort: Control ordering within each group
Issued (newest first)- Sort by publication date (year/month/day)Series + Number- Sort by series name and issue numberTitle- Sort alphabetically by titlePublisher- Group by publisher, then seriesRecently Added- Sort by when the file was added to your library (requiresENABLE_WATCH=truefor accurate timestamps)
JSON Configuration Example
{
"name": "Recent Comics by Writer",
"slug": "recent-by-writer",
"group_by": "writer",
"groups": [
{
"rules": [
{
"not": false,
"field": "year",
"op": ">=",
"value": "2020"
}
]
}
],
"sort": "issued_desc",
"limit": 0,
"distinct_by": "",
"distinct_mode": "latest"
}
This creates a dynamic list showing all writers who published comics since 2020, with each writer's comics sorted by newest first.
Screenshot
CBL Reading Lists
ComicOPDS supports .cbl files (ComicRack Reading List format) as a separate "Reading Lists" section in the OPDS feed.
What are CBL files?
CBL files are XML-based reading lists exported from comic book managers like ComicRack. They define a list of comics using two matching methods:
- Explicit Books — specific issues referenced by Series, Number, Volume, and Year
- Series Matchers — pattern-based rules that match all issues of a series by name
Note: CBL files are meant to be exported from ComicRack. They are not a practical format to create by hand. If you want to build custom lists without ComicRack, use the Smart Lists feature and its built-in web UI instead.
Setup
- Place your
.cblfiles in the/data/directory (the./datavolume mount in yourcompose.yaml) - No restart or reindex needed — CBL lists are read on the fly
OPDS Feed
CBL reading lists appear as a separate "Reading Lists" folder in the OPDS root, alongside the existing "Smart Lists" folder:
Library/
├── 📁 Smart Lists
├── 📁 Reading Lists
│ ├── Stranger Things
│ └── Letter 44
├── DC/
├── Marvel/
└── ...
CBL File Format
Explicit Book List
Lists specific issues by Series, Number, Volume, and Year. Comics are matched against your library's ComicInfo.xml metadata (case-insensitive series matching).
<?xml version="1.0"?>
<ReadingList>
<Name>Stranger Things</Name>
<Books>
<Book Series="Stranger Things SIX" Number="1" Volume="2019" Year="2019" />
<Book Series="Stranger Things SIX" Number="2" Volume="2019" Year="2019" />
<Book Series="Stranger Things" Number="1" Volume="2018" Year="2018" />
</Books>
<Matchers />
</ReadingList>
Series Matcher
Matches all issues of a series by name. Useful for collecting an entire run without listing every issue.
<?xml version="1.0"?>
<ReadingList>
<Name>Letter 44</Name>
<Books />
<Matchers>
<ComicBookMatcher xsi:type="ComicBookSeriesMatcher"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MatchValue>Letter 44</MatchValue>
</ComicBookMatcher>
</Matchers>
</ReadingList>
Combined
A single CBL file can use both explicit books and matchers — results are combined.
Matching Behavior
| CBL Element | Matches Against | Logic |
|---|---|---|
Book Series="X" |
m.series (case-insensitive) |
AND with Number/Volume if present |
Book Number="N" |
m.number (exact) |
Optional, narrows match |
Book Volume="V" |
m.volume (exact) |
Optional, narrows match |
ComicBookSeriesMatcher |
m.series (case-insensitive) |
Matches all issues of that series |
Multiple books and matchers within a single CBL file are combined with OR logic.