How to parse HTL content - aem

I'm loading a resource in AEM using SlingRequestProcessor as the example available here.
My page/html file looks like:
<div data-sly-use.stepPlanItem="stepPlanItemTemplate.html"
data-sly-call="${stepPlanItem.step # step = step}"
data-sly-unwrap />
But, when I invoke requestProcessor.processRequest(req, resp, request.getResourceResolver()); nothing happens. I'm getting exactly the same content of the file. Nothing is being parsed.
My main question is: How can I parse sly tags from Java code?
Should I use filters? Which one? This is a page (not an AEM one) just an HTL snippet.

You do not need to parse HTL files, this is done by the Sling Scripting Engine implementation. You are always processing/loading a resource and it needs to be resolved according to the Sling resource resolution.
Assuming you are trying to load a resource at: /content/myapp/mypage.html that has a sling:resourceType=myapp/myfile, you would put the above code snippet in an /apps/myapp/myfile/myfile.html file so that the scripting engine can execute the HTL.

Related

Can exams2moodle export additional metainfo such as idnumber and tags?

When I export the xml file of a multiple choice question, it contains the following lines:
<idnumber>arbitrary_id_set_by_user</idnumber>
<answernumbering>ABCD</answernumbering>
<tag></tag>
Is there a way to add idnumber, answernumbering and tag to the metainformation section of the question so that r-exams can export to moodle XML as <idnumber>idnumber</idnumber>,<answernumbering>ABCD</answernumbering>, <tag>tag1</tag>, and <tag>tag2</tag> etc?
The <answernumbering> tag can be set in exams2moodle() via the answernumbering= argument, see ?exams2moodle. The reason for this is that this is set in the same way for all exercises in a quiz. This is more consistent than setting it individually and potentially inconsistently in the meta-information of the different exercises.
The <idnumber> tag appears to be used by Moodle only for internal purposes. It is also not mentioned in the official Moodle XML documentation at https://docs.moodle.org/311/en/Moodle_XML_format. Hence we did not implement it in exams2moodle().
The <tag> is currently not supported in exams2moodle() because we felt that it would be more important to have tags in the Rmd (or Rnw) exercise itself and not the Moodle version of the exercise. For structuring the content on the Moodle side the exsection meta-information can be used, see boxhist for a worked example.
Finally, you can add arbitrary metainformation by using the exextra tag. This is used, for example, in the essayreg exercise template. However, there is no general way of using this extra metainformation to insert additional XML code in the exams2moodle() output. To do that, the source code underlying exams2moodle() would have to be adapted correspondingly.

Typoscript filelink - Wrap URL within link

First, here is the Typoscript :
20 = TEXT
20 {
value {
field = field_title
wrap = |.txt
}
filelink {
stdWrap.wrap = <li>|</li>
path = fileadmin/txt-files/
}
}
The result I get is :
<li>
<a href="/fileadmin/txt-files/Title.txt">
<img src="typo3/sysext/frontend/Resources/Public/Icons/FileIcons/txt.png">
</a>
</li>
And what I need is :
<li>
<a href="/fileadmin/force_download_script.php?filepath=/fileadmin/txt-files/Title.txt">
<img src="typo3/sysext/frontend/Resources/Public/Icons/FileIcons/txt.png">
</a>
</li>
I need to make the link downloadable, rather than opening the file in the browser. For that I have a force_download_script.php, but when I do that :
wrap = fileadmin/force_download_script.php?filepath=|txt
instead of the current wrap, filelink doesn't find the file anymore.
I have tried using ATagBeforeWrap.wrap but it doesn't look like it's made for that purpose. I also tried typolinkConfiguration.wrap without any success.
Any idea of how to achieve that ? Using a COA maybe ?
Thank you !
I would not do this with a script, but with server configuration. If you use Apache and have .htaccess enabled, you can add the configuration to a .htaccess file in the directory where the files are located. See https://css-tricks.com/snippets/htaccess/force-files-to-download-not-open-in-browser/
Alternatively you can also use the HTML5 download attribute. This is not supported by Internet Explorer however (it is supported by Edge though).
The issue can get quite a bit complicated, but step by step:
your code above might be wrong if it's not just a copy & paste fault:
wrap = fileadmin/force_download_script.php?filepath=|.txt
The dot before txt was missing.
Nevertheless it is still interesting if the php-script is triggered.
It's possible that the script is not triggered due to some settings in typo3conf/LocalConfiguration.php respectively some settings in the install-tool.
Depending on the TYPO3-Version it's also possible that the script is not triggered at all because all scripts are being required now in an extension. That means you might need to create an extension for that script.
Also simple wrapping of the result with the script-path might not be enough, but you have to call it explicitly by TypoScript perhaps by including the script as user-function or lib.
The admin-panel might be useful to debug some things about your script but if not you've to include some debug-output first in your own code, if that's not enough in the core (temporary).
So you've to find out if your script is triggered and if not, the reason for it.
Are you sure .filelink is what you are looking for?
.filelink is for a set of files. For all files in the folder given by .path a link will be generated. see manual
From your description you want a text wrapped with a link to one single file. That would be more a problem for .typolink where you specify the link in .parameter.
if you really want a link list of multiple files, each wrapped with your script you need to modify .typolinkConfiguration.parameter which will be used internaly by .filelink.
Anyway it might be possible to do a wrap which then would be:
.typolinkConfiguration.parameter.wrap = /fileadmin/force_download_script.php?|
Maybe it is easier to build your list with .stdWrap.filelist, where you can use the filenames in any way to wrap your own href parameter for an A-tag.
To use the TYPO3 core solution with file links you can use this guide:
Create a file storage where you want your "secured" files in TYPO3 backend
Do not set the checkbox "Is public?" in the storage record
The links will be rendered with eID and file parameters
You can look into the FileDumpController handling these links: https://github.com/TYPO3/TYPO3.CMS/blob/2348992f8e3045610636666af096911436fa1c89/typo3/sysext/core/Classes/Controller/FileDumpController.php
You can use the included hook to extend this controller with your logic.
Unfortunately I can't find any official documentation for this feature, but will post it when I find something or wrote it myself. ;)
Maybe this can help you, too: https://extensions.typo3.org/extension/fal_securedownload/
Here is the official part, but it's not much: https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Fal/Administration/Storages.html?highlight=filedumpcontroller

AEM 6.x: How to pass an HTL variable to clientlib/JS?

So I have the following lines which loads my javascript.
<sly data-sly-use.clientLib="${'/libs/granite/sightly/templates/clientlib.html'}" data-sly-unwrap />
<sly data-sly-call="${clientLib.js # categories='myhost.mycustomJS'}" data-sly-unwrap />
I have an HTL property (example: ${properties.myCustomProperty}) that I want to pass to myCustomJS.
Any ideas how it can be done?
I've looked around the net but didn't find anything useful.
Thank you.
You are trying to access a server side property with client side script. As you may realize sightly executes at server end and rendered output is returned to browser. In your case you need to send the properties to browser to make it available for clientside scripts to consume.
Technique 1: (Recommended) Data attributes -
This is easiest to send since DOM structure doesnt change. Pass the values as data elements and retrieve using jquery. For example:
var value = $('#mydiv').data('custom-property');
console.log(value);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mydiv" data-custom-property="${properties.myCustomProperty}" />
Technique 2: (Old school) - Hidden variable - Add hidden variable into component rendering script; set the value of variable with HTL property and read the variable from clientside js using getElementById or jquery.
Technique 3: (Not recommended) - Make a trip to server. If you dont want to dilute your DOM (maybe property is secret or not SEO friendly), you may need to make an ajax call to a sling servlet that returns the property value. There are multiple examples available for sling servlet you can refer to.
ACS Sample, AEM 6.3 servlet, 1 more example.
But do remember its not worth to make a trip to server just for 1 property.

data-sly-resource error handling in sightly - AEM

data-sly-resource tag allows to refer resource in another component in following way.
<article data-sly-resource="path/to/resource"></article>
We have path/to/resource being taken as part of dialog field by content authors. If the content authors select the path which is not existing by mistake, page becomes inaccessible to content authors, giving HTTP 500 error and there is no other way to correct it without going to CRX. On environments where access to CRX is not there, we cannot delete the incorrect node. Exception in logs is
Caused by: org.apache.sling.scripting.sightly.SightlyException: org.apache.sling.api.resource.ResourceNotFoundException: No resource found
at com.adobe.cq.sightly.WCMScriptHelper.includeResource(WCMScriptHelper.java:143)
at com.adobe.cq.sightly.WCMScriptHelper.includeResource(WCMScriptHelper.java:86)
at com.adobe.cq.sightly.internal.extensions.ResourceExtension.call(ResourceExtension.java:99)
at org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl.call(RenderContextImpl.java:89)
The out of the box reference component (/libs/foundation/components/reference/reference.jsp) handles this by having a catch block, Content Author can correct path. But that's JSP based not sightly based.
Is there a way to handle this in sightly?
The proper way to handle this is through an Use-API object that will attempt to find the resource and handle any exceptions:
<article data-sly-use.helper="myHelper" data-sly-test="${helper.resource}" data-sly-resource="${helper.resource}"></article>
Passing an actual org.apache.sling.api.resource.Resource to data-sly-resource is possible since SLING-5811, for older versions of HTL/Sightly you will need to pass a path.
Try this syntax, path should given in EL expression:
<article data-sly-resource="${ # path='path/to/resource'}"></article>

What is done here. What does this syntax means in sightly?

I am reading the docs about calling clientlibs in sightly.
I am not getting the below syntax
<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"
data-sly-call="${clientlib.all # categories='clientlib1,clientlib2'}"/>
why we are using category here? How does it related to clientlibs?
Lets break this down:
<sly> - is a sightly tag that does nothing :) So when you don't want to use an HTML tag you can use <sly> as a placeholder.
data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html - this line references the clientlib.html file that has templates marked with data-sly-template attributes. These templates are reusable piece of markup. Look at them as functions in htl.
data-sly-call - used to call one of the templates from the above clientlib.html
clientLib.all - "all" is the name of the template being called from clientlib.html which is referred using clientLib keyword (-use.clientLib)
# categories='clientlib1,clientlib2 - categories are used to identify cq:clientLibraryFolder that are used for client side code in AEM. If you check http://localhost:4502/libs/granite/ui/content/dumplibs.html it will show you the location of libraries clientlib1 & clientlib2
So in a nutshell, this line calls 2 libraries (containing js & css) with categories clientlib1 & clientlib2 and loads them on to the page/component