Dynamic property key - freemarker

My project has several events and I store event IDs in Site Properties and as each event page extends the same core template I want to assign the specific event ID to a generic variable.
The issue is that when I try to insert a variable inside the property key reference freemarker returns syntax errors. Is there any way around this?
${sectionName}
//rootSection
<#property key="eventID-rootsection" />
//32465
<#assign eventID = <#property key="eventID-${sectionName}" /> >
//syntax error

The problem is that property is defined as a directive (maybe as a macro), and not as a method (or function). You need a method (or function) version of it. Then your example would look like:
${sectionName}
//rootSection
${property("eventID-rootsection")}
//32465
<#assign eventID = property("eventID-${sectionName}")>
To define property as such, either implement TemplateMethodModelEx or use the #function directive.

Related

Thymeleaf: Building variable names dynamically

I am trying to build the name of a var dynamically by concatenating the value of a variable and adding some string afterwards, as I add these variable in runtime. Something like the following should work but it does not.
th:text="${__#{myClass.getA().getB()}+'-result'__}"
Is this even possible to do? I dont know the name of the variable, I can only construct it like this unfortunately.
Yes, that is possible, Thymeleaf supports expression preprocessing:
Let's start with some examples:
The message(i18n) expressions should be referenced using the # character. So let's suppose you have the message.key in your translation file. To reference it in Thymeleaf you will have to use
th:text="#{message.key}"
In your scenario your key name is generated dynamically based on a variable so for preprocessing it in thymeleaf you need to use two underscores __
Let's suppose in your context you have a model variable called myModelVariable with a method messagePrefix(). Our example becomes:
th:text="#{__${myModelVariable.messagePrefix()}__}"
This means the myModelVariable.messagePrefix() will be processed first and the result will be used as the key name which will be then resolved to a nice user friendly message.
And if you also want to add a static part at the end of it will look like this:
th:text="#{__${myModelVariable.messagePrefix()}__}+'*'"
Even the key can contain a static part so this is also accepted:
th:text="#{__${myModelVariable.messagePrefix()}__.staticsuffix}+'*'"
More info you can find in the section 2.7 here:
https://www.thymeleaf.org/doc/articles/standarddialect5minutes.html

assign value from attribute_view_gui from select attribute

I have an attribute if type select. When i try to get value from this attribute content it gives the identification number instead of the value. I call like
$node.data_map.my_attribute_identifier.content
This is expected behaviour. https://doc.ez.no/eZ-Publish/Technical-manual/4.x/Reference/Datatypes/Selection
Raw output
The ".content" of an ezcontentobjectattribute object using this datatype returns an array of the identification numbers (as strings) of the selected options.
I want the value not the identification number. I can get that using attribute_view_gui like
attribute_view_gui attribute=$node.data_map.my_attribute_identifier
But i can't assign value to a variable this way. How can i assign value from a select attribute?
First of all i recommend you to always check default templates in your ezpublish to figure out how should template look...
Maybe this example will help:
<input
id="whatever_id_you_like"
type="text" size="50"
name="ContentObjectAttribute_ezstring_data_text_{$node.object.data_map.YOUR_ATTRIBUTE_SHORT_NAME.id}"
value="{$YOUR_VAR}"
/>
or u can use default view for attribute like this:
{attribute_view_gui attribute=$node.data_map.YOUR_ATTRIBUTE_SHORT_NAME}
also might be helpful - way to find correct path (sometimes you need add ".data_int" or ".data_text" on the end of the path to display data):
{$path|attribute(show,depth)} example:
{$node|attribute(show,2)}
or
{$YOUR_FANCY_VAR.content|attribute(show,2)}
You may want to take a look at the view template of ezselection:
ezselection.tpl
This is the code that eZ Publish uses to view the data type.
content of ezselection.tpl:
{let selected_id_array=$attribute.content}
{section var=Options loop=$attribute.class_content.options}
{section-exclude match=$selected_id_array|contains( $Options.item.id )|not}
{$Options.item.name|wash( xhtml )}{delimiter}<br/>{/delimiter}{/section}
{/let}

How to specify composite action variables in magento dataflow xml profiles

I have created some custom actions to use inside a Magento Dataflow profile. I would like to pass in composite parameter values (arrays or dictionaries) to the action, similar to the map var you can pass to the default parser actions. I.e., I would like to do something like this:
<var name="attribute_map">
<map name="sColore"><![CDATA[colore]]></map>
<map name="sMarca"><![CDATA[marca]]></map>
<map name="sFornitore"><![CDATA[fornitore]]></map>
</var>
The variable turns out as null in this case, although, upon fiddling with the xml and skimming through the code, it seems that this pattern only works with <var name="map">. Puzzling and disappointing. I also have not been able to find even the slightest hint about the relevant xml schema in any documentation whatsoever...
Any idea on this? Thanks!
(I am working with Community Edition version 1.7.0.2)
If i understand right what you ask, you could overwrite the system/convert/profile/wizard.phtml from admin and add another section similar to existing map but the form elements should have name="gui_data[attribute_map]...[]".
Then you should overwrite the _parseGuiData method from Mage_Dataflow_Model_Profile to form the correct profile actions xml.
Hope that helps.
You can't, using the core implementation.
The var elements can only contain simple text, unless the element has the attribute name="map", in which case the profile parser will search for children map elements and use them to populate a php associative array.
The relevant code is inside the importProfileXml method of the Mage_Dataflow_Model_Convert_Profile_Collection class:
if ($varNode['name'] == 'map') {
$mapData = array();
foreach ($varNode->map as $mapNode) {
$mapData[(string)$mapNode['name']] = (string)$mapNode;
}
$container->setVar((string)$varNode['name'], $mapData);
}
To extend this behavior you should override this class with a custom (sub)class through the usual magento class override methods.

Can we dynamically set the value of "list" attribute of <apex:relatedList> component?

I am trying to design a generalized detail page for an object.
In the controller class I find the list of all child relations of that object.
I then want to create for each child relations found and for accomplishing this I will have to dynamically set the value of list attribute within it.
For example :
<apex:relatedList subject={!ObjName} list="{!relatedListName}" />
But the problem here is that list attribute only accepts String literal, so can't implement it. Please suggest a way for this requirement to be accomplished.
Yes, you can dynamically set the value of the "list" attribute on a relatedlist tag, and you do so via Dynamic Visualforce. This question has since been asked and concisely answered here on the Salesforce Stack exchange for any future browsers:
https://salesforce.stackexchange.com/questions/7531/apexrelatedlist-list-dontexistinallorgs-c-only-solveable-with-dynamic
Here is the general solution:
In a custom controller, add a function to dynamically generate the RelatedList markup. I will assume from your wording that you have already accessed the full list of child relationships in your controller, so in order to spit out all the lists in one block, I would use something like this:
public Component.Apex.OutputPanel getDynamicList()
{
Component.Apex.OutputPanel outPanel = new Component.Apex.OutputPanel();
for(String id : childNames) {
Component.Apex.RelatedList relList = new Component.Apex.RelatedList();
relList.list = id;
outPanel.childComponents.add(relList);
}
return outPanel;
}
In the middle there, you can dynamically set any string to the "List" value, and by iterating through your list of strings, you are adding related list objects over and over again. (To simply add one list, remove the for loop, and make the "id" string value whatever specific relationship you wish to display).
Then on your visualforce page, you can render this block out using a dynamic visualforce tag:
<apex:dynamicComponent componentValue="{!DynamicList}" />
(as you may know, the formulaic value field will dig up the getter automatically)
Great success!
I would suggest trying apex:dataTable or apex:repeat to build your own list display. You will likely need a wrapper class to handle passing attributes and values from the sObject to the page.

Is it possible to pass argument from visualforce apex tag?

I have a function searchWorkByName that takes "key" as an argument and use SQOL to retrieve the data.
In visualforce side, I have a link that calls searchWorkByName but would like to be able to pass argument such as character 'a'
example, (this throws an error)
<apex:commandLink value="search!" action="{!searchWorkByName('aaa')}" />
Is it possible to do so if not what is the alternatives?
apex class
public class SearchWorkTest {
public PageReference searchWorkByName(String key) {
//find record of work names starting from provided key character
workNames = [select name from work__c where work__c.name like 'key%'];
return Page.searchResult;
}
}
visualforce
<apex:page standardController="work__c" extenstions="SearchWorkTest">
<!-- Is it possible to pass argument like 'foo' ? -->
<apex:commandLink value="search!" action="{!searchWorkByName}" />
</apex:page>
You can pass in parameters from a page into a function like this:
<apex:commandLink value="search!" action="{!searchWorkByName}">
<apex:param name="key" value="val"/>
</apex:commandLink>
Obviously, the value of the parameter in this case is fixed. If you want something dynamic (i.e. user types something and that is passed to the function), I'm not 100% sure how you'd do that, but I think it might be possible. However, the solution already posted skins the cat for you, but I thought I'd follow up with an alternative in case it's any use.
No, you cannot pass arguments to actions like that.
1 option is to make this variable a normal form field that user can type text/select from dropdown/whatever - if you'll use same name for a variable in Apex (and make it publicly visible by setters/getters), this will work without problems. Check out my answer at How do I integrate Salesforce with Google Maps? to get started.
Second option - if this search must be somehow done programatically without user having to click anything, if the data for example comes from page itself (i.e. is read in <apex:repeat> tag)... you could make a small helper page & controller and call them as components. There is no problem with passing data to components. Check documentation for <apex:component> and <apex:componentBody>. But I think first answer os most useful for you.
Good luck!

Resources