# Templates Reference

This document explains how `window.templates` works in MediaMonkey addons, how to extend it safely, and what template entries are available in this repository snapshot.

## 1) How Templates Work

`window.templates` is a runtime dictionary of reusable UI render/bind helpers. In practice, templates are used through `data-bind` expressions inside generated HTML.

Common binding forms used with templates:

- `func:` executes a function expression, typically calling a template helper.
- `call:` calls a predefined binding callback object/function.
- `text:` binds plain text expressions.

Typical pattern:

1. Build or modify HTML for a view/list item.
2. Put template calls in `data-bind`, for example: `func: templates.itemImageFunc(div, item, div.itemIndex, params)`.
3. Call `initializeControls(...)`.
4. Call `recompileBinding(...)` or `precompileBinding(...)` when needed so bindings are reattached.

## 2) How To Modify or Improve Templates

### 2.1 Add a new template helper

Create addon code that defines a new function under `window.templates`.

Example pattern:

```js
window.templates.albumTitleHash = function (el, item) {
    var title = item.title + '  ' + item.albumArtist;
    el.innerText = removeThe(title).slice(0, 2);
    el.setAttribute('data-color', Math.abs(hashString(title)) % 10);
};
```

Then use it via `data-bind` in an overridden control:

```js
unk.setAttribute('data-bind', 'func: templates.albumTitleHash(el, item);');
```

### 2.2 Override an existing template preset

For preset objects (like `templates.imageItemsParams`), use `override(...)` to patch only what you need.

Example pattern:

```js
window.templates.imageItemsParams.override({
    albumListView: function ($super) {
        let orig = $super();
        delete orig.line3Bind;
        return orig;
    }
});
```

This is safer than copying the whole preset because it preserves upstream behavior.

### 2.3 Rebuild markup and bind templates dynamically

When building custom layout HTML at runtime, call template helpers in `data-bind`, then initialize and recompile bindings:

- `templates.itemImageFunc(...)`
- `templates.propertyHandler(...)`
- `templates.lyricsFunc(...)`

This allows custom layouts to reuse core behavior (artwork loading, metadata display, lyrics handling) without reimplementing internals.

## 3) Safe Extension Guidelines

- Prefer additive changes: add `window.templates.myHelper` instead of replacing core helpers.
- Prefer targeted overrides (`override`) for existing presets.
- Reuse existing helpers (`itemImageFunc`, `hotlinkHandler`, `ratingEditableFunc`) rather than duplicating logic.
- If template code attaches listeners/promises, ensure cleanup paths exist (Control clean functions, unlisten, canceled promises).
- Keep bind callbacks idempotent: list items are rebound often.
- Use small parameter objects for behavior toggles instead of creating many near-duplicate helpers.

## 4) Available Templates (Top-Level)

Top-level entries in `window.templates` from `templates.js`:

- `artworkClickFunc`
- `trackProperty`
- `groupedTracklistByAlbum`
- `groupedTracklistByAlbumHeaders`
- `addEllipsisTooltip`
- `propertyHandler`
- `hotlinkHandler`
- `lyricsFunc`
- `artistBioFunc`
- `bookmarkFunc`
- `getRatingWidth`
- `ratingEditableFunc`
- `saveImageToAlbum`
- `saveImageToTrack`
- `albumRatingFunc`
- `assignHTMLifDifferent`
- `imageItemsParams`
- `imageItem`
- `npItemText`
- `youtubeIcon`
- `npListItem`
- `simpleTracklistItem`
- `simpleTracklistSortMethods`
- `albumTracklistItem`
- `findLVStyleColorTypes`
- `setPopupListColors`
- `setLVPopupStyles`
- `_setLVPopupStyles`
- `itemImageTooltip`
- `nodeItemImageFunc`
- `itemImageFunc`
- `addViewAction`
- `addImageGridSelectButton`
- `addImageGridButtons`
- `artworkListSaveImage`
- `artworkListItem`
- `nodeIconFunc`
- `itemIconFunc`
- `setYoutubeIconDiv`
- `itemDoubleIconFunc`
- `rowNodeIconFunc`
- `rowNodeItem`
- `podcastDownloadFunc`
- `episodeTitleDateFunc`
- `episodeCommentFunc`
- `fillMultiValue`
- `popupRenderers`

## 5) Built-in Preset Collections

### 5.1 `templates.imageItemsParams` presets

- `standardItem`
- `iconNode`
- `imageNode`
- `podcastItem`
- `podcastNode`
- `playlistNode`
- `artistsGrid`
- `albumListView`
- `videoGrid`
- `trackGrid`
- `yearNode`

These are reusable parameter factories/objects for `templates.imageItem(...)`.

### 5.2 `templates.popupRenderers` presets

- `artist`
- `album`
- `genre`
- `feed`
- `addon`
- `unplayedPodcast`

These drive popup content composition for selected media entities.

## 6) Practical Usage Recipes

### Recipe A: Custom fallback when artwork is missing

1. Add a helper in `templates_add.js` under `window.templates`.
2. Override target control `setUpDiv`.
3. Replace `data-icon` fallback with custom `data-bind="func: templates.yourHelper(...)"`.

This pattern is useful for text-based placeholders.

### Recipe B: Remove one line from album grid tiles

1. Override `templates.imageItemsParams.albumListView`.
2. Call `$super()`.
3. Delete `line3Bind` (or adjust any bind).
4. Return modified object.

This pattern is useful for removing or replacing secondary metadata binds.

### Recipe C: Build a custom art/details panel using core helpers

1. Build custom HTML string with template calls in `data-bind`.
2. Run `initializeControls(div)` and `recompileBinding(div, parentControl)`.
3. Pass parameter object to `templates.itemImageFunc` and `templates.lyricsFunc`.
4. Preserve cleanup/unlisten behavior for listeners created during binding.

This pattern reuses core behavior while allowing layout customization.


## Further reading

Check out `templates.js` and `templateFormats.js` to find the exact source code used for formatting in MediaMonkey.