Umbraco: x.GetPropertyValue("myProp") vs x.myProp - asp.net

I use Umbraco v4, but think this should be a common problem.
I have a generic property "myNode" of "Content Picker", that should obtain a DynamicNode...
so doying myObj.myNode I obtain the node itself... so can use myObj.myNode.Url
But doying the myObj.GetPropertyValue("myNode") I obtain the ... string ID value of the node... so can't anymore do myObj.GetPropertyValue("myNode").Url (string does not have Url property)
I can't use directly myObj.myNode, because the name is "dynamic" (the same function should use "your"+"Node" or "their"+"Node" upon conditions - the example is very aproximative, but hope the idea is clear)...
I even did myObj.GetPropertyValue<DynamicNode>("myNode"), but the result was the same: "8124" (the node id)
So, how to obtain the real property value, not just string representation of it?

Your content picker does not contain a node, it contains an id of a node.
myObj.GetPropertyValue("myNode") does exactly what is says, gets the value of a property called myNode on the instantiated DynamicNode object. It is not designed to return the node itself.
If you want to return the node whose ID your 'myNode' property contains then you have to use that value in a call to instantiate another DynamicNode
DynamicNode myNewNode = new DynamicNode(myObj.GetPropertyValue("myNode"))
or
Model.NodeById(myObj.GetPropertyValue("myNode"))

Use somethings like: mynode = Umbraco.Content(CurrentPage.myNode).Url (for Umbraco 6 and 7) For Umbraco 4 i use this Model.NodeById(Model.myNode).Url; in a script file. (I think it need at least Umbraco 4.7.x)
See also https://our.umbraco.org/documentation/Using-Umbraco/Backoffice-Overview/Property-Editors/Built-in-Property-Editors/Content-Picker

A not so elegant solution, but at least a solution that work:
var linkNode = image.GetPropertyValue("imgLinkNode" + model._lang.ToUpper());
if (linkNode is string)
{
string id = linkNode;
linkNode = model.NodeById(id);
}
var linkNodeUrl = linkNode.Url;

Related

Get all properties for a node magnolia cms

I would like to get a list of properties for a given node in magnolia so that I can get values for each property.
I tried using the PropertyUtil but it cannot find "tags".
List<String> tags = info.magnolia.jcr.util.PropertyUtil.getValuesStringList(node.getProperty("tags").getValues());
Actual result is javax.jcr.PathNotFoundException: tags.
Expected result is a list of properties that I can use to query for property values.
It is called 'mgnl:tags', please refer to info.magnolia.contenttags.manager.TagManager#TAGS_PROPERTY
Cheers,
I was able to do it using javax.jcr Interface Node:
PropertyIterator pi = node.getProperties();
while(pi.hasNext())
{
Property p = pi.nextProperty();
String name = p.getName();
String val = p.getString();
}

SDL Tridion GetListKeywords using Anquilla Framework

I'm writing a GUI extension and using the Anquilla framework to get a list of Keywords within a Category. I'm obtaining an XML document for the list of keywords then working with that document within my extension.
My problem is that the returned XML doesn't contain the Keyword's 'Description' value. I have the Title and Key etc.
My original code looks like this:
var category = $models.getItem("CATEGORYTCMID:);
var list = category.getListKeywords();
list.getXml();
A typical node returned is this:
<tcm:Item ID="tcm:4-1749-1024"
Type="1024" Title="rate_one" Lock="0" IsRoot="true"
Modified="2012-12-17T23:01:59" FromPub="010 Schema"
Key="rate_one_value" IsAbstract="false"
CategoryTitle="TagSelector"
CategoryID="tcm:4-469-512" Icon="T1024L0P0"
Allow="268560384" Deny="96" IsNew="false"
Managed="1024"/></tcm:ListKeywords>
So I've tried using a Filter to give me additional column information:
var filter = new Tridion.ContentManager.ListFilter();
filter.columns = Tridion.Constants.ColumnFilter.EXTENDED;
var list = category.getListKeywords(filter);
Unfortunately this only gives the additional XML attributes:
IsShared="true" IsLocalized="false"
I'd really like the description value to be part of this XML without having to create a Keyword object from the XML. Is such a thing possible?
cough any ideas? cough
I'm afraid you'll have to load the Keyword itself to get the Description.
It's not used in any lists, so it's not returned in the XML.
You could always create a List Extender to add this information to the list, but try to be smart about it since this extender will execute everytime a GetList is called.
Won't save you from having to open every keyword in the list, but you'll be doing it server-side (with Core Service/NetTcp for instance) which will probably be easier and faster than opening each keyword with Anguilla.
In this instance I only need the one keyword, so I simply get it from the CMS. Getting an object in Anguilla is a bit weird, here's the code:
In your main code area:
var selectedKy = $models.getItem("TcmUriOfKeywordHere");
if (selectedKy.isLoaded()) {
p.selectedKy = selectedKy;
this.onselectedKyLoaded();
} else {
$evt.addEventHandler(selectedKy, "load", this.onselectedKyLoaded);
selectedKy.load();
}
It's worth noting how I store the keyword in the properties of the item, so I can obtain it in the onselectedKyLoaded function
The function called once the item is loaded
ContentBloom.ExampleGuiExtension.prototype.onselectedKyLoaded = function (event) {
var p = this.properties;
var selectedDescription = p.selectedKy.getDescription();
// do what you need to do with the description :)
};
I resolved this, thanks to the answer here: https://stackoverflow.com/a/12805939/1221032 - Cheers Nuno :)

vb.net alternative to select case when dealing with object values

Hey all, I was able to do this via a SELECT CASE statement, however I'm always trying to improve my code writing and was wondering if there was a better approach. Here's the scenario:
Each document has x custom fields on it.
There's y number of documents
However there's only 21 distinct custom fields, but they can obviously have n different combinations of them depending on the form.
So here's what I did, I created an object called CustomFields like so:
Private Class CustomFields
Public agentaddress As String
Public agentattorney As String
Public agentcity As String
Public agentname As String
Public agentnumber As String
Public agentstate As String
Public agentzip As String
... more fields here ....
End Class`
Then I went ahead and assigned the values I get from the user to each of those fields like so:
Set All of Our Custom Fields Accordingly
Dim pcc As New CustomFields()
pcc.agentaddress = agent.address1
pcc.agentattorney = cplinfo.attorneyname
pcc.agentcity = agent.city
pcc.agentname = agent.agencyName
pcc.agentnumber = agent.agentNumber
pcc.agentstate = agent.state
pcc.agentzip = agent.zip ....other values set to fields etc.
Now the idea is based upon what combo of fields come back based upon the document, we need to assign the value which matches up with that custom field's value. So if the form only needed agentaddress and agentcity:
'Now Let's Loop Through the Custom Fields for This Document
For Each cf As vCustomField In cc
Dim customs As New tblCustomValue()
Select Case cf.fieldname
Case "agentaddress"
customs.customfieldid = cf.customfieldid
customs.icsid = cpl.icsID
customs.value = pcc.additionalinfo
Case "agentcity"
customs.customfieldid = cf.customfieldid
customs.icsid = cpl.icsID
customs.value = pcc.additionalinfo
End Select
_db.tblCustomValues.InsertOnSubmit(customs)
_db.SubmitChanges()
This works, however we may end up having 100's of fields in the future so there a way to somehow "EVAL" (yes I know that doesn't exist in vb.net) the cf.fieldname and find it's corresponding value in the CustomFields object?
Just trying to write more efficient code and looking for some brainstorming here. Hopefully my code and description makes sense. If it doesn't let me know and I'll go hit my head up against the wall and try writing it again.
If I am reading your question correctly, you are trying to avoid setting the value of fields, when the field isn't used. If so, I would recommend you just go ahead and set the field to nothing in that case.

AS3: Whats determines the order of: for..in

OK I am looping through the properties in an object like so:
private var _propsList:Object = {'Type':'product_type'
,'Kind':'product_type_sub'
,'Stone':'primary_stone'
,'Stone Color':'primary_stone_sub'
,'Metal':'metal_type'
,'Brand':'product_brand'};
for(key in _propsList)
{
val = _propsList[key];
trace(key +" = "+ val);
}
I am expecting the first trace to be Type = property_type since that is the first one defined in the array, however it is coming up random everytime. I guess this is because my keys are strings and not integers, however is there a way to specify the order it loops through them?
Thanks!!
You can't rely on for (v in someObject) ... to return things in a predictable order, no.
Depending on your specific situation, you could just use an array to hold the keys, and just iterate through that:
private var keys:Array = ["Type", "Kind", "Stone", "Stone Color", "Metal", "Brand"];
private function iterate():void
{
for each (var k:String in keys)
{
trace(_propsList[k]);
}
}
Maybe a bit obvious or non-elegant, but it'd get the job done. :)
you could hack it by classing-out your "_propsList" object creating an array inside of the newly created PropsList class that references the properties in order. At that point, you could run a FOR loop on the array and get your properties in order.
OR, you could have a function inside that new class that would return an Array of those properties. like this:
public function getProps():Array {
return [myPropertyOne, myPropertyTwo, myPropertyThree];
}
In general, I think this is a case where you shouldn't depend on a particular behavior from the framework/language you are using. This type of behavior is generally poorly documented and can change from version to version.
If you really need a specific retrieval order, I would create a wrapper class as jevinkones suggested above. Maybe there's even a utility class in the framework somewhere to accomplish this (Dictionary, etc.?)
HTH,
Karthik
I found this link that gives some background:
Subtle Change in for..in Loops for ActionScript 3
This question is actually a dup of this one.
How about using an array representation like this:
var _propsList:Array = [
['Type', 'product_type'],
['Kind', 'product_type_sub'],
['Stone', 'primary_stone'],
['Stone Color', 'primary_stone_sub'],
['Metal', 'metal_type'],
['Brand', 'product_brand']
];
for(var i in _propsList) {
var elem = _propsList[i];
var key = elem[0];
var val = elem[1]
}

How do I delete a value from an Object-based associative array in Flex 3?

I need to remove the value associated with a property in a Flex 3 associative array; is this possible?
For example, suppose I created this array like so:
var myArray:Object = new Object();
myArray[someXML.#attribute] = "foo";
Later, I need to do something like this:
delete myArray[someXML.#attribute];
However, I get this error message at runtime:
Error #1119: Delete operator is not supported with operand of type XMLList.
How do I perform this operation?
delete doesn't do as much in AS3 as it did in AS2:
http://www.gskinner.com/blog/archives/2006/06/understanding_t.html
However, I think your problem might be solved by simply using toString(), i.e.
var myArray:Object = new Object();
myArray[someXML.#attribute.toString()] = "foo";
delete myArray[someXML.#attribute.toString()];
Rather than delete it, try setting the value to null.
myArray[someXML.#attribute] = null;
That way it'll end up the same as any other value in the array that isn't defined.

Resources