Related Pages

George Tselios asked on January 24, 2020 13:54

Dear Sirs,

We are currently developing a web site using Kentico MVC 12SP and in our article page we need to display related articles, so we need to decide which data type to use that will hold such information.

We have tried the “pages” data type and form control that seem suitable for the job, but there is no way to specify the desired selection page type in order to limit the author to always select article pages.

Our questions are:

  1. Is there a way to specify the page types that are allowed for selection in the pages form control?

  2. Since we decided not to use the TreeNode derived classes for our development and we solely base our queries on TreeNode, is there a MultiDocumentQuery that given a TreeNode would return a list of related documents as TreeNodes?

  3. Is there any other (out of the box) datatype / form control we may use for such functionality?

Thanks in advance,

G. Tselios

Correct Answer

Dat Nguyen answered on January 24, 2020 22:59

  1. No, but you can specify the path in the advanced field settings if all of your articles are confined in a certain section of the content tree.

  2. The following code should do what you need. If your page type display name is "Article" and your related pages field is captioned "Related Pages", the code you need will look like this:

    var relationshipDisplayName = "Article (Related Pages)"; 
    //make sure there is a space between Article and (Related Pages)
    
    var relationshipName = RelationshipNameInfoProvider.GetRelationshipNames()
        .WhereEquals("RelationshipDisplayName", relationshipDisplayName)
        .FirstOrDefault();
    
    var relationships = RelationshipInfoProvider.GetRelationships()
        .WhereEquals("LeftNodeID", yourArticleTreeNode.NodeID)
        .WhereEquals("RelationshipNameID", relationshipName.RelationshipNameId);
    
    var relationshipRightSideIDs = relationships.Select(x => (int)x["RightNodeID"]).ToList();
    
    var relatedPages = DocumentHelper.GetDocuments()
        .WithCoupledColumns()
        .WhereIn("NodeID", relationshipRightSideIDs);
    
  3. There is a Related pages form control (Text data type), but you have to set up relationship names in the Relationship names application to work with it. You can use the code above with slight changes (the relationshipDisplayName would simply be the display name of the created relationship name) to get the related pages.

2 votesVote for this answer Unmark Correct answer

Recent Answers


Trevor Fayas answered on January 26, 2020 19:32 (last edited on January 26, 2020 19:34)

Honestly...you should just install my Relationships Extended module, as it provides the interfaces to specify which page types you want relationships with, has an MVC helper to get these relationships, supports sorting without using the "Pages" field type.

It does what you are looking for, plus more. I built it to solve the exact issue you are having.

Here's the Github with NuGet Package links

Here's how to use it

Here's my blog article on why i created it

1 votesVote for this answer Mark as a Correct answer

George Tselios answered on January 27, 2020 11:39

Dear Mr. Nguyen,

Thank you very much for your answers.

As for my question No.2 I mistakenly asked for the wrong query. What we need is the query that is executed when a subclass of the TreeNode executes the GetRelatedDocuments protected method which returns the list of nodes that are selected by the Pages data type / Pages form control.

Thanks in advance,

George

1 votesVote for this answer Mark as a Correct answer

Dat Nguyen answered on January 27, 2020 12:17

It's basically the same code. The fieldName parameter for the GetRelatedDocuments method is used to retrieve the relationship name code name. Using that code name, you can find the related documents for a NodeGUID with the InRelationWith parameterized method of the MultiDocumentQuery.

Here's the code for the TreeNode.GetRelatedDocuments method:

protected MultiDocumentQuery GetRelatedDocuments(string fieldName)
{
  FormFieldInfo formField = FormHelper.GetFormInfo(this.NodeClassName, false, true, false)
    .GetFormField(fieldName);
  if (formField == null)
    return new MultiDocumentQuery().NoResults();
  string relationshipNameCodeName = RelationshipNameInfoProvider
    .GetAdHocRelationshipNameCodeName(this.NodeClassName, (IField) formField);
  RelationshipNameInfo relationshipNameInfo = RelationshipNameInfoProvider
    .GetRelationshipNameInfo(relationshipNameCodeName);
  return RelationshipInfoProvider.ApplyRelationshipOrderData(
    DocumentHelper.GetDocuments()
        .Culture(this.DocumentCulture)
        .CombineWithDefaultCulture(
            this.TreeProvider.GetCombineWithDefaultCulture(this.Site.SiteName))
        .Published(!this.IsLastVersion)
        .PublishedVersion(!this.IsLastVersion)
        .WithCoupledColumns(true)
        .InRelationWith(this.NodeGUID, relationshipNameCodeName, RelationshipSideEnum.Left),
    this.NodeID, 
    relationshipNameInfo.RelationshipNameId);
}

Hope that answers your question.

2 votesVote for this answer Mark as a Correct answer

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