In daily routine, while working in CRM, we keep using entities from the sitemap.
In this article, I am going to show you how we can add HTML web resources in Sitemap as Sub Area. An HTML page can be accessed in the same way as we access any entity in CRM.
There are different blogs that are available over the internet which shows how to do this using C# code.
The major challenge was to add HTML web resource in Sitemap and then publish using JavaScript code only.
I am using the “Settings” area and “Extensions” group in the XML of sitemap where I will add a subarea representing an HTML web resource. You can choose any area and group from a sitemap as per your needs.
The code below has 4 JS functions
createHTMLSubArea //— used to call “createHTMLSubArea”
addSitemapSubArea //— Used to add HTML webresource in sitemap
updateAndPublishSitemap //— Used to update sitemap XML after adding a webresource
publishSitemap //— Called from within function “updateAndPublishSitemap”. This will just publish the updated sitemap.
I tried to find a way over the internet how to publish sitemap changes using JavaScript but I didn’t find any blog depicting that. In order to think about its solution, I thought there should be some way to do this in RestBuilder (Developer by Jason Latimer). There is an action named “PublishXml” in RestBuilder. So, I used this and it worked. You can use PublishXmlRequest in C# to achieve the same. This is the link to Rest Builder.
Here is the complete code in JavaScript
// JavaScript source code var Sitemap = Sitemap || {}; Sitemap.createHTMLSubArea = function() { var webResourceGuid = '0e0207a0-68d5-46a7-92fd-d5901aea8428'; //-- A unique GUID of a web resource in CRM var InputParam_subAreaId = 'AUniqueSubAreadId'; //--- Any text containing alphabets and under score without space var InputParam_subAreaURL = '$webresource:prefix_ASampleHTMLPage'; //-- An HTML page already registered in CRM as a web resource var InputParam_subAreaTitle = 'A Sample HTML Page'; //--Any text containing alphabets and spaces var InputParam_subAreaIcon = '$webresource:prefix_/Images/Common/AnyImage32'; //--- It can be JPG, GIF or PNG var subAreaDescription = ''; Sitemap.addSitemapSubArea(webResourceGuid, InputParam_subAreaId, InputParam_subAreaURL, InputParam_subAreaTitle, InputParam_subAreaIcon, subAreaDescription); } Sitemap.addSitemapSubArea = function (webResourceGuid, InputParam_subAreaId, InputParam_subAreaURL, InputParam_subAreaTitle, InputParam_subAreaIcon, subAreaDescription) { var InputParam_GroupId = "Extensions"; var inputParam_AreaId = "Settings"; var req = new XMLHttpRequest(); req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.1/sitemaps?$select=sitemapid,sitemapxml", false); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("Prefer", "odata.include-annotations=\"*\""); req.send(); if (req.readyState === 4) { req.onreadystatechange = null; if (req.status === 200) { var data = JSON.parse(req.response); if (data != undefined && data != null) { var sitemapXML = data.value[0]["sitemapxml"]; var sitemapId = data.value[0]["sitemapid"]; var oParser = new DOMParser(); var oDOM = oParser.parseFromString(sitemapXML, "application/xml"); var areas = oDOM.children[0].getElementsByTagName("Area"); for (var i = 0; i < areas.length; i++) { var areaId = areas[i].getAttribute("Id"); var groups = areas[i].getElementsByTagName("Group"); var groupObject = null; for (var j = 0; j < groups.length; j++) { var groupId = groups[j].getAttribute("Id"); if (groupId == InputParam_GroupId && inputParam_AreaId == areaId) { var subArea = oDOM.createElement("SubArea"); subArea.setAttribute("Id", InputParam_subAreaId); subArea.setAttribute("Url", InputParam_subAreaURL); subArea.setAttribute("Description", subAreaDescription); subArea.setAttribute("Title", InputParam_subAreaTitle); subArea.setAttribute("AvailableOffline", "false"); subArea.setAttribute("PassParams", "false"); if (InputParam_subAreaIcon != undefined && InputParam_subAreaIcon != null && InputParam_subAreaIcon != '') { subArea.setAttribute("Icon", InputParam_subAreaIcon); } groups[j].appendChild(subArea); break; } } } Sitemap.updateAndPublishSitemap(oDOM.children[0].outerHTML, sitemapId, "add", InputParam_subAreaURL); } } } } Sitemap.updateAndPublishSitemap = function (siteMapXML, sitemapId, operationPerformed, webResourceURL) { var entity = {}; entity.sitemapxml = siteMapXML; var req = new XMLHttpRequest(); req.open("PATCH", Xrm.Page.context.getClientUrl() + "/api/data/v8.1/sitemaps(" + sitemapId + ")", false); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("Prefer", "odata.include-annotations=\"*\""); req.send(JSON.stringify(entity)); if (req.readyState === 4) { req.onreadystatechange = null; if (req.status === 204) { Sitemap.publishSitemap(sitemapId, operationPerformed, webResourceURL); } else { alert('Unable to update sitemap.'); } } } Sitemap.publishSitemap = function (sitemapId, operationPerformed, webResourceURL) { var parameters = {}; parameters.ParameterXml = "<importexportxml><sitemaps><sitemap>" + sitemapId + "</sitemap></sitemaps></importexportxml>"; var req = new XMLHttpRequest(); req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.1/PublishXml", false); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.send(JSON.stringify(parameters)); if (req.readyState === 4) { req.onreadystatechange = null; if (req.status === 204) { alert('Sitemap is published successfully.'); } else { alert('Unable to publish sitemap.'); } } }
*This post is locked for comments