Resolving InLine Document Macros

Neil Martin asked on July 22, 2019 16:22

Our content authors have defined some of the page's Metadata properties with Macros, for example the Page Description is defined as {%AuthorBio%} where AuthorBio is a custom field on the Page Type.

In our MVC application controller we want to retrtieve the page:

var tree = new TreeProvider(MembershipContext.AuthenticatedUser);
var page = tree.SelectSingleNode(
   nodeGUID, CultureHelpers.GetCultureCode(), SiteContext.CurrentSiteName, true);

We then want to map this data to a MVC View Model.

var viewModel = new PageViewModel
{
   MetaDescription = page["DocumentPageDescription"]
}

My question is, how to I resolve the Macro from the page property so that the view model's MetaDescription contains the data defined on the page's AuthorBio property?

I have tried to use the MacroResolver.Resolve() method, but I couldn't get this to work.

Any help would be much appreciated.

Recent Answers


Brenden Kehren answered on July 22, 2019 16:29

The standard usage is like so:

string contentBody = CMS.MacroEngine.MacroResolver.Resolve(ContentBodyString);

Not sure why this would't work for you in MVC.

1 votesVote for this answer Mark as a Correct answer

Neil Martin answered on July 22, 2019 16:39

Hi Brenden,

Thank you for helping. From my particular example, I tried the following which returned an empty string:

// page["DocumentPageDescription"] == "{%AuthorBio%}"
// page["AuthorBio"] == "This is some test AuthorBio text"
var metaDescription = MacroResolver.Resolve(page["DocumentPageDescription"])
// metaDescription == ""
0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on July 22, 2019 16:43

How is your page variable populated?

0 votesVote for this answer Mark as a Correct answer

Neil Martin answered on July 22, 2019 16:45

Hi Brendan, this is what I am using...

var tree = new TreeProvider(MembershipContext.AuthenticatedUser);
var page = tree.SelectSingleNode(
    nodeGUID, CultureHelpers.GetCultureCode(), SiteContext.CurrentSiteName, true);
0 votesVote for this answer Mark as a Correct answer

Neil Martin answered on July 22, 2019 17:15

Hi Brendan,

After some further debugging I found I needed to modify the code to get the full page property set by using the selectCoupledData feature of the SelectSingleNode() method.

var nodeGUID = new Guid("63458203-83d9-4f30-b44b-c848aaca1941");
var tree = new TreeProvider(MembershipContext.AuthenticatedUser);

// Note, I need to use the 'selectCoupledData' parameter to get the custom fields
var coupledPage = tree.SelectSingleNode(page.NodeID, CultureHelpers.GetCultureCode(), true, true);

// The following property is inherited from its parent page - this contains the macro
// text that we want to expand - "{%AuthorBio%}"
var metaDescriptionMacro = coupledPage.GetInheritedValue("DocumentPageDescription");

// This variable is used to check that the actual 'AuthorBio' property is populated
var actualBio = coupledPage.GetValue("AuthorBio");  // This is populated as expected

// Here we try and get the macro defined in 'metaDescriptionMacro ' is expanded
// This returns an empty string
var metaDescription2 = MacroResolver.Resolve(
    coupledPage.GetInheritedValue("DocumentPageDescription").ToString());
0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on July 22, 2019 17:19

You beat me to posting the answer. Yes, you need the coupled data if you want page specific data. If you want to get base page data and the inherited values you need to get the inherited value. Mainly because the metadata can be set individually for each page OR it can be inherited for each page. If it's inherited, it can be inherited from any parent page in that path all the way up to the master page.

0 votesVote for this answer Mark as a Correct answer

Neil Martin answered on July 22, 2019 17:35 (last edited on July 22, 2019 17:42)

Hmm, even using the coupled data option, the MacroResolver is still returning an empty string. It seems as if the MacroResolver context cannot resolve the reference to the custom field property set on the page (i.e. AuthorBio in this case). Here is my current test code for completeness:

var coupledPage = tree.SelectSingleNode(page.NodeID, CultureHelpers.GetCultureCode(), true, true);

// The following property is inherited from its parent page - this contains the macro
// text that we want to expand - "{%AuthorBio%}"
var metaDescriptionMacro = coupledPage.GetInheritedValue("DocumentPageDescription").ToString();

// This variable is used to check that the actual 'AuthorBio' property is populated
var actualBio = coupledPage.GetValue("AuthorBio");  // This is populated as expected

// Here we try and get the macro defined in 'metaDescriptionMacro ' is expanded
// This returns an empty string
var metaDescription = MacroResolver.Resolve(metaDescriptionMacro);

This can actually be simplified (for the purposes of debugging) to:

var coupledPage = tree.SelectSingleNode(page.NodeID, CultureHelpers.GetCultureCode(), true, true);
var metaDescription = MacroResolver.Resolve("{% AuthorBio %}");

Which raises the question, how does the MacroResolver know what to resolve against?

0 votesVote for this answer Mark as a Correct answer

Neil Martin answered on July 22, 2019 18:31 (last edited on July 22, 2019 18:31)

I think I have found the problem, or at least a workaround. I changed the MacroResolver as follows:

var coupledPage = tree.SelectSingleNode(
    page.NodeID, CultureHelpers.GetCultureCode(), true, true);
var metaDescriptionMacro = coupledPage.GetInheritedValue(
    "DocumentPageDescription").ToString();

var resolver = MacroResolver.GetInstance();
resolver.SetAnonymousSourceData(coupledPage);
var metaDescription = resolver.ResolveMacros(metaDescriptionMacro);

Creating an instance of the MacroResolver and then setting the SetAnonymousSourceData seems to fix the problem.

0 votesVote for this answer Mark as a Correct answer

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