The following has evaluated to null or missing:
==> .vars['reserved-article-group-id'] [in template "161555#161602#ARTICLE-PAGE---HERO" at line 14, column 20]
----
Tip: It's the final [] step that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: #assign groupId = .vars["reserved-art... [in template "161555#161602#ARTICLE-PAGE---HERO" at line 14, column 1]
----
1<#assign namespace = randomNamespace />
2<#assign JSONFactoryUtil = staticUtil["com.liferay.portal.kernel.json.JSONFactoryUtil"] />
3<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
4<#assign containerId = randomNamespace />
5<#assign shareURL = themeDisplay.getPortalURL()+themeDisplay.getURLCurrent()/>
6
7<#-- Auto-assign ALL category to every article -->
8<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService") />
9<#assign assetEntryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") />
10<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
11
12<#-- Get current JournalArticle -->
13<#assign articleId = .vars['reserved-article-id'].data />
14<#assign groupId = .vars['reserved-article-group-id'].data?number />
15<#assign journalArticle = journalArticleLocalService.getArticle(groupId, articleId) />
16
17<#-- Get AssetEntry for this article -->
18<#assign assetEntry = assetEntryLocalService.getEntry("com.liferay.journal.model.JournalArticle", journalArticle.getResourcePrimKey()) />
19
20<#-- Your ALL category ID -->
21<#assign allCategoryId = 4614994 />
22
23<#-- Assign ALL category if not already set -->
24<#if !assetEntry.getCategories()?seq_contains(assetCategoryLocalService.getCategory(allCategoryId))>
25 <#assign categoryIds = assetEntry.getCategoryIds() + [allCategoryId] />
26 ${assetEntryLocalService.updateEntry(
27 assetEntry.getUserId(),
28 assetEntry.getGroupId(),
29 assetEntry.getClassName(),
30 assetEntry.getClassPK(),
31 assetEntry.getUuid(),
32 assetEntry.getClassTypeId(),
33 categoryIds,
34 assetEntry.getTagNames()
35 )}
36</#if>
37
38<div class="hero jmarticle__hero-main-container">
39 <div class="container">
40 <div class="row">
41 <div class="article__cont">
42 <h1 class="article__heading">${Title.getData()}</h1>
43 <#if (SubTitle.getData())??>
44 <p class="article__para">
45 ${SubTitle.getData()}
46 </p>
47 </#if>
48
49 <#assign Date_Data=getterUtil.getString(Date.getData())>
50 <#if validator.isNotNull(Date_Data)>
51 <p class="article__date">
52 <#assign Date_DateObj=dateUtil.parseDate("yyyy-MM-dd", Date_Data, locale)>
53 ${dateUtil.getDate(Date_DateObj, "dd MMMM yyyy", locale)}
54 </p>
55 </#if>
56
57 <#if Link_Title?? && Link_Title.getData()?has_content>
58 <#list Link_Title.getSiblings() as cur_Link_Title>
59 <#if cur_Link_Title?? && cur_Link_Title.getData()?has_content>
60 <#assign linkHref="#" />
61 <#assign target="" />
62
63 <#assign rowId = containerId + cur_Link_Title?index />
64 <#if cur_Link_Title.Link_Internal?? && cur_Link_Title.Link_Internal.getFriendlyUrl()?has_content>
65 <#assign linkHref=cur_Link_Title.Link_Internal.getFriendlyUrl() />
66 <#elseif cur_Link_Title.Link_Media?? && cur_Link_Title.Link_Media.getData()?has_content>
67 <#assign linkHref=cur_Link_Title.Link_Media.getData() />
68 <#elseif cur_Link_Title.Link_Mailto?? && cur_Link_Title.Link_Mailto.getData()?has_content>
69 <#assign linkHref="mailto:" + cur_Link_Title.Link_Mailto.getData() />
70 <#elseif cur_Link_Title.Link_External?? && cur_Link_Title.Link_External.getData()?has_content>
71 <#assign linkHref=cur_Link_Title.Link_External.getData() />
72 </#if>
73 <#if (cur_Link_Title.Link_Target??) && (cur_Link_Title.Link_Target.getData())?has_content>
74 <#assign target=cur_Link_Title.Link_Target.getData() />
75 </#if>
76 <div id="blue_button_click_div" data-analytics-asset-type="custom">
77 <div class="jmarticle__hero-btn-list">
78 <a id="panel_blue_button_${rowId}" class="article__btn" href="${linkHref}" title="${cur_Link_Title.getData()}" target="${target}" data-analytics-asset-action="click" onclick="onBlueButtonClick(this)" >
79 <span class="btn__text">${cur_Link_Title.getData()}</span>
80 <span class="arrow__forward"></span>
81 </a>
82 </div>
83 </div>
84 </#if>
85 </#list>
86 </#if>
87 <div class="article-download-share">
88
89 <#if PDFTitle?? && PDFTitle.getData()?has_content>
90 <#assign title = PDFTitle.getData() />
91 <#assign pdf_link = "#" />
92 <#assign pdfrowId = containerId />
93 <#if PDFTitle.PDF?? && PDFTitle.PDF.getData()?has_content>
94 <#assign pdf_link = PDFTitle.PDF.getData() />
95 </#if>
96 <div class="article-download">
97 <div id="blue_button_click_div" data-analytics-asset-type="custom">
98 <div class="jmarticle__hero-btn-list">
99 <a id="panel_blue_button_${pdfrowId}" class="article__btn" href="${pdf_link}" title="${title}" data-analytics-asset-action="click" onclick="onBlueButtonClick(this)">
100 <span class="btn__text">${title}</span>
101 <span class="arrow__forward"></span>
102 </a>
103 <a id="panel_blue_button_${pdfrowId}" class="article__btn-mobile" href="${pdf_link}" title="${title}" data-analytics-asset-action="click" onclick="onBlueButtonClick(this)">
104 <img src="${themeDisplay.getPathThemeImages()}/new__jm__images/download-white-icon.svg" alt="twitter image"/>
105 </a>
106 </div>
107 </div>
108 </div>
109 </#if>
110
111 </div>
112
113 </div>
114 </div>
115 <#if (ImageLarge.getData())?? && ImageLarge.getData() != "">
116 <div class="row jmarticle__hero-banner" id="jmarticle__hero-${namespace}"
117 style="background-image: url(${ImageLarge.getData()})">
118 </#if>
119
120 </div>
121 </div>
122</div>
123
124<#if Author?? && Author.getData()?has_content>
125 <div class="jmarticle__author-info">
126 <div class="container">
127 <div class="hero__bar">
128 <#list Author.getSiblings() as cur_Author>
129 <#if cur_Author?? && cur_Author.getData()?has_content>
130 <#assign
131 webContentData = jsonFactoryUtil.createJSONObject(cur_Author.getData())
132 gId = groupId
133 journalArticle = journalArticleLocalService.getArticleByUrlTitle(gId, webContentData.title)
134 docXML = saxReaderUtil.read(journalArticle.getContent())
135
136 fName = docXML.valueOf("//dynamic-element[@name='FullName']/dynamic-content/text()")
137 jobTitle = docXML.valueOf("//dynamic-element[@name='JobTitle']/dynamic-content/text()")
138 role = docXML.valueOf("//dynamic-element[@name='ContactInfo']/dynamic-content/text()")
139 photoXML = docXML.valueOf("//dynamic-element[@name='Photo']/dynamic-content/text()")
140 photoSrc = JSONFactoryUtil.createJSONObject(photoXML).getString("uuid")
141 fullName = docXML.valueOf("//dynamic-element[@name='Title']/dynamic-content/text()")
142 authorImageXML = docXML.valueOf("//dynamic-element[@name='ImageLarge']/dynamic-content/text()")
143 authImageSrc = JSONFactoryUtil.createJSONObject(authorImageXML).getString("uuid")
144 summary = docXML.valueOf("//dynamic-element[@name='Summary']/dynamic-content/text()")
145 />
146
147 <div class="author">
148 <figure class="author__image">
149 <#if authImageSrc?? && authImageSrc?has_content>
150 <img src="/documents/${groupId}/${authImageSrc}" alt="${fullName}" class="author_img_class_new">
151 <#elseif photoSrc?? && photoSrc?has_content>
152 <img src="/documents/${groupId}/${photoSrc}" alt="${fName}" class="author_img_class_new">
153 </#if>
154 </figure>
155 <div class="author__details d-flex flex-column">
156 <h3 class="author__name">
157 <a rel="author">
158 <#if fullName?? && fullName?has_content>
159 ${fullName}
160 <#elseif fName?? && fName?has_content>
161 ${fName}
162 </#if>
163 </a>
164 </h3>
165 <p class="author__desc text-size-a author_job_title">
166 <#if jobTitle?? && jobTitle?has_content>
167 ${jobTitle}
168 </#if>
169 </p>
170 <span>
171 <p class="author__desc text-size-a">
172 <#if summary?? && summary?has_content>
173 ${summary}
174 </#if>
175 <#if role?? && role?has_content>
176 ${role}
177 </#if>
178 </p>
179 </span>
180 </div>
181 <div>
182 <div class="author__contact">
183 <ul class="author__contact-list">
184 </ul>
185 </div>
186 </div>
187 </div>
188 </#if>
189 </#list>
190 </div>
191 </div>
192 </div>
193</#if>
194
195
196
197<div class="container">
198 <div class="row">
199 <div class="article__intro">
200 <#if (Introduction.getData())??>
201 ${Introduction.getData()}
202 </#if>
203
204 <div class="article-download-share">
205
206 <#if PDFTitle?? && PDFTitle.getData()?has_content>
207 <#assign title = PDFTitle.getData() />
208 <#assign pdf_link = "#" />
209 <#assign pdfrowId = containerId />
210 <#if PDFTitle.PDF?? && PDFTitle.PDF.getData()?has_content>
211 <#assign pdf_link = PDFTitle.PDF.getData() />
212 </#if>
213 <div class="article-download">
214 <div id="blue_button_click_div" data-analytics-asset-type="custom">
215 <div class="jmarticle__hero-btn-list">
216 <a id="panel_blue_button_${pdfrowId}" class="article__btn" href="${pdf_link}" title="${title}" data-analytics-asset-action="click" onclick="onBlueButtonClick(this)">
217 <span class="btn__text">${title}</span>
218 <span class="arrow__forward"></span>
219 </a>
220 <a id="panel_blue_button_${pdfrowId}" class="article__btn-mobile" href="${pdf_link}" title="${title}" data-analytics-asset-action="click" onclick="onBlueButtonClick(this)">
221 <img src="${themeDisplay.getPathThemeImages()}/new__jm__images/download-white-icon.svg" alt="twitter image"/>
222 </a>
223 </div>
224 </div>
225 </div>
226 </#if>
227
228
229 <div class="article-share">
230 <a href="https://linkedin.com/shareArticle?url=${shareURL}&title=<#if (Title.getData())??>${Title.getData()}</#if>" target="_blank">
231 <img class="socialicons__img" src="${themeDisplay.getPathThemeImages()}/new__jm__images/social_icons-LinkedIN.png" alt="twitter image"/>
232 </a>
233 <a href="https://twitter.com/share?url=${shareURL}&text=<#if (Title.getData())??>${Title.getData()}</#if>" target="_blank">
234 <img class="socialicons__img" src="${themeDisplay.getPathThemeImages()}/new__jm__images/social_icons-Twitter.png" alt="twitter image"/>
235 </a>
236 </div>
237 </div>
238
239 </div>
240 </div>
241</div>
242
243<style>
244 img.author_img_class_new {
245 width: 100% !important;
246 height: 100% !important;
247 position: absolute;
248 margin: auto;
249 top: 0;
250 bottom: 0;
251 }
252
253 .article__btn:focus-visible {
254 outline: 2px solid blue !important;
255}
256
257@media (min-width: 320px) and (max-width: 650px) {
258 .article__intro li {
259 margin-left: -32px !important;
260 }
261 .journal-content-article .container .article__intro {
262 margin-top: 22px !important;
263}
264}
265@media (min-width: 540px) and (max-width: 834px) {
266 .article__intro li {
267 margin-left: -32px !important;
268 }
269 .article__intro {
270 margin: 60px 15px 0 5px !important;
271 }
272}
273
274@media (min-width: 320px) and (max-width: 539px){
275.jmarticle__author-info {
276 padding: 0px 0;
277}
278.jmarticle__author-info .author__image {
279 width: 39px;
280 height: 40px;
281}
282
283.jmarticle__author-info .author__name a {
284 line-height: 0px;
285 font-size: 18px !important;
286 margin-right: 10px;
287}
288
289.jmarticle__author-info .author__desc {
290
291 line-height: 14px;
292 font-size: 12px !important;
293 margin-bottom: 7px;
294}
295}
296
297</style>
Today, Johnson Matthey will hold a Capital Markets Day in which it will provide an update on its strategy for sustained growth and value creation, at a group level and across its sectors. This growth is underpinned by use of our world class science to address challenges posed by fundamental global trends including climate change, energy transition, population and longevity and resource challenges. Johnson Matthey has leading positions in high margin, technology driven growth markets and the company expects to deliver attractive and sustainable growth and returns over the medium term:
- Delivering mid to high single digit EPS CAGR
- Expanding group ROIC to 20%, and
- Continuing a progressive dividend
Clean Air: sustained growth for the next decade
Our Clean Air business will deliver mid single digit growth in operating performance to 2025 and sustained growth for the next decade. In the early years, we expect good growth as we start to see benefits from new legislation in Asia and tighter legislation in Europe. Over the medium term, we expect growth to accelerate with the full benefits of the new legislation in China and India coming through, which will more than double the size of our Asian business. In the longer term, growth is expected to moderate assuming penetration of pure battery electric vehicles increases substantially.
Efficient Natural Resources: growth accelerating and guidance upgraded
In Efficient Natural resources, we have undergone a period of restructuring, reorganisation and investment in R&D which has improved efficiency and built the platform for growth. These changes and the commercialisation of new technologies as we move into adjacent areas will drive higher growth for the overall sector. This gives us confidence in upgrading our financial guidance, to deliver mid to high single digit growth in operating performance to 2025.
Health: platform built for breakout growth, passed the point of inflection
We have made strong progress on operational improvements in Health and our increased investment has built a deeper and broader pipeline of new products. The business is now passed the inflection point and we are confident of delivering breakout growth with an additional £100m of operating profit from our generic and innovator pipeline by 2025.
New Markets: strong progress in Battery Materials
In New Markets, we are focused on Battery Materials and have made strong progress to commercialise eLNO®, our portfolio of next generation, ultra-high energy density cathode materials. Customer feedback from testing remains positive, in particular our ability to provide customised solutions and we have now moved to full cell testing with two customers. We expect our first commercial plant to be on stream in 2022 and to be supplying platforms in production in 2024. Our total investment when we have commercial production from our plant will amount to circa £350m.
Efficiencies remain a strong focus
We remain focused on building a more efficient business to strengthen our platform for growth and increase our agility. Today we commit to a further £40m in procurement savings over three years beginning 2020/21, giving total group savings announced of £145m since 2017/18. Of the additional £40m, two thirds will benefit the income statement and at least half will be reinvested.
Expanding return on invested capital to 20%
In order to deliver sustainable growth and value creation across the group and our sectors, we are investing in a number of strategic growth projects. The growth capex comprises spend on our new Clean Air plants in Poland, China and India, the commercialisation of eLNO, modernisation of our refineries in Efficient Natural Resources and upgrades to our IT systems. In future, maintenance capex will continue to be c.0.8-0.9x depreciation and we will further invest in strategic projects if they meet our disciplined investment criteria.
We continue to have a disciplined approach to our working capital position. We are targeting an improvement in non precious metal working capital to 50 days over the medium term, and expect to deliver £350m of savings in precious metal working capital, comprising £250m in backlog reduction and a further £100m of refinery efficiencies.
Over the medium term, these investments and the growth and efficiency they will generate give us confidence in expanding our ROIC to 20%.
Outlook unchanged for first half and full year 2019/20
Our group guidance, at constant rates, for the first half and the year ended 31st March 2020 remains unchanged. We expect growth in operating performance at constant rates to be within our medium term guidance of mid to high single digit growth.
- In terms of phasing, we expect performance to be more heavily weighted to the second half
- By sector, Clean Air performance is expected to be slightly below the prior year. This is expected to be compensated by better performance in Efficient Natural Resources driven by actions taken to improve efficiency, and other ongoing efficiencies across the group
We continue to expect capex of up to £500m in the fiscal year 2019/20.
At current foreign exchange rates (£:$ 1.218, £:€ 1.104, £:RMB 8.71) translational foreign exchange movements for the year ending 31st March 2020 are expected to benefit sales by £128 million and underlying operating profit by £21 million.
Commenting on the capital markets day, Robert MacLeod, Chief Executive said:
“Everything we do at Johnson Matthey is about helping to create a world that is cleaner and healthier. We apply our world class science to address key global challenges, solving our customers’ most challenging and increasingly complex problems. We are delivering on our strategy and will continue to execute with determination. As the world changes ever faster, we are increasingly excited by the significant opportunities we see for sustained growth and value creation.”