Hiroshima - Japan Travel Guide - Japanspecialist
An error occurred while processing the template.
The following has evaluated to null or missing: ==> image.getAttribute('alt') [in template "20098#20124#DESTINATION" at line 148, column 68] ---- 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: ${image.getAttribute("alt")?js_string... [in template "20098#20124#DESTINATION" at line 148, column 66] ----
1<!-- Destination detail FTL -->
2
3<#assign envSettings = vtaLibrary.getEnvSettings()>
4<#assign vocDestTypenId = envSettings.vocDestTypenId?number>
5<#assign vocDestLocationId = envSettings.vocDestLocationId?number>
6<#assign urlHelper = vtaLibrary.getUrlHelper()>
7<#assign toursFilterListingUrl = urlHelper + vtaLibrary.getLayoutUrlByCategoryName("Tour filter results listing")>
8
9
10<#-- check disabled -->
11<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")>
12<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService") />
13<#assign journalArticleResourceLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleResourceLocalService") />
14<#assign thisJournalArticleId = .vars['reserved-article-id'].data>
15<#assign thisArticleResourcePK = journalArticleResourceLocalService.getArticleResourcePrimKey(groupId,thisJournalArticleId)/>
16<#assign thisCategoryList=assetCategoryLocalService.getCategories("com.liferay.journal.model.JournalArticle",thisArticleResourcePK) >
17<#assign vocAviabilityId = envSettings.vocAviabilityId>
18<#assign thisJournalArticle = journalArticleLocalService.fetchArticle(groupId?number, thisJournalArticleId?string)>
19<#assign thisJournalArticleDefaultLanguageId = thisJournalArticle.getDefaultLanguageId()>
20<#assign thisJournalArticleRPK = thisJournalArticle.getResourcePrimKey()>
21
22<#-- set MAIN IMAGE & GALLERY-->
23<#assign thisMainImage = MainImage>
24<#assign thisGallerList = GalleryImage.getSiblings()>
25
26
27<#-- parse categories -->
28<#assign thisDestinationType = "none">
29<#assign isDisabled = false>
30<#list thisCategoryList as category>
31 <#assign curCatVocId = category.vocabularyId?string>
32 <#-- check Aviability state -->
33 <#if curCatVocId = vocAviabilityId?string>
34 <#if category.getTitle("en_US") = "Disabled">
35 <#assign isDisabled = true>
36 </#if>
37 <#elseif curCatVocId = vocDestTypenId?string>
38 <#assign thisDestinationType = category.getTitle(thisJournalArticleDefaultLanguageId)>
39 <#elseif curCatVocId = vocDestLocationId?string>
40 <#assign thisCountryCat = category>
41 </#if>
42</#list>
43
44<#-- get location tree & country & region & prefecture -->
45<#if thisCountryCat??>
46 <#assign thisLocationTree = []>
47 <#assign thisLocationIdTree = []>
48 <#assign thisTree = thisCountryCat.getTreePath()>
49 <#list thisTree?split("/") as cur_step>
50 <#if cur_step !="">
51 <#assign thisLocationTree = thisLocationTree + [assetCategoryLocalService.fetchCategory(cur_step?number).getTitle(thisJournalArticleDefaultLanguageId)]>
52 <#assign thisLocationIdTree = thisLocationIdTree + [assetCategoryLocalService.fetchCategory(cur_step?number).getCategoryId()]>
53 </#if>
54 </#list>
55</#if>
56<#assign thisCountry = (thisLocationTree[0]??)?then(thisLocationTree[0],"none")>
57<#assign thisRegion = (thisLocationTree[1]??)?then(thisLocationTree[1],"none")>
58<#assign thisPrefecture = (thisLocationTree[2]??)?then(thisLocationTree[2],"none")>
59<!-- ${thisJournalArticle} -->
60
61<#-- set globals for rest widgets on this tour page -->
62<#if thisLocationIdTree?size != 0>
63 <#assign tempString = thisLocationIdTree?join(",")>
64<#else>
65 <#assign tempString = "">
66</#if>
67<!-- SET DESTINATION LOCATION SCOPE ID: "${tempString}" ${request.setAttribute("DEST_LOCATION_SCOPE_ID", "${tempString}")} -->
68<!-- SET DESTINATION ARTICLE ID: "${thisJournalArticleId}" ${request.setAttribute("DEST_ARTICLE_ID", "${thisJournalArticleId}")} -->
69
70
71<#if !isDisabled>
72 <#-- emebed LG resources to the html top -->
73 <@vtaLibrary.lightGalleryInjectTop/>
74
75 <#-- fake breadcrumbs -->
76 <div class="-marginBottom-1">
77 <@printFakeBreadcrumbs/>
78 </div>
79
80 <div id="page-wrapper" class="-Destination -Destination--typeDetail" data-pagetype="destination">
81 <div class="-Destination-inner">
82 <div class="-Destination-head">
83 <header class="-Header -Header--typeH1">
84 <h1 class="-Heading -Heading--typeH1 -Header-heading">${ScreenName.getData()}</h1>
85 <p class="-Subheading -Header-subheading">
86 ${ShortDescription.getData()}
87 </p>
88 </header>
89 </div>
90 <#if themeDisplay.isSignedIn()>
91 <p>
92 <button id="masterButton">Master Data Html</button>
93 <button id="masterButtonWord">Master Data Word DOC</button>
94 </p>
95 <@setmasterData />
96 </#if>
97 <div class="-Destination-body">
98
99 <!-- gray section/ -->
100 <div class="-Section -Section--verticalSpacingMedium -Section--verticalIndentMedium -fullBleed -skin-tertiaryBare">
101 <div class="-Section-inner">
102 <div class="-Container -Container--typeNestedPreserve">
103 <div class="-Tour-card">
104
105
106 <!-- gallery -->
107 <#assign gallerySize = thisGallerList?size + 1>
108 <div class="-GalleryWrapper">
109 <div class="-Gallery -Gallery--typeTile" id="-Gallery">
110 <#-- first big-->
111 <span class="-Gallery-item" data-media-count="${gallerySize} ${translationsUtils.getMessage(locale,'vta.webcontent.photos')}">
112 <img alt="${thisMainImage.getAttribute('alt')}" src="${vtaLibrary.getAdaptiveImageUrl(thisMainImage, 'large')}">
113 </span>
114 <#-- first four from gallery -->
115 <#list thisGallerList as image>
116 <#if image?index lt 4>
117 <span class="-Gallery-item" data-media-count="${gallerySize} ${translationsUtils.getMessage(locale,'vta.webcontent.photos')}">
118 <img loading="lazy" alt="${image.getAttribute('alt')}" src="${vtaLibrary.getAdaptiveImageUrl(image, 'medium')}">
119 </span>
120 </#if>
121 </#list>
122 </div>
123 <script>
124 const lgContainer = document.getElementById('-Gallery');
125 const lgItems = lgContainer.querySelectorAll('.-Gallery-item');
126 const lgGallery = lightGallery(lgContainer, {
127 licenseKey: '9N5TA-AWA8R-H9ZLD-GCJBW',
128 plugins: [lgZoom, lgThumbnail, lgHash],
129 container: '#wrapper',
130 dynamic: true,
131 dynamicEl: [{
132 src: '${vtaLibrary.getAdaptiveImageUrl(thisMainImage, 'big')}',
133 <#--
134 sources: '[{"srcset": "${vtaLibrary.getAdaptiveImageUrl(thisMainImage, 'big')}", "media": "(min-width:1280px)"}, {"srcset": "${vtaLibrary.getAdaptiveImageUrl(thisMainImage, 'medium')}", "media": "(min-width:640px)"}]',
135 -->
136 thumb: '${vtaLibrary.getAdaptiveImageUrl(thisMainImage, 'small')}',
137 subHtml: '<p>${thisMainImage.getAttribute('alt')?js_string!""}</p>'
138 }
139
140 //<#if thisGallerList?size gt 0>
141 // <#list thisGallerList as image>
142 , {
143 src: '${vtaLibrary.getAdaptiveImageUrl(image, 'big')}',
144 <#--
145 sources: '[{"srcset": "${vtaLibrary.getAdaptiveImageUrl(image, 'big')}", "media": "(min-width:1280px)"}, {"srcset": "${vtaLibrary.getAdaptiveImageUrl(image, 'medium')}", "media": "(min-width:640px)"}]',
146 -->
147 thumb: '${vtaLibrary.getAdaptiveImageUrl(image, 'small')}',
148 subHtml: '<p>${image.getAttribute('alt')?js_string!""}</p>'
149 }
150 // </#list>
151 //</#if>
152 ],
153 selector: '.-Gallery-item',
154 download: false,
155 speed: 500,
156 thumbnail: true,
157 mobileSettings: {
158 controls: false,
159 showCloseIcon: true,
160 download: false
161 }
162 });
163 lgItems.forEach(function (item, index) {
164 item.addEventListener("click", function () {
165 lgGallery.openGallery(index);
166 });
167 });
168 </script>
169 </div>
170 <!-- /gallery -->
171
172
173
174
175
176 <!-- right panel -->
177 <div class="-Panel -Panel--typeFlyer -Tour-panel">
178 <div class="-boxLayout" data-space="3">
179 <div class="-stackLayout" data-space="1" data-splitafter="1">
180 <div>
181 <strong>
182 <span class="-clusterLayout" data-space="02" data-nowrap="true">
183 <span>
184 <span><i class="-Icon -Icon--tour-type"></i></span>
185 <span> ${thisDestinationType} </span>
186 </span>
187 </span>
188 </strong>
189 <hr class="-Hr -Hr--skinTertiaryBare -Panel-hr">
190 <div class="-stackLayout" data-space="03">
191 <div>
192 <strong>
193 <span class="-clusterLayout" data-space="02" data-nowrap="true">
194 <span>
195 <span><i class="-Icon -Icon--location-2"></i></span>
196 <span> ${translationsUtils.getMessage(locale,'vta.common.labels.location')} </span>
197 </span>
198 </span>
199 </strong>
200 </div>
201 <div>
202 <div class="-clusterLayout" data-space="02" data-nowrap="true">
203 <div>
204 <div>
205 <i class="-Icon -Icon--location-2 -visuallyHidden"></i>
206 </div>
207 <div class="-stackLayout" data-space="05">
208 <#if thisCountry != "none">
209 <div class="-textSize-small"> ${translationsUtils.getMessage(locale,'vta.common.labels.country')}: ${thisCountry} </div>
210 </#if>
211 <#if thisRegion != "none">
212 <div class="-textSize-small"> ${translationsUtils.getMessage(locale,'vta.common.labels.region')}: ${thisRegion} </div>
213 </#if>
214 <#if thisPrefecture != "none">
215 <div class="-textSize-small"> ${translationsUtils.getMessage(locale,'vta.common.labels.prefecture')}: ${thisPrefecture} </div>
216 </#if>
217 </div>
218 </div>
219 </div>
220 </div>
221 </div>
222 </div>
223 <div class="-stackLayout -textJustifyCenter" data-space="02">
224 <span class="-textSize-small"><strong>${translationsUtils.getMessage(locale,'vta.webcontent.ready.to.experience.this.incredible.destination')}</strong></span>
225 <span class="-textSize-small -colorSecondaryPale">${translationsUtils.getMessage(locale,'vta.webcontent.destination.ready.to.experience.paragraph')}</span>
226 <#-- <span class="-textSize-small"><strong>Ready to experience this incredible destination?</strong></span>
227 <span class="-textSize-small -colorSecondaryPale">We offer a range of expertly designed tours, from cultural immersions and scenic explorations to culinary adventures and off-the-beaten-path experiences.</span>
228 <span class="-textSize-small -colorSecondaryPale"> Discover all our tours featuring this destination and start planning your adventure today.</span> -->
229 <a class="-Button -Button--sizeLarge -Button--typePrimary -width-stretch"
230 href='${toursFilterListingUrl}?f%5Bdata-tdest%5D=${thisJournalArticleRPK}'>${translationsUtils.getMessage(locale,'vta.webcontent.view.tours')}</a>
231 </div>
232 </div>
233 </div>
234 </div>
235 <!-- /right panel -->
236 </div>
237 </div>
238 </div>
239 </div>
240 <!-- /gray section -->
241
242 <div class="-Section -Destination-section -Destination-section--typeDescription -gridLayout" data-fragment-md="2of3">
243 <div class="-Section-inner">
244 <div class="-maxWidth-colspan8 -htmlElements">
245 ${Description.getData()}
246 </div>
247 </div>
248 </div>
249 <div class="mb-5"></div>
250 </div>
251 </div>
252 </div>
253
254 <script>
255 AUI().ready(
256 function() {
257 const lgContainer = document.getElementById('-DestinationGallery');
258 lightGallery(lgContainer, {
259 licenseKey: '9N5TA-AWA8R-H9ZLD-GCJBW',
260 plugins: [lgZoom, lgThumbnail, lgHash],
261 selector: '.-Gallery-item',
262 container: '#wrapper',
263 download: false,
264 speed: 500,
265 thumbnail: true,
266 mobileSettings: {
267 controls: false,
268 showCloseIcon: true,
269 download: false
270 }
271 });
272
273 }
274 );
275
276 var rescroll = function() {
277 var assetAnchor = document.querySelector("body:not(.has-control-menu) [id*=portlet_com_liferay_asset_publisher_] .asset-anchor");
278 if( assetAnchor ) {
279 assetAnchor.scrollIntoView();
280 }
281 document.removeEventListener('scroll', rescroll);
282 }
283 document.addEventListener('scroll', rescroll);
284 </script>
285
286<#else>
287 <#-- disabled only -->
288 <p>This Destination is disabled to display.</p>
289 <@liferay_util["html-top"] outputKey="disable-destination">
290 <meta name="robots" content="noindex,nofollow">
291 </@>
292</#if>
293
294<#-- Macros/Functions -->
295
296
297<#macro printFakeBreadcrumbs >
298 <#-- read expandos -->
299 <#-- <#assign group = themeDisplay.getSiteGroup() > -->
300 <#-- <#assign curPageLayout = themeDisplay.getLayout()> -->
301 <#-- <#assign expando = curPageLayout.getExpandoBridge()> -->
302 <#assign fakeParentUrl = vtaLibrary.getLayoutUrlByCategoryName("Destination listing")>
303
304 <#local layoutLocalService = serviceLocator.findService("com.liferay.portal.kernel.service.LayoutLocalService")>
305 <#-- <#assign pageLayoutId = (page.getData()?eval["layoutId"]?number)> -->
306 <#local pageLayout = layoutLocalService.fetchLayoutByFriendlyURL(groupId, false, fakeParentUrl)!"">
307 <#if pageLayout != "">
308 <#local parentLayouts = pageLayout.getAncestors()>
309 <#local allLayouts = parentLayouts + [pageLayout]>
310 </#if>
311 <div class="-marginBottom-1">
312 <div class="-Nav -Nav--typeBreadcrumb -clusterLayout" data-space-breadcrumb="1">
313 <ul class="-Nav-list">
314 <@printBradcrumbItem "Japanspecialist" urlHelper+"/"/>
315 <#if allLayouts??>
316 <#list allLayouts as cur_item>
317 <@printBradcrumbItem cur_item.getName(locale) urlHelper+cur_item.getFriendlyURL()/>
318 </#list>
319 </#if>
320 <@printBradcrumbItem ScreenName.getData() />
321 </ul>
322 </div>
323 </div>
324</#macro>
325
326<#macro printBradcrumbItem name url="">
327 <li class="-Nav-item">
328 <div class="-Nav-itemContents">
329 <#if url !="">
330 <a class="-Nav-link" href="${url}">
331 <span class="-Nav-linkContents">
332 <span class="-Nav-linkContent">
333 ${name}
334 </span>
335 </span>
336 </a>
337 <#else>
338 ${name}
339 </#if>
340 </div>
341 </li>
342</#macro>
343
344
345
346
347
348<#-- embed liferay webcontent (banners) -->
349<#macro embedWc WcId subjectName>
350
351 <#assign
352 JournalArticleService = serviceLocator.findService("com.liferay.journal.service.JournalArticleService")
353 serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()
354 group_id = themeDisplay.getScopeGroupId()?number
355 journalArticle = JournalArticleService.getArticle(group_id, WcId)
356 temp = serviceContext.setAttribute("subject_name", "${subjectName}")
357 />
358 <@liferay_journal["journal-article"]
359 articleId=journalArticle.getArticleId()
360 <#-- ddmTemplateKey="xxxxxxx" -->
361 ddmTemplateKey=journalArticle.getDDMTemplateKey()
362 groupId=journalArticle.getGroupId()
363 wrapperCssClass="gtm-DestinationDetail"
364 />
365</#macro>
366
367
368<#-- print a "featured in" card -->
369<#macro printCard wcData cardInex>
370 <#-- <#local webContentData = jsonFactoryUtil.createJSONObject(tourData.getData()))/> -->
371 <#-- used for back compatibility, for new usage apply commented line above (object type templateNode): -->
372 <#local webContentData = jsonFactoryUtil.createJSONObject(wcData.get("data"))>
373 <#if webContentData.classPK??>
374 <#attempt>
375 <#local classPK = webContentData.classPK?number!""
376 journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")
377 journalArticle = journalArticleLocalService.getLatestArticle(classPK)!"none"
378 structureId = journalArticle.getDDMStructureId()?string
379 template = vtaLibrary.getTemplateForStructure(structureId,"card")
380 />
381 <#recover>
382 <#local classPK = webContentData.classPK?number!""
383 journalArticle = "none"
384 structureId = "none"
385 template = vtaLibrary.getTemplateForStructure(structureId,"card")
386 />
387 </#attempt>
388 <!-- structure: ${structureId}, template: ${template} -->
389 <#if journalArticle = "none">
390 <!-- BIG ERROR -->
391 <!-- ${webContentData} -->
392 <#elseif journalArticle.status != 3><#-- article is publicated and non expired -->
393
394 <#attempt>
395 <#local thisCode><#-- render an article to string -->
396 <@liferay_journal["journal-article"]
397 articleId=journalArticle.getArticleId()
398 ddmTemplateKey="${template}"
399 groupId=journalArticle.getGroupId()
400 />
401 </#local>
402 <#recover><#-- if render failed -->
403 <#local thisCode>
404 <p>something wrong with this tour:</p>
405 <p>${journalArticle.urlTitle} status: ${journalArticle.status}</p>
406 </#local>
407 </#attempt>
408 <#-- print article if is not disabled -->
409 <#if thisCode?contains('data-tour-state="disabled"')>
410 <!-- tour is DISABLED: ${journalArticle.getTitle()} -->
411 <#else>
412 <div class="-ContentsLayout-content -ContentsLayout-content--size4">
413 <div class="-Tour -Tour--typePreview -Tour--typePreviewMain -TourGroup-tour">
414 ${thisCode}
415 </div>
416 </div>
417 </#if>
418 <#else><#-- article IS expired -->
419 <!-- Card ${cardInex+1}: Tour ${journalArticle.urlTitle} is Expired -->
420 </#if>
421 <#else><#-- article has not a classPK -->
422 <!-- Card ${cardInex+1}: empty, wrong or missing data -->
423 </#if>
424
425</#macro>
426
427<#-- embed - destination detail - master data file export -->
428<#macro setmasterData >
429 <#assign thisMainImage = MainImage>
430 <#assign thisGallerList = GalleryImage.getSiblings()>
431 <#assign thisTitle = ScreenName.getData()>
432 <#assign thisSubHeader = ShortDescription.getData()>
433 <#assign thisLangIdString = thisJournalArticleDefaultLanguageId?split('_')[0]?upper_case >
434 <#assign thisMetaDescription = thisJournalArticle.getDescription()>
435
436 <#-- BUILD TABLES DATA -->
437 <#-- table section -->
438 <#assign masterDataArray = []>
439 <#assign tempObject = {
440 "Content code": ContentID.getData()!"none",
441 "Meta description": thisMetaDescription,
442 "Category": thisDestinationType,
443 "Country": thisCountry,
444 "Region": thisRegion,
445 "Prefecture": thisPrefecture,
446 "Destination name": thisTitle,
447 "Sub header": thisSubHeader,
448 "Description": Description.getData()
449 }>
450 <#assign masterDataArray = masterDataArray + [{"Content data":[tempObject]}]>
451 <#-- /table section -->
452
453 <#-- Gallery -->
454 <#-- <#assign tempObject = [["Image no.","Image file name","Image description"]]> -->
455 <#assign tempObject = []>
456 <#assign imagesList = [thisMainImage] + thisGallerList >
457 <#list imagesList as image>
458 <#assign tempImageNo = 1+image?index>
459 <#assign tempImageFileName = image.getData()?keep_before_last('/')?keep_after_last('/')>
460 <#assign tempImageUrl = image.getData()>
461 <#assign tempImageDescription = image.getAttribute('alt')>
462 <#assign tempObject = tempObject + [[tempImageNo, tempImageFileName, tempImageUrl, tempImageDescription]]>
463 </#list>
464 <#assign masterDataGalleryArray = [{"Gallery detail":[tempObject]}]>
465 <#-- /Gallery -->
466
467 <#-- HTML GENERATOR DATA -->
468 <#assign masterData>
469 <html>
470 <head>
471 <title>Destination Master Data "${thisTitle}"</title>
472 <style type="text/css">
473 html body {
474 font-family: monospace;
475 }
476
477 .--master-data > p {
478 margin-bottom: 10px;
479 font-weight: 800;
480 font-size: 1.2em;
481 }
482 .--master-data table {
483 width: 100%;
484 margin-bottom: 20px;
485 border-collapse: collapse;
486 }
487 .--master-data table tr td:first-child {
488 width: 250px;
489 }
490 .--master-data table td {
491 border: 1px solid lightgray;
492 padding: 5px 7px;
493 vertical-align: top;
494 }
495 </style>
496 </head>
497 <body>
498
499 <div class="--master-data">
500
501 <#list masterDataArray as table>
502 <#list table as name,tarray>
503 <p>${name}</p>
504 <#list tarray as table>
505 <table>
506 <tbody>
507 <#list table as k,v>
508 <tr>
509 <td>${k}:</td>
510 <td>${v}</td>
511 </tr>
512 </#list>
513 </tbody>
514 </table>
515 </#list>
516 </#list>
517 </#list>
518
519 <#list masterDataGalleryArray as table>
520 <#list table as name,tarray>
521 <p>${name}</p>
522 <#list tarray as table>
523 <table>
524 <tbody>
525 <tr>
526 <td>Image no.</td>
527 <td>File name</td>
528 <td>Description</td>
529 </tr>
530 <#list table as row>
531 <tr>
532 <td>${row[0]}</td>
533 <td><a href='${row[2]}' target='_blank'>${row[1]}</a></td>
534 <td>${row[3]}</td>
535 </tr>
536 </#list>
537 </tbody>
538 </table>
539 </#list>
540 </#list>
541 </#list>
542
543 </div>
544 </body>
545 </html>
546 </#assign>
547
548 <#assign masterDataJS = masterData?js_string>
549
550 <#-- html generator script -->
551 <script>
552 document.getElementById('masterButton').addEventListener('click', function() {
553 var newWindow = window.open('', '_blank');
554 var htmlContent = `${masterData}`;
555 newWindow.document.write(htmlContent);
556 newWindow.document.close();
557 });
558 </script>
559
560 <#-- word generator script -->
561 <script src="https://unpkg.com/docx@7.1.0/build/index.js"></script>
562
563 <#assign tableCellMargins = "{ top: 20, bottom: 20, left: 80, right: 80 }">
564 <#assign tableCellBorder>
565 {
566 top: { style: docx.BorderStyle.SINGLE, size: 1, color: "000000" },
567 bottom: {style: docx.BorderStyle.SINGLE, size: 1, color: "000000" },
568 left: {style: docx.BorderStyle.SINGLE, size: 1, color: "000000" },
569 right: {style: docx.BorderStyle.SINGLE, size: 1, color: "000000" }
570 }
571 </#assign>
572 <#assign tableBaseFont = 'font: "Calibri", size: 16'>
573
574 <script>
575 function generateWord() {
576 // Vytvoření dokumentu
577 const doc = new docx.Document({
578 sections: [
579 {
580 properties: {
581 page: {
582 margin: {
583 top: 720,
584 right: 720,
585 bottom: 720,
586 left: 720,
587 },
588 },
589 },
590 children: [
591 <@printDocxTables masterDataArray/>
592 <@printDocxTableGallery masterDataGalleryArray/>
593 ],
594 },
595 ],
596 });
597 // Uložení dokumentu
598 docx.Packer.toBlob(doc).then(blob => {
599 const link = document.createElement("a");
600 link.href = URL.createObjectURL(blob);
601 link.download = "Destination-${thisTitle}-${thisLangIdString}.docx";
602 link.click();
603 });
604 };
605
606 document.getElementById("masterButtonWord").addEventListener("click", generateWord);
607 </script>
608</#macro>
609
610<#-- DOCX data print macros -->
611<#macro printDocxTableGallery tables>
612 <#list tables as table>
613 <#list table as name,tarray>
614 <@printDocxParagraph name/>
615 <#list tarray as table>
616 new docx.Table({
617 rows: [
618 new docx.TableRow({
619 children: [
620 <@printDocxTableCell "Img. no." 10/>
621 <@printDocxTableCell "Filename" 50/>
622 <@printDocxTableCell "Description" 40/>
623 ],
624 }),
625 <#list table as row>
626 new docx.TableRow({
627 children: [
628 <@printDocxTableCell row[0] 10/>
629 <@printDocxTableCellHyperlink row[1] row[2] 50/>
630 <@printDocxTableCell row[3] 40/>
631 ],
632 }),
633 </#list>
634 ],
635 width: {
636 size: 100,
637 type: docx.WidthType.PERCENTAGE,
638 },
639 }),
640 <@printDocxParagraph ""/>
641 </#list>
642 </#list>
643 </#list>
644</#macro>
645
646<#macro printDocxTables tables>
647 <#list tables as table>
648 <#list table as name,tarray>
649 <@printDocxParagraph name/>
650 <#list tarray as table>
651 new docx.Table({
652 rows: [
653 <#list table as k,v>
654 new docx.TableRow({
655 children: [
656 <@printDocxTableCell k 25/>
657 <@printDocxTableCell v 75/>
658 ],
659 }),
660 </#list>
661 ],
662 width: {
663 size: 100,
664 type: docx.WidthType.PERCENTAGE,
665 },
666 }),
667 <@printDocxParagraph ""/>
668 </#list>
669 </#list>
670 </#list>
671</#macro>
672
673<#macro printDocxParagraph label>
674 new docx.Paragraph({
675 children: [
676 new docx.TextRun({
677 text: "${label?js_string}",
678 bold: true,
679 ${tableBaseFont},
680 }),
681 ],
682 }),
683</#macro>
684
685<#macro printDocxTableCell data width>
686 <#local paragraphs = textToArray(data)>
687 <#--
688 /* SERVICE PRINTING
689 ${data}
690 */
691 /*<#list paragraphs as paragraph>
692 <#list paragraph as line>
693 ${paragraph?index}-${line?index}: ${line}
694 </#list>
695 </#list>
696 */
697 /* AAQ ${paragraphs?size} */
698 -->
699 new docx.TableCell({
700 children: [
701 <#list paragraphs as cur_par>
702 new docx.Paragraph({
703 children: [
704 <#list cur_par as textLine>
705 new docx.TextRun({
706 text: "${(textLine)?js_string}",
707 ${tableBaseFont},}),
708 <#sep> new docx.TextRun({ text: "", break: 1 }),</#sep>
709 </#list>
710 ],
711 <#sep>
712 spacing: { after: 240, },
713 </#sep>
714 }),
715 </#list>
716 ],
717 margins: ${tableCellMargins},
718 width: {size: ${width},type: docx.WidthType.PERCENTAGE,},
719 borders: ${tableCellBorder},
720 }),
721</#macro>
722
723<#macro printDocxTableCellHyperlink data link width>
724 new docx.TableCell({
725 children: [new docx.Paragraph({
726 children: [
727 new docx.ExternalHyperlink({
728 children: [
729 new docx.TextRun({
730 text: "${data}",
731 ${tableBaseFont},
732 style: "Hyperlink",
733 }),
734 ],
735 link: "https://japanspecialist.com${link}",
736 }),
737 ],
738 })],
739 margins: ${tableCellMargins},
740 width: {size: ${width}, type: docx.WidthType.PERCENTAGE,},
741 borders: ${tableCellBorder},
742 }),
743</#macro>
744
745<#-- convert a field text/richtext to an array of paragraphs and lines -->
746<#function textToArray sourceData>
747 <#local retArray = []>
748 <#local string = sourceData?replace("\\s* ", " ", "r")><#-- replace spaces -->
749 <#local string = string?replace("\\t|\\n", "", "r")><#-- remove tabs, new lines -->
750 <#list string?split("</p>") as cur_paragraph>
751 <#if cur_paragraph?length != 0>
752 <#local cur_parLinesArray = []>
753 <#local cur_paragraphString = cur_paragraph?replace("<br>|<br/>|<br />|</li>", "*EOL*", "r")><#-- set End Of Line -->
754 <#list cur_paragraphString?split("*EOL*") as cur_line>
755 <#local cur_lineString = cur_line?replace("<li>", "• ")><#-- a dot for list item line -->
756 <#local cur_lineString = removeHtmlTags(cur_lineString)><#-- remove rest of html tags -->
757 <#local cur_lineString = cur_lineString?trim><#-- trim start/end whitespaces -->
758 <#if cur_lineString?length != 0>
759 <#local cur_parLinesArray = cur_parLinesArray + [cur_lineString]>
760 </#if>
761 </#list>
762 <#if cur_parLinesArray?size != 0>
763 <#local retArray = retArray + [cur_parLinesArray]>
764 </#if>
765 </#if>
766 </#list>
767 <#return retArray>
768</#function>
769
770<#function removeHtmlTags string>
771 <#local retString = string?replace("<[^>]*>", "", "r")>
772 <#return retString>
773</#function>