Skip to content
A HubL language extension for the Visual Studio Code IDE, allowing for 🚀 fast local HubSpot CMS Platform development.
Branch: master
Clone or download
williamspiro Merge pull request #29 from bkrainer/update-fields
Update hubl_custom_module_fields.json
Latest commit a11e894 Jul 10, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode initial commit Dec 20, 2018
langconfig add hubl comments Dec 28, 2018
snippets Update hubl_custom_module_fields.json Jul 10, 2019
.DS_Store updated changelog Apr 10, 2019
.vscodeignore update vscode ignore Dec 20, 2018
LICENSE Initial commit Dec 20, 2018 updated some spelling errors on readme Feb 20, 2019 updates Mar 12, 2019
package.json 0.1.4 Feb 21, 2019

HubL Visual Studio Code Language Extension

Get it 👉

HubL is the underlying syntax used in the HubSpot content management system. HubL can be used to dynamically render content, as well as generate easy to edit modules within the content editors marketers work in so they do not ever need to touch the underlying HTML of a template. This allows for many pages to use a single template, making managing content and websites significantly easier and quicker.

This is a HubL language extension for the Visual Studio Code IDE, allowing for 🚀 fast local HubSpot CMS Platform development in .html files. For comprehensive HubL documentation, see the HubL docs.

All HubL snippets are auto-generated by the script from @JinjavaDoc annotations to ensure the snippets are always up to date, and easy to maintain 🚰

language extention demo
For nice HubL syntax highlighting, install the Jinja scopes extension which lays on top of .html files.


HubL Snippets

All HubL supported tags, filters, expression tests and functions have auto-complete snippets. Expression tests are accessed by typing the test name alone, filters are accessed with | and fucntions/tags are acccessed with ~. All snippets include descriptions and parameter details. You up/down arrow to navigate the IntelliSense and hit enter to execute a snippet. Snippet completed HubL statements will auto-highlight available parameters, which can be tabbed through (${parameter}).

NOTE: HubL tags, functions, expression tests and filters are all pulled from the cos-rendering/v1/hubldoc api, so do not update any snippets/auto-gen/... json files manually. Run to re-generate these JSON files when HubL changes occur. snippets/man_gen/... files are for any extra/helpful snippets used in HubL - these files are maintained manually.

Parameters HubL Tags produce entire HubL tag statements with available parameters. Ex ~he > Enter produces:

{% header "${my_header}" 

HubL Filters produce entire HubL filter statements with available parameters. Ex |se > Enter produces:

|selectattr("${attr}", ${exp_test})

HubL Functions produce entire HubL function statements with available parameters, without wrapping curly braces. The intention of this is so you can use HubL functions within other HubL statements easily (like setting variables, for loops, etc.) Ex ~hub > Enter produces:

hubdb_table_rows(${table_id}, ${query})

HubL Expression Tests produce expression test names. Ex di > Enter produces:


Other Helpful HubL Things
standard_footer_includes & standard_header_includes

{{ standard_footer_includes }}
{{ standard_header_includes }}


{% for ${iterable} in ${dict} %}
   {{ ${iterable} }}
{% endfor %}


{% if ${test} %}
{% endif %}

elif & else

{% elif ${test} %}
{% else %}

blog variables

{{ content.post_body }}
{{ content.blog_post_author }}
{{ group }}
{{ next_page_num }}

NOTE: Some of these variables are nested
Nested variables


<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="{{ html_lang }}" {{ html_lang_dir }}> <![endif]-->
<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8" lang="{{ html_lang }}" {{ html_lang_dir }}>        <![endif]-->
<!--[if IE 8]>    <html class="no-js lt-ie9" lang="{{ html_lang }}" {{ html_lang_dir }}>               <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="{{ html_lang }}" {{ html_lang_dir }}> <!--<![endif]-->
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="author" content="{{ meta_author }}">
        <meta name="description" content="{{ page_meta.meta_description }}">
        <title>{{ page_meta.html_title }}</title>
        {% if site_settings.favicon_src %}<link rel="shortcut icon" href="{{ site_settings.favicon_src }}" />{% endif %}
        {{ standard_header_includes }}
        {{ standard_footer_includes }}


{% if is_listing_view %}
    <!-- Markup for blog listing template -->
    {% for content in contents %}
        <h2><a href="{{content.absolute_url}}">{{ }}</a></h2>
        {% if content.post_list_summary_featured_image %}
            <a href="{{content.absolute_url}}">
                <img src="{{ content.post_list_summary_featured_image }}" alt="{{ content.featured_image_alt_text }}">
        {% endif %}
        {{ content.post_list_content|safe }}
    {% endfor %}
{% else %}
    <!-- Markup for blog post template -->
    <h1>{{ }}</h1>
    <a href="{{ group.absolute_url }}/author/{{ content.blog_post_author.slug }}">{{ content.blog_post_author.display_name }}</a>
    {{ content.publish_date_localized }}
    {{ content.post_body }}
    {% for topic in content.topic_list %}
        <a href="{{ blog_tag_url(, topic.slug) }}">{{ }}</a>{% if not loop.last %},{% endif %}
    {% endfor %}
    {% blog_comments "blog_comments" overrideable=False, label='Blog Comments' %}
{% endif %}


{{ request.cookies }}
{{ request.domain }}
{{ request.full_url }}

Email Required Template Variables

{{ site_settings.company_city }}
{{ site_settings.company_name }}
{{ unsubscribe_link }}
{{ unsubscribe_link_all }}

Custom Module Fields In effort to allow for more streamlined local development of custom modules, snippets have been added that can be added to the fields.json file within a custom module. The snippet trigger roughly corresponds with the field names in the design manager.
For example: to add a rich text field, you would type


To create a group, use

To create a repeater, use


all associated fields need to be added into the children array within the snippet output

NOTE: If you are having trouble getting IntelliSense suggestions when in snippet placeholders you may need to add the following to your User Settings "editor.suggest.snippetsPreventQuickSuggestions": false. If parameter suggestions are not showing up, set "editor.parameterHints": true.

HubL Langage Configuration

langconfig/language-configuration.json contains some nice to haves when it comes to writing HubL. This supports auto completes of all HubL statement types and supports HubL statement swrapping (Supports {%%},{##},{{}}). Additionally, makes commenting (CMD + /) create HubL comments. Install the Jinja scopes extension for pretty HubL syntax highlighting in .html files.


This project is licensed under the MIT License - see the file for details


Anyone should feel free to fork/PR this! Open source for the win 💩💩💩💩. Please make sure and explain your changes thoroughly, update version and changelog where needed. See above note about for updating HubL snippets/auto-gen/... json files.

To run locally, git clone repo, open in Visual Studio Code and press f5 to launch a new VSCode window with the extension installed. CMD + R to reload the window after having made any changes.

You can’t perform that action at this time.