Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jamie Attwood 112 posts 318 karma points
    Sep 28, 2018 @ 20:23
    Jamie Attwood
    0

    Virtual Nodes Macros Not rendering!

    Spent considerable trying to generate virtual pages/nodes to mirror content generated in another area of my CMS using custom routing as hinted at here: https://our.umbraco.com/documentation/reference/routing/custom-routes and in this great article here: https://blog.sandervanlooveren.be/posts/custom-routes-in-umbraco-for-better-seo/

    Finally got it all up and running as a proof of concept after trying to track down all the assembly references (this drives me nuts how the documentation never includes this critical information - it's not always available via intellisense...). Interestingly the view that I passed in (that relies on a few macros for navigation, etc.) are not rendering in the virtual page views....

    Essentially if I attempt to render a macro in the view that uses no dynamic parameters, like this: @Umbraco.RenderMacro("Breadcrumb") it works.

    If I try to evaluate a field and pass it to the macro, there is a null result:

    @Umbraco.RenderMacro("UtilityNavigation", new {startNodeId= Umbraco.Field("utilityMenu", recursive: true),showLanguageToggle="0"})

    Perhaps it's because of the properties being called rely on recursive and virtual items are not able to traverse a virtual node tree?

    Anyone know why they would not be rendering, no errors, just blank.??

    Thanks in advance,

    Jamie

  • David Peck 583 posts 1546 karma points c-trib
    Sep 28, 2018 @ 21:39
    David Peck
    0

    I spent some time on something similar early this week. The RenderMacro code assumes quite a lot about your request, including that you have a PublishedContentRequest properly set. If you don't then it just renders nothing.

    So I'd make sure that your custom route properly sets a really content item to the request and perhaps look at your route handlers PreparePublishedContentRequest(PublishedContentRequest) in case there is more you can do it get your custom route looking like a normal request.

  • Jamie Attwood 112 posts 318 karma points
    Oct 09, 2018 @ 16:44
    Jamie Attwood
    0

    Thanks David for getting back to me on this. I believe that you are right in that the context is not returning back as I was expecting it, this leads me to believe that the recursive elements that my in view macros are looking for are not present in the node tree and are therefore not returning to me. Here is my problem in detail.

    I have a multi language site structure with a shared content folder content folder that is stored outside of the website trees like this:

    Content
    - English
    -- English page virtual page placeholder
    
    - French
    -- French page virtual page placeholder
    
    - Shared content Folder
    --Shared content item
    

    I am trying to push the virtual pages to both placeholders while retaining the context of the actual English/French page virtual page placeholder pages. To achieve this, I allowed the shared content doc type as a child of my EN/FR site.

    I am aware that in my CustomRouteHandler, there are several overrrides on FindContent(), however the documentation is pretty thin on the examples of this. Any idea how I can pass in the context of my placeholder page? Here is my route handler:

    public class CustomRouteHandler : UmbracoVirtualNodeRouteHandler
        {
            protected override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext)
            {
                var umbracoHelper = new UmbracoHelper(umbracoContext);
    
                //I am trying to look for the first item under the "shared content" (ID 1153) page of doctype "SharedContent" in order to properly build a model and reference from which to compose the request.
                return umbracoHelper.TypedContent(1153).Descendants().FirstOrDefault(c => c.DocumentTypeAlias == "SharedContent");
            }
    }
    

    and my controller:

    public class SharedContentController : RenderMvcController
        {
            public ActionResult Index(RenderModel model, string name)
            {
                var sc= GetSharedContent(name);
                if (sc == null)
                    return HttpNotFound();
    
                return View("SharedContentPage", sc);
            }
    
            private IPublishedContent GetSharedContent(string name)
            {
                var umbracoHelper = new UmbracoHelper(UmbracoContext);
    
                var container = umbracoHelper.TypedContent(1157);
                if (container == null)
                    return null;
    
                foreach (var child in container.Descendants("SharedContent"))
                {
                    if (child.Url.Contains(name))
                        return child;
                }
    
                return null;
            }
        }
    
  • David Peck 583 posts 1546 karma points c-trib
    Oct 09, 2018 @ 20:27
    David Peck
    0

    While I can't speak for the logic in your FindContent method, if looks correct. You're sure your route handler and your controller is firing on your request? That will show that your route is set up correctly.

    What you returned in your route handler should be passed through as the argument to your Index method. Is it not? Potentially try changing RenderModel model to IPublishedContent model.

  • Jamie Attwood 112 posts 318 karma points
    Oct 10, 2018 @ 20:45
    Jamie Attwood
    0

    Thanks for all your time David - much appreciated, I tried some of your suggestions, unfortunately no go. So to be clear, the virtual route is working, however it pulls with it the context passed from the controller (the source item). So for example, if I output @CurrentPage.Parent.Id my view returns the parent of the source content item, and not the parent of the placeholder specified in the Find content method....

    Can I ask the question, what exactly does the CustomRouteHandler do?, in my case it's not pulling the context in the way that I thought it would... if I am passing in content through the controller, I am not even sure why I should be using the Find Content method in the CustomRouteHandler...

    Again thanks for your thoughts...

    Jamie

  • David Peck 583 posts 1546 karma points c-trib
    Oct 10, 2018 @ 20:59
    David Peck
    0

    The CustomRouteHandler is intended to help with routes/paths that don't have a corresponding IPublishedContent. It fires before the controller that is specified in the route and should receive the IPublishedContent supplied by the CustomRouteHander as an argument.

  • Jamie Attwood 112 posts 318 karma points
    Oct 11, 2018 @ 14:01
    Jamie Attwood
    0

    Ok thanks David, I'm switching to workaround mode now and providing fixed property values for those recursive elements that are not present in the virtual node.

    The reference provided in the FindContent Method sort of works - the breadcrumb for example indicates the correct location on the node tree, however, the provided model in the controller seems to overwrite everything else so none of the recursive elements can be found as the virtual node still thinks its located in the shared content tree, not the website tree. Maybe I am looking for something that does not exist - a hybrid of the model of the website virtual item and the provided controller model.

    Thanks for all your help on this.

    Jamie

Please Sign in or register to post replies

Write your reply to:

Draft