Alfresco multi-select - Disable delete option based on a aspect - alfresco

In Alfresco, how to disable actions in multiselect drop down. Assume I have delete couple of files. So i am selecting all those files. Now, if any of the selected files have a specific aspect then the delete option should not be enabled. How can I achieve this?
This is what I tried. But no luck.
<action type="action-link" id="onActionDelete" label="menu.selected-items.delete" notAspect="p:hasSecondaryParent" />
My expectation here is if any of the selected items have "p:hasSecondaryParent" aspect then I do not want the "Delete" action in "Selected Items" drop down. All other time it should display

You need to create action evaluator for that. There is out of box has aspect evaluator available which you need to utilize set your custom aspect in that evaluator. Now add that evaluator in config of delete action. Restart server And that's it.
Ex.
<bean id="evaluator.doclib.indicator.exifMetadata" class="org.alfresco.web.evaluator.HasAspectEvaluator">
<property name="aspects">
<list>
<value>exif:exif</value>
</list>
</property>
This is example from out of box context file you need to replace aspect name and id of evaluator. Then Add this evaluator in your action config.
<config evaluator="string-compare" condition="DocLibActions">
<actions>
<!-- Download document -->
<action id="custom-action" type="link" label="customaction">
<evaluator>evaluator.doclib.indicator.exifMetadata</evaluator>
</action>
</actions>

Related

alfresco evaluator on custom component

I've made a component and I'd like to show that component on the document-details page only if the document has a certain aspect, so I tried to use an evaluator. I've added this bean in custom-slingshot-application-context.xml
<bean id="evaluator.doclib.metadata.hasInvoiceAspect"
parent="evaluator.doclib.action.propertyNotNull">
<property name="property" value="inv:invoice"/>
</bean>
In document-details.xml I added this
<component>
<region-id>custom-comp</region-id>
<sub-components>
<sub-component id="default">
<evaluations>
<evaluation>
<evaluators>
<evaluator type="evaluator.doclib.metadata.hasInvoiceAspect"/>
</evaluators>
<url>/components/custom/custom-comp</url>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
I guess I've missed something as the component doesn't show up. I have 2 files named custom-slingshot, I tried both tomcat/shared/classes/alfresco/web-extension and tomcat/webapps/share/WEB-INF/classes/alfresco/web-extension.
Am I completely wrong with this? Is it possible to achieve what I want like that? How should I proceed?
There is a predefined evaluator to check whether a node has an aspect called evaluator.doclib.action.hasAspect. You simply need to create a bean with this evaluator as the parent and give an aspect to check against in the properties:
*added to some -context.xml in web-extension
<bean id="my.custom.evaluator" parent="evaluator.doclib.action.hasAspect">
<property name="aspects">
<list>
<value>my:hasInvoiceAspect</value>
</list>
</property>
</bean>
Then you'll reference that bean in your DocLibActions config added to *extension-modules.xml (web-extension/site-data/extensions)...
<config condition="DocLibActions" evaluator="string-compare">
<actions>
<action...>
<!-- Custom evaluator -->
<evaluator>my.custom.evaluator</evaluator>
</action>
</actions>
</config>
Voila.
More info on predefined evaluators.
Good sample project here.

How can I share content-properties between templates

I have different templates.
default
category
article
overview
They share some properties like the text-editor with it's settings.
<property name="article" type="text_editor">
<meta>
<title lang="de">Inhalt</title>
<title lang="en">Content</title>
</meta>
<params>
<param name="table" value="true"/>
<param name="link" value="true"/>
<param name="paste_from_word" value="true"/>
<param name="height" value="200"/>
<param name="max_height" value="2000"/>
<!-- CKEditor Parameters examples: -->
<param name="extra_allowed_content" value="img(*)[*]; span(*)[*]; div(*)[*]; iframe(*)[*]; script(*)[*]" />
</params>
</property>
I don't want to duplicate the configuration and instead link it from somewhere?
I did not find anything about it in the Sulu-Docs, but I'm sure there is a solution for this.
We've already been thinking about some kind of import functionality, but we haven't implemented that yet, and it has not the highest priority, and would make certain things a bit more complex.
But what you could do until then, is to inherit from the TextEditor Content Type, put your default values in there, register it as a new content type, and use this one instead. Then you would at least save typing the parameters all the time.
If you like you might also be able to use Symfony's Bundle Inheritance feature.
I don't know the Sulu tool but in symfony if you want to factoring code in twig template, you can use the macro twig : Twig macro doc
create a macro file in twig format
import macro file in your template specific page
use a macro in your macro file with call the name of the macro (not the file but the inside macro name file)
With this you can also call the function macro with parameter. For each page generate call this macro with few differents aspects for generate few differents party of this factoring code.

How to use VelocityLayoutViewResolver in spring-webmvc with velocity

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="prefix" value="" />
<property name="suffix" value=".vm"></property>
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="layoutUrl" value="layout/default.vm" />
</bean>
how the key word "layoutUrl" work in VelocityLayoutViewResolver?
Its very common to have a dynamic web page divided into a layout part and a content part. The layout part might consist of a header, a footer, a sidebar, a navigation and so on. Elements meant to look more or less the same on every response, that is. But the content part differs, because that's where the action goes on, right?
Layout and content should be kept apart in different .vm files, so that the layout has to be designed (and changed) only once and the content part doesn't have to repeat anything.
The question is how to put those two parts together on each response. One approach is to parse the layout file in every content file. But as the layout usually wraps the content this very likely leads to more than one parsed layout file per content file.
A better way is to reverse that and to merge the content into the layout. This is way easier to handle. All you have to do is to declare a .vm file to work as the general layout file. In this file you put a var named $screen_content and magically the view you returned in your controller at a certain request is blended in at that spot.
Your layoutUrl property tells path and file name of your layout file relative to the resourceLoaderPath you have declared in this bean
<bean
id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<beans:property name="resourceLoaderPath" value="/WEB-INF/templates/" />
</bean>
Following your example...
<bean
id="viewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
...
<property name="layoutUrl" value="layout/default.vm" />
</bean>
...your layout file has to be /WEB-INF/templates/layout/default.vm

Alfresco: Finding out the type of a piece of content

When I log into http://localhost:8080/alfresco I can navigate to a folder and see four content items. So far so good. But there is no indication as to what the type is of each content type, except for a PDF icon.
Is there a way for me to specify an icon for my custom content types?
I would like the icon to be dependent on my custom type.
<types>
<type name="sc:doc">
<title>Someco Content</title>
<parent>cm:content</parent>
<icon>boring-icon.png</icon> <-- something like this
</type>
<type name="sc:marketingDoc">
<title>Marketing Document</title>
<parent>bnp:doc</parent>
<icon>fancy-marketing-icon.png</icon> <-- something like this
</type>
</types>
If it matters, I am using Alfresco 3.3 (Enterprise).
Take a look here http://docs.alfresco.com/3.4/tasks/kb-code-explorer-add.html
e.g. web-client-config-custom.xml (sc:marketingDocis the Alfresco content type):
<!-- Specify icon for the kb:document instances -->
<config evaluator="string-compare" condition="sc:marketingDoc icons">
<icons>
<icon name="sc_marketingDoc-icon" path="/images/icons/your_custom_icon.gif" />
</icons>
</config>
Are you informed, that Alfresco Explorer is deprecated & you should use Share instead?

Alfresco Share - Dynamic rendering of fields in a form

My question is more or less in the title, I added a new data type in my data model.
<type name="moi:montype">
<title>titre type</title>
<parent>cm:content</parent>
<mandatory-aspects>
<aspect>moi:monaspect</aspect>
</mandatory-aspects>
</type>
This one uses a new aspect in which I added a new field
<aspect name="moi:monaspect">
<title>titre aspect</title>
<properties>
<property name="moi:monchamp">
<type>d:text</type>
<mandatory>false</mandatory>
</property>
...
</properties>
</aspect>
I then displayed this new field in a Share form by editing the file share-config-custom.xml.
<config evaluator="node-type" condition="moi:montype">
<forms>
<form>
<field-visibility>
<show id="moi:monchamp"/>
...
</field-visibility>
<appearance>
<field id="moi:monchamp" label="Champ texte" />
...
</appearance>
</form>
</forms>
</config>
Till then, I could test my changes and the new field displays well.
But I would like to go further, and condition for example the display of the field depending on the logged in user's group.
If the logged in user is part of the "priviledged group", then the field is displayed, otherwise it will not, or only in read only mode.
Do you think we can do this ? And how ?
I looked at documentation, but can't find my happiness.
I don't ask for the full solution, but for tips to follow.
Thank you for your help.
Every field has a component renderer. These are implemented using FreeMarker. Most of the time, as in your case, you are relying on the default component renderer. In addition to the options mentioned by Matjaz, another option would be to point the field at a custom renderer. The renderer could inspect the user's group membership and the group required for this field (maybe passed in as an argument, for example), and then decide whether or not to show itself.
There are a few ways to do this.
The easiest way is to make a webscript which returns html for a form field based on if a current logged in user is in your target group. Then add a form control which is only javascript making an ajax call to the webscript and and appending results to your container div which is specified in your form control (ftl).
The second approach you could use is to extend "org.alfresco.repo.forms.processor.AbstractFilter" and implement the functionality in Java. You could probably implement after generate and remove the form field if current logged in user is not in a target group.
Hope this helps a bit... :)
There is no easy way to do this as alfresco does not allow you to set rights on node properties.
Every field has control template, you could define your own. in your template you would define how this property is rendered depending of user type.
<config evaluator="node-type" condition="cm:content">
<forms>
<form>
<appearance>
<field id="cm:title">
<control template="/org/alfresco/components/form/controls/yourOwnFtl.ftl" />
</field>
</appearance>
</form>
</forms>
</config>
Another approach is to write your own share config form evaluator (like node-type ...)
This could check for node type and user permission role/group
let you write one config for each setup (per user group/role)
...
NB! this will one work for forms, so is purely a cosmetical setup, alfresco interface and CIFS etc. will not support this setup.

Resources