CC file name templates are similar to calibre templates. You can use some column names, a prefix, and a suffix, and printf-style format specifications. An if-then-else construct is available to support conditional text; this construct is not supported by calibre. It does not support template functions.
- The CC Template Language
- Basic syntax
- The columns allowed are:
- {title}, {title_sort} (title is the real title. No articles are moved)
- {authors}, {first_author}, {author_sort}, {first_author_sort}
- {series}, {series_index}
- {id} (the calibre database identifier, which is a number)
- text-type custom columns {#col_lookup_name}
- (CC version 4.3.4 and later) custom series columns. A custom series lookup name such as #series returns the custom series name without the index, and the lookup name with _index appended (e.g., #series_index) returns the custom series index as a number.
- Prefixes and suffixes are specified as in calibre:
Code:
{column:| prefix | suffix}
Code:{series:| - |}
- Format specifications can be supplied as in calibre, but using printf format syntax instead of Python syntax. The usual use is to format a series index but it can be used for other purposes. Because series_index can be either an integer or a floating point number, you can supply two format specifiers: one for each. See the example below.
Use this syntax to add a format specification:
Code:{columnName:format|prefix|suffix)
A format specifier is a string beginning with a % character and ending with a format type character. Examples:- %d -- format as an integer
- %04d -- format as an integer four digits long and zero-filled
- %06.2f -- format as a floating point number 6 characters wide, zero-filled, with 3 digits to the left of the decimal point and 2 digits to the right of the decimal point.
- %.10s -- format as a string to be at most 10 characters long.
As a special case, series_index can have two format specifiers, one to use if the index is an integer and the other to use if the index is a floating point number. The second format specifier is separated from the first by a slash. See the third example below for more details.
As a second special case and starting with CC V5.1.5.1, you can use the format specifier allowslashes to tell CC not to strip slashes from template items during expansion. This permits storing paths in custom columns. - The following are examples of complete templates. The first has one segment (segments are separated by slashes):
Code:{title} - {authors} ({id})
Code:{series}/{title} - {authors} ({id})
Code:{series} {series_index:%03d/%06.2f| [|]}/{title}-{authors} ({id})
- The columns allowed are:
- Conditional text (if-then-else) is specified as follows:
Code::if: some template :then: another template :else: another template :::
Some notes:- The :else: part is optional: it is legal to have
Code::if: template :then: template 2 :::
- In the then and else templates, the special value :tv: will be replaced with the value of the :if: template. (Yes, this doesn't have much use in the :else: part because it will always be empty.)
- Spaces after the :if:, around :then: and :else:, and before ::: are removed.
- You cannot nest an if-then-else inside another if-then-else. In other words, the following will not work because the second :if: is inside the first :else: part.
Code::if: {something} :then: bla :else: :if: {something else} :then: mumble ::: :::
- :if:{series}:then: :tv:/ :else:{first_author}/:::
If the series is not empty then create a directory named by the series, otherwise create a directory named by the first author. - :if: {#genre} :then: {#genre:|Genre |} :else: {series:|Series ||} ::: {title}
If the genre is not empty then prefix the title with Genre the-genre otherwise prefix the title with Series the-series if the series exists,
- The :else: part is optional: it is legal to have
- CC's template processor "cleans" the result of the template as follows:
- If a character is not in the following list then it is changed to undescore: letters, numbers, underscore, minus "-", ampersand "&", left square bracket "[", right square bracket "]", left parenthesis "(", right parenthesis ")", period ".", comma "," , slash "/", single quote "'", and equals "="
- Multiple spaces are changed to a single space
- Leading and trailing spaces in a segment (something between slashes) are removed
- Leading and trailing periods in a segment are removed
Code:bookTitle - bookAuthors (123)
Code:bookSeries/bookTitle - bookAuthors (123)
- Basic syntax
- Advanced Techniques
It might be that you want to change the template based on some combination of metadata values. There are two ways to do this.- Create a Yes/No column that is set to Yes for any book that would match the expression you want to use in the if test, otherwise set to empty. In this case the if test would be
Code::if: {#yesno_col} :then: {series_index:%04d} :else: {series_index:%04.2f}:::
- Use the order CC evaluates if/then within templates to insert information from calibre columns into the template.
CC evaluates the if/then/else parts, substitutes the results back into the template, then evaluates the template with the substitutions. This permits you to specify arbitrary template parts inside the if statement that are used when finally evaluating the template. Consequence: you can put templates or template components in calibre columns then use these in CC. For example, the following would use a CC template stored in a text column in calibre:
Code::if:{#sometextcolumn}:then: :tv: :else:{the default template}:::
Code::if: {series}:then:{series:|_|}:else:{first_author} :::/{series_index:%04d/%07.2f|[|] - }{title} - {first_author}
You can do the same thing with template components. For example, assume that #sif is a text column containing the format specifier to use for the series index for the book. The following template segment would use that format if it exists, otherwise %04d/%07.2f. You must use the allowslashes format specifier because the expanded item contains a slash that must not be converted to an underscore.
Code:{series} {series_index::if: {#sif:allowslashes} :then: :tv: :else: %04d/%07.2f:::}
Code:{series} {series_index:%03d/%06.2f}
Code:{series} {series_index:%04d/%07.2f}
- Create a Yes/No column that is set to Yes for any book that would match the expression you want to use in the if test, otherwise set to empty. In this case the if test would be