[ How to: ] On the fly On demand Pages - Glidias/Kilogaiajax GitHub Wiki

I encountered this problem when developing websites with potentially numerous static/dynamically generated links (eg. blogs-articles/project-pages, etc.). What happens if ajaxified anchor links (or user-inputted browser urls) aren't explicitly found in the site.xml, but you still need to transition into those pages (or preload specific stuff) as if it's an Ajax-based page? This guide provides a workaround to get around such a limitation, allowing you to dynamically add (on-the-fly/on-demand) valid pages to specific branches in your Site Model structure at runtime in order to successfully transition into those pages!

The basic premise is to consider whether to dynamically add a page, given a navigation change that occurs (or when you first enter the website). (This "change" will happen as a deeplink, since the page isn't declared in the Site XML explicitly. The objective is to prevent this from happening by hooking the onChange event to consider whether dynamically add a page into the Site Model beforehand via Gaiajax.api.setOnDemandPage(handler:Function) method.

Generally, you need to check whether to add a page-on-demand whenever an ajax link is being clicked upon (or navigation occurs via History forward/back). Also, when you first land upon the page, you need to check whether the current address bar URL refers to a specific dynamic Gaia page to be loaded on demand. Thus, you need to create a specifc handler method to handle these cases:

The structure of the handler method goes like this:

function( href:String, jqAnchor:JQuery)

  • href - If a gaiaHrefLink anchor tag is clicked and/or navigation via history occurs, this parameter contains the href attribute value.
  • jqAnchor - If a gaiaHrefLink anchor tag is clicked, this parameter contains the JQuery for the anchor tag. Otherwise, it is null.

This is the basic code structure you use:

Gaiajax.api.onSiteXMLReady.add( function() {		
	var gaiaOnDemandHandler = function(href, jqAnchor) { 
		var srcURL =   Gaiajax.api.getSrcURL(href  || window.location.href);
		if ( !Gaiajax.api.getPageBySrc(srcURL) ) { 
			// no page such page for src attribute is currently found in Site Model, 
                      // Prepare to call Gaiajax.api.setOnDemandPage() (if needed) with relevant parameters as determined from srcURL.
		}
	}	
	Gaiajax.api.setOnDemandPageHandler(gaiaOnDemandHandler);  // to capture gaiaHrefLinks when they are being clicked upon
	Gaiajax.api.onChange.add( gaiaOnDemandHandler) ;  // to capture browser history back/forward navigation 
	gaiaOnDemandHandler(); // to determine if current URL is valid
});

Here's a basic rundown of the parameters for setOnDemandPage():

setOnDemandPage(src:String, branchPath:String, id:String, assetBranchPath:String, title:String)

  • src (Required) The "src" attribute of the page.
  • branchPath (Required) The branch location to place this page in the Site Model XML, either at root (eg. an empty string "") or some branch path location without trailing slash (eg. "blog" or something like "page-container/section"). The branchPath is usually a unique path pointing to a specific unique page resource. If it currnetly doesn't exist, it'll create the path accordingly. If it already exists, it will replace it with the parameters defined for the page-on-demand. If it's defined as an empty string, then the "id" parameter is used as a branchPath from the root index location of the site.
  • id (Required) The "id" attribute of the page node.
  • assetBranchPath (Optional) A branch path pointing to a page node already found in the Site XML, which contains asset nodes to use/reference for the newly added page branch path.
  • title (Optional) The "title" attribute of the page. If left null or empty string, it'll be "Untitled". If you are unsure of what title to use (because the nature of the page hasn't been determined yet), you could use a string consisting of an empty space " " first, and later assign the title dynamically through some other means when the page's HTML contents are ready.

To dynamically generate a uniquely-identifiable page on-the-fly, ensure you either supply a unique id for the page, or a unique branch path, for the given src.

Simple catch-all example

A simple "catch-all" pages example that involves adding any HTML page dynamically on the fly (uniquely identifying pages by their html page name without file extension) at site root level (without any asset dependencies), is found below. Using this approach, you could even theoretically keep your site.xml empty (i think..) without having to explicitly declare any other pages (except maybe the homepage). You'd, however, need to explicitly specify a "data-title" attribute to any ajaxified anchor link, in order to determine the the page title to set by javascript. (Or, you could determine this through some other means later, once the HTML contents are loaded in and you could use some "data-title" attribute to be search for on on some dynamically loaded page section, etc.)

Gaiajax.api.onSiteXMLReady.add( function() {		
	var gaiaOnDemandHandler = function(href, jqAnchor) { 
		var srcURL =   Gaiajax.api.getSrcURL(href  || window.location.href);
		if ( !Gaiajax.api.getPageBySrc(srcURL) ) { 
          
           var pageId = srcURL; 
            // pageId = srcURL.split("/").pop().split(".")[0]  // for 'uniqueFileName.fileExtension' format
			Gaiajax.api.setOnDemandPage(srcURL, "", pageId, null, jqAnchor ? (jqAnchor.data("title") || document.title) : document.title )
		}
	}	
	Gaiajax.api.setOnDemandPageHandler(gaiaOnDemandHandler);  
	Gaiajax.api.onChange.add( gaiaOnDemandHandler) ;  back/forward navigation 
	gaiaOnDemandHandler(); 
});

Thus, this will allows you to transition seamlessly to ANY html content without having to declare them explicitly in the site.xml.

The parameter "jqAnchor" for the gaiaOnDemandHandler refers to any specific clicked-on link (if any) that triggered the URL (history api) change. The srcURL refers to the specific href relative to the site. By examining the srcURL property, you determine how should a page by dynamically loaded accordingly.