In my main.ftl file I have:
<Product>
<#include "product.ftl">
</Product>
and then in product.ftlfile I have:
<#if product.value ??>
<Value>${product.value}</Value>
</#if>
However I would like to know that product.ftl was called from main.ftl file, not from another e.g otherFile.ftl. How can I pass value from main.ftl to product.ftl?
I tried with:
<Product>
<#assign name=final>
<#include "product.ftl">
</Product>
and then:
<#if product.value ?? && name = "final">
<Value>${product.value}</Value>
</#if>
but it doesn't work
In main.ftl added:
<#assign isFinal=true>
then in product.ftl added:
<#if product.value ?? && isFinal?? && isFinal>
<Value>${product.value}</Value>
</#if>
and now it works.
Related
Hi I have a question in liferay 7.4 ,
I am using assetRenderer Class to build a freemarker template.
https://docs.liferay.com/portal/7.4-latest/javadocs/portal-kernel/com/liferay/dynamic/data/mapping/kernel/DDMFormFieldValue.html
My problem is I cannot get the url from the featuredImage field which is an image field in a structure, I get a whole value which is a string, I would like to have another way.
<#function getFieldData ddmFormFieldValues fieldReference>
<#list ddmFormFieldValues as ddmFormFieldValue>
<#if ddmFormFieldValue.getDDMFormField().getFieldReference()==fieldReference>
<#if (ddmFormFieldValue)??>
<#assign value=ddmFormFieldValue />
<#return value />
<#else>
<#return null />
</#if>
</#if>
</#list>
<#return null />
</#function>
<#assign ddmFormValuesReader = assetRenderer.getDDMFormValuesReader() />
<#assign ddmFormFieldValues =
ddmFormValuesReader.getDDMFormValues().getDDMFormFieldValues()/>
<#assign newsImage = getFieldData(ddmFormFieldValues, 'featuredImage') />
${newsImage.getValue().getString(locale)}
The result will be a string like this :
{"extension":"jpg","fileEntryId":"631318","groupId":"630625","title":"Dino-bakgrund.png","type":"document","url":"\/documents\/630625\/0\/Dino-bakgrund.png.jpg\/ecffe3b3-333e-3da3-6bb4-732da3d60947?t=1557132929823&imagePreview=1","uuid":"ecffe3b3-333e-3da3-6bb4-732da3d60947"}
Is there a way to get the property directly, since I get a string here ?
I can convert the String to Json and get the result, but this is not a good way something like this :
<#assign newsImage_map = jsonFactoryUtil.createJSONObject(newsImage) />
<#if (newsImage_map.url)?? >
<#assign newsImageUrl = newsImage_map.url />
${newsImageUrl }
</#if>
Is there away that I do not covert to JSON ?
In freemarker, how do I iterate over all blog posts with a particular tag, for example the tag "algorithms"?
<#assign relatedBlogs = ...>
<#if relatedBlogs?size > 0>
<h2>Related blog posts</h2>
<ul>
<#list relatedBlogs as blog>
<li>
${blog.title}
</li>
</#list>
</ul>
</#if>
This doesn't work for me:
<#assign relatedBlogs = tagged_posts["algorithms"]>
This doesn't work either:
<#assign relatedBlogs = tags["algorithms"].tagged_posts>
tags is a sequence, and to use tags[...] you need a hash.
I ended up getting it to work through ?filter()and ?first:
<#assign relatedTags = tags?filter(tag -> tag.name == "algorithms")>
<#if relatedTags?size > 0>
<#assign relatedTag = relatedTags?first>
<h2>Algorithms related blog posts</h2>
<ul>
<#list relatedTag.tagged_posts as blog>
<li>
${blog.title}
</li>
</#list>
</ul>
</#if>
This won't scale well, because filter() iterates the tags for every page, but it works fast enough for websites with hundreds of pages. Here's the related issue.
Hy, I'd like to know how i can prevent, that the ouptut will show two times the same date or the same contract type. Furthermore I don't know how i can put a comma behind the last Date/contract type...
At the moment the output would be:
Alessia: 200m2, EUR 100'000, Contract type: Limited/ Limited Start of contract: 2000-01-01 / 2000-01-01 End of contract: 2020-12-31 / 2020-12-31
Jan: 870m2, EUR 3'400'000, Contract type: Limited / Unknown Start of contract: 2001-01-09 / 2002-03-10 End of contrats: 2025-12-31
How I'd like to have the output:
Alessia: 200m2, EUR 100'000, Contract type: Limited, Start of contract: 2000-01-01, End of contract: 2020-12-31
Jan: 870m2, EUR 3'400'000, Contract Types: Limited / Unknown, Start of contracts: 2001-01-09 / 2002-03-10, End of contrats: 2025-12-31
So if there is two times the same date or same contract i only want it once in my list. If it's different it should show all of them and in both cases a comma behind the last output of the list. If you knew how to change the title depending on if there is 0, 1 or two dates following that would be amazing.
<#assign translations = {
"de": {
"bbo": "Per {0}",
"sqm":"m²",
"contract00":"Vertragstyp:",
"contract01":"Befristet",
"contract02":"Unbefristet",
"contract03":"Befristet mit echter Option",
"contract04":"Befristet mit unechter Option",
"contract05":"Amortisation Mieterausbau",
"contract06":"Umsatzmiete",
"contract07":"Andere",
"contract08":"Unbekannt",
"start00":"Vertragsstart:",
"end00":"Vertragsende"
},
"en":{
"bbo": "Per {0}",
"sqm":"m²",
"contract00":"Contract type:",
"contract01":"Limited",
"contract02":"Unlimited",
"contract03":"Limited with real option",
"contract04":"Limited with unreal option",
"contract05":"Amortisation Mieterausbau",
"contract06":"Umsatzmiete",
"contract07":"Other",
"contract08":"Unknown",
"start00":"Start of contract:",
"end00":"End of contract:"
}
}>
<br>
<#assign msg = translations[.lang]>
<#assign currency = valuation.valuationSettings.valuationCurrency>
<#assign rentalUnits = valuation.draftRul.rentalUnits>
<#assign rentalUnitsWithTenant = []>
<#list rentalUnits as ru>
<#if ru.currentLease?? && ru.currentLease.tenant?? >
<#assign rentalUnitsWithTenant = rentalUnitsWithTenant + [ru]>
</#if>
</#list>
<#assign rentalUnitsByTenant = groupBy(rentalUnitsWithTenant, "currentLease.tenant")>
<ul>
<#list rentalUnitsByTenant?keys?sort as tenant>
<#assign rentalUnitsOfTenant = rentalUnitsByTenant[tenant]>
<#assign area=sum(rentalUnitsOfTenant, "areaPerUnitValue")>
<#assign income = sum(rentalUnitsOfTenant, "currentLease.income.income")>
<#assign units = sum(rentalUnitsOfTenant, "units")>
<#if income gte 100000>
<li>
${tenant}: ${area} ${msg["sqm"]}, ${currency} ${income?string[",##0"]},
${msg["contract00"]}
<#list rentalUnitsOfTenant as ru>
<#if ru.currentLease??>
<#if ru.currentLease.contractType= "LIMITED">
<#assign contract = msg["contract01"]>
<#elseif ru.currentLease.contractType="UNLIMITED">
<#assign contract = msg["contract02"]>
<#elseif ru.currentLease.contractType="LIMITED_WITH_REAL_OPTION">
<#assign contract = msg["contract03"]>
<#elseif ru.currentLease.contractType="LIMITED_WITH_UNREAL_OPTION">
<#assign contract = msg["contract04"]>
<#elseif ru.currentLease.contractType="AMORTISATION">
<#assign contract = msg["contract05"]>
<#elseif ru.currentLease.contractType="UMSATZMIETE">
<#assign contract = msg["contract06"]>
<#elseif ru.currentLease.contractType="OTHER">
<#assign contract = msg["contract07"]>
<#elseif ru.currentLease.contractType="UNKNOWN">
<#assign contract = msg["contract08"]>
</#if>
${contract}<#sep>/</#sep>
</#if>
</#list>
${msg["start00"]}
<#list rentalUnitsOfTenant as ru>
<#if ru.currentLease??>
${ru.currentLease.start!}<#sep>/</#sep>
</#if>
</#list>
Enddaten:
<#list rentalUnitsOfTenant as ru>
<#if ru.currentLease.end??>
${ru.currentLease.end!}<#sep>/</#sep>
</#if>
</#list>
</li>
</#if>
</#list>
</ul>
If you have the solution for one of my questions I'm already grateful.
Try to build unique list before printing values, it can be something like in example below. The key thing is seq_contains method.
<#assign uniqueList = []>
<#list rentalUnitsOfTenant as ru>
<#if ru.currentLease??>
<#if ru.currentLease.contractType= "LIMITED">
<#assign contract = msg["contract01"]>
...
</#if>
<#if !uniqueList?seq_contains(contract) >
<#assign uniqueList = uniqueList + [contract]>
</#if>
</#if>
</#list>
<#list uniqueList as contract>
${contract}<#sep>/</#sep>
</#list>
I'm sure there must be an elegant way to turn Spring Boot configuration meta-data files into HTML (or markdown or ...). While I could write a parser myself I'm convinced that this has already been solved. Yet, I failed to find a lead for that so far.
Here is a simple example of converting Spring Boot configuration metadata into HTML using org.springframework.boot:spring-boot-configuration-processor and org.freemarker:freemarker libraries.
Parse Metadata
Use classes from spring-boot-configuration-processor library to parse the JSON file,
File metadataFile = new File("spring-configuration-metadata.json");
ConfigurationMetadata metadata =
new JsonMarshaller().read(new FileInputStream(metadataFile));
HTML Generation
Once you have the metadata converted into Java object, use FreeMarker templated to convert it into an HTML file. It uses metadata.ftl template to convert the metadata object into metadata.html.
Configuration cfg = new Configuration(new Version(2, 3, 27));
// template is loaded from 'templates' folder under resources
cfg.setClassForTemplateLoading(
SpringConfigurationMetadataProcessorTest.class, "/templates");
cfg.setDefaultEncoding("UTF-8");
cfg.setLocale(Locale.US);
cfg.setTemplateExceptionHandler(
TemplateExceptionHandler.RETHROW_HANDLER);
Map<String, Object> input = new HashMap<String, Object>();
input.put("title", "Spring Configuration Metadata Example");
input.put("metadata", metadata);
input.put("GROUP", ItemMetadata.ItemType.GROUP);
input.put("PROPERTY", ItemMetadata.ItemType.PROPERTY);
Template template = cfg.getTemplate("metadata.ftl");
// write output into a file
Writer fileWriter = new FileWriter(new File("metadata.html"));
try {
template.process(input, fileWriter);
} finally {
fileWriter.close();
}
Here is the example metadata.ftl,
<html>
<head>
<title>${title}</title>
</head>
<body>
<h1>${title}</h1>
<#if metadata.hints??>
<section>
<h1>Hints</h1>
<#list metadata.hints as hint>
<section>
<dl>
<dt><b>name: </b>${hint.name}</dt>
<#if hint.values?? && hint.values?size != 0>
<dt><b>values:</b></dt>
<#list hint.values as value>
<#if value.value??>
<dd><b>value: </b>${value.value}</dd>
</#if>
<#if value.description??>
<dd><b>description: </b>${value.description}</dd>
</#if>
<br/>
</#list>
</#if>
<#if hint.providers?? && hint.providers?size != 0>
<dt><b>providers:</b></dt>
<#list hint.providers as provider>
<#if provider.name??>
<dd><b>name: </b>${provider.name}</dd>
</#if>
<#if provider.parameters?? && provider.parameters?size != 0>
<dd><b>parameters:</b></dd>
<#list provider.parameters as key, value>
<dd> <b>${key}: </b>${value}
</dd>
</#list>
</#if>
<br/>
</#list>
</dl>
</#if>
</section>
</#list>
</section>
</#if>
<#if metadata.items??>
<section>
<h1>Groups</h1>
<#list metadata.items as item>
<#if item.isOfItemType(GROUP)>
<section>
<dl>
<#if item.sourceType??>
<dt><b>sourceType: </b> ${item.sourceType}</dt>
</#if>
<#if item.name??>
<dt><b>name: </b> ${item.name}</dt>
</#if>
<#if item.description??>
<dt><b>description: </b> ${item.description}</dt>
</#if>
<#if item.type??>
<dt><b>type: </b> ${item.type}</dt>
</#if>
<#if item.sourceMethod??>
<dt><b>sourceMethod: </b> ${item.sourceMethod}</dt>
</#if>
<#if item.defaultValue??>
<#if item.defaultValue?is_enumerable>
<dt><b>defaultValue: </b></dt>
<#list item.defaultValue as df>
<dd>${df}</dd>
</#list>
<#else>
<dt><b>defaultValue: </b> ${item.defaultValue}</dt>
</#if>
</#if>
<#if item.deprecation??>
<dt><b>deprecation: </b></dt>
<#if item.deprecation.reason??>
<dd><b>reason: </b> ${item.deprecation.reason}</dd>
</#if>
<#if item.deprecation.replacement??>
<dd><b>replacement: </b> ${item.deprecation.replacement}</dd>
</#if>
<#if item.deprecation.level??>
<dd><b>level: </b> ${item.deprecation.level}</dd>
</#if>
</#if>
</dl>
</section>
</#if>
</#list>
<h1>Properties</h1>
<#list metadata.items as item>
<#if item.isOfItemType(PROPERTY)>
<section>
<dl>
<#if item.sourceType??>
<dt><b>sourceType: </b> ${item.sourceType}</dt>
</#if>
<#if item.name??>
<dt><b>name: </b> ${item.name}</dt>
</#if>
<#if item.description??>
<dt><b>description: </b> ${item.description}</dt>
</#if>
<#if item.type??>
<dt><b>type: </b> ${item.type}</dt>
</#if>
<#if item.sourceMethod??>
<dt><b>sourceMethod: </b> ${item.sourceMethod}</dt>
</#if>
<#if item.defaultValue??>
<#if item.defaultValue?is_enumerable>
<dt><b>defaultValue: </b></dt>
<#list item.defaultValue as df>
<dd>${df}</dd>
</#list>
<#else>
<dt><b>defaultValue: </b> ${item.defaultValue}</dt>
</#if>
</#if>
<#if item.deprecation??>
<dt><b>deprecation: </b></dt>
<#if item.deprecation.reason??>
<dd><b>reason: </b> ${item.deprecation.reason}</dd>
</#if>
<#if item.deprecation.replacement??>
<dd><b>replacement: </b> ${item.deprecation.replacement}</dd>
</#if>
<#if item.deprecation.level??>
<dd><b>level: </b> ${item.deprecation.level}</dd>
</#if>
</#if>
</dl>
</section>
</#if>
</#list>
</section>
</#if>
</body>
</html>
I have the following freemarker code
<#assign carsPriceDescriptionSB = "Price guide" >
<#if vehicle.getPriceDescription == carsPriceDescriptionSB >
<div class="cgl304 data-source small">Some text
<br/><br/>
</div>
</#if>
What I want to do is check that the value of vehicle.getPriceDescription() is equal to Price guide and if the result is true display the block of code
To access the get method you should drop the 'get' or explicitly specify the method name followed by brackets. Avoid using the second method unless necessary.
Normally omit the get prefix
<#assign carsPriceDescriptionSB = "Price guide" >
<#if vehicle.priceDescription == carsPriceDescriptionSB >
<div class="cgl304 data-source small">Some text
<br/><br/>
</div>
</#if>
Or if it is not a get method then specify the entire method name
<#assign carsPriceDescriptionSB = "Price guide" >
<#if vehicle.readPriceDescription() == carsPriceDescriptionSB >
<div class="cgl304 data-source small">Some text
<br/><br/>
</div>
</#if>