View inheritance problem - spring-webflow

I have copied this question here from spring forum.
I have a parent flow and a child flow. The parent flow has following folder structure
parent
|
|--parent-flow.xml
|--parentView.xhtml
This parent has following view-state
<view-state id="parentState" view="parentView.xhtml">
</view-state>
Child flow looks like this:
<flow ...
parent="parent">
...
<view-state id="test">
<transition on="bang" to="parentState"/>
</view-state>
...
</flow>
The problem is when I hit 'bang' action of child flow it can't see parentView.xhtml view in parent flow. I get something like this:
Code:
The requested resource (/spring/child?execution=e3s2) is not available.
If I copy parentView.xhtml into child's flow folder, everything works as a charm.
I wonder if it is a defect or it was designed to work like this? If it's a defect, then it worse opening JIRA ticket... This situation is quite common I think, for example in my case I have delete conformation screen (parent view-state) that is used in all pages where user is able to delete entities.

Workaround for the issue:
One can specify relative path in view attribute. The example below works if you specify parent view like that:
<view-state id="parentState" view="../parent/parentView.xhtml">
</view-state>

Related

How to edit Teaser's Tab options order on AEM?

I'm (trying) customizing the Teaser component on .content.xml to reach out to my requirements but I don't understand how I can set up an order to tabs options. The best solution would be to write some logic to hide/unhide the Teaser's fields based on the parent component, but I don't know how to do it yet. Meanwhile, I'm editing the XML file.
Options:
Image
Metadata
Text
Link & Actions
The first thing stranger is that I've written the code to show only three options but on AEM Editor keeping showing all options, with "Link & Actions" not declared on .XML. As you can see in the print below.
Path file: ui.apps/.../components/teaser/_cq_dialog/.content.xml
The second thing is that I want to put "Link & Actions" options as the last option on the tab bar. So, how make it?
The following print is my current behavior.
The behaviour you notice is due to Sling's Resource Merger feature. The same feature can be leveraged to achieve everything that you want to do.
To answer your question in parts
You see Links & Actions tab even though you've not defined it in your dialog because your component extends the OOB teaser component and the Sling Resource Merger would merge the options in the parent and the child dialogs to create the final dialog that is presented to the author.
This allows easily extending the features of the parent and only defining the custom properties within your dialog. For e.g. If you only need to add a new tab called Metadata in your teaser component it is enough to just create configurations for that new tab in your custom component and the rest of the configs will flow through from your parent component.
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
<metadata ...>
</items>
</tabs>
You can then use the following properties provided by Sling to further customise the ordering of the properties / tabs or remove / hide some properties.
sling:hideProperties - Specifies the property, or list of properties, to hide. The wildcard * hides all.
sling:hideResource - Indicates whether the resources should be completely hidden, including its children.
sling:hideChildren - Contains the child node, or list of child nodes, to hide. The properties of the node will be maintained. The wildcard * hides all.
sling:orderBefore - Contains the name of the sibling node that the current node should be positioned in front of.
Now to answer your second part, if you want to hide the Links & Actions tab completely in your component, then create a node called actions (same name as parent) and then set the property sling:hideResource to true
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
<metadata ...>
<actions
jcr:primaryType="nt:unstructured"
sling:hideResource="{Boolean}true"/>
</items>
</tabs>
Alternatively, if you don't want it removed but just moved to the end, just create a node called actions and place it after all the other nodes or use the sling:orderBefore property to specify the order of the tabs. An example of order before shown below where metadata tab appears second, followed by text and then links and actions.
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
<metadata
jcr:primaryType="nt:unstructured"
sling:orderBefore="text"
...>
<text
jcr:primaryType="nt:unstructured"
sling:orderBefore="actions"/>
</items>
</tabs>
EDIT: How do you know what tab names to use?:
Sling Resource Merger works when you overlay a component (think of it like inheritance in Java where you are extending another class).
You can overlay an existing component using the property sling:resourceSuperType on the component node. For e.g., this is the screenshot of my teaser component which is overlaying the OOB teaser component core/wcm/components/teaser/v1/teaser.
Since it is not an absolute path, the order of preference for seaching the component in the repository is /libs/ followed by /apps/
So, searching under /libs/ I was able to find the component at /libs/core/wcm/components/teaser/v1/teaser and expanding the dialog showed the following tabs. The same names need to be used in our component to override the position or visibility or any other sling merger features.
I would recommend understanding the inheritance concepts of Sling in general to make it easier working with AEM.

Is it possible to inherit cm:folder properties to its content in alfresco?

I have the following in my model.xml
<type name="abc:Policy">
<title>abc Policy</title>
<parent>cm:folder</parent>
<archive>true</archive>
<mandatory-aspects>
<aspect>abc:policyProperties</aspect>
</mandatory-aspects>
</type>
abc:policyProperties has the following.
<aspect name="abc:policytProperties">
<title>abc Policy Properties</title>
<properties>
<property name="abc:dated">
<title>Dated</title>
<type>d:date</type>
</property>
</properties>
</aspect>
A user can upload a document to the abc:Policy folder. But there is no reference to that document currently in the model. How to make it possible for any document within this folder to inherit abc:dated and display it within its properties in Alfresco-share?
It sounds like what you want to do is have a document inherit a property value from the same-named property on the document's parent folder.
One way to do this would be to write a folder rule in JavaScript that reads the property and sets it on a document. You can configure the rule to do that when the document is created or when it is updated.
Here's a quick example that does this with the out-of-the-box cm:title property:
var title = document.parent.properties['cm:title'];
if (title != undefined) {
document.properties['cm:title'] = title;
document.save();
}
You can put that script in a file called "inherit-title.js" under Data Dictionary/Scripts, then configure your rule to execute the script. Any time a new object is created in that folder it will get the current title.
You can modify this to work with your content model.
Note that unless you configure the rule to work on updates, the value on the child will never be updated. So if the title changes in the folder it will not change in its children. And if a child is changed it will not pull the latest value from the parent. You could get that to happen through some rule config and script tweaks, but be mindful of the performance cost.
If you wanted to make this happen more universally, i.e., without setting this up as rules on individual folders, you could write a behavior to do it (tutorial).
If you refer to alfresco content model definitions contentModel.xml
you will find that, cm:folder has default child association cm:contains for the type sys:base. So you are able to add node of type that extends sys:base.
Each document added to your folder abc:Policy goes as a child. And the aspect is applied to parent i.e. abc:Policy. So abc:dated is a property of abc:Policy and not of the document.
One thing you can do is, define one more type that extends cm:content and add is as a child association to your abc:Policy also apply the aspect to it, then you can get the abc:dated as a property of your document

Change root element in association picker control in Alfresco Share

I'm using Alfresco Share 4.2c and I have to change a root node of an association picker. When I change some property of my document I want that picker directly points to the folder where my document is placed (parent of my document).
My problem is how to access nodeRef of document from association.ftl. I think that one solution is to use page.url.args.nodeRef, find his parent and add pass it to parameter rootNode. I'm not satisfied with that because it works only if I'm on Edit metadata page and my clients also what to use popup window to manage properties which appears on click Edit Properties link.
In that case I don't have nodeRef of document in url.
Do you have any idea how to solve this?
The best way is to a NodeLocator fur such purposes: http://docs.alfresco.com/4.1/concepts/node-locator-intro.html
the ancestor NodeLocator should be sufficient for your needs. Try the following setting in your form configuration:
<field id="my:association">
<control>
<control-param name="startLocation">{ancestor}</control-param>
</control>
</field>

How to pass data to a viewmodel in Caliburn.Micro

This is probably a very simple question, but at this time I have myself so confused I can't see the answer. Simply put, I have a window that contains a content control. I'm using Caliburn.Micro's conventions to "locate" the view.
The window looks like this:
<Window x:Class="Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox/>
<ContentControl x:Name="MyViewModel" Height="Auto" Background="Blue"/>
</Grid>
</Window>
The view itself is successfully found, and the screen displays as I expected. However, MyViewModel needs to make a service call to get information based on what is typed into the text box.
So, what I can't seem to figure out is how one would pass that information from the text box to the view model. I've thought of several options, but they all seem to be too much work which makes me think that I'm missing something simple.
Thanks a lot
Like you said there are a number of things you can do:
You could expose a property on MyViewModel and set it within
MainWindowView.
You could use the EventAgregator, publish an event from the
MainWindowView and subscribe to that event from MyViewModel.
Using MEF you could inject a shared resource between the two
ViewModels, set it in MainWindowViewModel, and be able to access it
from MyViewModel.

Spring Webflow, return to main flow from any sub-flow

I'm trying to return to my main flow in spring, from any of my subflows just by clicking a button.
when I use <end-state> it just goes to the previous flow, which is also a sub-flow in the application.
Any ideas?
You just need the appropriate transitions in each subflow-state in the calling flow to do what you want. The end-state id in your subflow is what will be used as the event id you can transition on in your calling flow.
A subflow can be thought of as a branch of execution. So when your subflow is finished, control is returned back to the calling flow. Think of your end-state as a return statement (and the id attribute as the value returned -- you can also set output attributes but that is not important here).
When your subflow terminates, control is returned backed to the calling flow. The calling flow should define a transition that determines how to handle this event. The event id you will see is the id of the end-state in your subflow.
So in your subflow if you have the following end-state:
<end-state id="back"/>
You can then handle this transition in the flow that called the subflow:
<subflow-state id="do-some-sub" flow="some-sub">
< ... input variables, expressions, etc ... />
<transition on="back" to="some-state"/>
</subflow-state>
Note that some-state here can also be an end-state. Your situation sounds like you have a main flow that calls a subflow which in turn calls another subflow. So you would want some-state to be an end-state, which would then be handled by its calling flow (in your case the "main" flow).
You can achieve this by adding the 'parent' attribute when you define your sub flow like this
<flow parent="login" xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<view-state id="forgotPassword">
<transition on="backtoLogin" to="login">
</transition>
here i want my subflow to return to the login page on a back button 'click' .
One thing to notice is that in your parent flow.xml u need to specify the absolute path of the view
my parent ie login-flow.xml is given below
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<view-state id="login" view="../login/defaultLogin.xhtml">

Resources