Alfresco Share Customization for Advanced Search - alfresco

I am trying to modify share-config-custom.xml so that I can search emails by the following properties:
<!-- cm:emailed aspect -->
<show id="cm:originator" />
<show id="cm:addressee" />
<show id="cm:addressees" />
<show id="cm:sentdate" />
<show id="cm:subjectline" />
This is my share-config-custom.xml:
<config evaluator="model-type" condition="cm:content">
<forms>
<form label="Mails">
<field-visibility>
<show id="cm:originator" />
<show id="cm:addressee" />
<show id="cm:addressees" />
<show id="cm:sentdate" />
<show id="cm:subjectline" />
</field-visibility>
</form>
</forms>
</config>
<config evaluator="string-compare" condition="AdvancedSearch">
<advanced-search>
<!-- Forms for the advanced search type list -->
<forms>
<!--
The 'form' config element contains the name of the model type
of the form to display.
The element supports the following optional attributes:
id = form id, the id of "search" will be assumed if not set
label = label text to display - defaults to model type if not set
labelId = I18N message id of label text to display
description = description text to display
descriptionId = I18N message id of description text to display
-->
<form labelId="Mails" descriptionId="Search for Mails">cm:content</form>
</forms>
</advanced-search>
And it doesn't work. I have tried aspect, node-type instead of model-type. I used many combination of force="true", for-mode="view" ... still couldn't get it work. In the search form I can't see anything related to the properties. It's just a default search form. Any help will be appreciated.
up: To be clear, the problem is that I have some documents with cm:emailed aspect. I want to create a form for only searching such documents. However, when I say "<form labelId="Mails" descriptionId="Search for Mails">cm:content</form> " the default content search form also modified. I believe that there must be some easy way or ways. I don't want to define a new type in my custom model, I leave this solution for the last.

The share config isn't correct. Take a look at https://wiki.alfresco.com/wiki/Share_Advanced_Search#Search_Forms
You need to change the model-type of cm:content form id="search" with the aspect fields.
I'm on the phone so the answer maybe short.
--UPDATE--
You can't select an Aspect in the drop-down in the Advanced Search, the current implementation of Alfresco doesn't allow that.
You what I do in most cases, I just add the aspect fields to the default cm:content type.
Or when I have more control on when the aspect is applied, I just create a new type custom:mailed and have the parent cm:content and as mandatory aspect cm:emailed. Then you could create a behaviour which specialized the type to custom:mailed or create an inbound rule in Alfresco which fires on hasAspect cm:emailed.
I hope this clears a bit.

Related

How to edit template-instance of start workflow page in Alfresco Share?

I want to add a upload button the start-workflow page and for that i need to add upload component xml tags as follows in template instance:
<component>
<region-id>html-upload</region-id>
<url>/components/upload/html-upload</url>
</component>
<component>
<region-id>flash-upload</region-id>
<url>/components/upload/flash-upload</url>
</component>
<component>
<region-id>file-upload</region-id>
<url>/components/upload/file-upload</url>
</component>
<component>
<region-id>dnd-upload</region-id>
<url>/components/upload/dnd-upload</url>
</component>
<component>
<region-id>archive-and-download</region-id>
<url>/components/download/archive</url>
</component>
Why you wanted to add a upload button to the start-workflow page alfresco OOTB provides the workflow package you can attach your documents here.
You just need to define it in share config
<config evaluator="string-compare" condition="activiti$submitDocument">
<forms>
<form>
<field-visibility>
<show id="packageItems" />
</field-visibility>
<appearance>
<set id="general" appearance="title" label-id="workflow.set.other" />
<field id="packageItems" set="general" label="Purchase request document">
<control template="/org/alfresco/components/form/controls/workflow/packageitems.ftl">
</control>
</field>
</appearance>
</form>
</forms>
</config>
and you can get all the attached document using javascript
var documents = bpm_package.children;
It was as simple and obvious as it could have been. All you need to do is create a file named start-workflow.xml in the directory src/main/resources/alfresco/web-extension/site-data/template-instances. Then just copy paste the original file and add your components. This isn't enough in itself. You also have to add regions of these components to the template of start-workflow. Again, a simple process. Create a file start-workflow.ftl in the directory src/main/resources/alfresco/web-extension/site-data/templates/org/alfresco. Once again copy paste the original file and add your regions. In my case it was :
<#region id="html-upload" scope="template"/>
<#region id="flash-upload" scope="template"/>
<#region id="file-upload" scope="template"/>
<#region id="dnd-upload" scope="template"/>
<#region id="archive-and-download" scope="template"/>

Activiti workflow: setting value of an aspect from StartTask

I need to set a value from a text field on my start form and then pull this information on several other tasks. To do this, I'm using an aspect and trying to send the data up to the execution variable, and then pull it down.
The problem is that I cannot send the value from the start form to the execution variable. As it is now, Share will just say that the workflow cannot be started.
I am using Alfresco 4.2.f Community edition.
The start event is defined in the BPMN as follows:
<startEvent id="start" name="Start Delivery Ticket Workflow" activiti:initiator="initiatorUserName" activiti:formKey="deliveryTicketWorkflow:start">
<documentation>Project Manager initiates workflow. A customer purchase order is provided, along with the specific line items for the delivery ticket.</documentation>
<extensionElements>
<activiti:executionListener class="org.alfresco.repo.workflow.activiti.listener.ExecutionListener" event="start">
<activiti:field name="script">
<activiti:string><![CDATA[
execution.setVariable('deliveryTicketWorkflow_requestdetailstext', task.getVariable('deliveryTicketWorkflow_requestdetailstext'));;
]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</startEvent>
The relevant parts of my model are:
<type name="deliveryTicketWorkflow:start">
<parent>bpm:startTask</parent>
<properties />
<associations />
<overrides />
<mandatory-aspects>
<aspect>deliveryTicketWorkflow:requestdetails</aspect>
</mandatory-aspects>
</type>
[...]
<aspect name="deliveryTicketWorkflow:requestdetails">
<properties>
<property name="deliveryTicketWorkflow:requestdetailstext">
<title>Specific Details</title>
<type>d:text</type>
<mandatory>true</mandatory>
<multiple>false</multiple>
</property>
</properties>
</aspect>
In the config:
<config condition="deliveryTicketWorkflow:start" evaluator="task-type">
<forms>
<form>
<field-visibility>
<show id="packageItems"/>
<show id="deliveryTicketWorkflow:requestdetailstext"/>
<show id="transitions"/>
</field-visibility>
<appearance>
<set appearance="title" label-id="Prepare Delivery Ticket" id="info"/>
<field set="info" id="packageItems"/>
<field set="info" label-id="Request Details" id="deliveryTicketWorkflow:requestdetailstext">
<control template="/org/alfresco/components/form/controls/info.ftl"/>
</field>
<set id="response"/>
<field set="response" id="transitions"/>
</appearance>
</form>
</forms>
</config>
[...]
<config condition="activiti$deliveryTicketWorkflow" evaluator="string-compare">
<forms>
<form>
<field-visibility>
<show id="bpm:workflowPriority"/>
<show id="packageItems"/>
<show id="deliveryTicketWorkflow:requestdetails"/>
<show id="transitions"/>
<show id="deliveryTicketWorkflow:approveRejectOutcome"/>
</field-visibility>
<appearance>
<set appearance="title" label-id="Request Delivery Ticket" id="info"/>
<field set="info" label-id="workflow.field.priority" id="bpm:workflowPriority">
<control template="/org/alfresco/components/form/controls/workflow/priority.ftl"/>
</field>
<field set="info" id="packageItems"/>
<field set="info" label-id="Request Details" id="deliveryTicketWorkflow:requestdetails">
<control template="/org/alfresco/components/form/controls/textarea.ftl"/>
</field>
<set id="response"/>
<field set="response" id="approveRejectOutcome">
<control template="/org/alfresco/components/form/controls/workflow/activiti-transitions.ftl"/>
</field>
<field set="response" id="transitions"/>
</appearance>
</form>
</forms>
</config>
I have seen at least one question here that was similar, but the answers were stating to use task listeners for the start form. I'm not sure at all how that is intended to function, because it seems like a start task isn't a "true" task and can only use ExecutionListeners. The difference should be small, but it seems that any reference to "task" in the start task will either cause a failure or just have no affect at all. Becasue I can't use task.getVariableLocal() to get the value, I don't see what to give to execution.setVariable() as the value.
In my experience, all values of aspects and properties in a start task are automatically copied to the executionContext and are already available for future tasks.
Try removing the executionlistener in your BPMN, you shouldnt need that. Then try making a starttasklistener on your subsequent task that copyies the value from your execeutioncontext into this task. It should work fine.
Getting the var back from your executioncontext in your subsequent task should work like this:
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="language" stringValue="groovy" /
<activiti:field name="script">
<activiti:string><![CDATA[
System.out.println(execution.getVariable("deliveryTicketWorkflow_requestdetailstext"));
if (execution.getVariable("deliveryTicketWorkflow_requestdetailstext") != null){
task.setVariableLocal('deliveryTicketWorkflow_requestdetailstext', execution.getVariable("deliveryTicketWorkflow_requestdetailstext"));
}]]>
</activiti:string>
</activiti:field>
</activiti:taskListener>
This is a long shot but in your share form, your custom field is using the info control:
I believe you need there to be a regular field there, the info field is to display text, AFAIK, it doesn't include an input field and won't send anything to the workflow start.

How to populate property value while creating content in Alfresco Share?

I create a product of type abc:product with a product Id - 12345 (for example) in the abc:productId field.
I have a type called abc:productContent with the abc:productNumber field. Now when I'm creating the document of type abc:productContent, I'm trying to populate the abc:productNumber field with the value of the above mentioned product Id of abc:product object (and make the field read only).
How to achieve the above?
Thank you for the help
You need a form definition such as:
<alfresco-config>
<!-- ... -->
<config evaluator="model-type" condition="abc:productContent">
<forms>
<form>
<field-visibility>
<!-- ... other fields -->
<show id="abc:productNumber"/>
<!-- ... more fields -->
</field-visibility>
<appearance>
<!-- ... other fields -->
<field id="abc:productNumber" mandatory="true">
<control template="/xxx/value-from-url.ftl" />
</field>
<!-- ... even more ...>
</appearance>
</form>
</forms>
</config>
<!-- ... -->
<alfresco-config>
Append the a parameter with the productNumber value you want to the create-content link in the dashlet.
In your custom value-from-url.ftl (see /org/alfresco/components/form/controls/*.ftl for examples), get the value from the url and put it in the input field.

Alfresco CMS issues

We have Alfresco (Community Edition 4.2) environment set on Server. WE created some websites and Custom content model and deployed on server.
We are facing following issues which need to resolved.
RTF Field : In custom content model we have defined a rtf field. This rtf field is not saving its value.
Folder Creation: There is no option available to create Folders in Document library.
Web Script Query: We need to write webscript queries to fetch the data for each website separately.
following is code from share-forms-config for RTF fields
<config evaluator="node-type" condition="custom:questionscategory">
<forms>
<!-- Default form configuration for the cm:content type -->
<form>
<field-visibility>
<show id="cm:name" />
<show id="custom:categoyTitle" />
<show id="custom:categoryDesc" />
</field-visibility>
<appearance>
<field id="custom:categoryDesc">
<control template="/org/alfresco/components/form/controls/richtext.ftl">
<control-param name="editorAppearance">full</control-param>
</control>
</field>
</appearance>
</form>
<form id="doclib-simple-metadata">
<field-visibility>
<show id="cm:name" />
<show id="custom:categoyTitle" />
<show id="custom:categoryDesc" />
</field-visibility>
<appearance>
<field id="custom:categoryDesc">
<control template="/org/alfresco/components/form/controls/richtext.ftl">
<control-param name="editorAppearance">full</control-param>
</control>
</field>
</appearance>
</form>
</forms>
</config>
<config evaluator="model-type" condition="custom:questionscategory">
<forms>
<!-- Default form configuration for the cm:content type -->
<form>
<field-visibility>
<show id="cm:name" />
<show id="custom:categoyTitle" />
<show id="custom:categoryDesc" />
</field-visibility>
<appearance>
<field id="custom:categoryDesc">
<control template="/org/alfresco/components/form/controls/richtext.ftl">
<control-param name="editorAppearance">full</control-param>
</control>
</field>
</appearance>
</form>
</forms>
</config>
here is the query I have written to fetch data..I need to add website name to it
// locate folder by path
// NOTE: only supports path beneath company home, not from root
var query='TYPE:custom\:questionscategory';
var fbaQuetions = search.luceneSearch(query);
if (fbaQuetions== undefined || fbaQuetions.isContainer)
{
status.code = 404;
status.message = "fbaQuetions " + url.extension + " not found.";
status.redirect = true;
}
model.folder = fbaQuetions;
For number 2. The answer probably lies in lack of permissions, make sure you have the right privileges in the site, that is at least contributor.
To answer your other questions we need more information:
What do you mean by RTF-field? What datatype are we talking about? Could you post snippets from your custom model togheter with the appropriate share-forms-config section?
There are a lot of webscripts present to fetch data per site. In fact Alfresco Share only uses webscripts to talk to the repository. What data do you need?
Update: Extend your search query with a "+PATH" which searches just in your site expression.
ie: "PATH:"/app:company_home/st:sites/cm:yoursiteshortname//*"
This looks like a bug that has been patched, I've got a similar problem.
https://issues.alfresco.com/jira/browse/MNT-10238?jql=text%20~%20%22r57658%22
I'm going to upgrade to get the patch.

Is it possible to make document picker default to document library in alfresco share?

I have a copy of association.ftl which I use for a control added to the advanced search form in share. Unfortunately when opened the default display is companyhome where as I'd rather have it default to the related site's document library.
I read this wiki and also tried the changing the parentNodeRef value in the javascript to at least add sites to the path to no success.
The share form config control:
<config evaluator="model-type" condition="cm:content">
<forms>
<!-- Search form -->
<form id="search">
<field-visibility>
<show id="cm:name" force="true" />
<show id="space" force="true" />
</field-visibility>
<appearance>
<field id="cm:name" label-id="prop.search.cm_name" />
<field id="space" label-id="prop.search.cm_search_in_folder" >
<control template="/org/alfresco/components/form/controls/space.ftl">
<control-param name="startLocation">{doclib}</control-param>
</control>
</field>
</appearance>
</form>
</forms>
</config>
The freemarker control file :
<#include "common/picker.inc.ftl" />
<#assign controlId = fieldHtmlId + "-cntrl">
<script type="text/javascript">//<![CDATA[
(function()
{
<#renderPickerJS field "picker" />
picker.setOptions(
{
<#if field.control.params.showTargetLink??>
showLinkToTarget: ${field.control.params.showTargetLink},
<#if page?? && page.url.templateArgs.site??>
targetLinkTemplate: "${url.context}/page/site/${page.url.templateArgs.site!""}/document-details?nodeRef={nodeRef}",
<#else>
targetLinkTemplate: "${url.context}/page/document-details?nodeRef={nodeRef}",
</#if>
</#if>
<#if field.control.params.allowNavigationToContentChildren??>
allowNavigationToContentChildren: ${field.control.params.allowNavigationToContentChildren},
</#if>
itemType: "cm:folder",
multipleSelectMode: false,
parentNodeRef: "alfresco://company/home/sites", //<== Not the default path
<#if field.control.params.rootNode??>
rootNode: "${field.control.params.rootNode}",
</#if>
itemFamily: "node",
displayMode: "${field.control.params.displayMode!"items"}"
});
})();
//]]></script>
<div class="form-field">
<#if form.mode == "view">
<div id="${controlId}" class="viewmode-field">
<span class="viewmode-label">${field.label?html}:</span>
<span id="${controlId}-currentValueDisplay" class="viewmode-value current-values"></span>
</div>
<#else>
<label for="${controlId}">${field.label?html}:</label>
<div id="${controlId}" class="object-finder">
<div id="${controlId}-currentValueDisplay" class="current-values"></div>
<input type="hidden" id="${fieldHtmlId}" name="-" value="${field.value?html}" />
<input type="hidden" id="${controlId}-added" name="${field.name}_added" />
<input type="hidden" id="${controlId}-removed" name="${field.name}_removed" />
<div id="${controlId}-itemGroupActions" class="show-picker"></div>
<#renderPickerHTML controlId />
</div>
</#if>
</div>
The wiki is pretty clear on how to do this:
Supply a startLocation as parameter to the picker in the forms-config, since you want to go with the documentLibrary of the site the user searches from I would recommend you to implement a NodeLocator as described in the wiki:
https://wiki.alfresco.com/wiki/NodeLocatorService
In fact that seems to already have been implemented for you and seems to reside in the alfresco source:
http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/COMMUNITYTAGS/V4.2e/root/projects/repository/source/java/org/alfresco/repo/site/DocLibNodeLocator.java
However I cant find the bean declaration so you might have to add it to your spring-bean definitions (or copy the source to an own implementation) to be able to use it properly.

Resources