Symfonium Custom String Templates
This page documents Symfonium custom string template syntax and the field lists available in each context.
It is organized into:
- Common template syntax: placeholders, conditional blocks, conditions/operators, text formatting, escaping rules, and global localized
string.*labels - Context-specific sections:
- Now Playing: additional features (
\t,\o,next.fields,chapter.*fields) plus the full Now Playing field list - Album subtitle: album-level fields available on album pages
- Artist subtitle: artist-level fields available on artist pages
- Now Playing: additional features (
Common template syntax (works everywhere)
Basic placeholders
Syntax: %fieldname%
- Replaces
%fieldname%with the field value - If the field is empty or missing, nothing is shown
Examples:
| Template | Example result |
|---|---|
%title% by %artist% |
Seven Nation Army by The White Stripes |
%album% (%year%) |
Thriller (1982) |
%composer% ● %artist% |
Ludwig van Beethoven ● Berliner Philharmoniker |
%artist%%lb%%composer% |
Berliner Philharmoniker Ludwig van Beethoven |
%lb% is a line break.
Conditional blocks
Use blocks to show punctuation or labels only when something exists or when a condition matches.
Syntax: { ... }
- A
{ ... }block is displayed only if its first placeholder matches:- either a non-empty field
- or a true condition placeholder (
%|condition%)
- You can include multiple placeholders and literal text inside the same
{ ... }block, but only the first placeholder controls whether the block is shown - Put required spaces inside the block, for example
{ by %artist%}
Conditional block based on a field
Examples:
| Template | Example result | If field is empty |
|---|---|---|
%title%{ by %artist%} |
Seven Nation Army by The White Stripes | Seven Nation Army |
%album%{ (%year%)} |
Thriller (1982) | Thriller |
{%composer% ● }%artist% |
Beethoven ● Berliner Philharmoniker | Berliner Philharmoniker |
Conditional block based on a condition
Use %|condition% as the first placeholder to gate a block without printing a value.
Example:
{%|format.samplerate>"48"% Hi-Res: %format.codec%}
Shows Hi-Res: FLAC only if format.samplerate > 48.
Line breaks inside { ... }
Use \n inside conditional blocks:
%album%{\n(%year%)}
Outside of { ... }, prefer %lb% for line breaks.
Conditions inside placeholders
Syntax: %field|condition%
Prints the field only if the condition is true.
What you can compare:
- Another field name, for example
artist,composer,year - A literal string or number in quotes, for example
"2012","Rock","256"
Notes on literals:
trackmeans the track field"track"means the literal texttrack- Quotes can appear inside values; ensure the literal starts and ends with
"
Examples:
%year|year>"2012"%
%composer|composer!=artist%
%composer|genre=="Classical"%
Operators
| Operator | Meaning | Example | Notes |
|---|---|---|---|
== |
equals | genre=="Classical" / artist==composer |
|
!= |
not equals | artist!="Metallica" |
|
+= |
contains | genre+="Rock" |
works with literal or another field |
-= |
does not contain | mood-="depressing" |
|
> |
greater than | year>"1999" |
use quotes for literal numbers |
< |
less than | duration<"500" |
duration is in seconds |
==empty |
is empty | year==empty |
empty is reserved |
!=empty |
not empty | composer!=empty |
empty is reserved |
[] |
in range | bpm[]"0".."100" |
inclusive bounds |
Multiple conditions, mixed && / ||, and parentheses
- Use
&&for AND - Use
||for OR - You can mix
&&and||in the same condition - Use parentheses
(...)to control evaluation priority
Example:
%format|format.bitdepth!=empty && (format.samplerate>"48" || format.bitdepth>"24")%
This prints %format% only when bit depth exists and either:
- sample rate is greater than 48
- bit depth is greater than 24
Inline text formatting markup
**Bold**
__Underline__
~~Strike~~
//Italics//
^^CAPS^^
Localized labels (string.*)
These placeholders return translated strings in the user locale:
string.hiresstring.losslessstring.lossystring.hires.losslessstring.low.qualitystring.high.qualitystring.high.efficiencystring.time.unit.day.shortstring.time.unit.hour.shortstring.time.unit.minute.shortstring.time.unit.second.shortstring.time.unit.day.onestring.time.unit.day.otherstring.time.unit.hour.onestring.time.unit.hour.otherstring.time.unit.minute.onestring.time.unit.minute.otherstring.time.unit.second.onestring.time.unit.second.otherstring.track.onestring.track.otherstring.album.onestring.album.other
Now Playing (Compact & Expanded)
Now Playing templates can access:
- track metadata
- playback state
- queue state
- chapter state
- audio format
- EQ / renderer info
- and more
Now Playing-only features
Split into multiple segments with \t
Use \t to split one template into multiple segments.
Example:
%player.position%\t%format%\t%player.duration%
With horizontal alignment space between, this typically renders:
- left: position
- center: format
- right: duration
Selective protection overlay with \o
Use \o to apply a protection overlay only to that part, even if the full string is not protected.
next. prefix
Add next. before item-data fields to refer to the next queue item:
%next.title%
For chapter fields, next.chapter.* refers to the next chapter.
Supported fields (Now Playing)
Track / album metadata
titletitle.rawcleantitle(title without added track number or explicit symbol)artistalbumalbum.rawalbum.versionalbum.type(also known as Release Type)albumartistalbum.tagsalbum.titlealbum.title.rawalbum.title.versioncomposeryearreleasedateoriginaldatereleasedate.yearoriginaldate.yeartrackdiscdisctitledurationduration.seconds(Total seconds)duration.d(Add .nz to hide if zero)duration.h(Add .nz to hide if zero)duration.m(Add .nz to hide if zero)duration.s(Add .nz to hide if zero)duration.dd(0 padded, add .nz to hide if zero)duration.hh(0 padded, add .nz to hide if zero)duration.mm(0 padded, add .nz to hide if zero)duration.ss(0 padded, add .nz to hide if zero)bpmgenrestylemoodoccasiongroupinglanguagecommentworkmovement.namemovement.numbermovement.number.romanmediatypeprovidernameofflinestatusexplicitfavoriteuserratingratinguserrating.5(normalized to 5 stars)rating.5(normalized to 5 stars)track.tagsoriginal.artistoriginal.albumfilepathfilenamelastplayedlastSkippedisaudiobookplaycountskipcount
Playback / player
player.positionplayer.durationplayer.remainingplayer.position.secondsplayer.duration.secondsplayer.remaining.secondsplayer.pausedplayer.repeat.modeplayer.shuffle.modevolume.currentsleep.timersleep.timer.secondssleep.timer.eos
Queue / smart features
queue.positionqueue.sizequeue.namesmartqueuesmartflowradio.mode(1 if from Smart Queue, 2+ if from Smart Flow)
Chapters
chapter.countchapter.indexchapter.titlechapter.positionchapter.position.secondschapter.position.d(Add .nz to hide if zero)chapter.position.h(Add .nz to hide if zero)chapter.position.m(Add .nz to hide if zero)chapter.position.s(Add .nz to hide if zero)chapter.position.dd(0 padded, add .nz to hide if zero)chapter.position.hh(0 padded, add .nz to hide if zero)chapter.position.mm(0 padded, add .nz to hide if zero)chapter.position.ss(0 padded, add .nz to hide if zero)chapter.remainingchapter.remaining.secondschapter.remaining.d(Add .nz to hide if zero)chapter.remaining.h(Add .nz to hide if zero)chapter.remaining.m(Add .nz to hide if zero)chapter.remaining.s(Add .nz to hide if zero)chapter.remaining.dd(0 padded, add .nz to hide if zero)chapter.remaining.hh(0 padded, add .nz to hide if zero)chapter.remaining.mm(0 padded, add .nz to hide if zero)chapter.remaining.ss(0 padded, add .nz to hide if zero)chapter.durationchapter.duration.secondschapter.duration.d(Add .nz to hide if zero)chapter.duration.h(Add .nz to hide if zero)chapter.duration.m(Add .nz to hide if zero)chapter.duration.s(Add .nz to hide if zero)chapter.duration.dd(0 padded, add .nz to hide if zero)chapter.duration.hh(0 padded, add .nz to hide if zero)chapter.duration.mm(0 padded, add .nz to hide if zero)chapter.duration.ss(0 padded, add .nz to hide if zero)chapter.all.positionchapter.all.position.secondschapter.all.position.d(Add .nz to hide if zero)chapter.all.position.h(Add .nz to hide if zero)chapter.all.position.m(Add .nz to hide if zero)chapter.all.position.s(Add .nz to hide if zero)chapter.all.position.dd(0 padded, add .nz to hide if zero)chapter.all.position.hh(0 padded, add .nz to hide if zero)chapter.all.position.mm(0 padded, add .nz to hide if zero)chapter.all.position.ss(0 padded, add .nz to hide if zero)chapter.all.remainingchapter.all.remaining.secondschapter.all.remaining.d(Add .nz to hide if zero)chapter.all.remaining.h(Add .nz to hide if zero)chapter.all.remaining.m(Add .nz to hide if zero)chapter.all.remaining.s(Add .nz to hide if zero)chapter.all.remaining.dd(0 padded, add .nz to hide if zero)chapter.all.remaining.hh(0 padded, add .nz to hide if zero)chapter.all.remaining.mm(0 padded, add .nz to hide if zero)chapter.all.remaining.ss(0 padded, add .nz to hide if zero)chapter.all.durationchapter.all.duration.secondschapter.all.duration.d(Add .nz to hide if zero)chapter.all.duration.h(Add .nz to hide if zero)chapter.all.duration.m(Add .nz to hide if zero)chapter.all.duration.s(Add .nz to hide if zero)chapter.all.duration.dd(0 padded, add .nz to hide if zero)chapter.all.duration.hh(0 padded, add .nz to hide if zero)chapter.all.duration.mm(0 padded, add .nz to hide if zero)chapter.all.duration.ss(0 padded, add .nz to hide if zero)
Format / audio info
formatformat.bitrateformat.bitrate.rawformat.samplerateformat.samplerate.rawformat.bitdepthformat.codecformat.bitandsampleformat.channels
EQ / output / renderer
eq.profileeq.configoutput.currentrenderer.currentrenderer.type
Utility
lb(line break)bool1bool2bool3bool4bool5
Now Playing examples
clean two-line title block
%title%%lb%{by %artist%}
album + year only if year exists
%album%{ (%year%)}
Composer ● Artist only when composer exists
{%composer% ● }%artist%
three-part line using \t (position / format / duration)
%player.position%\t%format%\t%player.duration%
show Hi-Res only for high sample rate
{%|format.samplerate>"48"% Hi-Res: %format.codec%}
show active output device (Android vs other renderer)
{ %output.current|renderer.type=="Android"%}{ %renderer.current|renderer.type!="Android"%}
toggleable Apple-style quality indicator (uses bool1)
ⓘ {%format|bool1=="true"%}{Dolby Atmos %|format.channels>"2" && bool1=="false"%}{%string.high.efficiency|format.bitrate>"10" && format.bitrate<"256" && format.bitdepth==empty && bool1=="false"%}{%string.high.quality|format.bitrate>"255" && format.bitrate<"321" && format.bitdepth==empty && bool1=="false"%}{%string.lossless|format.bitdepth[]"16".."24" && format.samplerate<"49" && bool1=="false"%}{%string.hires.lossless|format.bitdepth[]"16".."32" && format.samplerate>"48" && bool1=="false"%}
If you bind a toggle bool1 action to the custom string, it alternates between:
- showing
%format%whenbool1is true - showing the Apple-style indicator when
bool1is false
show current volume
Vol %volume.current%%
current chapter title with index
{%chapter.index% - }%chapter.title%
current chapter elapsed / remaining
%chapter.position%\t%chapter.title%\t%chapter.remaining%
full audiobook progress relative to first chapter
%chapter.all.position%\t%chapter.all.duration%
next chapter title
%next.chapter.title%
raw format values
%format.codec% • %format.bitdepth%/%format.samplerate.raw% • %format.bitrate.raw%
Album subtitle (Album page)
Album pages typically expose album-level metadata, not queue or player state. You can use the same common template syntax.
Supported fields (Album subtitle)
titletitle.rawversiontagstypestatuscomposerartistyeardurationduration.seconds(Total seconds)duration.d(Add .nz to hide if zero)duration.h(Add .nz to hide if zero)duration.m(Add .nz to hide if zero)duration.s(Add .nz to hide if zero)duration.dd(0 padded, add .nz to hide if zero)duration.hh(0 padded, add .nz to hide if zero)duration.mm(0 padded, add .nz to hide if zero)duration.ss(0 padded, add .nz to hide if zero)genrestylemoodlanguageprovidernameofflinestatusoccasionmediatypegroupingexplicitreleasedateoriginaldatereleasedate.yearoriginaldate.yearlastplayedlastSkippeduserratingratinguserrating.5rating.5favoritesong.countplaycountskipcountdescriptionformatformat.bitrateformat.channelsformat.samplerateformat.bitdepthformat.codecformat.bitandsampleformat.bitrate.rawformat.samplerate.rawlb
Album subtitle examples
album title + version only if version exists
%title%{ — %version%}
year + genre line, skipping missing parts
%year%{ • %genre%}
rating shown only if user rated it
{★ %userrating.5%/5%|userrating!=empty%}
Downloaded indicator
{⬇ Offline%|offlinestatus!=empty%}
Artist subtitle (Artist page)
Artist pages typically expose artist-level metadata and library stats. You can use the same common template syntax.
Supported fields (Artist subtitle)
titletitle.rawversiontagstypegenderdurationduration.seconds(Total seconds)duration.d(Add .nz to hide if zero)duration.h(Add .nz to hide if zero)duration.m(Add .nz to hide if zero)duration.s(Add .nz to hide if zero)duration.dd(0 padded, add .nz to hide if zero)duration.hh(0 padded, add .nz to hide if zero)duration.mm(0 padded, add .nz to hide if zero)duration.ss(0 padded, add .nz to hide if zero)genrestylemoodsong.countalbum.countinstrumentprovidernameofflinestatuslastplayeduserratinguserrating.5favoriteplaycountdescriptionlb
Artist subtitle examples
show counts with labels
%song.count% songs{ • %album.count% albums}
genre / style line
%genre%{ • %style%}
show Favorite badge only when favorited
{♥ Favorite%|favorite!=empty%}
instrument on a new line
%title%{\n%instrument%}