hubspot-cms-sync 0.5.3 → 0.5.4

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hubspot-cms-sync",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Git-backed bidirectional sync for HubSpot CMS themes, content, blogs, forms, and assets.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,7 +41,7 @@ async function loadTagSlugs(siteDir) {
41
41
  * trackingPortalId, if set, injects the HubSpot tracking script into the footer so
42
42
  * forms keep de-anonymizing (`standard_footer_includes`). Returns counts.
43
43
  */
44
- export async function buildStatic({ siteDir, outDir, baseUrl = '', assetBase = '/assets', trackingPortalId } = {}) {
44
+ export async function buildStatic({ siteDir, outDir, baseUrl = '', assetBase = '/assets', trackingPortalId, blogPageSize = 20 } = {}) {
45
45
  const tagMap = await loadTagSlugs(siteDir);
46
46
  const tagSlugFor = (name) => tagMap[name] || slugify(name);
47
47
  const footerIncludes = trackingPortalId
@@ -76,7 +76,17 @@ export async function buildStatic({ siteDir, outDir, baseUrl = '', assetBase = '
76
76
  fileCount++;
77
77
  }
78
78
 
79
- await emit('/blog', renderBlogListing(posts, { ...opts, route: '/blog' }));
79
+ // Paginate listings to match HubSpot (20 posts/page; page 1 = base, page N = base/page/N).
80
+ // Without this the static listing renders every post on one page.
81
+ async function emitListing(basePath, items) {
82
+ const totalPages = Math.max(1, Math.ceil(items.length / blogPageSize));
83
+ for (let pageNum = 1; pageNum <= totalPages; pageNum += 1) {
84
+ const route = pageNum === 1 ? basePath : `${basePath}/page/${pageNum}`;
85
+ await emit(route, renderBlogListing(items, { ...opts, route, basePath, pageNum, pageSize: blogPageSize }));
86
+ }
87
+ }
88
+
89
+ await emitListing('/blog', posts);
80
90
 
81
91
  // One listing per tag, posts grouped by tag slug (preserves newest-first order).
82
92
  const byTag = new Map();
@@ -88,7 +98,7 @@ export async function buildStatic({ siteDir, outDir, baseUrl = '', assetBase = '
88
98
  }
89
99
  }
90
100
  for (const [slug, tagPosts] of byTag) {
91
- await emit(`/blog/tag/${slug}`, renderBlogListing(tagPosts, { ...opts, route: `/blog/tag/${slug}` }));
101
+ await emitListing(`/blog/tag/${slug}`, tagPosts);
92
102
  }
93
103
 
94
104
  // Assets. get_asset_url maps ../css|js|images -> /css|js|images; @asset:<p> -> /assets/<p>.
@@ -306,13 +306,23 @@ export function renderPage(page, { siteDir, site, baseUrl = '', assetBase = '/as
306
306
  // by contents.total_page_count > 1) is inert.
307
307
  // ---------------------------------------------------------------------------
308
308
  export function renderBlogListing(posts, { siteDir, site, baseUrl = '', assetBase = '/assets', lang = 'en',
309
- headerIncludes = '', footerIncludes = '', tagSlugFor, route = '/blog' } = {}) {
309
+ headerIncludes = '', footerIncludes = '', tagSlugFor, route = '/blog',
310
+ basePath = null, pageNum = 1, pageSize = 0 } = {}) {
310
311
  const opts = { baseUrl, assetBase, lang, headerIncludes, footerIncludes, tagSlugFor };
311
312
  const env = makeEnv(siteDir, { site, opts });
313
+ // Pagination: pageSize <= 0 keeps the whole list on one page (back-compat). Otherwise
314
+ // slice to the page window. blog_page_link mirrors HubSpot — page 1 is the listing
315
+ // base (e.g. /blog), page N is <base>/page/N — and drives the template's paginator.
316
+ const base = basePath || route;
317
+ const totalPages = pageSize > 0 ? Math.max(1, Math.ceil(posts.length / pageSize)) : 1;
318
+ const pageItems = pageSize > 0 ? posts.slice((pageNum - 1) * pageSize, pageNum * pageSize) : posts;
319
+ env.addGlobal('blog_page_link', (n) => (Number(n) <= 1 ? base : `${base}/page/${n}`));
320
+ const contents = pageItems.map((p) => postContent(p, opts));
321
+ contents.total_page_count = totalPages;
312
322
  const context = {
313
- contents: posts.map((p) => postContent(p, opts)),
323
+ contents,
314
324
  content: { absolute_url: baseUrl + route, canonical_url: baseUrl + route },
315
- current_page_num: 1,
325
+ current_page_num: pageNum,
316
326
  nav_active: null,
317
327
  nav_hide_cta: false,
318
328
  };