<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>processed.info</title>
	<atom:link href="http://blog.processed.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.processed.info</link>
	<description>processed information from me to you</description>
	<lastBuildDate>Thu, 20 May 2010 14:16:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>No Custom Constraints for Associations in Alfresco</title>
		<link>http://blog.processed.info/2010/05/no-custom-constraints-for-associations-in-alfresco/</link>
		<comments>http://blog.processed.info/2010/05/no-custom-constraints-for-associations-in-alfresco/#comments</comments>
		<pubDate>Thu, 20 May 2010 14:16:23 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Alfresco]]></category>
		<category><![CDATA[Alfresco 3.3CE]]></category>
		<category><![CDATA[association]]></category>
		<category><![CDATA[behavior]]></category>
		<category><![CDATA[category browsing]]></category>
		<category><![CDATA[custom constraint]]></category>
		<category><![CDATA[share]]></category>

		<guid isPermaLink="false">http://blog.processed.info/?p=56</guid>
		<description><![CDATA[Unfortunately I was wrong when I stated that the restriction for an association to a specific subfolder &#8220;can be cross checked server-side and configured directly within the  content model using a custom constraint.&#8221; (compare my blog entry on custom categories)
Why? Cause custom constraints are only possible for properties &#8211; not for associations. Too bad [...]]]></description>
			<content:encoded><![CDATA[<p>Unfortunately I was wrong when I stated that the restriction for an association to a specific subfolder &#8220;can be cross checked server-side and configured directly within the  content model using a <a title="Writing Further  Constraints" href="http://wiki.alfresco.com/wiki/Constraints#Writing_Further_Constraints" target="_blank">custom constraint</a>.&#8221; (compare my blog entry on <a title="Custom Categories - A Custom Control Template for Hierarchical Properties" href="http://blog.processed.info/2010/04/custom-categories-a-custom-control-template-for-hierarchical-properties/" target="_self">custom categories</a>)</p>
<p>Why? Cause custom constraints are only possible for properties &#8211; not for associations. Too bad as I had the constraint nearly implemented. *sigh* I would really appreciate it if Alfresco could implement this functionality also for associations. And by the way &#8211; could also a built-in constraint for subfolder-selections be integrated? This would make my work-around unnecessary.</p>
<p>However, while the custom constraint thing didn&#8217;t work, I managed to implement a comparable functionality to the built-in category browsing for my custom categories: I implemented a <a title="New Alfresco tutorial on implementing custom behaviors" href="http://ecmarchitect.com/archives/2007/09/26/770" target="_blank">Behavior</a> that creates respectively removes links in the linked to custom category folder. This allows to browse for documents by browsing the custom-category folders. And this is easily possible from within share through the new <a title="Enabling Share Repository Document Library" href="http://wiki.alfresco.com/wiki/Enabling_Share_Repository_Document_Library" target="_blank">Repository Link</a>. :) Stay tuned &#8211; a tutorial will soon be published on this blog.</p>
<p><strong>PS: Is there someone else having a similar <a title="Custom Categories - A Custom Control Template  for Hierarchical Properties" href="../2010/04/custom-categories-a-custom-control-template-for-hierarchical-properties/" target="_self">use-case</a> than I have? How do or would you solve it?</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.processed.info/2010/05/no-custom-constraints-for-associations-in-alfresco/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom Categories &#8211; A Custom Control Template for Hierarchical Properties</title>
		<link>http://blog.processed.info/2010/04/custom-categories-a-custom-control-template-for-hierarchical-properties/</link>
		<comments>http://blog.processed.info/2010/04/custom-categories-a-custom-control-template-for-hierarchical-properties/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 13:53:23 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Alfresco]]></category>
		<category><![CDATA[Alfresco 3.3 CE]]></category>
		<category><![CDATA[custom content model]]></category>
		<category><![CDATA[custom control template]]></category>
		<category><![CDATA[share]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.processed.info/?p=20</guid>
		<description><![CDATA[This tutorial describes how to integrate a custom control template (custom UI element for share) for displaying and selecting from a hierarchical structure in Alfresco 3.3. Such an element can be used to assign category-like values to a property. Opposed to the built-in category-function of Alfresco these custom categories can be assigned to specific properties [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial describes how to integrate a custom control template (custom UI element for share) for displaying and selecting from a hierarchical structure in Alfresco 3.3. Such an element can be used to assign category-like values to a property. Opposed to the built-in category-function of Alfresco these custom categories can be assigned to specific properties and are safe in regard to which categories are displayed respectively selectable.</p>
<p><span id="more-20"></span></p>
<h3><strong>Problem Description</strong></h3>
<p>Often, properties need to be protected from duplicate values due to misspelling or ambiguity. A common solution is to let users select from a predefined list which can easily be done in Alfresco <a title="Content Model Constraints" href="http://wiki.alfresco.com/wiki/Constraints" target="_blank">using the list constraint</a>. However, somtimes you also need the flexibility to define the options during runtime which means that you either need a combobox (opposed to a drop-down list) or a way to implement dynamic lists which are populated during runtime and obtain their values from a runtime configurable source. While comboboxes are not supported at all by Alfresco <a title="Dynamic Data-Driven Drop Downs for List Properties" href="http://blogs.alfresco.com/wp/jbarmash/2008/08/08/dynamic-data-driven-drop-downs-for-list-properties/" target="_blank">Jean Barmash proposes a good solution</a> for dynamic lists based on a Lucene search.</p>
<p>However, sometimes a flat list just doesn&#8217;t meet the requirements as you might need to be able to select your values from a hierarchical structure. While you would be able to use the built-in category functionality of Alfresco this would not allow you to assign properties a specific kind of category respectively restrict the selectable values.</p>
<p>An example for such a need (which will also be used as an example for this tutorial) is an aspect that defines the place where a document is physically filed (for instance to define that your fire insurance policy is filed in the accountancy office in the suspension files of Ms. Brown&#8217;s desk within the folder insurances: Accountancy Office / Desk Ms. Brown / Suspension Files / Folder Insurances).</p>
<h3><strong>Proposed Solution</strong></h3>
<p>The solution described in this tutorial uses a folder structure to define custom categories and a custom control template to render a UI element which restricts the selection of the value(s) to this structure. The value itself is thereby an association to the selected folder(s).</p>
<p>This solution offers a comparable functionality to the built-in categories of Alfresco. However, it does not offer the possibility to browse through the categories so far. This would need scripts that automatically create links within the associated folders and is not covered within this tutorial. Advantages of this solution opposed to the built-in categories are:</p>
<ul>
<li>Categories can be defined for specific types or aspects.</li>
<li>More than one category property can be defined which is restricted to a specific kind of category.</li>
<li>Single and multiple value selection is possible.</li>
<li>Custom categories can be directly managed from within share (using the <a title="Enabling Share Repository Document Library" href="http://wiki.alfresco.com/wiki/Enabling_Share_Repository_Document_Library" target="_blank">share repository document library</a> of Alfresco 3.2 EE / 3.3 CE).</li>
<li>Categories can easily be moved with an immediate effect on the associated documents. In our example you could for instance move a (physical) folder to another room and represent that change by also moving the folder within Alfresco. All documents within this folder will automatically represent this change.</li>
</ul>
<p>Please note: Within this tutorial, the restriction of values to a specific kind of category is reached only by restricting the UI. However, this restriction can be cross checked server-side and configured directly within the content model using a <a title="Writing Further Constraints" href="http://wiki.alfresco.com/wiki/Constraints#Writing_Further_Constraints" target="_blank">custom constraint</a>.</p>
<h3>Tutorial</h3>
<p>The following tutorial will show the main steps, code snippets and screenshots to implement a custom aspect for defining the place of physically filed documents. It is assumed that you have first experiences in defining a custom data model. Thus these steps will be explained rather quickly. However, feel free to ask questions in the comments if there is something that you do not understand.</p>
<p>Please mind that I&#8217;m not a native speaker and that I&#8217;m using a customized Alfresco 3.3 CE with the german language pack (unfortunately still of version 3.2 CE). Thus the screenshots might look a little bit odd to you. Anyhow, I&#8217;m pretty sure they will support your comprehension. Thank you for your understanding.</p>
<h4>Creating the Custom Category Folder Structure</h4>
<p>This is probably the most simple step of this tutorial. Create a main folder which will hold all custom categories of your company. I chose to create a folder called <em>Company Categories</em> within the root folder of the repository (<em>Company Home</em>).</p>
<p>Now create a folder for the filing places structure (called <em>Ablageort</em> in the screenshot) within this folder and herein in turn one folder for each filing place you have.</p>
<p><a href="http://blog.processed.info/wp-content/uploads/2010/04/filing_places_structure.png"><img class="alignnone size-medium wp-image-49" title="filing_places_structure" src="http://blog.processed.info/wp-content/uploads/2010/04/filing_places_structure-300x167.png" alt="" width="300" height="167" /></a></p>
<h4>Adding the Filed Aspect</h4>
<p>Will Abson describes how to add a custom aspect and enable it in share <a title="Adding Custom Aspect Support in Alfresco Share" href="http://blogs.alfresco.com/wp/wabson/2010/02/25/adding-custom-aspect-support-in-alfresco-share/" target="_blank">in this blog post</a>. Following is the definition of the filed aspect as it is defined in the <em>something-model.xml </em>(<em>kb-model.xml</em> in Will Abson&#8217;s blog post):</p>
<pre>&lt;!-- Filed Aspect --&gt;
&lt;aspect name="cl:filed"&gt;
   &lt;title&gt;Filed&lt;/title&gt;
   &lt;associations&gt;
      &lt;association name="cl:place"&gt;
         &lt;title&gt;Place&lt;/title&gt;
         &lt;source&gt;
            &lt;mandatory&gt;false&lt;/mandatory&gt;
            &lt;many&gt;true&lt;/many&gt;
         &lt;/source&gt;
         &lt;target&gt;
            &lt;class&gt;cm:folder&lt;/class&gt;
            &lt;mandatory&gt;false&lt;/mandatory&gt;
            &lt;many&gt;false&lt;/many&gt;
         &lt;/target&gt;
      &lt;/association&gt;
   &lt;/associations&gt;
&lt;/aspect&gt;
</pre>
<p>As you can see, we define the filing place as an association to one folder. For other custom categories you might want to allow the selection of multiple values. Therefore you need to change the <em>&lt;many&gt;</em><em> </em>tag of the association&#8217;s <em>&lt;target&gt;</em> definition to <em>true</em>.</p>
<h4>Defining a Custom Control Template</h4>
<p>Now that we have an aspect allowing us to reference a folder as a filing place we need a custom control template which renders us a UI element for selecting the specific place from out filing places structure. Unfortunately, the association picker Alfresco uses per default for selecting an association does not allow to restrict the selection of an association&#8217;s target. It would rather allow to select any folder and would further start the process of selection in the repository root folder. Thus, we have to implement this functionality ourselves.</p>
<p>The freemarker template used for rendering the association UI element is <em>alfresco/tomcat/webapps/share/WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/form/controls/association.ftl</em>. This template uses the JavaScript <em>ObjectFinder </em>which is indirectly referenced through the <em>picker.inc.ftl</em> template from the <em>common</em> subfolder. The <em>ObjectFinder </em>itself is defined in <em>alfresco/tomcat/webapps/share/components/object-finder/object-finder.js</em>.</p>
<p>In order to customize how the association picker is rendered we would have to either duplicate or overwrite these files, whereas both would be quite ugly solutions. However, we can apply a trick to inject our customization during runtime. This solution leaves us with duplicating and adjusting only one file: <em>association.ftl</em>. For convenience I upoaded the adjusted file: <a title="category_association.ftl" href="http://files.processed.info/category_association.ftl" target="_blank">category_association.ftl</a>. This file needs to be placed in <em>alfresco/tomcat/shared/alfresco/web-extension/site-webscripts/</em>. Following I will describe the adjustments I made:</p>
<p><span style="text-decoration: underline;">Render only folders starting with the custom categorie&#8217;s root folder</span></p>
<p><span style="text-decoration: underline;"><a href="http://blog.processed.info/wp-content/uploads/2010/04/edit_metadata_choose.png"><img class="alignnone size-medium wp-image-46" title="edit_metadata_restrict" src="http://blog.processed.info/wp-content/uploads/2010/04/edit_metadata_choose-300x159.png" alt="" width="300" height="159" /></a><br />
</span></p>
<p>In order to skip the rendering of folders above the one holding our specific custom categories we need to tell the object picker to start within this folder and further to forget all folders which are above. The first can easily be done by setting the corresponding option:</p>
<pre>&lt;#if field.control.params.startWithinSelectedCategory?exists&gt;
   &lt;#if field.value != ""&gt;
parentNodeRef: "${field.value}",
   &lt;#else&gt;
parentNodeRef: "${field.control.params.parentNodeRef}",
   &lt;/#if&gt;
&lt;#else&gt;
parentNodeRef: "${field.control.params.parentNodeRef}",
&lt;/#if&gt;
parentNodeRef: "${field.control.params.parentNodeRef}",
&lt;/#if&gt;
</pre>
<p>The nested if-statements thereby allows to configure whether to start within a previously selected category folder or not. This is done by setting the <em>startWithinSelectedCategory </em>option. The category&#8217;s root folder is configured in the <em>parentNodeRef </em>property. More on configuring the UI widget later.</p>
<p>In order to tell the object picker to forget about the parent folders we need to change the json-object delivered by the server-side WebScript. This can be done in the <em>onParentDetails</em> function which we therefore replace with a custom version which in turn passes a tailored version of the json-object to the original function:</p>
<pre>&lt;#if field.control.params.numberOfHiddenLayers?exists&gt;
// place a custom function before the execution of the onParentDetails-function
Alfresco.ObjectFinder.prototype.onParentDetailsOriginal = Alfresco.ObjectFinder.prototype.onParentDetails;
Alfresco.ObjectFinder.prototype.onParentDetails = function(layer, args)
{
   // cut the last x parent elements
   var counter = 0;
   cut = function(node)
   {
      if (node.parent)
      {
         cut(node.parent);
         if (counter &lt; ${field.control.params.numberOfHiddenLayers})
         {
            delete node.parent;
            counter = counter + 1;
         }
      }
   }
   cut(args[1]);
   // call the original function with the modified args-parameter
   this.onParentDetailsOriginal(layer, args);
};
&lt;/#if&gt;
</pre>
<p>The <em>numberOfHiddenLayers </em>parameter needs to be configured and should always represent the number of folders above the category&#8217;s root folder.</p>
<p><span style="text-decoration: underline;">Display the full path of the custom category</span></p>
<p><span style="text-decoration: underline;"><a href="http://blog.processed.info/wp-content/uploads/2010/04/edit_metadata_show_full_path_1.png"><img class="alignnone size-medium wp-image-47" title="edit_metadata_show_full_path_1" src="http://blog.processed.info/wp-content/uploads/2010/04/edit_metadata_show_full_path_1-300x207.png" alt="" width="300" height="207" /></a><a href="http://blog.processed.info/wp-content/uploads/2010/04/edit_metadata_show_full_path_2.png"><img class="alignnone size-medium wp-image-48" title="edit_metadata_show_full_path_2" src="http://blog.processed.info/wp-content/uploads/2010/04/edit_metadata_show_full_path_2-300x202.png" alt="" width="300" height="202" /></a><br />
</span></p>
<p>In some cases you want to display the full path of the selected value(s). In our example this means to show &#8220;Accountancy Office / Desk Ms. Brown / Suspension Files / Folder  Insurances&#8221; instead of just &#8220;Folder Insurances&#8221; (which would be the default behaviour). Therefore, we again inject a custom method &#8211; this time the name of the selected item(s) is temporarily replaced with the full path, the original render method called and the item(s) renamed again:</p>
<pre>&lt;#if field.control.params.showFullPath?exists&gt;
// place a custom function before the execution of the onRenderCurrentValue-function
Alfresco.ObjectFinder.prototype.onRenderCurrentValueOriginal = Alfresco.ObjectFinder.prototype.onRenderCurrentValue;
Alfresco.ObjectFinder.prototype.onRenderCurrentValue = function(layer, args)
{
   // temporarily replace the names with the fully qualified names
   var items = this.currentValueMeta;
   var nameMap = new Array();
   for (var i = 0, ii = items.length; i &lt; ii; i++)
   {
      var item = items[i];
      var name = item.name;
      // add path to name except the last x path elements
      var pathElements = (item.displayPath + "/" + name).split("/");
      // we need to remove two more elements than configured:
      // 1st: the leading slash from item.displayPath leads to an empty element in the array
      // 2nd: we do not want to show the category name inside the path
      pathElements.splice(0,${field.control.params.numberOfHiddenLayers} + 2);
      item.name = pathElements.join(" / ");
      // save original name later restore
      nameMap[item.name] = name;
   }
   // call the original function to render the names
   this.onRenderCurrentValueOriginal(layer, args);
   // reset the names
   for (var i = 0, ii = items.length; i &lt; ii; i++)
   {
      items[i].name = nameMap[items[i].name]
   }
}
&lt;/#if&gt;
</pre>
<p><span style="text-decoration: underline;">Other adjustments</span></p>
<p>For Version 3.3 CE I needed to check whether the field really exists as otherwise an exception would have been thrown:</p>
<pre>&lt;#if field.endpointType?exists&gt;
...
&lt;/#if&gt;
</pre>
<p>The reason for this is that Alfresco 3.3 renders the property as soon as a property with a custom control template is defined for a form. It does not check whether the property exists on this document (meaning whether for instance the filed aspect is set for this document or not). However, I did not encounter this behaviour on Alfresco 3.2 CE.</p>
<p>Last we need to adjust the path to the original picker.inc.ftl template as our custom template resides in a different place:</p>
<pre>&lt;#include "org/alfresco/components/form/controls/common/picker.inc.ftl" /&gt;
</pre>
<h4>Configuring Share to use the Custom Control Template</h4>
<p>Having a custom control template we can now tell share to use this for displaying and selecting custom categories. This is generally done in the share-config-custom.xml file as described in <a title="Adding Custom Aspect Support in Alfresco Share" href="http://blogs.alfresco.com/wp/wabson/2010/02/25/adding-custom-aspect-support-in-alfresco-share/" target="_blank">Will Abson&#8217;s blog post</a>. The difference is that we define to use our custom control template for rendering the according UI element:</p>
<pre>&lt;field id="cl:place" label-id="label.cl_place" &gt;
   &lt;control template="/category_association.ftl" &gt;
      &lt;control-param name="parentNodeRef"&gt;workspace://SpacesStore/c98ddef6-1cc8-489d-aab6-5aab2f889e61&lt;/control-param&gt;
      &lt;control-param name="numberOfHiddenLayers"&gt;2&lt;/control-param&gt;
      &lt;control-param name="startWithinSelectedCategory" /&gt;
      &lt;control-param name="showFullPath" /&gt;
   &lt;/control&gt;
&lt;/field&gt;
</pre>
<p>The control parameters are (compare paragraph <em>Defining the Custom Control Template</em>):</p>
<ul>
<li>parentNodeRef: Defines the root folder of the specific category.</li>
<li>numberOfHiddenLayers: Defines the depth of the root folder and thus the number of folders or layers that need to be suppressed.</li>
<li>startWithinSelectedCategory: If set, the UI element will start browsing the custom categories within the previously selected category (in case a value is already set).</li>
<li>showFullPath: If set, the UI element will show the full path of the custom category.</li>
</ul>
<p>The URL of the custom category&#8217;s root folder is the Alfresco Node Reference which is linked on the folder&#8217;s details page in Alfresco Explorer respectively the last part of the URL (after <em>?nodeRef=</em>) of the folder&#8217;s detail page in Alfresco Share.</p>
<h3>Conclusion</h3>
<p>Defining a custom control template and injecting custom methods into the object finder seems to be a suitable solution for the described problem. However, sometimes a combobox might be the better solution and hopefully Alfresco will support this some day. What do you think? Do you have any other idea how this could be solved? Please let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.processed.info/2010/04/custom-categories-a-custom-control-template-for-hierarchical-properties/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A new blog is born</title>
		<link>http://blog.processed.info/2010/03/welcome/</link>
		<comments>http://blog.processed.info/2010/03/welcome/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 18:15:35 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://processed.info/blog/?p=7</guid>
		<description><![CDATA[I&#8217;m happy to welcome you to my new blog. While currently there is just this welcome message, this will hopefully change soon. I plan to post articles on interesting IT topics &#8211; especially on the document management system Alfresco and the new star in the programming language sky: Scala. So far I recommend to read [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to welcome you to my new blog. While currently there is just this welcome message, this will hopefully change soon. I plan to post articles on interesting IT topics &#8211; especially on the document management system <a title="Alfresco" href="http://www.alfresco.com" target="_blank">Alfresco</a> and the new star in the programming language sky: <a title="Scala" href="http://www.scala-lang.org" target="_blank">Scala</a>. So far I recommend to read the <a title="About" href="http://blog.processed.info/?page_id=2" target="_self">about page</a> to get a short overview of what this blog is about and who I am.</p>
<p>Hope you will return soon!</p>
<p>Cheers<br />
Chris</p>
<p>PS: How do you like the logo and the design in general?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.processed.info/2010/03/welcome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

