1. Setup steps

1) Install Hubspot CMS command line tools
a) Create a project folder, open in editor and go to terminal,
b) Enter: npm install @hubspot/cli
2) Link local hubspot setup to online setup
a) Enter: npx hs init
b) Make sure you are logged in correct Hubspot account for setup
c) Enter a username
d) Press Enter and it will open browser page in Hubspot to generate ‘Personal Access key’
e) Paste key on console
f) hubspot.config.yml file created, saves this data
3) Install a theme
a) Enter following command to fetch default free theme:
npx hs create website-theme theme1
4) Upload project to Hubspot
a) npx hs upload theme1 theme1
5) In Hubspot Webpages, a new page can be created using CMS and edited. (It needs starter plan)
6) Header/footer code, website logo, domain name, teams (write and publish access restrictions), etc. can be done is Hubspot’s main settings, on top right.

—–
(Commands in 3) and 4) are a mix of
https://developers.hubspot.com/docs/cms/guides/getting-started
and
https://app.hubspot.com/academy/6927185/tracks/121/813/4337
as theme upload don’t work as per commands in academy tutorial)
3) Academy says: npx @hubspot/create-cms-project test-theme
4) Academy says: npx hs upload test-theme/src test-theme
—–

2. HubL Language

It is not programming language. Similar to Jinja.
We can get data from database using HubL and then move to Javascript, but not opposite.

HubL structure:

{% set my_variable = “a statement added in brace percentage” %}
{{ an_expression_to_evaluate_in_two_curly_braces }}
{# comments like this #}
—–
using example:
1) Create and output any variable
{% set my_variable =”I’m a string” %}
{{ my_variable }}
{# OUTPUT: I’m a string #}
—–
2) Create array list
{% list1 = [“part1”, “part2”] %}
{{ list1[0] }}
{# OUTPUT: part1 #}
—–
In above code, to count list:
{{ list1|length }}

{# OUTPUT: 2 }}
—–
3) Multi-dimensional array
{% set arr = {“name”: “Inderjeet”, “does”: “web developer”} %}
{{arr.does}}
{# OUTPUT: web developer #}
—–
4) Functions using macros
{% macro add_numbers(n1, n2) %}
{{ n1+n2 }}
{% endmacro %}

{{ add_numbers(4,5) }}

{# OUTPUT: 9 #}
—–
5) Conditional statements, expressions

{% set friends = [‘Joe’, ‘Rachel’, ‘Winston’] %}

{% if friends is iterable %}

My friends are {{ friends|join(‘, ‘) }}

{% else %}

My friend is {{friends}}

{% endif %}

{# Output: My friends are Joe, Rachel, Winston #}
—–
6) Loops (for, while):
{% set numbers = [‘one’, ‘two’, ‘three’] %}
{% for number in numbers|reverse %}

Loop index:{{ loop.index }} Number: {{ number }}

{% endfor %}

{# OUTPUT:
Loop index: 1 Number: three
Loop index: 2 Number: two
Loop index: 3 Number: one #}
—–
All website pages has ‘Developer Info’ tab available which shows all available variables, database values, etc. available in that page.
—–
To create own elements, rather than using drag and drop:
1) Basic Module syntax of HubL (mostly like HTML):
{% text “movie_name” label=”Movie Name”, value=”Citizen Kane” %}

2) Block Module syntax for HubL
{% widget_block rich_text “movie_description” overridable=True, label=”Movie Description” %}
{% widget_attribute “html” %}

It is heading

It is paragraph

{% end_widget_attribute %}
{% end_widget_block %}
—–
Helpful page for tags available in HubL: https://developers.hubspot.com/docs/cms/hubl/tags
—–
Add CSS using HubL(convert to rgb to add transparency of .5):

{% set brand_color = ‘#ff99000’ %}

a.brand:hover{
color: rgba({{ brand_color|convert_rgb }}, .5);
}

{# OUTPUT:
a.brand: hover {
color: rgba(255, 153, 0, .5);
}
#}
—–
rejectattr(‘read’): It is subset of books, when value is false

{% set books: [{“name”: “book1”, “read”: false}, {“name”: “book2”, “read”: true}] %}

{% set unread_books = books|rejectattr(“read”) %}

Books I haven’t read yet

{% for book in unread_books %}

{{ book.name }}

{% endfor %}

{# OUTPUT:

book1

#}
—–
Debugging filter {{ site_settings|pprint }}: pretty print shows all data available on page
—–
Find filters available to do quick works in HubL: https://developers.hubspot.com/docs/cms/hubl/filters
—–
CSS values conversion pixel to rem:
{% macro rem(value) %}
{% set baselineFontSize = 16 %}
{% set remValue = value/baselineFontSize %}
{{ remValue }}rem
<% endmacro %}

How to use in CSS:
.class1 {
padding-top: {{ rem(20) }};
}

{# OUTPUT:
.class1{
padding-top: 1.25rem;
}
#}
—–
Convering multiple value to rem, at once (using ‘this’):

{% macro rem(values) %}
{% set baselineFontSize = 16 %}
{% set cssValues = [] %}
{% for v in values %}
{% set thisVal = v/baselineFontSize~’rem’ %}
{% do cssValues.append(thisValue) %}
{% endfor %}
{{ cssValues|join(‘, ‘) }}
{% endmacro %}

How to use in CSS:
.class1 {
padding: {{ rem([30, 3, 33, 32]) }};
}

{# OUTPUT:
.class {
padding: 1.875rem, 1.25rem, 0.3125rem, 1.25rem;
}
#}

3. Create template for page

1) Create a template:
ENTER: hs create template basic-template-demo
select a template type and it gets created.
2) Comments on top shows template type create, {{ standard_header_includes }} and {{ standard_footer_includes }} are required, rest is HTML structure.
3) We can add non-editable and editable content in it using HTML and block modules, as explained in other file.
4) Upload template to Hubspot live:
ENTER: hs upload basic-template-demo.html basic-template-demo.html
—–
Video page on how to find page online: https://app.hubspot.com/academy/6927185/tracks/121/814/4341 to work on it. (It needs starter pack to create website pages.)
—–
Create different types of modules: https://designers.hubspot.com/docs/modules/getting-started
—–
Code to create independent, working drag and drop area in template:
{% dnd_area “no_structure”, label=”No Structure” %}
{% end_dnd_area %}
—–
Create predefined drag and drop area in template:
{% dnd_area “little_structure”, label=”Some structure” %}
{% dnd_section
background_color={
r: 100,
g: 100,
b: 100,
a: 1
}, padding={
top: 10,
bottom: 10,
left: 10,
right: 10
}, vertical_alignment=’MIDDLE’
%}
{% dnd_column width=4 %}
{% dnd_row %}
{% dnd_module “image” path=”@hubspot/image”, flexbox_positioning=’MIDDLE_CENTER’, label=”Feature Image” %}
{% end_dnd_module %}
{% end_dnd_row %}
{% dnd_end_column %}

{% dnd_column width=8, offset=4 %}
{% dnd_row %}
{% dnd_module “rich_text” path=”@hubspot/rich_text”, label=”Feature Text” %}
{% end_dnd_module %}
{% end_dnd_row %}
{% end_dnd_column %}
{% end_dnd_section %}
{% end_dnd_area %}

This code CSS padding only apply to lowermost, and needs fixed.
—–
Help on modules: https://designers.hubspot.com/transitioning-from-v1-to-v2-modules

4. Create module

In Design Manager, on left, click ‘File’, create new file, select Module, name module and create.
Other instructions: https://app.hubspot.com/academy/6927185/tracks/121/290/4345
—–
Write all code in HTML.
(logo module and rich text module are default created in new template)
Rich text default contents can be replaced by module block syntax, eg:

{% module_block module “my_rich_text_module” label=”My module label” path=”@hubspot/rich_text” %}
{% module_attribute “html” %}

My text

{% end_module_attribute %}
{% end_module_block %}
—–
To change default logo of a template, than other website, write following module code (it is not block module, it is single line module code):

{% module “page_template_logo” path=”@hubspot/logo” label=”logo”,
img={
“override_inherited_src”: true,
“src”: “https://new-logo-link.png”,
“alt”: “secondary logo” }
%}
—–
Different module field types: https://developers.hubspot.com/en/docs/cms/building-blocks/module-theme-fields

https://developers.hubspot.com/docs/cms/building-blocks/modules/configuration

5. Create theme

Boilerplate free theme setup: https://github.com/hubspot/cms-theme-boilerplate
—–
Theme file/folder structure explained here: https://app.hubspot.com/academy/6927185/tracks/121/1011818/4347
—–
Build a theme from scratch: https://app.hubspot.com/academy/6927185/tracks/121/1011818/4348
1) Create folder, setup local dev tool and configure it to sandbox account
2) Run watch command in other terminal window, to syn all changes itself to sandbox account
—-
How to setup ‘Watch’ command to automatically upload changes dynamically from local code to online code:

npx hs fetch –portal=DEV cms-project

npx hs upload –mode=draft cms-project cms-project

npx hs watch –mode=draft cms-project cms-project

(Here ‘DEV’ is your name, ‘cms-project’ is theme or project name. Enter Ctrl-c to stop watching.)
—-
Fow above two steps: https://developers.hubspot.com/docs/cms/developer-reference/local-development-cli
3) Crate a theme folder
Enter: mkdir theme-name
4) Inside this folder create other folders:
Enter: mkdir templates modules js images css
5) hs create template templates/basic-page
(Using cli is good because it automatically put basic code in files.)
Further make changes in file as shown in video
6) Create sub-directory
Enter: mkdir templates/partials
7)
Enter: hs create template templates/partials/header
Select ‘Global Partial’, for letting editors to modify it for entire site
Add code from main template file to header file.
In main template add global partial tag and link to header page.
8) Create CSS
Enter: touch css/main.css
Intags of theme template, link to CSS file.There will be ready made css in css file.To add image use url({{ get_asset_url(‘../path/to/file/’)}}) function9) Create fields file and another for metadata for the themeEnter: touch fields.jsonEnter: touch theme.json10) In fields.json, add code as in video. This can be used in main css file as function.(Same can be seen in Hubspot account, after creating a page, it will have these template options.)

6. HubDB

Create table, fill data, fetch data from table: https://app.hubspot.com/academy/6927185/tracks/121/354/1922
Different filters available to fetch specific data from table.
Written details at: https://developers.hubspot.com/docs/cms/guides/hubdb/join-multiple-tables
—–
Dynamically fetch data from table:
1) Click ‘Settings’ in table and select ‘Use for dynamic pages’. It add two new columns in table: ‘page title’ and ‘page path’.
2) In template code following code:
{% if dynamic_page_hubdb_row %}

{{ dynamic_page_hubdb_row.name }}

{{ dynamic_page_hubdb_row.author }}

{% elif dynamic_page_hubdb_table_id %}

{% for row in hubdb_table_rows(1027263) %}

{{row.name}}

{{ row.author }}

{% for tag in row.tags %}
{{ tag.name }} {% if !loop.last %}, {% endif %}
{% endfor %}

{% endform %}

{% endif %}

Go to create new website page (in hubspot) and this template created will be there.
In Settings, fill page title, page URL.
In HubDB section, in ‘Table for dynamic pages’, select table name.
Publish page and see output.
When we click links, it opens new pages, with data, according to code done above.
—–
In table multi-select can be used to get data from foriegn tables. ID is unique field for foreign tables.
HubDB data is public so never save passwords there.
Only GET request to get data.
To write data to table, authentication is required.
Data can be pulled inside or outside CMS as well. Ajax or Javascript can be used to do it.
APIs available and Javascript.
For authenticated access, there is need of API key and OAuth. Code is also public. Third party service or proxy server required to mask authentication or build project outside CMS.
Link for API to update data, etc.: https://legacydocs.hubspot.com/docs/methods/hubdb/hubdb_overview
Link to API JS clients: https://docs.google.com/document/u/1/d/e/2PACX-1vTuu12oFF4bQY1zVD2-WKFuM2dEDN81-fZRV1tGaCL5Z_OcjC-B6O3mHXR6chaq25BU1D2FuvKIjc49/pub
—–
HubDB data can be exported as csv and imported as well. But if new select and multi-select column’s values added and imported, they won’t get imported, it will ask to select options.