Alle Artikel

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.

Auf einen Blick
  • 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

SyntaxWirkung
{{ ... }}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:

VariableEnthält
contentDie Seite oder den Blogbeitrag: content.absolute_url, content.name, content.publish_date …
page_meta.html_title, page_meta.meta_descriptionTitel und Meta-Description aus den Seiteneinstellungen.
requestDie Anfrage: request.path, request.domain, request.query_dict (der Query-String als Dict).
local_dtAktuelles Datum und aktuelle Uhrzeit in der Zeitzone des Kontos.
themeDie Einstellungen des Themes aus seiner fields.json: theme.colors.primary.color und so weiter, so wie dein Theme sie benennt.
moduleInnerhalb eines Moduls: seine Feldwerte, module.heading, module.image.src …
contactDie Kontakteigenschaften des bekannten Besuchers, für Personalisierung: contact.firstname.
is_in_editorTrue, solange die Seite im HubSpot-Editor geöffnet ist.
Halte Seiten schnell. 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 von if.
  • 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.

FilterBeispielErgebnis
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_urlalt="{{ 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

FunktionWirkung
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

TagWirkung
{% 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:

FeldtypHubL
Text, Rich Text{{ module.heading }}, {{ module.text }}
Bildmodule.image.src, .alt, .width, .height
Linkmodule.link.url.href, module.link.open_in_new_tab
Farbemodule.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_text und inline_rich_text machen ein Feld im Editor direkt auf der Seite bearbeitbar.
  • module.css unterstützt fast kein HubL (nur Helfer wie module_asset_url) und kann keine Feldwerte lesen; module.js unterstützt gar keins. Für einen Wert aus einem Feld setzt du einen {% require_css %}-Block in module.html.
  • Eine in einem Feld gewählte Farbe, die in einem Inline-style="" ausgegeben wird, schlägt das CSS des Moduls: Prüfe zuerst module.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=true an 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.

Gestalte deine Website heute, geh morgen live.

Bei transjt zählt jede Sekunde. Deshalb ist unsere Mission einfach: dir Zeit sparen und Reibung aus deinem Workflow nehmen.