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
              behaviour 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.

       @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

              @sort   the sort key for this track

              @display
                      the UNQUOTED display string for this track

       @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)