Question

I am working on Tridon 2009 using .NET Templating C# 2.0

I need to read all the components from folders and its subfolder.

If in my code I write:

OrganizationalItem imageFolder = 
    (OrganizationalItem)m_Engine.GetObject(comp.OrganizationalItem.Id);  

I am able to read all the components in subfolder from the place where indicator component is present, but I am not able to read other components present in the folder where indicator is present.

But If I write

OrganizationalItem imageFolder = (OrganizationalItem)m_Engine.GetObject(
                                comp.OrganizationalItem.OrganizationalItem.Id);  

then I am able to read only folder where indicator component is present.

Below is my code.

XmlDocument doc = xBase.createNewXmlDocRoot("ImageLibrary");
XmlElement root = doc.DocumentElement;


Filter filter = new Filter();
Component comp = this.GetComponent();

filter.Conditions["ItemType"] = ItemType.Folder;
filter.Conditions["Recursive"] = "true";

OrganizationalItem imageFolder = 
       (OrganizationalItem)m_Engine.GetObject(comp.OrganizationalItem.Id);            
XmlElement itemList = imageFolder.GetListItems(filter);

foreach (XmlElement itemImg in itemList)
{
    filter.Conditions["ItemType"] = ItemType.Component;
    filter.Conditions["BasedOnSchema"] = comp.Schema.Id;

    OrganizationalItem imgFolder = 
       (OrganizationalItem)m_Engine.GetObject(itemImg.GetAttribute("ID")
       .ToString());
    XmlElement imageLibs = imgFolder.GetListItems(filter);

    doc = this.createImageNodes(imageLibs, doc, filter, comp);
    foreach (XmlElement imglib in imageLibsList)
    {
        XmlElement imageroot = doc.CreateElement("Image");
        XmlElement uploadeddateNode = doc.CreateElement("DateUploaded");
        Component imgComp =    
                (Component)m_Engine.GetObject(imglib.GetAttribute("ID"));
    }
}

Please suggest.

Was it helpful?

Solution

I see a lot of superfluous code on your snippet regarding the question "Reading all components from folder and subfolder"

But answering the question itself, when you are doing:

OrganizationalItem imageFolder = (OrganizationalItem)m_Engine.GetObject(comp.OrganizationalItem.Id);

Your are not being able to read components present on that folder, because you have previously set the filter to folders only on the following line:

filter.Conditions["ItemType"] = ItemType.Folder;

Solution:

If you want to retrieve all components on the "indicator component" folder and below, you need to set the filter on your first search as following:

filter.Conditions["Recursive"] = "true";
filter.Conditions["ItemType"] = ItemType.Component;
filter.Conditions["BasedOnSchema"] = comp.Schema.Id;

And perform the search:

OrganizationalItem imageFolder = (OrganizationalItem)m_Engine.GetObject(comp.OrganizationalItem.Id);            
XmlElement itemList = imageFolder.GetListItems(filter);

OTHER TIPS

Pretty basic stuff. Try to avoid using Filter class, since it was deprecated in 2009, and use GetListItems as much as possible as fetching lists is ALWAYS faster.

public class GetComponentsInSameFolder : ITemplate
{
    public void Transform(Engine engine, Package package)
    {
        TemplatingLogger log = TemplatingLogger.GetLogger(GetType());
        if (package.GetByName(Package.ComponentName) == null)
        {
            log.Info("This template should only be used with Component Templates. Could not find component in package, exiting");
            return;
        }
        var c = (Component)engine.GetObject(package.GetByName(Package.ComponentName));
        var container = (Folder)c.OrganizationalItem;
        var filter = new OrganizationalItemItemsFilter(engine.GetSession()) { ItemTypes = new[] { ItemType.Component } };

        // Always faster to use GetListItems if we only need limited elements
        foreach (XmlNode node in container.GetListItems(filter))
        {
            string componentId = node.Attributes["ID"].Value;
            string componentTitle = node.Attributes["Title"].Value;
        }

        // If we need more info, use GetItems instead
        foreach (Component component in container.GetItems(filter))
        {
            // If your filter is messed up, GetItems will return objects that may
            // not be a Component, in which case the code will blow up with an
            // InvalidCastException. Be careful with filter.ItemTypes[]
            Schema componentSchema = component.Schema;
            SchemaPurpose purpose = componentSchema.Purpose;
            XmlElement content = component.Content;
        }
    }
}

I'd think you'd want to collect sub folders and recursively call your function for each of them, which seems like what you're trying to achieve.

Is this function called createImageNodes() and where do you set imageLibsList?

It looks like you're treating each item as a folder in your first loop, what about the components?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top