Uploaded image for project: 'Hippo CMS'
  1. Hippo CMS
  2. CMS-15203

[Backport 15.2] Support efficient SiteMap rendering in the Channel Manager for many XPage documents

    XMLWordPrintable

Details

    • New Feature
    • Status: Closed
    • Normal
    • Resolution: Fixed
    • None
    • 15.2.0
    • None
    • None
    • Quasar
    • Quasar Sprint 298, Quasar Sprint 300
    • Medium (3-5)

    Description

      Problem description

      When rendering the SiteMap in the Channel Mgr, we need to see a sitemap which is the result of

      1. The HST sitemap (routes)
      2. All XPage documents

      At this moment, the entire SiteMap is returned to the client (browser). This doesn't scale in case there are many XPage documents (which has been known since the inception of the feature). This is because the entire SiteMap has to be computed and will be recomputed on every request for every Channel Mgr user.

      Complexity

      What makes it very complex is that

      1. To 'know' the URL space for XPage documents, the HST needs to find a URL (pathInfo) for every XPage document. This can only be done via the HST linkcreator as the HST sitemap (routes) influence the pathInfo (URL). For this reason, to figure out the hierarchical URL space for all XPage documents, we need to get a URL for all of them, which doesn't scale with increasing amount of XPage documents. Note that the HST sitemap (routes) can be different for different branches of a channel
      2. The XPage documents URL space needs to be merged with the HST sitemap (routes) which can also have URLs (explicit sitemap (routes) items)
      3. the CMS user session might not have read access to all XPage documents : as the SiteMap is user specific, caching becomes much harder

      Solution

      In memory model

      Instead of every user rendering its own PageTree (SiteMap) model which is expensive to create, we'll create a service backed by a jcr READ everywhere session which loads the model in memory. Note that these models will be PER channel (and potentially per BRANCH however only when the branch has sitemap changes we should do this)

      This model must be kept in sync with fine grained invalidation when a handle node gets

      1. created
      2. deleted
      3. moved
        And also when the HST sitemap (routes) gets modified for a channel (branch). Special handling might be needed for the sitemap of a branch in case the sitemap for the branch gets modified.

      For this to work, we must add a JCR listener which triggers a reload of the model whenever needed.

      When returning the SiteMap model to the user, we cannot return the in-memory SiteMap model as this is rendered by a JCR Session which has read-everywhere.

      We need to filter the SiteMap to remove entries which are not readable by the current user

      'Resty' model

      At this moment, the 'resty' endpoint

      _rp/{sitemapUUID}./pagetree
      

      returns the entire SiteMap, regardless of which part is visible.

      However instead of returning the entire SiteMap, we can instead return only the visible elements. This means we need extra 'resty' endpoints which will return deeper nested SiteMap structures.

      Current Response

      The current response for a call like

      _rp/{sitemapUUID}./pagetree
      

      is something like

      {
         "errorCode":null,
         "message":"Page tree loaded successfully",
         "reloadRequired":false,
         "success":true,
         "data":{
            "id":"/",
            "name":"home",
            "pageTitle":null,
            "pathInfo":"/",
            "renderPathInfo":"/site/v1/channels/brxsaas",
            "experiencePage":false,
            "children":[
               {
                  "id":"about",
                  "name":"about",
                  "pageTitle":"About",
                  "pathInfo":"about",
                  "renderPathInfo":"/site/v1/channels/brxsaas/about",
                  "experiencePage":true,
                  "children":[
                     
                  ]
               },
               {
                  "id":"articles",
                  "name":"articles",
                  "pageTitle":null,
                  "pathInfo":"articles",
                  "renderPathInfo":"/site/v1/channels/brxsaas/articles",
                  "experiencePage":false,
                  "children":[
                     
                  ]
               },
               {
                  "id":"aaa",
                  "name":"Aaa",
                  "pageTitle":null,
                  "pathInfo":null,
                  "renderPathInfo":null,
                  "experiencePage":false,
                  "children":[
                     {
                        "id":"bbb",
                        "name":"Bbb",
                        "pageTitle":null,
                        "pathInfo":null,
                        "renderPathInfo":null,
                        "experiencePage":false,
                        "children":[
                           {
                              "id":"ccc",
                              "name":"Ccc",
                              "pageTitle":null,
                              "pathInfo":null,
                              "renderPathInfo":null,
                              "experiencePage":false,
                              "children":[
                                 {
                                    "id":"mydoc",
                                    "name":"MyDoc",
                                    "pageTitle":"bar",
                                    "pathInfo":"test/test/foo/bar",
                                    "renderPathInfo":"/site/v1/channels/brxsaas/aaa/bbb/ccc/mydoc",
                                    "experiencePage":true,
                                    "children":[
                                       
                                    ]
                                 }
                              ]
                           }
                        ]
                     }
                  ]
               }
            ]
         }
      }
      

      With the above, the UI shows for the sitemap something like

      / 
         + about
         + articles
         +  > Aaa
      

      in which the > Aaa  starts with '>' to indicate that it can be expanded. NOTE that in the example above > Aaa  does have a 'renderPathInfo' of NULL. The result is that it can be expanded but a click on it won't load the page for 'Aaa' as there is no such page.

      New 'Resty' endpoint

      We'll add

      __rp/{sitemapUUID}./sitemapitem
      

      Instead of the above response, when being the homepage, the response will be:

      {
         "errorCode":null,
         "message":"Page tree loaded successfully",
         "reloadRequired":false,
         "success":true,
         "data":{
            "id":"/",
            "name":"home",
            "pageTitle":null,
            "pathInfo":"/",
            "renderPathInfo":"/site/v1/channels/brxsaas",
            "experiencePage":false,
            "children":[
               {
                  "id":"about",
                  "name":"about",
                  "pageTitle":"About",
                  "pathInfo":"about",
                  "renderPathInfo":"/site/v1/channels/brxsaas/about",
                  "experiencePage":true,
                  "expandable":false
               },
               {
                  "id":"articles",
                  "name":"articles",
                  "pageTitle":null,
                  "pathInfo":"articles",
                  "renderPathInfo":"/site/v1/channels/brxsaas/articles",
                  "experiencePage":false,
                  "expandable":false
               },
               {
                  "id":"aaa",
                  "name":"Aaa",
                  "pageTitle":null,
                  "pathInfo":null,
                  "renderPathInfo":null,
                  "experiencePage":false,
                  "expandable":true
               }
            ]
         }
      }
      

      With the above response. the FE can also draw

      / 
         + about
         + articles
         +  > Aaa
      
      

      When clicking in the FE on 'Aaa', the FE must invoke

      __rp/{sitemapUUID}./sitemapitem/aaa
      

      which will return 'aaa' and the direct children of 'aaa' and the FE will include the response in the UI,. The response will contain again for the children whether they are expandable, and if so, eg

      _rp/{sitemapUUID}./sitemapitem/aaa/bbb
      

      can be invoked for the next level.

      Attachments

        Issue Links

          Activity

            People

              aschrijvers Ard Schrijvers
              aschrijvers Ard Schrijvers
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: