How to create a page tree structure in Kentico 8.2 efficiently?

Marco Glasbergen asked on October 27, 2015 17:18

Hi,

We are running a vacancy (as in jobs) import using a scheduled task and are programmatically creating (or updating) a page tree structure under one root page. Each vacancy has information about function, region, etc. and we are building a page tree structure like this:

  • Vacancies root node
    • Function1
      • Region1
        • Vacancy1
        • Vacancy2
      • Region2
        • Vacancy3
    • Function2
      • Region1
        • Vacancy4
      • Region3
        • Vacancy5
        • Vacancy6

To achieve this we loop through all vacancies and insert or update function and/or region and/or vacancy nodes as needed (only important code fragments mentioned below):

foreach (var vacancy in vacancyCollection)
{
    var jobRoot = DocumentHelper.GetDocuments()
            .OnSite(SiteContext.CurrentSiteName)
            .Published(false)
            .SingleOrDefault(n => n.NodeID == jobRootId);

    CreateVacancy(treeProvider, jobRoot, vacancy)

    // Or update vacancy (not included here)
}

private static void CreateVacancy(TreeProvider treeProvider, TreeNode jobRoot, Vacancy vacancy)
{
    var functionNode = jobRoot.Children.SingleOrDefault(n => n.DocumentName.Equals(vacancy.igJobFunction, StringComparison.InvariantCultureIgnoreCase));
    if (functionNode == null)
    {
        // Create function node
        functionNode = TreeNode.New(JobContainerCodeName, treeProvider);

        // Insert function node
        functionNode.Insert(jobRoot);
    }

    var regionNode = functionNode.Children.SingleOrDefault(n => n.DocumentName.Equals(vacancy.Region, StringComparison.InvariantCultureIgnoreCase));
    if (regionNode == null)
    {
        // Create placename node
        regionNode = TreeNode.New(JobContainerCodeName, treeProvider);

        // Insert placename node
        regionNode.Insert(functionNode);
    }

    // Create job item
    var jobItemNode = TreeNode.New(JobItemCodeName, treeProvider);

    // Insert job item
    jobItemNode.Insert(regionNode);
}

This code works but it is slow because I need to call DocumentHelper.GetDocuments() for every vacancy to update the Children property of the root node (to be able to look for existing child nodes).

Is this a correct approach to building a page tree in Kentico 8.2? And is there a more efficient way to achieve this functionality?

Regards,

Marco

Recent Answers


Brenden Kehren answered on October 27, 2015 17:37

Just a question/suggestion, why not keep your page structure simple and use the built-in taxonomy (categories, tags, etc.). You could also use related pages if you have your regions and functions specified elsewhere in the site. This way you can use smart search filters. Then for each vacancy/job you import/update you can update your individual page, the related pages, categories and/or tags vs. the whole navigation structure.

0 votesVote for this answer Mark as a Correct answer

Marco Glasbergen answered on October 28, 2015 14:40

Thanks for your suggestion, Brenden. Our main reason for choosing this hierarchical structure was to have better SEO (better URL's) for each individual vacancy page.

The updating of vacancy pages is not really the problem. They can be easily found and updated. But creating multiple new vacancy pages is error prone without calling DocumentHelper.GetDocuments() for every vacancy to refresh all children in the page tree. I'd like to know if there is a better way. The Kentico examples only show how to create one page at a time.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on October 29, 2015 01:37

You might look into the placing your data in a structured data format on the page vs. having such a long URL. I think this will benefit your SEO better. If you have /Vacancies/Region/Vacancy and add the functions as categories/tags to the page and display them on our page in the structured data format, this would be better.

You might try a USING statement and turning off logging (see code sample below) while this is happening. Also if you're using workflow, you might want to account for that as well. Maybe turn workflow off during this import/update. You can also turn on DEBUG when running your code to see what is taking a long time to run. Maybe it has nothing to do with your code but maybe there is a cache key you need to clear to get things updated.

using (CMSActionContext context = new CMSActionContext())
{
    // turn off all these "features" to speed things up during import/update
    // could also look into other properties of "context" to disable
    context.LogEvents = false;
    context.LogSynchronization = false;
    context.LogWebFarmTasks = false;

    // perform your actions to add/update pages
    foreach (var vacancy in vacancyCollection)
    {
        ...
    }
}
0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.