DokumentationHubSpotHubL-Cheat-Sheet
HubL-Cheat-Sheet
Die HubSpot Markup Language auf einer Seite: die Syntax, die Filter, Funktionen und Tags, die du am häufigsten brauchst, und wie Modulfelder funktionieren, jeweils mit Beispiel.
- HubL ist die HubSpot Markup Language: die Template-Sprache für Themes, Module, Partials und E-Mails in HubSpot CMS.
- Sie basiert auf Jinjava, HubSpots Java-Version von Jinja, daher lassen sich die meisten Jinja-Gewohnheiten übertragen.
- HubSpot rendert sie auf dem Server; Besucher sehen immer nur das fertige HTML.
- transjt schreibt das HubL für dich: Jedes exportierte Modul kommt mit fertig verbundenen Feldern. Diese Übersicht ist für die Momente, in denen du etwas anpassen willst.
Delimiter
| Syntax | Wirkung |
|---|---|
{{ ... }} | Gibt einen Ausdruck aus: eine Variable, ein Feld, das Ergebnis einer Funktion. |
{% ... %} | Eine Anweisung oder ein Tag: if, for, set, module, include … |
{# ... #} | Ein Kommentar. Er erscheint nie auf der Seite. |
{%- ... -%} | Whitespace-Kontrolle: Der Bindestrich entfernt den Leerraum vor oder nach dem Tag. |
{# A module's heading field #}
<h1>{{ module.heading }}</h1>
Variablen
Eigene Variablen setzt du mit set. Strings, Zahlen, Booleans, Listen und Dicts funktionieren wie in Jinja:
{% set title = "Pricing" %}
{% set sizes = [480, 960, 1440] %}
{% set button = {"label": "Start free", "url": "/start/"} %}
{{ title ~ " | transjt" }} {# ~ joins strings #}
{{ sizes[0] }} {# 480 #}
{{ button.label }} {# or button["label"] #}
{% do sizes.append(1920) %} {# change a list in place #}
HubSpot stellt diese Variablen auf jeder Seite bereit:
| Variable | Enthält |
|---|---|
content | Die Seite oder den Blogbeitrag: content.absolute_url, content.name, content.publish_date … |
page_meta.html_title, page_meta.meta_description | Titel und Meta-Description aus den Seiteneinstellungen. |
request | Die Anfrage: request.path, request.domain, request.query_dict (der Query-String als Dict). |
local_dt | Aktuelles Datum und aktuelle Uhrzeit in der Zeitzone des Kontos. |
theme | Die Einstellungen des Themes aus seiner fields.json: theme.colors.primary.color und so weiter, so wie dein Theme sie benennt. |
module | Innerhalb eines Moduls: seine Feldwerte, module.heading, module.image.src … |
contact | Die Kontakteigenschaften des bekannten Besuchers, für Personalisierung: contact.firstname. |
is_in_editor | True, solange die Seite im HubSpot-Editor geöffnet ist. |
contact, local_dt, request.query_dict und today() ändern sich bei jedem Besuch, deshalb kann HubSpot eine Seite, die sie verwendet, nicht vollständig aus seinem vorgerenderten Cache ausliefern. Verwende sie nur dort, wo du sie brauchst.If und for
{% if module.items %}
<ul>
{% for item in module.items %}
<li class="{{ 'is-first' if loop.first else '' }}">{{ loop.index }}. {{ item.title }}</li>
{% endfor %}
</ul>
{% elif is_in_editor %}
<p>Add an item in the sidebar.</p>
{% else %}
{# Nothing to show on the live page #}
{% endif %}
- In einer Schleife:
loop.index(ab 1),loop.index0(ab 0),loop.first,loop.last,loop.length. {% unless condition %} … {% endunless %}ist das Gegenteil vonif.- Tests lesen sich wie englische Sätze:
{% if module.subtitle is defined %},is string,is number,is even,is divisibleby 3. - Operatoren:
==,!=,and,or,not,in.
Filter
Ein Filter verändert einen Wert hinter einer Pipe, {{ value|filter }}, und Filter werden von links nach rechts verkettet.
| Filter | Beispiel | Ergebnis |
|---|---|---|
default | {{ module.label|default("Read more", true) }} | Ein Ersatzwert, wenn der Wert fehlt; mit true auch, wenn er leer ist |
upper, lower, capitalize, title | {{ "hubl"|upper }} | HUBL |
truncate | {{ text|truncate(120) }} | An einer Wortgrenze auf 120 Zeichen gekürzt, dann „...“ |
truncatehtml | {{ module.text|truncatehtml(200) }} | Kürzt Rich Text, ohne offene Tags zu hinterlassen |
striptags | {{ module.text|striptags }} | Reiner Text ohne das HTML |
escape_html, escape_attr, escape_url | alt="{{ module.alt|escape_attr }}" | Sichere Ausgabe in HTML-Text, Attributen und URLs |
replace | {{ "a-b"|replace("-", " ") }} | a b |
split, join | {{ "a,b"|split(",")|join(" · ") }} | a · b |
length | {{ module.items|length }} | Die Anzahl der Einträge |
sort | {{ posts|sort(False, False, "name") }} | Nach einem Attribut sortiert (umgekehrt, Groß-/Kleinschreibung beachten, Attribut) |
selectattr, map | {{ items|selectattr("featured")|map("title")|join(", ") }} | Die Titel der hervorgehobenen Einträge |
format_datetime | {{ content.publish_date|format_datetime("medium", "Europe/Berlin") }} | Ein formatiertes Datum mit Uhrzeit in dieser Zeitzone (UTC, wenn du keine angibst) |
int, float, round | {{ "3.7"|float|round }} | 4 |
tojson | {{ module|tojson }} | Der Wert als JSON, für ein Script |
pprint | {{ module|pprint }} | Gibt einen Wert mit seinem Typ aus, zum Debuggen |
Funktionen
| Funktion | Wirkung |
|---|---|
get_asset_url("../css/main.css") | Die öffentliche URL einer Datei in deinem Theme. |
require_css(url), require_js(url) | Lädt ein Stylesheet im Head oder ein Script vor dem schließenden Body-Tag, einmal pro Seite, egal wie oft die Funktion aufgerufen wird. |
resize_image_url(url, 800) | Eine skalierte Kopie eines Bildes aus dem File Manager, 800 Pixel breit. |
menu("main") | Ein Navigationsmenü nach Name oder ID, mit seinen Unterpunkten, für dein eigenes Markup. |
blog_recent_posts("default", 3) | Die drei neuesten Beiträge des Standard-Blogs. |
blog_popular_posts("default", 5) | Die fünf meistgelesenen Beiträge des vergangenen Jahres, alle sechs Stunden aktualisiert. |
hubdb_table_rows(table, "orderBy=name&limit=10") | Zeilen aus einer HubDB-Tabelle, gefiltert und sortiert über einen Query-String (Content Hub Professional oder Enterprise). |
color_variant("#FF00F4", -40) | Eine Farbe, aufgehellt (positiv) oder abgedunkelt (negativ). |
today(), unixtimestamp(local_dt) | Das heutige Datum; ein Datum als Unix-Zeitstempel in Millisekunden. |
{% for post in blog_recent_posts("default", 3) %}
<a href="{{ post.absolute_url }}">{{ post.name }}</a>
{% endfor %}
Tags
| Tag | Wirkung |
|---|---|
{% module "hero" path="../modules/hero" %} | Platziert ein Modul an fester Position in einem Template. |
{% dnd_area "main" %} … {% end_dnd_area %} | Ein Drag-and-drop-Bereich, den die Redaktion im Seiten-Editor füllt, mit dnd_section, dnd_row, dnd_column und dnd_module darin. |
{% include "../partials/footer.html" %} | Fügt eine andere Datei ein. |
{% global_partial path="../partials/header.html" %} | Ein Partial, das einmal bearbeitet wird und das alle Seiten gemeinsam nutzen. |
{% extends "./layouts/base.html" %} mit {% block body %} | Template-Vererbung: Eine Seite füllt die Blöcke ihres Layouts. |
{% macro button(label, url) %} | Ein wiederverwendbarer Baustein mit Parametern, eingebunden mit {% from "/my-theme/macros.html" import button %} (der Pfad der Datei im Design Manager). |
{% require_css %} … {% end_require_css %} | Ein <style>-Block, der in den Head verschoben wird und dort HubL verwenden darf. Anders als die Funktion wird er jedes Mal hinzugefügt. |
{% raw %} … {% endraw %} | Gibt seinen Inhalt unverändert aus, ohne darin HubL auszuführen. |
Jedes Seiten-Template braucht {{ standard_header_includes }} vor dem schließenden </head> und {{ standard_footer_includes }} vor dem schließenden </body>: Sie binden HubSpots eigene Scripts, Styles und das Tracking ein.
<!--
templateType: page
isAvailableForNewContent: true
label: Landing page
-->
{% extends "./layouts/base.html" %}
{% block body %}
{% dnd_area "main" label="Main" %}
{% dnd_section %}
{% dnd_column %}
{% dnd_row %}
{% dnd_module path="@hubspot/rich_text" %}{% end_dnd_module %}
{% end_dnd_row %}
{% end_dnd_column %}
{% end_dnd_section %}
{% end_dnd_area %}
{% endblock %}
Module und Felder
Ein Modul ist ein Ordner mit der Endung .module, der module.html (HubL), module.css, module.js, fields.json und meta.json enthält. In module.html ist jedes Feld module. plus sein Name:
| Feldtyp | HubL |
|---|---|
| Text, Rich Text | {{ module.heading }}, {{ module.text }} |
| Bild | module.image.src, .alt, .width, .height |
| Link | module.link.url.href, module.link.open_in_new_tab |
| Farbe | module.color.color, module.color.opacity |
| Auswahl, Boolean | {{ module.style }}, {% if module.show_button %} |
Repeater (ein Feld mit occurrence) | {% for item in module.items %} |
{% set img = module.image %}
<section class="hero hero--{{ name }}">
{% inline_text field="heading" value="{{ module.heading }}" %}
{% if img.src %}
<img src="{{ img.src }}" alt="{{ img.alt|escape_attr }}" width="{{ img.width }}" height="{{ img.height }}" loading="lazy">
{% endif %}
</section>
{{ name }}ist der eindeutige Name der Modulinstanz: Damit beschränkst du CSS auf eine einzelne Instanz.inline_textundinline_rich_textmachen ein Feld im Editor direkt auf der Seite bearbeitbar.module.cssunterstützt fast kein HubL (nur Helfer wiemodule_asset_url) und kann keine Feldwerte lesen;module.jsunterstützt gar keins. Für einen Wert aus einem Feld setzt du einen{% require_css %}-Block inmodule.html.- Eine in einem Feld gewählte Farbe, die in einem Inline-
style=""ausgegeben wird, schlägt das CSS des Moduls: Prüfe zuerstmodule.html, wenn sich ein Style nicht ändern lässt.
Debugging
{{ module|pprint }}gibt einen Wert mit seinem Typ direkt auf der Seite aus. Entferne das vor dem Veröffentlichen.- Hänge
?hsDebug=truean die URL einer Live-Seite an: CSS und JavaScript laden dann unminifiziert und nicht zusammengefasst, nichts kommt aus dem Cache, und am Ende des Quelltexts stehen HubL-Fehler und -Warnungen, die Renderzeit und ob die Seite vorgerendert werden kann. - Der Design Manager markiert HubL-Fehler in der Datei, während du sie bearbeitest. Mit der HubSpot CLI prüft
hs cms lint <path>Dateien, und Uploads melden fatale Fehler im Terminal. - HubSpot rendert die Seiten, die ein aktualisiertes Modul oder Template verwenden, von selbst neu; das kann ein paar Minuten dauern. Wenn eine Live-Seite noch die alte Version zeigt, veröffentliche sie erneut.
HubL in transjt-Themes
Wenn du ein Design oder einen KI-Build exportierst, schreibt transjt das Theme für dich: Templates mit Drag-and-drop-Bereichen und ein Modul pro Sektion, mit Texten, Bildern, Links und Farben als Feldern. Dein Marketing-Team bearbeitet diese Felder im Seiten-Editor; niemand muss HubL schreiben.
Wenn du ein Theme selbst anpassen willst, leg dein eigenes CSS und JavaScript in custom.css und custom.js ab: Diese Dateien bleiben erhalten, wenn du erneut exportierst. Siehe Für HubSpot-Entwickler und Dein Theme in HubSpot verwenden.
Die vollständige HubL-Referenz findest du in der Entwicklerdokumentation von HubSpot.