Load resources
Shows how to load additional resources after form rendering with IViewModeExternalResources.
NoteOptimizely Forms is only supported by MVC-based websites and HTML5-compliant browsers.
You can load additional resources after form rendering with IViewModeExternalResources. Implement the IViewModeExternalResources interface to return a list of resources (JavaScript or CSS files) that are loaded into ViewMode along with EPiServerForms.js.
The interface is used mostly for the following:
- Third-party validators.
- Rich element types (with rich, complex user interface that needs JavaScript to render UI and handle interaction), such as
DateTimeElementin theForms.Samplesproject.
using EPiServer.Forms.Core;
using EPiServer.ServiceLocation;
using System;
using System.Collections.Generic;
namespace EPiServer.Templates.Alloy.FormsExtended {
/// <summary>
/// This example will force Forms.Core to load a JS and a CSS file
/// (at http://example.com/Customized/ViewMode/Alloy.css) along with Form rendering
/// </summary>
[ServiceConfiguration(ServiceType = typeof (IViewModeExternalResources))]
public class ExampleViewModeExternalResources: IViewModeExternalResources {
public IEnumerable<Tuple<string, string>> Resources {
get {
var arrRes = new List<Tuple<string, string>>();
arrRes.Add(new Tuple<string, string>("script", "/Customized/ViewMode/Example.js"));
arrRes.Add(new Tuple<string, string>("css", "/Customized/ViewMode/Example.css"));
// The above line will not work in nonJS mode
return arrRes;
}
}
}
}Load embedded resources from separate projects
When developing element blocks in separate projects (for instance, a class library) within your Optimizely solution, you might embed JavaScript or CSS files directly into those projects. Unlike external files accessible through standard web paths, these embedded resources are compiled into your assembly and are not directly addressable by a URL. To load them using the IViewModeExternalResources interface, you must first expose them through your main web application.
This typically involves one of two common ASP.NET patterns:
-
Use a custom
VirtualPathProvider.A
VirtualPathProviderallows you to map virtual paths (URLs) within your web application to resources that are not physically present in the web project's file system, such as embedded resources in a separate assembly.- Create a custom
VirtualPathProvider– Implement a class that inherits fromVirtualPathProvider(for ASP.NET) orIFileProvider(for ASP.NET Core) to locate and serve your embedded resources. This implementation will typically useAssembly.GetManifestResourceStream()to read the embedded file. - Register the provider – Register your custom
VirtualPathProviderwith your application at startup. - Define the virtual paths – Establish a convention for virtual paths that correspond to your embedded resources (for instance,
~/EmbeddedResources/MyProject/Scripts/my-script.js).
- Create a custom
-
Implement a dedicated controller or handler.
Alternatively, you can create a specific controller action or an HTTP handler in your main web project whose sole purpose is to retrieve and serve embedded resources.
- Create a controller action – Develop a controller action that takes a resource identifier (for instance, assembly name, resource path) as a parameter.
- Retrieve and serve – Inside the action, use
Assembly.GetManifestResourceStream()to read the embedded resource and return it as aFileResultwith the appropriate MIME type. - Define the route – Configure a route that maps a URL pattern (for instance,
/embedded-content/{assemblyName}/{resourcePath}) to this controller action.
Reference exposed embedded resources
When your embedded resources are exposed and accessible through a URL (whether through a VirtualPathProvider or a dedicated controller/handler), you can then reference them in your IViewModeExternalResources implementation just like any other external resource:
namespace EPiServer.Templates.Alloy.FormsExtended
{
[ServiceConfiguration(ServiceType = typeof(IViewModeExternalResources))]
public class ExampleViewModeExternalResources : IViewModeExternalResources
{
public IEnumerable<Tuple<string, string>> Resources
{
get
{
var arrRes = new List<Tuple<string, string>>();
// Reference an embedded script exposed via a custom mechanism
arrRes.Add(new Tuple<string, string>("script", "/EmbeddedResources/MyElementBlockProject/Scripts/my-block-script.js"));
// Reference an embedded stylesheet exposed via a custom mechanism
arrRes.Add(new Tuple<string, string>("css", "/EmbeddedResources/MyElementBlockProject/Styles/my-block-style.css"));
return arrRes;
}
}
}
}Important considerations
- MIME Types – Ensure your
VirtualPathProvideror controller correctly sets the Content-Type header (for instance, application/javascript for .js files, text/css for .css files) to ensure browsers interpret the resources correctly. - Caching – Implement appropriate caching headers to optimize performance for these served resources.
- Security – Be mindful of security implications when exposing embedded resources. Ensure that only intended files are served and that no sensitive information is inadvertently exposed.
This approach lets you maintain your element block's resources within its own project while still integrating seamlessly with Optimizely Forms' resource loading mechanism.
