ecLearn - Learning Management System built on top of Microsoft Dataverse for Power Platform and Dynamics 365 users

ENGINEERED CODE BLOG

Where’s That Dynamics 365 Portals Code? – Part 1

When someone first gets started with the Portal capabilities for Dynamics 365, one thing I’ve noticed that can be a bit overwhelming is how many different places you can put a piece of HTML, JavaScript, CSS, Liquid, etc to achieve the same result. In this series of posts, I describe some of the options, and provide some our best practices.

General Structure

If our goal is to find out where someone has put HTML, JavaScript, CSS, or Liquid, it is helpful to understand the markup that is being returned by the Portals server when a page requested, because in the end, that’s typically where it will be (except of course you won’t see Liquid, as it’s evaluated on the server, but you will see the result of the Liquid code in the markup). The trick is determining where in the Dynamics 365 data that particular piece of code came from that eventually made it’s way into the response.

I like to think of the markup in a top-down approach. Those of you familiar with Adxstudio Portals will know that the Portals code is implemented as an ASP.NET Web Project, using Master Pages. However, as of v8, we no longer have access to this ASP.NET project, so it’s easiest to consider the page to be made up of three main building blocks – Header, Page Content, and Footer.

As a general rule, the markup that is returned when a page is requested is determined by the Page Template. The Portals code uses the requested URL to determine which Web Page the user is asking for, and then looks at the Page Template for that Web Page to determine how to render the page. The Page Template defines what appears in the Page Content, as well as if the site-wide header and footer are used.

Header and Footer

The header and footer are defined on the Website record by a lookup to Web Templates. Web Templates are essentially just named blocks that can contain elements like HTML, JavaScript, CSS, and Liquid, and can be referenced in many places. If you’re not familiar with them, check out this documentation as I’ll be referring to them quite a bit in the series.

However, if you look at the source of a Portals page, you’ll see a lot more markup than just what appears in your Header and Footer Web Templates, including a <head> section, JavaScript includes, and more. The Header and Footer Web Templates are just for the content that is displayed at the beginning and end of each page, within the <body> tag – the ASP.NET project hosted by Microsoft defines the proper HTML document structure, and inserts the Header and Footer Web Templates in the appropriate places.

Below is the markup that is returned for the most basic of pages. In this case, the Header, Footer and Page Content are simply HTML comments to show where they appear in the markup.

<!DOCTYPE html>
<html lang="en-US" data-lang="en-US" crm-lang="en-US" crm-lcid="1033">
	<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width,&#32;initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="IE=edge" />
			<script type="text/javascript">
				
			</script>
		<title>
	test&nbsp;&middot; Partner Portal
</title>
			
			<script src="/_resources/getresourcemanager?lang=en-US"></script>
		
		<script type="text/javascript">
			// Fix for incorrect viewport width setting in IE 10 on Windows Phone 8.
			if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
				var msViewportStyle = document.createElement("style");
				msViewportStyle.appendChild(document.createTextNode("@-ms-viewport{width:auto!important}"));
				document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
			}
		</script>
		<script type="text/javascript">
				
				var Microsoft = { 
					 Dynamic365 : {
					 	Portal : {
					 		User : {
					 			contactId : ''
					 		},
					 		version : '9.0.9.5',
					 		type: 'PartnerPortal',
							id: 'ec34b4c4-2055-41d1-b4c4-4b16f913ec24' 
					 	}
					}
				}
		</script>
		
			
			<link href="/bootstrap.min.css" rel="stylesheet" />

			<link href="/css/glyphicons-font-awesome-migrate.min.css" rel="stylesheet"/>

			<link href="/css/default.bundle.css?v=Q8Wnwe53xB7-kjp8-U_uZcJ-md-rchLH6k4CqBOwCF01" rel="stylesheet"/>

			
			<!--[if lt IE 9]>
				<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
			<![endif]-->
			
			<!--[if lt IE 10]>
				<script src="~/js/formdata.js"></script>
			<![endif]-->
			
			
			
			<link href="/theme.css" rel="stylesheet" />

			
			
			
			
		
			</head>
	<body data-sitemap-state="/test/:/"
		data-dateformat="M/d/yyyy"
		data-timeformat="h:mm tt"
		data-datetimeformat="M/d/yyyy h:mm tt"
		data-app-path="/"
		data-ckeditor-basepath="/js/BaseHtmlContentDesigner/Libs/msdyncrm_/libs/ckeditor/"
		data-case-deflection-url="/_services/search/6d6b3012-e709-4c45-a00d-df4b3befc518">
	
		
			<!-- header -->

		<!-- add anti-forgery token-->
		<div id="antiforgerytoken" data-url="/_layout/tokenhtml"></div>
		<script src="/js/default.preform.bundle.js?v=qOI-EizdNGe2Ld7pszjMTe5wtIkDv4tF6AhBB0-mp341"></script>

		
		
	<!-- web template -->


		
			<!-- footer -->

		
		
		
		<script src="/js/default-1033.bundle.js?v=2AUqahw12wEOa0Hgt-xiSiWX18DT3LVqeUFMcu6BQxM1"></script>

		
		
		
		<script>
			//this event will update the title of the page based on active breadcrumb
			$('.breadcrumb').ready(function () {
				if ($('.breadcrumb').is(':visible')) {
					document.querySelector('title').innerHTML = ($('.breadcrumb > li.active').text() + "&nbsp;&middot; Partner Portal");
				}
			});
		</script>
		
			
		
	</body>
</html>
<!-- Generated at 9/24/2018 3:17:23 AM -->
<!-- Page OK -->

Page Template

The Page Template offers a few variations. First of all, a Page Template is either of type Rewrite, or of type Web Template. This goes back to the old Adxstudio days (or the current xRM Portals Community Edition days) when it was possible to add your own ASPX templates to the web project. When you did this, you’d use the Rewrite type of Page Templates. This type is still in use today with the Microsoft-hosted version, but now that code is completely controlled by Microsoft, so it is not possible that a partner would add custom code to an ASPX template.

The other type is Web Template, which allows you to define the Page Content of a page using the Web Template entity.

Exceptions, Just to Keep Things Interesting

As I mentioned, most pages will leverage the site-wide Header and Footer Web Templates. However, this is not required, as in some cases it is desirable to not use the header and footer. This can be done during the development of your Page Template.

If you’re implementing using a Rewrite Page Template, you can choose to not include the header and footer by not inheriting from the project’s default master pages. Again, in the Microsoft-hosted portals, you don’t need to worry about this option.

If you’re creating a Page Template using Web Templates, it’s as simple as unchecking the Use Website Header and Footer option. This is especially useful when creating pages that return JSON (more like a web service as opposed to a page you’d expect a user to visit). In that case, the markup for the page is determined exclusively by what’s contained in the Web Template, and does not include the HTML document structure discussed in the Header and Footer section. In other words, the Web Template is completely responsible for the entire HTML response, including <html> and <body> tags, if necessary.

So, Where is the Code?

So at this point, I’ve introduced the idea headers, footers and the main page content. If the code you’re looking for appears on every page, start by looking at the Header and Footer Web Templates (or, if for some reason the defaults are not being used, look at which ever Web Templates are referenced in the Header and Footer lookups on the Website record).

Also keep in mind that Web Templates can (and often do) refer to other Web Templates, using the following syntax:

{% include 'Page Copy' %}

In this particular example, a Web Template called Page Copy is being included using the include Liquid keyword. So while the code may not be directly in the Header or Footer, it may be in a Web Template included in the Header or Footer.

In the next post, I’ll look at where the code might be if it page-specific.

9 responses to “Where’s That Dynamics 365 Portals Code? – Part 1”

  1. […] post Where’s That Dynamics 365 Portals Code? – Part 1 appeared first on Engineered […]

  2. […] my previous blog post, I talked about the overall page structure for a Dynamics 365 Portals page, and the main elements […]

  3. […] Where’s that Dynamics 365 portals code by Nicholas Hayduk […]

  4. […] my series on where you can (and should) put your HTML, CSS, Liquid and JavaScript I covered the various places where you can put code. In general, I like to put in the most specific […]

  5. Arthur says:

    I need to build a page that is connected to an Entity Form without Header and Footer. Everything (Form controls, validations, datepickers and odata retrieves and filters for entity lists) works fine only if I have checked the Header and Footer used by the website. Which scripts, libraries or methods should I include in my Web Template in order to have the same functionality?. I appreciate all your help.

    • Nicholas Hayduk says:

      I don’t know off hand exactly which scripts you’d need. The approach I’d recommend is looking at the source code for a page with the header and footer, and copy the script and CSS references from there – that might work.

      Nick

  6. […] my previous blog post, I talked about the overall page structure for a Dynamics 365 Portals page, and the main elements […]

  7. […] Unlike model-driven apps, there is no official JavaScript API for interacting with forms created using Entity Forms or Web Forms. But this doesn’t mean that it’s unsupported; instead, you need to rely on standard client-side web development techniques to meet your business requirements. Unfortunately, this means that any code you write for your model-driven forms won’t work since the API doesn’t exist on the portal. You have to create Portals-specific JavaScript (for details on all the different places you can drop this code in, see this series of posts). […]

  8. […] Unlike model-driven apps, there is no official JavaScript API for interacting with forms created using Entity Forms or Web Forms. But this doesn’t mean that it’s unsupported; instead, you need to rely on standard client-side web development techniques to meet your business requirements. Unfortunately, this means that any code you write for your model-driven forms won’t work since the API doesn’t exist on the portal. You have to create Portals-specific JavaScript (for details on all the different places you can drop this code in, see this series of posts). […]

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact

Engineered Code is a web application development firm and Microsoft Partner specializing in web portals backed by Dynamics 365 & Power Platform. Led by a professional engineer, our team of technology experts are based in Regina, Saskatchewan, Canada.