@hubspot/cli 4.1.4-beta.0 → 4.1.4-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,73 +1,10 @@
1
- const path = require('path');
2
1
  const { createModulePrompt } = require('../../lib/prompts/createModulePrompt');
3
- const fs = require('fs-extra');
4
2
  const { logger } = require('@hubspot/cli-lib/logger');
5
3
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
4
+ const { createModule } = require('@hubspot/cli-lib/modules');
6
5
 
7
6
  const i18nKey = 'cli.commands.create.subcommands.module';
8
7
 
9
- const createModule = (moduleDefinition, name, dest) => {
10
- const writeModuleMeta = ({ contentTypes, moduleLabel, global }, dest) => {
11
- const metaData = {
12
- label: moduleLabel,
13
- css_assets: [],
14
- external_js: [],
15
- global: global,
16
- help_text: '',
17
- host_template_types: contentTypes,
18
- js_assets: [],
19
- other_assets: [],
20
- smart_type: 'NOT_SMART',
21
- tags: [],
22
- is_available_for_new_content: false,
23
- };
24
-
25
- fs.writeJSONSync(dest, metaData, { spaces: 2 });
26
- };
27
-
28
- const moduleFileFilter = (src, dest) => {
29
- const emailEnabled = moduleDefinition.contentTypes.includes('EMAIL');
30
-
31
- switch (path.basename(src)) {
32
- case 'meta.json':
33
- writeModuleMeta(moduleDefinition, dest);
34
- return false;
35
- case 'module.js':
36
- case 'module.css':
37
- if (emailEnabled) {
38
- return false;
39
- }
40
- return true;
41
- default:
42
- return true;
43
- }
44
- };
45
-
46
- const assetPath = path.resolve(__dirname, '../../defaults/Sample.module');
47
- const folderName = name.endsWith('.module') ? name : `${name}.module`;
48
- const destPath = path.join(dest, folderName);
49
- if (fs.existsSync(destPath)) {
50
- logger.error(
51
- i18n(`${i18nKey}.errors.pathExists`, {
52
- path: destPath,
53
- })
54
- );
55
- return;
56
- }
57
- logger.log(
58
- i18n(`${i18nKey}.creatingPath`, {
59
- path: destPath,
60
- })
61
- );
62
- fs.mkdirp(destPath);
63
- logger.log(
64
- i18n(`${i18nKey}.creatingModule`, {
65
- path: destPath,
66
- })
67
- );
68
- fs.copySync(assetPath, destPath, { filter: moduleFileFilter });
69
- };
70
-
71
8
  module.exports = {
72
9
  dest: ({ dest }) => dest,
73
10
  validate: ({ name }) => {
@@ -2,63 +2,11 @@ const {
2
2
  createTemplatePrompt,
3
3
  } = require('../../lib/prompts/createTemplatePrompt');
4
4
  const { logger } = require('@hubspot/cli-lib/logger');
5
- const path = require('path');
6
- const fs = require('fs-extra');
7
5
  const { i18n } = require('@hubspot/cli-lib/lib/lang');
6
+ const { createTemplate } = require('@hubspot/cli-lib/templates');
8
7
 
9
8
  const i18nKey = 'cli.commands.create.subcommands.template';
10
9
 
11
- const ASSET_PATHS = {
12
- 'page-template': path.resolve(__dirname, '../../defaults/page-template.html'),
13
- partial: path.resolve(__dirname, '../../defaults/partial.html'),
14
- 'global-partial': path.resolve(
15
- __dirname,
16
- '../../defaults/global-partial.html'
17
- ),
18
- 'email-template': path.resolve(
19
- __dirname,
20
- '../../defaults/email-template.html'
21
- ),
22
- 'blog-listing-template': path.resolve(
23
- __dirname,
24
- '../../defaults/blog-listing-template.html'
25
- ),
26
- 'blog-post-template': path.resolve(
27
- __dirname,
28
- '../../defaults/blog-post-template.html'
29
- ),
30
- 'search-template': path.resolve(
31
- __dirname,
32
- '../../defaults/search-template.html'
33
- ),
34
- };
35
-
36
- const createTemplate = (name, dest, type = 'page-template') => {
37
- const assetPath = ASSET_PATHS[type];
38
- const filename = name.endsWith('.html') ? name : `${name}.html`;
39
- const filePath = path.join(dest, filename);
40
- if (fs.existsSync(filePath)) {
41
- logger.error(
42
- i18n(`${i18nKey}.errors.pathExists`, {
43
- path: filePath,
44
- })
45
- );
46
- return;
47
- }
48
- logger.debug(
49
- i18n(`${i18nKey}.debug.creatingPath`, {
50
- path: dest,
51
- })
52
- );
53
- fs.mkdirp(dest);
54
- logger.log(
55
- i18n(`${i18nKey}.log.creatingFile`, {
56
- path: filePath,
57
- })
58
- );
59
- fs.copySync(assetPath, filePath);
60
- };
61
-
62
10
  module.exports = {
63
11
  dest: ({ dest }) => dest,
64
12
  validate: ({ name }) => {
@@ -30,7 +30,7 @@ exports.describe = i18n(`${i18nKey}.describe`);
30
30
  exports.handler = async options => {
31
31
  await loadAndValidateOptions(options);
32
32
 
33
- const { forceCreate, path: projectPath } = options;
33
+ const { forceCreate, path: projectPath, message } = options;
34
34
  const accountId = getAccountId(options);
35
35
  const accountConfig = getAccountConfig(accountId);
36
36
  const sandboxType = accountConfig && accountConfig.sandboxAccountType;
@@ -111,7 +111,13 @@ exports.handler = async options => {
111
111
  process.exit(exitCode);
112
112
  };
113
113
 
114
- await handleProjectUpload(accountId, projectConfig, projectDir, startPolling);
114
+ await handleProjectUpload(
115
+ accountId,
116
+ projectConfig,
117
+ projectDir,
118
+ startPolling,
119
+ message
120
+ );
115
121
  };
116
122
 
117
123
  exports.builder = yargs => {
@@ -126,6 +132,13 @@ exports.builder = yargs => {
126
132
  default: false,
127
133
  });
128
134
 
135
+ yargs.option('message', {
136
+ alias: 'm',
137
+ describe: i18n(`${i18nKey}.options.message.describe`),
138
+ type: 'string',
139
+ default: '',
140
+ });
141
+
129
142
  yargs.example([
130
143
  ['$0 project upload myProjectFolder', i18n(`${i18nKey}.examples.default`)],
131
144
  ]);
package/lib/projects.js CHANGED
@@ -22,7 +22,9 @@ const {
22
22
  const {
23
23
  createProject,
24
24
  getBuildStatus,
25
+ getBuildStructure,
25
26
  getDeployStatus,
27
+ getDeployStructure,
26
28
  fetchProject,
27
29
  uploadProject,
28
30
  } = require('@hubspot/cli-lib/api/dfs');
@@ -169,6 +171,8 @@ const ensureProjectExists = async (
169
171
  projectName,
170
172
  { forceCreate = false, allowCreate = true, noLogs = false } = {}
171
173
  ) => {
174
+ const i18nKey = 'cli.commands.project.lib.ensureProjectExists';
175
+ const accountIdentifier = uiAccountDescription(accountId);
172
176
  try {
173
177
  const project = await fetchProject(accountId, projectName);
174
178
  return !!project;
@@ -180,9 +184,10 @@ const ensureProjectExists = async (
180
184
  const promptResult = await promptUser([
181
185
  {
182
186
  name: 'shouldCreateProject',
183
- message: `The project ${projectName} does not exist in ${uiAccountDescription(
184
- accountId
185
- )}. Would you like to create it?`,
187
+ message: i18n(`${i18nKey}.createPrompt`, {
188
+ projectName,
189
+ accountIdentifier,
190
+ }),
186
191
  type: 'confirm',
187
192
  },
188
193
  ]);
@@ -191,7 +196,11 @@ const ensureProjectExists = async (
191
196
 
192
197
  if (shouldCreateProject) {
193
198
  try {
194
- return createProject(accountId, projectName);
199
+ await createProject(accountId, projectName);
200
+ logger.success(
201
+ i18n(`${i18nKey}.createSuccess`, { projectName, accountIdentifier })
202
+ );
203
+ return true;
195
204
  } catch (err) {
196
205
  return logApiErrorInstance(err, new ApiErrorContext({ accountId }));
197
206
  }
@@ -200,7 +209,7 @@ const ensureProjectExists = async (
200
209
  logger.log(
201
210
  `Your project ${chalk.bold(
202
211
  projectName
203
- )} could not be found in ${chalk.bold(accountId)}.`
212
+ )} could not be found in ${chalk.bold(accountIdentifier)}.`
204
213
  );
205
214
  }
206
215
  return false;
@@ -233,7 +242,12 @@ const getProjectDeployDetailUrl = (projectName, deployId, accountId) => {
233
242
  accountId
234
243
  )}/activity/deploy/${deployId}`;
235
244
  };
236
- const uploadProjectFiles = async (accountId, projectName, filePath) => {
245
+ const uploadProjectFiles = async (
246
+ accountId,
247
+ projectName,
248
+ filePath,
249
+ uploadMessage
250
+ ) => {
237
251
  const i18nKey = 'cli.commands.project.subcommands.upload';
238
252
  const spinnies = new Spinnies({
239
253
  succeedColor: 'white',
@@ -250,7 +264,12 @@ const uploadProjectFiles = async (accountId, projectName, filePath) => {
250
264
  let buildId;
251
265
 
252
266
  try {
253
- const upload = await uploadProject(accountId, projectName, filePath);
267
+ const upload = await uploadProject(
268
+ accountId,
269
+ projectName,
270
+ filePath,
271
+ uploadMessage
272
+ );
254
273
 
255
274
  buildId = upload.buildId;
256
275
 
@@ -295,9 +314,20 @@ const handleProjectUpload = async (
295
314
  accountId,
296
315
  projectConfig,
297
316
  projectDir,
298
- callbackFunc
317
+ callbackFunc,
318
+ uploadMessage
299
319
  ) => {
300
320
  const i18nKey = 'cli.commands.project.subcommands.upload';
321
+ const srcDir = path.resolve(projectDir, projectConfig.srcDir);
322
+
323
+ const filenames = fs.readdirSync(srcDir);
324
+ if (!filenames || filenames.length === 0) {
325
+ logger.log(
326
+ i18n(`${i18nKey}.logs.emptySource`, { srcDir: projectConfig.srcDir })
327
+ );
328
+ process.exit(EXIT_CODES.SUCCESS);
329
+ }
330
+
301
331
  const tempFile = tmp.fileSync({ postfix: '.zip' });
302
332
 
303
333
  logger.debug(
@@ -319,7 +349,8 @@ const handleProjectUpload = async (
319
349
  const { buildId } = await uploadProjectFiles(
320
350
  accountId,
321
351
  projectConfig.name,
322
- tempFile.name
352
+ tempFile.name,
353
+ uploadMessage
323
354
  );
324
355
 
325
356
  if (callbackFunc) {
@@ -329,10 +360,8 @@ const handleProjectUpload = async (
329
360
 
330
361
  archive.pipe(output);
331
362
 
332
- archive.directory(
333
- path.resolve(projectDir, projectConfig.srcDir),
334
- false,
335
- file => (shouldIgnoreFile(file.name) ? false : file)
363
+ archive.directory(srcDir, false, file =>
364
+ shouldIgnoreFile(file.name) ? false : file
336
365
  );
337
366
 
338
367
  archive.finalize();
@@ -340,6 +369,7 @@ const handleProjectUpload = async (
340
369
 
341
370
  const makePollTaskStatusFunc = ({
342
371
  statusFn,
372
+ structureFn,
343
373
  statusText,
344
374
  statusStrings,
345
375
  linkToHubSpot,
@@ -372,9 +402,19 @@ const makePollTaskStatusFunc = ({
372
402
 
373
403
  spinnies.add('overallTaskStatus', { text: 'Beginning' });
374
404
 
375
- const initialTaskStatus = await statusFn(accountId, taskName, taskId);
405
+ const [
406
+ initialTaskStatus,
407
+ { topLevelComponentsWithChildren: taskStructure },
408
+ ] = await Promise.all([
409
+ statusFn(accountId, taskName, taskId),
410
+ structureFn(accountId, taskName, taskId),
411
+ ]);
412
+
413
+ const topLevelSubtasks = initialTaskStatus[statusText.SUBTASK_KEY].filter(
414
+ ({ id }) => !!taskStructure[id]
415
+ );
376
416
 
377
- const numOfComponents = initialTaskStatus[statusText.SUBTASK_KEY].length;
417
+ const numOfComponents = topLevelSubtasks.length;
378
418
  const componentCountText = `\nFound ${numOfComponents} component${
379
419
  numOfComponents !== 1 ? 's' : ''
380
420
  } in this project ...\n`;
@@ -383,7 +423,7 @@ const makePollTaskStatusFunc = ({
383
423
  text: `${statusStrings.INITIALIZE(taskName)}${componentCountText}`,
384
424
  });
385
425
 
386
- for (let subTask of initialTaskStatus[statusText.SUBTASK_KEY]) {
426
+ for (let subTask of topLevelSubtasks) {
387
427
  const subTaskName = subTask[statusText.SUBTASK_NAME_KEY];
388
428
 
389
429
  spinnies.add(subTaskName, {
@@ -491,6 +531,7 @@ const pollBuildStatus = makePollTaskStatusFunc({
491
531
  getProjectBuildDetailUrl(taskName, taskId, accountId)
492
532
  ),
493
533
  statusFn: getBuildStatus,
534
+ structureFn: getBuildStructure,
494
535
  statusText: PROJECT_BUILD_TEXT,
495
536
  statusStrings: {
496
537
  INITIALIZE: name => `Building ${chalk.bold(name)}`,
@@ -510,6 +551,7 @@ const pollDeployStatus = makePollTaskStatusFunc({
510
551
  getProjectDeployDetailUrl(taskName, taskId, accountId)
511
552
  ),
512
553
  statusFn: getDeployStatus,
554
+ structureFn: getDeployStructure,
513
555
  statusText: PROJECT_DEPLOY_TEXT,
514
556
  statusStrings: {
515
557
  INITIALIZE: name => `Deploying ${chalk.bold(name)}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "4.1.4-beta.0",
3
+ "version": "4.1.4-beta.1",
4
4
  "description": "CLI for working with HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,8 +8,8 @@
8
8
  "url": "https://github.com/HubSpot/hubspot-cms-tools"
9
9
  },
10
10
  "dependencies": {
11
- "@hubspot/cli-lib": "4.1.4-beta.0",
12
- "@hubspot/serverless-dev-runtime": "4.1.4-beta.0",
11
+ "@hubspot/cli-lib": "4.1.4-beta.1",
12
+ "@hubspot/serverless-dev-runtime": "4.1.4-beta.1",
13
13
  "archiver": "^5.3.0",
14
14
  "chalk": "^4.1.2",
15
15
  "express": "^4.17.1",
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "0a74040f490d7c20d65da0b20ad79517b396243f"
40
+ "gitHead": "ccf28361f15b4834b32d25f0879d40b3b1ee8b52"
41
41
  }
@@ -1,11 +0,0 @@
1
- [
2
- {
3
- "default": "<h1>Hello, world!</h1>",
4
- "label": "Rich text field",
5
- "locked": false,
6
- "name": "text",
7
- "required": false,
8
- "type": "richtext",
9
- "validation_regex": ""
10
- }
11
- ]
@@ -1,12 +0,0 @@
1
- {
2
- "css_assets": [],
3
- "external_js": [],
4
- "global": false,
5
- "help_text": "",
6
- "host_template_types": ["PAGE"],
7
- "js_assets": [],
8
- "other_assets": [],
9
- "smart_type": "NOT_SMART",
10
- "tags": [],
11
- "is_available_for_new_content": false
12
- }
File without changes
@@ -1 +0,0 @@
1
- <!-- module html -->
File without changes
@@ -1,151 +0,0 @@
1
- <!--
2
- templateType: blog_listing
3
- isAvailableForNewContent: true
4
- label: Blog listing
5
- -->
6
- <!doctype html>
7
- <html>
8
- <head>
9
- <meta charset="utf-8">
10
- <title>{{ content.html_title }}</title>
11
- <meta name="description" content="{{ content.meta_description }}">
12
- {{ standard_header_includes }}
13
- </head>
14
- <body>
15
- <main>
16
-
17
- {# Blog author listing #}
18
- {% if blog_author %}
19
- <div>
20
- {% if blog_author.avatar %}
21
- <img src="{{ blog_author.avatar }}" alt="image of blog {{ blog_author.display_name }}">
22
- {% endif %}
23
- <h1>{{ blog_author.display_name }}</h1>
24
- {% if blog_author.bio %}
25
- <p>{{ blog_author.bio }}</p>
26
- {% endif %}
27
- {% if blog_author.has_social_profiles %}
28
- <div>
29
- {% if blog_author.website %}
30
- <a href="{{ blog_author.website }}" target="_blank" rel="noopener">
31
- {% icon
32
- name='link',
33
- purpose='semantic',
34
- style='SOLID',
35
- title='Follow me on my website',
36
- width='10'
37
- %}
38
- </a>
39
- {% endif %}
40
- {% if blog_author.facebook %}
41
- <a href="{{ blog_author.facebook }}" target="_blank" rel="noopener">
42
- {% icon
43
- name='facebook-f',
44
- purpose='semantic',
45
- style='SOLID',
46
- title='Follow me on Facebook',
47
- width='10'
48
- %}
49
- </a>
50
- {% endif %}
51
- {% if blog_author.linkedin %}
52
- <a href="{{ blog_author.linkedin }}" target="_blank" rel="noopener">
53
- {% icon
54
- name='linkedin-in',
55
- purpose='semantic',
56
- style='SOLID',
57
- title='Follow me on LinkedIn',
58
- width='10'
59
- %}
60
- </a>
61
- {% endif %}
62
- {% if blog_author.twitter %}
63
- <a href="{{ blog_author.twitter }}" target="_blank" rel="noopener">
64
- {% icon
65
- name='twitter',
66
- purpose='semantic',
67
- style='SOLID',
68
- title='Follow me on Twitter',
69
- width='10'
70
- %}
71
- </a>
72
- {% endif %}
73
- </div>
74
- {% endif %}
75
- </div>
76
- {% elif tag %}
77
- {# End blog author listing #}
78
-
79
- {# Blog tag listing #}
80
- <div>
81
- <h1>Posts about {{ page_meta.html_title|split(' | ')|last }}</h1>
82
- </div>
83
- {% else %}
84
- {# End blog tag listing #}
85
-
86
- {# Blog header #}
87
- <div>
88
- <h1>{{ group.public_title }}</h1>
89
- <p>{{ group.description }}</p>
90
- </div>
91
- {% endif %}
92
- {# End blog header #}
93
-
94
- <div>
95
-
96
- {# Blog listing section #}
97
- <section>
98
-
99
- {# Blog listing #}
100
- {% for content in contents %}
101
- <article>
102
- {% if content.featured_image and group.use_featured_image_in_summary %}
103
- <a href="{{ content.absolute_url }}">
104
- <img src="{{ content.featured_image }}" alt="{{ content.featured_image_alt_text }}">
105
- </a>
106
- {% endif %}
107
- <div>
108
- <h2><a href="{{ content.absolute_url }}">{{ content.name }}</a></h2>
109
- {% if content_group.show_summary_in_listing %}
110
- {{ content.post_list_content|truncatehtml(100) }}
111
- {% endif %}
112
- </div>
113
- </article>
114
- {% endfor %}
115
- {# End blog listing #}
116
-
117
- </section>
118
- {# End blog listing section #}
119
-
120
- {# Blog pagination #}
121
- {% if contents.total_page_count > 1 %}
122
- <nav aria-label="Pagination" role="navigation">
123
- {% set page_list = [-2, -1, 0, 1, 2] %}
124
- {% if contents.total_page_count - current_page_num == 1 %}{% set offset = -1 %}
125
- {% elif contents.total_page_count - current_page_num == 0 %}{% set offset = -2 %}
126
- {% elif current_page_num == 2 %}{% set offset = 1 %}
127
- {% elif current_page_num == 1 %}{% set offset = 2 %}
128
- {% else %}{% set offset = 0 %}{% endif %}
129
-
130
- <a class="blog-pagination__link blog-pagination__prev-link {{ 'blog-pagination__prev-link--disabled' if !last_page_num }}"{% if last_page_num %} href="{% if current_page_num == 2 %}{{ group.absolute_url }} {% else %}{{ blog_page_link(last_page_num) }}{% endif %}" rel="prev"{% else %} aria-disabled="true" disabled {% endif %} role="button" aria-label="Go to previous page">
131
- Prev
132
- </a>
133
- {% for page in page_list %}
134
- {% set this_page = current_page_num + page + offset %}
135
- {% if this_page > 0 and this_page <= contents.total_page_count %}
136
- <a class="blog-pagination__link blog-pagination__number-link {{ 'blog-pagination__link--active' if this_page == current_page_num }}" aria-label="Go to Page {{ this_page }}" {% if this_page == current_page_num %}aria-current="true"{% endif %} href="{% if this_page == 1 %}{{ group.absolute_url }}{% else %}{{ blog_page_link(this_page) }}{% endif %}">{{ this_page }}</a>
137
- {% endif %}
138
- {% endfor %}
139
- <a class="blog-pagination__link blog-pagination__next-link {{ 'blog-pagination__next-link--disabled' if !next_page_num }}"{% if next_page_num %} href="{{ blog_page_link(current_page_num + 1) }}" rel="prev" {% else %} aria-disabled="true" disabled {% endif %} role="button" aria-label="Go to next page">
140
- Next
141
- </a>
142
- </nav>
143
- {% endif %}
144
- {# End blog pagination #}
145
-
146
- </div>
147
-
148
- </main>
149
- {{ standard_footer_includes }}
150
- </body>
151
- </html>
@@ -1,50 +0,0 @@
1
- <!--
2
- templateType: blog_post
3
- isAvailableForNewContent: true
4
- label: Blog post
5
- -->
6
- <!DOCTYPE html>
7
- <html>
8
- <head>
9
- <meta charset="utf-8" />
10
- <title>{{ content.html_title }}</title>
11
- <meta name="description" content="{{ content.meta_description }}" />
12
- {{ standard_header_includes }}
13
- </head>
14
- <body>
15
- <main>
16
-
17
- {# Blog post #}
18
- <article>
19
- <h1>{{ content.name }}</h1>
20
- <div>
21
- <a href="{{ blog_author_url(group.id, content.blog_post_author.slug) }}" rel="author">
22
- {{ content.blog_post_author.display_name }}
23
- </a>
24
- <time>
25
- {{ content.publish_date_localized }}
26
- </time>
27
- </div>
28
- <div>
29
- {{ content.post_body }}
30
- </div>
31
- {% if content.tag_list %}
32
- <div>
33
- {% for tag in content.tag_list %}
34
- <a href="{{ blog_tag_url(group.id, tag.slug) }}" rel="tag">{{ tag.name }}</a> {% if not loop.last %},{% endif %}
35
- {% endfor %}
36
- </div>
37
- {% endif %}
38
- </article>
39
-
40
- {% if group.allow_comments %}
41
- <div>
42
- {% module 'blog_comments' path='@hubspot/blog_comments', label="Blog comments" %}
43
- </div>
44
- {% endif %}
45
- {# End blog post #}
46
-
47
- </main>
48
- {{ standard_footer_includes }}
49
- </body>
50
- </html>
@@ -1,48 +0,0 @@
1
- <!--
2
- templateType: email
3
- label: Email
4
- isAvailableForNewContent: true
5
- -->
6
- <!doctype html>
7
- <html>
8
- <head>
9
- <title>{% if content.html_title and content.html_title != '' %}{{ content.html_title }}{% else %}{{ content.body.subject }}{% endif %}</title>
10
- {% if content.meta_description %}<meta name="description" content="{{ content.meta_description }}"/>{% endif %}
11
- <style type="text/css" id="hs-inline-css">
12
- /*<![CDATA[*/
13
- /* everything in this style tag will be inlined onto matching elements */
14
- .sample-rule {
15
- }
16
- /*]]>*/
17
- </style>
18
- </head>
19
- <body>
20
- <!-- Preview text (text which appears right after subject in certain email clients) -->
21
- <div id="preview_text" style="display:none!important">{% text "preview_text" label="Preview Text <span class=help-text>This will be used as the preview text that displays in some email clients</span>", value="", no_wrapper=True %}</div>
22
- <!-- View as webpage link -->
23
- {% if content.create_page %}
24
- <div>
25
- Not rendering correctly? View this email as a web page <a class="hubspot-mergetag" data-viewaswebpage="true" href="{{ view_as_page_url }}">here</a>.
26
- </div>
27
- {% endif %}
28
- <!-- Insert body here -->
29
- {% module "email_template_logo" path="@hubspot/logo" label="Logo" %}
30
- {% module "email_template_main_email_body" path="@hubspot/email_body" label="Main Email Body" %}
31
- <!-- Office location information and unsubscribe links -->
32
- <p id="footer">
33
- {{ site_settings.company_name }}&nbsp;
34
- {{ site_settings.company_street_address_1 }}&nbsp;
35
- {{ site_settings.company_street_address_2 }}&nbsp;
36
- {{ site_settings.company_city }}&nbsp;
37
- {{ site_settings.company_state }}&nbsp;
38
- {{ site_settings.company_zip }}&nbsp;
39
- {{ site_settings.company_country }}&nbsp;
40
- <br/>
41
- You received this email because you are subscribed to {{ subscription_name }} from {{ site_settings.company_name }}.
42
- <br/>
43
- Update your <a class="hubspot-mergetag" data-unsubscribe="true" href="{{ unsubscribe_link }}">email preferences</a> to choose the types of emails you receive.
44
- <br/>
45
- <a class="hubspot-mergetag" data-unsubscribe="true" href="{{ unsubscribe_link_all }}">Unsubscribe from all future emails</a>
46
- </p>
47
- </body>
48
- </html>
@@ -1,8 +0,0 @@
1
- <!--
2
- templateType: global_partial
3
- label: Global partial
4
- isAvailableForNewContent: false
5
- -->
6
- <!-- Begin partial -->
7
-
8
- <!-- End partial -->
@@ -1,19 +0,0 @@
1
- <!--
2
- templateType: page
3
- label: Page template
4
- isAvailableForNewContent: true
5
- -->
6
- <!doctype html>
7
- <html>
8
- <head>
9
- <meta charset="utf-8">
10
- <title>{{ content.html_title }}</title>
11
- <meta name="description" content="{{ content.meta_description }}">
12
- {{ standard_header_includes }}
13
- </head>
14
- <body>
15
- {% module "page_template_logo" path="@hubspot/logo" label="Logo" %}
16
- {% module "page_template_rich_text" path="@hubspot/rich_text" label="Rich Text" %}
17
- {{ standard_footer_includes }}
18
- </body>
19
- </html>
@@ -1,7 +0,0 @@
1
- <!--
2
- templateType: page
3
- isAvailableForNewContent: false
4
- -->
5
- <!-- Begin partial -->
6
-
7
- <!-- End partial -->
@@ -1,15 +0,0 @@
1
- <!--
2
- templateType: section
3
- isAvailableForNewContent: false
4
- -->
5
- {% dnd_section %}
6
- {% dnd_column %}
7
- {% dnd_row %}
8
- {% dnd_module
9
- path='@hubspot/rich_text',
10
- html='<h1>Hello world</h1>'
11
- %}
12
- {% end_dnd_module %}
13
- {% end_dnd_row %}
14
- {% end_dnd_column %}
15
- {% end_dnd_section %}
@@ -1,20 +0,0 @@
1
- <!--
2
- templateType: search_results_page
3
- label: Search results page
4
- isAvailableForNewContent: true
5
- -->
6
- <!doctype html>
7
- <html>
8
- <head>
9
- <meta charset="utf-8">
10
- <title>{{ content.html_title }}</title>
11
- <meta name="description" content="{{ content.meta_description }}">
12
- {{ standard_header_includes }}
13
- </head>
14
- <body>
15
- {% module "search_results_page_template_logo" path="@hubspot/logo" label="Logo" %}
16
- {% module "search_results_page_search_field" overrideable=true, path="@hubspot/search_input", label='Site Search Input' %}
17
- {% module "search_results_page_search_results" overrideable=true, path="@hubspot/search_results", label='Site Search Results' %}
18
- {{ standard_footer_includes }}
19
- </body>
20
- </html>