Reuse markup with includes and categories
Extract repeated markup into a partial and pass its inputs explicitly.
{% include "_garden_card.tpl" id=id %}
Inside the partial, read the resource using m.rsc[id]. Keep the partial focused on one component so another page can reuse it without inheriting unrelated page behavior.
Use a category include when the representation depends on the resource's category:
{% catinclude "_garden_card.tpl" id %}
Provide a generic fallback and add category-specific variants when their markup differs. Use the template selection tools to check which variant wins for the resource. See tag#include, tag#catinclude, and Find the template used by a page.
For the example above, save the fallback as priv/templates/_garden_card.tpl. An event-specific version is _garden_card.event.tpl. A resource named garden_open_day can override both with _garden_card.name.garden_open_day.tpl. Test an event and an ordinary text resource: the latter should still use the fallback.
Display values safely
Resource properties read through m.rsc follow Zotonic's content handling. Query arguments and values returned by custom models do not automatically have the same guarantees.
Escape plain text from those sources:
<p>{{ q.term|escape }}</p>
Do not mark arbitrary user input as safe HTML. Decide at the model or content boundary whether a field contains text, sanitized HTML, a URL, or another type. Keep that decision consistent across templates and API responses.
When a value renders unexpectedly, inspect its type and translation behavior before applying more filters. See filter#escape, Expose data through a model, and Keep permission checks at the boundary.
Override a module template
Find the active template and its path relative to priv/templates. Create the same relative path in your site or another active module with a higher selection priority.
Copy only the structure you need to change. When the original template offers blocks, extend it using the supported inheritance pattern rather than duplicating a large file. Check tag#overrules for extending the next matching template.
Load the affected page and inspect the selected template again. A successful compile does not prove that your override is used. Test neighboring categories and languages if the original template serves more than one page type.
For example, place this in the same relative template path as the template being overridden:
{% overrules %}
{% block content %}
{% inherit %}
<p>{_ Contact us for more information. _}</p>
{% endblock %}
Use a block that exists in the original. {% inherit %} keeps its content; omit it only when replacing that entire block is intentional. This is especially important for admin panels, where copying a small fragment over a large panel can remove controls.