A tag of your own with a .pad template is a component: the caller's content goes where the template writes @content@. Named slots give it more than one place for content, and {parms} says which parameters it takes. The card below is _tags/card.pad:

{parms title, tone='plain'}
<div class="card {#tone}" style="border: 1px solid #999; padding: 6px; margin: 4px">
<b>{#title}</b>
{slot 'header'}<i>no header given</i>{/slot}
<div>@content@</div>
{slot 'footer'}<small>@content@</small>{/slot}
</div>
PHP
HTML
fragments/components_1.pad
Result
{card title='Monthly revenue'}
<strong>12.500</strong>
{slot 'footer'}<a href="?reports">View report</a>{/slot}
{/card}

{card title='Visitors', tone='warn'}
{slot 'header'}<i>last 30 days</i>{/slot}
<strong>1.204</strong>
{/card}
Monthly revenue no header given
12.500
View report
Visitors last 30 days
1.204

Slots

Every use has its own

The fills belong to one use of the tag, so a card inside a card keeps its own footer:

PHP
HTML
fragments/components_2.pad
Result
{card title='Outer'}
{slot 'footer'}outer footer{/slot}
{card title='Inner'}
inner body
{slot 'footer'}inner footer{/slot}
{/card}
{/card}
Outer no header given
Inner no header given
inner body
inner footer
outer footer

Declared parameters

Components written in the template

A component used on one page only needs no file of its own. {define 'name'}...{/define} writes it in the template: from there on {name} renders the body as _tags/name.pad would - {parms}, {#name}, @content@ and slots work alike.

PHP
HTML
fragments/components_3.pad
Result
{define 'pill'}
{parms label, tone='info'}
<span class="pill {#tone}">{#label}@content@</span>
{/define}

{pill label='New'}
{pill label='Sold out', tone='warn'}: 0 left{/pill}
New Sold out: 0 left

A {macro} is called the way a function is: its parameters are declared on it - a name alone required, name=default filling in - given in their order or by name, and read as fields, {$label}.

PHP
HTML
fragments/components_4.pad
Result
{macro 'entry', label, type='text', value=''}
<p><label>{$label} <input type="{$type}" name="{$label}" value="{$value}"></label></p>
{/macro}

{entry 'E-mail', 'email'}
{entry label='Name', value='Alice'}