Finishing up your integration
Pricing section integration
Let’s look at the overview of the modeling required for the pricing elements:
The mapping from the definition to the visual elements is similar to what we have seen in the feature section. We again have a type that is composed of sub-type elements. This is done using the
+ * (solidTemplate:pricingTier)
line. This is a child node definition that is restricted to a single content node type solidTemplate:pricingTier
. The type definition is just below and is rather straightforward except for the feature property: it is multi-valued, and allowed to have a dynamic number of values, which will be useful when content editors want to list more or fewer features for a single pricing tier. Finally, the pricing button is modeled exactly like the hero section buttons.
Now let’s add the content definition in definitions.cnd
[solidTemplate:pricingTier]
- price (string) = '49/month'
- featuresTitle (string) = 'What you will get' i18n
- feature (string) = 'Lorem ipsum dolor sit nisi' i18n multiple
- pricingButtonText (string) = 'Pre order now' i18n
- pricingButtonLink (weakreference) < jnt:page
And then
[solidTemplate:pricingSection] > jnt:content, solidTemplatemix:solidTemplateComponents
- title (string) = 'Unlimited for all' i18n
- text (string) = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut ad quis nostrud.' i18n
+ * (solidTemplate:pricingTier)
As we have two content type definitions, we will need two view files to render these. Let’s start with the pricingTier
one, which is embedded in the pricingSection
one. We will therefore create a file called $NPM_TEMPLATE/src/server/views/pricingTier/PricingTierDefault.jsx
with the following content:
import React from 'react';
import { useServerContext, getNodeProps, buildUrl } from '@jahia/js-server-core';
export const PricingTierDefault = () => {
const {currentNode, renderContext, currentResource} = useServerContext();
const props = getNodeProps(currentNode, ['featuresTitle', 'feature', 'price', 'pricingButtonText', 'pricingButtonLink']);
return (
<div className="pricing-table">
<div className="pricing-table-inner is-revealing">
<div className="pricing-table-main">
<div className="pricing-table-header pb-24">
<div className="pricing-table-price"><span className="pricing-table-price-currency h2">$</span><span className="pricing-table-price-amount h1">{props.price}</span></div>
</div>
<div className="pricing-table-features-title text-xs pt-24 pb-24">{props.featuresTitle}</div>
<ul className="pricing-table-features list-reset text-xs">
{props.feature.map(value =>
<li key={value}>
<span>{value}</span>
</li>
)}
</ul>
</div>
<div className="pricing-table-cta mb-8">
<a className="button button-primary button-shadow button-block" href={props.pricingButtonLink ? buildUrl({path:props.pricingButtonLink.getPath()}, renderContext, currentResource) : '#'}>{props.pricingButtonText}</a>
</div>
</div>
</div>
)
}
PricingTierDefault.jahiaComponent = {
nodeType: 'solidTemplate:pricingTier',
displayName: 'Pricing tier',
componentType: 'view'
}
In this view, we have to render a multi-valued property (feature
). We do so by simply iterating over the values as they are directly accessible as an array.
We can now work on the parent view, which will display the title, introduction text, and the list of pricing entries.
Basically let’s create a new file: $NPM_TEMPLATE/src/server/views/pricingSection/PricingSectionDefault.jsx
with the following content:
import React from 'react';
import {Render, AddContentButtons, useServerContext, getChildNodes, getNodeProps} from '@jahia/js-server-core';
export const PricingSectionDefault = () => {
const {currentNode} = useServerContext();
const allChildren = getChildNodes(currentNode, -1);
const props = getNodeProps(currentNode, ['title', 'paragraph']);
return (
<section className="pricing section">
<div className="container-sm">
<div className="pricing-inner section-inner">
<div className="pricing-header text-center">
<h2 className="section-title mt-0">{props.title}</h2>
<p className="section-paragraph mb-0">{props.paragraph}</p>
</div>
<div className="pricing-tables-wrap">
{allChildren && allChildren.map((child) =>
<Render path={child.getPath()} key={child.getIdentifier()} />
)}
</div>
<AddContentButtons />
</div>
</div>
</section>
)
}
PricingSectionDefault.jahiaComponent = {
nodeType: 'solidTemplate:pricingSection',
displayName: 'Pricing section',
componentType: 'view'
}
As done in the features section, we use the get
to iterate through the node children nodes to render them using the Render
helper.
Finally, the <AddContentButtons
/>
helper call is used to render, only in edit mode, a button to add new content nodes.
Now we can remove the hardcoded HTML section from the $NPM_TEMPLATE/src/server/templates/page/PageHome.jsx
template. Simply remove the following HTML section:
<section class="pricing section">
... content removed for brevity...
</section>
Then we need to export our two views, we first need to create a src/server/views/pricingTier/index.js
file with the following content:
export * from './PricingTierDefault';
And then create a src/server/views/pricingSection/index.js
file with the following content:
export * from './PricingSectionDefault';
And finally we must add the new types to the main src/server/views/index.js
file with the following content:
export * from './pricingTier';
export * from './pricingSection';
We can now refresh our browser and creating the content by using a process exactly like the one for the features section:
- Click on the
New content
button in the page - Open the
base
category - Select the
pricingSection
type and clickCREATE
- Click
SAVE
to create the section with the default values and then click the back button. You should now see the section with apricingTier
button. - Click the New
pricingTier
button to open the Content Editor to create a newpricingTier
content object. - Notice the
feature
property that has anADD
button below it. Click that button a few times to add features. You may copy-paste the default text if you like or enter your own. - Click the
SAVE
button and then the back button to return to the home page. - Click the
PREVIEW
button to see what the resulting page looks like, it should look like this:
Call to action section
The call to action section is possibly the simplest of all the content type definitions in this template. Here is the overview:
First let’s add definition to definitions.cnd
[solidTemplate:ctaSection] > jnt:content, solidTemplatemix:solidTemplateComponents
- text (string) = 'Still not convinced on buying?' i18n
- ctaButtonText (string) = 'Get in touch' i18n
- ctaButtonLink (weakreference) < jnt:page
Creating its view is equally straightforward, in $NPM_TEMPLATE/src/server/views/ctaSection/CtaSectionDefault.jsx
:
import React from 'react';
import {useServerContext, getNodeProps, buildUrl } from '@jahia/js-server-core';
export const CtaSectionDefault = () => {
const {currentNode, renderContext, currentResource} = useServerContext();
const props = getNodeProps(currentNode, ['text', 'ctaButtonLink', 'ctaButtonText']);
return (
<section className="cta section">
<div className="container">
<div className="cta-inner section-inner">
<h3 className="section-title mt-0">{props.text}</h3>
<div className="cta-cta">
<a className="button button-primary button-wide-mobile" href={props.ctaButtonLink ? buildUrl({path: props.ctaButtonLink.getPath()}, renderContext, currentResource) : '#'}>{props.ctaButtonText}</a>
</div>
</div>
</div>
</section>
);
}
CtaSectionDefault.jahiaComponent = {
nodeType: 'solidTemplate:ctaSection',
displayName: 'Call to action section',
componentType: 'view'
}
Finally don’t forget to remove the hardcoded HTML section from the $NPM_TEMPLATE/src/server/templates/page/PageHome.jsx
template:
<section class="cta section">
<div class="container">
<div class="cta-inner section-inner">
<h3 class="section-title mt-0">Still not convinced on buying?</h3>
<div class="cta-cta">
<a class="button button-primary button-wide-mobile" href="#">Get in touch</a>
</div>
</div>
</div>
</section>
Then we need to export our view, we first need to create a src/server/views/ctaSection/index.js
file with the following content:
export * from './CtaSectionDefault';
And finally, we must add the new type to the main src/server/views/index.js
file with the following content:
export * from './ctaSection';
We can then re-create the content object using the following steps:
- Refresh your browser’s page
- Click on
New content
in the page - Select the
ctaSection
content type and clickCREATE
- Click
SAVE
to create the section content object and then click the back button - Click the
PREVIEW
button to see what the resulting page looks like, it should look like this:
Next step
Continue to conclusion