Files
Libation/docs/features/naming-templates.md
2026-05-01 10:05:41 -04:00

53 KiB
Raw Blame History

pageClass
pageClass
naming-templates-mono

Naming Templates

File and Folder names can be customized using Libation's built-in tag template naming engine. To edit how folder and file names are created, go to Settings > Download/Decrypt and edit the naming templates. If you're splitting your audiobook into multiple files by chapter, you can also use a custom template to set each chapter's title metadata tag by editing the template in Settings > Audio File Options.

These templates apply to both GUI and CLI.

Template Tags

These are the naming template tags currently supported by Libation.

Property Tags

These tags will be replaced in the template with the audiobook's values.

Tag Description Type
<id> Audible book ID (ASIN) Text
<title> Full title with subtitle Text
<title short> Title. Stop at first colon Text
<audible title> Audible's title (does not include subtitle) Text
<audible subtitle> Audible's subtitle Text
<author> Author(s) Name List
<first author> First author Name
<narrator> Narrator(s) Name List
<first narrator> First narrator Name
<series> All series to which the book belongs (if any) Series List
<first series> First series Series
<series#> Number order in series (alias for <first series[{#}]> Number
<minutes> Duration of the audiobook in minutes TimeSpan
<bitrate> Bitrate (kbps) of the last downloaded audiobook Number
<samplerate> Sample rate (Hz) of the last downloaded audiobook Number
<channels> Number of audio channels in the last downloaded audiobook Number
<codec> Audio codec of the last downloaded audiobook Text
<file version> Audible's file version number of the last downloaded audiobook Text
<libation version> Libation version used during last download of the audiobook Text
<account> Audible account of this book Text
<account nickname> Audible account nickname of this book Text
<tag> Tag(s) Text List
<first tag> First tag Text
<locale> Region/country Region
<year> Year published Number
<language> Book's language Language
<language short> Book's language abbreviated. Eg: ENG Text
<os> Language currently set in the operating system Language
<ui> User interface language Language
<file date> File creation date/time. DateTime
<pub date> Audiobook publication date DateTime
<date added> Date the book added to your Audible account DateTime
<ch count> Number of chapters Number
<ch title> Chapter title Text
<ch#> Chapter number Number
<ch# 0> Chapter number with leading zeros Number

Does not support custom formatting

Only valid for Chapter Filename and Chapter Tile Metadata

To change how these properties are displayed, read about custom formatters

Conditional Tags

Anything between the opening tag (<tagname->) and closing tag (<-tagname>) will only appear in the name if the condition evaluates to true.

Tag Description Type
<if series->...<-if series> Only include if part of a book series or podcast Conditional
<if podcast->...<-if podcast> Only include if part of a podcast Conditional
<if bookseries->...<-if bookseries> Only include if part of a book series Conditional
<if podcastparent->...<-if podcastparent> Only include if item is a podcast series parent Conditional
<if abridged->...<-if abridged> Only include if item is abridged Conditional
<has PROPERTY->...<-has> Only include if the PROPERTY has a value (i.e. not null or empty) Conditional
<is PROPERTY[CHECK]->...<-is> Only include if the PROPERTY or a single value of a list PROPERTY satisfies the CHECK Conditional
<is PROPERTY[FORMAT][CHECK]->...<-is> Only include if the formatted PROPERTY or a single value of a list PROPERTY satisfies the CHECK Conditional
<is PROPERTY[...separator(...)...][CHECK]->...<-is> Only include if the joined form of all formatted values of a list PROPERTY satisfies the CHECK Conditional
<cmp 1st-PROPERTY [CHECK] 2nd-PROPERTY->...<-cmp> Only include if two given PROPERTIES satisfy the CHECK Conditional

Only affects the podcast series folder naming if "Save all podcast episodes to the series parent folder" option is checked.

For example, <if podcast-><series><-if podcast> will evaluate to the podcast's series name if the file is a podcast. For audiobooks that are not podcasts, that tag will be blank.

You can invert the condition (instead of displaying the text when the condition is true, display the text when it is false) by playing a ! symbol before the opening tag name.

Inverted Tag Description Type
<!if series->...<-if series> Only include if not part of a book series or podcast Conditional
<!if podcast->...<-if podcast> Only include if not part of a podcast Conditional
<!if bookseries->...<-if bookseries> Only include if not part of a book series Conditional
<!if podcastparent->...<-if podcastparent> Only include if item is not a podcast series parent Conditional
<!has PROPERTY->...<-has> Only include if the PROPERTY does not have a value (i.e. is null or empty) Conditional
<!is PROPERTY[CHECK]->...<-is> Only include if neither the whole PROPERTY nor the values of a list PROPERTY satisfies the CHECK Conditional
<!cmp 1st-PROPERTY [CHECK] 2nd-PROPERTY->...<-cmp> Only include if two given PROPERTIES do not satisfy the CHECK Conditional

Only affects the podcast series folder naming if "Save all podcast episodes to the series parent folder" option is checked.

As an example, this folder template will place all Liberated podcasts into a "Podcasts" folder and all liberated books (not podcasts) into a "Books" folder.

<if podcast->Podcasts<-if podcast><!if podcast->Books<-if podcast><title>

This example will add a number if the <series#> tag has a value:

<has series#><series#><-has>

This example will put non-series books in a "Standalones" folder:

<!if series->Standalones/<-if series>

And this example will customize the title based on whether the book has a subtitle:

<audible title><has audible subtitle->-<audible subtitle><-has>

Tag Formatters

Text, Name, Series, Number, TimeSpan, DateTime, Region, Language and their List tags can be optionally formatted using format text in square brackets after the tag name. Below is a list of supported formatters for each tag type.

Text Formatters

Text formatting can change length and case of the text. Use <#>, <#><case> or <case> to specify one or both of these.

Formatter Description Example Usage Example Result
# Cuts down the text to the specified number of characters <title[14]> A Study in Scar
L Converts text to lowercase <title[L]> a study in scarlet a sherlock holmes novel
U Converts text to uppercase <title short[U]> A STUDY IN SCARLET
t Converts text to title case <title[t]> The Abc Murders
T Converts text to title case where uppercase words are preserved <title[T]> The ABC Murders
<title[6T]> The AB

Text List Formatters

Formatter Description Example Usage Example Result
separator() Specify the text used to join
multiple entries.

Default is ", "
<tag[separator(_)]> Tag1_Tag2_Tag3_Tag4_Tag5
format({S}) Formats the entries by placing their values into the specified template.
Use {S:Text formatters} to place the entry and optionally apply a format.
<tag[format(Tag={S:l})
separator(;)]>
Tag=tag1;Tag=tag2;Tag=tag3;Tag=tag4;Tag=tag5
sort(S) Sorts the elements by their value.

Sorting direction:
uppercase = ascending
lowercase = descending

Default is unsorted
<tag[sort(s)
separator(;)]>
Tag5;Tag4;Tag3;Tag2;Tag1
max(#) Only use the first # of entries <tag[max(1)]> Tag1
slice(#) Only use the nth entry of the list <tag[slice(2)]> Tag2
slice(#..) Only use entries of the list starting from # <tag[slice(2..)]> Tag2, Tag3, Tag4, Tag5
slice(..#) Like max(#). Only use the first # of entries <tag[slice(..1)]> Tag1
slice(#..#) Only use entries of the list starting from # and ending at # (inclusive) <tag[slice(2..4)]> Tag2, Tag3, Tag4
slice(-#..-#) Numbers may be specified negative. In that case positions ar counted from the end with -1 pointing at the last member <tag[slice(-3..-2)]> Tag3, Tag4

For further information on format templates, please refer to the Format templates section.

Series Formatters

Formatter Description Example Usage Example Result
{N | # | ID} Formats the series using
the series part tags.
{N:Text_Formatter} = Series Name
{#:Number_Formatter} = Number order in series
{ID:Text_Formatter} = Audible Series ID

Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the corresponding formatter.

Default is {N}
<first series>
<first series[{N:l}]>
<first series[{N}, {#}, {ID}]>
<first series[{N:10U}, {ID}, {#:00.0}]>
Sherlock Holmes
sherlock holmes
Sherlock Holmes, 1-6, B08376S3R2
SHERLOCK H, B08376S3R2, 01.0-06.0

For further information on format templates, please refer to the Format templates section.

Series List Formatters

Formatter Description Example Usage Example Result
separator() Specify the text used to join
multiple series names.

Default is ", "
<series[separator(; )]> Sherlock Holmes; Some Other Series
format({N | # | ID}) Formats the series properties
using the name series tags.
See Series Formatter Usage above.
<series[format({N}, {#})
separator(; )]>
<series[format({ID}-{N}, {#:00.0})]>
Sherlock Holmes, 1-6; Book Collection, 1
B08376S3R2-Sherlock Holmes, 01.0-06.0, B000000000-Book Collection, 01.0
sort(N | # | ID) Sorts the series by name, number or ID.

These terms define the primary, secondary, tertiary, … sorting order.
You may combine multiple terms in sequence to specify multilevel sorting.

Sorting direction:
uppercase = ascending
lowercase = descending

Default is unsorted
<series[sort(N)
separator(; )]>
Book Collection, 1; Sherlock Holmes, 1-6
max(#) Only use the first # of series <series[max(1)]> Sherlock Holmes
slice(#..#) Only use entries of the series list starting from # and ending at # (inclusive)

See Text List Formatter Usage above for details on all the variants of slice()
<series[slice(..-2)]> Sherlock Holmes

For further information on format templates, please refer to the Format templates section.

Name Formatters

Formatter Description Example Usage Example Result
{T | F | M | L | S | ID} Formats the human name using
the name part tags.
{T:Text_Formatter} = Title (e.g. "Dr.")
{F:Text_Formatter} = First name
{M:Text_Formatter} = Middle name
{L:Text_Formatter} = Last Name
{S:Text_Formatter} = Suffix (e.g. "PhD")
{ID:Text_Formatter} = Audible Contributor ID

Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the correspoing formatter.

Default is {T} {F} {M} {L} {S}
<first narrator[{L}, {F:1}.]>
<first author[{L:u}, {F} _{ID}_]>
Fry, S.
DOYLE, Arthur _B000AQ43GQ_

For further information on format templates, please refer to the Format templates section.

Name List Formatters

Formatter Description Example Usage Example Result
separator() Specify the text used to join
multiple people's names.

Default is ", "
<author[separator(; )]> Arthur Conan Doyle; Stephen Fry
format({T | F | M | L | S | ID}) Formats the human name using
the name part tags.
See Name Formatter Usage above.
<author[format({L:u}, {F})
separator(; )]>
<author[format({L}, {F:1}.
_{ID}_) separator(; )]>
DOYLE, Arthur; FRY, Stephen
Doyle, A. _B000AQ43GQ_;
Fry, S. _B000APAGVS_
sort(T | F | M | L | S | ID) Sorts the names by title,
first, middle, or last name,
suffix or Audible Contributor ID

These terms define the primary, secondary, tertiary, … sorting order.
You may combine multiple terms in sequence to specify multilevel sorting.

Sorting direction:
uppercase = ascending
lowercase = descending

Default is unsorted
<author[sort(M)]>
<author[sort(Fl)]>
<author[sort(L FM ID)]>
Stephen Fry, Arthur Conan Doyle
Stephen King, Stephen Fry
John P. Smith _B000TTTBBB_, John P. Smith _B000TTTCCC_, John S. Smith _B000HHHVVV_
max(#) Only use the first # of names

Default is all names
<author[max(1)]> Arthur Conan Doyle
slice(#..#) Only use entries of the names list starting from # and ending at # (inclusive)

See Text List Formatter Usage above for details on all the variants of slice()
<author[slice(..-2)]> Arthur Conan Doyle

For further information on format templates, please refer to the Format templates section.

TimeSpan Formatters

For more custom formatters and examples, see this guide from Microsoft.

Formatter Description Example Usage Example Result
d The "d" custom format specifier outputs the value of the TimeSpan.Days property, which represents the number of whole days in the time interval. It outputs the full number of days in a TimeSpan value, even if the value has more than one digit. If the value of the TimeSpan.Days property is zero, the specifier outputs "0".

Use "dd"-"dddddddd" for zero padding up to the specified size.
<minutes[dd]> 02
h The "h" custom format specifier outputs the value of the TimeSpan.Hours property, which represents the number of whole hours in the time interval that isn't counted as part of its day component. It returns a one-digit string value if the value of the TimeSpan.Hours property is 0 through 9, and it returns a two-digit string value if the value of the TimeSpan.Hours property ranges from 10 to 23.

Use "hh" for zero padding.
<minutes[hh]> 14
m The "m" custom format specifier outputs the value of the TimeSpan.Minutes property, which represents the number of whole minutes in the time interval that isn't counted as part of its day component. It returns a one-digit string value if the value of the TimeSpan.Minutes property is 0 through 9, and it returns a two-digit string value if the value of the TimeSpan.Minutes property ranges from 10 to 59.

Use "mm" for zero padding.
<minutes[m]> 42
'string' Literal string delimiter. <minutes[d'd 'h'h 'm'm']> 2d 14h 42m
\ The escape character. <minutes[d\d h\h m\m]> 2d 14h 42m

These formatters have been enhanced to allow the display of days, hours or months beyond their usual limits. For example, the total number of hours, even if it exceeds 23. Here, a number format is inserted for the desired part in accordance with Microsoft's instructions. Unlike standard number formats, however, the letters D, H or M (uppercase) are used instead of zeros.

Formatter Description Example Usage Example Result
D A number format with "D" instead of "0". Using this will output the total number of days and reduce the amount of minutes avalable for "H" and "M". <minutes[DD]> 02
H A number format with "H" instead of "0". Using this will output the total number of hours and reduce the amount of minutes available for "M". <minutes[HH]> 62
M A number format with "M" instead of "0". Using this will output the total number of minutes. <minutes[#,#MM]> 3,762
D H M A combination of the above. <minutes[D'days 'MM'minutes']> 02days 882minutes

Number Formatters

For more custom formatters and examples, see this guide from Microsoft.

Formatter Description Example Usage Example Result
[integer] Zero-pads the number <bitrate[4]>
<series#[3]>
<samplerate[6]>
0128
001
044100
0 Replaces the zero with the corresponding digit if one
is present; otherwise, zero appears in the result string.
<series#[000.0]> 001.0
# Replaces the "#" symbol with the corresponding digit if one
is present; otherwise, no digit appears in the result string
<series#[00.##]> 01

Date Formatters

For more standard formatters, see this guide from Microsoft.

Standard DateTime Formatters

Formatter Description Example Usage Example Result
s Sortable date/time pattern. <file date[s]> 2023-02-14T13:45:30
Y Year month pattern. <file date[Y]> February 2023

Custom DateTime Formatters

You can use custom formatters to construct customized DateTime string. For more custom formatters and examples, see this guide from Microsoft.

Formatter Description Example Usage Example Result
yyyy 4-digit year <file date[yyyy]> 2023
yy 2-digit year <file date[yy]> 23
MM 2-digit month <file date[MM]> 02
dd 2-digit day of the month <file date[yyyy-MM-dd]> 2023-02-14
HH
mm
The hour, using a 24-hour clock from 00 to 23
The minute, from 00 through 59.
<file date[HH:mm]> 14:45

Region Formatters

You can specify which part of a region you are interested in.

Formatter Description Example Usage Example Result
{O | I | I2 | I3 | E | N | W | L | T | ID} Formats the region using
the region part tags.
{O:Text_Formatter} = Region as used in Libation
{I:Text_Formatter} = Two letter ISO code
{I2:Text_Formatter} = Two letter ISO code
{I3:Text_Formatter} = Three letter ISO code
{E:Text_Formatter} = English name
{N:Text_Formatter} = Native name - OS dependent
{W:Text_Formatter} = Unique Windows code
{L:Text_Formatter} = Lang code used for this region/store
{T:Text_Formatter} = TLD under which the audible store is hosted
{ID:Text_Formatter} = Region code


Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the corresponding formatter.

Default is {O}
<locale[{I} ({E})]>
www.audible.<locale[{T}]>
US (United States)
www.audible.com
{D} , Display name interpreted by the current language settings.
To ensure output in a specific language the lang-code to use might be specified with a leading '@'.
Formatter part is also optional and introduced by the colon.
{D@LANG:Text_Formatter}
<locale[{D@es:u}]> ESTADOS UNIDOS

For further information on format templates, please refer to the Format templates section.

LANG may be any code from the ISO 639-1 standard like es for Spanish, en for English, de for German, etc. or even a IETF language tag like 'fr-CA'.

Language Formatters

You can specify which part of a language you are interested in.

Formatter Description Example Usage Example Result
{O | I | I2 | I3 | E | N | W | ID} Formats the language using
the language part tags.
{O:Text_Formatter} = Language as provided by audible
{I:Text_Formatter} = Two letter ISO code
{I2:Text_Formatter} = Two letter ISO code
{I3:Text_Formatter} = Three letter ISO code
{E:Text_Formatter} = English name
{N:Text_Formatter} = Native name - OS dependent
{W:Text_Formatter} = Unique Windows code
{ID:Text_Formatter} = Lang code

Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the corresponding formatter.

Default is {O}
<language[{I3:l} ({E})]> fra (French)
{D} , Display name interpreted by the current language settings.
To ensure output in a specific language the lang-code to use might be specified with a leading '@'.
Formatter part is also optional and introduced by the colon.
{D@LANG:Text_Formatter}
<language[{D@es}]> francés

For further information on format templates, please refer to the Format templates section.

LANG may be any code from the ISO 639-1 standard like es for Spanish, en for English, de for German, etc. or even a IETF language tag like 'fr-CA'.

Format Templates

Depending on which property is to be displayed, one or more placeholders can be used in a format template. The placeholders are defined in the form {A}:

<first author[{F} {U}]>

The format template must sometimes be enclosed in square brackets and sometimes in round brackets. In addition to placeholders, the format template may also contain arbitrary text. To prevent this text from being mistaken for a bracket at the end of the template or a placeholder, escapes can be used within the text:

  • \x - Escapes the next character.
  • \\ - Escapes a backslash.
  • "text" - encloses text that may contain special characters. To include a double quote in the text, escape it by doubling it: "She said ""Hello""" will output She said "Hello".
  • 'text'- encloses text that may contain special characters. To include a single quote in the text, escape it by doubling it: 'It''s a test' will output It's a test.

<series[separator(,) format('{Series:' {N}\})]>

Not all elements of a property are always present or have content. In this case, format templates would contain gaps after substitution. Groups of spaces are automatically merged. Other characters, however, remain unchanged. By doubling the curly brackets, you can specify text fragments before and after the placeholder, which are only used if the placeholder is replaced with content.

<narrator[format({{F} }{({M}') '}{L})]> -> Neil Gaiman, Christopher (Evan) Welch

Checks

There are two formats for checks, with slightly different syntax for specifying parameters:

<is PROPERTY[CHECK-with-value]->...<-is>

<cmp 1st-PROPERTY CHECK 2nd-PROPERTY->...<-cmp>

For CHECK-with-value, the value (2nd parameter) is specified directly after the check operator (e.g., =). This may be a number or a string with escaped characters like \]. Single backslashes must be doubled if they are part of the string.

1st-PROPERTY and 2nd-PROPERTY may be any of the properties listed in the Property tags section, or they may be string or number literals. Use digits only for numbers. To specify a string literal, enclose it in single or double quotes. If the string contains a single or double quote, escape it by doubling it. For example, to specify the string literal O'Reilly, you can use either 'O''Reilly' or "O'Reilly".

String Checks Unicode Operator Description Examples
= Matches if values are equal (case-insensitive) <is tag[=Tag1]->
!= Matches if values are not equal (case-insensitive) <is first author[!=Arthur]->
<cmp "foo" != 'bar'->
~ Matches if the first parameter matches the regular expression specified by the second parameter (case-insensitive) <is title[~([XYZ]).*\1]->
Number Checks Unicode Operator Description Examples
#= Matches if the number value equals NUMBER <is channels[#=2]->
<cmp channels #= 1->
#!= Matches if the number value does not equal NUMBER <is author[#!=1]->
#>= Matches if the number value is greater than or equal to NUMBER <is bitrate[#>=128]->
<cmp 44100 #>= samplerate->
#> Matches if the number value is greater than NUMBER <is title[#>30]->
<cmp minutes #> 60->
#<= Matches if the number value is less than or equal to NUMBER <is first narrator[format({F})][#<=1]->
#< Matches if the number value is less than NUMBER <is author[#<3]->
List Checks Unicode Operator Description Examples
== | :equals: Matches if both values contain the same elements <cmp author[slice(-2..-1)] == narrator[slice(..2)]->
>> | :contains: Matches if the first parameter contains the second parameter <is author[format({L})][∋King]->
!>> | :not_contains: Matches if the first parameter does not contain the second parameter <cmp series :not_contains: 'Harry Potter'->
<< | :in: Matches if the first parameter is contained in the second parameter <cmp first author << author[slice(2..)]->
!<< | :not_in: Matches if the first parameter is not contained in the second parameter <cmp author[slice(1)] ∉ narrator->
&& | :overlaps: Matches if both values share at least one element <cmp author && narrator->
&&! | :disjoint: ⋂̸ Matches if both values share no elements <cmp tag :disjoint: series->
<=< | :subset: Matches if all elements from the first parameter are found in the second parameter <cmp author[slice(-3..)] <=< author[slice(..-4)]->
>=> | :superset: Matches if the first parameter contains all elements from the second parameter <cmp author ⊇ narrator->
<-< | :proper_subset: Matches if all elements from the first parameter are found in the second parameter, and the second has additional elements <cmp author[slice(..2)] :proper_subset: author->
>-> | :proper_superset: Matches if the first parameter contains all elements from the second parameter plus at least one additional element <cmp author ⊃ narrator->

NUMBER checks on lists check the size of the list. For string values, the string length is used.

More Complex Examples

This example truncates the title to 4 characters and checks if its (trimmed) value equals "the" (case-insensitive):

<is title[4][=the]>

This example takes tags 2 through 4, joins them with a colon, and checks if the result equals "Tag2:Tag3:Tag4":

<is tag[separator(:)slice(2..4)][=Tag2:Tag3:Tag4]->