ghost 5.62.0 → 5.63.0

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.
Files changed (157) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.63.0.tgz +0 -0
  2. package/components/{tryghost-adapter-cache-redis-5.62.0.tgz → tryghost-adapter-cache-redis-5.63.0.tgz} +0 -0
  3. package/components/{tryghost-adapter-manager-5.62.0.tgz → tryghost-adapter-manager-5.63.0.tgz} +0 -0
  4. package/components/{tryghost-announcement-bar-settings-5.62.0.tgz → tryghost-announcement-bar-settings-5.63.0.tgz} +0 -0
  5. package/components/{tryghost-api-framework-5.62.0.tgz → tryghost-api-framework-5.63.0.tgz} +0 -0
  6. package/components/{tryghost-api-version-compatibility-service-5.62.0.tgz → tryghost-api-version-compatibility-service-5.63.0.tgz} +0 -0
  7. package/components/{tryghost-audience-feedback-5.62.0.tgz → tryghost-audience-feedback-5.63.0.tgz} +0 -0
  8. package/components/tryghost-bookshelf-repository-5.63.0.tgz +0 -0
  9. package/components/{tryghost-bootstrap-socket-5.62.0.tgz → tryghost-bootstrap-socket-5.63.0.tgz} +0 -0
  10. package/components/tryghost-collections-5.63.0.tgz +0 -0
  11. package/components/{tryghost-constants-5.62.0.tgz → tryghost-constants-5.63.0.tgz} +0 -0
  12. package/components/tryghost-custom-theme-settings-service-5.63.0.tgz +0 -0
  13. package/components/{tryghost-data-generator-5.62.0.tgz → tryghost-data-generator-5.63.0.tgz} +0 -0
  14. package/components/{tryghost-domain-events-5.62.0.tgz → tryghost-domain-events-5.63.0.tgz} +0 -0
  15. package/components/{tryghost-donations-5.62.0.tgz → tryghost-donations-5.63.0.tgz} +0 -0
  16. package/components/tryghost-dynamic-routing-events-5.63.0.tgz +0 -0
  17. package/components/tryghost-email-analytics-provider-mailgun-5.63.0.tgz +0 -0
  18. package/components/{tryghost-email-analytics-service-5.62.0.tgz → tryghost-email-analytics-service-5.63.0.tgz} +0 -0
  19. package/components/{tryghost-email-content-generator-5.62.0.tgz → tryghost-email-content-generator-5.63.0.tgz} +0 -0
  20. package/components/tryghost-email-events-5.63.0.tgz +0 -0
  21. package/components/{tryghost-email-service-5.62.0.tgz → tryghost-email-service-5.63.0.tgz} +0 -0
  22. package/components/tryghost-email-suppression-list-5.63.0.tgz +0 -0
  23. package/components/tryghost-event-aware-cache-wrapper-5.63.0.tgz +0 -0
  24. package/components/tryghost-express-dynamic-redirects-5.63.0.tgz +0 -0
  25. package/components/{tryghost-external-media-inliner-5.62.0.tgz → tryghost-external-media-inliner-5.63.0.tgz} +0 -0
  26. package/components/{tryghost-extract-api-key-5.62.0.tgz → tryghost-extract-api-key-5.63.0.tgz} +0 -0
  27. package/components/{tryghost-html-to-plaintext-5.62.0.tgz → tryghost-html-to-plaintext-5.63.0.tgz} +0 -0
  28. package/components/tryghost-i18n-5.63.0.tgz +0 -0
  29. package/components/tryghost-importer-handler-content-files-5.63.0.tgz +0 -0
  30. package/components/{tryghost-importer-revue-5.62.0.tgz → tryghost-importer-revue-5.63.0.tgz} +0 -0
  31. package/components/{tryghost-in-memory-repository-5.62.0.tgz → tryghost-in-memory-repository-5.63.0.tgz} +0 -0
  32. package/components/{tryghost-job-manager-5.62.0.tgz → tryghost-job-manager-5.63.0.tgz} +0 -0
  33. package/components/{tryghost-link-redirects-5.62.0.tgz → tryghost-link-redirects-5.63.0.tgz} +0 -0
  34. package/components/{tryghost-link-replacer-5.62.0.tgz → tryghost-link-replacer-5.63.0.tgz} +0 -0
  35. package/components/{tryghost-link-tracking-5.62.0.tgz → tryghost-link-tracking-5.63.0.tgz} +0 -0
  36. package/components/tryghost-magic-link-5.63.0.tgz +0 -0
  37. package/components/{tryghost-mail-events-5.62.0.tgz → tryghost-mail-events-5.63.0.tgz} +0 -0
  38. package/components/{tryghost-mailgun-client-5.62.0.tgz → tryghost-mailgun-client-5.63.0.tgz} +0 -0
  39. package/components/{tryghost-member-attribution-5.62.0.tgz → tryghost-member-attribution-5.63.0.tgz} +0 -0
  40. package/components/{tryghost-member-events-5.62.0.tgz → tryghost-member-events-5.63.0.tgz} +0 -0
  41. package/components/tryghost-members-api-5.63.0.tgz +0 -0
  42. package/components/{tryghost-members-csv-5.62.0.tgz → tryghost-members-csv-5.63.0.tgz} +0 -0
  43. package/components/{tryghost-members-events-service-5.62.0.tgz → tryghost-members-events-service-5.63.0.tgz} +0 -0
  44. package/components/{tryghost-members-importer-5.62.0.tgz → tryghost-members-importer-5.63.0.tgz} +0 -0
  45. package/components/{tryghost-members-offers-5.62.0.tgz → tryghost-members-offers-5.63.0.tgz} +0 -0
  46. package/components/{tryghost-members-payments-5.62.0.tgz → tryghost-members-payments-5.63.0.tgz} +0 -0
  47. package/components/tryghost-members-ssr-5.63.0.tgz +0 -0
  48. package/components/{tryghost-members-stripe-service-5.62.0.tgz → tryghost-members-stripe-service-5.63.0.tgz} +0 -0
  49. package/components/tryghost-mentions-email-report-5.63.0.tgz +0 -0
  50. package/components/tryghost-milestones-5.63.0.tgz +0 -0
  51. package/components/{tryghost-minifier-5.62.0.tgz → tryghost-minifier-5.63.0.tgz} +0 -0
  52. package/components/tryghost-model-to-domain-event-interceptor-5.63.0.tgz +0 -0
  53. package/components/tryghost-mw-api-version-mismatch-5.63.0.tgz +0 -0
  54. package/components/tryghost-mw-cache-control-5.63.0.tgz +0 -0
  55. package/components/{tryghost-mw-error-handler-5.62.0.tgz → tryghost-mw-error-handler-5.63.0.tgz} +0 -0
  56. package/components/tryghost-mw-session-from-token-5.63.0.tgz +0 -0
  57. package/components/tryghost-mw-update-user-last-seen-5.63.0.tgz +0 -0
  58. package/components/tryghost-mw-version-match-5.63.0.tgz +0 -0
  59. package/components/tryghost-mw-vhost-5.63.0.tgz +0 -0
  60. package/components/{tryghost-nql-filter-expansions-5.62.0.tgz → tryghost-nql-filter-expansions-5.63.0.tgz} +0 -0
  61. package/components/tryghost-oembed-service-5.63.0.tgz +0 -0
  62. package/components/{tryghost-package-json-5.62.0.tgz → tryghost-package-json-5.63.0.tgz} +0 -0
  63. package/components/tryghost-post-events-5.63.0.tgz +0 -0
  64. package/components/tryghost-post-revisions-5.63.0.tgz +0 -0
  65. package/components/tryghost-posts-service-5.63.0.tgz +0 -0
  66. package/components/tryghost-recommendations-5.63.0.tgz +0 -0
  67. package/components/tryghost-referrers-5.63.0.tgz +0 -0
  68. package/components/{tryghost-security-5.62.0.tgz → tryghost-security-5.63.0.tgz} +0 -0
  69. package/components/tryghost-session-service-5.63.0.tgz +0 -0
  70. package/components/tryghost-settings-path-manager-5.63.0.tgz +0 -0
  71. package/components/tryghost-slack-notifications-5.63.0.tgz +0 -0
  72. package/components/{tryghost-staff-service-5.62.0.tgz → tryghost-staff-service-5.63.0.tgz} +0 -0
  73. package/components/tryghost-stats-service-5.63.0.tgz +0 -0
  74. package/components/{tryghost-tiers-5.62.0.tgz → tryghost-tiers-5.63.0.tgz} +0 -0
  75. package/components/{tryghost-update-check-service-5.62.0.tgz → tryghost-update-check-service-5.63.0.tgz} +0 -0
  76. package/components/tryghost-verification-trigger-5.63.0.tgz +0 -0
  77. package/components/{tryghost-version-notifications-data-service-5.62.0.tgz → tryghost-version-notifications-data-service-5.63.0.tgz} +0 -0
  78. package/components/{tryghost-webmentions-5.62.0.tgz → tryghost-webmentions-5.63.0.tgz} +0 -0
  79. package/core/built/admin/assets/{chunk.143.5b5502a550ce35005d0f.js → chunk.143.1c5d21facf1f9b9beef9.js} +5 -5
  80. package/core/built/admin/assets/{chunk.178.546664edca0b1b0f2ab2.js → chunk.178.43b03c9ac011a54262b0.js} +4 -4
  81. package/core/built/admin/assets/{chunk.853.f743ed975e8838475532.js → chunk.237.9b7032162949850f6c76.js} +690 -678
  82. package/core/built/admin/assets/{ghost-8a4e981c272f793157133814ca7c7e84.css → ghost-33664cad4cd6664a8b5fa56e62c5005f.css} +1 -1
  83. package/core/built/admin/assets/{ghost-d804aba7bca07fa75d308ab892c508fc.js → ghost-7c3f2de2ec83e591ad9f9db5165b2733.js} +62 -57
  84. package/core/built/admin/assets/ghost-dark-0452daeaee3a9b16dcd954ea60dad518.css +1 -0
  85. package/core/built/admin/assets/{vendor-b50a3e5c2079b8a35d9122a1a4c34ef6.js → vendor-f8ce8bd43cf5dad6608f828ab48cee9b.js} +2 -2
  86. package/core/built/admin/index.html +6 -6
  87. package/core/frontend/helpers/foreach.js +8 -0
  88. package/core/frontend/helpers/get.js +3 -0
  89. package/core/frontend/meta/schema.js +1 -1
  90. package/core/frontend/services/data/checks.js +6 -0
  91. package/core/frontend/src/cards/css/collection.css +186 -0
  92. package/core/frontend/src/cards/css/header_v2.css +19 -23
  93. package/core/frontend/src/cards/css/signup.css +20 -23
  94. package/core/server/api/endpoints/recommendations-public.js +42 -0
  95. package/core/server/api/endpoints/recommendations.js +2 -1
  96. package/core/server/api/endpoints/utils/serializers/output/members.js +22 -5
  97. package/core/server/data/exporter/table-lists.js +3 -1
  98. package/core/server/data/migrations/versions/5.63/2023-09-12-11-22-10-add-recommendation-click-events-table.js +8 -0
  99. package/core/server/data/migrations/versions/5.63/2023-09-12-11-22-11-add-recommendation-subscribe-events-table.js +8 -0
  100. package/core/server/data/migrations/versions/5.63/2023-09-13-13-03-10-add-ghost-core-content-integration.js +57 -0
  101. package/core/server/data/migrations/versions/5.63/2023-09-13-13-34-11-add-ghost-core-content-integration-key.js +87 -0
  102. package/core/server/data/schema/fixtures/fixtures.json +7 -0
  103. package/core/server/data/schema/schema.js +12 -0
  104. package/core/server/lib/lexical.js +20 -1
  105. package/core/server/models/base/plugins/crud.js +0 -6
  106. package/core/server/models/base/plugins/sanitize.js +1 -1
  107. package/core/server/models/post.js +1 -1
  108. package/core/server/models/recommendation-click-event.js +22 -0
  109. package/core/server/models/recommendation-subscribe-event.js +22 -0
  110. package/core/server/services/collections/BookshelfCollectionsRepository.js +67 -5
  111. package/core/server/services/collections/service.js +8 -8
  112. package/core/server/services/members/middleware.js +14 -1
  113. package/core/server/services/members/utils.js +1 -0
  114. package/core/server/services/recommendations/RecommendationServiceWrapper.js +23 -2
  115. package/core/server/services/settings/SettingsBREADService.js +5 -0
  116. package/core/server/web/members/app.js +14 -0
  117. package/core/shared/config/defaults.json +1 -1
  118. package/core/shared/settings-cache/public.js +2 -1
  119. package/package.json +159 -159
  120. package/yarn.lock +381 -369
  121. package/components/tryghost-adapter-cache-memory-ttl-5.62.0.tgz +0 -0
  122. package/components/tryghost-bookshelf-repository-5.62.0.tgz +0 -0
  123. package/components/tryghost-collections-5.62.0.tgz +0 -0
  124. package/components/tryghost-custom-theme-settings-service-5.62.0.tgz +0 -0
  125. package/components/tryghost-dynamic-routing-events-5.62.0.tgz +0 -0
  126. package/components/tryghost-email-analytics-provider-mailgun-5.62.0.tgz +0 -0
  127. package/components/tryghost-email-events-5.62.0.tgz +0 -0
  128. package/components/tryghost-email-suppression-list-5.62.0.tgz +0 -0
  129. package/components/tryghost-event-aware-cache-wrapper-5.62.0.tgz +0 -0
  130. package/components/tryghost-express-dynamic-redirects-5.62.0.tgz +0 -0
  131. package/components/tryghost-i18n-5.62.0.tgz +0 -0
  132. package/components/tryghost-importer-handler-content-files-5.62.0.tgz +0 -0
  133. package/components/tryghost-magic-link-5.62.0.tgz +0 -0
  134. package/components/tryghost-members-api-5.62.0.tgz +0 -0
  135. package/components/tryghost-members-ssr-5.62.0.tgz +0 -0
  136. package/components/tryghost-mentions-email-report-5.62.0.tgz +0 -0
  137. package/components/tryghost-milestones-5.62.0.tgz +0 -0
  138. package/components/tryghost-model-to-domain-event-interceptor-5.62.0.tgz +0 -0
  139. package/components/tryghost-mw-api-version-mismatch-5.62.0.tgz +0 -0
  140. package/components/tryghost-mw-cache-control-5.62.0.tgz +0 -0
  141. package/components/tryghost-mw-session-from-token-5.62.0.tgz +0 -0
  142. package/components/tryghost-mw-update-user-last-seen-5.62.0.tgz +0 -0
  143. package/components/tryghost-mw-version-match-5.62.0.tgz +0 -0
  144. package/components/tryghost-mw-vhost-5.62.0.tgz +0 -0
  145. package/components/tryghost-oembed-service-5.62.0.tgz +0 -0
  146. package/components/tryghost-post-events-5.62.0.tgz +0 -0
  147. package/components/tryghost-post-revisions-5.62.0.tgz +0 -0
  148. package/components/tryghost-posts-service-5.62.0.tgz +0 -0
  149. package/components/tryghost-recommendations-5.62.0.tgz +0 -0
  150. package/components/tryghost-referrers-5.62.0.tgz +0 -0
  151. package/components/tryghost-session-service-5.62.0.tgz +0 -0
  152. package/components/tryghost-settings-path-manager-5.62.0.tgz +0 -0
  153. package/components/tryghost-slack-notifications-5.62.0.tgz +0 -0
  154. package/components/tryghost-stats-service-5.62.0.tgz +0 -0
  155. package/components/tryghost-verification-trigger-5.62.0.tgz +0 -0
  156. package/core/built/admin/assets/ghost-dark-084169b0e968ef763dfbbf63b253e0c6.css +0 -1
  157. /package/core/built/admin/assets/{chunk.853.f743ed975e8838475532.js.LICENSE.txt → chunk.237.9b7032162949850f6c76.js.LICENSE.txt} +0 -0
@@ -7559,7 +7559,7 @@ e.LIST_SECTION_TYPE=3
7559
7559
  e.CARD_SECTION_TYPE=10})),
7560
7560
  /**
7561
7561
  reframe.js - Reframe.js: responsive iframes for embedded content
7562
- @version v4.0.1
7562
+ @version v4.0.2
7563
7563
  @link https://github.com/yowainwright/reframe.ts#readme
7564
7564
  @author Jeff Wainwright <yowainwright@gmail.com> (http://jeffry.in)
7565
7565
  @license MIT
@@ -13616,4 +13616,4 @@ e.default=class{constructor(e){if(this._data=new t.default,e)for(let t=0;t<e.len
13616
13616
  return this}get(e){let t=this._data[e]
13617
13617
  return t===r.UNDEFINED_KEY?void 0:t}set(e,t){return this._data[e]=t,this}delete(e){return this._data[e]=r.UNDEFINED_KEY,!0}}}))
13618
13618
 
13619
- //# sourceMappingURL=vendor-b50a3e5c2079b8a35d9122a1a4c34ef6.map
13619
+ //# sourceMappingURL=vendor-f8ce8bd43cf5dad6608f828ab48cee9b.map
@@ -8,7 +8,7 @@
8
8
  <title>Ghost Admin</title>
9
9
 
10
10
 
11
- <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.62%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
11
+ <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.63%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
12
12
 
13
13
  <meta name="HandheldFriendly" content="True" />
14
14
  <meta name="MobileOptimized" content="320" />
@@ -37,7 +37,7 @@
37
37
  </style>
38
38
 
39
39
  <link integrity="" rel="stylesheet" href="assets/vendor-3e6947aa681f0fb82b193090e520dc73.css">
40
- <link integrity="" rel="stylesheet" href="assets/ghost-8a4e981c272f793157133814ca7c7e84.css" title="light">
40
+ <link integrity="" rel="stylesheet" href="assets/ghost-33664cad4cd6664a8b5fa56e62c5005f.css" title="light">
41
41
 
42
42
 
43
43
  </head>
@@ -56,9 +56,9 @@
56
56
 
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
- <script src="assets/vendor-b50a3e5c2079b8a35d9122a1a4c34ef6.js"></script>
60
- <script src="assets/chunk.853.f743ed975e8838475532.js"></script>
61
- <script src="assets/chunk.143.5b5502a550ce35005d0f.js"></script>
62
- <script src="assets/ghost-d804aba7bca07fa75d308ab892c508fc.js"></script>
59
+ <script src="assets/vendor-f8ce8bd43cf5dad6608f828ab48cee9b.js"></script>
60
+ <script src="assets/chunk.237.9b7032162949850f6c76.js"></script>
61
+ <script src="assets/chunk.143.1c5d21facf1f9b9beef9.js"></script>
62
+ <script src="assets/ghost-7c3f2de2ec83e591ad9f9db5165b2733.js"></script>
63
63
  </body>
64
64
  </html>
@@ -31,6 +31,14 @@ module.exports = function foreach(items, options) {
31
31
  if (Object.values(items).length > 0 && checks.isPost(Object.values(items)[0])) {
32
32
  visibility = visibility || 'all';
33
33
  }
34
+ }
35
+
36
+ if (_.isArray(items) && items.length > 0 && checks.isNewsletter(items[0])) {
37
+ visibility = visibility || 'all';
38
+ } else if (_.isObject(items) && _.isArray(Object.values(items))) {
39
+ if (Object.values(items).length > 0 && checks.isNewsletter(Object.values(items)[0])) {
40
+ visibility = visibility || 'all';
41
+ }
34
42
  }
35
43
  // Exclude items which should not be visible in the theme
36
44
  items = ghostHelperUtils.visibility.filter(items, visibility);
@@ -33,6 +33,9 @@ const RESOURCES = {
33
33
  },
34
34
  tiers: {
35
35
  alias: 'tiersPublic'
36
+ },
37
+ newsletters: {
38
+ alias: 'newslettersPublic'
36
39
  }
37
40
  };
38
41
 
@@ -152,7 +152,7 @@ function getAuthorSchema(metaData, data) {
152
152
  sameAs: trimSameAs(data, 'author'),
153
153
  name: escapeExpression(data.author.name),
154
154
  url: metaData.authorUrl,
155
- image: schemaImageObject(metaData.coverImage),
155
+ image: schemaImageObject(metaData.authorImage) || schemaImageObject(metaData.coverImage),
156
156
  mainEntityOfPage: metaData.authorUrl,
157
157
  description: metaData.metaDescription ?
158
158
  escapeExpression(metaData.metaDescription) :
@@ -3,6 +3,11 @@ function isPost(jsonData) {
3
3
  Object.prototype.hasOwnProperty.call(jsonData, 'title') && Object.prototype.hasOwnProperty.call(jsonData, 'slug');
4
4
  }
5
5
 
6
+ function isNewsletter(jsonData) {
7
+ return Object.prototype.hasOwnProperty.call(jsonData, 'name') &&
8
+ Object.prototype.hasOwnProperty.call(jsonData, 'subscribe_on_signup') && Object.prototype.hasOwnProperty.call(jsonData, 'visibility');
9
+ }
10
+
6
11
  function isPage(jsonData = {}) {
7
12
  return Object.prototype.hasOwnProperty.call(jsonData, 'show_title_and_feature_image');
8
13
  }
@@ -24,6 +29,7 @@ function isNav(jsonData) {
24
29
 
25
30
  module.exports = {
26
31
  isPost,
32
+ isNewsletter,
27
33
  isPage,
28
34
  isTag,
29
35
  isUser,
@@ -0,0 +1,186 @@
1
+ .kg-collection-card {
2
+ width: 100%;
3
+ }
4
+
5
+ .kg-collection-card-title {
6
+ padding: .8rem 0 1.6rem 0;
7
+ font-size: 1.5rem;
8
+ text-transform: uppercase;
9
+ }
10
+
11
+ .kg-collection-card-post {
12
+ display: flex;
13
+ gap: 2rem;
14
+ }
15
+
16
+ .kg-collection-card-img {
17
+ position: relative;
18
+ aspect-ratio: 3/2;
19
+ }
20
+
21
+ .kg-collection-card-img img {
22
+ position: absolute;
23
+ inset: 0;
24
+ width: 100%;
25
+ height: 100%;
26
+ object-fit: cover;
27
+ }
28
+
29
+ .kg-collection-card-content {
30
+ display: flex;
31
+ flex-direction: column;
32
+ font-size: 1.45rem;
33
+ }
34
+
35
+ h2.kg-collection-card-post-title {
36
+ font-size: 1.9rem;
37
+ overflow: hidden;
38
+ display: -webkit-box;
39
+ -webkit-box-orient: vertical;
40
+ -webkit-line-clamp: 2;
41
+ }
42
+
43
+ p.kg-collection-card-post-excerpt {
44
+ margin-top: .8rem;
45
+ overflow: hidden;
46
+ display: -webkit-box;
47
+ -webkit-box-orient: vertical;
48
+ -webkit-line-clamp: 2;
49
+ line-height: 1.4;
50
+ }
51
+
52
+ .kg-collection-card-post-meta {
53
+ display: flex;
54
+ opacity: .5;
55
+ margin-top: .8rem;
56
+ }
57
+
58
+ /* List layout */
59
+
60
+ .kg-collection-card-list {
61
+ display: flex;
62
+ flex-direction: column;
63
+ gap: 2rem;
64
+ }
65
+
66
+ @media (max-width: 767px) {
67
+ .kg-collection-card-list .kg-collection-card-post {
68
+ flex-direction: column;
69
+ }
70
+ }
71
+
72
+ .kg-collection-card-list .kg-collection-card-img {
73
+ flex: 0 0 30%;
74
+ }
75
+
76
+ /* Grid layout */
77
+
78
+ .kg-collection-card-grid {
79
+ display: grid;
80
+ grid-template-columns: repeat(1,minmax(0,1fr));
81
+ gap: 2.4rem;
82
+ }
83
+
84
+ @media (min-width: 640px) {
85
+ .kg-collection-card-grid:not(.columns-1) {
86
+ grid-template-columns: repeat(2,minmax(0,1fr));
87
+ }
88
+ }
89
+
90
+ @media (min-width: 1024px) {
91
+ .kg-collection-card-grid:not(.columns-1):not(.columns-2) {
92
+ grid-template-columns: repeat(3,minmax(0,1fr));
93
+ gap: 3.2rem
94
+ }
95
+
96
+ .kg-collection-card-grid.columns-1 {
97
+ gap: 4.8rem
98
+ }
99
+
100
+ .kg-collection-card-grid.columns-2 {
101
+ gap: 4rem
102
+ }
103
+ }
104
+
105
+ @media (min-width: 1280px) {
106
+ .kg-collection-card-grid:not(.columns-1):not(.columns-2):not(.columns-3) {
107
+ grid-template-columns: repeat(4,minmax(0,1fr));
108
+ }
109
+ }
110
+
111
+ .kg-collection-card-grid .kg-collection-card-post {
112
+ flex-direction: column;
113
+ gap: 1.2rem;
114
+ }
115
+
116
+ @media (min-width: 1024px) {
117
+ .kg-collection-card-grid.columns-1 .kg-collection-card-post {
118
+ gap: 2rem
119
+ }
120
+
121
+ .kg-collection-card-grid.columns-2 .kg-collection-card-post {
122
+ gap: 1.6rem
123
+ }
124
+ }
125
+
126
+ .kg-collection-card-grid.columns-1 .kg-collection-card-img,
127
+ .kg-collection-card-grid.columns-2 .kg-collection-card-img {
128
+ aspect-ratio: 16/9;
129
+ }
130
+
131
+ .kg-collection-card-grid .kg-collection-card-content {
132
+ font-size: 1.5rem;
133
+ }
134
+
135
+ @media (min-width: 640px) {
136
+ .kg-collection-card-grid .kg-collection-card-content {
137
+ font-size: 1.6rem;
138
+ }
139
+ }
140
+
141
+ @media (min-width: 1024px) {
142
+ .kg-collection-card-grid.columns-1 .kg-collection-card-content {
143
+ font-size: 1.8rem;
144
+ }
145
+
146
+ .kg-collection-card-grid.columns-3 .kg-collection-card-content,
147
+ .kg-collection-card-grid.columns-4 .kg-collection-card-content {
148
+ font-size: 1.5rem;
149
+ }
150
+ }
151
+
152
+ .kg-collection-card-grid h2.kg-collection-card-post-title {
153
+ font-size: 1.7rem;
154
+ }
155
+
156
+ @media (min-width: 640px) {
157
+ .kg-collection-card-grid h2.kg-collection-card-post-title {
158
+ font-size: 1.9rem;
159
+ }
160
+
161
+ .kg-collection-card-grid.columns-1 h2.kg-collection-card-post-title {
162
+ font-size: 2.4rem;
163
+ }
164
+ }
165
+
166
+ /* @media (min-width: 768px) {
167
+ .kg-collection-card-grid.columns-1 h2.kg-collection-card-post-title {
168
+ font-size: 2.4rem;
169
+ }
170
+ } */
171
+
172
+ @media (min-width: 1024px) {
173
+ .kg-collection-card-grid.columns-1 h2.kg-collection-card-post-title {
174
+ font-size: 3.6rem;
175
+ }
176
+
177
+ .kg-collection-card-grid.columns-2 h2.kg-collection-card-post-title {
178
+ font-size: 2.4rem;
179
+ }
180
+ }
181
+
182
+ @media (min-width: 1280px) {
183
+ .kg-collection-card-grid.columns-4 h2.kg-collection-card-post-title {
184
+ font-size: 1.7rem;
185
+ }
186
+ }
@@ -71,7 +71,7 @@
71
71
  }
72
72
 
73
73
  .kg-header-card.kg-style-image h2.kg-header-card-heading,
74
- .kg-header-card.kg-style-image h3.kg-header-card-subheading,
74
+ .kg-header-card.kg-style-image .kg-header-card-subheading,
75
75
  .kg-header-card.kg-style-image.kg-v2 .kg-header-card-button {
76
76
  z-index: 999;
77
77
  }
@@ -112,26 +112,22 @@
112
112
 
113
113
  .kg-header-card h2.kg-header-card-heading {
114
114
  margin: 0;
115
- font-size: clamp(2.8rem, 4vw, 4rem);
115
+ font-size: clamp(2.4rem, 4vw, 3.6rem);
116
116
  font-weight: 700;
117
117
  line-height: 1em;
118
118
  letter-spacing: -0.01em;
119
119
  }
120
120
 
121
121
  .kg-header-card.kg-width-wide h2.kg-header-card-heading {
122
- font-size: clamp(2.8rem, 5vw, 5.2rem);
122
+ font-size: clamp(2.4rem, 5vw, 4.8rem);
123
123
  }
124
124
 
125
125
  .kg-header-card.kg-width-full h2.kg-header-card-heading {
126
- font-size: clamp(3.6rem, 5.6vw, 6.4rem);
126
+ font-size: clamp(2.8rem, 5.6vw, 6rem);
127
127
  }
128
128
 
129
129
  .kg-header-card.kg-width-full.kg-layout-split h2.kg-header-card-heading {
130
- font-size: clamp(3.2rem, 4vw, 5.6rem);
131
- }
132
-
133
- .kg-header-card.kg-width-full.kg-layout-split.kg-content-wide h2.kg-header-card-heading {
134
- font-size: clamp(2.8rem, 4vw, 5.2rem);
130
+ font-size: clamp(2.8rem, 4vw, 4.8rem);
135
131
  }
136
132
 
137
133
  /* Subheading */
@@ -140,33 +136,33 @@
140
136
  margin: 0 0 2em;
141
137
  }
142
138
 
143
- .kg-header-card h3.kg-header-card-subheading {
139
+ .kg-header-card .kg-header-card-subheading {
144
140
  max-width: 40em;
145
141
  margin: 0;
146
142
  font-size: clamp(1.05em, 2vw, 2rem);
147
143
  font-weight: 500;
148
- line-height: 1.4em;
144
+ line-height: 1.2em;
149
145
  }
150
146
 
151
- .kg-header-card h2 + h3.kg-header-card-subheading {
147
+ .kg-header-card h2 + .kg-header-card-subheading {
152
148
  margin: 0.6em 0 0;
153
149
  }
154
150
 
155
- .kg-header-card h3.kg-header-card-subheading strong {
151
+ .kg-header-card .kg-header-card-subheading strong {
156
152
  font-weight: 600;
157
153
  }
158
154
 
159
- .kg-header-card.kg-width-wide h3.kg-header-card-subheading {
160
- font-size: clamp(1.05em, 2vw, 2.4rem);
155
+ .kg-header-card.kg-width-wide .kg-header-card-subheading {
156
+ font-size: clamp(1.05em, 2vw, 2.2rem);
161
157
  }
162
158
 
163
- .kg-header-card.kg-width-full h3.kg-header-card-subheading:not(.kg-layout-split h3.kg-header-card-subheading) {
159
+ .kg-header-card.kg-width-full .kg-header-card-subheading:not(.kg-layout-split .kg-header-card-subheading) {
164
160
  max-width: min(65vmax, 1200px);
165
- font-size: clamp(1.05em, 2vw, 2.6rem);
161
+ font-size: clamp(1.05em, 2vw, 2.4rem);
166
162
  }
167
163
 
168
- .kg-header-card.kg-width-full.kg-layout-split h3.kg-header-card-subheading {
169
- font-size: clamp(1.05em, 2vw, 2.4rem);
164
+ .kg-header-card.kg-width-full.kg-layout-split .kg-header-card-subheading {
165
+ font-size: clamp(1.05em, 2vw, 2.2rem);
170
166
  }
171
167
 
172
168
  .kg-header-card.kg-v2 .kg-header-card-button {
@@ -194,7 +190,7 @@
194
190
  }
195
191
 
196
192
  .kg-header-card.kg-v2 h2 + .kg-header-card-button,
197
- .kg-header-card.kg-v2 h3 + .kg-header-card-button {
193
+ .kg-header-card.kg-v2 p + .kg-header-card-button {
198
194
  margin: 1.5em 0 0;
199
195
  }
200
196
 
@@ -207,7 +203,7 @@
207
203
  }
208
204
 
209
205
  .kg-header-card.kg-v2.kg-width-wide h2 + .kg-header-card-button,
210
- .kg-header-card.kg-v2.kg-width-wide h3 + .kg-header-card-button {
206
+ .kg-header-card.kg-v2.kg-width-wide p + .kg-header-card-button {
211
207
  margin-top: 1.75em;
212
208
  }
213
209
 
@@ -216,7 +212,7 @@
216
212
  }
217
213
 
218
214
  .kg-header-card.kg-v2.kg-width-full h2 + .kg-header-card-button,
219
- .kg-header-card.kg-v2.kg-width-full h3 + .kg-header-card-button {
215
+ .kg-header-card.kg-v2.kg-width-full p + .kg-header-card-button {
220
216
  margin-top: 2em;
221
217
  }
222
218
 
@@ -236,7 +232,7 @@
236
232
  padding: min(9.6vmax, 180px) 0;
237
233
  }
238
234
 
239
- .kg-header-card.kg-width-full h3.kg-header-card-subheading:not(.kg-layout-split h3.kg-header-card-subheading) {
235
+ .kg-header-card.kg-width-full .kg-header-card-subheading:not(.kg-layout-split .kg-header-card-subheading) {
240
236
  max-width: unset;
241
237
  }
242
238
 
@@ -64,7 +64,7 @@
64
64
  }
65
65
 
66
66
  .kg-signup-card.kg-style-image h2.kg-signup-card-heading,
67
- .kg-signup-card.kg-style-image h3.kg-signup-card-subheading,
67
+ .kg-signup-card.kg-style-image .kg-signup-card-subheading,
68
68
  .kg-signup-card.kg-style-image .kg-signup-card-button {
69
69
  z-index: 999;
70
70
  }
@@ -105,26 +105,22 @@
105
105
 
106
106
  .kg-signup-card h2.kg-signup-card-heading {
107
107
  margin: 0;
108
- font-size: clamp(2.8rem, 4vw, 4rem);
108
+ font-size: clamp(2.4rem, 4vw, 3.6rem);
109
109
  font-weight: 700;
110
110
  line-height: 1em;
111
111
  letter-spacing: -0.01em;
112
112
  }
113
113
 
114
114
  .kg-signup-card.kg-width-wide h2.kg-signup-card-heading {
115
- font-size: clamp(2.8rem, 5vw, 5.2rem);
115
+ font-size: clamp(2.4rem, 5vw, 4.8rem);
116
116
  }
117
117
 
118
118
  .kg-signup-card.kg-width-full h2.kg-signup-card-heading {
119
- font-size: clamp(3.6rem, 5.6vw, 6.4rem);
119
+ font-size: clamp(2.8rem, 5.6vw, 6rem);
120
120
  }
121
121
 
122
122
  .kg-signup-card.kg-width-full.kg-layout-split h2.kg-signup-card-heading {
123
- font-size: clamp(3.2rem, 4vw, 5.6rem);
124
- }
125
-
126
- .kg-signup-card.kg-width-full.kg-layout-split.kg-content-wide h2.kg-signup-card-heading {
127
- font-size: clamp(2.8rem, 4vw, 5.2rem);
123
+ font-size: clamp(2.8rem, 4vw, 4.8rem);
128
124
  }
129
125
 
130
126
  /* Subheading */
@@ -133,33 +129,33 @@
133
129
  margin: 0 0 2em;
134
130
  }
135
131
 
136
- .kg-signup-card h3.kg-signup-card-subheading {
132
+ .kg-signup-card .kg-signup-card-subheading {
137
133
  max-width: 40em;
138
134
  margin: 0;
139
135
  font-size: clamp(1.05em, 2vw, 2rem);
140
136
  font-weight: 500;
141
- line-height: 1.4em;
137
+ line-height: 1.2em;
142
138
  }
143
139
 
144
- .kg-signup-card h2 + h3.kg-signup-card-subheading {
140
+ .kg-signup-card h2 + .kg-signup-card-subheading {
145
141
  margin: 0.6em 0 0;
146
142
  }
147
143
 
148
- .kg-signup-card h3.kg-signup-card-subheading strong {
144
+ .kg-signup-card .kg-signup-card-subheading strong {
149
145
  font-weight: 600;
150
146
  }
151
147
 
152
- .kg-signup-card.kg-width-wide h3.kg-signup-card-subheading {
153
- font-size: clamp(1.05em, 2vw, 2.4rem);
148
+ .kg-signup-card.kg-width-wide .kg-signup-card-subheading {
149
+ font-size: clamp(1.05em, 2vw, 2.2rem);
154
150
  }
155
151
 
156
- .kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
152
+ .kg-signup-card.kg-width-full .kg-signup-card-subheading:not(.kg-layout-split .kg-signup-card-subheading) {
157
153
  max-width: min(65vmax, 1200px);
158
- font-size: clamp(1.05em, 2vw, 2.6rem);
154
+ font-size: clamp(1.05em, 2vw, 2.4rem);
159
155
  }
160
156
 
161
- .kg-signup-card.kg-width-full.kg-layout-split h3.kg-signup-card-subheading {
162
- font-size: clamp(1.05em, 2vw, 2.4rem);
157
+ .kg-signup-card.kg-width-full.kg-layout-split .kg-signup-card-subheading {
158
+ font-size: clamp(1.05em, 2vw, 2.2rem);
163
159
  }
164
160
 
165
161
  /* Subscribe form */
@@ -238,6 +234,7 @@
238
234
  text-overflow: ellipsis;
239
235
  border-radius: 3px;
240
236
  transition: opacity .2s ease;
237
+ cursor: pointer;
241
238
  }
242
239
 
243
240
  .kg-signup-card-button.kg-style-accent {
@@ -245,7 +242,7 @@
245
242
  }
246
243
 
247
244
  .kg-signup-card h2 + .kg-signup-card-button,
248
- .kg-signup-card h3 + .kg-signup-card-button {
245
+ .kg-signup-card p + .kg-signup-card-button {
249
246
  margin: 1.5em 0 0;
250
247
  }
251
248
 
@@ -258,7 +255,7 @@
258
255
  }
259
256
 
260
257
  .kg-signup-card.kg-width-wide h2 + .kg-signup-card-button,
261
- .kg-signup-card.kg-width-wide h3 + .kg-signup-card-button {
258
+ .kg-signup-card.kg-width-wide p + .kg-signup-card-button {
262
259
  margin-top: 1.75em;
263
260
  }
264
261
 
@@ -267,7 +264,7 @@
267
264
  }
268
265
 
269
266
  .kg-signup-card.kg-width-full h2 + .kg-signup-card-button,
270
- .kg-signup-card.kg-width-full h3 + .kg-signup-card-button {
267
+ .kg-signup-card.kg-width-full p + .kg-signup-card-button {
271
268
  margin-top: 2em;
272
269
  }
273
270
 
@@ -347,7 +344,7 @@
347
344
  padding: min(9.6vmax, 180px) 0;
348
345
  }
349
346
 
350
- .kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
347
+ .kg-signup-card.kg-width-full .kg-signup-card-subheading:not(.kg-layout-split .kg-signup-card-subheading) {
351
348
  max-width: unset;
352
349
  }
353
350
 
@@ -17,5 +17,47 @@ module.exports = {
17
17
  async query(frame) {
18
18
  return await recommendations.controller.listRecommendations(frame);
19
19
  }
20
+ },
21
+
22
+ trackClicked: {
23
+ headers: {
24
+ cacheInvalidate: false
25
+ },
26
+ options: [
27
+ 'id'
28
+ ],
29
+ validation: {
30
+ options: {
31
+ id: {
32
+ required: true
33
+ }
34
+ }
35
+ },
36
+ permissions: true,
37
+ statusCode: 204,
38
+ async query(frame) {
39
+ await recommendations.controller.trackClicked(frame);
40
+ }
41
+ },
42
+
43
+ trackSubscribed: {
44
+ headers: {
45
+ cacheInvalidate: false
46
+ },
47
+ options: [
48
+ 'id'
49
+ ],
50
+ validation: {
51
+ options: {
52
+ id: {
53
+ required: true
54
+ }
55
+ }
56
+ },
57
+ permissions: true,
58
+ statusCode: 204,
59
+ async query(frame) {
60
+ await recommendations.controller.trackSubscribed(frame);
61
+ }
20
62
  }
21
63
  };
@@ -9,7 +9,8 @@ module.exports = {
9
9
  },
10
10
  options: [
11
11
  'limit',
12
- 'page'
12
+ 'page',
13
+ 'include'
13
14
  ],
14
15
  permissions: true,
15
16
  validation: {},
@@ -1,4 +1,5 @@
1
1
  //@ts-check
2
+ const _ = require('lodash');
2
3
  const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:output:members');
3
4
  const {unparse} = require('@tryghost/members-csv');
4
5
  const mappers = require('./mappers');
@@ -113,6 +114,26 @@ function serializeAttribution(attribution) {
113
114
  };
114
115
  }
115
116
 
117
+ function serializeNewsletter(newsletter) {
118
+ const newsletterFields = [
119
+ 'id',
120
+ 'name',
121
+ 'description',
122
+ 'status'
123
+ ];
124
+
125
+ return _.pick(newsletter, newsletterFields);
126
+ }
127
+
128
+ function serializeNewsletters(newsletters) {
129
+ return newsletters
130
+ .filter(newsletter => newsletter.status === 'active')
131
+ .sort((a, b) => {
132
+ return a.sort_order - b.sort_order;
133
+ })
134
+ .map(newsletter => serializeNewsletter(newsletter));
135
+ }
136
+
116
137
  /**
117
138
  * @param {import('bookshelf').Model} member
118
139
  * @param {object} options
@@ -174,11 +195,7 @@ function serializeMember(member, options) {
174
195
  serialized.email_suppression = json.email_suppression;
175
196
 
176
197
  if (json.newsletters) {
177
- serialized.newsletters = json.newsletters
178
- .filter(newsletter => newsletter.status === 'active')
179
- .sort((a, b) => {
180
- return a.sort_order - b.sort_order;
181
- });
198
+ serialized.newsletters = serializeNewsletters(json.newsletters);
182
199
  }
183
200
  // override the `subscribed` param to mean "subscribed to any active newsletter"
184
201
  serialized.subscribed = false;
@@ -51,7 +51,9 @@ const BACKUP_TABLES = [
51
51
  'milestones',
52
52
  'collections',
53
53
  'collections_posts',
54
- 'recommendations'
54
+ 'recommendations',
55
+ 'recommendation_click_events',
56
+ 'recommendation_subscribe_events'
55
57
  ];
56
58
 
57
59
  // NOTE: exposing only tables which are going to be included in a "default" export file
@@ -0,0 +1,8 @@
1
+ const {addTable} = require('../../utils');
2
+
3
+ module.exports = addTable('recommendation_click_events', {
4
+ id: {type: 'string', maxlength: 24, nullable: false, primary: true},
5
+ recommendation_id: {type: 'string', maxlength: 24, nullable: false, references: 'recommendations.id', unique: false, cascadeDelete: true},
6
+ member_id: {type: 'string', maxlength: 24, nullable: true, references: 'members.id', unique: false, setNullDelete: true},
7
+ created_at: {type: 'dateTime', nullable: false}
8
+ });
@@ -0,0 +1,8 @@
1
+ const {addTable} = require('../../utils');
2
+
3
+ module.exports = addTable('recommendation_subscribe_events', {
4
+ id: {type: 'string', maxlength: 24, nullable: false, primary: true},
5
+ recommendation_id: {type: 'string', maxlength: 24, nullable: false, references: 'recommendations.id', unique: false, cascadeDelete: true},
6
+ member_id: {type: 'string', maxlength: 24, nullable: true, references: 'members.id', unique: false, setNullDelete: true},
7
+ created_at: {type: 'dateTime', nullable: false}
8
+ });