0% found this document useful (0 votes)
18 views21 pages

Developing Standard Features Exercises (15.2.2)

Uploaded by

gar181469
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views21 pages

Developing Standard Features Exercises (15.2.2)

Uploaded by

gar181469
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Developing

Standard
Features
EXERCISES
EXERCISE 1. FILTER THE NEWS LIST
COMPONENT
On this exercise you will start by exploring the repository servlet.
Then, you will filter the news list using an Essentials extension point.

1 Log on to the repository servlet as username: “admin” password: “admin”


on http://localhost:8080/cms/repository

2 Use the lower part of the screen to navigate through the hierarchical
structure of the jcr.
You will notice that the presentation here is much simpler than in the
console.
At the top, you find four search options. We will now explore the SQL
search.

3 Click the SQL tab and enter this SQL query:


select * from myproject:newsdocument

Take a look at the results: can you explain all of them?

4 Append some different constraints and ordering to the query from step 3:

a. where jcr:path like '/content/documents/%'

b. where contains(hippo:availability, 'live')

c. order by hippostdpubwf:lastModificationDate

d. asc or desc

e. where contains (.,'lorem')

5 Also check out the "Text" search option by entering a search term, e.g.
"lorem".
AHA!

━ Be aware that the queries will only retrieve data. Updating or deleting is
not possible with the repository servlet interface.

6 Log into the CMS. From the content perspective, browse to the “news”
folder.
Create one folder within “news” with the name of the current year i.e.
“2023”.
Create a second folder within the folder created previously with the
number of the current month i.e. “03”.

7 Browse to Setup -> System -> Updater Editor.

8 There you will find a script called “Add News Items”. On its repository path
property, use /content/documents/myproject/news/<year>/<month>
updating the year and the month respectively with the year and month
that you have in your project.

9 Execute the script and once it’s finished inspect the news folder and check
that the news items were created correctly.

10 In your source code navigate to the site/components module and find the
NewsComponent class. (hint: it’s in the org.example/components folder)

11 You’ll notice that we have some unused imports already available in this
class.
Make the class extend the unused import EssentialsNewsComponent and
add the following annotation to it:
@ParametersInfo(type = EssentialsNewsComponentInfo.class)

You probably noticed that the script you ran before added news items, some of
which have the word “Fake” in their title property. We are now going to remove
all those “Fake news” items, using a Filter.
12 Uncomment the contributeAndFilters method and add a new filter to the
filters list, for news that does not contain “Fake” in the title (You can use
“myproject:title” for the property to be filtered).

13 Rebuild and restart the project.

14 You may have a -preview structure that the Experience manager uses. If
that is the case, you must remove it now. Check if you have the node at the
path /hst:myproject/hst:configurations/myproject-preview and remove
it if it exists.

15 In the HST configuration, navigate to the workspace and find the main
container of the newslist

16 In the main container, update the hst:componentclassname of the


newslist hst:containeritemcomponent with our custom NewsComponent
class.
Don't forget to write changes to the repository!
EXERCISE 2. ADD THE NEWS LIST INFO
CLASS
In this exercise you will give your webmaster users the option to determine if the
news list component should be filtered or not and what text to filter.

The News List component now uses the ParameterInfo class. We added a new
filter that we want to make available to the webmasters, so we will make a class
of our own.

1 This interface class exists in the project:


org.example.components.NewsComponentInfo

Make it extend the EssentialsNewsComponentInfo interface.


2 Add a new Boolean getter method named getFilterNews.
Add a @Parameter annotation to it.

3 Add a new String getter method named getTextToFilter.


Add a @Parameter annotation to it and add a name attribute to it.

4 Go back to the NewsComponent and change its annotation so it uses the


new info class.

5 Where you create the filter, retrieve the component parameters info.
Only create the filter if getFilterNews is true and getTextToFilter is not
empty.

6 Use the value on getTextToFilter on the filter you created.

7 Rebuild and restart the site.

8 Verify that the news component in the Experience manager has functional
new checkbox and input fields.

AHA!

━ You can localize your parameter name with a resource bundle. You can
read more about it:
https://xmdocumentation.bloomreach.com/library/concepts/template-
composer/annotate-channel-or-component-configuration.html

EXERCISE 3.
CONTRIBUTE TO THE MODEL
You might want to contribute to the Delivery API, customized for your own SPA
implementation. With the following exercise we will create an HST component
and add an additional JSON element to the Delivery API.

For this exercise, the following documentation is relevant:


https://xmdocumentation.bloomreach.com/library/concepts/page-model-
api/model-contribution.html

1 In your source code, navigate to the site/components module and find the
BannerComponent class that was added for you.

2 We will extend EssentialsBannerComponent, import it


import org.onehippo.cms7.essentials.components.EssentialsBannerComponent;

3 Make it extend the EssentialsBannerComponent


Add the following annotation to it:

@ParametersInfo(type = EssentialsBannerComponentInfo.class)
public class BannerComponent extends EssentialsBannerComponent {
...
}

4 Uncomment the #doBeforeRender method.

5 There are 3 To-Do’s to finish there.


You are given the code to get the banner bean's path from the
parametersInfo object.
So, get the bean from the root bean using getBean(documentPath).
Now, Create a new BannerModel object.
Finally, set it on the request as “myData”.
request.setModel("myData", bannerModel);

6 Do a build and rerun the project.

7 In the hst configuration, navigate to the workspace and find the main
container of the homepage.

8 In the main container, update the hst:componentclassname of the first


hst:containeritemcomponent to the BannerComponent created before.
Don't forget to write changes to the repository!
9 When you access the Delivery API at http://localhost:8080/site/resourceapi
you should see the model in the JSON output. It should be similar to this:
** Notice "myData" in the "models" element of the first banner.

EXERCISE 4.
CUSTOMIZE JSON BY REGISTERING A
MIXIN AND CONVERTER
In exercise 3, we added an additional (model) element to the Delivery API.
In this exercise, we will make more advanced changes to the Delivery API.
We will remove a redundant element and change the value of another element.

For this exercise, the following documentation is relevant:

https://xmdocumentation.bloomreach.com/library/concepts/page-model-
api/customization.html
1 In your source code, navigate to the site module
(site/components/src/main/java).

2 Create a new package named "org.example.mixin" and add the newly


created classes in the next steps in this package.

3 In this exercise, we will target the class:


org.hippoecm.hst.pagemodelapi.v10.core.model.ComponentWindowModel

This model class is serializing the components in our page model.


We will create a mixin and a converter to modify our page model.

4 First, create the mixin class.


public abstract class ComponentWindowModelMixin extends
ComponentWindowModel {

public ComponentWindowModelMixin(final HstComponentWindow window) {


super(window);
}
}

Override the getComponentClass method and annotate this with @JsonIgnore.


This will make the componentClass element hidden in the JSON output.

@JsonIgnore
@Override
public String getComponentClass() {
return super.getComponentClass();
}

5 Override the getName method and add a @JsonSerialize annotation to


the method. By adding the @JsonSerialize annotation, you allow
modifications to the name element in the JSON output.

@JsonSerialize(/*converter = todo*/)
@Override
public String getName() {
return super.getName();
}

6 Create a Jackson Converter by creating a new class,


ComponentNameConverter.
In this class, extend
com.fasterxml.jackson.databind.util.StdConverter<String, String>

public class ComponentNameConverter extends StdConverter<String, String> {


@Override
public String convert(final String value) {
return
//todo: implement this feature, strip away numeric characters in string
}
}

7 Take a look at step 5.


Note that there’s a “todo” waiting to be completed.
Set the ComponentNameConverter class as an argument of the
@JsonSerialize converter annotation of the getName method in the
ComponentWindowModelMixin class.

8 Under the path site/components/src/main/resources/META-INF/hst-


assembly/overrides/addon/org/hippoecm/hst/pagemodelapi/v10, create a

new xml file and give it the name “mixin.xml”

9 Add the following snippet to it:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pageModelJacksonObjectMapperExtraMixins"
class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<entry key="org.hippoecm.hst.pagemodelapi.v10.core.model.ComponentWindowModel"
value="org.example.mixin.ComponentWindowModelMixin"/>
</map>
</property>
</bean>
</beans>

10 Rebuild and restart the project.

11 Access the Delivery API to view the result.


http://localhost:8080/site/resourceapi.
You should see the model in the JSON output:
** notice the componentClass element
(compare the result with the 2nd
exercise) is not a visible element and the
name does not contain a number on the
second element.

EXERCISE 5.
CREATE A DYNAMIC COMPONENT
In this exercise you are going to create a dynamic component based on the
example provided.

1 In the CMS console, browse to the essentials catalog node on:


/hst:myproject/hst:configurations/hst:default/hst:catalog/essentials-catalog

2 Add a new node called DynamicBanner with primary type


hst:componentdefinition.

3 On the new node, add a property hst:componentclassname with value


org.hippoecm.hst.component.support.bean.dynamic.BaseHstDynamicComponent

a. We are using the BaseHstDynamicComponent here, which is a


component that provides dynamic behavior on top of the
BaseHstComponent. This component exposes all its params.
4 Add the following String properties:

hst:ctype with value DynamicBanner


hst:label with value DynamicBanner

hst:iconpath with value images/essentials/catalog-component-icons/banner.svg

5 On the DynamicBanner node, add a child node called “document”, of type


hst:dynamicparameter

6 On this new child node “document”, add a String property


hst:valuetype with value text

7 On the new document node, add a new child node called hst:fieldconfig of
type hst:jcrpath. This indicates that this new document parameter will
have a document picker for the users to choose the document from.

8 Add the following properties to the hst:fieldconfig node:


hst:pickerconfiguration: cms-pickers/documents-only
hst:pickerinitialpath: banners
hst:relative: true

9 You now have a new DynamicBanner component (similar to the Banner


Component previously installed from Essentials) usable on the Experience
Manager, but this one was added on the fly, without any kind of
development needed.
Open the CMS and browse to the Experience Manager.

10 On the side panel choose the components tab, check if the new
component is there and add it to your homepage.

11 Can you configure and see the new component?


What happened?

a. Leave it as it is for now.


EXERCISE 6.
CREATE A REACT COMPONENT
You probably noticed in the previous exercise that the new component is
configurable on the Experience Manager but it is not being rendered on the front
end. We will take care of that now.

Let’s start by adding a new React component for the Dynamic Banner:

1 Open the frontend project located inside your archetype directory on root
level “/react”.

2 Copy the Banner.tsx file located on react/src/components inside the


components directory and name it DynamicBanner.tsx

3 Change its function name to DynamicBanner

4 Open index.ts and add the following line to it:


export * from './DynamicBanner';

a. This makes the component available to be imported in other places.

5 In App.tsx, append the DynamicBanner component to the './components'


imports.

Also, add it to the const mapping = {}

Please note - mappings require various string keys to link them

● For type “hst:component”, the mapping is done by node name.


'News List': NewsList
● For type “hst:containeritemcomponent”, use the “hst:label” property value.
'Content list': ContentList
● For a dynamic component, it is done using the “hst:ctype” property
value.
DynamicBanner
6 If you haven’t published your channel in the Experience Manager, do it
now. Your new DynamicBanner component should appear correctly there.

7 Check the homepage at http://localhost:3000/ and see if it also appears


correctly.

8 You might have noticed that the Content List React component was not
defined, so our Content page is not correct yet. We’re going to create a
React component similar to the News List component, to make it work.

9 Copy the NewsList.tsx file and name it ContentList.tsx

10 Adjust its function name to be ContentList, and any other methods and
variables that you think are needed.

11 Locate the ContentList component in the console


(hint: check the workspace containers)

12 In index.ts, add the newly created component to make it available.


In App.tsx, make sure you add the import and the mapping with the new
component too.
NOTE: Refer to the component in the mapping using the reference for the
specific nodetype as mentioned in step 5

13 You should now have a working Content List component and detail page.
If it still doesn’t work, verify the mapping reference in App.tsx matches the
hst:label
(why? b/c this node is a hst:containeritemcomponent Primary type)
EXERCISE 7.
ADD THE ABOUT PAGE
For the About page we need a document and a sitemap item to make it available
on the site.

AHA! CONSOLE TIPS:


━ If you want to open a node by its path the “Open” function of the console
can help you. Use the button at the top or use the Ctrl-O shortcut.

━ For an overview of all the available shortcuts in the Console use Ctrl-H.

7.1 ADD THE DOCUMENT


The URL http://localhost:3000/content shows the content list.
The links take you to content pages where a single content detail page can be
seen.
Each detail page shows the content of one document of the type Simple content.

We will reuse this document type for the About page, but it should not show up
in the content list.

1 In the CMS, go to the Content section and “Add new translated folder” in
the My Project folder. Name it service.

2 In the service folder, create a new document of the type "Simple


Document" and name it About Us.

3 Add some content to it. Publish it.

4 Use the View button from the document actions: note that there is no
preview available. It has no preview yet, because the document is not
matched by any sitemap item.

7.2 CREATE THE URL IN THE SITEMAP


5 Open the console and browse to the node
/hst:myproject/hst:configurations/myproject/hst:sitemap

6 Add a new node called about of type hst:sitemapitem

7 Add a String property (CTRL+P) to the about node called


hst:componentconfigurationid and enter the value hst:pages/contentpage

8 Add another String property to the about node called


hst:relativecontentpath and enter the value service/about-us.

9 Save these changes by clicking the "Write changes repository" button


(Ctrl+S)

SITEMAP: You have now created a new URL /about in the sitemap.
CONTENT: the sitemap item points to the About Us document for content using
relativecontentpath.
STRUCTURE: the sitemap item uses the hst:pages/contentpage page template to
display it.

10 On the Experience Manager, click the ‘show container and component


overlays’ button.
It’s in the top-right, the icon looks like a few rectangles.
Click the edit menu button, It has a chain-link icon.

11 Edit the menu. Add a new item called "About".


Select "internal link" and use the Select button to select the About Us
document.
Click “Save”.

12 Click the “Done” button to close the menu editor and publish the changes
of the channel.

13 Verify in the site that the About menu item brings you to the /about URL in
the site.
Check if you can see that the About us document is rendered in full.
Can you explain what happened?
EXERCISE 8.
ADD A TWO COLUMNS PAGE
CONFIGURATION
You previously created the About Us page with a one column layout.
In this exercise, we will give the webmaster users the option to add additional
components on a new container on the right hand side of the page.

1 Go to the node
/hst:myproject/hst:configurations/myproject/hst:pages/contentpage
This node defines the content page template.
Using a property hst:referencecomponent, it inherits from the base
abstract page.
It has a child node, named “main” of primary type
hst:containercomponentreference.
We will use this main node as one of the two columns.
Right-click on the main node, and rename the main node “left”.

2 Change its property hst:referencecomponent to contentpage/left.


You will notice a blue message (Reference not found. Might be used in inheriting
structure though.)

This is not a problem, we have just not created that container reference
yet.

3 Add a sibling to “left” onto the contentpage node.


Name it “right”, with primary type hst:containercomponentreference.
On the right node, add a new property hst:referencecomponent with value
contentpage/right

4 The structure of the main part of the contentpage will change now.
Instead of just having one element main with no child components that
shows the content, we will have two nodes, left and right, to show content.
This drawing shows the change you are making.
Header

Main: showing Left: Right


the content showing
details the
content

Footer

Now we have to create the containers referenced by our page structure.


This should remove the blue info message mentioned in step 2.

5 Browse to the following node:


/hst:myproject/hst:configurations/myproject/hst:workspace/hst:cont
ainers/contentpage

6 Rename the node main to left

7 Under the contentpage container node, add a new node of type


hst:containercomponent called right

8 On the CMS, browse to the Experience Manager and check your changes.
What happened? Inspect App.tsx on your React application and try to
figure out.

9 As you probably noticed, our React app uses the path main to render our
main content area, but we just changed that. We need to adjust the react
code.

Add the following piece of code after the main BrComponent rendering:
<div className="row">
<div className="column">
<BrComponent path="left" />
</div>
<div className="column">
<BrComponent path="right" />
</div>
</div>

10 Open react/src/index.css and add some styling to it:


.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
}

.column {
display: flex;
flex-direction: column;
flex: 1;
}

11 Check the About page in the Experience Manager.


Did everything work as you expected?
How about on localhost:3000/about?
HINT: you may need to delete the -preview node in the console interface to
refresh the experience manager view..
COPYRIGHT © 2024 BLOOMREACH
B.V.
Unless otherwise indicated, all materials on these pages are copyrighted by
Bloomreach B.V.

All rights reserved. No part of these pages, either text or image may be used for
any purpose other than its original intent.

Reproduction, modification, storage in a retrieval system or retransmission, in any


form or by any means, electronic, mechanical or otherwise, for reasons other than
its original intent, is strictly prohibited without prior written permission.

You might also like