Skip to content

Instantly share code, notes, and snippets.

@mvirkkunen
Last active May 6, 2019 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mvirkkunen/10484486 to your computer and use it in GitHub Desktop.
Save mvirkkunen/10484486 to your computer and use it in GitHub Desktop.
<%@ Page Language="C#" %>
<%@ Import Namespace="EPiServer.Framework.Serialization"%>
<%@ Import Namespace="EPiServer.Framework.Web.Resources"%>
<%@ Import Namespace="EPiServer.ServiceLocation" %>
<%@ Import Namespace="EPiServer.Shell" %>
<%@ Import Namespace="EPiServer.Shell.Modules" %>
<script runat="server">
static IEnumerable<ModuleViewModel> GetModuleSettings()
{
// Adapted from EPiServer.Shell.UI.Bootstrapper.CreateViewModel
// Creates a data structure that contains module resource paths (JS and CSS) and settings.
var modules = ServiceLocator.Current.GetInstance<ModuleTable>();
var resourceService = ServiceLocator.Current.GetInstance<IClientResourceService>();
var moduleList = modules.GetModules()
.Select(m => m.CreateViewModel(modules, resourceService))
.OrderBy(mv => mv.ModuleDependencies != null ? mv.ModuleDependencies.Count : 0)
.ToList();
// Can be uncommented to remove a hard dependency on jQuery. ReportCenter.js is probably not needed on external pages
// anyways, and the only thing besides it that depends on epiJQuery seems to be the ancient version of TinyMCE EPiServer
// uses. If you want to use your own JQuery you must create a global alias called epiJQuery because the TinyMCE build is
// hardcoded to look for it, e.g.: window.epiJQuery = jQuery;
//foreach (ModuleViewModel mvm in moduleList)
// mvm.ScriptResources.RemoveWhere(r => r.EndsWith("/ReportCenter.js", StringComparison.OrdinalIgnoreCase));
return moduleList;
}
static string SerializeObject(object obj)
{
// On an MVC page this can be replaced with the built-in Html.SerializeObject extension method
using (var writer = new System.IO.StringWriter())
{
ServiceLocator.Current.GetInstance<IObjectSerializerFactory>().GetSerializer(KnownContentTypes.Json).Serialize(writer, obj);
return writer.ToString();
}
}
</script>
<!DOCTYPE html>
<html>
<head>
<title>EPiServer Dojo widgets outside the shell</title>
</head>
<%-- The default theme "Sleek" requires this class on body --%>
<body class="Sleek" style="padding: 20px;">
<%-- BEGIN EXAMPLE --%>
<h1>EPiServer Dojo widgets outside the shell</h1>
<h2>Select an image</h2>
<div id="mediaSelector"
data-dojo-type="epi-cms/widget/UrlContentSelector"
data-dojo-props="repositoryKey: 'media', allowedTypes: ['episerver.core.icontentimage'], allowedDndTypes: [], value: null"></div>
<div id="mediaDisplay" style="display: none; margin: 20px 0;"><img style="max-height: 200px; "/></div>
<h2>Or a page</h2>
<div id="pageSelector"
data-dojo-type="epi-cms/widget/ContentSelector"
data-dojo-props="repositoryKey: 'pages', allowedTypes: ['episerver.core.pagedata'], allowedDndTypes: [], value: null"></div>
<div id="pageDisplay" style="display: none; margin: 20px 0;"><a target="_blank"></a></div>
<script>
function example() {
require([
"dojo/_base/connect",
"dojo/query",
"dojo/when",
"dijit/registry",
"epi-cms/core/PermanentLinkHelper"
], function (
connect,
query,
when,
registry,
PermanentLinkHelper
) {
connect.connect(registry.byId("mediaSelector"), "onChange", function (link) {
if (!link) {
query("#mediaDisplay").style("display", "none");
return;
}
when(PermanentLinkHelper.getContent(link), function (content) {
console.log(query("#mediaDisplay").query("img"));
query("#mediaDisplay").style("display", "block")
.query("img").attr("src", content.publicUrl);
});
});
connect.connect(registry.byId("pageSelector"), "onChange", function (link) {
if (!link) {
query("#pageDisplay").style("display", "none");
return;
}
when(PermanentLinkHelper.getContent(link), function (content) {
query("#pageDisplay").style("display", "block")
.query("a").attr("href", content.publicUrl).text("Page: " + content.name);
});
});
});
}
</script>
<%-- END EXAMPLE --%>
<%-- Sets up the dojoConfig variable which contains module load paths and aliases. parseOnLoad is set to false
so that the parser can be run later after everything is loaded. --%>
<%= Page.ConfigureDojo(false, true, true) %>
<%-- Loads Dojo itself and a small collection of bundled EPi-specific classes --%>
<script type="text/javascript" src="<%= Paths.ToShellClientResource("ClientResources/dojo/dojo.js") %>"></script>
<script type="text/javascript" src="<%= Paths.ToShellClientResource("ClientResources/epi/epi.js") %>"></script>
<%-- This mainly loads epiJQuery and can be removed if it's not needed --%>
<%= Page.ClientResources("DojoDashboardCompatibility", new[] { ClientResourceType.Script }) %>
<script>
// At this point it's not safe to require() arbitrary things yet or everything will blow up spectacularly. The
// "Bootstrapper" has to be run first, so only require that.
require(["epi/shell/Bootstrapper"], function (Bootstrapper) {
var bs = new Bootstrapper(<%= SerializeObject(GetModuleSettings()) %>);
// Loads the specified module ("CMS") and all the script bundles ClientResources that come with it. If this isn't done
// correctly all require() calls will load modules with separate requests which can reduce the amount of total code
// loaded but generates a *lot* of requests in the process
bs.initializeApplication(null, "CMS").then(function () {
// It's now safe to require() anything including your own modules.
require([
"dojo/_base/connect",
"dojo/parser",
"epi-cms/ApplicationSettings"
], function (
connect,
parser,
ApplicationSettings
) {
// This sets the "current context" which is required by some controls such as the WYSIWYG.
// It's used to show the current page media list as well as the "Current page" button in page selectors. This
// just sets it to the root page so everything doesn't break.
connect.publish("/epi/shell/context/updateRequest", [{ uri: "epi.cms.contentdata:///" + ApplicationSettings.rootPage }]);
// All done! Everything should be set up now. Run your own code here.
// Should probably run this at some point as it's not done automatically - this initializes all the declarative
// widgets (elements with data-dojo-type). Use .then() if you want to run code after this to ensure everything has
// finished executing.
parser.parse().then(example);
});
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment