NAME
       disorder_templates - DisOrder template file syntax

DESCRIPTION
       DisOrder  template files are text files containing HTML documents, with
       an expansion syntax to enable data supplied by the implementation to be
       inserted.

   Expansion Syntax
       An  expansion  starts  with an at ("@") symbol and takes the form of an
       expansion name followed by zero or more arguments.

       Expansion names may contain letters, digits or "-" (and must start with
       a  letter  or  digit).   No  spacing is allowed between the "@" and the
       expansion name.

       Each argument is bracketed Any of "(" and ")", "[" and "]" or  "{"  and
       "}"  may  be  used but all arguments for a given expansion must use the
       same bracket pair.

       Arguments may be separated from one another and the expansion  name  by
       whitespace  (including  newlines and even completely blank lines).  The
       parser always reads as many arguments as are available, even if that is
       more  than  the  expansion name can accept (so if an expansion is to be
       followed by an open bracket of the same kind it uses, you must use  the
       @_ separator; see below).

       Arguments are expanded within themselves following the same rules, with
       a few exceptions discussed below.

   Special Symbols
       A few sequences are special:

       @@     This expands to a single "@" sign.

       @#     This expands to nothing, and moreover removes the  rest  of  the
              line  it appears on and its trailing newline.  It is intended to
              be used as a comment market but can also be  used  to  eliminate
              newlines introduced merely to keep lines short.

       @_     This  expands  to nothing (but does not have the line-eating be-
              haviour of @#).  It is intended to be used to mark the end of an
              expansion where that would otherwise be ambiguous.

   Macros
       It  is  possible  to define new expansions using the @define expansion.
       For example,

       @define{reverse}{a b}{@b @a}

       defines an expansion called @reverse which expands to its two arguments
       in  reversed  order.   The  input  @reverse{this}{that} would therefore
       expand to "that this".

   Sub-Expansions
       Many  expansions  expand  their  argument  with  additional  expansions
       defined.  For example, the @playing expansion expands its argument with
       the extra expansion @id defined as the ID of the playing track.

       The scope of these sub-expansions is purely lexical.  Therefore if  you
       invoke  a macro or include another template file, if the sub-expansions
       appear within it they will not be expanded.

       In the case of a macro you can work around this by passing the value as
       an argument.  Included files do not have arguments, so in this case you
       must rewrite the inclusion as a macro.

   Search Path
       All template files are first searched for in /etc/disorder and then  in
       /usr/share/disorder.

   macros.tmpl and user.tmpl
       Before  any  template is expanded, the CGI will process macros.tmpl and
       discard any output.  This defines a collection of commonly used macros.

       Following this the CGI will process user.tmpl, again discarding output.
       This  can  be  used  to  override the common macros without editing the
       installed version of macros.tmpl, or to define new ones.

       It is not an error if user.tmpl does not exist.

   Character Encoding
       The CGI does not (currently)  declare  any  character  encoding.   This
       could  be changed quite easily but in practice is not a pressing neces-
       sity.

       The recommended approach is to treat the templates as ASCII  files  and
       if  non-ASCII  characters  are required, use HTML entities to represent
       them.

       For example, to represent the copyright sign, use © or ©.

       If you know the decimal or hex unicode value for a character  then  you
       can use &#NNN; or &#xHHHH; respectively.

EXPANSIONS
       @and{BRANCH}{BRANCH}...
              Expands  to  "true"  if all the branches are "true" otherwise to
              "false".  If there are no brances then  the  result  is  "true".
              Only  as  many  branches  as necessary to compute the answer are
              evaluated (starting from the first one), so  if  later  branches
              have side effects they may not take place.

       @arg{NAME}
              Expands  to the UNQUOTED form of CGI argument NAME, or the empty
              string if there is no such argument.  Use @argq for a quick  way
              to quote the argument.

       @argq{NAME}
              Expands  to the (quoted) form of CGI argument NAME, or the empty
              string if there is no such argument.  Use @arg for the  unquoted
              argument.

       @basename{PATH}
              Expands to the UNQUOTED basename of PATH.

       @breadcrumbs{DIR}{TEMPLATE}
              Expands  TEMPLATE  for  each  directory  in  the path up to DIR,
              excluding the root but including DIR itself, with the  following
              expansions:

              @dir    the directory

              @last   "true" if this is the last directory, otherwise "false"

              DIR must be an absolute path.

       @define{NAME}{ARG1 ARG2...}{DEFINITION}
              Define a macro.  The macro will be called NAME and will act like
              an expansion.  When it is expanded, the expansion is replaced by
              DEFINITION,  with  each  occurence of @ARG1@ etc replaced by the
              parameters to the expansion.

       @dirname{PATH}
              Expands to the UNQUOTED directory name of PATH.

       @dirs{DIR}{RE}{TEMPLATE}
              For each directory below DIR, expands TEMPLATE with the  follow-
              ing expansions:

              @track  the UNQUOTED directory name

              @index  the directory number from 0

              @parity "even" or "odd" alternately

              @first  "true" on the first directory and "false" otherwise

              @last   "true" on the last directory and "false" otherwise

              @sort   the sort key for this directory

              @display
                      the UNQUOTED display string for this directory

              RE is optional and if present is the regexp to match against.

       @discard{...}
              Expands  to nothing.  Unlike the comment expansion @#{...}, side
              effects of arguments are not suppressed.  So this can be used to
              surround a collection of macro definitions with whitespace, free
              text commentary, etc.

       @enabled
              Expands to "true" if playing is enabled, otherwise "false".

       @eq{S1}{S2}...
              Expands to "true" if all the arguments are identical,  otherwise
              to "false" (i.e. if any pair of arguments differs).

              If there are no arguments then expands to "true".  Evaluates all
              arguments (with their side effects) even if that's not  strictly
              necessary to discover the result.

       @error Expands to the latest error string.

       @if{CONDITION}{IF-TRUE}{IF-FALSE}
              If  CONDITION  is  "true"  then evaluates to IF-TRUE.  Otherwise
              evaluates to IF-FALSE.  The IF-FALSE part is optional.

       @image{NAME}
              Expands to the URL of the image called NAME.

              Firstly if there is a label called images.NAME  then  the  image
              stem  will  be the value of that label.  Otherwise the stem will
              be NAME.png.

              If the label url.static exists then it will give  the  base  URL
              for images.  Otherwise the base url will be /disorder/.

       @include{COMMAND}
              Executes  COMMAND  via  the shell (using "sh -c") and copies its
              standard output to the template output.  The shell command  out-
              put is not expanded or modified in any other way.

              The shell command's standard error is copied to the error log.

              If  the  shell  exits nonzero then this is reported to the error
              log but otherwise no special action is taken.

       @isnew Expands to "true"  if  there  the  newly  added  track  list  is
              nonempty, otherwise "false".

       @isplaying
              Expands  to  "true"  if  there  is  a  playing  track, otherwise
              "false".

       @isqueue
              Expands to "true" if there  the  queue  is  nonempty,  otherwise
              "false".

       @isrecent
              Expands to "true" if there the recently played list is nonempty,
              otherwise "false".

       @label{NAME}
              Expands to label NAME  from  options.labels.   Undefined  lables
              expand to the last dot-separated component, e.g. X.Y.Z to Z.

       @length{ID|TRACK}
              Expands  to the length of a track, identified by its queue ID or
              its name.  If it is the playing track (identified  by  ID)  then
              the amount played so far is included.

       @movable{ID}{DIR}
              Expands to "true" if track ID is movable and "false" otherwise.

              DIR  (which is optional) should be a non-zero integer.  If it is
              negative then the intended move is down (later in the queue), if
              it  is  positive  then  the  intended move is up (earlier in the
              queue).  The first track is not movable up and  the  last  track
              not movable down.

       @ne{S1}{S2}...
              Expands  to  "true"  if  all  of  the  arguments differ from one
              another, otherwise to "false" (i.e. if any  value  appears  more
              than once).

              If there are no arguments then expands to "true".  Evaluates all
              arguments (with their side effects) even if that's not  strictly
              necessary to discover the result.

       @new{TEMPLATE}
              For each track in the newly added list, expands TEMPLATE wit the
              following expansions:

              @track  the UNQUOTED track name

              @index  the track number from 0

              @parity "even" or "odd" alternately

              @first  "true" on the first track and "false" otherwise

              @last   "true" on the last track and "false" otherwise

              Note that unlike @playing, @queue and @recent which  are  other-
              wise superficially similar, there is no @id sub-expansion here.

       @not{CONDITION}
              Expands  to  "true"  unless  CONDITION  is  "true" in which case
              "false".

       @or{BRANCH}{BRANCH}...
              Expands to "true" if any of the branches are "true" otherwise to
              "false".   If  there  are no brances then the result is "false".
              Only as many branches as necessary to  compute  the  answer  are
              evaluated  (starting  from  the first one), so if later branches
              have side effects they may not take place.

       @origin{ID}
              Expands to the current origin of track ID.

       @part{TRACK|ID}{PART}{CONTEXT}
              Expands to a track name part.

              A track may be identified by name or by queue ID.

              CONTEXT may be omitted.  If it is then 'display' is assumed.

              If the CONTEXT is 'short' then the 'display' part is looked  up,
              and  the result truncated according to the length defined by the
              short_display configuration directive.

       @paused
              Expands to "true" if the playing track is paused, to "false"  if
              it is playing (or if there is no playing track at all).

       @playing{TEMPLATE}
              Expands to TEMPLATE, with the following expansions:

              @id     the queue ID of the playing track

              @track  the playing track's
                       UNQUOTED name

              If no track is playing expands to nothing.

              TEMPLATE is optional.  If it is left out then instead expands to
              the queue ID of the playing track.

       @pref{TRACK}{KEY}
              Expands to a track preference.

       @prefs{TRACK}{TEMPLATE}
              For each track preference of track TRACK, expands TEMPLATE  with
              the following expansions:

              @name   the UNQUOTED preference name

              @index  the preference number from 0

              @value  the UNQUOTED preference value

              @parity "even" or "odd" alternately

              @first  "true" on the first preference and "false" otherwise

              @last   "true" on the last preference and "false" otherwise

              Use @quote to quote preference names and values where necessary;
              see below.

       @q{STRING}
              Expands to STRING.

       @queue{TEMPLATE}
              For each track in the queue, expands TEMPLATE with the following
              expansions:

              @id     the queue ID of the track

              @track  the UNQUOTED track name

              @index  the track number from 0

              @parity "even" or "odd" alternately

              @first  "true" on the first track and "false" otherwise

              @last   "true" on the last track and "false" otherwise

       @quote{STRING}
              SGML-quotes  STRING.   Note  that  most  expansion  results  are
              already suitable  quoted,  so  this  expansion  is  usually  not
              required.

       @random-enabled
              Expands to "true" if random play is enabled, otherwise "false".

       @recent{TEMPLATE}
              For  each  track  in  the recently played list, expands TEMPLATE
              with the following expansions:

              @id     the queue ID of the track

              @track  the UNQUOTED track name

              @index  the track number from 0

              @parity "even" or "odd" alternately

              @first  "true" on the first track and "false" otherwise

              @last   "true" on the last track and "false" otherwise

       @removable{ID}
              Expands to "true" if track ID is removable (or  scratchable,  if
              it is the playing track) and "false" otherwise.

       @resolve{TRACK}
              Expands  to an UNQUOTED name for the TRACK that is not an alias,
              or to nothing if it is not a valid track.

       @right{RIGHT}{WITH-RIGHT}{WITHOUT-RIGHT}
              Expands to WITH-RIGHT if the current user has right RIGHT,  oth-
              erwise to WITHOUT-RIGHT.  The WITHOUT-RIGHT argument may be left
              out.

              If both WITH-RIGHT and WITHOUT-RIGHT are left out  then  expands
              to "true" if the user has the right and "false" otherwise.

              If  there is no connection to the server then expands to nothing
              (in all cases).

       @search{KEYWORDS}{TEMPLATE}
              For each track matching KEYWORDS, expands TEMPLATE with the fol-
              lowing expansions:

              @track  the UNQUOTED directory name

              @index  the directory number from 0

              @parity "even" or "odd" alternately

              @first  "true" on the first directory and "false" otherwise

              @last   "true" on the last directory and "false" otherwise

       @server-version
              Expands to the server's version string, or a (safe to use) error
              value if the server is unavailable or broken.

       @state{ID}
              Expands to the current state of track ID.

       @status
              Expands to the latest status string.

       @thisurl
              Expands to an UNQUOTED URL which  points  back  to  the  current
              page.   (NB  it  might  not  be  byte  for  byte identical - for
              instance, CGI arguments might be re-ordered.)

       @tracks{DIR}{RE}{TEMPLATE}
              For each track below DIR, expands TEMPLATE  with  the  following
              expansions:

              @track  the UNQUOTED track name

              @index  the track number from 0

              @parity "even" or "odd" alternately

              @first  "true" on the first track and "false" otherwise

              @last   "true" on the last track and "false" otherwise

              @sort   the sort key for this track

              @display
                      the UNQUOTED display string for this track

              RE is optional and if present is the regexp to match against.

       @trackstate{TRACK}
              Expands  to  "playing" if TRACK is currently playing, or "queue"
              if it is in the queue, otherwise to nothing.

       @transform{TRACK}{TYPE}{CONTEXT}
              Transforms a track name (if TYPE is "track") or  directory  name
              (if  type  is  "dir").   CONTEXT should be the context, if it is
              left out then "display" is assumed.

       @url   Expands to the base URL of the web interface.

       @urlquote{STRING}
              URL-quotes a string, i.e. replaces any characters  not  safe  to
              use unquoted in a URL with %-encoded form.

       @user  Expands  to  the logged-in username (which might be "guest"), or
              to the empty string if not connected.

       @userinfo{PROPERTY}
              Expands to the named property of the current user.

       @version
              Expands to the local version string.

       @volume{CHANNEL}
              Expands to the volume in  a  given  channel.   CHANNEL  must  be
              "left" or "right".

       @when{ID}
              Expands  to  the  time  a track started or is expected to start.
              The track must be a playing track,  in  the  queue,  or  in  the
              recent list.

       @who{ID}
              Expands  to the name of the submitter of track ID, which must be
              a playing track, in the queue, or in the recent list.

SEE ALSO
       disorder_actions(5),  disorder_options(5),  disorder_config(5),  disor-
       der.cgi(8)