Skip to content

Template API Manual

Goal

This document explains how player templates connect to the Studio Player core engine. It is intentionally practical and not overly technical: you should be able to understand how a template is built from PHP + CSS + JS, which DOM “hooks” are expected, and which parts are already handled by the core (streaming, timing, text engine, and waveform plumbing).

1. What is a template?

A Studio Player template defines the player’s structure and presentation. The core engine (streaming, variant switching, synchronization, buffering, and global keyboard handling) stays the same across templates. Templates connect to the engine via a small set of predefined DOM hooks (CSS classes and data attributes), plus a small JS API that the core attaches to the player root element.

The current plugin ships with two templates: default and cover-flow.

2. Where templates live (plugin vs. uploads)

Location Purpose Example path
Plugin templates Built-in templates shipped with the plugin. wp-content/plugins/the-studio-player/templates/player/<slug>/
Uploads templates Update-safe overrides and custom templates. wp-content/uploads/the-studio-player/templates/player/<slug>/
Note

If a template exists in both locations, the uploads version is used. This allows you to copy a built-in template into uploads, customize it, and keep it unchanged across plugin updates.

Note

Default template selection uses a folder name marker: a template directory name can optionally end with (default). If multiple templates are marked as default, the first one in lexical order wins (uploads candidates are preferred over plugin candidates).

Note

Template folders must contain a player.php file. Folders starting with an underscore are ignored (reserved for internal use).

3. Template file structure (PHP/CSS/JS)

A player template folder contains a required player.php file. Typically it also includes style.css and script.js:

templates/player/<slug>/
  player.php
  style.css
  script.js

player.php outputs the HTML markup and reads the playlist context (playlist id, selected template slug, design schema). It also declares template defaults via a header block (colors, “show playlist”, “show audio info”, etc.).

style.css styles the template. The core design system provides CSS variables on the root element, so templates can share a common palette and still look different.

script.js binds the template UI to the core engine. This is where the “predefined” calls live (bind playlist, bind variants, bind transport buttons, render the text engine, and optional waveform/canvas visuals).

How templates are loaded

When you embed players via the shortcode, the plugin automatically enqueues the core scripts and the selected template’s style.css/script.js (from uploads or plugin). The selected template comes from the playlist (Player-Builder) and can also be set via shortcode, e.g. [[thespl_player playlist_id="123" template="cover-flow"]].

4. DOM contract (required hooks)

The core initializes players by scanning for .thespl-player[data-playlist-id]. Your template must provide a root wrapper with at least:

<div
  class="thespl-player"
  id="thespl-player-123-XXXX"
  data-playlist-id="123"
  data-template-slug="my-template"
>
  ...
</div>
About data-template-slug

data-template-slug is used by template scripts to find “their” player instances (the built-in templates bind to .thespl-player[data-template-slug="…"]).

You may see data-thespl-core-ui in older templates or builds. It is deprecated and will be removed, so it is not part of the public template API and should not be relied on.

Both built-in templates also use these standard elements (recommended):

Hook What it connects Where it appears
.thespl-player__audio (audio element) Audio output owned by the core engine. default, cover-flow
.thespl-player__status Text engine line 1 (status: Buffering / Ready / Paused / errors). default, cover-flow
.thespl-player__infotext Text engine line 2 (infotext: track/variant/message rotation). default, cover-flow
.thespl-player__variants Variant buttons (A/B or Pro: A/B/C/D), driven by UI facade. default, cover-flow
.thespl-player__playlist Track list / coverflow list, driven by UI facade. default, cover-flow
.thespl-player__btn--play, --pause, --stop Transport controls (predefined actions). default (+ cover-flow uses a toggle button as well)
.thespl-player__canvas inside __canvas-wrap Optional canvas UI (progress ring, waveform visualization, etc.). default, cover-flow
data-thespl-audio-info="…" (optional) Audio info box (plugin version/build + runtime metrics). default, cover-flow

5. JS contract (predefined API calls)

The core attaches a small API object to the root element as root._thesplPlayerApi. Templates can call it, and the shared UI facade uses it to connect buttons and lists.

// Provided by the core on each player root:
root._thesplPlayerApi = {
  play: async () => { ... },
  pause: () => { ... },
  stop: () => { ... },
  toggle: () => { ... },
  playTrack: async (index) => { ... },
  selectVariant: (index) => { ... }
};
Template principle

The template should not re-implement playback logic. Instead, it renders buttons and containers and then calls the shared UI facade to bind them to the core API.

Minimal binding pattern used by both built-in templates:

(function () {
  function initTemplate(root) {
    if (!window.THESPL_Player_Store || !window.THESPL_Player_UI) return;
    window.THESPL_Player_Store.init(root);
    var api = root._thesplPlayerApi;
    window.THESPL_Player_UI.setInfotextMode(root, 'scroll');
    window.THESPL_Player_UI.bindInfotext(root);
    window.THESPL_Player_UI.bindPlaylist(root, api);
    window.THESPL_Player_UI.bindVariants(root, api);
    window.THESPL_Player_UI.bindTransport(root, api);
    window.THESPL_Player_UI.renderStatus(root);
  }
})();

6. Design schema & CSS variables

Templates read colors and visibility defaults from the template header and the playlist’s design schema. On render, the template maps the schema into CSS variables on the root element. This gives you a consistent “design language” without hardcoding everything.

Typical variables include: --thespl-bg, --thespl-text, --thespl-accent, --thespl-accent-2, --thespl-waveform, and button/chip colors. Your template CSS can rely on these.

/* Example usage inside a template CSS */
.thespl-player {
  background: var(--thespl-bg);
  color: var(--thespl-text);
}
.thespl-player__btn--play {
  background: var(--thespl-button-bg);
  color: var(--thespl-button-text);
}

7. Waveforms & visualization

Waveforms are an optional UI layer on top of the core. The core handles streaming and timing; the template can decide how to visualize progress and (optionally) waveform data. Both shipped templates include a canvas element for visualization, but the design is fully template-specific.

Note

You do not need to invent your own streaming, buffering, or variant switching. Templates should treat these as “framework” features. For waveform display, you can build your UI around the existing player store/UI facade patterns and show a friendly notice when waveform data is missing.

8. Steps to build your own template

  1. Copy an existing template folder (recommended starting point: default).
  2. Rename the folder to your slug (letters/numbers/dashes). Keep it inside uploads for update safety.
  3. Adjust player.php markup (layout/structure). Keep the required hooks.
  4. Adjust style.css (use CSS variables from the design schema).
  5. Adjust script.js to bind UI components via THESPL_Player_UI and the core API.
  6. Select the template in Player-Builder and embed the player with a shortcode, e.g. [[thespl_player playlist_id="123"]].
Important

The template slug is derived from the template folder name. After renaming the folder, update your copied script.js to bind to the new slug (the shipped templates use selectors like .thespl-player[data-template-slug="default"]). Then select the new template slug in Player-Builder (or pass it via shortcode using template="your-slug").

Where to put the folder

For update-safe templates, use: wp-content/uploads/the-studio-player/templates/player/<your-template>/

Need a custom template?

If the built-in design options don't fully match your vision, we can create a fully custom template tailored to your brand for a flat fee. Contact us at support@studioplayer.de.