diff --git a/packages/marko-web-theme-monorail/.eslintignore b/packages/marko-web-theme-monorail/.eslintignore new file mode 100644 index 000000000..c7a811092 --- /dev/null +++ b/packages/marko-web-theme-monorail/.eslintignore @@ -0,0 +1 @@ +*.marko.js diff --git a/packages/marko-web-theme-monorail/.eslintrc.js b/packages/marko-web-theme-monorail/.eslintrc.js new file mode 100644 index 000000000..2415c8b75 --- /dev/null +++ b/packages/marko-web-theme-monorail/.eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.marko'], + }, + }, + }, +}; diff --git a/packages/marko-web-theme-monorail/browser/.eslintrc.js b/packages/marko-web-theme-monorail/browser/.eslintrc.js new file mode 100644 index 000000000..2eb0b8d9c --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/.eslintrc.js @@ -0,0 +1,21 @@ +module.exports = { + extends: [ + 'airbnb-base', + 'plugin:vue/recommended', + ], + env: { + browser: true, + }, + rules: { + 'vue/max-attributes-per-line': ['error', { + singleline: 3, + multiline: { + max: 1, + allowFirstLine: false, + }, + }], + }, + parserOptions: { + parser: 'babel-eslint', + }, +}; diff --git a/packages/marko-web-theme-monorail/browser/block-loader.vue b/packages/marko-web-theme-monorail/browser/block-loader.vue new file mode 100644 index 000000000..a610c7c74 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/block-loader.vue @@ -0,0 +1,64 @@ + + + + Loading {{ label }}... + + + + + Unable to load {{ label }} block. + {{ error.message }} + + + + + diff --git a/packages/marko-web-theme-monorail/browser/comment-toggle-button.vue b/packages/marko-web-theme-monorail/browser/comment-toggle-button.vue new file mode 100644 index 000000000..6d31f1aa8 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/comment-toggle-button.vue @@ -0,0 +1,89 @@ + + + {{ translate("viewAllComments") }} + + + + diff --git a/packages/marko-web-theme-monorail/browser/i18n-vue.js b/packages/marko-web-theme-monorail/browser/i18n-vue.js new file mode 100644 index 000000000..db06f7640 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/i18n-vue.js @@ -0,0 +1,11 @@ +import translations from './translations-vue'; + +export default (lang, fieldLabelKey) => { + if (!translations[lang]) { + throw new Error(`No translations available for requested language ${lang}!`); + } + if (!translations[lang][fieldLabelKey]) { + throw new Error(`No translations available in ${lang} for requested key ${fieldLabelKey}!`); + } + return translations[lang][fieldLabelKey]; +}; diff --git a/packages/marko-web-theme-monorail/browser/index.js b/packages/marko-web-theme-monorail/browser/index.js new file mode 100644 index 000000000..779b7b26c --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/index.js @@ -0,0 +1,114 @@ +import GTM from '@parameter1/base-cms-marko-web-gtm/browser'; +import GAM from '@parameter1/base-cms-marko-web-gam/browser'; +import Search from '@parameter1/base-cms-marko-web-search/browser'; +import SocialSharing from '@parameter1/base-cms-marko-web-social-sharing/browser'; +import Inquiry from '@parameter1/base-cms-marko-web-inquiry/browser'; +import NativeX from '@parameter1/base-cms-marko-web-native-x/browser'; +import IdentityX from '@parameter1/base-cms-marko-web-identity-x/browser'; +import OmedaIdentityX from '@parameter1/base-cms-marko-web-omeda-identity-x/browser'; + +const CommentToggleButton = () => import(/* webpackChunkName: "theme-comment-toggle-button" */ './comment-toggle-button.vue'); +const BlockLoader = () => import(/* webpackChunkName: "theme-block-loader" */ './block-loader.vue'); +const InlineNewsletterForm = () => import(/* webpackChunkName: "theme-inline-newsletter-form" */ './inline-newsletter-form.vue'); +const MenuToggleButton = () => import(/* webpackChunkName: "theme-menu-toggle-button" */ './menu-toggle-button.vue'); +const NewsletterCloseButton = () => import(/* webpackChunkName: "theme-newsletter-close-button" */ './newsletter-close-button.vue'); +const NewsletterToggleButton = () => import(/* webpackChunkName: "theme-newsletter-toggle-button" */ './newsletter-toggle-button.vue'); + +const SiteNewsletterMenu = () => import(/* webpackChunkName: "theme-site-newsletter-menu" */ './site-newsletter-menu.vue'); +const WufooForm = () => import(/* webpackChunkName: "theme-wufoo-form" */ './wufoo-form.vue'); +const TopStoriesMenu = () => import(/* webpackChunkName: "theme-top-stories-menu" */ './top-stories-menu.vue'); + +const setP1EventsIdentity = ({ p1events, brandKey, encryptedId }) => { + if (!p1events || !brandKey || !encryptedId) return; + p1events('setIdentity', `omeda.${brandKey}.customer*${encryptedId}~encrypted`); +}; + +export default (Browser, config = { + enableOmedaIdentityX: true, + withGTM: true, + withP1Events: true, +}) => { + const { EventBus } = Browser; + const { enableOmedaIdentityX } = config; + + if (enableOmedaIdentityX) { + EventBus.$on('omeda-identity-x-authenticated', ({ brandKey, encryptedId }) => { + setP1EventsIdentity({ p1events: window.p1events, brandKey, encryptedId }); + }); + EventBus.$on('omeda-identity-x-rapid-identify-response', ({ brandKey, encryptedId }) => { + setP1EventsIdentity({ p1events: window.p1events, brandKey, encryptedId }); + }); + } + + Browser.register('ThemeCommentToggleButton', CommentToggleButton); + + EventBus.$on('identity-x-logout', () => { + if (window.p1events) window.p1events('setIdentity', null); + }); + const emitNewsletterEvent = ({ type, action, data }) => { + let label = `Step ${data.step}`; + if (action === 'Error') label = `${label} Error: ${data.error}`; + EventBus.$emit('newsletter-form-action', { + category: `Newsletter Signup Form (${type})`, + action, + label, + }); + }; + + const emitNewsletterSubscription = ({ type, newsletter }) => { + EventBus.$emit('newsletter-form-subscription', { + category: newsletter.eventCategory || newsletter.name, + action: type, + }); + }; + + GTM(Browser); + GAM(Browser); + Search(Browser); + SocialSharing(Browser); + NativeX(Browser); + if (enableOmedaIdentityX) { + OmedaIdentityX(Browser); + } else { + IdentityX(Browser); + } + Inquiry(Browser); + + Browser.register('ThemeBlockLoader', BlockLoader); + + Browser.register('ThemeSiteNewsletterMenu', SiteNewsletterMenu, { + provide: { EventBus }, + on: { + load: (data) => { + emitNewsletterEvent({ type: 'Pushdown', action: 'Load', data }); + emitNewsletterEvent({ type: 'Pushdown', action: 'View', data }); + }, + focus: data => emitNewsletterEvent({ type: 'Pushdown', action: 'Focus', data }), + submit: data => emitNewsletterEvent({ type: 'Pushdown', action: 'Submit', data }), + subscribe: ({ newsletter }) => emitNewsletterSubscription({ type: 'Pushdown', newsletter }), + error: data => emitNewsletterEvent({ type: 'Pushdown', action: 'Error', data: { ...data, error: data.error.message } }), + }, + }); + Browser.register('ThemeInlineNewsletterForm', InlineNewsletterForm, { + on: { + load: data => emitNewsletterEvent({ type: 'Inline', action: 'Load', data }), + view: data => emitNewsletterEvent({ type: 'Inline', action: 'View', data }), + focus: data => emitNewsletterEvent({ type: 'Inline', action: 'Focus', data }), + submit: (data) => { + emitNewsletterEvent({ type: 'Inline', action: 'Submit', data }); + if (window.olytics) window.olytics.confirm(data.encryptedCustomerId); + }, + subscribe: ({ newsletter }) => emitNewsletterSubscription({ type: 'Pushdown', newsletter }), + error: data => emitNewsletterEvent({ type: 'Inline', action: 'Error', data: { ...data, error: data.error.message } }), + }, + }); + + Browser.register('ThemeMenuToggleButton', MenuToggleButton); + Browser.register('ThemeNewsletterCloseButton', NewsletterCloseButton); + + Browser.register('ThemeNewsletterToggleButton', NewsletterToggleButton, { + provide: { EventBus }, + }); + Browser.register('ThemeTopStoriesMenu', TopStoriesMenu); + Browser.register('WufooForm', WufooForm); +}; diff --git a/packages/marko-web-theme-monorail/browser/inline-newsletter-form.vue b/packages/marko-web-theme-monorail/browser/inline-newsletter-form.vue new file mode 100644 index 000000000..fa4d551f6 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/inline-newsletter-form.vue @@ -0,0 +1,129 @@ + + + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/inline-newsletter-form/step1.vue b/packages/marko-web-theme-monorail/browser/inline-newsletter-form/step1.vue new file mode 100644 index 000000000..0cb41b29c --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/inline-newsletter-form/step1.vue @@ -0,0 +1,139 @@ + + + + + + + + {{ name }} + + + + + + + Email + + + + + + + + + An error ocurred. + {{ error.message }} + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/menu-toggle-button.vue b/packages/marko-web-theme-monorail/browser/menu-toggle-button.vue new file mode 100644 index 000000000..693c774c0 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/menu-toggle-button.vue @@ -0,0 +1,143 @@ + + + + {{ calcBefore }} + + + + {{ calcAfter }} + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-close-button.vue b/packages/marko-web-theme-monorail/browser/newsletter-close-button.vue new file mode 100644 index 000000000..4fa6f020f --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-close-button.vue @@ -0,0 +1,44 @@ + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/check-icon.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/check-icon.vue new file mode 100644 index 000000000..61a9fa58d --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/check-icon.vue @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/form-group.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/form-group.vue new file mode 100644 index 000000000..c31bbb85f --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/form-group.vue @@ -0,0 +1,50 @@ + + + + {{ displayLabel }} + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/get-recaptcha-token.js b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/get-recaptcha-token.js new file mode 100644 index 000000000..05f1a74cc --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/get-recaptcha-token.js @@ -0,0 +1,3 @@ +export default siteKey => window.grecaptcha.execute(siteKey, { + action: 'newsletterSignup', +}); diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/input-form-group.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/input-form-group.vue new file mode 100644 index 000000000..441475d11 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/input-form-group.vue @@ -0,0 +1,57 @@ + + + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/newsletter-checkbox.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/newsletter-checkbox.vue new file mode 100644 index 000000000..c58c11f7d --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/newsletter-checkbox.vue @@ -0,0 +1,63 @@ + + + + + + {{ name }} + + + {{ description }} + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/privacy-policy.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/privacy-policy.vue new file mode 100644 index 000000000..c839370d5 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/privacy-policy.vue @@ -0,0 +1,38 @@ + + + {{ translate("emailProviding") }} + + {{ privacyPolicyLink.label }}. + {{ translate("protectedBy") }} + {{ translate("privacyPolicy") }} + {{ translate("and") }} + {{ translate("termsOfService") }} + {{ translate("apply") }} + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/select-form-group.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/select-form-group.vue new file mode 100644 index 000000000..0143a8997 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/select-form-group.vue @@ -0,0 +1,59 @@ + + + + + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/sign-up-button.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/sign-up-button.vue new file mode 100644 index 000000000..3165472e7 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/sign-up-button.vue @@ -0,0 +1,50 @@ + + + + + Loading... + + {{ label }} + {{ translate("signUp") }} + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-signup-form/step2.vue b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/step2.vue new file mode 100644 index 000000000..d9671ddc3 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-signup-form/step2.vue @@ -0,0 +1,279 @@ + + + + + {{ translate("signedUpFor") }} {{ defaultNewsletter.name }} + + + + + + {{ translate("completeSignUp") }} + + + {{ translate("aboutYou") }} + + + + + + + {{ translate("select") }} + + + {{ value.label }} + + + + + + + + + {{ translate("chooseSubscriptions") }} + + + + + + + + + + + + + + + + + + + + + + {{ translate("thankYou") }} + + + {{ translate("startReceiving") }} {{ siteName }}. + + + + + + An error ocurred. + {{ error.message }} + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/newsletter-toggle-button.vue b/packages/marko-web-theme-monorail/browser/newsletter-toggle-button.vue new file mode 100644 index 000000000..d4e5060fc --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/newsletter-toggle-button.vue @@ -0,0 +1,31 @@ + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/site-newsletter-menu.vue b/packages/marko-web-theme-monorail/browser/site-newsletter-menu.vue new file mode 100644 index 000000000..d4a9fede3 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/site-newsletter-menu.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/packages/marko-web-theme-monorail/browser/site-newsletter-menu/step1.vue b/packages/marko-web-theme-monorail/browser/site-newsletter-menu/step1.vue new file mode 100644 index 000000000..aee2182e8 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/site-newsletter-menu/step1.vue @@ -0,0 +1,162 @@ + + + + + + + + {{ name }} + + + + + + Email + + + + + + + An error ocurred. + {{ error.message }} + + + + + + + + + diff --git a/packages/marko-web-theme-monorail/browser/ssr.js b/packages/marko-web-theme-monorail/browser/ssr.js new file mode 100644 index 000000000..378d3147f --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/ssr.js @@ -0,0 +1,9 @@ +import ThemeMenuToggleButton from './menu-toggle-button.vue'; +import ThemeNewsletterToggleButton from './newsletter-toggle-button.vue'; +import ThemeSiteNewsletterMenu from './site-newsletter-menu.vue'; + +export default { + ThemeMenuToggleButton, + ThemeNewsletterToggleButton, + ThemeSiteNewsletterMenu, +}; diff --git a/packages/marko-web-theme-monorail/browser/top-stories-menu.vue b/packages/marko-web-theme-monorail/browser/top-stories-menu.vue new file mode 100644 index 000000000..d1b6ea607 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/top-stories-menu.vue @@ -0,0 +1,58 @@ + + + + Loading top stories... + + + + + {{ error.message }} + + + + + diff --git a/packages/marko-web-theme-monorail/browser/translations-vue.js b/packages/marko-web-theme-monorail/browser/translations-vue.js new file mode 100644 index 000000000..6063cd936 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/translations-vue.js @@ -0,0 +1,46 @@ +export default { + en: { + visitSiteLabel: 'Visit Site', + // Email Signup Privacy Policy + emailProviding: 'By providing your email, you agree to our', + protectedBy: 'This site is protected by reCAPTCHA and the Google', + privacyPolicy: 'Privacy Policy', + and: 'and', + termsOfService: 'Terms of Service', + apply: 'apply.', + signUp: 'Sign Up', + // Email Signup step 2: + signedUpFor: 'Signed up for the', + completeSignUp: 'Complete your sign-up', + aboutYou: 'About you', + companyName: 'Company Name', + select: 'Select', + chooseSubscriptions: 'Choose your subscriptions', + thankYou: 'Thank you for subscribing!', + startReceiving: 'You should start receiving your subscription in the next 24 hours along with a special welcome from the experts at', + // Comments + viewAllComments: 'View All Comments', + }, + es: { + visitSiteLabel: 'Visite el sitio', + // Email Signup Privacy Policy + emailProviding: 'By providing your email, you agree to our', + protectedBy: 'This site is protected by reCAPTCHA y the Google', + privacyPolicy: 'Privacy Policy', + and: 'y', + termsOfService: 'Terms of Service', + apply: 'apply.', + signUp: '¡Sign Up!', + // Email Signup step 2: + signedUpFor: 'Signed up for the', + completeSignUp: 'Complete your sign-up', + aboutYou: 'About you', + companyName: 'Company Name', + select: 'Select', + chooseSubscriptions: 'Choose your subscriptions', + thankYou: 'Thank you for subscribing!', + startReceiving: 'You should start receiving your subscription in the next 24 hours along with a special welcome from the experts at', + // Comments + viewAllComments: 'View All Comments', + }, +}; diff --git a/packages/marko-web-theme-monorail/browser/wufoo-form.vue b/packages/marko-web-theme-monorail/browser/wufoo-form.vue new file mode 100644 index 000000000..d57f13566 --- /dev/null +++ b/packages/marko-web-theme-monorail/browser/wufoo-form.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/callout-cards.marko b/packages/marko-web-theme-monorail/components/blocks/callout-cards.marko new file mode 100644 index 000000000..efe1ca5ab --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/callout-cards.marko @@ -0,0 +1,15 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; + +$ const blockName = "callout-cards"; +$ const slots = getAsArray(input, "slots"); + + + + + <${slots[0].renderBody} /> + + + <${slots[1].renderBody} /> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/full-width-native-ad.marko b/packages/marko-web-theme-monorail/components/blocks/full-width-native-ad.marko new file mode 100644 index 000000000..75c7c27de --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/full-width-native-ad.marko @@ -0,0 +1,21 @@ +import { get } from "@parameter1/base-cms-object-path"; + +$ const blockName = "full-width-native-ad"; + + + + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/hero-card.marko b/packages/marko-web-theme-monorail/components/blocks/hero-card.marko new file mode 100644 index 000000000..7f065de8e --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/hero-card.marko @@ -0,0 +1,91 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/content-list"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + + +$ const queryParams = { + ... input.queryParams, + sectionAlias: input.alias, + limit: 3, + queryFragment, + sectionFragment, +}; + +$ const name = defaultValue(input.name, ""); +$ const description = defaultValue(input.description, ""); +$ const blockName = "hero-card"; + + + + + ${section && section.name || name} + + + + $!{section && section.description || description} + + + + + ${i18n("View more")} » + + + + + + + + <@slot|{ node }|> + + <@image fluid=true width=790 ar="16:9" /> + + @slot> + + + + + <@slot|{ node }|> + + <@image fluid=true width=240 ar="16:9" /> + + @slot> + + + + + + + ${i18n("View more")} » + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/latest-podcast.marko b/packages/marko-web-theme-monorail/components/blocks/latest-podcast.marko new file mode 100644 index 000000000..d0dff4dca --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/latest-podcast.marko @@ -0,0 +1,64 @@ +import queryFragment from "../../graphql/fragments/latest-podcast-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const queryParams = { + sectionAlias: input.alias, + includeContentTypes: ["Podcast"], + limit: 1, + queryFragment, + sectionFragment, +}; + +$ const { site, i18n } = out.global; +$ const podcastLinks = site.getAsArray("podcastLinks"); +$ const blockName = "latest-podcast"; + + + $ const [node] = nodes; + + + + ${section.name} + + + + <@body> + <@header> + <@left> + ${i18n("Latest Episode")} + @left> + @header> + <@title tag="h5"> + + @title> + <@text modifiers=["more-episodes"]> + + ${i18n("More episodes")} » + + @text> + + <@footer> + <@left modifiers=["buttons"]> + + + ${link.label} + + + @left> + @footer> + + @body> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/latest-products-feed.marko b/packages/marko-web-theme-monorail/components/blocks/latest-products-feed.marko new file mode 100644 index 000000000..ecd02877b --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/latest-products-feed.marko @@ -0,0 +1,57 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/latest-products-feed-block"; + +$ const queryParams = { + ...input.queryParams, + sectionAlias: input.alias, + queryFragment, +}; + +$ const blockName = "latest-products-feed"; +$ const countOnly = defaultValue(input.countOnly, false); + + + + <${input.renderBody} ...data /> + + + + + + <@nodes nodes=nodes> + <@slot|{ node }|> + + @slot> + <@slot position="after" index=2 modifiers=["ad"]> + + @slot> + <@slot position="after" index=5 modifiers=["ad"]> + + @slot> + <@slot position="after" index=8 modifiers=["ad"]> + + @slot> + @nodes> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/marko.json b/packages/marko-web-theme-monorail/components/blocks/marko.json new file mode 100644 index 000000000..e21fad9f8 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/marko.json @@ -0,0 +1,111 @@ +{ + "taglib-imports": [], + "": { + "template": "./callout-cards.marko", + "@slots []": {} + }, + "": { + "template": "./full-width-native-ad.marko" + }, + "": { + "template": "./hero-card.marko", + "@alias": "string", + "@description": "string", + "@name": "string", + "@query-params": "object" + }, + "": { + "template": "./latest-podcast.marko" + }, + "": { + "template": "./latest-products-feed.marko", + "": {}, + "@alias": "string", + "@count-only": "boolean" + }, + "": { + "template": "./more-products.marko" + }, + "": { + "template": "./most-popular.marko" + }, + "": { + "template": "./native-x-card-deck.marko" + }, + "": { + "template": "./newsletter-signup-banner.marko" + }, + "": { + "template": "./newsletter-signup-banner-large.marko" + }, + "": { + "template": "./opinion.marko", + "@alias" : "string" + }, + "": { + "template": "./primary-image.marko" + }, + "": { + "template": "./products.marko" + }, + "": { + "template": "./read-next.marko" + }, + "": { + "template": "./related-stories.marko" + }, + "": { + "template": "./resource-library.marko" + }, + "": { + "template": "./section-body-feed.marko", + "": {}, + "": {}, + "@alias": "string", + "@count-only": "boolean" + }, + "": { + "template": "./section-card-deck.marko", + "@alias" : "string", + "@default-description": "string" + }, + "": { + "template": "./section-card-deck-featured.marko" + }, + "": { + "template": "./section-card-list.marko" + }, + "": { + "template": "./section-feed.marko", + "": {}, + "": {}, + "@alias": "string", + "@count-only": "boolean", + "@display-image": "boolean", + "@with-section": "boolean", + "@lazyload": "boolean", + "@modifiers": "array", + "@query-name": "string" + }, + "": { + "template": "./section-list-deck.marko" + }, + "": { + "template": "./section-list.marko" + }, + "": { + "template": "./section-title-feed.marko", + "": {}, + "@alias": "string", + "@count-only": "boolean" + }, + "": { + "template": "./top-stories.marko" + }, + "": { + "template": "./top-stories-menu.marko" + }, + "": { + "template": "./white-papers.marko" + } +} diff --git a/packages/marko-web-theme-monorail/components/blocks/more-products.marko b/packages/marko-web-theme-monorail/components/blocks/more-products.marko new file mode 100644 index 000000000..1620c0a37 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/more-products.marko @@ -0,0 +1,49 @@ +import queryFragment from "../../graphql/fragments/products-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + +$ const queryParams = { + requiresImage: true, + ...input.params, + sectionAlias: input.alias, + limit: 6, + queryFragment, + sectionFragment, +}; + +$ const blockName = "more-products"; + + + + + + ${i18n("More")} ${section.name} + + + + ${i18n("View more")} » + + + + + <@slot|{ node }|> + + <@image width=112 ar="1:1" /> + + @slot> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/most-popular.marko b/packages/marko-web-theme-monorail/components/blocks/most-popular.marko new file mode 100644 index 000000000..05fd2e582 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/most-popular.marko @@ -0,0 +1,89 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; +import gql from "graphql-tag"; +import fetch from "node-fetch"; +import { extractFragmentData } from "@parameter1/base-cms-web-common/utils"; +import queryFragment from "../../graphql/fragments/most-popular-block"; + +$ const { MOST_POPULAR_API_URI } = process.env; +$ const { site, config, apollo, i18n } = out.global; + +$ const blockName = "most-popular"; + +$ const getMostPopular = async () => { + const uri = MOST_POPULAR_API_URI || 'https://most-popular-content.base.parameter1.com'; + const tenant = site.get("p1events.tenant"); + const realm = config.website("id"); + + const url = `${uri}/retrieve?tenant=${tenant}&realm=${realm}`; + const res = await fetch(url); + const json = await res.json(); + if (!res.ok) { + const e = json.message || res.statusText; + throw new Error(e || "An unknown fatal error occurred."); + } + return json.data; +}; + +$ const buildContentQuery = () => { + const { spreadFragmentName, processedFragment } = extractFragmentData(queryFragment); + return gql` + query WebsiteMostPopularBlock( + $ids: [Int!]! + $limit: Int! + ) { + allContent(input: { + ids: $ids, + status: any, + pagination: { limit: $limit } + }) { + edges { + node { + ${spreadFragmentName} + } + } + } + } + + ${processedFragment} + `; +}; + + + $ const ids = resolved.map(({ id }) => id); + + $ const query = buildContentQuery(); + $ const variables = { ids, limit: 6 }; + + $ const nodes = getAsArray(response, "data.allContent.edges").map((edge) => edge.node); + $ const map = nodes.reduce((m, r) => m.set(`${r.id}`, r), new Map()); + $ const ordered = ids.map(id => map.get(`${id}`)).filter(id => id); + + + + ${i18n("Most Popular")} + + + <@slot|{ node, index }|> + + + ${index + 1} + + + + @slot> + + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/native-x-card-deck.marko b/packages/marko-web-theme-monorail/components/blocks/native-x-card-deck.marko new file mode 100644 index 000000000..d24844e4e --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/native-x-card-deck.marko @@ -0,0 +1,55 @@ +import { defaultValue } from "@parameter1/base-cms-marko-web/utils"; +import convertAdToContent from "@parameter1/base-cms-marko-web-native-x/utils/convert-ad-to-content"; + +$ const { nativeX: nxConfig, i18n } = out.global; +$ const { section } = input; +$ const limit = defaultValue(input.limit, 3); +$ const placementName = defaultValue(input.placementName, "default"); +$ const aliases = defaultValue(input.aliases, []); + +$ const blockName = "section-card-deck"; +$ const uri = nxConfig.getUri(); +$ const placement = nxConfig.getPlacement({ name: placementName, aliases }); + + + $ const hasAd = ads && ads.length && ads[0] && ads[0].hasCampaign; + + + + ${section.name} + + + + $!{section.description || input.defaultDescription} + + + + + + + + + $ const node = convertAdToContent(ad, { sectionName: `${i18n("Sponsored by")} ${ad.campaign.advertiserName}` }); + + + <@image fluid=true width=330 ar="4:3" /> + + + + + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/newsletter-signup-banner-large.marko b/packages/marko-web-theme-monorail/components/blocks/newsletter-signup-banner-large.marko new file mode 100644 index 000000000..382bfc686 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/newsletter-signup-banner-large.marko @@ -0,0 +1,36 @@ +$ const blockName = "newsletter-signup-banner-large"; + +$ const { site } = out.global; +$ const { + action, + hiddenInputs, + name, + description, + disabled +} = site.getAsObject('newsletter.signupBannerLarge'); + + + + + ${name} + + + $!{description} + + + Email + + + + + Sign Up + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/newsletter-signup-banner.marko b/packages/marko-web-theme-monorail/components/blocks/newsletter-signup-banner.marko new file mode 100644 index 000000000..8c227fc5c --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/newsletter-signup-banner.marko @@ -0,0 +1,39 @@ +import { buildImgixUrl } from "@parameter1/base-cms-image"; + +$ const blockName = "newsletter-signup-banner"; + +$ const { config, site, recaptcha } = out.global; +$ const { + name, + description, + imagePath, + defaultNewsletter, + newsletters, + demographic, + disabled, + privacyPolicy, +} = site.getAsObject("newsletter.signupBanner"); + +$ const lang = site.config.lang || "en"; +$ const imageSrc = imagePath ? buildImgixUrl(`https://${config.website("imageHost")}/${imagePath}`, { w: 120, auto: "format,compress" }) : null; +$ const imageSrcset = imageSrc ? `${imageSrc}&dpr=2 2x` : null; + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/opinion.marko b/packages/marko-web-theme-monorail/components/blocks/opinion.marko new file mode 100644 index 000000000..ecb930a0b --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/opinion.marko @@ -0,0 +1,34 @@ +import queryFragment from "../../graphql/fragments/opinion-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + + +$ const queryParams = { + sectionAlias: input.alias, + limit: 3, + queryFragment, + sectionFragment, +}; + +$ const blockName = "opinion"; + + + + + + <@slot|{ node }|> + + @slot> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/primary-image.marko b/packages/marko-web-theme-monorail/components/blocks/primary-image.marko new file mode 100644 index 000000000..fbe2d768a --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/primary-image.marko @@ -0,0 +1,82 @@ +import { buildImgixUrl } from "@parameter1/base-cms-image"; +import { getAsObject, getAsArray, get } from "@parameter1/base-cms-object-path"; +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; + +$ const blockName = "primary-image"; +$ const image = getAsObject(input, "obj"); +$ const hasImage = Boolean(image.src); + +$ const forceDisplay = defaultValue(input.forceDisplay); +$ let display = forceDisplay || image.primaryImageDisplay || "center"; +$ const aspectRatio = get(image, "cropDimensions.aspectRatio"); +$ const { isLogo } = image; + +$ const withCaption = defaultValue(input.withCaption, true); +$ const withCredit = defaultValue(input.withCredit, true); +$ const withDisplayName = defaultValue(input.withDisplayName, true); + +$ const fluidWidth = defaultValue(input.fluidWidth, 700); +$ const alignedWidth = defaultValue(input.alignedWidth, 300); +$ const shouldFill = defaultValue(input.shouldFill, false); +$ const lazyload = defaultValue(input.lazyload, false); + +$ if (display === "center" && isLogo) { + // force logos to the right when set to center + display = "right"; +} + +$ const modifiers = [...getAsArray(input, "modifiers")]; +$ if (["left", "right"].includes(display)) { + modifiers.push("aligned"); +} +$ modifiers.push(`aligned-${display}`); + +$ const maxWidth = input.maxWidth || 700; +$ const fluid = !["left", "right"].includes(display); +$ if (fluid) modifiers.push("fluid"); +$ if (fluid && aspectRatio === "16x9") modifiers.push("fluid-16by9") + +$ const imageOptions = {}; +$ if (fluid) { + imageOptions.w = fluidWidth; + if (shouldFill && !isLogo) { + imageOptions.fit = "fillmax"; + imageOptions.fill = "blur"; + } +} else { + imageOptions.w = alignedWidth; +}; + +$ const imageAttrs = {}; +$ if (image.id) imageAttrs["data-image-id"] = image.id; + + + $ const src = buildImgixUrl(image.src, imageOptions); + $ const srcset = [`${buildImgixUrl(src, { dpr: 2 })} 2x`]; + + + + + + + + + + + + + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/products.marko b/packages/marko-web-theme-monorail/components/blocks/products.marko new file mode 100644 index 000000000..9159377d7 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/products.marko @@ -0,0 +1,57 @@ +import queryFragment from "../../graphql/fragments/products-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + +$ const queryParams = { + sectionAlias: input.alias, + limit: 3, + queryFragment, + sectionFragment, +}; + +$ const blockName = "products-block"; + + + + + ${section.name} + + + + $!{section.description || input.defaultDescription} + + + + ${i18n("View more")} » + + + + + <@slot|{ node }|> + + <@image width=112 ar="1:1" /> + + @slot> + + + + + ${i18n("View more")} » + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/read-next.marko b/packages/marko-web-theme-monorail/components/blocks/read-next.marko new file mode 100644 index 000000000..08fbba4c0 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/read-next.marko @@ -0,0 +1,42 @@ +import queryFragment from "../../graphql/fragments/read-next-block"; + +$ const { i18n } = out.global; + +$ const queryParams = { + publishedAfter: input.published, + excludeContentIds: [input.contentId], + sectionId: input.sectionId, + limit: 1, + queryFragment, +}; +$ const blockName = "read-next"; + + + + + + ${i18n("Read Next")} + + + + <@nodes nodes=nodes> + <@slot|{ node }|> + + <@image width=160 ar="3:2" /> + + @slot> + @nodes> + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/related-stories.marko b/packages/marko-web-theme-monorail/components/blocks/related-stories.marko new file mode 100644 index 000000000..9d75229c5 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/related-stories.marko @@ -0,0 +1,70 @@ +import { defaultValue } from "@parameter1/base-cms-marko-web/utils"; +import queryFragment from "../../graphql/fragments/related-stories-block"; + +$ const { i18n } = out.global; +$ const { contentId, sectionId, published } = input; + +$ const withNativeX = defaultValue(input.withNativeX, false); +$ const nativeX = { + name: "default", + index: 3, + sectionName: "Sponsor Content", + ...input.nativeX, +}; + +$ const limit = 4; +$ const queryParams = { + contentId, + limit, + requiresImage: true, + queryFragment, +}; + +$ const title = `${i18n("Related Stories")}`; +$ const blockName = "related-stories"; + + + + + $ const excludeContentIds = [contentId, ...nodes.map(node => node.id)]; + $ const sinceParams = { + sectionId, + since: published, + limit: limit - nodes.length, + excludeContentIds, + requiresImage: true, + excludeContentTypes: ["Contact", "Company", "Document", "Product", "Promotion"], + queryFragment + }; + + $ nodes.push(...related); + + + + ${title} + + + <@node modifiers=[blockName] /> + + + + + + + + + ${title} + + + <@node modifiers=[blockName] /> + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/resource-library.marko b/packages/marko-web-theme-monorail/components/blocks/resource-library.marko new file mode 100644 index 000000000..0be1a01b5 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/resource-library.marko @@ -0,0 +1,76 @@ +import queryFragment from "../../graphql/fragments/resource-library-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + + +$ const queryParams = { + ...input.queryParams, + sectionAlias: input.alias, + requiresImage: true, + limit: 4, + queryFragment, + sectionFragment, +}; + +$ const blockName = "resource-library"; + + + + + ${section && section.name || input.name} + + + + $!{section && section.description || input.defaultDescription} + + + + + ${i18n("View more")} » + + + + + + + + + + + <@image + fluid=true + gradient=true + width=250 + ar="3:4" + src=node.primaryImage.src + alt=node.primaryImage.alt + link=true + > + <@body> + <@title tag="h5"> + + @title> + @body> + @image> + + + + + + + + + + ${i18n("View more")} » + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-body-feed.marko b/packages/marko-web-theme-monorail/components/blocks/section-body-feed.marko new file mode 100644 index 000000000..b5e0375de --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-body-feed.marko @@ -0,0 +1,39 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/section-body-feed-block"; + +$ const queryParams = { + ...input.queryParams, + sectionAlias: input.alias, + queryFragment, +}; + +$ const blockName = "section-feed"; +$ const countOnly = defaultValue(input.countOnly, false); + + + + <${input.renderBody} ...data /> + + + + + + <@nodes nodes=nodes> + <@slot|{ node }|> + + @slot> + @nodes> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-card-deck-featured.marko b/packages/marko-web-theme-monorail/components/blocks/section-card-deck-featured.marko new file mode 100644 index 000000000..8aebf31d3 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-card-deck-featured.marko @@ -0,0 +1,37 @@ +import queryFragment from "../../graphql/fragments/section-card-deck-featured-block"; + +$ const { i18n } = out.global; + +$ const queryParams = { + limit: 3, + requiresImage: true, + sectionAlias: input.alias, + queryFragment, +}; + +$ const blockName = "section-card-deck-featured"; + + + + + + ${i18n("Featured")} + + + + <@slot|{ node }|> + + <@image ar="3:2" fluid=true /> + + @slot> + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-card-deck.marko b/packages/marko-web-theme-monorail/components/blocks/section-card-deck.marko new file mode 100644 index 000000000..d84653642 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-card-deck.marko @@ -0,0 +1,60 @@ +import queryFragment from "../../graphql/fragments/section-card-deck-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + +$ const queryParams = { + sectionAlias: input.alias, + requiresImage: true, + limit: 3, + queryFragment, + sectionFragment, +}; + +$ const blockName = "section-card-deck"; + + + + + ${section.name} + + + + $!{section.description || input.defaultDescription} + + + + ${i18n("View more")} » + + + + + + + + + + + <@image fluid=true width=330 ar="4:3" /> + + + + + + + + + ${i18n("View more")} » + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-card-list.marko b/packages/marko-web-theme-monorail/components/blocks/section-card-list.marko new file mode 100644 index 000000000..27a4fd0b1 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-card-list.marko @@ -0,0 +1,86 @@ +import queryFragment from "../../graphql/fragments/section-card-list-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + +$ const queryParams = { + limit: 3, + requiresImage: true, + sectionAlias: input.alias, + queryFragment, + sectionFragment, +}; +$ const blockName = "section-card-list"; + + + $ const heroNode = nodes.slice(0, 1)[0]; + $ const heroImageNode = { + id: heroNode.id, + type: heroNode.type, + siteContext: heroNode.siteContext, + primaryImage: heroNode.primaryImage, + }; + $ const listNodes = nodes.slice(1); + + + + ${section.name} + + + ${section.description || input.defaultDescription} + + + + + + <@image fluid=true width=340 ar="3:2" /> + + + + + + + + <@nodes nodes=listNodes> + <@slot|{ node }|> + + @slot> + @nodes> + + + + ${i18n("More")} ${section.name} + + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-feed.marko b/packages/marko-web-theme-monorail/components/blocks/section-feed.marko new file mode 100644 index 000000000..370ca25bc --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-feed.marko @@ -0,0 +1,44 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/section-feed-block"; + +$ const queryName = input.queryName ? input.queryName : "website-scheduled-content"; +$ const queryParams = { + ...input.queryParams, + ...(queryName === "website-scheduled-content") && { + sectionAlias: input.alias, + queryFragment, + } +}; + +$ const blockName = "section-feed"; +$ const countOnly = defaultValue(input.countOnly, false); +$ const modifiers = defaultValue(input.modifiers, []); +$ const lazyload = defaultValue(input.lazyload, true); +$ const withSection = defaultValue(input.withSection, true); + + + + <${input.renderBody} ...data /> + + + + + + <@nodes nodes=nodes> + <@slot|{ node }|> + + @slot> + @nodes> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-list-deck.marko b/packages/marko-web-theme-monorail/components/blocks/section-list-deck.marko new file mode 100644 index 000000000..0b316140d --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-list-deck.marko @@ -0,0 +1,18 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; + +$ const blockName = "section-list-deck"; +$ const aliases = getAsArray(input, "aliases"); + + + + + + + + + + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-list.marko b/packages/marko-web-theme-monorail/components/blocks/section-list.marko new file mode 100644 index 000000000..84b83aa7f --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-list.marko @@ -0,0 +1,86 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import { getAsObject } from "@parameter1/base-cms-object-path"; +import cardFragment from "../../graphql/fragments/section-list-card-block"; +import listFragment from "../../graphql/fragments/section-list-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + +$ const { alias } = input; + +$ const withSection = defaultValue(input.withSection, true); +$ const withViewMore = defaultValue(input.withViewMore, true); + +$ const queryParams = { + limit: 4, + ...getAsObject(input, "queryParams"), + queryFragment: listFragment, + sectionFragment, + sectionAlias: alias, +}; +$ const heroParams = { + ...queryParams, + limit: 1, + requiresImage: true, + queryFragment: cardFragment, +}; + +$ const blockName = "section-list"; + + + $ const listParams = { + ...queryParams, + limit: queryParams.limit - 1, + excludeContentIds: heroNodes.map((node) => node.id), + sectionFragment: undefined, + }; + + $ const nodes = [...heroNodes, ...listNodes]; + + <@header> + + @header> + <@nodes nodes=nodes> + <@slot|{ node, index }|> + + + <@image fluid=true width=330 ar="3:2" /> + + + + + + @slot> + @nodes> + + <@footer modifiers=["view-more"]> + + ${i18n("View More")} » + + @footer> + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/section-title-feed.marko b/packages/marko-web-theme-monorail/components/blocks/section-title-feed.marko new file mode 100644 index 000000000..6826fcdba --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/section-title-feed.marko @@ -0,0 +1,40 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/section-body-feed-block"; + +$ const queryParams = { + ...input.queryParams, + sectionAlias: input.alias, + queryFragment, +}; + +$ const blockName = "section-feed"; +$ const countOnly = defaultValue(input.countOnly, false); + + + + <${input.renderBody} ...data /> + + + + + + <@nodes nodes=nodes> + <@slot|{ node }|> + + @slot> + @nodes> + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/top-stories-menu.marko b/packages/marko-web-theme-monorail/components/blocks/top-stories-menu.marko new file mode 100644 index 000000000..547208a94 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/top-stories-menu.marko @@ -0,0 +1,40 @@ +import { getAsObject } from "@parameter1/base-cms-object-path"; +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/top-stories-menu-block"; + +$ const { i18n } = out.global; + +$ const sectionAlias = defaultValue(input.sectionAlias, 'home'); + +$ const queryParams = { + limit: 5, + queryFragment, + sectionAlias, +}; + +$ const blockName = "top-stories-menu"; + + + + <@header> + ${i18n("Top Stories")} + @header> + <@nodes nodes=nodes> + <@slot|{ node }|> + + @slot> + @nodes> + + diff --git a/packages/marko-web-theme-monorail/components/blocks/top-stories.marko b/packages/marko-web-theme-monorail/components/blocks/top-stories.marko new file mode 100644 index 000000000..b2c853992 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/top-stories.marko @@ -0,0 +1,75 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/top-stories-block"; + +$ const { i18n } = out.global; + +$ const queryParams = { + limit: 5, + requiresImage: true, + queryFragment, + sectionAlias: "home", + ...input.queryParams, +}; +$ const blockName = "top-stories"; +$ const withHeader = defaultValue(input.withHeader, true); +$ const withNativeX = defaultValue(input.withNativeX, true); +$ const lazyload = defaultValue(input.lazyload, true); +$ const queryName = (queryParams.optionName) ? "website-optioned-content" : "website-scheduled-content"; + + + + $ const heroNode = nodes.slice(0, 1)[0]; + $ const heroImageNode = { + id: heroNode.id, + type: heroNode.type, + siteContext: heroNode.siteContext, + primaryImage: heroNode.primaryImage, + }; + $ const cardNodes = nodes.slice(1); + + + + + ${i18n("Top Stories")} + + + + + + + <@image fluid=true width=600 ar="3:2" lazyload=lazyload /> + + + + + + + + + + <@node modifiers=[`${blockName}-card`]> + <@image lazyload=lazyload /> + @node> + + + + + diff --git a/packages/marko-web-theme-monorail/components/blocks/white-papers.marko b/packages/marko-web-theme-monorail/components/blocks/white-papers.marko new file mode 100644 index 000000000..3d74fa044 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/blocks/white-papers.marko @@ -0,0 +1,74 @@ +import { get } from "@parameter1/base-cms-object-path"; +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import queryFragment from "../../graphql/fragments/white-papers-block"; +import sectionFragment from "../../graphql/fragments/section-info"; + +$ const { i18n } = out.global; + +$ const sectionAlias = defaultValue(input.sectionAlias, "white-papers"); +$ const contentTypes = defaultValue(input.contentTypes, ["Whitepaper"]); + +$ const queryParams = { + sectionAlias, + includeContentTypes: contentTypes, + ...input.queryParams, + limit: 1, + queryFragment, + sectionFragment, +}; + + + + $ const node = nodes[0]; + $ const blockName = "white-papers"; + + + + + ${section.name} + + + + <@body> + <@header> + <@left modifiers=["company-name"]> + + ${i18n("Sponsored by")} ${value} + + @left> + @header> + <@title tag="h5"> + + @title> + <@text modifiers=["teaser"] show=(Boolean(node.teaser))> + + @text> + <@footer modifiers=["buttons"]> + <@left> + + ${i18n("Download")} + + + ${i18n("View All")} + + @left> + @footer> + @body> + + + + diff --git a/packages/marko-web-theme-monorail/components/breadcrumbs/content-page.marko b/packages/marko-web-theme-monorail/components/breadcrumbs/content-page.marko new file mode 100644 index 000000000..9043c7846 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/breadcrumbs/content-page.marko @@ -0,0 +1,6 @@ + diff --git a/packages/marko-web-theme-monorail/components/breadcrumbs/index.marko b/packages/marko-web-theme-monorail/components/breadcrumbs/index.marko new file mode 100644 index 000000000..74a3398ad --- /dev/null +++ b/packages/marko-web-theme-monorail/components/breadcrumbs/index.marko @@ -0,0 +1,20 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; + +$ const items = getAsArray(input, "items"); +$ const modifiers = getAsArray(input, "modifiers"); +$ const blockName = "breadcrumbs"; +$ const classes = [blockName, ...modifiers.map(mod => `${blockName}--${mod}`)]; + + + + + + + + <${item.renderBody} /> + + + + + + diff --git a/packages/marko-web-theme-monorail/components/breadcrumbs/marko.json b/packages/marko-web-theme-monorail/components/breadcrumbs/marko.json new file mode 100644 index 000000000..8ae0e762a --- /dev/null +++ b/packages/marko-web-theme-monorail/components/breadcrumbs/marko.json @@ -0,0 +1,30 @@ +{ + "": { + "template": "./index.marko", + "@items []": {}, + "@modifiers": "array" + }, + "": { + "template": "./with-home.marko", + "@items []": {}, + "@home-title": "string" + }, + "": { + "template": "./content-page.marko", + "@section": "object", + "@home-title": "string", + "@home-alias": "string", + "@display-self": "boolean", + "@display-home": "boolean", + "@modifiers": "array" + }, + "": { + "template": "./website-section.marko", + "@section": "object", + "@home-title": "string", + "@home-alias": "string", + "@display-self": "boolean", + "@display-home": "boolean", + "@modifiers": "array" + } +} diff --git a/packages/marko-web-theme-monorail/components/breadcrumbs/scss/_breadcrumbs.scss b/packages/marko-web-theme-monorail/components/breadcrumbs/scss/_breadcrumbs.scss new file mode 100644 index 000000000..118a50187 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/breadcrumbs/scss/_breadcrumbs.scss @@ -0,0 +1,35 @@ +.breadcrumbs { + @include media-breakpoint-down($theme-responsive-text-breakpoint) { + font-size: $theme-breadcrumbs-font-size-sm; + line-height: $theme-breadcrumbs-line-height-sm; + } + + font-family: $theme-breadcrumbs-font-family; + font-size: $theme-breadcrumbs-font-size; + font-weight: $theme-breadcrumbs-font-weight; + line-height: $theme-breadcrumbs-line-height; + text-transform: $theme-breadcrumbs-transform; + letter-spacing: $theme-breadcrumbs-letter-spacing; + + .breadcrumb { + padding-top: 0; + background-color: $theme-breadcrumbs-background-color; + } + + a { + color: $theme-breadcrumbs-link-color; + text-decoration: $theme-breadcrumbs-link-decoration; + + &:hover { + color: $theme-breadcrumbs-link-hover-color; + text-decoration: $theme-breadcrumbs-link-hover-decoration; + } + } + + &--content-page { + @include skin-typography($style: "slug-medium", $link-style: "primary"); + .breadcrumb { + padding-bottom: 1rem; + } + } +} diff --git a/packages/marko-web-theme-monorail/components/breadcrumbs/website-section.marko b/packages/marko-web-theme-monorail/components/breadcrumbs/website-section.marko new file mode 100644 index 000000000..29fbd3ff9 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/breadcrumbs/website-section.marko @@ -0,0 +1,31 @@ +import { getAsObject, getAsArray } from "@parameter1/base-cms-object-path"; +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; + +$ const section = getAsObject(input, "section"); +$ const children = getAsArray(section, "hierarchy"); +$ const homeTitle = input.homeTitle || "Home"; +$ const homeAlias = input.homeAlias || "home"; +$ const displaySelf = defaultValue(input.displaySelf, true); +$ const displayHome = defaultValue(input.displayHome, true); + + + + <@item> + ${homeTitle} + @item> + + + + + <@item> + $!{child.name} + @item> + + + <@item> + $!{child.name} + @item> + + + + diff --git a/packages/marko-web-theme-monorail/components/breadcrumbs/with-home.marko b/packages/marko-web-theme-monorail/components/breadcrumbs/with-home.marko new file mode 100644 index 000000000..0e588d6b6 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/breadcrumbs/with-home.marko @@ -0,0 +1,13 @@ +import { getAsArray } from "@parameter1/base-cms-object-path"; + +$ const items = getAsArray(input, "items"); +$ const homeTitle = input.homeTitle || "Home"; + + + <@item> + $!{homeTitle} + @item> + + <@item ...item /> + + diff --git a/packages/marko-web-theme-monorail/components/client-side-block-loader.marko b/packages/marko-web-theme-monorail/components/client-side-block-loader.marko new file mode 100644 index 000000000..7205831b0 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/client-side-block-loader.marko @@ -0,0 +1 @@ + diff --git a/packages/marko-web-theme-monorail/components/client-side-blocks/marko.json b/packages/marko-web-theme-monorail/components/client-side-blocks/marko.json new file mode 100644 index 000000000..8865e2e00 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/client-side-blocks/marko.json @@ -0,0 +1,5 @@ +{ + "": { + "template": "./most-popular.marko" + } +} diff --git a/packages/marko-web-theme-monorail/components/client-side-blocks/most-popular.marko b/packages/marko-web-theme-monorail/components/client-side-blocks/most-popular.marko new file mode 100644 index 000000000..15f6cda7d --- /dev/null +++ b/packages/marko-web-theme-monorail/components/client-side-blocks/most-popular.marko @@ -0,0 +1 @@ + diff --git a/packages/marko-web-theme-monorail/components/flows/content/card-deck-col.marko b/packages/marko-web-theme-monorail/components/flows/content/card-deck-col.marko new file mode 100644 index 000000000..527eed7f4 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/flows/content/card-deck-col.marko @@ -0,0 +1,49 @@ +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; +import { getAsObject } from "@parameter1/base-cms-object-path"; + +$ const { nativeX: nxConfig } = out.global; +$ const nativeX = getAsObject(input, "nativeX"); +$ const cols = defaultValue(input.cols, 4); +$ const nodeImageInput = getAsObject(input, "node.image"); + + + <@slot|{ node, index }|> + + + + <@image ar="3:2" fluid=true ...nodeImageInput /> + + + + + + <@image ar="3:2" fluid=true ...nodeImageInput /> + + + @slot> + diff --git a/packages/marko-web-theme-monorail/components/flows/content/directory-section.marko b/packages/marko-web-theme-monorail/components/flows/content/directory-section.marko new file mode 100644 index 000000000..541a09b44 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/flows/content/directory-section.marko @@ -0,0 +1,41 @@ +import { getAsObject } from "@parameter1/base-cms-object-path"; +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; + +$ const { nodes, header } = input +$ const image = getAsObject(input, "node.image"); + +$ const withSection = defaultValue(input.withSection, false); + +$ const blockName = "read-next"; + + + + + + <${header.renderBody} /> + + + + <@nodes nodes=nodes> + <@slot|{ node }|> + + <@image width=160 ar="3:2" ...image /> + + @slot> + @nodes> + + + diff --git a/packages/marko-web-theme-monorail/components/flows/content/list.marko b/packages/marko-web-theme-monorail/components/flows/content/list.marko new file mode 100644 index 000000000..6037c5ba2 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/flows/content/list.marko @@ -0,0 +1,44 @@ +import { getAsArray, getAsObject } from "@parameter1/base-cms-object-path"; +import defaultValue from "@parameter1/base-cms-marko-core/utils/default-value"; + +$ const { nativeX: nxConfig } = out.global; +$ const nodes = getAsArray(input, "nodes"); +$ const nativeX = getAsObject(input, "nativeX"); + + + <@nodes nodes=nodes> + <@slot|{ node, index }|> + + + + + + + + + @slot> + @nodes> + diff --git a/packages/marko-web-theme-monorail/components/flows/content/marko.json b/packages/marko-web-theme-monorail/components/flows/content/marko.json new file mode 100644 index 000000000..d53283b59 --- /dev/null +++ b/packages/marko-web-theme-monorail/components/flows/content/marko.json @@ -0,0 +1,36 @@ +{ + "": { + "template": "./list.marko", + "": {}, + "": {}, + "
{{ error.message }}
+ {{ translate("startReceiving") }} {{ siteName }}. +