In a previous post I described a simpler approach to constructing a page. This post will delve deeper into exactly what is happening to render that page, how the dependency analysis works and what ultimately ends up on the page.
The URL “/share/page/dp/ws/my-new-page” was used to access the page. Once this request is mapped to the Share application the following occurs:
If you view the source of a page you should see the Dojo bootstrap configuration and a request to load the main “dojo.js” bootstrap module.
If you inspect the resources loaded into the page (e.g. in the Web Developer Tools or Firebug) you should also see the following files imported:
The names of the resources are MD5 checksums generated from the resource contents. This allows the browser to cache each resource indefinitely to avoid the need to download it again. Should the contents of the page change (e.g. an update to an individual modules source code or the page model being customized) then the resource contents will change, a new checksum will be generated and the browser will download the updated version.
“/share/res/890525bee5cf4228da1a0e45b491ed.css”
This contains all of the CSS resources referenced by widgets included in the page. Note that images are directly encoded into the resource to avoid additional HTTP requests.
“/share/res/40ef2558ae7e1d0a225e277cc6672d0.js”
This contains the messages object construction code and the call to instantiate the main “page” widget (shown highlighted). Note that it is declaring a requirement on the final resource loaded – it is requesting our dynamically built resource that includes all the dependencies.
“/share/res/js/surf/b4dc46167c64e043e227df402bf7bc1.js”
This is the layer that has been built through dynamic dependency analysis. Note how it contains core Dojo modules that have been identified as dependencies.
If you look in the “spring-surf-services-context.xml” file (this is included in “spring-surf-<n>.<n>.<n>.jar”) you’ll find a number of new bean definitions. Of these new beans the “dojo.dependency.handler” defines the main class for analysing the dependencies on a page. It has a property called “dependencyRules” that is a list of all the individual dependency handling beans. By default the following beans are referenced:
The purpose of each bean is to analyse the source code of each widget and identify one or more of 4 different types of dependency to include in the page:
All of these beans extend the “org.springframework.extensions.surf.DojoDependencyRule” class and use regular expressions configured in the bean context to identify the different dependencies. The “dojo.dependency.handler” passes the minified source of each module to each rule processor to identify additional dependencies (this means that the Regular Expression doesn't need to address whitespace characters or comments).
It’s possible to either reconfigure the regular expressions for the beans provided or create and add entirely new beans to the “dependencyRules” list to satisfy your specific requirements.
Dependencies are recursively processed until they have all been analysed. As each module is analysed it is added to a cache and if it is referenced again the cached version will be used. Surf does not allow a module to be analysed twice so even if circular dependencies are declared it will not fall into an infinite loop.
Even if it is not possible to identify all of the dependencies it is not a major problem. Ultimately Surf is just making an attempt to construct a layer containing all of the resources required for that page. If a resource is missing then the Dojo loader will simply asynchronously request it. In fact if you view the source on Share pages you will notice that the occasional AMD module is still getting asynchronously requested – there’s obviously a little bit of tightening up we could do on the dependency analysis expressions!
By default Share uses the “alfresco/core/Page” module as the root widget on the page (the default in a “vanilla” Surf application is “surf/core/Page” which is a much simpler version). However it is possible to update the “surf.xml” configuration to use any widget that you would prefer – simply update the “page-widget” element to map to whatever widget you’d like to use.
Hopefully this post has gone some way to explaining how Surf performs dependency analysis of the widgets included in a page in order to construct a build layer that can then be requested on the page. Although this series of posts relates specifically to Alfresco the Dojo dependency analysis code is part of Surf and as such could be used in independent applications.
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.