5

Ran into the issue where I have clientName in the package which gets merged into the content. Later programName gets added to the package which happens to have the same value as clientName. There is a C# frag which removes registered trademark from the clientName. It is removing the programName because it finds that value first and adds a duplicate clientName. Is there any way to remove item by name?

<%@Import Namespace="Tridion.ContentManager.ContentManagement.Fields"%>

Item outputItem = package.GetByName("client.name");
if(outputItem != null){
    string outputString = outputItem.GetAsString();
    outputString = outputString.Replace("\u00AE", ""); 
    outputString = outputString.Replace("\u24C7", ""); 
    outputString = outputString.Replace("®", "");
    package.Remove(outputItem);
    outputItem.SetAsString(outputString);
    package.PushItem("client.name", outputItem);
}
  • Quite confused about your question... doesn't seem to be about removing items at all (your code is already removing items), but perhaps more about dealing with items with duplicate names? – Nuno Linhares May 27 '14 at 18:25
  • 1
    After removing Try creating a string item Item newOutputItem = package.CreateStringItem(ContentType.Text, outputString ); and then package.PushItem("client.name", newOutputItem );. I was checking some of our TBBs and this seems to be working. Couldn't recollect why we have it this way, but may be we hit the same issue and worked around this way... – Ram G May 27 '14 at 19:42
  • I acknowledge your question is about failing to remove, but I'm offering a workaround: do NOT remove the old item... Simply set a new value to it using SetAsString. This will in fact overwrite the old value. Additionally it might be worth checking if the dot (.) in the item name (client.name) is not causing this effect... Remember, dot is special in DWT syntax :) – Mihai Cădariu Jun 13 '14 at 5:39
4

Yes, you can remove items by name, something along these lines:

Item item = package.GetByName("ItemName");
package.RemoveItem(item);

Given the package is a stack, if you have two items with the same name GetByName will get the last item that was added, so you may have to play around with this until it behaves as you want it to.

If your challenge is more about how to deal with multiple items with the same name in the package, then you should perhaps look at package.GetAllByType method.

| improve this answer | |
  • Nuno, unfortunately that doesn't appear to be how it works. When you request the item using package.GetByName("ItemName"); the item that is returned doesn't have a name property. When you subsequently call RemoveItem(item); what is removed is the first item in the package with the same Type, Content Type and Value, not the original named item, but another almost identical package item with a different name that was more recently added. I was as suprised as Brandon! – Daniel May 27 '14 at 19:26
  • I think the method should be Remove, though there is a RemoveItem for bundles (working on workflow lately?). :-) The TOM.NET docs (7.1) explain Package.Remove: "Remove an item from the package. If the item is present in the package multiple times, only the first occurence is removed." The Item Class explains an Item is identified by Type, value, and ContentType, but also named Properties, and if stored in a package, a name. Interesting... – Alvin Reyes May 28 '14 at 12:38
  • You're right, it is package.Remove :) – Nuno Linhares May 28 '14 at 12:38
  • So if you have two items that are named differently, but have the same value, how do you ensure that you are removing the correct item? – Brandon Mahoney May 29 '14 at 12:44
  • If the name is different, GetByName is what you should be using, I guess – Nuno Linhares May 29 '14 at 14:31
4

This is an interesting find. I've been able to reproduce the scenario described in the question. Consider the following:

We have two items with different names, but identical values. However, the values have different business meanings. So here is the package:

enter image description here

Next, you want to pop an item off (by usual means of peeking then removing):

    public override void Transform(Tridion.ContentManager.Templating.Engine engine, Tridion.ContentManager.Templating.Package package)
    {
        Item i = package.GetByName("client.name");
        string removedItemName = package.Remove(i);
        Logger.Debug(removedItemName);
    }

After running the above code we expect the item "client.name" to be removed, however the result was that the other item is removed:

enter image description here

What appears is that the item with the matching value that's closest to the top of the stack is removed. This looks like a bug to me.

Now back to your question of how work around this:

In Tridion 2013 there are Append and SetAs methods. So just use those instead of the old school way of peeking and popping. If you're on pre-2013, then simply leave the item on the package. At the very least, you'll later be able to write your own function to cycle through all the items and find by name yourself.

| improve this answer | |
  • RemoveItem finds the first item in the package that "equals" the given Item. The problem is that Item doesn't have a key or name property -- so it compares all the other properties instead. The name of the item is only available in the collection (in Package) -- so RemoveItem should probably be fixed to also compare the name of the items instead of just calling Equals. That would require someone to report this issue to Customer Support so it can be changed in the future :) – Peter Kjaer Jun 13 '14 at 8:46
  • @Brandon, it would be great if you could open a ticket with Support and refer them to this post? – Nickoli Roussakov Jun 13 '14 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.