Get it 👉 https://marketplace.visualstudio.com/items?itemName=WilliamSpiro.hubl
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 hubl_snippets_gen.py
script from @JinjavaDoc
annotations to ensure the snippets are always up to date, and easy to maintain 🚰
For nice HubL syntax highlighting, install the Jinja scopes extension which lays on top of .html
files.
HubSpot employees have indicated that due to budget reasons HubSpot may not be able to throw Developer Day 2019. The truth is, HubSpot doesn't actually have to foot the whole bill, they don't even have to do all of the organization around it. Us community developers can help organize the event and outline our needs and work together to figure out how to get those needs met. That includes volunteers, getting sponsorships and coordinating.
This project has benefitted from some contributions from the developer community and so Developer Day 2019 is a shared benefit for all of us.
Let's make Developer Day 2019 a reality. Join us in the HubSpot developer Slack in #inbound19_dev_meetup and check out and feel free to add to our Google doc, we're using to coordinate.
We need:
- Volunteers
- Sponsors
- Input from the HS dev community.
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 hubl_snippets_gen.py
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.
HubL Tags produce entire HubL tag statements with available parameters. Ex ~he
> Enter produces:
{% header "${my_header}"
header_tag="${header_tag}",
value="${value}"
%}
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:
divisibleby
Other Helpful HubL Things
standard_footer_includes
& standard_header_includes
{{ standard_footer_includes }}
{{ standard_header_includes }}
{% for ${iterable} in ${dict} %}
{{ ${iterable} }}
{% endfor %}
{% if ${test} %}
${do_something}
{% endif %}
{% elif ${test} %}
{% else %}
{{ content.post_body }}
{{ content.blog_post_author }}
{{ group }}
{{ next_page_num }}
etc.
NOTE: Some of these variables are nested
hubldoc
<!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]-->
<head>
<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 }}
</head>
<body>
${stuff}
{{ standard_footer_includes }}
</body>
</html>
hublblog
{% if is_listing_view %}
<!-- Markup for blog listing template -->
{% for content in contents %}
<h2><a href="{{content.absolute_url}}">{{ content.name }}</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 }}">
</a>
{% endif %}
{{ content.post_list_content|safe }}
{% endfor %}
{% else %}
<!-- Markup for blog post template -->
<h1>{{ content.name }}</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(group.id, topic.slug) }}">{{ topic.name }}</a>{% if not loop.last %},{% endif %}
{% endfor %}
{% blog_comments "blog_comments" overrideable=False, label='Blog Comments' %}
{% endif %}
{{ request.cookies }}
{{ request.domain }}
{{ request.full_url }}
etc.
Email Required Template Variables
{{ site_settings.company_city }}
{{ site_settings.company_name }}
{{ unsubscribe_link }}
{{ unsubscribe_link_all }}
etc.
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
field.richtext
To create a group, use
group.group
To create a repeater, use
group.repeater
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
.
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 LICENSE.md 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 hubl_snippets_gen.py
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.