Skip to content

Commit

Permalink
Support static pages from Contentful
Browse files Browse the repository at this point in the history
Static pages can be defined in Contentful:

Implementation details:
- Contentful pages are preferred over local static files
- To avoid excessive API calls to contentful, a list of valid paths that contentful has defined every 5 mins
- Slow fetch interval for contentful to reduce API usage when in dev (resets will still trigger API calls) to 15-30 min
- Add preview api key to support previewing unpublished contentful pages - uses a hardcoded value for now
- Contentful pages are accessed via GraphQL
- Add postcss-inherit to have css classes inherit other properites from other css classes (for markdown)

Supported Contentful Models:
- Markdown
- Html
- Paragraph

Supported Contentful Data Types:
- Rich Text Field

Refactors:
 - Move at-at's pool to a component that is shared

Limitations:
- Paths must be still specified in storefront's routing before new pages can be visible from contentful
- Code embed in rich text isn't supported
- No visual difference between inline / block embed of assets + entries.
- Paragraphs (rich text content modules) can only nest once.
  • Loading branch information
jeffh committed Sep 7, 2021
1 parent f33c818 commit 972f914
Show file tree
Hide file tree
Showing 17 changed files with 603 additions and 123 deletions.
1 change: 1 addition & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ function css() {
require('postcss-calc')(),
require('postcss-color-function')(),
require('postcss-discard-comments')(),
require('postcss-inherit'),
require('postcss-inline-svg')(),
require('autoprefixer')({browsers: ['last 3 versions']}),
/* require('postcss-reporter')(), */
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"basscss-ui-utility-groups": "^1.0.1",
"jsqr": "1.1.0",
"muuri-react": "^3.1.6",
"normalize.css": "^4.2.0"
"normalize.css": "^4.2.0",
"postcss-inherit": "^4.1.0"
},
"devDependencies": {
"autoprefixer": "^6.3.1",
Expand Down
4 changes: 3 additions & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
[com.cemerick/url "0.1.1"]
[overtone/at-at "1.2.0"]
[camel-snake-kebab "0.4.0"]
[org.clojure/spec.alpha "0.2.176"]]
[org.clojure/spec.alpha "0.2.176"]
[meander/epsilon "0.0.650"]
[markdown-clj "1.10.6"]]
:repositories [["private" {:url "s3p://mayvenn-dependencies/releases/"}]]
:plugins [[s3-wagon-private "1.3.1"]
[lein-cljsbuild "1.1.7"]
Expand Down
1 change: 1 addition & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@

/* Third-party Overrides */

@import 'custom-contentful.css';
@import 'custom-uploadcare.css';
@import 'custom-yotpo.css';
@import 'custom-kustomer.css';
Expand Down
58 changes: 58 additions & 0 deletions resources/css/custom-contentful.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
@import 'basscss-typography';
@import 'custom-typography.css';
@import 'basscss-margin';
@import 'custom-margin.css';
@import 'basscss-padding';
@import 'custom-padding.css';
@import 'basscss-border';
@import 'custom-border.css';
@import 'basscss-addons/modules/colors';
@import 'custom-colors.css';
@import 'basscss-addons/modules/border-colors';
@import 'custom-border-colors.css';

.content-markdown a:link {
@inherit: .p-color, .button-font-2, .border-bottom, .border-width-2, .border-p-color;
}
.content-markdown {
font: 13px/18px var(--font-family-proxima);
line-height: 26px;
}
.content-markdown ul, .content-markdown ol { @inherit: .mb2, .content-2; }
.content-markdown p { @inherit: .content-2, .mb2; }
.content-markdown li { @inherit: .content-2, .my1; }
.content-markdown h1 { @inherit: .title-2.canela, .my3; }
.content-markdown h2 { @inherit: .title-2.canela, .my3; }
.content-markdown h3 { @inherit: .title-3.canela, .my3; }
.content-markdown b { @inherit: .bold; }
.content-markdown table {
border-collapse: collapse;
table-layout: fixed;
margin: 10px 0;
width: 100%;
border: 2px solid var(--gray-mask);
}
.content-markdown table tr {
border-bottom: 1px solid var(--cool-gray);
}
.content-markdown table th {
@inherit: .content-3, .p1, .bold;
background: var(--cool-gray);
}
.content-markdown table td:first-child {
border-left: 0;
}
.content-markdown table td {
@inherit: .p1;
border-left: 1px solid var(--cool-gray);
margin: 0;
vertical-align: top;
}

:root {
--gray-mask: rgba(204, 204, 204, 0.1);
--cool-gray: #eeefef;
--medium-font-weight: 400;
--font-weight: var(--medium-font-weight);
--font-family-proxima: 'Proxima Nova', Arial, sans-serif;
}
9 changes: 9 additions & 0 deletions resources/gql/all_static_pages.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query($preview: Boolean) {
staticPageCollection(preview: $preview) {
items {
sys { id }
path
title
}
}
}
122 changes: 122 additions & 0 deletions resources/gql/static_page.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
fragment Subcontent on Entry {
sys {
id
}
__typename
...on Markdown {
title
content
}
...on Html {
html
}
...on Paragraph {
title
textAlignment
text {
json
links {
entries {
inline {
sys {
id
}
# graphql does not allow recursive queries
# ...Content
}
block {
sys {
id
}
# graphql does not allow recursive queries
# ...Content
}
}
assets {
# hyperlink {}
block {
sys { id }
title
url
width
height
}
}
}
}
}
}
fragment Content on Entry {
sys {
id
}
__typename
...on Markdown {
title
content
}
...on Html {
html
}
...on Paragraph {
title
textAlignment
text {
json
links {
entries {
inline {
# graphql does not allow recursive queries - so we can step one down
...Subcontent
}
block {
# graphql does not allow recursive queries - so we can step one down
...Subcontent
}
}
assets {
# hyperlink {}
block {
sys { id }
title
url
width
height
}
}
}
}
}
}

query($preview: Boolean, $path: String) {
staticPageCollection(preview: $preview, limit: 1, where: {path: $path}) {
items {
path
title
content {
json
links {
entries {
inline {
...Content
}
block {
...Content
}
}
assets {
# hyperlink {}
block {
sys { id }
url
title
width
height
}
}
}
}
}
}
}
6 changes: 4 additions & 2 deletions src-cljc/storefront/components/content.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
(:require [storefront.component :as component :refer [defcomponent]]
[storefront.keypaths :as keypaths]))

(defcomponent component [{:keys [content]} owner opts]
[:div {:dangerouslySetInnerHTML {:__html content}}])
(defcomponent component [{:keys [content static-content-id]} owner opts]
[:div.mx-960.mx-auto
{:id (str "content-" static-content-id)
:dangerouslySetInnerHTML {:__html content}}])

(defn query [data]
(let [sms-number (get-in data keypaths/sms-number)]
Expand Down
19 changes: 10 additions & 9 deletions src-cljc/storefront/routes.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@
(read-string (name value)))

(def static-page-routes
{"/guarantee" (edn->bidi events/navigate-content-guarantee)
"/help" (edn->bidi events/navigate-content-help)
"/about-us" (edn->bidi events/navigate-content-about-us)
"/policy/privacy" (edn->bidi events/navigate-content-privacy)
"/policy/tos" (edn->bidi events/navigate-content-tos)
"/ugc-usage-terms" (edn->bidi events/navigate-content-ugc-usage-terms)
"/voucher-terms" (edn->bidi events/navigate-content-voucher-terms)
"/program-terms" (edn->bidi events/navigate-content-program-terms)
"/our-hair" (edn->bidi events/navigate-content-our-hair)})
{"/guarantee" (edn->bidi events/navigate-content-guarantee)
"/help" (edn->bidi events/navigate-content-help)
"/about-us" (edn->bidi events/navigate-content-about-us)
"/policy/privacy" (edn->bidi events/navigate-content-privacy)
"/policy/privacy/v1" (edn->bidi events/navigate-content-privacy)
"/policy/tos" (edn->bidi events/navigate-content-tos)
"/ugc-usage-terms" (edn->bidi events/navigate-content-ugc-usage-terms)
"/voucher-terms" (edn->bidi events/navigate-content-voucher-terms)
"/program-terms" (edn->bidi events/navigate-content-program-terms)
"/our-hair" (edn->bidi events/navigate-content-our-hair)})

(def static-api-routes
["/static" static-page-routes])
Expand Down
6 changes: 6 additions & 0 deletions src-cljs/storefront/frontend_effects.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@
(get-in app-state keypaths/static-id))
(api/get-static-content event)))

(defmethod effects/perform-effects events/navigate-static-page
[_ _ _ _ app-state]
(when-not (= static-content-id
(get-in app-state keypaths/static-id))
(api/get-static-content event)))

(defmethod effects/perform-effects events/navigate-content-about-us [_ _ _ _ app-state]
(wistia/load))

Expand Down
22 changes: 18 additions & 4 deletions src/storefront/config.clj
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,32 @@
(catch java.lang.IllegalArgumentException e
"unknown")))

;; Macro?
(defn- if-dev-else
"Use dev-value if in env, otherwise use prod-value"
[env dev-value prod-value]
(if (#{"production" "acceptance"} (env :environment))
prod-value
dev-value))

(def ^:private minute (* 60 1000))

(def default-config {:server-opts {:port 3006}
:client-version client-version
:contentful-config {:cache-timeout 120000
:endpoint "https://cdn.contentful.com"}
:contentful-config {:endpoint "https://cdn.contentful.com"
:graphql-endpoint "https://graphql.contentful.com"
:env-id "master"}
:logging {:system-name "storefront.system"}})

(defn env-config []
{:environment (env :environment)
:bugsnag-token (env :bugsnag-token)
:welcome-config {:url (env :welcome-url)}
:contentful-config {:api-key (env :contentful-content-delivery-api-key)
:space-id (env :contentful-space-id)}
:contentful-config {:cache-timeout (* (if-dev-else env 4 15) minute)
:static-page-fetch-interval (* (if-dev-else env 5 30) minute)
:api-key (env :contentful-content-delivery-api-key)
:preview-api-key (env :contentful-content-delivery-preview-api-key)
:space-id (env :contentful-space-id)}
:launchdarkly-config {:sdk-key (env :launchdarkly-sdk-key)}
:storeback-config {:endpoint (env :storeback-endpoint)
:internal-endpoint (or
Expand Down
Loading

0 comments on commit 972f914

Please sign in to comment.