---
title: "Pass data to templates instead of markup · Agent Wranglers"
url: https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/partials-take-data
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Pass data to templates instead of markup

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

For AI agents: [llms.txt](https://agentwranglers.se/llms.txt) is a short guide that sends you to the rules your problem needs, and [rules.json](https://agentwranglers.se/playbook/html-css/rules.json) holds every rule of this playbook as JSON.

- Level: Recommended
- Chapter: [HTML structure and reuse](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse)
- Rule: Give every template or component function plain data, such as text, numbers, lists and named options. Callers never pass HTML strings or extra class names into it.
- How: The function escapes every text value and builds all markup itself. A variant is a named option, as [Change components through variants](https://agentwranglers.se/playbook/app-ui/styles-and-components/component-variants) describes, not a class the caller adds. Shared pieces come from one module each, as [Build every repeated piece of HTML from one shared module](https://agentwranglers.se/playbook/website/site-architecture/shared-html-modules-only) requires.
- Check: A unit test renders each template with `<script>` in every text field. The output contains 0 raw `<script>` tags. No template signature accepts a parameter named `html`, `className` or `class`.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
const escape = text => String(text).replace(/[&<>"']/g, c => `&#${c.charCodeAt(0)};`);
export const priceTag = ({ name, price, variant = 'default' }) =>
  `<p class="price-tag" data-variant="${escape(variant)}"><span class="price-tag-name">${escape(name)}</span> ${escape(price)}</p>`;

// test
assert.ok(!priceTag({ name: '<script>', price: '4.50' }).includes('<script>'));
```

### Python example

```python
from html import escape

def price_tag(name, price, variant="default"):
    return (f'<p class="price-tag" data-variant="{escape(variant)}">'
            f'<span class="price-tag-name">{escape(name)}</span> {escape(price)}</p>')

# test
assert "<script>" not in price_tag("<script>", "4.50")
```

## Related rules

- [Change components through variants](https://agentwranglers.se/playbook/app-ui/styles-and-components/component-variants) in App interface
- [Build repeated HTML from shared modules](https://agentwranglers.se/playbook/website/site-architecture/shared-html-modules-only) in Website

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/partials-take-data">Agent Wranglers HTML and CSS playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Use the native element first](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/native-elements-first)
- Next: [Give each template one root element](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse/one-root-per-template)
- [HTML structure and reuse](https://agentwranglers.se/playbook/html-css/html-structure-and-reuse)
