I've found a bug in pickerresults.lib.ftl that i have already reported
Briefly: if the user does not have the permission on a file parent, the line
<#if row.item.parent??>"parentName": "${row.item.parent.name!""}",
will fail, failing the entire script (and the user can't see any file)
So, waiting for the bug being resolved i need to patch this. I'd like to override the macro "pickerResultsJSON" defined in the file removong the line or putting a string value in place of "${row.item.parent.name!""}" that cause the exception
I have no idea of how to redefine the macro and where to place the file inside my amp. Can someone help me?
UPDATE
I'm using the Alfresck SDK 2.0 and my project structure is:
I've tryed to put a file "custom-pickerresults.lib.ftl" with the following content (as suggested by sev) but it does not seem to be the right position. Or should i "register" it in some way?
<#macro pickerResultsJSON results>
<#-- new code here -->
</#macro>
<#global pickerResultsJSON = pickerResultsJSON />
Since macros are just variables, you might be able to do something like this:
<#macro pickerResultsJSON>
<#-- new code here -->
</#macro>
<#global pickerResultsJSON = pickerResultsJSON />
As to where you would put that... you could put it in any file that is included globally on your project. It might require a little trial and error since I'm not sure what your project structure is.
Many thanks to sev, he pointed me the right way.
I realized that pickerresults.lib.ftl is used by the webservice pickerchildren.get.desc.xml and pickerchildren.post.desc.xmlso, the solution is to copy the web service definition and files along with the library in
/alfresco-myamp-repo/src/main/amp/config/alfresco/extension/templates/webscripts/com/my/repository/forms/
(repository/forms/ just becouse the original files are inside config/alfresco/templates/webscripts/org/alfresco/repository/forms/ but any other folder under /alfresco-myamp-repo/src/main/amp/config/alfresco/extension shuld do)
and change the library like this:
...
"type": "${row.item.typeShort}",
"parentType": "${row.item.parentTypeShort!""}",
<#-- from here -->
<#attempt>
<#if row.item.parent??>"parentName": "${row.item.parent.name!""}",</#if>
<#recover>
"parentName": "<unknown>",
</#attempt>
<#-- to here -->
"isContainer": ${row.item.isContainer?string},
<#if row.container??>"container": "${row.container!""}",</#if>
...
This way even if the user has not the permissions to read the parent's name the template can complete without errors (i don't know if the value "unknown" in place of the parent name can cause any troubles, but i did not notice nothing right now)
Related
I'm using Typo3 8.7.11 and the extension indexedSearch 8.7.11 with Fluid-Templates
I created an extension with my own fluid-templates for the search and search-results form.
Now I also want to use my own translations for these templates. So I created the following files in myTemplateExt/Resources/Private/Language:
locallang.xlf (for the default - en - language)
de.locallang.xlf
fr.locallang.xlf
it.locallang.xlf
Alas, the translations are not loaded.
I found out that I can add the whole path to the translations like
<f:translate key="LLL:EXT:myTemplateExt/Resources/Private/Language/locallang.xlf:sform.submit" />
But then only the locallang.xlf file is loaded. All other languages are ignored.
I also tried to add my own variable to the indexed-search TS-setup:
plugin.tx_indexedsearch.settings.langfile = EXT:myTemplateExt/Resources/Private/Language/locallang.xlf
Which of course fails miserably (most likely because I can't define my own settings-var in TS for another extension?)
Any ideas how I can make the indexed-search extension use my own lang-files?
P.S. I found this suggestion on StackOverflow:
Typo3 Indexed Search Local_Lang path
But this is not what I want - I need more flexibility for my templates, as I need to add some more text than just the regular keys that indexed-search provides to them (yeah, customers, you know ;)
It might not be the best solution, but I solved the problem like this:
I set a variable according to the current language:
<v:variable.set name="currentLang" value="{v:page.language(languages: 'LLL:EXT:myExt/Resources/Private/Language/de.locallang.xlf,
LLL:EXT:myExt/Resources/Private/Language/en.locallang.xlf,
LLL:EXT:myExt/Resources/Private/Language/fr.locallang.xlf,
LLL:EXT:myExt/Resources/Private/Language/it.locallang.xlf',
normalWhenNoLanguage: 'LLL:EXT:myExt/Resources/Private/Language/de.locallang.xlf')}" />
And then for the translation:
<f:form.submit name="search[submitButton]" value="{f:translate(key: '{currentLang}:sform.submit')}" id="tx-indexedsearch-searchbox-button-submit" class="tx-indexedsearch-searchbox-button" />
This isn't elegant, but it works...
I am trying to create a folder at a location different from the application installation location which happens to be C:\Program Files(x86). I am using the following fragment
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="PhotosDir" Name="Photos" />
</DirectoryRef>
<!--<SetDirectory Id="PhotosDir" Value="[TARGETDIR]Photos" Sequence="execute"></SetDirectory>-->
</Fragment>
I tried with a SetDirectory element as shown above and also with a CustomAction as shown below. (If I use both, I get an error saying Id is duplicated. Hence I commented it.)
<CustomAction Id="SetPhotosDir" Directory="PhotosDir" Value="[TARGETDIR]Photos"></CustomAction>
<InstallExecuteSequence>
<Custom Action="SetPhotosDir" Before="CreateFolders"/>
</InstallExecuteSequence>
I have a component also defined for this directory element as below.
<Component Id="cmpPhotosDir" Guid="{8F757344-CA0A-42BC-B292-A51CE86B19E2}" KeyPath="yes" Directory="PhotosDir"><CreateFolder/></Component>
But the directory called Photos is always getting created in D drive, even though it is nested inside of TARGETDIR. I actually want to control the location where this directory gets created, probably through UI. I googled for SetDirectory element example, but couldn't find a proper working sample. All I get to see is that I have to use a custom action type 35 or 51. But it is not clear what code should go inside of these custom actions. Also, I am not sure, if these custom actions are required in addition to the SetDirectory element or not. Can anyone please help me achieve this, with some working sample?
The problem is your directory identifier is not PUBLIC. Change its name to include no lower-case letters; use only upper-case letters, numbers, and underscores. (This came up in reverse pretty recently over here.)
I would also probably schedule the action to After="CostFinalize" , or just set the property of the same name Before="CostInitialize. Neither of those are likely to be relevant to your symptoms, however.
I'm working in Alfresco and I'd like to create my own custom component (for a form) extending an exiting one. In my case "number.ftl".
I'd like to provide the ability to set a defaultValue, so that if field.value is empty the default value will be used
default-number.flt
<#if field.control.params.defaultValue?? && !field.value?has_content>
<#assign field.value=field.control.params.defaultValue>
</#if>
<#include "/org/alfresco/components/form/controls/number.ftl" />
It complains about the dot (.) in field.value:
Caused by: freemarker.core.ParseException: Parsing error in template "org/alfresco/components/form/controls/year.ftl" in line 3, column 23:
Encountered ".", but was expecting one of:
"="
"in"
">"
How do I set the variable?
UPDATE
I've tried as suggested by abarisone (but I can't set the variable after importing "number.ftl" or the old value would be used):
<#if field.control.params.curretYearDefaultValue?? && !field.value?has_content>
<#assign value in field>
${.now?string("yy")}
</#assign>
</#if>
<#include "/org/alfresco/components/form/controls/number.ftl" />
but i get:
FreeMarker template error: For "#assign" namespace: Expected a namespace, but this evaluated to an extended_hash+string (org.alfresco.web.scripts.forms.FormUIGet$Field wrapped into f.e.b.StringModel): ==> field [in template "org/alfresco/components/form/controls/year.ftl" at line 3, column 27]
UPDATE2 (solved)
As suggested by ddekany here a working solution
<#if field.control.params.useCurretYearAsDefaultValue?? && field.control.params.useCurretYearAsDefaultValue = "true" && !field.value?has_content>
${field.setValue(.now?string("yyyy"))!}
</#if>
<#include "/org/alfresco/components/form/controls/number.ftl" />
FreeMarker templates don't support data-model modification. They only meant to read the stuff that was already prepared by Java code. You can set top-level variables only because those aren't part of the data-model (they are in a scope in front of the top-level data-model variables). And so FreeMarker doesn't even have a syntax for modifying a subvariable. But, a back door might exists to achieve what you want. Depending on configuration settings and on what field is on Java-level, ${field.setValue(...)} might works. It's quite a hack to do that, mind you. Manipulating form content from a template, that stinks. You should call out to some Java helper method at least.
If you look at the Freemarker assign reference, you will see that when you use assign you usually write <#assign name=value> where name is the name of the variable. It is not expression.
In fact the compiler complains about the fact it was expecting a "=" or "in".
The latter makes sense if you look further to this:
<#assign name in namespacehash>
capture this
</#assign>
explained like that:
If you know what namespaces are: assign directive creates variables in namespaces. Normally it creates the variable in the current namespace (i.e. in the namespace associated with the template where the tag is). However, if you use in namespacehash then you can create/replace a variable of another namespace than the current namespace. For example, here you create/replace variable bgColor of the namespace used for /mylib.ftl:
<#import "/mylib.ftl" as my>
<#assign bgColor="red" in my>
So I can suggest you to import the number.ftl file first and then search for the variable you're wishing to set.
In Alfresco, if a type name is removed/changed all nodes of that type will disappears but still exists.
Using alfresco 5.0.c I've added some custom types:
eg:
<type name="my:test">
<title>Test folder</title>
<parent>cm:folder</parent>
</type>
now i deploy it and create a folder of this type (a simple folder, then change type)
Now i edit the type like this:
<type name="my:test2"> <!-- from my:test to my:test2 -->
<title>Test folder</title>
<parent>cm:folder</parent>
</type>
Deploying this: any "my:test" folder will disappear, but, if I try to create another folder with the same name I get an error becouse the node still exists.
These nodes will not be not even listed within the folder child:
print(document.getChildren());
How can I recover (if possible using the the javascript console) all the "broken" nodes and be able to change the type?
A little preface: as widely stated by Alfresco, if you want to change your custom content model you should change it only incrementally.
This means that you can't remove any properties, types or aspect at definition level of the model, you only can add new definitions in the content model of Alfresco.
So it is a very bad practice to change types "on the fly".
A good practice is to always start with a model as small as you can and then add features as long as you need them.
In your case you should have deleted all nodes referencing my:test type BEFORE changing the model and then safely remove it and finally you should have performed a full reindex. This could be the reason why the repository tells you that the folder exists even if you cannot see it anymore.
As far as I know it is not possible to delete this inconsistent nodes through the console, so my advice is to perform a full reindex. If the issues come up again then you should consider to start again from scratch.
Another approach next time is to add the new type and programmatically hide the older one.
This question is a reformulation of this question which had evolved in a confusing way. Please refer to this question if you search some in depth details or are interested in workarounds and alternative solutions.
This question is about the call to template folder_full_view_item.pt in folder_full_view.pt, not about other templates in general!
Please avoid workarounds like skin layers, editskinswitcher, etc. I don't want to solve a particular use case here. What I want is to really understand how this actually works.
I present this question in three parts: scenario, result, questions.
scenario
Have a Folder with a Document. The layout of the Folder is folder_full_view. The layout of the Document is document_view:
Folder (layout=folder_full_view)
Document (layout=document_view)
The template folder_full_view.pt calls template folder_full_view_item.pt via item.getObject().folder_full_view_item().
folder_full_view_item.pt calls (e.g. for a Document content type ) the template document_view.pt via use-macro="item_macro" (item_macro being something like here/document_view/macros/content-core). Schematically as follows:
folder_full_view.pt :: item.getObject().folder_full_view_item()
folder_full_view_item.pt :: use-macro="here/document_view/macros/content-core"
document_view.pt
In a plone3_theme have overriden versions of the templates folder_full_view.pt, folder_full_view_item.pt, and document_view.pt. These templates are registered as follows in configure.zcml.
<browser:page
for="*"
name="folder_full_view_item"
template="folder_full_view_item.pt"
layer="example.theme.browser.interfaces.IThemeSpecific"
permission="zope2.View"
/>
<browser:page
for="Products.ATContentTypes.content.folder.ATFolder"
name="folder_full_view"
template="folder_full_view.pt"
layer="example.theme.browser.interfaces.IThemeSpecific"
permission="zope2.View"
/>
<browser:page
for="Products.ATContentTypes.content.document.ATDocument"
name="document_view"
template="document_view.pt"
layer="example.theme.browser.interfaces.IThemeSpecific"
permission="zope2.View"
/>
results
With the theme installed the results are:
Document and Folder get their templates (I guess) via traversal. The (sub)templates though don't go through the traversal.
Folder: uses overriden folder_full_view.pt, original folder_full_view_item.pt, and original document_view.pt
Document: uses overriden document_view.pt
questions
is it the case that item.getObject().folder_full_view_item() doesn't go through traversal? If yes why?
what can be modified (in folder_full_view.pt!) to force a traversal to the overriden folder_full_view_item.pt(!) and subsequently to the overriden document_view.pt? Is this possible?
Again, please avoid workarounds like skin layers, editskinswitcher, etc. I don't want to solve a particular use case here. What I want is to really understand how this actually works.