Question

I'm using Ektron CMS version 9.0

I have smart form content which is allocated to taxonomies e.g. I might have five smart form content items (all of same) type allocated to a taxonomy, and another three to a different taxonomy:

I need to get all content of a smart form type from a taxonomy:

public IEnumerable<T> GetListOfSmartFormFromTaxonomy<T>(long taxonomyId, bool isRecursive) where T : class
{
  // TODO
}

What I have working, based on links below, is this:

public IEnumerable<TaxonomyItemData> GetListOfSmartFormFromTaxonomy(long taxonomyId)
{
    TaxonomyItemCriteria criteria = new TaxonomyItemCriteria();
    criteria.AddFilter(TaxonomyItemProperty.TaxonomyId, CriteriaFilterOperator.EqualTo, taxonomyId);

    TaxonomyItemManager taxonomyItemManager = new TaxonomyItemManager();
    List<TaxonomyItemData> taxonomyItemList = taxonomyItemManager.GetList(criteria);

    return taxonomyItemList;
}

But this just gets the item's titles and ids, not the smart form data itself.

As an Ektron newbie, I don't know how to get all the items of one Smart Form type using only one call (instead of looping through each item and fetching it by ID which is not efficient)

What have I missed? I am working on this actively today and will post my findings here.

References used so far:

EDIT

Posted my just-got-it-working solution below as an fyi and awarded closest answer as accepted. Thanks everyone for your help. Please chime in with any improvements ;)

Was it helpful?

Solution

I'd recommend using the ContentTaxonomyCriteria with the ContentManager.

long smartFormId = 42;
long taxonomyId = 127;
bool isRecursive = true;

var cm = new ContentManager();

var taxonomyCriteria = new ContentTaxonomyCriteria();
taxonomyCriteria.AddFilter(ContentProperty.XmlConfigurationId, CriteriaFilterOperator.EqualTo, smartFormId);
taxonomyCriteria.AddFilter(taxonomyId, isRecursive);

var content = cm.GetList(taxonomyCriteria);

UPDATE

The ContentData object has a property called XmlConfiguration. When the content is based on a smartform, this property will be non-null and have a positive (non-zero) Id: content[0].XmlConfiguration.Id for example.

I often add an Extension Method to my code that will tell me whether a given ContentData is based on a smart form:

public static class ContentDataExtensions
{
    public static bool IsSmartFormContent(this ContentData content)
    {
        return content != null && content.XmlConfiguration != null && content.XmlConfiguration.Id > 0;
    }
}

That way I can take a content (or list of content) and check it very quickly in code to see if it's based on a smartform or not:

foreach (var contentData in contentList)
{
    if (contentData.IsSmartFormContent())
    {
        // Do smart-form stuff here...
    }
}

Of course, if your content is coming from the framework api and you used a criteria object that is selecting based on a specific XmlConfigurationId, then in theory you wouldn't have to use that, but it still comes in handy quite often.

OTHER TIPS

I'm not quite sure I understand your organizational structure, but you do have the ability to do your own sub clauses that select directly against the database.

In this case I wouldn't use the TaxonomyItemManager, I would use the ContentManager with a special criteria:

ContentManager cApi = new ContentManager();
var criteria = new ContentCriteria();
criteria.AddFilter(ContentProperty.Id, CriteriaFilterOperator.InSubClause, "select taxonomy_item_id where taxonomy_id = " + taxonomyId);
criteria.AddFilter(ContentProperty.XmlConfigurationId, CriteriaFilterOperator.EqualTo, smartformTypeId);
var yourContent = cApi.GetList(criteria);

That should do what you're asking for (grab the content specifically that is a member of a Taxonomy while only being of a specific SmartForm config). It's worth noting you don't need the second criteria piece (XmlConfigurationId) if your Taxonomy only contains that XmlConfiguration.

For Information, this is what I came up with. Noted Brian Oliver's comment on List but using patterns from other devs, can refactor later.

To clarify, we are creating classes from the XSDs generated from the smart forms, so have smart form types to play with. Your use may be simpler that ours.

public IEnumerable<T> GetListOfSmartFormFromTaxonomy<T>(long taxonomyId, bool isRecursive = false) where T : class
{
    long smartFormId = GetSmartFormIdFromType(typeof(T));
    // checks here for smartformid=0

    ContentManager contentManager = new ContentManager();
    ContentTaxonomyCriteria criteria = new ContentTaxonomyCriteria();

    // Smart Form Type
    criteria.AddFilter(ContentProperty.XmlConfigurationId, CriteriaFilterOperator.EqualTo, smartFormId);

    // Taxonomy
    criteria.AddFilter(taxonomyId, isRecursive);

    List<ContentData> contentDataList = contentManager.GetList(criteria);
    IEnumerable<T> smartFormList = ConvertToSmartFormList<T>(pressReleaseDataList);

    return smartFormList;
}

private IEnumerable<T> ConvertToSmartFormList<T>(List<ContentData> contentDataList) where T : class
{
    List<T> smartFormList = new List<T>();
    if (contentDataList != null && contentDataList.Count > 0)
    {
        foreach (ContentData contentData in contentDataList)
        {
            if (contentData.IsSmartFormContent())
            {
                T smartForm = GetDeserializedContent<T>(contentData.Html);
                if (smartForm != null)
                {
                    PropertyInfo property = smartForm.GetType().GetProperty("ContentId");
                    if (property != null)
                    {
                        property.SetValue(smartForm, contentData.Id, null);
                    }

                    smartFormList.Add(smartForm);
                }
            }
        }
    }

    return smartFormList;
}

private long GetSmartFormIdFromType(Type smartFormType)
{
    SmartFormConfigurationManager manager = new SmartFormConfigurationManager();
    SmartFormConfigurationCriteria criteria = new SmartFormConfigurationCriteria();

    // Note: Smart Form Title must match the type's name, i.e. no spaces, for this to work
    criteria.AddFilter(SmartFormConfigurationProperty.Title, CriteriaFilterOperator.EqualTo, smartFormType.Name);

    List<SmartFormConfigurationData> configurationData = manager.GetList(criteria);

    if (configurationData == null || configurationData.Count == 0)
    {
        return 0;
    }

    return configurationData.First().Id;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top