We have data that is fairly static, and we load that data into an XPage for attributes or label names or combo/radio/pull-down dataValues.
Using Resource Files in the Resources section is fast and simple EL syntax.
But how to dynamically update the data in the Resource File became the challenge. This is how we gotter' done:
First, accessing a Resource File containing manually pasted key=value,[n]; paired-data, just to prove we can; we did like this:
<xp:this.resources>
<xp:bundle src="/dojoPivotData.properties" var="dojoPivotProperties"></xp:bundle>
</xp:this.resources>
The data in the 'dojoPivotProperties.properties' file looks like this:
Passing the variable name var="dojoPivotProperites" into a Custom Property of a CustomControl is done by changing the Type: of the Property Definition of the property by Pasting java.util.PropertyResourceBundle into the Type: property, like so:
And passing in the Resource var variable name to the Custom Property where the Custom Control in embedded looks like this:
How I used values from the Custom Property, defined in the Custom Control:
How is used the .properties file to find keys to get their values to use in repeat controls by doing computations on the value of the passed in .property file in a DataContext:
To get the Finále where the data is driving the design elements that get generated in the UI:
**
Special Note
**
The voyages associated with each Destination cell above is generated at load by using the same java.util.ResourceBundle .property file to grab each Destination keyName from the .properties file. Each keyName in the .properties file has a list of voyages associated with that keyName like so:
And those voyages associated with Africa are generated into an attribute-list for "Africa" square like this:
To get this HTML result in the browser:
Question: How do we load the keyName=Value pairs into the Resource File on the Fly?
Ans: See* "Dynamic .property Resources File on the Fly"
I will show how I did it in a post by that title
Related
I wish to use cq:inplaceEditing to modify a property on my JCR whenever it is used by the AEM authors. Unfortunately, I do not know how to modify the name of the property that it actually modifies in the JCR. It appears that it only modifies the value of the property "text" by default.
For my purposes, I want to use its rich-text-editing for properties that have names I define, not just the default name "text."
The image at this link shows the tree which contains the cq:inplaceEditing (courtesy of CRXDE):
These are the attributes of cq:editConfig:
These are the attributes of cq:inplaceEditing:
...and this is what a content node of my JCR looks like when I use the inplaceEditor. I've blotted out the names of some properties for potential security reasons. Note that the "text" property below was changed when I used the inplaceEditor. Also note that I want to be able to define the property name that the inplaceEditor changes, rather than just the "text" property:
Is there a way to use a different property name instead of "text"?
-----------EDIT----------
After changing the property "textPropertyName" to the property that I am searching for, it still doesn't appear to actually modify the behavior of the inplaceEditor. It still only modifies the "text" property of my JCR nodes instead of the one that I put in the "textPropertyName" attribute.
This picture contains the attributes of my cq:InplaceEditingConfig:
The picture below contains the attributes of the JCR node at the path specified in the "configPath" variable in the picture above. Note that I set the textPropertyName attribute in this node and the text component still modifies the default attribute "text" instead of the one specified:
Finally, the picture below shows the contents of my JCR tree inside of the text component.
-----------ANOTHER EDIT----------
I discovered that the inline text editor was persisting the correct property after I had switched to the classic UI. For some reason, it doesn't work correctly with the touch UI.
How to find it
The inplace editing capability is defined by subclasses of CQ.ipe.InplaceEditing function. You can find it easily by just searching for editorType through the CRXDE tool.
Searching for the CQ.ipe.InplaceEditing returns multiple results such as CQ.ipe.TextEditor that at the very end of the script registers desired editorType i.e.: CQ.ipe.InplaceEditing.register("text", CQ.ipe.TextEditor);
The answer
Reading through the editor code you can find the first configurable property called textPropertyName which according to it's documentation is just what you are looking for. Combining it with the inplace configuration node (see Adobe's documentation) it is the solution for your case.
An example
You can try it by yourself on an instance of Geometrixx component.
First go to CRXDE and find Geometrixx Text component: /apps/geometrixx-gov/components/text.
Notice /apps/geometrixx-gov/components/text/cq:editConfig/cq:inplaceEditing#configPath property value.
Find /apps/geometrixx-gov/components/text/dialog/items/tab1/items/text resource and add new property: textPropertyName=myPropertyName.
Then just open the Geometrixx Gov page add Geometrixx Text component, edit it inplace and look into the Network console. You'll notice POST request with the altered parameter name
edit after TouchUI clarification
TouchUI case
If you want to achieve the same for TouchUI interface it doesn't go so easy, unfortunately. The text inplace editor for TouchUI is defined by /libs/cq/gui/components/authoring/clientlibs/editor/js/editors/InlineTextEditor.js.
Searching for "text" gives you an overview how hardcoded is this property. For AEM 6.1 (on which I'm testing it) you can find it's occurence in the ns.persistence.readParagraphContent function where the initialContent is extracted from the resource JSON map. Another occurence can be found in finishInlineEdit and addHistoryStep methods. Changing all three occurences of "text" to your value brings expected outcome.
This is obviously non-acceptable - it's a platform-wide change and will affect other (incl. ootb) components where it might no be expected. The simplest would be to just copy-paste whole editor into your clientlib and register the editor into a new name - see last couple of lines: ns.editor.register. If you feel comfortable in JS, it might be worth to extend this editor and alter just three methods that are affected.
As of AEM 6.3, the textPropertyName works correctly with the out-of-the-box PlainTextEditor.js
The property needs to be set on a config node under the cq:InplaceEditingConfig
Note – the source of the editor can now be found at:
/libs/cq/gui/components/authoring/editors/clientlibs/core/inlineediting/js/PlainTextEditor.js
I have an application which has a server side part and a client side part. The server side part is implemented with WebApi2 and EF6 and uses Json AND Protobuf as serialisers.That's why I use [DataMember] as attribute on the properties of my models. Here I need to put the order into the Attribute [DataMember(Order = number)] because of the Protobuf serialiser.
From my serverside models (codefirst) I generate an edmx file which holds the information of the models. On the clientside I generate these models with a t4 template which uses the edmx file. Before I used Protobuf I just put the DataMember attribute on top of every property in the t4 template which worked fine. But now I have to use the same Order as on the server so that it still works with Protobuf. This means that I have to read the DataMember Attribute in the edmx and find the Order value. But I just can't read the attribute.
I tried to read the
edmProperty.TypeUsage.Facets
and some other properties on this object. I also searched on google and had a look at some sampleprojects on t4 templates. But no luck.
So how can I read the order of the attribute?
MyServerModel
{
[DataMember(Order=1)] //this number of the order is what I'm looking for
MyProperty{get;set;}
}
Now use the magic of T4 and generate following with the help of the edmx file.
MyClientModel
{
[DataMember(Order=1)] //I want to generate this Attribute with the t4 template from
//the edmx file
MyProperty{get;set;}
}
The DataMember Attribute is not part of the edmx file because every member is a DataMember attribute. And as a result of this the order information is lost.
We have solved this problem in the following way: First we generate the edmx file normaly. Afterwards we parse it manualy and look for the EntityType entries. Then we load the Type with reflection from the Assembly the code first models reside in. Parse the CustomAttributes to find the DateMemberAttribute where we can read the Order. After we have this information we can write this into the edmx file by either putting it in the documentation tag (not so elegant) or add it the Property/NavigationProperty tag as custom annotation.
After this our edmx Property tags look similar to this:
<Property Name="PropertyName" Type="Guid" xmlns:d2p8:DataMemberOrder="5" xmlns:d2p8="http://www.yourcompany.com/customAnnotation" />
In the t4 template script you have to parse edmx file again for this information and you can write the DataMember annotation with order.
I have created a custom content type (via the admin UI) that consists mostly of text fields. I know how to position the fields using zones and Placement.info but for simplicity I would like to use a single view template and to just arrange the fields by name instead of having to use Placement.info. Is there a good way to reference the fields by name from the content item in my MVC view?
So for example, I have a template named Content-MyContentType-Detail.cshtml. Instead of the generic
#Display(Model.Content)
I would like to be able to do something like
#Display(...MyField...)
#Display(...MyOtherField...)
Is there a way to explicitly render a field by name that is associated with my content item?
You can use Shape Tracing module to view model properties and how to get access to content parts.
Then in your template you can use something like this:
<h3>#Model.ContentItem.TitlePart.Title - £#Model.ContentItem.Product.Fields[1].Value</h3>
<p>#Model.ContentItem.BodyPart.Text</p>
If you don't just want to access the field's properties, but rather would like its shape rendered in-place, but like it would be when using placement (i.e. using the existing template), then read this article, which describes how to do direct rendering without placement: http://weblogs.asp.net/bleroy/archive/2013/02/13/easy-content-templates-for-orchard-take-2.aspx
I use ElasticSearch to index resources. I create document for each indexed resource. Each resource can contain meta-data and an array of binary files. I decided to handle these binary files with attachment type. Meta-data is mapped to simple fields of string type. Binary files are mapped to array field of attachment type (field named attachments). Everything works fine - I can find my resources based on contents of binary files.
Another ElasticSearch's feature I use is highlighting. I managed to successfully configure highlighting for both meta-data and binary files, but...
When I ask for highlighted fragments of my attachments field I only get fragments of these files without any information about source of the fragment (there are many files in attachment array field). I need mapping between highlighted fragment and element of attachment array - for instance the name of the file or at least the index in array.
What I get:
"attachments" => ["Fragment <em>number</em> one", "Fragment <em>number</em> two"]
What I need:
"attachments" => [("file_one.pdf", "Fragment <em>number</em> one"), ("file_two.pdf", "Fragment <em>number</em> two")]
Without such mapping, the user of application knows that particular resource contains files with keyword but has no indication about the name of the file.
Is it possible to achieve what I need using ElasticSearch? How?
Thanks in advance.
So what you want here is to store the filename.
Did you send the filename in your json document? Something like:
{
"my_attachment" : {
"_content_type" : "application/pdf",
"_name" : "resource/name/of/my.pdf",
"content" : "... base64 encoded attachment ..."
}
}
If so, you can probably ask for field my_attachment._name.
If it's not the right answer, can you refine a little your question and give a JSON sample document (without the base64 content) and your mapping if any?
UPDATE:
When it come from an array of attachments you can't get from each file it comes because everything is flatten behind the scene. If you really need that, you may want to have a look at nested fields instead.
I have defined my own projection by a query which returns a set of content items of known content type. I would like to take pick up certain content parts of these content items and display them in the list. Using shape tracing tool I have found the view template where to write my custom layout:
/Views/Parts.ProjectionPart.cshtml
but from the Model variable in the template I can not get the data I want because it is way too high above from the content parts data.
a good example of what I want: let's say I want to render product catalog as defined in this tutorial:
http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-part-5
but I want only to render a list which consists from items:
name of the owner who created the product
name of the product.
publish date of the product
and I need to render it at one place, i.e., not separately in their own part views.
Have you tried adding a layout in the projector module? There is a properties mode option that lets you select which fields/data to show. If the data you want is not there, you should be able to implement an IPropertyProvider. There are examples of this in the Projections module code.