├── .editorconfig ├── .gitattributes ├── .gitignore ├── Alloy.Mvc.Template.sln ├── LICENSE ├── README.md ├── build ├── Templates.targets ├── database │ ├── Alloy.mdf │ └── DefaultSiteContent.episerverdata ├── tools │ └── EPiServer.Build.Tasks.dll └── transformers │ ├── AlloyMvc.Views.web.config.transform │ ├── AlloyMvc.web.config.transform │ └── web.config.install.xdt ├── setup.cmd └── src └── Alloy.Mvc.Template ├── Alloy.Mvc.Template.Search.Sources.nuspec ├── Alloy.Mvc.Template.Sources.nuspec ├── Alloy.Mvc.Template.csproj ├── Business ├── AdministratorRegistrationPage.cs ├── Channels │ ├── DisplayResolutionBase.cs │ ├── DisplayResolutions.cs │ ├── MobileChannel.cs │ └── WebChannel.cs ├── ContentExtensions.cs ├── ContentLocator.cs ├── EditorDescriptors │ ├── ContactPageSelectionFactory.cs │ ├── ContactPageSelector.cs │ └── StringListEditorDescriptor.cs ├── IModifyLayout.cs ├── Initialization │ ├── BundleConfig.cs │ ├── CustomizedRenderingInitialization.cs │ ├── DependencyResolverInitialization.cs │ ├── DisplayModesInitialization.cs │ ├── DisplayRegistryInitialization.cs │ ├── ExtendedTinyMceInitialization.cs │ └── FilterConfig.cs ├── PageContextActionFilter.cs ├── PageTypeExtensions.cs ├── PageViewContextFactory.cs ├── Rendering │ ├── AlloyContentAreaRenderer.cs │ ├── ErrorHandlingContentRenderer.cs │ ├── IContainerPage.cs │ ├── ICustomCssInContentArea.cs │ ├── SiteViewEngine.cs │ └── TemplateCoordinator.cs ├── SearchService.cs ├── ServiceLocatorDependencyResolver.cs └── UIDescriptors │ └── ContainerPageUIDescriptor.cs ├── ClientResources ├── Images │ └── icons │ │ └── layoutIcons24x24.png ├── Scripts │ └── Editors │ │ └── StringList.js └── Styles │ ├── LayoutIcons.css │ └── Styles.css ├── ConnectionStrings.config ├── Controllers ├── ContactBlockController.cs ├── DefaultPageController.cs ├── ImageFileController.cs ├── PageControllerBase.cs ├── PageListBlockController.cs ├── PreviewController.cs ├── RegisterController.cs ├── SearchPageController.cs ├── StartPageController.cs └── VideoFileController.cs ├── EPiServerFramework.config ├── Global.asax.cs ├── Global.cs ├── Helpers ├── CategorizableExtensions.cs ├── HtmlHelpers.cs └── UrlHelpers.cs ├── IndexingService └── IndexingService.svc ├── Models ├── Blocks │ ├── ButtonBlock.cs │ ├── ContactBlock.cs │ ├── EditorialBlock.cs │ ├── JumbotronBlock.cs │ ├── PageListBlock.cs │ ├── SiteBlockData.cs │ ├── SiteLogotypeBlock.cs │ ├── TeaserBlock.cs │ └── _ReadMe.txt ├── Media │ ├── GenericMedia.cs │ ├── ImageFile.cs │ └── VideoFile.cs ├── Pages │ ├── ArticlePage.cs │ ├── ContactPage.cs │ ├── ContainerPage.cs │ ├── IHasRelatedContent.cs │ ├── ISearchPage.cs │ ├── LandingPage.cs │ ├── NewsPage.cs │ ├── ProductPage.cs │ ├── SearchPage.cs │ ├── SitePageData.cs │ ├── StandardPage.cs │ ├── StartPage.cs │ └── _ReadMe.txt ├── Properties │ └── PropertyStringList.cs ├── Register │ └── RegisterViewModel.cs ├── SiteContentType.cs ├── SiteImageUrl.cs └── ViewModels │ ├── ContactBlockModel.cs │ ├── ContentRenderingErrorModel.cs │ ├── IPageViewModel.cs │ ├── ImageViewModel.cs │ ├── LayoutModel.cs │ ├── PageListModel.cs │ ├── PageViewModel.cs │ ├── PreviewModel.cs │ ├── SearchContentModel.cs │ └── VideoViewModel.cs ├── Properties └── AssemblyInfo.cs ├── Resources └── LanguageFiles │ ├── ContentTypeNames.xml │ ├── Display.xml │ ├── EditorHints.xml │ ├── GroupNames.xml │ ├── PropertyNames.xml │ ├── Views.xml │ └── _ReadMe.txt ├── Startup.cs ├── Static ├── css │ ├── bootstrap-collapse.js │ ├── bootstrap-responsive.css │ ├── bootstrap.css │ ├── editmode.css │ ├── editor.css │ ├── media.css │ └── style.css ├── gfx │ ├── New_FDT_Press_Contact_.JPG │ ├── carouselbackground.png │ ├── contact.jpg │ ├── exampelspan4.png │ ├── experts.png │ ├── fallows-media-wide.jpg │ ├── leader.png │ ├── leader2.png │ ├── logotype.png │ ├── meet.jpg │ ├── page-type-thumbnail-article.png │ ├── page-type-thumbnail-contact.png │ ├── page-type-thumbnail-product.png │ ├── page-type-thumbnail-standard.png │ ├── page-type-thumbnail.png │ ├── person.png │ ├── plan.jpg │ ├── play.png │ ├── playInactive.png │ ├── productLandingv2.png │ ├── searchbutton.png │ ├── searchbuttonsmall.png │ └── track.jpg ├── html │ └── error.htm ├── img │ ├── glyphicons-halflings-white.png │ └── glyphicons-halflings.png ├── js │ ├── bootstrap.js │ └── jquery.js └── jwplayer │ ├── jwplayer.js │ ├── player.swf │ ├── preview.jpg │ └── video.mp4 ├── Views ├── ArticlePage │ └── Index.cshtml ├── ContactBlock │ └── Index.cshtml ├── ImageFile │ └── Index.cshtml ├── LandingPage │ └── Index.cshtml ├── NewsPage │ └── Index.cshtml ├── PageListBlock │ └── Index.cshtml ├── Preview │ └── Index.cshtml ├── ProductPage │ └── Index.cshtml ├── Register │ └── Index.cshtml ├── SearchPage │ └── Index.cshtml ├── Shared │ ├── Blocks │ │ ├── ButtonBlock.cshtml │ │ ├── EditorialBlock.cshtml │ │ ├── JumbotronBlockWide.cshtml │ │ ├── NoRenderer.cshtml │ │ ├── SiteLogotypeBlock.cshtml │ │ ├── TeaserBlock.cshtml │ │ └── TeaserBlockWide.cshtml │ ├── Breadcrumbs.cshtml │ ├── DisplayTemplates │ │ ├── ContactPage.cshtml │ │ ├── DateTime.cshtml │ │ ├── Image.cshtml │ │ ├── StringsCollection.cshtml │ │ └── _ReadMe.txt │ ├── Footer.cshtml │ ├── Header.cshtml │ ├── Layouts │ │ ├── _LeftNavigation.cshtml │ │ ├── _Root.cshtml │ │ └── _TwoPlusOne.cshtml │ ├── PagePartials │ │ ├── ContactPage.cshtml │ │ ├── ContactPageWide.cshtml │ │ ├── Page.cshtml │ │ └── PageWide.cshtml │ ├── Readonly.cshtml │ ├── SubNavigation.cshtml │ ├── TemplateError.cshtml │ └── TemplateHint.cshtml ├── StandardPage │ └── Index.cshtml ├── StartPage │ └── Index.cshtml ├── VideoFile │ └── Index.cshtml ├── Web.config ├── _ReadMe.txt └── _viewstart.cshtml ├── Web.Debug.config ├── Web.Release.config ├── episerver.config ├── favicon.ico ├── global.asax ├── module.config ├── modules └── _protected │ ├── CMS │ ├── CMS.zip │ └── web.config │ ├── EPiServer.Cms.TinyMce │ ├── EPiServer.Cms.TinyMce.zip │ └── web.config │ ├── EPiServer.Search.Cms │ ├── IndexContent.aspx │ └── module.config │ └── Shell │ ├── Shell.zip │ └── web.config ├── modulesbin ├── .gitkeep └── README.txt ├── packages.config └── web.config /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.{cs,svc,asax,aspx,cshtml,csproj,sln}] 11 | charset = utf-8-bom 12 | 13 | [*.{config,csproj,nuspec,xml}] 14 | indent_size = 2 15 | insert_final_newline = false 16 | 17 | [*.sln] 18 | indent_style = tab 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | 23 | # Ignore these files 24 | [{LICENSE,build/database/*,src/Alloy.Mvc.Template/App_Data/**,src/Alloy.Mvc.Template/modulesbin/**,src/Alloy.Mvc.Template/obj/**,src/Alloy.Mvc.Template/Static/**}] 25 | indent_style = unset 26 | indent_size = unset 27 | trim_trailing_whitespace = unset 28 | insert_final_newline = unset 29 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ## Set default behavior to automatically normalize line endings. 2 | * text=auto 3 | 4 | ## Visual Studio and .NET text files 5 | *.ascx text 6 | *.aspx text 7 | *.cmd text 8 | *.config text 9 | *.cs text diff=csharp 10 | *.cshtml text 11 | *.csproj text eol=crlf 12 | *.master text 13 | *.msbuild text 14 | *.ps1 text 15 | *.psm1 text 16 | *.sln text eol=crlf 17 | *.sql text 18 | *.targets text 19 | *.transform text 20 | *.xml text 21 | 22 | ## Common web text files 23 | *.css text 24 | *.htm text 25 | *.html text 26 | *.js text 27 | *.less text 28 | *.md text 29 | 30 | ## Bash and Linux text files 31 | *.sh text eol=lf 32 | 33 | ## Visual Studio and .NET binary files 34 | *.dll binary 35 | *.snk binary 36 | 37 | ## Common web binary files 38 | *.gif binary 39 | *.ico binary 40 | *.jpeg binary 41 | *.jpg binary 42 | *.png binary 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Repository specific files 2 | 3 | App_Code/ 4 | App_Data/ 5 | 6 | License.config 7 | 8 | ## Ignore Visual Studio temporary files and build results. 9 | 10 | # User-specific files 11 | *.user 12 | 13 | # Build results 14 | [Bb]in/ 15 | [Oo]bj/ 16 | [Ll]og/ 17 | 18 | # Visual Studio 2015 cache/options directory 19 | .vs/ 20 | 21 | # NuGet Packages 22 | [Pp]ackages/ 23 | 24 | .idea/ 25 | -------------------------------------------------------------------------------- /Alloy.Mvc.Template.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Alloy.Mvc.Template", "src\Alloy.Mvc.Template\Alloy.Mvc.Template.csproj", "{3D79ADE5-DADB-47D2-933D-E98F9773AFAD}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F856CAEC-B3F9-4320-B39D-E8F2EB8F6111}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{A1272902-1CD0-4507-9714-CB3AE96E78FD}" 11 | ProjectSection(SolutionItems) = preProject 12 | build\Templates.targets = build\Templates.targets 13 | EndProjectSection 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|Any CPU = Debug|Any CPU 18 | Release|Any CPU = Release|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {3D79ADE5-DADB-47D2-933D-E98F9773AFAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {3D79ADE5-DADB-47D2-933D-E98F9773AFAD}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {3D79ADE5-DADB-47D2-933D-E98F9773AFAD}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {3D79ADE5-DADB-47D2-933D-E98F9773AFAD}.Release|Any CPU.Build.0 = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | GlobalSection(NestedProjects) = preSolution 30 | {3D79ADE5-DADB-47D2-933D-E98F9773AFAD} = {F856CAEC-B3F9-4320-B39D-E8F2EB8F6111} 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Alloy MVC Template (CMS 11, .NET Framework 4.x) 2 | 3 | ## Setup the Development Environment 4 | 1. Run `setup.cmd` 5 | 2. Build the solution in Visual Studio 6 | 7 | Once the environment is setup, you can press `CTRL-F5` in Visual Studio to start the sample site. 8 | -------------------------------------------------------------------------------- /build/Templates.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CopyTemplatesSourceFiles;ReplaceNamespacesSourceFiles;$(BuildDependsOn) 9 | $(CoreCleanDependsOn);CleanTemplatesSourceFiles 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /build/database/Alloy.mdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/build/database/Alloy.mdf -------------------------------------------------------------------------------- /build/database/DefaultSiteContent.episerverdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/build/database/DefaultSiteContent.episerverdata -------------------------------------------------------------------------------- /build/tools/EPiServer.Build.Tasks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/build/tools/EPiServer.Build.Tasks.dll -------------------------------------------------------------------------------- /build/transformers/AlloyMvc.Views.web.config.transform: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /build/transformers/AlloyMvc.web.config.transform: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /build/transformers/web.config.install.xdt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /setup.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET AlloyMVC=src\Alloy.Mvc.Template 4 | 5 | IF EXIST %AlloyMVC%\App_Data ( 6 | ECHO Remove all files from the app data folder 7 | DEL %AlloyMVC%\App_Data\*.* /F /Q || Exit /B 1 8 | ) ELSE ( 9 | MKDIR %AlloyMVC%\App_Data || Exit /B 1 10 | ) 11 | 12 | REM Copy the database files to the site. 13 | XCOPY /y/i build\Database\DefaultSiteContent.episerverdata %AlloyMVC%\App_Data\ || Exit /B 1 14 | XCOPY /y/i/k build\database\Alloy.mdf %AlloyMVC%\App_Data\ || Exit /B 1 15 | 16 | EXIT /B %ERRORLEVEL% 17 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Alloy.Mvc.Template.Search.Sources.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alloy.Mvc.Template.Search.Sources 5 | $version$ 6 | EPiServer AB 7 | EPiServer AB 8 | http://www.episerver.com/ 9 | false 10 | Contains source code for the Alloy Search Templates written using MVC. Can be added to an Alloy project without search. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Alloy.Mvc.Template.Sources.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alloy.Mvc.Template.Sources 5 | $version$ 6 | EPiServer AB 7 | EPiServer AB 8 | http://www.episerver.com/ 9 | false 10 | Contains source code for the Alloy Templates written using MVC. Can be added to an empty EPiServer project. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/AdministratorRegistrationPage.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.ServiceLocation; 2 | using EPiServer.Shell.Security; 3 | using Owin; 4 | using System; 5 | using System.Web; 6 | using System.Web.Mvc; 7 | using System.Web.Routing; 8 | 9 | namespace AlloyTemplates 10 | { 11 | public static class AdministratorRegistrationPage 12 | { 13 | private static Func _isLocalRequest = () => false; 14 | 15 | private static Lazy _isAnyUserRegistered = new Lazy(() => false); 16 | 17 | private static bool? _isEnabled = null; 18 | 19 | public static bool IsEnabled 20 | { 21 | get 22 | { 23 | if (_isEnabled.HasValue) 24 | { 25 | return _isEnabled.Value; 26 | } 27 | 28 | var showUserRegistration = _isLocalRequest() && !_isAnyUserRegistered.Value; 29 | if (!showUserRegistration) 30 | { 31 | _isEnabled = false; 32 | } 33 | 34 | return showUserRegistration; 35 | } 36 | set 37 | { 38 | _isEnabled = value; 39 | } 40 | } 41 | 42 | public static void UseAdministratorRegistrationPage(this IAppBuilder app, Func isLocalRequest) 43 | { 44 | _isLocalRequest = isLocalRequest; 45 | _isAnyUserRegistered = new Lazy(IsAnyUserRegistered); 46 | GlobalFilters.Filters.Add(new RegistrationActionFilterAttribute()); 47 | if (isLocalRequest()) 48 | { 49 | AddRoute(); 50 | } 51 | } 52 | 53 | private static bool IsAnyUserRegistered() 54 | { 55 | var provider = ServiceLocator.Current.GetInstance(); 56 | int totalUsers = 0; 57 | var res = provider.GetAllUsers(0, 1, out totalUsers); 58 | return totalUsers > 0; 59 | } 60 | 61 | public class RegistrationActionFilterAttribute : ActionFilterAttribute 62 | { 63 | public override void OnActionExecuting(ActionExecutingContext context) 64 | { 65 | var registerUrl = VirtualPathUtility.ToAbsolute("~/Register"); 66 | if (IsEnabled && !context.RequestContext.HttpContext.Request.Path.StartsWith(registerUrl)) 67 | { 68 | context.Result = new RedirectResult(registerUrl); 69 | } 70 | } 71 | } 72 | 73 | static void AddRoute() 74 | { 75 | var routeData = new RouteValueDictionary(); 76 | routeData.Add("Controller", "Register"); 77 | routeData.Add("action", "Index"); 78 | RouteTable.Routes.Add("Register", new Route("Register", routeData, new MvcRouteHandler()) { RouteExistingFiles = false }); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Channels/DisplayResolutionBase.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Framework.Localization; 2 | using EPiServer.ServiceLocation; 3 | using EPiServer.Web; 4 | 5 | namespace AlloyTemplates.Business.Channels 6 | { 7 | /// 8 | /// Base class for all resolution definitions 9 | /// 10 | public abstract class DisplayResolutionBase : IDisplayResolution 11 | { 12 | private Injected LocalizationService { get; set; } 13 | 14 | protected DisplayResolutionBase(string name, int width, int height) 15 | { 16 | Id = GetType().FullName; 17 | Name = Translate(name); 18 | Width = width; 19 | Height = height; 20 | } 21 | 22 | /// 23 | /// Gets the unique ID for this resolution 24 | /// 25 | public string Id { get; protected set; } 26 | 27 | /// 28 | /// Gets the name of resolution 29 | /// 30 | public string Name { get; protected set; } 31 | 32 | /// 33 | /// Gets the resolution width in pixels 34 | /// 35 | public int Width { get; protected set; } 36 | 37 | /// 38 | /// Gets the resolution height in pixels 39 | /// 40 | public int Height { get; protected set; } 41 | 42 | private string Translate(string resurceKey) 43 | { 44 | string value; 45 | 46 | if(!LocalizationService.Service.TryGetString(resurceKey, out value)) 47 | { 48 | value = resurceKey; 49 | } 50 | 51 | return value; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Channels/DisplayResolutions.cs: -------------------------------------------------------------------------------- 1 | namespace AlloyTemplates.Business.Channels 2 | { 3 | /// 4 | /// Defines resolution for desktop displays 5 | /// 6 | public class StandardResolution : DisplayResolutionBase 7 | { 8 | public StandardResolution() : base("/resolutions/standard", 1366, 768) 9 | { 10 | } 11 | } 12 | 13 | /// 14 | /// Defines resolution for a horizontal iPad 15 | /// 16 | public class IpadHorizontalResolution : DisplayResolutionBase 17 | { 18 | public IpadHorizontalResolution() : base("/resolutions/ipadhorizontal", 1024, 768) 19 | { 20 | } 21 | } 22 | 23 | /// 24 | /// Defines resolution for a vertical iPhone 5s 25 | /// 26 | public class IphoneVerticalResolution : DisplayResolutionBase 27 | { 28 | public IphoneVerticalResolution() : base("/resolutions/iphonevertical", 320, 568) 29 | { 30 | } 31 | } 32 | 33 | /// 34 | /// Defines resolution for a vertical Android handheld device 35 | /// 36 | public class AndroidVerticalResolution : DisplayResolutionBase 37 | { 38 | public AndroidVerticalResolution() : base("/resolutions/androidvertical", 480, 800) 39 | { 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Channels/MobileChannel.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.WebPages; 3 | using EPiServer.Web; 4 | 5 | namespace AlloyTemplates.Business.Channels 6 | { 7 | // 8 | //Defines the 'Mobile' content channel 9 | // 10 | public class MobileChannel : DisplayChannel 11 | { 12 | public const string Name = "mobile"; 13 | 14 | public override string ChannelName 15 | { 16 | get 17 | { 18 | return Name; 19 | } 20 | } 21 | 22 | public override string ResolutionId 23 | { 24 | get 25 | { 26 | return typeof(IphoneVerticalResolution).FullName; 27 | } 28 | } 29 | 30 | public override bool IsActive(HttpContextBase context) 31 | { 32 | return context.GetOverriddenBrowser().IsMobileDevice; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Channels/WebChannel.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using EPiServer.Web; 3 | 4 | namespace AlloyTemplates.Business.Channels 5 | { 6 | /// 7 | /// Defines the 'Web' content channel 8 | /// 9 | public class WebChannel : DisplayChannel 10 | { 11 | public override string ChannelName 12 | { 13 | get 14 | { 15 | return "web"; 16 | } 17 | } 18 | 19 | public override bool IsActive(HttpContextBase context) 20 | { 21 | return !context.Request.Browser.IsMobileDevice; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/ContentExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using EPiServer.Core; 4 | using EPiServer.Filters; 5 | using EPiServer.Framework.Web; 6 | using EPiServer.ServiceLocation; 7 | using EPiServer; 8 | 9 | namespace AlloyTemplates.Business 10 | { 11 | /// 12 | /// Extension methods for content 13 | /// 14 | public static class ContentExtensions 15 | { 16 | /// 17 | /// Filters content which should not be visible to the user. 18 | /// 19 | public static IEnumerable FilterForDisplay(this IEnumerable contents, bool requirePageTemplate = false, bool requireVisibleInMenu = false) 20 | where T : IContent 21 | { 22 | var accessFilter = new FilterAccess(); 23 | var publishedFilter = new FilterPublished(); 24 | contents = contents.Where(x => !publishedFilter.ShouldFilter(x) && !accessFilter.ShouldFilter(x)); 25 | if (requirePageTemplate) 26 | { 27 | var templateFilter = ServiceLocator.Current.GetInstance(); 28 | templateFilter.TemplateTypeCategories = TemplateTypeCategories.Page; 29 | contents = contents.Where(x => !templateFilter.ShouldFilter(x)); 30 | } 31 | if (requireVisibleInMenu) 32 | { 33 | contents = contents.Where(x => VisibleInMenu(x)); 34 | } 35 | return contents; 36 | } 37 | 38 | private static bool VisibleInMenu(IContent content) 39 | { 40 | var page = content as PageData; 41 | if (page == null) 42 | { 43 | return true; 44 | } 45 | return page.VisibleInMenu; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/EditorDescriptors/ContactPageSelectionFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using EPiServer.ServiceLocation; 4 | using EPiServer.Shell.ObjectEditing; 5 | 6 | namespace AlloyTemplates.Business.EditorDescriptors 7 | { 8 | /// 9 | /// Provides a list of options corresponding to ContactPage pages on the site 10 | /// 11 | /// 12 | public class ContactPageSelectionFactory : ISelectionFactory 13 | { 14 | private Injected ContentLocator { get; set; } 15 | 16 | public IEnumerable GetSelections(ExtendedMetadata metadata) 17 | { 18 | var contactPages = ContentLocator.Service.GetContactPages(); 19 | 20 | return new List(contactPages.Select(c => new SelectItem {Value = c.PageLink, Text = c.Name})); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/EditorDescriptors/ContactPageSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using EPiServer.Core; 4 | using EPiServer.Shell.ObjectEditing; 5 | using EPiServer.Shell.ObjectEditing.EditorDescriptors; 6 | 7 | namespace AlloyTemplates.Business.EditorDescriptors 8 | { 9 | /// 10 | /// Registers an editor to select a ContactPage for a PageReference property using a dropdown 11 | /// 12 | [EditorDescriptorRegistration(TargetType = typeof(PageReference), UIHint = Global.SiteUIHints.Contact)] 13 | public class ContactPageSelector : EditorDescriptor 14 | { 15 | public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable attributes) 16 | { 17 | SelectionFactoryType = typeof(ContactPageSelectionFactory); 18 | 19 | ClientEditingClass = "epi-cms/contentediting/editors/SelectionEditor"; 20 | 21 | base.ModifyMetadata(metadata, attributes); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/EditorDescriptors/StringListEditorDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using EPiServer.Shell.ObjectEditing.EditorDescriptors; 4 | using EPiServer.Shell.ObjectEditing; 5 | 6 | namespace AlloyTemplates.Business.EditorDescriptors 7 | { 8 | /// 9 | /// Register an editor for StringList properties 10 | /// 11 | [EditorDescriptorRegistration(TargetType = typeof(String[]), UIHint = Global.SiteUIHints.Strings)] 12 | public class StringListEditorDescriptor : EditorDescriptor 13 | { 14 | public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable attributes) 15 | { 16 | ClientEditingClass = "alloy/editors/StringList"; 17 | 18 | base.ModifyMetadata(metadata, attributes); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/IModifyLayout.cs: -------------------------------------------------------------------------------- 1 | using AlloyTemplates.Models.ViewModels; 2 | 3 | namespace AlloyTemplates.Business 4 | { 5 | /// 6 | /// Defines a method which may be invoked by PageContextActionFilter allowing controllers 7 | /// to modify common layout properties of the view model. 8 | /// 9 | interface IModifyLayout 10 | { 11 | void ModifyLayout(LayoutModel layoutModel); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Initialization/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Optimization; 2 | using EPiServer.Framework; 3 | using EPiServer.Framework.Initialization; 4 | 5 | namespace AlloyTemplates.Business.Initialization 6 | { 7 | [InitializableModule] 8 | public class BundleConfig : IInitializableModule 9 | { 10 | public void Initialize(InitializationEngine context) 11 | { 12 | if (context.HostType == HostType.WebApplication) 13 | { 14 | RegisterBundles(BundleTable.Bundles); 15 | } 16 | } 17 | 18 | // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725 19 | public static void RegisterBundles(BundleCollection bundles) 20 | { 21 | bundles.Add(new ScriptBundle("~/bundles/js").Include( 22 | "~/Static/js/jquery.js", //jquery.js can be removed and linked from CDN instead, we use a local one for demo purposes without internet connectionzz 23 | "~/Static/js/bootstrap.js")); 24 | 25 | bundles.Add(new StyleBundle("~/bundles/css") 26 | .Include("~/Static/css/bootstrap.css", new CssRewriteUrlTransform()) 27 | .Include("~/Static/css/bootstrap-responsive.css") 28 | .Include("~/Static/css/media.css") 29 | .Include("~/Static/css/style.css", new CssRewriteUrlTransform()) 30 | .Include("~/Static/css/editmode.css")); 31 | } 32 | 33 | public void Uninitialize(InitializationEngine context) 34 | { 35 | } 36 | 37 | public void Preload(string[] parameters) 38 | { 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Initialization/CustomizedRenderingInitialization.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using EPiServer.Framework; 3 | using EPiServer.Framework.Initialization; 4 | using EPiServer.ServiceLocation; 5 | using AlloyTemplates.Business.Rendering; 6 | using EPiServer.Web; 7 | 8 | namespace AlloyTemplates.Business.Initialization 9 | { 10 | /// 11 | /// Module for customizing templates and rendering. 12 | /// 13 | [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] 14 | public class CustomizedRenderingInitialization : IInitializableModule 15 | { 16 | public void Initialize(InitializationEngine context) 17 | { 18 | //Add custom view engine allowing partials to be placed in additional locations 19 | //Note that we add it first in the list to optimize view resolving when using DisplayFor/PropertyFor 20 | ViewEngines.Engines.Insert(0, new SiteViewEngine()); 21 | 22 | context.Locate.TemplateResolver() 23 | .TemplateResolved += TemplateCoordinator.OnTemplateResolved; 24 | } 25 | 26 | public void Uninitialize(InitializationEngine context) 27 | { 28 | ServiceLocator.Current.GetInstance() 29 | .TemplateResolved -= TemplateCoordinator.OnTemplateResolved; 30 | } 31 | 32 | public void Preload(string[] parameters) 33 | { 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Initialization/DependencyResolverInitialization.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using EPiServer.Framework; 3 | using EPiServer.Framework.Initialization; 4 | using EPiServer.ServiceLocation; 5 | using AlloyTemplates.Business.Rendering; 6 | using EPiServer.Web.Mvc; 7 | using EPiServer.Web.Mvc.Html; 8 | 9 | namespace AlloyTemplates.Business.Initialization 10 | { 11 | [InitializableModule] 12 | public class DependencyResolverInitialization : IConfigurableModule 13 | { 14 | public void ConfigureContainer(ServiceConfigurationContext context) 15 | { 16 | //Implementations for custom interfaces can be registered here. 17 | 18 | context.ConfigurationComplete += (o, e) => 19 | { 20 | //Register custom implementations that should be used in favour of the default implementations 21 | context.Services.AddTransient() 22 | .AddTransient(); 23 | }; 24 | } 25 | 26 | public void Initialize(InitializationEngine context) 27 | { 28 | DependencyResolver.SetResolver(new ServiceLocatorDependencyResolver(context.Locate.Advanced)); 29 | } 30 | 31 | public void Uninitialize(InitializationEngine context) 32 | { 33 | } 34 | 35 | public void Preload(string[] parameters) 36 | { 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Initialization/DisplayModesInitialization.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web; 3 | using System.Web.WebPages; 4 | using EPiServer.Framework; 5 | using EPiServer.Framework.Initialization; 6 | using EPiServer.ServiceLocation; 7 | using AlloyTemplates.Business.Channels; 8 | using EPiServer.Web; 9 | 10 | namespace AlloyTemplates.Business.Initialization 11 | { 12 | /// 13 | /// Adds a new display mode for mobile which is active if the mobile channel is active in addition to if the request is from a mobile device (like the default one) 14 | /// 15 | /// 16 | /// It's also possible to map a display mode as a channel through the DisplayChannelService.RegisterDisplayMode() method. 17 | /// Adding channels that way does not however enable specifying ResolutionId which we want to do for the mobile channel. 18 | /// 19 | [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] 20 | public class DisplayModesInitialization : IInitializableModule 21 | { 22 | public void Initialize(InitializationEngine context) 23 | { 24 | var mobileChannelDisplayMode = new DefaultDisplayMode("mobile") 25 | { 26 | ContextCondition = IsMobileDisplayModeActive 27 | }; 28 | DisplayModeProvider.Instance.Modes.Insert(0, mobileChannelDisplayMode); 29 | } 30 | 31 | private static bool IsMobileDisplayModeActive(HttpContextBase httpContext) 32 | { 33 | if (httpContext.GetOverriddenBrowser().IsMobileDevice) 34 | { 35 | return true; 36 | } 37 | var displayChannelService = ServiceLocator.Current.GetInstance(); 38 | return displayChannelService.GetActiveChannels(httpContext).Any(x => x.ChannelName == MobileChannel.Name); 39 | } 40 | 41 | public void Uninitialize(InitializationEngine context) 42 | { 43 | } 44 | 45 | public void Preload(string[] parameters) 46 | { 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Initialization/DisplayRegistryInitialization.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Framework; 2 | using EPiServer.Framework.Initialization; 3 | using EPiServer.ServiceLocation; 4 | using EPiServer.Web; 5 | using System.Collections.Generic; 6 | using System.Web.Mvc; 7 | 8 | namespace AlloyTemplates.Business.Initialization 9 | { 10 | [InitializableModule] 11 | [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] 12 | public class DisplayRegistryInitialization : IInitializableModule 13 | { 14 | public void Initialize(InitializationEngine context) 15 | { 16 | if (context.HostType == HostType.WebApplication) 17 | { 18 | // Register Display Options 19 | var options = ServiceLocator.Current.GetInstance(); 20 | options 21 | .Add("full", "/displayoptions/full", Global.ContentAreaTags.FullWidth, "", "epi-icon__layout--full") 22 | .Add("wide", "/displayoptions/wide", Global.ContentAreaTags.TwoThirdsWidth, "", "epi-icon__layout--two-thirds") 23 | .Add("narrow", "/displayoptions/narrow", Global.ContentAreaTags.OneThirdWidth, "", "epi-icon__layout--one-third"); 24 | 25 | AreaRegistration.RegisterAllAreas(); 26 | 27 | } 28 | } 29 | 30 | public void Preload(string[] parameters){} 31 | 32 | public void Uninitialize(InitializationEngine context){} 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Initialization/ExtendedTinyMceInitialization.cs: -------------------------------------------------------------------------------- 1 | using AlloyTemplates.Models.Blocks; 2 | using AlloyTemplates.Models.Pages; 3 | using EPiServer.Cms.TinyMce.Core; 4 | using EPiServer.Framework; 5 | using EPiServer.Framework.Initialization; 6 | using EPiServer.ServiceLocation; 7 | 8 | namespace AlloyTemplates.Business.Initialization 9 | { 10 | [ModuleDependency(typeof(TinyMceInitialization))] 11 | public class ExtendedTinyMceInitialization : IConfigurableModule 12 | { 13 | public void Initialize(InitializationEngine context) 14 | { 15 | } 16 | 17 | public void Uninitialize(InitializationEngine context) 18 | { 19 | } 20 | 21 | public void ConfigureContainer(ServiceConfigurationContext context) 22 | { 23 | context.Services.Configure(config => 24 | { 25 | // Add content CSS to the default settings. 26 | config.Default() 27 | .ContentCss("/static/css/editor.css"); 28 | 29 | // This will clone the default settings object and extend it by 30 | // limiting the block formats for the MainBody property of an ArticlePage. 31 | config.For(t => t.MainBody) 32 | .BlockFormats("Paragraph=p;Header 1=h1;Header 2=h2;Header 3=h3"); 33 | 34 | // Passing a second argument to For<> will clone the given settings object 35 | // instead of the default one and extend it with some basic toolbar commands. 36 | config.For(t => t.MainBody, config.Empty()) 37 | .AddEpiserverSupport() 38 | .DisableMenubar() 39 | .Toolbar("bold italic underline strikethrough"); 40 | }); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Initialization/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using EPiServer.Framework; 3 | using EPiServer.Framework.Initialization; 4 | using EPiServer.ServiceLocation; 5 | 6 | namespace AlloyTemplates.Business.Initialization 7 | { 8 | /// 9 | /// Module for registering filters which will be applied to controller actions. 10 | /// 11 | [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] 12 | public class FilterConfig : IInitializableModule 13 | { 14 | public void Initialize(InitializationEngine context) 15 | { 16 | GlobalFilters.Filters.Add(ServiceLocator.Current.GetInstance()); 17 | } 18 | 19 | public void Uninitialize(InitializationEngine context) 20 | { 21 | } 22 | 23 | public void Preload(string[] parameters) 24 | { 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/PageContextActionFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using AlloyTemplates.Models.Pages; 3 | using AlloyTemplates.Models.ViewModels; 4 | using EPiServer.Web.Routing; 5 | 6 | namespace AlloyTemplates.Business 7 | { 8 | /// 9 | /// Intercepts actions with view models of type IPageViewModel and populates the view models 10 | /// Layout and Section properties. 11 | /// 12 | /// 13 | /// This filter frees controllers for pages from having to care about common context needed by layouts 14 | /// and other page framework components allowing the controllers to focus on the specifics for the page types 15 | /// and actions that they handle. 16 | /// 17 | public class PageContextActionFilter : IResultFilter 18 | { 19 | private readonly PageViewContextFactory _contextFactory; 20 | public PageContextActionFilter(PageViewContextFactory contextFactory) 21 | { 22 | _contextFactory = contextFactory; 23 | } 24 | 25 | public void OnResultExecuting(ResultExecutingContext filterContext) 26 | { 27 | var viewModel = filterContext.Controller.ViewData.Model; 28 | 29 | var model = viewModel as IPageViewModel; 30 | if (model != null) 31 | { 32 | var currentContentLink = filterContext.RequestContext.GetContentLink(); 33 | 34 | var layoutModel = model.Layout ?? _contextFactory.CreateLayoutModel(currentContentLink, filterContext.RequestContext); 35 | 36 | var layoutController = filterContext.Controller as IModifyLayout; 37 | if(layoutController != null) 38 | { 39 | layoutController.ModifyLayout(layoutModel); 40 | } 41 | 42 | model.Layout = layoutModel; 43 | 44 | if (model.Section == null) 45 | { 46 | model.Section = _contextFactory.GetSection(currentContentLink); 47 | } 48 | } 49 | } 50 | 51 | public void OnResultExecuted(ResultExecutedContext filterContext) 52 | { 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/PageTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EPiServer.DataAbstraction; 3 | using EPiServer.ServiceLocation; 4 | 5 | namespace AlloyTemplates.Business 6 | { 7 | /// 8 | /// Provides extension methods for types intended to be used when working with page types 9 | /// 10 | public static class PageTypeExtensions 11 | { 12 | /// 13 | /// Returns the definition for a specific page type 14 | /// 15 | /// 16 | /// 17 | public static PageType GetPageType(this Type pageType) 18 | { 19 | var pageTypeRepository = ServiceLocator.Current.GetInstance>(); 20 | 21 | return pageTypeRepository.Load(pageType); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/PageViewContextFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web; 3 | using System.Web.Mvc; 4 | using System.Web.Routing; 5 | using System.Web.Security; 6 | using AlloyTemplates.Models.Pages; 7 | using AlloyTemplates.Models.ViewModels; 8 | using EPiServer; 9 | using EPiServer.Core; 10 | using EPiServer.Data; 11 | using EPiServer.Web; 12 | using EPiServer.Web.Routing; 13 | 14 | namespace AlloyTemplates.Business 15 | { 16 | public class PageViewContextFactory 17 | { 18 | private readonly IContentLoader _contentLoader; 19 | private readonly UrlResolver _urlResolver; 20 | private readonly IDatabaseMode _databaseMode; 21 | 22 | public PageViewContextFactory(IContentLoader contentLoader, UrlResolver urlResolver, IDatabaseMode databaseMode) 23 | { 24 | _contentLoader = contentLoader; 25 | _urlResolver = urlResolver; 26 | _databaseMode = databaseMode; 27 | } 28 | 29 | public virtual LayoutModel CreateLayoutModel(ContentReference currentContentLink, RequestContext requestContext) 30 | { 31 | var startPageContentLink = SiteDefinition.Current.StartPage; 32 | 33 | // Use the content link with version information when editing the startpage, 34 | // otherwise the published version will be used when rendering the props below. 35 | if (currentContentLink.CompareToIgnoreWorkID(startPageContentLink)) 36 | { 37 | startPageContentLink = currentContentLink; 38 | } 39 | 40 | var startPage = _contentLoader.Get(startPageContentLink); 41 | 42 | return new LayoutModel 43 | { 44 | Logotype = startPage.SiteLogotype, 45 | LogotypeLinkUrl = new MvcHtmlString(_urlResolver.GetUrl(SiteDefinition.Current.StartPage)), 46 | ProductPages = startPage.ProductPageLinks, 47 | CompanyInformationPages = startPage.CompanyInformationPageLinks, 48 | NewsPages = startPage.NewsPageLinks, 49 | CustomerZonePages = startPage.CustomerZonePageLinks, 50 | LoggedIn = requestContext.HttpContext.User.Identity.IsAuthenticated, 51 | LoginUrl = new MvcHtmlString(GetLoginUrl(currentContentLink)), 52 | SearchActionUrl = new MvcHtmlString(EPiServer.Web.Routing.UrlResolver.Current.GetUrl(startPage.SearchPageLink)), 53 | IsInReadonlyMode = _databaseMode.DatabaseMode == DatabaseMode.ReadOnly 54 | }; 55 | } 56 | 57 | private string GetLoginUrl(ContentReference returnToContentLink) 58 | { 59 | return string.Format( 60 | "{0}?ReturnUrl={1}", 61 | (FormsAuthentication.IsEnabled ? FormsAuthentication.LoginUrl : VirtualPathUtility.ToAbsolute(Global.AppRelativeLoginPath)), 62 | _urlResolver.GetUrl(returnToContentLink)); 63 | } 64 | 65 | public virtual IContent GetSection(ContentReference contentLink) 66 | { 67 | var currentContent = _contentLoader.Get(contentLink); 68 | if (currentContent.ParentLink != null && currentContent.ParentLink.CompareToIgnoreWorkID(SiteDefinition.Current.StartPage)) 69 | { 70 | return currentContent; 71 | } 72 | 73 | return _contentLoader.GetAncestors(contentLink) 74 | .OfType() 75 | .SkipWhile(x => x.ParentLink == null || !x.ParentLink.CompareToIgnoreWorkID(SiteDefinition.Current.StartPage)) 76 | .FirstOrDefault(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Rendering/AlloyContentAreaRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using EPiServer.Core; 4 | using EPiServer.Core.Html.StringParsing; 5 | using EPiServer.Web; 6 | using EPiServer.Web.Mvc; 7 | using EPiServer.Web.Mvc.Html; 8 | using EPiServer; 9 | 10 | namespace AlloyTemplates.Business.Rendering 11 | { 12 | /// 13 | /// Extends the default to apply custom CSS classes to each . 14 | /// 15 | public class AlloyContentAreaRenderer : ContentAreaRenderer 16 | { 17 | protected override string GetContentAreaItemCssClass(HtmlHelper htmlHelper, ContentAreaItem contentAreaItem) 18 | { 19 | var baseItemClass = base.GetContentAreaItemCssClass(htmlHelper, contentAreaItem); 20 | 21 | var tag = GetContentAreaItemTemplateTag(htmlHelper, contentAreaItem); 22 | return $"block {baseItemClass} {GetTypeSpecificCssClasses(contentAreaItem, ContentRepository)} {GetCssClassForTag(tag)} {tag}"; 23 | } 24 | 25 | /// 26 | /// Gets a CSS class used for styling based on a tag name (ie a Bootstrap class name) 27 | /// 28 | /// Any tag name available, see 29 | private static string GetCssClassForTag(string tagName) 30 | { 31 | if (string.IsNullOrEmpty(tagName)) 32 | { 33 | return ""; 34 | } 35 | switch (tagName.ToLower()) 36 | { 37 | case "span12": 38 | return "full"; 39 | case "span8": 40 | return "wide"; 41 | case "span6": 42 | return "half"; 43 | default: 44 | return string.Empty; 45 | } 46 | } 47 | 48 | private static string GetTypeSpecificCssClasses(ContentAreaItem contentAreaItem, IContentRepository contentRepository) 49 | { 50 | var content = contentAreaItem.GetContent(); 51 | var cssClass = content == null ? String.Empty : content.GetOriginalType().Name.ToLowerInvariant(); 52 | 53 | var customClassContent = content as ICustomCssInContentArea; 54 | if (customClassContent != null && !string.IsNullOrWhiteSpace(customClassContent.ContentAreaCssClass)) 55 | { 56 | cssClass += string.Format(" {0}", customClassContent.ContentAreaCssClass); 57 | } 58 | 59 | return cssClass; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Rendering/ErrorHandlingContentRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Web; 4 | using System.Web.Mvc; 5 | using System.Web.Mvc.Html; 6 | using EPiServer.Core; 7 | using EPiServer.DataAbstraction; 8 | using EPiServer.Security; 9 | using AlloyTemplates.Models.ViewModels; 10 | using EPiServer.Web.Mvc; 11 | 12 | namespace AlloyTemplates.Business.Rendering 13 | { 14 | /// 15 | /// Wraps an MvcContentRenderer and adds error handling to ensure that blocks and other content 16 | /// rendered as parts of pages won't crash the entire page if a non-critical exception occurs while rendering it. 17 | /// 18 | /// 19 | /// Prints an error message for editors so that they can easily report errors to developers. 20 | /// 21 | public class ErrorHandlingContentRenderer : IContentRenderer 22 | { 23 | private readonly MvcContentRenderer _mvcRenderer; 24 | public ErrorHandlingContentRenderer(MvcContentRenderer mvcRenderer) 25 | { 26 | _mvcRenderer = mvcRenderer; 27 | } 28 | 29 | /// 30 | /// Renders the contentData using the wrapped renderer and catches common, non-critical exceptions. 31 | /// 32 | public void Render(HtmlHelper helper, PartialRequest partialRequestHandler, IContentData contentData, TemplateModel templateModel) 33 | { 34 | try 35 | { 36 | _mvcRenderer.Render(helper, partialRequestHandler, contentData, templateModel); 37 | } 38 | catch (NullReferenceException ex) 39 | { 40 | if (HttpContext.Current.IsDebuggingEnabled) 41 | { 42 | //If debug="true" we assume a developer is making the request 43 | throw; 44 | } 45 | HandlerError(helper, contentData, ex); 46 | } 47 | catch (ArgumentException ex) 48 | { 49 | if (HttpContext.Current.IsDebuggingEnabled) 50 | { 51 | throw; 52 | } 53 | HandlerError(helper, contentData, ex); 54 | } 55 | catch (ApplicationException ex) 56 | { 57 | if (HttpContext.Current.IsDebuggingEnabled) 58 | { 59 | throw; 60 | } 61 | HandlerError(helper, contentData, ex); 62 | } 63 | catch (InvalidOperationException ex) 64 | { 65 | if (HttpContext.Current.IsDebuggingEnabled) 66 | { 67 | throw; 68 | } 69 | HandlerError(helper, contentData, ex); 70 | } 71 | catch (NotImplementedException ex) 72 | { 73 | if (HttpContext.Current.IsDebuggingEnabled) 74 | { 75 | throw; 76 | } 77 | HandlerError(helper, contentData, ex); 78 | } 79 | catch (IOException ex) 80 | { 81 | if (HttpContext.Current.IsDebuggingEnabled) 82 | { 83 | throw; 84 | } 85 | HandlerError(helper, contentData, ex); 86 | } 87 | catch (EPiServerException ex) 88 | { 89 | if (HttpContext.Current.IsDebuggingEnabled) 90 | { 91 | throw; 92 | } 93 | HandlerError(helper, contentData, ex); 94 | } 95 | } 96 | 97 | private void HandlerError(HtmlHelper helper, IContentData contentData, Exception renderingException) 98 | { 99 | if (PrincipalInfo.HasEditAccess) 100 | { 101 | var errorModel = new ContentRenderingErrorModel(contentData, renderingException); 102 | helper.RenderPartial("TemplateError", errorModel); 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Rendering/IContainerPage.cs: -------------------------------------------------------------------------------- 1 | namespace AlloyTemplates.Business.Rendering 2 | { 3 | /// 4 | /// Marker interface for content types which should not be handled by DefaultPageController. 5 | /// 6 | interface IContainerPage 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Rendering/ICustomCssInContentArea.cs: -------------------------------------------------------------------------------- 1 | namespace AlloyTemplates.Business.Rendering 2 | { 3 | /// 4 | /// Defines a property for CSS class(es) which will be added to the class 5 | /// attribute of containing elements when rendered in a content area with a size tag. 6 | /// 7 | interface ICustomCssInContentArea 8 | { 9 | string ContentAreaCssClass { get; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/Rendering/SiteViewEngine.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web.Mvc; 3 | 4 | namespace AlloyTemplates.Business.Rendering 5 | { 6 | /// 7 | /// Extends the Razor view engine to include the folders ~/Views/Shared/Blocks/ and ~/Views/Shared/PagePartials/ 8 | /// when looking for partial views. 9 | /// 10 | public class SiteViewEngine : RazorViewEngine 11 | { 12 | private static readonly string[] AdditionalPartialViewFormats = new[] 13 | { 14 | TemplateCoordinator.BlockFolder + "{0}.cshtml", 15 | TemplateCoordinator.PagePartialsFolder + "{0}.cshtml" 16 | }; 17 | 18 | public SiteViewEngine() 19 | { 20 | PartialViewLocationFormats = PartialViewLocationFormats.Union(AdditionalPartialViewFormats).ToArray(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/SearchService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Web; 3 | using EPiServer.Core; 4 | using EPiServer.Search; 5 | using EPiServer.Search.Queries; 6 | using EPiServer.Search.Queries.Lucene; 7 | using EPiServer.Security; 8 | using EPiServer; 9 | using EPiServer.ServiceLocation; 10 | 11 | namespace AlloyTemplates.Business 12 | { 13 | public class SearchService 14 | { 15 | private readonly SearchHandler _searchHandler; 16 | private readonly IContentLoader _contentLoader; 17 | 18 | public SearchService(SearchHandler searchHandler, IContentLoader contentLoader) 19 | { 20 | _searchHandler = searchHandler; 21 | _contentLoader = contentLoader; 22 | } 23 | 24 | public virtual bool IsActive 25 | { 26 | get { return ServiceLocator.Current.GetInstance().Active; } 27 | } 28 | 29 | public virtual SearchResults Search(string searchText, IEnumerable searchRoots, HttpContextBase context, string languageBranch, int maxResults) 30 | { 31 | var query = CreateQuery(searchText, searchRoots, context, languageBranch); 32 | return _searchHandler.GetSearchResults(query, 1, maxResults); 33 | } 34 | 35 | private IQueryExpression CreateQuery(string searchText, IEnumerable searchRoots, HttpContextBase context, string languageBranch) 36 | { 37 | //Main query which groups other queries. Each query added 38 | //must match in order for a page or file to be returned. 39 | var query = new GroupQuery(LuceneOperator.AND); 40 | 41 | //Add free text query to the main query 42 | query.QueryExpressions.Add(new FieldQuery(searchText)); 43 | 44 | //Search for pages using the provided language 45 | var pageTypeQuery = new GroupQuery(LuceneOperator.AND); 46 | pageTypeQuery.QueryExpressions.Add(new ContentQuery()); 47 | pageTypeQuery.QueryExpressions.Add(new FieldQuery(languageBranch, Field.Culture)); 48 | 49 | //Search for media without languages 50 | var contentTypeQuery = new GroupQuery(LuceneOperator.OR); 51 | contentTypeQuery.QueryExpressions.Add(new ContentQuery()); 52 | contentTypeQuery.QueryExpressions.Add(pageTypeQuery); 53 | 54 | query.QueryExpressions.Add(contentTypeQuery); 55 | 56 | //Create and add query which groups type conditions using OR 57 | var typeQueries = new GroupQuery(LuceneOperator.OR); 58 | query.QueryExpressions.Add(typeQueries); 59 | 60 | foreach (var root in searchRoots) 61 | { 62 | var contentRootQuery = new VirtualPathQuery(); 63 | contentRootQuery.AddContentNodes(root); 64 | typeQueries.QueryExpressions.Add(contentRootQuery); 65 | } 66 | 67 | var accessRightsQuery = new AccessControlListQuery(); 68 | accessRightsQuery.AddAclForUser(PrincipalInfo.Current, context); 69 | query.QueryExpressions.Add(accessRightsQuery); 70 | 71 | return query; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/ServiceLocatorDependencyResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Mvc; 5 | using EPiServer.ServiceLocation; 6 | 7 | namespace AlloyTemplates.Business 8 | { 9 | public class ServiceLocatorDependencyResolver : IDependencyResolver 10 | { 11 | readonly IServiceLocator _serviceLocator; 12 | 13 | public ServiceLocatorDependencyResolver(IServiceLocator serviceLocator) 14 | { 15 | _serviceLocator = serviceLocator; 16 | } 17 | 18 | public object GetService(Type serviceType) 19 | { 20 | if (serviceType.IsInterface || serviceType.IsAbstract) 21 | { 22 | return GetInterfaceService(serviceType); 23 | } 24 | return GetConcreteService(serviceType); 25 | } 26 | 27 | private object GetConcreteService(Type serviceType) 28 | { 29 | try 30 | { 31 | // Can't use TryGetInstance here because it won’t create concrete types 32 | return _serviceLocator.GetInstance(serviceType); 33 | } 34 | catch (ActivationException) 35 | { 36 | return null; 37 | } 38 | } 39 | 40 | private object GetInterfaceService(Type serviceType) 41 | { 42 | object instance; 43 | return _serviceLocator.TryGetExistingInstance(serviceType, out instance) ? instance : null; 44 | } 45 | 46 | public IEnumerable GetServices(Type serviceType) 47 | { 48 | return _serviceLocator.GetAllInstances(serviceType).Cast(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Business/UIDescriptors/ContainerPageUIDescriptor.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Editor; 2 | using EPiServer.Shell; 3 | using AlloyTemplates.Models.Pages; 4 | 5 | namespace AlloyTemplates.Business.UIDescriptors 6 | { 7 | /// 8 | /// Describes how the UI should appear for content. 9 | /// 10 | [UIDescriptorRegistration] 11 | public class ContainerPageUIDescriptor : UIDescriptor 12 | { 13 | public ContainerPageUIDescriptor() 14 | : base(ContentTypeCssClassNames.Container) 15 | { 16 | DefaultView = CmsViewNames.AllPropertiesView; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/ClientResources/Images/icons/layoutIcons24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/ClientResources/Images/icons/layoutIcons24x24.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/ClientResources/Styles/LayoutIcons.css: -------------------------------------------------------------------------------- 1 | .Sleek .epi-icon__layout--full { 2 | background: url('../Images/Icons/layoutIcons24x24.png') 0px -24px no-repeat; 3 | height: 24px; 4 | width: 24px; 5 | } 6 | .Sleek .epi-icon__layout--half { 7 | background: url('../Images/Icons/layoutIcons24x24.png') 0px -48px no-repeat; 8 | height: 24px; 9 | width: 24px; 10 | } 11 | .Sleek .epi-icon__layout--two-thirds { 12 | background: url('../Images/Icons/layoutIcons24x24.png') 0px -72px no-repeat; 13 | height: 24px; 14 | width: 24px; 15 | } 16 | .Sleek .epi-icon__layout--one-third { 17 | background: url('../Images/Icons/layoutIcons24x24.png') 0px -96px no-repeat; 18 | height: 24px; 19 | width: 24px; 20 | } 21 | .Sleek .epi-icon__layout--one-quarter { 22 | background: url('../Images/Icons/layoutIcons24x24.png') 0px -120px no-repeat; 23 | height: 24px; 24 | width: 24px; 25 | } 26 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/ClientResources/Styles/Styles.css: -------------------------------------------------------------------------------- 1 | @import url("LayoutIcons.css"); 2 | 3 | .epiStringList .dijitTextArea { 4 | width: 250px; 5 | } 6 | 7 | .epiStringList .epiStringListError .dijitTextArea { 8 | border: solid 1px #d46464; 9 | } 10 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/ConnectionStrings.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/ContactBlockController.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using EPiServer.Core; 4 | using AlloyTemplates.Helpers; 5 | using AlloyTemplates.Models.Blocks; 6 | using AlloyTemplates.Models.Pages; 7 | using AlloyTemplates.Models.ViewModels; 8 | using EPiServer.Web; 9 | using EPiServer.Web.Mvc; 10 | using EPiServer; 11 | 12 | namespace AlloyTemplates.Controllers 13 | { 14 | public class ContactBlockController : BlockController 15 | { 16 | private readonly IContentLoader _contentLoader; 17 | private readonly IPermanentLinkMapper _permanentLinkMapper; 18 | 19 | public ContactBlockController(IContentLoader contentLoader, IPermanentLinkMapper permanentLinkMapper) 20 | { 21 | _contentLoader = contentLoader; 22 | _permanentLinkMapper = permanentLinkMapper; 23 | } 24 | 25 | public override ActionResult Index(ContactBlock currentBlock) 26 | { 27 | ContactPage contactPage = null; 28 | if(!ContentReference.IsNullOrEmpty(currentBlock.ContactPageLink)) 29 | { 30 | contactPage = _contentLoader.Get(currentBlock.ContactPageLink); 31 | } 32 | 33 | var linkUrl = GetLinkUrl(currentBlock); 34 | 35 | var model = new ContactBlockModel 36 | { 37 | Heading = currentBlock.Heading, 38 | Image = currentBlock.Image, 39 | ContactPage = contactPage, 40 | LinkUrl = GetLinkUrl(currentBlock), 41 | LinkText = currentBlock.LinkText, 42 | ShowLink = linkUrl != null 43 | }; 44 | 45 | //As we're using a separate view model with different property names than the content object 46 | //we connect the view models properties with the content objects so that they can be edited. 47 | ViewData.GetEditHints() 48 | .AddConnection(x => x.Heading, x => x.Heading) 49 | .AddConnection(x => x.Image, x => x.Image) 50 | .AddConnection(x => (object) x.ContactPage, x => (object) x.ContactPageLink) 51 | .AddConnection(x => x.LinkText, x => x.LinkText); 52 | 53 | return PartialView(model); 54 | } 55 | 56 | private IHtmlString GetLinkUrl(ContactBlock contactBlock) 57 | { 58 | if (contactBlock.LinkUrl != null && !contactBlock.LinkUrl.IsEmpty()) 59 | { 60 | var linkUrl = contactBlock.LinkUrl.ToString(); 61 | 62 | //If the url maps to a page on the site we convert it from the internal (permanent, GUID-like) format 63 | //to the human readable and pretty public format 64 | var linkMap = _permanentLinkMapper.Find(new UrlBuilder(linkUrl)); 65 | if (linkMap != null && !ContentReference.IsNullOrEmpty(linkMap.ContentReference)) 66 | { 67 | return Url.PageLinkUrl(linkMap.ContentReference); 68 | } 69 | 70 | return new MvcHtmlString(contactBlock.LinkUrl.ToString()); 71 | } 72 | 73 | return null; 74 | } 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/DefaultPageController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using EPiServer; 4 | using EPiServer.Framework.DataAnnotations; 5 | using AlloyTemplates.Models.Pages; 6 | using AlloyTemplates.Models.ViewModels; 7 | 8 | namespace AlloyTemplates.Controllers 9 | { 10 | /// 11 | /// Concrete controller that handles all page types that don't have their own specific controllers. 12 | /// 13 | /// 14 | /// Note that as the view file name is hard coded it won't work with DisplayModes (ie Index.mobile.cshtml). 15 | /// For page types requiring such views add specific controllers for them. Alterntively the Index action 16 | /// could be modified to set ControllerContext.RouteData.Values["controller"] to type name of the currentPage 17 | /// argument. That may however have side effects. 18 | /// 19 | [TemplateDescriptor(Inherited = true)] 20 | public class DefaultPageController : PageControllerBase 21 | { 22 | public ViewResult Index(SitePageData currentPage) 23 | { 24 | var model = CreateModel(currentPage); 25 | return View(string.Format("~/Views/{0}/Index.cshtml", currentPage.GetOriginalType().Name), model); 26 | } 27 | 28 | /// 29 | /// Creates a PageViewModel where the type parameter is the type of the page. 30 | /// 31 | /// 32 | /// Used to create models of a specific type without the calling method having to know that type. 33 | /// 34 | private static IPageViewModel CreateModel(SitePageData page) 35 | { 36 | var type = typeof(PageViewModel<>).MakeGenericType(page.GetOriginalType()); 37 | return Activator.CreateInstance(type, page) as IPageViewModel; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/ImageFileController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using AlloyTemplates.Models.Media; 3 | using AlloyTemplates.Models.ViewModels; 4 | using EPiServer.Web.Mvc; 5 | using EPiServer.Web.Routing; 6 | 7 | namespace AlloyTemplates.Controllers 8 | { 9 | /// 10 | /// Controller for the image file. 11 | /// 12 | public class ImageFileController : PartialContentController 13 | { 14 | private readonly UrlResolver _urlResolver; 15 | 16 | public ImageFileController(UrlResolver urlResolver) 17 | { 18 | _urlResolver = urlResolver; 19 | } 20 | 21 | /// 22 | /// The index action for the image file. Creates the view model and renders the view. 23 | /// 24 | /// The current image file. 25 | public override ActionResult Index(ImageFile currentContent) 26 | { 27 | var model = new ImageViewModel 28 | { 29 | Url = _urlResolver.GetUrl(currentContent.ContentLink), 30 | Name = currentContent.Name, 31 | Copyright = currentContent.Copyright 32 | }; 33 | 34 | return PartialView(model); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/PageControllerBase.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using AlloyTemplates.Business; 3 | using AlloyTemplates.Models.Pages; 4 | using AlloyTemplates.Models.ViewModels; 5 | using EPiServer.Web.Mvc; 6 | using EPiServer.Shell.Security; 7 | 8 | namespace AlloyTemplates.Controllers 9 | { 10 | /// 11 | /// All controllers that renders pages should inherit from this class so that we can 12 | /// apply action filters, such as for output caching site wide, should we want to. 13 | /// 14 | public abstract class PageControllerBase : PageController, IModifyLayout 15 | where T : SitePageData 16 | { 17 | 18 | protected EPiServer.ServiceLocation.Injected UISignInManager; 19 | 20 | /// 21 | /// Signs out the current user and redirects to the Index action of the same controller. 22 | /// 23 | /// 24 | /// There's a log out link in the footer which should redirect the user to the same page. 25 | /// As we don't have a specific user/account/login controller but rely on the login URL for 26 | /// forms authentication for login functionality we add an action for logging out to all 27 | /// controllers inheriting from this class. 28 | /// 29 | public ActionResult Logout() 30 | { 31 | UISignInManager.Service.SignOut(); 32 | return RedirectToAction("Index"); 33 | } 34 | 35 | public virtual void ModifyLayout(LayoutModel layoutModel) 36 | { 37 | var page = PageContext.Page as SitePageData; 38 | if(page != null) 39 | { 40 | layoutModel.HideHeader = page.HideSiteHeader; 41 | layoutModel.HideFooter = page.HideSiteFooter; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/PageListBlockController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Web.Mvc; 4 | using EPiServer.Core; 5 | using EPiServer.Filters; 6 | using AlloyTemplates.Business; 7 | using AlloyTemplates.Models.Blocks; 8 | using AlloyTemplates.Models.ViewModels; 9 | using EPiServer.Web.Mvc; 10 | using EPiServer; 11 | 12 | namespace AlloyTemplates.Controllers 13 | { 14 | public class PageListBlockController : BlockController 15 | { 16 | private ContentLocator contentLocator; 17 | private IContentLoader contentLoader; 18 | public PageListBlockController(ContentLocator contentLocator, IContentLoader contentLoader) 19 | { 20 | this.contentLocator = contentLocator; 21 | this.contentLoader = contentLoader; 22 | } 23 | 24 | public override ActionResult Index(PageListBlock currentBlock) 25 | { 26 | var pages = FindPages(currentBlock); 27 | 28 | pages = Sort(pages, currentBlock.SortOrder); 29 | 30 | if(currentBlock.Count > 0) 31 | { 32 | pages = pages.Take(currentBlock.Count); 33 | } 34 | 35 | var model = new PageListModel(currentBlock) 36 | { 37 | Pages = pages 38 | }; 39 | 40 | ViewData.GetEditHints() 41 | .AddConnection(x => x.Heading, x => x.Heading); 42 | 43 | return PartialView(model); 44 | } 45 | 46 | private IEnumerable FindPages(PageListBlock currentBlock) 47 | { 48 | IEnumerable pages; 49 | var listRoot = currentBlock.Root; 50 | if (currentBlock.Recursive) 51 | { 52 | if (currentBlock.PageTypeFilter != null) 53 | { 54 | pages = contentLocator.FindPagesByPageType(listRoot, true, currentBlock.PageTypeFilter.ID); 55 | } 56 | else 57 | { 58 | pages = contentLocator.GetAll(listRoot); 59 | } 60 | } 61 | else 62 | { 63 | if (currentBlock.PageTypeFilter != null) 64 | { 65 | pages = contentLoader.GetChildren(listRoot) 66 | .Where(p => p.ContentTypeID == currentBlock.PageTypeFilter.ID); 67 | } 68 | else 69 | { 70 | pages = contentLoader.GetChildren(listRoot); 71 | } 72 | } 73 | 74 | if (currentBlock.CategoryFilter != null && currentBlock.CategoryFilter.Any()) 75 | { 76 | pages = pages.Where(x => x.Category.Intersect(currentBlock.CategoryFilter).Any()); 77 | } 78 | return pages; 79 | } 80 | 81 | private IEnumerable Sort(IEnumerable pages, FilterSortOrder sortOrder) 82 | { 83 | var asCollection = new PageDataCollection(pages); 84 | var sortFilter = new FilterSort(sortOrder); 85 | sortFilter.Sort(asCollection); 86 | return asCollection; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/PreviewController.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web.Mvc; 3 | using EPiServer.Core; 4 | using EPiServer.Framework.DataAnnotations; 5 | using EPiServer.Framework.Web; 6 | using AlloyTemplates.Business; 7 | using AlloyTemplates.Models.Pages; 8 | using AlloyTemplates.Models.ViewModels; 9 | using EPiServer.Web; 10 | using EPiServer.Web.Mvc; 11 | using EPiServer; 12 | using EPiServer.Framework.Web.Mvc; 13 | 14 | namespace AlloyTemplates.Controllers 15 | { 16 | /* Note: as the content area rendering on Alloy is customized we create ContentArea instances 17 | * which we render in the preview view in order to provide editors with a preview which is as 18 | * realistic as possible. In other contexts we could simply have passed the block to the 19 | * view and rendered it using Html.RenderContentData */ 20 | [TemplateDescriptor( 21 | Inherited = true, 22 | TemplateTypeCategory = TemplateTypeCategories.MvcController, //Required as controllers for blocks are registered as MvcPartialController by default 23 | Tags = new[] { RenderingTags.Preview, RenderingTags.Edit }, 24 | AvailableWithoutTag = false)] 25 | [VisitorGroupImpersonation] 26 | [RequireClientResources] 27 | public class PreviewController : ActionControllerBase, IRenderTemplate, IModifyLayout 28 | { 29 | private readonly IContentLoader _contentLoader; 30 | private readonly TemplateResolver _templateResolver; 31 | private readonly DisplayOptions _displayOptions; 32 | 33 | public PreviewController(IContentLoader contentLoader, TemplateResolver templateResolver, DisplayOptions displayOptions) 34 | { 35 | _contentLoader = contentLoader; 36 | _templateResolver = templateResolver; 37 | _displayOptions = displayOptions; 38 | } 39 | 40 | public ActionResult Index(IContent currentContent) 41 | { 42 | //As the layout requires a page for title etc we "borrow" the start page 43 | var startPage = _contentLoader.Get(SiteDefinition.Current.StartPage); 44 | 45 | var model = new PreviewModel(startPage, currentContent); 46 | 47 | var supportedDisplayOptions = _displayOptions 48 | .Select(x => new { Tag = x.Tag, Name = x.Name, Supported = SupportsTag(currentContent, x.Tag) }) 49 | .ToList(); 50 | 51 | if (supportedDisplayOptions.Any(x => x.Supported)) 52 | { 53 | foreach (var displayOption in supportedDisplayOptions) 54 | { 55 | var contentArea = new ContentArea(); 56 | contentArea.Items.Add(new ContentAreaItem 57 | { 58 | ContentLink = currentContent.ContentLink 59 | }); 60 | var areaModel = new PreviewModel.PreviewArea 61 | { 62 | Supported = displayOption.Supported, 63 | AreaTag = displayOption.Tag, 64 | AreaName = displayOption.Name, 65 | ContentArea = contentArea 66 | }; 67 | model.Areas.Add(areaModel); 68 | } 69 | } 70 | 71 | return View(model); 72 | } 73 | 74 | private bool SupportsTag(IContent content, string tag) 75 | { 76 | var templateModel = _templateResolver.Resolve(HttpContext, 77 | content.GetOriginalType(), 78 | content, 79 | TemplateTypeCategories.MvcPartial, 80 | tag); 81 | 82 | return templateModel != null; 83 | } 84 | 85 | public void ModifyLayout(LayoutModel layoutModel) 86 | { 87 | layoutModel.HideHeader = true; 88 | layoutModel.HideFooter = true; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/RegisterController.cs: -------------------------------------------------------------------------------- 1 | using AlloyTemplates.Models; 2 | using EPiServer.Core; 3 | using EPiServer.ServiceLocation; 4 | using EPiServer.Shell.Security; 5 | using EPiServer.Web.Routing; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Web.Mvc; 9 | using System.Web.Profile; 10 | using EPiServer.Security; 11 | using EPiServer.DataAbstraction; 12 | using EPiServer.Personalization; 13 | 14 | namespace AlloyTemplates.Controllers 15 | { 16 | /// 17 | /// Used to register a user for first time 18 | /// 19 | public class RegisterController : Controller 20 | { 21 | const string AdminRoleName = "WebAdmins"; 22 | public const string ErrorKey = "CreateError"; 23 | 24 | public ActionResult Index() 25 | { 26 | return View(); 27 | } 28 | 29 | // 30 | // POST: /Register 31 | [HttpPost] 32 | [AllowAnonymous] 33 | [ValidateAntiForgeryToken] 34 | [ValidateInput(false)] 35 | public ActionResult Index(RegisterViewModel model) 36 | { 37 | if (ModelState.IsValid) 38 | { 39 | UIUserCreateStatus status; 40 | IEnumerable errors = Enumerable.Empty(); 41 | var result = UIUserProvider.CreateUser(model.Username, model.Password, model.Email, null, null, true, out status, out errors); 42 | if (status == UIUserCreateStatus.Success) 43 | { 44 | UIRoleProvider.CreateRole(AdminRoleName); 45 | UIRoleProvider.AddUserToRoles(result.Username, new string[] { AdminRoleName }); 46 | 47 | if (ProfileManager.Enabled) 48 | { 49 | var profile = EPiServerProfile.Wrap(ProfileBase.Create(result.Username)); 50 | profile.Email = model.Email; 51 | profile.Save(); 52 | } 53 | 54 | AdministratorRegistrationPage.IsEnabled = false; 55 | SetFullAccessToWebAdmin(); 56 | var resFromSignIn = UISignInManager.SignIn(UIUserProvider.Name, model.Username, model.Password); 57 | if (resFromSignIn) 58 | { 59 | return Redirect(UrlResolver.Current.GetUrl(ContentReference.StartPage)); 60 | } 61 | } 62 | AddErrors(errors); 63 | } 64 | // If we got this far, something failed, redisplay form 65 | return View(model); 66 | } 67 | 68 | private void SetFullAccessToWebAdmin() 69 | { 70 | var securityrep = ServiceLocator.Current.GetInstance(); 71 | var permissions = securityrep.Get(ContentReference.RootPage).CreateWritableClone() as IContentSecurityDescriptor; 72 | permissions.AddEntry(new AccessControlEntry(AdminRoleName, AccessLevel.FullAccess)); 73 | securityrep.Save(ContentReference.RootPage, permissions, SecuritySaveType.Replace); 74 | } 75 | 76 | private void AddErrors(IEnumerable errors) 77 | { 78 | foreach (var error in errors) 79 | { 80 | ModelState.AddModelError(ErrorKey, error); 81 | } 82 | } 83 | 84 | protected override void OnAuthorization(AuthorizationContext filterContext) 85 | { 86 | if (!AdministratorRegistrationPage.IsEnabled) 87 | { 88 | filterContext.Result = new HttpNotFoundResult(); 89 | return; 90 | } 91 | base.OnAuthorization(filterContext); 92 | } 93 | 94 | UIUserProvider UIUserProvider 95 | { 96 | get 97 | { 98 | return ServiceLocator.Current.GetInstance(); 99 | } 100 | } 101 | UIRoleProvider UIRoleProvider 102 | { 103 | get 104 | { 105 | return ServiceLocator.Current.GetInstance(); 106 | } 107 | } 108 | UISignInManager UISignInManager 109 | { 110 | get 111 | { 112 | return ServiceLocator.Current.GetInstance(); 113 | } 114 | } 115 | 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/StartPageController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using AlloyTemplates.Models.Pages; 3 | using AlloyTemplates.Models.ViewModels; 4 | using EPiServer.Web; 5 | using EPiServer.Web.Mvc; 6 | 7 | namespace AlloyTemplates.Controllers 8 | { 9 | public class StartPageController : PageControllerBase 10 | { 11 | public ActionResult Index(StartPage currentPage) 12 | { 13 | var model = PageViewModel.Create(currentPage); 14 | 15 | if (SiteDefinition.Current.StartPage.CompareToIgnoreWorkID(currentPage.ContentLink)) // Check if it is the StartPage or just a page of the StartPage type. 16 | { 17 | //Connect the view models logotype property to the start page's to make it editable 18 | var editHints = ViewData.GetEditHints, StartPage>(); 19 | editHints.AddConnection(m => m.Layout.Logotype, p => p.SiteLogotype); 20 | editHints.AddConnection(m => m.Layout.ProductPages, p => p.ProductPageLinks); 21 | editHints.AddConnection(m => m.Layout.CompanyInformationPages, p => p.CompanyInformationPageLinks); 22 | editHints.AddConnection(m => m.Layout.NewsPages, p => p.NewsPageLinks); 23 | editHints.AddConnection(m => m.Layout.CustomerZonePages, p => p.CustomerZonePageLinks); 24 | } 25 | 26 | return View(model); 27 | } 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Controllers/VideoFileController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using AlloyTemplates.Models.Media; 3 | using AlloyTemplates.Models.ViewModels; 4 | using EPiServer.Web.Mvc; 5 | using EPiServer.Web.Routing; 6 | using System; 7 | using EPiServer.Core; 8 | 9 | namespace AlloyTemplates.Controllers 10 | { 11 | /// 12 | /// Controller for the video file. 13 | /// 14 | public class VideoFileController : PartialContentController 15 | { 16 | private readonly UrlResolver _urlResolver; 17 | 18 | public VideoFileController(UrlResolver urlResolver) 19 | { 20 | _urlResolver = urlResolver; 21 | } 22 | 23 | /// 24 | /// The index action for the video file. Creates the view model and renders the view. 25 | /// 26 | /// The current video file. 27 | public override ActionResult Index(VideoFile currentContent) 28 | { 29 | var model = new VideoViewModel 30 | { 31 | Url = _urlResolver.GetUrl(currentContent.ContentLink), 32 | PreviewImageUrl = ContentReference.IsNullOrEmpty(currentContent.PreviewImage) ? String.Empty : _urlResolver.GetUrl(currentContent.PreviewImage), 33 | }; 34 | 35 | return PartialView(model); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/EPiServerFramework.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Global.asax.cs: -------------------------------------------------------------------------------- 1 | namespace AlloyTemplates 2 | { 3 | public class EPiServerApplication : EPiServer.Global 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Global.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.DataAnnotations; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | 5 | namespace AlloyTemplates 6 | { 7 | 8 | public class Global 9 | { 10 | public static readonly string LoginPath = "/util/login.aspx"; 11 | public static readonly string AppRelativeLoginPath = string.Format("~{0}", LoginPath); 12 | 13 | /// 14 | /// Group names for content types and properties 15 | /// 16 | [GroupDefinitions()] 17 | public static class GroupNames 18 | { 19 | [Display(Name = "Contact", Order = 1)] 20 | public const string Contact = "Contact"; 21 | 22 | [Display(Name = "Default", Order = 2)] 23 | public const string Default = "Default"; 24 | 25 | [Display(Name = "Metadata", Order = 3)] 26 | public const string MetaData = "Metadata"; 27 | 28 | [Display(Name = "News", Order = 4)] 29 | public const string News = "News"; 30 | 31 | [Display(Name = "Products", Order = 5)] 32 | public const string Products = "Products"; 33 | 34 | [Display(Name = "SiteSettings", Order = 6)] 35 | public const string SiteSettings = "SiteSettings"; 36 | 37 | [Display(Name = "Specialized", Order = 7)] 38 | public const string Specialized = "Specialized"; 39 | } 40 | 41 | /// 42 | /// Tags to use for the main widths used in the Bootstrap HTML framework 43 | /// 44 | public static class ContentAreaTags 45 | { 46 | public const string FullWidth = "span12"; 47 | public const string TwoThirdsWidth = "span8"; 48 | public const string HalfWidth = "span6"; 49 | public const string OneThirdWidth = "span4"; 50 | public const string NoRenderer = "norenderer"; 51 | } 52 | 53 | /// 54 | /// Main widths used in the Bootstrap HTML framework 55 | /// 56 | public static class ContentAreaWidths 57 | { 58 | public const int FullWidth = 12; 59 | public const int TwoThirdsWidth = 8; 60 | public const int HalfWidth = 6; 61 | public const int OneThirdWidth = 4; 62 | } 63 | 64 | public static Dictionary ContentAreaTagWidths = new Dictionary 65 | { 66 | { ContentAreaTags.FullWidth, ContentAreaWidths.FullWidth }, 67 | { ContentAreaTags.TwoThirdsWidth, ContentAreaWidths.TwoThirdsWidth }, 68 | { ContentAreaTags.HalfWidth, ContentAreaWidths.HalfWidth }, 69 | { ContentAreaTags.OneThirdWidth, ContentAreaWidths.OneThirdWidth } 70 | }; 71 | 72 | /// 73 | /// Names used for UIHint attributes to map specific rendering controls to page properties 74 | /// 75 | public static class SiteUIHints 76 | { 77 | public const string Contact = "contact"; 78 | public const string Strings = "StringList"; 79 | public const string StringsCollection = "StringsCollection"; 80 | } 81 | 82 | /// 83 | /// Virtual path to folder with static graphics, such as "~/Static/gfx/" 84 | /// 85 | public const string StaticGraphicsFolderPath = "~/Static/gfx/"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Helpers/CategorizableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using EPiServer; 4 | using EPiServer.Core; 5 | using EPiServer.DataAbstraction; 6 | using EPiServer.ServiceLocation; 7 | 8 | namespace AlloyTemplates.Helpers 9 | { 10 | /// 11 | /// Provides extension methods for categorizable content 12 | /// 13 | /// ICategorizable content includes for example pages and blocks. 14 | public static class CategorizableExtensions 15 | { 16 | /// 17 | /// Returns the CSS classes (if any) associated with the theme(s) of the content, as decided by its categories 18 | /// 19 | /// 20 | /// CSS classes associated with the content's theme(s), or an empty string array if no theme is applicable 21 | /// Content's categorization may map to more than one theme. This method assumes there are website categories called "Meet", "Track", and "Plan" 22 | public static string[] GetThemeCssClassNames(this ICategorizable content) 23 | { 24 | if (content.Category == null) 25 | { 26 | return new string[0]; 27 | } 28 | 29 | var cssClasses = new HashSet(); // Although with some overhead, a HashSet allows us to ensure we never add a CSS class more than once 30 | var categoryRepository = ServiceLocator.Current.GetInstance(); 31 | 32 | foreach (var categoryName in content.Category.Select(category => categoryRepository.Get(category).Name.ToLower())) 33 | { 34 | switch (categoryName) 35 | { 36 | case "meet": 37 | cssClasses.Add("theme1"); 38 | break; 39 | case "track": 40 | cssClasses.Add("theme2"); 41 | break; 42 | case "plan": 43 | cssClasses.Add("theme3"); 44 | break; 45 | } 46 | } 47 | 48 | return cssClasses.ToArray(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Helpers/UrlHelpers.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | using EPiServer.Core; 5 | using EPiServer.Globalization; 6 | using EPiServer.ServiceLocation; 7 | using EPiServer.Web.Routing; 8 | using EPiServer; 9 | 10 | namespace AlloyTemplates.Helpers 11 | { 12 | public static class UrlHelpers 13 | { 14 | /// 15 | /// Returns the target URL for a ContentReference. Respects the page's shortcut setting 16 | /// so if the page is set as a shortcut to another page or an external URL that URL 17 | /// will be returned. 18 | /// 19 | public static IHtmlString PageLinkUrl(this UrlHelper urlHelper, ContentReference contentLink) 20 | { 21 | if(ContentReference.IsNullOrEmpty(contentLink)) 22 | { 23 | return MvcHtmlString.Empty; 24 | } 25 | 26 | var contentLoader = ServiceLocator.Current.GetInstance(); 27 | var page = contentLoader.Get(contentLink); 28 | 29 | return PageLinkUrl(urlHelper, page); 30 | } 31 | 32 | /// 33 | /// Returns the target URL for a page. Respects the page's shortcut setting 34 | /// so if the page is set as a shortcut to another page or an external URL that URL 35 | /// will be returned. 36 | /// 37 | public static IHtmlString PageLinkUrl(this UrlHelper urlHelper, PageData page) 38 | { 39 | var urlResolver = ServiceLocator.Current.GetInstance(); 40 | switch (page.LinkType) 41 | { 42 | case PageShortcutType.Normal: 43 | case PageShortcutType.FetchData: 44 | return new MvcHtmlString(urlResolver.GetUrl(page.ContentLink)); 45 | 46 | case PageShortcutType.Shortcut: 47 | var shortcutProperty = page.Property["PageShortcutLink"] as PropertyPageReference; 48 | if (shortcutProperty != null && !ContentReference.IsNullOrEmpty(shortcutProperty.ContentLink)) 49 | { 50 | return urlHelper.PageLinkUrl(shortcutProperty.ContentLink); 51 | } 52 | break; 53 | 54 | case PageShortcutType.External: 55 | return new MvcHtmlString(page.LinkURL); 56 | } 57 | return MvcHtmlString.Empty; 58 | } 59 | 60 | public static RouteValueDictionary GetPageRoute(this RequestContext requestContext, ContentReference contentLink) 61 | { 62 | var values = new RouteValueDictionary(); 63 | values[RoutingConstants.NodeKey] = contentLink; 64 | values[RoutingConstants.LanguageKey] = ContentLanguage.PreferredCulture.Name; 65 | return values; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/IndexingService/IndexingService.svc: -------------------------------------------------------------------------------- 1 | <%@ ServiceHost Language="C#" Debug="false" Service="EPiServer.Search.IndexingService.IndexingService" Factory="IndexingServiceHostFactory" %> 2 | 3 | using System.ServiceModel; 4 | using System.ServiceModel.Activation; 5 | 6 | public class IndexingServiceHostFactory : WebServiceHostFactory 7 | { 8 | protected override ServiceHost CreateServiceHost(System.Type serviceType, System.Uri[] baseAddresses) 9 | { 10 | var host = base.CreateServiceHost(serviceType, baseAddresses); 11 | 12 | WebHttpBinding binding = new WebHttpBinding("IndexingServiceCustomBinding"); 13 | var endpoint = host.AddServiceEndpoint(typeof(EPiServer.Search.IndexingService.IIndexingService), binding, ""); 14 | 15 | return host; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/ButtonBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.DataAbstraction; 3 | using EPiServer; 4 | 5 | namespace AlloyTemplates.Models.Blocks 6 | { 7 | /// 8 | /// Used to insert a link which is styled as a button 9 | /// 10 | [SiteContentType(GUID = "426CF12F-1F01-4EA0-922F-0778314DDAF0")] 11 | [SiteImageUrl] 12 | public class ButtonBlock : SiteBlockData 13 | { 14 | [Display(Order = 1, GroupName = SystemTabNames.Content)] 15 | [Required] 16 | public virtual string ButtonText { get; set; } 17 | 18 | [Display(Order = 2, GroupName = SystemTabNames.Content)] 19 | [Required] 20 | public virtual Url ButtonLink { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/ContactBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | using EPiServer.Web; 6 | using EPiServer; 7 | 8 | namespace AlloyTemplates.Models.Blocks 9 | { 10 | /// 11 | /// Used to present contact information with a call-to-action link 12 | /// 13 | /// Actual contact details are retrieved from a contact page specified using the ContactPageLink property 14 | [SiteContentType(GUID = "7E932EAF-6BC2-4753-902A-8670EDC5F363")] 15 | [SiteImageUrl] 16 | public class ContactBlock : SiteBlockData 17 | { 18 | [Display( 19 | GroupName = SystemTabNames.Content, 20 | Order = 1)] 21 | [CultureSpecific] 22 | [UIHint(UIHint.Image)] 23 | public virtual ContentReference Image { get; set; } 24 | 25 | [Display( 26 | GroupName = SystemTabNames.Content, 27 | Order = 2)] 28 | [CultureSpecific] 29 | public virtual string Heading { get; set; } 30 | 31 | /// 32 | /// Gets or sets the contact page from which contact information should be retrieved 33 | /// 34 | [Display( 35 | GroupName = SystemTabNames.Content, 36 | Order = 3)] 37 | [UIHint(Global.SiteUIHints.Contact)] 38 | public virtual PageReference ContactPageLink { get; set; } 39 | 40 | [Display( 41 | GroupName = SystemTabNames.Content, 42 | Order = 4)] 43 | [CultureSpecific] 44 | public virtual string LinkText { get; set; } 45 | 46 | [Display( 47 | GroupName = SystemTabNames.Content, 48 | Order = 5)] 49 | [CultureSpecific] 50 | public virtual Url LinkUrl { get; set; } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/EditorialBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | 6 | namespace AlloyTemplates.Models.Blocks 7 | { 8 | /// 9 | /// Used to insert editorial content edited using a rich-text editor 10 | /// 11 | [SiteContentType( 12 | GUID = "67F617A4-2175-4360-975E-75EDF2B924A7", 13 | GroupName = SystemTabNames.Content)] 14 | [SiteImageUrl] 15 | public class EditorialBlock : SiteBlockData 16 | { 17 | [Display(GroupName = SystemTabNames.Content)] 18 | [CultureSpecific] 19 | public virtual XhtmlString MainBody { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/JumbotronBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.DataAbstraction; 3 | using EPiServer.DataAnnotations; 4 | using EPiServer.Web; 5 | using EPiServer.Core; 6 | using EPiServer; 7 | 8 | namespace AlloyTemplates.Models.Blocks 9 | { 10 | /// 11 | /// Used for a primary message on a page, commonly used on start pages and landing pages 12 | /// 13 | [SiteContentType( 14 | GroupName = Global.GroupNames.Specialized, 15 | GUID = "9FD1C860-7183-4122-8CD4-FF4C55E096F9")] 16 | [SiteImageUrl] 17 | public class JumbotronBlock : SiteBlockData 18 | { 19 | [Display( 20 | GroupName = SystemTabNames.Content, 21 | Order = 1 22 | )] 23 | [CultureSpecific] 24 | [UIHint(UIHint.Image)] 25 | public virtual ContentReference Image { get; set; } 26 | 27 | /// 28 | /// Gets or sets a description for the image, for example used as the alt text for the image when rendered 29 | /// 30 | [Display( 31 | GroupName = SystemTabNames.Content, 32 | Order = 1 33 | )] 34 | [CultureSpecific] 35 | [UIHint(UIHint.Textarea)] 36 | public virtual string ImageDescription 37 | { 38 | get 39 | { 40 | var propertyValue = this["ImageDescription"] as string; 41 | 42 | // Return image description with fall back to the heading if no description has been specified 43 | return string.IsNullOrWhiteSpace(propertyValue) ? Heading : propertyValue; 44 | } 45 | set { this["ImageDescription"] = value; } 46 | } 47 | 48 | [Display( 49 | GroupName = SystemTabNames.Content, 50 | Order = 1 51 | )] 52 | [CultureSpecific] 53 | public virtual string Heading { get; set; } 54 | 55 | [Display( 56 | GroupName = SystemTabNames.Content, 57 | Order = 2 58 | )] 59 | [CultureSpecific] 60 | [UIHint(UIHint.Textarea)] 61 | public virtual string SubHeading { get; set; } 62 | 63 | [Display( 64 | GroupName = SystemTabNames.Content, 65 | Order = 3 66 | )] 67 | [CultureSpecific] 68 | [Required] 69 | public virtual string ButtonText { get; set; } 70 | 71 | //The link must be required as an anchor tag requires an href in order to be valid and focusable 72 | [Display( 73 | GroupName = SystemTabNames.Content, 74 | Order = 4 75 | )] 76 | [CultureSpecific] 77 | [Required] 78 | public virtual Url ButtonLink { get; set; } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/PageListBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.ComponentModel.DataAnnotations; 3 | using EPiServer.Core; 4 | using EPiServer.DataAbstraction; 5 | using EPiServer.DataAnnotations; 6 | using EPiServer.Filters; 7 | 8 | namespace AlloyTemplates.Models.Blocks 9 | { 10 | /// 11 | /// Used to insert a list of pages, for example a news list 12 | /// 13 | [SiteContentType(GUID = "30685434-33DE-42AF-88A7-3126B936AEAD")] 14 | [SiteImageUrl] 15 | public class PageListBlock : SiteBlockData 16 | { 17 | [Display( 18 | GroupName = SystemTabNames.Content, 19 | Order = 1)] 20 | [CultureSpecific] 21 | public virtual string Heading { get; set; } 22 | 23 | [Display( 24 | GroupName = SystemTabNames.Content, 25 | Order = 2)] 26 | [DefaultValue(false)] 27 | public virtual bool IncludePublishDate { get; set; } 28 | 29 | /// 30 | /// Gets or sets whether a page introduction/description should be included in the list 31 | /// 32 | [Display( 33 | GroupName = SystemTabNames.Content, 34 | Order = 3)] 35 | [DefaultValue(true)] 36 | public virtual bool IncludeIntroduction { get; set; } 37 | 38 | [Display( 39 | GroupName = SystemTabNames.Content, 40 | Order = 4)] 41 | [DefaultValue(3)] 42 | [Required] 43 | public virtual int Count { get; set; } 44 | 45 | [Display( 46 | GroupName = SystemTabNames.Content, 47 | Order = 4)] 48 | [DefaultValue(FilterSortOrder.PublishedDescending)] 49 | [UIHint("SortOrder")] 50 | [BackingType(typeof(PropertyNumber))] 51 | public virtual FilterSortOrder SortOrder { get; set; } 52 | 53 | [Display( 54 | GroupName = SystemTabNames.Content, 55 | Order = 5)] 56 | [Required] 57 | public virtual PageReference Root { get; set; } 58 | 59 | [Display( 60 | GroupName = SystemTabNames.Content, 61 | Order = 6)] 62 | public virtual PageType PageTypeFilter{get; set;} 63 | 64 | [Display( 65 | GroupName = SystemTabNames.Content, 66 | Order = 7)] 67 | public virtual CategoryList CategoryFilter { get; set; } 68 | 69 | [Display( 70 | GroupName = SystemTabNames.Content, 71 | Order = 8)] 72 | public virtual bool Recursive { get; set; } 73 | 74 | #region IInitializableContent 75 | 76 | /// 77 | /// Sets the default property values on the content data. 78 | /// 79 | /// Type of the content. 80 | public override void SetDefaultValues(ContentType contentType) 81 | { 82 | base.SetDefaultValues(contentType); 83 | 84 | Count = 3; 85 | IncludeIntroduction = true; 86 | IncludePublishDate = false; 87 | SortOrder = FilterSortOrder.PublishedDescending; 88 | } 89 | 90 | #endregion 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/SiteBlockData.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace AlloyTemplates.Models.Blocks 3 | { 4 | /// 5 | /// Base class for all block types on the site 6 | /// 7 | public abstract class SiteBlockData : EPiServer.Core.BlockData 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/SiteLogotypeBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAnnotations; 4 | using EPiServer.Shell.ObjectEditing; 5 | using EPiServer.Web; 6 | using EPiServer; 7 | 8 | namespace AlloyTemplates.Models.Blocks 9 | { 10 | /// 11 | /// Used to provide a composite property on the start page to set site logotype settings 12 | /// 13 | [SiteContentType( 14 | GUID = "09854019-91A5-4B93-8623-17F038346001", 15 | AvailableInEditMode = false)] // Should not be created and added to content areas by editors, the SiteLogotypeBlock is only used as a property type 16 | [SiteImageUrl] 17 | public class SiteLogotypeBlock : SiteBlockData 18 | { 19 | /// 20 | /// Gets the site logotype URL 21 | /// 22 | /// If not specified a default logotype will be used 23 | [DefaultDragAndDropTarget] 24 | [UIHint(UIHint.Image)] 25 | public virtual Url Url 26 | { 27 | get 28 | { 29 | var url = this.GetPropertyValue(b => b.Url); 30 | 31 | return url == null || url.IsEmpty() 32 | ? new Url("/Static/gfx/logotype.png") 33 | : url; 34 | } 35 | set 36 | { 37 | this.SetPropertyValue(b => b.Url, value); 38 | } 39 | } 40 | 41 | [CultureSpecific] 42 | public virtual string Title { get; set; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/TeaserBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | using EPiServer.Web; 6 | 7 | namespace AlloyTemplates.Models.Blocks 8 | { 9 | /// 10 | /// Used to provide a stylized entry point to a page on the site 11 | /// 12 | [SiteContentType(GUID = "EB67A99A-E239-41B8-9C59-20EAA5936047")] // BEST PRACTICE TIP: Always assign a GUID explicitly when creating a new block type 13 | [SiteImageUrl] // Use site's default thumbnail 14 | public class TeaserBlock : SiteBlockData 15 | { 16 | [CultureSpecific] 17 | [Required(AllowEmptyStrings = false)] 18 | [Display( 19 | GroupName = SystemTabNames.Content, 20 | Order = 1)] 21 | public virtual string Heading { get; set; } 22 | 23 | [CultureSpecific] 24 | [Required(AllowEmptyStrings = false)] 25 | [Display( 26 | GroupName = SystemTabNames.Content, 27 | Order = 2)] 28 | [UIHint(UIHint.Textarea)] 29 | public virtual string Text { get; set; } 30 | 31 | [CultureSpecific] 32 | [Required(AllowEmptyStrings = false)] 33 | [UIHint(UIHint.Image)] 34 | [Display( 35 | GroupName = SystemTabNames.Content, 36 | Order = 3)] 37 | public virtual ContentReference Image { get; set; } 38 | 39 | [Display( 40 | GroupName = SystemTabNames.Content, 41 | Order = 4)] 42 | public virtual PageReference Link { get; set; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Blocks/_ReadMe.txt: -------------------------------------------------------------------------------- 1 | This folder contains all block types. 2 | 3 | Blocks should be named with a suffix of "Block", such as "TeaserBlock" or "NewsListBlock". 4 | 5 | Default block controls should be named with a suffix of "Control", 6 | such as "TeaserBlockControl" or "NewsListBlockControl". 7 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Media/GenericMedia.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | using EPiServer.DataAnnotations; 3 | using System; 4 | 5 | namespace AlloyTemplates.Models.Media 6 | { 7 | [ContentType(GUID = "EE3BD195-7CB0-4756-AB5F-E5E223CD9820")] 8 | public class GenericMedia : MediaData 9 | { 10 | /// 11 | /// Gets or sets the description. 12 | /// 13 | public virtual String Description { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Media/ImageFile.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | using EPiServer.DataAnnotations; 3 | using EPiServer.Framework.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace AlloyTemplates.Models.Media 7 | { 8 | [ContentType(GUID = "0A89E464-56D4-449F-AEA8-2BF774AB8730")] 9 | [MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")] 10 | public class ImageFile : ImageData 11 | { 12 | /// 13 | /// Gets or sets the copyright. 14 | /// 15 | /// 16 | /// The copyright. 17 | /// 18 | public virtual string Copyright { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Media/VideoFile.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAnnotations; 4 | using EPiServer.Framework.DataAnnotations; 5 | using EPiServer.Web; 6 | 7 | namespace AlloyTemplates.Models.Media 8 | { 9 | [ContentType(GUID = "85468104-E06F-47E5-A317-FC9B83D3CBA6")] 10 | [MediaDescriptor(ExtensionString = "flv,mp4,webm")] 11 | public class VideoFile : VideoData 12 | { 13 | /// 14 | /// Gets or sets the copyright. 15 | /// 16 | public virtual string Copyright { get; set; } 17 | 18 | /// 19 | /// Gets or sets the URL to the preview image. 20 | /// 21 | [UIHint(UIHint.Image)] 22 | public virtual ContentReference PreviewImage { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/ArticlePage.cs: -------------------------------------------------------------------------------- 1 | namespace AlloyTemplates.Models.Pages 2 | { 3 | /// 4 | /// Used primarily for publishing news articles on the website 5 | /// 6 | [SiteContentType( 7 | GroupName = Global.GroupNames.News, 8 | GUID = "AEECADF2-3E89-4117-ADEB-F8D43565D2F4")] 9 | [SiteImageUrl(Global.StaticGraphicsFolderPath + "page-type-thumbnail-article.png")] 10 | public class ArticlePage : StandardPage 11 | { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/ContactPage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using AlloyTemplates.Business.Rendering; 3 | using EPiServer.Web; 4 | using EPiServer.Core; 5 | 6 | namespace AlloyTemplates.Models.Pages 7 | { 8 | /// 9 | /// Represents contact details for a contact person 10 | /// 11 | [SiteContentType( 12 | GUID = "F8D47655-7B50-4319-8646-3369BA9AF05B", 13 | GroupName = Global.GroupNames.Specialized)] 14 | [SiteImageUrl(Global.StaticGraphicsFolderPath + "page-type-thumbnail-contact.png")] 15 | public class ContactPage : SitePageData, IContainerPage 16 | { 17 | [Display(GroupName = Global.GroupNames.Contact)] 18 | [UIHint(UIHint.Image)] 19 | public virtual ContentReference Image { get; set; } 20 | 21 | [Display(GroupName = Global.GroupNames.Contact)] 22 | public virtual string Phone { get; set; } 23 | 24 | [Display(GroupName = Global.GroupNames.Contact)] 25 | [EmailAddress] 26 | public virtual string Email { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/ContainerPage.cs: -------------------------------------------------------------------------------- 1 | using AlloyTemplates.Business.Rendering; 2 | 3 | namespace AlloyTemplates.Models.Pages 4 | { 5 | /// 6 | /// Used to logically group pages in the page tree 7 | /// 8 | [SiteContentType( 9 | GUID = "D178950C-D20E-4A46-90BD-5338B2424745", 10 | GroupName = Global.GroupNames.Specialized)] 11 | [SiteImageUrl] 12 | public class ContainerPage : SitePageData, IContainerPage 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/IHasRelatedContent.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | 3 | namespace AlloyTemplates.Models.Pages 4 | { 5 | public interface IHasRelatedContent 6 | { 7 | ContentArea RelatedContentArea { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/ISearchPage.cs: -------------------------------------------------------------------------------- 1 | namespace AlloyTemplates.Models.Pages 2 | { 3 | /// 4 | /// Marker interface for search implementation 5 | /// 6 | public interface ISearchPage 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/LandingPage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | 6 | namespace AlloyTemplates.Models.Pages 7 | { 8 | /// 9 | /// Used for campaign or landing pages, commonly used for pages linked in online advertising such as AdWords 10 | /// 11 | [SiteContentType( 12 | GUID = "DBED4258-8213-48DB-A11F-99C034172A54", 13 | GroupName = Global.GroupNames.Specialized)] 14 | [SiteImageUrl] 15 | public class LandingPage : SitePageData 16 | { 17 | [Display( 18 | GroupName = SystemTabNames.Content, 19 | Order=310)] 20 | [CultureSpecific] 21 | public virtual ContentArea MainContentArea { get; set; } 22 | 23 | public override void SetDefaultValues(ContentType contentType) 24 | { 25 | base.SetDefaultValues(contentType); 26 | 27 | HideSiteFooter = true; 28 | HideSiteHeader = true; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/NewsPage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.DataAbstraction; 3 | using EPiServer.Filters; 4 | using EPiServer.Framework.Localization; 5 | using EPiServer.ServiceLocation; 6 | using AlloyTemplates.Business; 7 | using AlloyTemplates.Models.Blocks; 8 | 9 | namespace AlloyTemplates.Models.Pages 10 | { 11 | /// 12 | /// Presents a news section including a list of the most recent articles on the site 13 | /// 14 | [SiteContentType(GUID = "638D8271-5CA3-4C72-BABC-3E8779233263")] 15 | [SiteImageUrl] 16 | public class NewsPage : StandardPage 17 | { 18 | [Display( 19 | GroupName = SystemTabNames.Content, 20 | Order = 305)] 21 | public virtual PageListBlock NewsList { get; set; } 22 | 23 | public override void SetDefaultValues(ContentType contentType) 24 | { 25 | base.SetDefaultValues(contentType); 26 | 27 | NewsList.Count = 20; 28 | NewsList.Heading = ServiceLocator.Current.GetInstance().GetString("/newspagetemplate/latestnews"); 29 | NewsList.IncludeIntroduction = true; 30 | NewsList.IncludePublishDate = true; 31 | NewsList.Recursive = true; 32 | NewsList.PageTypeFilter = typeof(ArticlePage).GetPageType(); 33 | NewsList.SortOrder = FilterSortOrder.PublishedDescending; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/ProductPage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations; 3 | using AlloyTemplates.Models.Blocks; 4 | using EPiServer.Core; 5 | using EPiServer.DataAbstraction; 6 | using EPiServer.DataAnnotations; 7 | using AlloyTemplates.Models.Properties; 8 | 9 | namespace AlloyTemplates.Models.Pages 10 | { 11 | /// 12 | /// Used to present a single product 13 | /// 14 | [SiteContentType( 15 | GUID = "17583DCD-3C11-49DD-A66D-0DEF0DD601FC", 16 | GroupName = Global.GroupNames.Products)] 17 | [SiteImageUrl(Global.StaticGraphicsFolderPath + "page-type-thumbnail-product.png")] 18 | [AvailableContentTypes( 19 | Availability = Availability.Specific, 20 | IncludeOn = new[] { typeof(StartPage) })] 21 | public class ProductPage : StandardPage, IHasRelatedContent 22 | { 23 | [Required] 24 | [Display(Order = 305)] 25 | [UIHint(Global.SiteUIHints.StringsCollection)] 26 | [CultureSpecific] 27 | public virtual IList UniqueSellingPoints { get; set; } 28 | 29 | [Display( 30 | GroupName = SystemTabNames.Content, 31 | Order = 330)] 32 | [CultureSpecific] 33 | [AllowedTypes(new[] { typeof(IContentData) },new[] { typeof(JumbotronBlock) })] 34 | public virtual ContentArea RelatedContentArea { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/SearchPage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using AlloyTemplates.Models.Blocks; 3 | using EPiServer.Core; 4 | using EPiServer.DataAbstraction; 5 | using EPiServer.DataAnnotations; 6 | 7 | namespace AlloyTemplates.Models.Pages 8 | { 9 | /// 10 | /// Used to provide on-site search 11 | /// 12 | [SiteContentType( 13 | GUID = "AAC25733-1D21-4F82-B031-11E626C91E30", 14 | GroupName = Global.GroupNames.Specialized)] 15 | [SiteImageUrl] 16 | public class SearchPage : SitePageData, IHasRelatedContent, ISearchPage 17 | { 18 | [Display( 19 | GroupName = SystemTabNames.Content, 20 | Order = 310)] 21 | [CultureSpecific] 22 | [AllowedTypes(new[] { typeof(IContentData) }, new[] { typeof(JumbotronBlock) })] 23 | public virtual ContentArea RelatedContentArea { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/SitePageData.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | using AlloyTemplates.Business.Rendering; 6 | using AlloyTemplates.Models.Properties; 7 | using EPiServer.Web; 8 | 9 | namespace AlloyTemplates.Models.Pages 10 | { 11 | /// 12 | /// Base class for all page types 13 | /// 14 | public abstract class SitePageData : PageData, ICustomCssInContentArea 15 | { 16 | [Display( 17 | GroupName = Global.GroupNames.MetaData, 18 | Order = 100)] 19 | [CultureSpecific] 20 | public virtual string MetaTitle 21 | { 22 | get 23 | { 24 | var metaTitle = this.GetPropertyValue(p => p.MetaTitle); 25 | 26 | // Use explicitly set meta title, otherwise fall back to page name 27 | return !string.IsNullOrWhiteSpace(metaTitle) 28 | ? metaTitle 29 | : PageName; 30 | } 31 | set { this.SetPropertyValue(p => p.MetaTitle, value); } 32 | } 33 | 34 | [Display( 35 | GroupName = Global.GroupNames.MetaData, 36 | Order = 200)] 37 | [CultureSpecific] 38 | [BackingType(typeof(PropertyStringList))] 39 | public virtual string[] MetaKeywords { get; set; } 40 | 41 | [Display( 42 | GroupName = Global.GroupNames.MetaData, 43 | Order = 300)] 44 | [CultureSpecific] 45 | [UIHint(UIHint.Textarea)] 46 | public virtual string MetaDescription { get; set; } 47 | 48 | [Display( 49 | GroupName = Global.GroupNames.MetaData, 50 | Order = 400)] 51 | [CultureSpecific] 52 | public virtual bool DisableIndexing { get; set; } 53 | 54 | [Display( 55 | GroupName = SystemTabNames.Content, 56 | Order = 100)] 57 | [UIHint(UIHint.Image)] 58 | public virtual ContentReference PageImage { get; set; } 59 | 60 | [Display( 61 | GroupName = SystemTabNames.Content, 62 | Order = 200)] 63 | [CultureSpecific] 64 | [UIHint(UIHint.Textarea)] 65 | public virtual string TeaserText 66 | { 67 | get 68 | { 69 | var teaserText = this.GetPropertyValue(p => p.TeaserText); 70 | 71 | // Use explicitly set teaser text, otherwise fall back to description 72 | return !string.IsNullOrWhiteSpace(teaserText) 73 | ? teaserText 74 | : MetaDescription; 75 | } 76 | set { this.SetPropertyValue(p => p.TeaserText, value); } 77 | } 78 | 79 | [Display( 80 | GroupName = SystemTabNames.Settings, 81 | Order = 200)] 82 | [CultureSpecific] 83 | public virtual bool HideSiteHeader { get; set; } 84 | 85 | [Display( 86 | GroupName = SystemTabNames.Settings, 87 | Order = 300)] 88 | [CultureSpecific] 89 | public virtual bool HideSiteFooter { get; set; } 90 | 91 | public string ContentAreaCssClass 92 | { 93 | get { return "teaserblock"; } //Page partials should be style like teasers 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/StandardPage.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | using EPiServer.DataAbstraction; 3 | using EPiServer.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations; 5 | 6 | namespace AlloyTemplates.Models.Pages 7 | { 8 | /// 9 | /// Used for the pages mainly consisting of manually created content such as text, images, and blocks 10 | /// 11 | [SiteContentType(GUID = "9CCC8A41-5C8C-4BE0-8E73-520FF3DE8267")] 12 | [SiteImageUrl(Global.StaticGraphicsFolderPath + "page-type-thumbnail-standard.png")] 13 | public class StandardPage : SitePageData 14 | { 15 | [Display( 16 | GroupName = SystemTabNames.Content, 17 | Order = 310)] 18 | [CultureSpecific] 19 | public virtual XhtmlString MainBody { get; set; } 20 | 21 | [Display( 22 | GroupName = SystemTabNames.Content, 23 | Order = 320)] 24 | public virtual ContentArea MainContentArea { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/StartPage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | using EPiServer.SpecializedProperties; 6 | using AlloyTemplates.Models.Blocks; 7 | 8 | namespace AlloyTemplates.Models.Pages 9 | { 10 | /// 11 | /// Used for the site's start page and also acts as a container for site settings 12 | /// 13 | [ContentType( 14 | GUID = "19671657-B684-4D95-A61F-8DD4FE60D559", 15 | GroupName = Global.GroupNames.Specialized)] 16 | [SiteImageUrl] 17 | [AvailableContentTypes( 18 | Availability.Specific, 19 | Include = new[] { typeof(ContainerPage), typeof(ProductPage), typeof(StandardPage), typeof(ISearchPage), typeof(LandingPage), typeof(ContentFolder) }, // Pages we can create under the start page... 20 | ExcludeOn = new[] { typeof(ContainerPage), typeof(ProductPage), typeof(StandardPage), typeof(ISearchPage), typeof(LandingPage) })] // ...and underneath those we can't create additional start pages 21 | public class StartPage : SitePageData 22 | { 23 | [Display( 24 | GroupName = SystemTabNames.Content, 25 | Order = 320)] 26 | [CultureSpecific] 27 | public virtual ContentArea MainContentArea { get; set; } 28 | 29 | [Display(GroupName = Global.GroupNames.SiteSettings, Order = 300)] 30 | public virtual LinkItemCollection ProductPageLinks { get; set; } 31 | 32 | [Display(GroupName = Global.GroupNames.SiteSettings, Order = 350)] 33 | public virtual LinkItemCollection CompanyInformationPageLinks { get; set; } 34 | 35 | [Display(GroupName = Global.GroupNames.SiteSettings, Order = 400)] 36 | public virtual LinkItemCollection NewsPageLinks { get; set; } 37 | 38 | [Display(GroupName = Global.GroupNames.SiteSettings, Order = 450)] 39 | public virtual LinkItemCollection CustomerZonePageLinks { get; set; } 40 | 41 | [Display(GroupName = Global.GroupNames.SiteSettings)] 42 | public virtual PageReference GlobalNewsPageLink { get; set; } 43 | 44 | [Display(GroupName = Global.GroupNames.SiteSettings)] 45 | public virtual PageReference ContactsPageLink { get; set; } 46 | 47 | [Display(GroupName = Global.GroupNames.SiteSettings)] 48 | public virtual PageReference SearchPageLink { get; set; } 49 | 50 | [Display(GroupName = Global.GroupNames.SiteSettings)] 51 | public virtual SiteLogotypeBlock SiteLogotype { get; set; } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Pages/_ReadMe.txt: -------------------------------------------------------------------------------- 1 | This folder contains all page types. 2 | 3 | Blocks should be named with a suffix of "Page", such as "StandardPage" or "ProductPage". 4 | 5 | Default page templates should be named with a suffix of "Template", 6 | such as "StandardPageTemplate" or "ProductPageTemplate". 7 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Properties/PropertyStringList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EPiServer.Core; 3 | using EPiServer.Framework.DataAnnotations; 4 | using EPiServer.PlugIn; 5 | 6 | namespace AlloyTemplates.Models.Properties 7 | { 8 | /// 9 | /// Property type for storing a list of strings 10 | /// 11 | /// For an example, see where this property type is used for the MetaKeywords property 12 | [EditorHint(Global.SiteUIHints.Strings)] 13 | [PropertyDefinitionTypePlugIn(Description = "A property for list of strings", DisplayName = "String List")] 14 | public class PropertyStringList : PropertyLongString 15 | { 16 | protected String Separator = "\n"; 17 | 18 | public String[] List 19 | { 20 | get 21 | { 22 | return (String[])Value; 23 | } 24 | } 25 | 26 | public override Type PropertyValueType 27 | { 28 | get 29 | { 30 | return typeof(String[]); 31 | } 32 | } 33 | 34 | public override object SaveData(PropertyDataCollection properties) 35 | { 36 | return LongString; 37 | } 38 | 39 | public override object Value 40 | { 41 | get 42 | { 43 | var value = base.Value as string; 44 | 45 | if (value == null) 46 | { 47 | return null; 48 | } 49 | 50 | return value.Split(Separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 51 | } 52 | set 53 | { 54 | if (value is String[]) 55 | { 56 | var s = String.Join(Separator, value as String[]); 57 | base.Value = s; 58 | } 59 | else 60 | { 61 | base.Value = value; 62 | } 63 | 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/Register/RegisterViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.Web.Mvc; 3 | 4 | namespace AlloyTemplates.Models 5 | { 6 | public class RegisterViewModel 7 | { 8 | [Required] 9 | [Display(Name = "Username")] 10 | [RegularExpression(@"^[a-zA-Z0-9_-]+$", ErrorMessage = "Username can only contain letters a-z, numbers, underscores and hyphens.")] 11 | [StringLength(20, ErrorMessage ="The {0} field can not be more than {1} characters long.")] 12 | public string Username { get; set; } 13 | 14 | [Required] 15 | [EmailAddress] 16 | [Display(Name = "Email")] 17 | public string Email { get; set; } 18 | 19 | [Required] 20 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 21 | [DataType(DataType.Password)] 22 | [Display(Name = "Password")] 23 | [AllowHtml] 24 | public string Password { get; set; } 25 | 26 | [DataType(DataType.Password)] 27 | [Display(Name = "Confirm password")] 28 | [System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 29 | [AllowHtml] 30 | public string ConfirmPassword { get; set; } 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/SiteContentType.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.DataAnnotations; 2 | 3 | namespace AlloyTemplates.Models 4 | { 5 | /// 6 | /// Attribute used for site content types to set default attribute values 7 | /// 8 | public class SiteContentType : ContentTypeAttribute 9 | { 10 | public SiteContentType() 11 | { 12 | GroupName = Global.GroupNames.Default; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/SiteImageUrl.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.DataAnnotations; 2 | 3 | namespace AlloyTemplates.Models 4 | { 5 | /// 6 | /// Attribute to set the default thumbnail for site page and block types 7 | /// 8 | public class SiteImageUrl : ImageUrlAttribute 9 | { 10 | /// 11 | /// The parameterless constructor will initialize a SiteImageUrl attribute with a default thumbnail 12 | /// 13 | public SiteImageUrl() : base("~/Static/gfx/page-type-thumbnail.png") 14 | { 15 | 16 | } 17 | 18 | public SiteImageUrl(string path) : base(path) 19 | { 20 | 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/ContactBlockModel.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.ComponentModel.DataAnnotations; 3 | using AlloyTemplates.Models.Pages; 4 | using EPiServer.Web; 5 | using EPiServer.Core; 6 | 7 | namespace AlloyTemplates.Models.ViewModels 8 | { 9 | public class ContactBlockModel 10 | { 11 | [UIHint(UIHint.Image)] 12 | public ContentReference Image { get; set; } 13 | public string Heading { get; set; } 14 | public string LinkText { get; set; } 15 | public IHtmlString LinkUrl { get; set; } 16 | public bool ShowLink { get; set; } 17 | public ContactPage ContactPage { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/ContentRenderingErrorModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EPiServer; 3 | using EPiServer.Core; 4 | 5 | namespace AlloyTemplates.Models.ViewModels 6 | { 7 | public class ContentRenderingErrorModel 8 | { 9 | public ContentRenderingErrorModel(IContentData contentData, Exception exception) 10 | { 11 | var content = contentData as IContent; 12 | if(content != null) 13 | { 14 | ContentName = content.Name; 15 | } 16 | else 17 | { 18 | ContentName = string.Empty; 19 | } 20 | 21 | ContentTypeName = contentData.GetOriginalType().Name; 22 | 23 | Exception = exception; 24 | } 25 | 26 | public string ContentName { get; set; } 27 | public string ContentTypeName { get; set; } 28 | public Exception Exception { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/IPageViewModel.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | using AlloyTemplates.Models.Pages; 3 | 4 | namespace AlloyTemplates.Models.ViewModels 5 | { 6 | /// 7 | /// Defines common characteristics for view models for pages, including properties used by layout files. 8 | /// 9 | /// 10 | /// Views which should handle several page types (T) can use this interface as model type rather than the 11 | /// concrete PageViewModel class, utilizing the that this interface is covariant. 12 | /// 13 | public interface IPageViewModel where T : SitePageData 14 | { 15 | T CurrentPage { get; } 16 | LayoutModel Layout { get; set; } 17 | IContent Section { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/ImageViewModel.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace AlloyTemplates.Models.ViewModels 3 | { 4 | /// 5 | /// View model for the image file 6 | /// 7 | public class ImageViewModel 8 | { 9 | /// 10 | /// Gets or sets the URL to the image. 11 | /// 12 | public string Url { get; set; } 13 | 14 | /// 15 | /// Gets or sets the name of the image. 16 | /// 17 | public string Name { get; set; } 18 | 19 | /// 20 | /// Gets or sets the copyright information of the image. 21 | /// 22 | public string Copyright { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/LayoutModel.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using EPiServer.SpecializedProperties; 4 | using AlloyTemplates.Models.Blocks; 5 | 6 | namespace AlloyTemplates.Models.ViewModels 7 | { 8 | public class LayoutModel 9 | { 10 | public SiteLogotypeBlock Logotype { get; set; } 11 | public IHtmlString LogotypeLinkUrl { get; set; } 12 | public bool HideHeader { get; set; } 13 | public bool HideFooter { get; set; } 14 | public LinkItemCollection ProductPages { get; set; } 15 | public LinkItemCollection CompanyInformationPages { get; set; } 16 | public LinkItemCollection NewsPages { get; set; } 17 | public LinkItemCollection CustomerZonePages { get; set; } 18 | public bool LoggedIn { get; set; } 19 | public MvcHtmlString LoginUrl { get; set; } 20 | public MvcHtmlString LogOutUrl { get; set; } 21 | public MvcHtmlString SearchActionUrl { get; set; } 22 | 23 | public bool IsInReadonlyMode {get;set;} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/PageListModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EPiServer.Core; 3 | using AlloyTemplates.Models.Blocks; 4 | 5 | namespace AlloyTemplates.Models.ViewModels 6 | { 7 | public class PageListModel 8 | { 9 | public PageListModel(PageListBlock block) 10 | { 11 | Heading = block.Heading; 12 | ShowIntroduction = block.IncludeIntroduction; 13 | ShowPublishDate = block.IncludePublishDate; 14 | } 15 | public string Heading { get; set; } 16 | public IEnumerable Pages { get; set; } 17 | public bool ShowIntroduction { get; set; } 18 | public bool ShowPublishDate { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/PageViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EPiServer.Core; 3 | using AlloyTemplates.Models.Pages; 4 | 5 | namespace AlloyTemplates.Models.ViewModels 6 | { 7 | public class PageViewModel : IPageViewModel where T : SitePageData 8 | { 9 | public PageViewModel(T currentPage) 10 | { 11 | CurrentPage = currentPage; 12 | } 13 | 14 | public T CurrentPage { get; private set; } 15 | public LayoutModel Layout { get; set; } 16 | public IContent Section { get; set; } 17 | } 18 | 19 | public static class PageViewModel 20 | { 21 | /// 22 | /// Returns a PageViewModel of type . 23 | /// 24 | /// 25 | /// Convenience method for creating PageViewModels without having to specify the type as methods can use type inference while constructors cannot. 26 | /// 27 | public static PageViewModel Create(T page) where T : SitePageData 28 | { 29 | return new PageViewModel(page); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/PreviewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EPiServer.Core; 3 | using AlloyTemplates.Models.Pages; 4 | 5 | namespace AlloyTemplates.Models.ViewModels 6 | { 7 | public class PreviewModel : PageViewModel 8 | { 9 | public PreviewModel(SitePageData currentPage, IContent previewContent) 10 | : base(currentPage) 11 | { 12 | PreviewContent = previewContent; 13 | Areas = new List(); 14 | } 15 | 16 | public IContent PreviewContent { get; set; } 17 | public List Areas { get; set; } 18 | 19 | public class PreviewArea 20 | { 21 | public bool Supported { get; set; } 22 | public string AreaName { get; set; } 23 | public string AreaTag { get; set; } 24 | public ContentArea ContentArea { get; set; } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/SearchContentModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using AlloyTemplates.Models.Pages; 3 | 4 | namespace AlloyTemplates.Models.ViewModels 5 | { 6 | public class SearchContentModel : PageViewModel 7 | { 8 | public SearchContentModel(SearchPage currentPage) : base(currentPage) 9 | { 10 | } 11 | 12 | public bool SearchServiceDisabled { get; set; } 13 | public string SearchedQuery { get; set; } 14 | public int NumberOfHits { get; set; } 15 | public IEnumerable Hits { get; set; } 16 | 17 | public class SearchHit 18 | { 19 | public string Title { get; set; } 20 | public string Url { get; set; } 21 | public string Excerpt { get; set; } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Models/ViewModels/VideoViewModel.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace AlloyTemplates.Models.ViewModels 3 | { 4 | /// 5 | /// View model for the video file 6 | /// 7 | public class VideoViewModel 8 | { 9 | /// 10 | /// Gets or sets the URL to the video. 11 | /// 12 | public string Url { get; set; } 13 | 14 | /// 15 | /// Gets or sets the URL to a preview image for the video. 16 | /// 17 | public string PreviewImageUrl { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("EPiServer CMS MVC Template package")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyProduct("EPiServer CMS MVC Template package")] 12 | 13 | [assembly: AssemblyCompany("EPiServer AB")] 14 | [assembly: AssemblyCopyright("© 2003-2017 by EPiServer AB. All rights reserved")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: AssemblyConfiguration("")] 18 | 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | 26 | [assembly: CLSCompliant(false)] 27 | [assembly: AssemblyVersion("1.2.0")] 28 | [assembly: AssemblyInformationalVersion("1.2.0-developerbuild")] 29 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Resources/LanguageFiles/ContentTypeNames.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page List 7 | Displays a list of pages, for example to display recent news 8 | 9 | 10 | Teaser 11 | Used to insert a content teaser 12 | 13 | 14 | Logotype 15 | Used to set the logotype for the website 16 | 17 | 18 | Video Player 19 | Used to embed a video player 20 | 21 | 22 | Editorial 23 | Used to add simple editorial content 24 | 25 | 26 | Contact 27 | Used to add contact information 28 | 29 | 30 | Button 31 | Used to add a button with a link 32 | 33 | 34 | Jumbotron 35 | Used to add a large section 36 | 37 | 38 | Article 39 | Used to publish news articles on the website 40 | 41 | 42 | Contact 43 | Used to publish contact details for a specific contact 44 | 45 | 46 | Container Page 47 | Used to logically group pages in the content tree 48 | 49 | 50 | Landing Page 51 | Used to create a page consisting entirely of blocks 52 | 53 | 54 | News Page 55 | Used as a start page for a site's news section and commonly displays a list of the most recent articles 56 | 57 | 58 | Product 59 | Used to present a specific product 60 | 61 | 62 | Search Page 63 | Used to provide on-site search features 64 | 65 | 66 | Start Page 67 | The home page of the website 68 | 69 | 70 | Standard Page 71 | Used mainly for default editorial content such as text and images 72 | 73 | 74 | Image 75 | Used for image files (BMP, GIF, ICO, JPEG, PNG) 76 | 77 | 78 | Video 79 | Used for video files (FLV, MP4, WEBM) 80 | 81 | 82 | Generic File 83 | Used for media which doesn't have a specific content type 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Resources/LanguageFiles/Display.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Mobile 7 | 8 | 9 | Web 10 | 11 | 12 | 13 | Full 14 | Wide 15 | Narrow 16 | 17 | 18 | Standard (1366x768) 19 | iPad horizontal (1024x768) 20 | iPhone vertical (320x568) 21 | Android vertical (480x800) 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Resources/LanguageFiles/EditorHints.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Button Text 11 | 12 | 13 | 14 | 15 | 16 | This block type does not have a renderer for this type of content area. 17 | 18 | 19 | 20 | 21 | 22 | Error while rendering {0} {1} 23 | 24 | 25 | 26 | The block '{0}' when displayed as {1} 27 | The block '{0}' cannot be displayed as {1} 28 | No renderer found for '{0}' 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Resources/LanguageFiles/GroupNames.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Default 9 | 10 | 11 | News 12 | 13 | 14 | Products 15 | 16 | 17 | SEO 18 | 19 | 20 | Site settings 21 | 22 | 23 | Specialized 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Resources/LanguageFiles/Views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | E-mail 8 | Phone 9 | No contact selected 10 | 11 | 12 |
13 | The Company 14 | Customer Zone 15 | Log in 16 | Log out 17 | News & Events 18 | Products 19 |
20 | 21 | 22 | Search 23 | 24 | 25 | 26 | Latest news 27 | News list will be empty since no list root has been set 28 | 29 | 30 | 31 | no 32 | Search result 33 | Search 34 | Your search for 35 | resulted in 36 | hits 37 | EPiServer Search is not configured or is not active for this website. 38 | 39 | 40 |
41 | 42 |
43 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Resources/LanguageFiles/_ReadMe.txt: -------------------------------------------------------------------------------- 1 | All language files in this folder are included in the LocalizationService. 2 | 3 | The path to this folder is configured in EPiServerFramework.config: 4 | 5 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | using EPiServer.Cms.UI.AspNetIdentity; 4 | using Microsoft.AspNet.Identity; 5 | using Microsoft.AspNet.Identity.Owin; 6 | using Microsoft.Owin; 7 | using Microsoft.Owin.Security.Cookies; 8 | using Owin; 9 | 10 | [assembly: OwinStartup(typeof(AlloyTemplates.Startup))] 11 | 12 | namespace AlloyTemplates 13 | { 14 | public class Startup 15 | { 16 | 17 | public void Configuration(IAppBuilder app) 18 | { 19 | 20 | // Add CMS integration for ASP.NET Identity 21 | app.AddCmsAspNetIdentity(); 22 | 23 | // Remove to block registration of administrators 24 | app.UseAdministratorRegistrationPage(() => HttpContext.Current.Request.IsLocal); 25 | 26 | // Use cookie authentication 27 | app.UseCookieAuthentication(new CookieAuthenticationOptions 28 | { 29 | AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 30 | LoginPath = new PathString(Global.LoginPath), 31 | Provider = new CookieAuthenticationProvider 32 | { 33 | // If the "/util/login.aspx" has been used for login otherwise you don't need it you can remove OnApplyRedirect. 34 | OnApplyRedirect = cookieApplyRedirectContext => 35 | { 36 | app.CmsOnCookieApplyRedirect(cookieApplyRedirectContext, cookieApplyRedirectContext.OwinContext.Get>()); 37 | }, 38 | 39 | // Enables the application to validate the security stamp when the user logs in. 40 | // This is a security feature which is used when you change a password or add an external login to your account. 41 | OnValidateIdentity = SecurityStampValidator.OnValidateIdentity, ApplicationUser>( 42 | validateInterval: TimeSpan.FromMinutes(30), 43 | regenerateIdentity: (manager, user) => manager.GenerateUserIdentityAsync(user)) 44 | } 45 | }); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/css/editmode.css: -------------------------------------------------------------------------------- 1 | /* CSS specific to edit mode, such as help content displayed to the editor */ 2 | 3 | .alert-info 4 | { 5 | border-color: #B8C0C5; 6 | color: black; 7 | font-family: Verdana; 8 | font-size: 1em; 9 | font-style: italic; 10 | background-color: #B8C0C5; 11 | box-shadow: 3px 3px 5px #CCC; 12 | text-align: center; 13 | } 14 | 15 | .alert-error p { 16 | text-align: left; 17 | } 18 | 19 | .alert-error .heading { 20 | font-weight: bold; 21 | color: #ff0000; 22 | } 23 | 24 | .alert-error .details { 25 | font-size: 0.8em; 26 | max-height: 100px; 27 | overflow: scroll; 28 | } 29 | 30 | .header.dim { 31 | margin: 2% 0; 32 | opacity: 0.3; 33 | } -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/css/editor.css: -------------------------------------------------------------------------------- 1 | @import "bootstrap.css"; 2 | @import "style.css"; 3 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/css/media.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | /* CSS Document */ 3 | 4 | 5 | 6 | @media (max-width: 979px) { 7 | .span12, .span8, .span6, .span4 { 8 | float: none; 9 | width: auto !important; 10 | } 11 | 12 | .span4 h2, .span6 h2 13 | { 14 | clear:both; 15 | } 16 | 17 | .teaserblock.full h2, .teaserblock.wide h2 { 18 | font-size: 2.5em; 19 | } 20 | 21 | .subHeader 22 | { 23 | width:100% !important; 24 | font-weight:normal !important; 25 | } 26 | 27 | .jumbotronblock .span4 28 | { 29 | display:none; 30 | } 31 | 32 | .media .mediaImg img 33 | { 34 | width:75%;} 35 | 36 | 37 | .hideMyTracks {display:none;} 38 | 39 | } 40 | 41 | 42 | 43 | @media (max-width: 834px) { 44 | 45 | .teaserblock.full h2, .teaserblock.wide h2 { 46 | clear:both; 47 | } 48 | 49 | .teaserblock.full h2, .teaserblock.wide h2, .teaserblock.full p, .teaserblock.wide p { 50 | text-align:center; 51 | } 52 | 53 | .teaserblock.full img, .teaserblock.wide img { 54 | width:75%; 55 | } 56 | 57 | #header .span2 58 | { 59 | float:left; 60 | width:20% !important; 61 | } 62 | 63 | #header .span10 64 | { 65 | float:right; 66 | } 67 | 68 | .span12 .media .mediaText, .span8 .media .mediaText 69 | { 70 | clear:both; 71 | margin:0 2% 5px; 72 | } 73 | 74 | } 75 | 76 | @media (max-width: 767px) { 77 | 78 | h1 79 | { 80 | font-size:35px !important; 81 | } 82 | 83 | h2 84 | { 85 | font-size:20px !important; 86 | } 87 | 88 | .introduction { 89 | font-size:1.2em !important; 90 | margin:2% 0 4% 0; 91 | } 92 | 93 | .alloyMenu .navbar .nav>li>a { 94 | color:#323335; 95 | padding-bottom:12px; 96 | line-height:23px; 97 | text-shadow:none !important; 98 | outline:none; 99 | } 100 | 101 | .alloyMenu .navbar .nav>li>ul>li a:hover { 102 | outline:1px solid; 103 | background:#2980bd; 104 | } 105 | 106 | 107 | .span3 { 108 | width:100% !important; 109 | 110 | } 111 | 112 | .teaserblock img { 113 | width:75%; 114 | } 115 | 116 | .btn-blue { 117 | margin-right:1%; 118 | float:left; 119 | clear:none; 120 | } 121 | 122 | .searchButton { 123 | float:right; 124 | margin-top:7px !important; 125 | } 126 | 127 | .alloyMenu .navbar-search .search-query 128 | { 129 | max-width:70%; 130 | } 131 | 132 | 133 | #header .span2 134 | { 135 | float:left; 136 | width:20% !important; 137 | } 138 | 139 | #header .span10 140 | { 141 | float:right; 142 | } 143 | 144 | } 145 | 146 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/New_FDT_Press_Contact_.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/New_FDT_Press_Contact_.JPG -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/carouselbackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/carouselbackground.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/contact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/contact.jpg -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/exampelspan4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/exampelspan4.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/experts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/experts.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/fallows-media-wide.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/fallows-media-wide.jpg -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/leader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/leader.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/leader2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/leader2.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/logotype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/logotype.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/meet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/meet.jpg -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-article.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-contact.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-product.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-product.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-standard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail-standard.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/page-type-thumbnail.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/person.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/person.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/plan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/plan.jpg -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/play.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/playInactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/playInactive.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/productLandingv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/productLandingv2.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/searchbutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/searchbutton.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/searchbuttonsmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/searchbuttonsmall.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/gfx/track.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/gfx/track.jpg -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/html/error.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | An error occured 4 | 5 | 6 | 9 | Logotype 10 |

When things go wrong...

11 |

This error message can be modified by editing the /Static/html/error.htm file.

12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/jwplayer/player.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/jwplayer/player.swf -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/jwplayer/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/jwplayer/preview.jpg -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Static/jwplayer/video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/Static/jwplayer/video.mp4 -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/ArticlePage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using AlloyTemplates 2 | @model PageViewModel 3 | 4 | @{ Layout = "~/Views/Shared/Layouts/_LeftNavigation.cshtml"; } 5 | 6 |

x.CurrentPage.PageName)>@Model.CurrentPage.PageName

7 |

x.CurrentPage.MetaDescription)>@Model.CurrentPage.MetaDescription

8 |
9 |
x.CurrentPage.MainBody)> 10 | @Html.DisplayFor(m => m.CurrentPage.MainBody) 11 |
12 |
13 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.TwoThirdsWidth }) 14 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/ContactBlock/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model ContactBlockModel 2 | 3 |
4 | @Html.PropertyFor(x => x.Image) 5 |

x.Heading)>@Model.Heading

6 | @Html.PropertyFor(x => x.ContactPage) 7 | @if(Model.ShowLink) 8 | { 9 | x.LinkText)> 10 | @Model.LinkText 11 | 12 | } 13 |
14 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/ImageFile/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model ImageViewModel 2 | 3 | @Model.Name 4 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/LandingPage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using AlloyTemplates 2 | @model PageViewModel 3 |
4 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row equal-height", tag = Global.ContentAreaTags.FullWidth }) 5 |
6 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/NewsPage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using AlloyTemplates 2 | @model PageViewModel 3 | 4 | @{ Layout = "~/Views/Shared/Layouts/_LeftNavigation.cshtml"; } 5 | 6 |

x.CurrentPage.PageName)>@Model.CurrentPage.PageName

7 |

x.CurrentPage.MetaDescription)>@Model.CurrentPage.MetaDescription

8 |
9 |
x.CurrentPage.MainBody)> 10 | @Html.DisplayFor(m => m.CurrentPage.MainBody) 11 |
12 |
13 | @Html.PropertyFor(x => x.CurrentPage.NewsList) 14 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.TwoThirdsWidth }) 15 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/PageListBlock/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model PageListModel 2 | @Html.FullRefreshPropertiesMetaData(new[] { "IncludePublishDate", "IncludeIntroduction", "Count", "SortOrder", "Root", "PageTypeFilter", "CategoryFilter", "Recursive" }) 3 |

x.Heading)>@Model.Heading

4 |
5 | 6 | @foreach(var page in Model.Pages) 7 | { 8 |
9 |

10 | @Html.PageLink(page) 11 |

12 | @if(Model.ShowPublishDate && page.StartPublish.HasValue) 13 | { 14 |

@Html.DisplayFor(x => page.StartPublish)

15 | } 16 | @if(Model.ShowIntroduction && page is SitePageData) 17 | { 18 | var withTeaserText = (SitePageData) page; 19 |

@withTeaserText.TeaserText

20 | } 21 |
22 |
23 | } 24 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Preview/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model PreviewModel 2 | 3 | @foreach(var area in Model.Areas) 4 | { 5 | if(area.Supported) 6 | { 7 | @Html.Partial("TemplateHint", string.Format(@Html.Translate("/preview/heading"), Model.PreviewContent.Name, @Html.Translate(area.AreaName))) 8 |
9 | @Html.DisplayFor(x => area.ContentArea, new {Tag = area.AreaTag}) 10 |
11 | } 12 | else 13 | { 14 | @Html.Partial("TemplateHint", string.Format(@Html.Translate("/preview/norenderer"), Model.PreviewContent.Name, @Html.Translate(area.AreaName))) 15 | } 16 | } 17 | 18 | @if(!Model.Areas.Any()) 19 | { 20 | @Html.Partial("TemplateHint", string.Format(@Html.Translate("/preview/norendereratall"), Model.PreviewContent.Name)) 21 | } 22 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/ProductPage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using AlloyTemplates 2 | @model PageViewModel 3 | 4 | @{ Layout = "~/Views/Shared/Layouts/_TwoPlusOne.cshtml"; } 5 | 6 |

x.CurrentPage.PageName)>@Model.CurrentPage.PageName

7 |

x.CurrentPage.MetaDescription)>@Model.CurrentPage.MetaDescription

8 |
9 |
x.CurrentPage.MainBody)> 10 | @Html.DisplayFor(m => m.CurrentPage.MainBody) 11 |
12 |
13 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.TwoThirdsWidth }) 14 | 15 | @section RelatedContent 16 | { 17 |
x.CurrentPage.PageImage)> 18 | 19 |
20 | 21 |
22 |

x.CurrentPage.PageName)>@Model.CurrentPage.PageName

23 | @Html.PropertyFor(x => x.CurrentPage.UniqueSellingPoints) 24 |
25 | 26 | @Html.PropertyFor(x => x.CurrentPage.RelatedContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.OneThirdWidth }) 27 | } 28 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Register/Index.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | @using System.Web.Optimization 4 | @using AlloyTemplates.Controllers 5 | @model AlloyTemplates.Models.RegisterViewModel 6 | @{ 7 | Layout = ""; 8 | } 9 | 10 | 11 | 12 | Create Administrator Account 13 | @Styles.Render("~/bundles/css") 14 | @Scripts.Render("~/bundles/js") 15 | 16 | 17 | 18 |
19 |
20 |
21 | 22 |

Create Administrator Account

23 | 24 | @using (Html.BeginForm("/", "Register", FormMethod.Post)) 25 | { 26 | @Html.AntiForgeryToken() 27 |
28 | @Html.LabelFor(m => m.Username) 29 | @Html.TextBoxFor(m => m.Username) 30 | @Html.ValidationMessageFor(m => m.Username) 31 |
32 |
33 | @Html.LabelFor(m => m.Email) 34 | @Html.TextBoxFor(m => m.Email) 35 | @Html.ValidationMessageFor(m => m.Email) 36 |
37 |
38 | @Html.LabelFor(m => m.Password) 39 | @Html.PasswordFor(m => m.Password) 40 | @Html.ValidationMessageFor(m => m.Password) 41 |
42 |
43 | @Html.LabelFor(m => m.ConfirmPassword) 44 | @Html.PasswordFor(m => m.ConfirmPassword) 45 | @Html.ValidationMessageFor(m => m.ConfirmPassword) 46 |
47 |
48 | @Html.ValidationMessage(RegisterController.ErrorKey) 49 |
50 |
51 | 52 |
53 | } 54 |
55 |
56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/SearchPage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Editor 2 | @using EPiServer.Security 3 | @model SearchContentModel 4 | 5 | @{ 6 | Layout = "~/Views/Shared/Layouts/_TwoPlusOne.cshtml"; 7 | } 8 | 9 |
10 |
11 | @*We use GET to submit the form to enable bookmarking etc of search results. However, as GET will remove other 12 | query string values not in the form we can't use that in edit mode.*@ 13 | 14 | @{ 15 | using (Html.BeginForm(null, null, PageEditing.PageIsInEditMode ? FormMethod.Post : FormMethod.Get, new { @action = Model.Layout.SearchActionUrl })) 16 | { 17 | 18 | 19 | } 20 | } 21 |
22 |
23 | 24 | @if(Model.Hits != null) 25 | { 26 |
27 |
28 |

@Html.Translate("/searchpagetemplate/result")

29 |

30 | @Html.Translate("/searchpagetemplate/searchfor") @Model.SearchedQuery 31 | @Html.Translate("/searchpagetemplate/resultedin") 32 | @if(Model.NumberOfHits > 0) 33 | { 34 | @Model.NumberOfHits 35 | } 36 | else 37 | { 38 | @Html.Translate("/searchpagetemplate/zero") 39 | } 40 | @Html.Translate("/searchpagetemplate/hits") 41 |

42 |
43 |
44 | 45 |
46 |
47 | @foreach (var hit in Model.Hits) 48 | { 49 |
50 |

@hit.Title

51 |

@hit.Excerpt

52 |
53 |
54 | } 55 |
56 |
57 | 58 | } 59 | 60 | @if(Model.SearchServiceDisabled && PrincipalInfo.HasEditAccess) 61 | { 62 | @Html.Partial("TemplateHint", Html.Translate("/searchpagetemplate/disabled" )) 63 | } 64 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Blocks/ButtonBlock.cshtml: -------------------------------------------------------------------------------- 1 | @model ButtonBlock 2 | 3 | m.ButtonText)> 4 | @{ 5 | var buttonText = string.IsNullOrWhiteSpace(Model.ButtonText) 6 | ? Html.Translate("/blocks/buttonblockcontrol/buttondefaulttext") 7 | : Model.ButtonText; 8 | } 9 | @buttonText 10 | 11 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Blocks/EditorialBlock.cshtml: -------------------------------------------------------------------------------- 1 | @model EditorialBlock 2 | 3 |
x.MainBody)> 4 | @Html.DisplayFor(x => Model.MainBody) 5 |
6 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Blocks/JumbotronBlockWide.cshtml: -------------------------------------------------------------------------------- 1 | @model JumbotronBlock 2 | 3 |
4 |
5 | @Html.PropertyFor(m=>m.Image) 6 |
7 | 8 |
9 |

m.Heading)>@Model.Heading

10 |

m.SubHeading)>@Model.SubHeading

11 | m.ButtonText)>@Model.ButtonText 12 |
13 |
14 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Blocks/NoRenderer.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Shell.Web.Mvc.Html 2 | @Html.Partial("TemplateHint", @Html.Translate("/blocks/norenderer/message")) 3 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Blocks/SiteLogotypeBlock.cshtml: -------------------------------------------------------------------------------- 1 | @model SiteLogotypeBlock 2 | 3 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Blocks/TeaserBlock.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Core 2 | @using AlloyTemplates.Controllers 3 | @model TeaserBlock 4 |
5 | @*Link the teaser block only if a link has been set and not displayed in preview*@ 6 | @using(Html.BeginConditionalLink( 7 | !ContentReference.IsNullOrEmpty(Model.Link) && !(ViewContext.Controller is PreviewController), 8 | Url.PageLinkUrl(Model.Link), 9 | Model.Heading)) 10 | { 11 |

x.Heading)>@Model.Heading

12 |

x.Text)>@Model.Text

13 |
x.Image)>
14 | } 15 | 16 |
17 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Blocks/TeaserBlockWide.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Core 2 | @using AlloyTemplates.Controllers 3 | @model TeaserBlock 4 | 5 |
6 | @*Link the teaser block only if a link has been set and not displayed in preview*@ 7 | @using(Html.BeginConditionalLink( 8 | !ContentReference.IsNullOrEmpty(Model.Link) && !(ViewContext.Controller is PreviewController), 9 | Url.PageLinkUrl(Model.Link), 10 | Model.Heading)) 11 | { 12 |
13 |
x.Image)> 14 | 15 |
16 |
17 |

x.Heading)>@Model.Heading

18 |

x.Text)>@Model.Text

19 |
20 |
21 | } 22 |
23 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Breadcrumbs.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Core 2 | @using EPiServer.Web 3 | @*Helper used as template for a page in the bread crumb, recursively triggering the rendering of the next page*@ 4 | @helper ItemTemplate(HtmlHelpers.MenuItem breadCrumbItem) { 5 | if (breadCrumbItem.Selected) 6 | { 7 | if (breadCrumbItem.Page.HasTemplate() && !breadCrumbItem.Page.ContentLink.CompareToIgnoreWorkID(Model.CurrentPage.ContentLink)) 8 | { 9 | @Html.PageLink(breadCrumbItem.Page) 10 | } 11 | else 12 | { 13 | @breadCrumbItem.Page.PageName 14 | } 15 | if (!breadCrumbItem.Page.ContentLink.CompareToIgnoreWorkID(Model.CurrentPage.ContentLink)) 16 | { 17 | / 18 | @Html.MenuList(breadCrumbItem.Page.ContentLink, ItemTemplate) 19 | } 20 | } 21 | } 22 | 23 |
24 |
25 |
    26 | @Html.ContentLink(SiteDefinition.Current.StartPage) 27 | / 28 | @Html.MenuList(SiteDefinition.Current.StartPage, ItemTemplate, requireVisibleInMenu: false, requirePageTemplate: false) 29 |
30 |
31 |
32 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/DisplayTemplates/ContactPage.cshtml: -------------------------------------------------------------------------------- 1 | @model ContactPage 2 | 3 |

4 | @if(Model != null) 5 | { 6 | @Model.PageName
7 | @Html.Translate("/contact/phone")@: : @Model.Phone
8 | @Html.Translate("/contact/email")@: : @Html.DisplayFor(m => m.Email) 9 | } 10 | else 11 | { 12 | @Html.Translate("/contact/noneselected") 13 | } 14 |

15 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/DisplayTemplates/DateTime.cshtml: -------------------------------------------------------------------------------- 1 | @model DateTime 2 | @Model.ToString("d MMMM yyyy") 3 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/DisplayTemplates/Image.cshtml: -------------------------------------------------------------------------------- 1 | @model EPiServer.Core.ContentReference 2 | @if (Model != null) 3 | { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/DisplayTemplates/StringsCollection.cshtml: -------------------------------------------------------------------------------- 1 | @model IEnumerable 2 | @if(Model != null && Model.Any()) 3 | { 4 |
    5 | @foreach(var stringValue in Model) 6 | { 7 |
  • @stringValue
  • 8 | } 9 |
10 | } 11 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/DisplayTemplates/_ReadMe.txt: -------------------------------------------------------------------------------- 1 | The views in this folder are used when rendering properties using Html.DisplayFor and Html.PropertyFor. 2 | Display templates are selected based on the type name of the property and, optionally, by UIHint and DataType attributes added to the property. 3 | Note that the CMS adds a number of view templates which do not exist in this folder but found through a view engine which the CMS adds at start up. 4 | Those view templates can be found in \Application\Util\Views\Shared\DisplayTemplates. Views in this folder takes precedence meaning 5 | that we can override those templates, which is currently done for content areas. 6 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Footer.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 |
3 | 40 |
41 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Header.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Editor 2 | @using EPiServer.Core 3 | @using EPiServer.Web 4 | @model IPageViewModel 5 |
6 | 51 |
52 | 53 |
54 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Layouts/_LeftNavigation.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 | 3 | @{ Layout = "~/Views/Shared/Layouts/_Root.cshtml"; } 4 | 5 | @{Html.RenderPartial("Breadcrumbs", Model);} 6 | 7 |
8 |
9 |
10 |
11 | @{Html.RenderPartial("SubNavigation", Model);} 12 | @RenderSection("RelatedContent", false) 13 |
14 |
15 |
16 | 17 |
18 | @RenderBody() 19 |
20 |
21 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Layouts/_Root.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Optimization 2 | @using EPiServer.Framework.Web.Mvc.Html 3 | @using AlloyTemplates.Business 4 | @model IPageViewModel 5 | 6 | 7 | 8 | 9 | 10 | 11 | @Model.CurrentPage.MetaTitle 12 | @if (Model.CurrentPage.MetaKeywords != null && Model.CurrentPage.MetaKeywords.Length > 0) 13 | { 14 | 15 | } 16 | @if (!string.IsNullOrWhiteSpace(Model.CurrentPage.MetaDescription)) 17 | { 18 | 19 | } 20 | 21 | @Html.CanonicalLink() 22 | @Html.AlternateLinks() 23 | @Styles.Render("~/bundles/css") 24 | @Scripts.Render("~/bundles/js") 25 | @Html.RequiredClientResources("Header") @*Enable components to require resources. For an example, see the view for VideoBlock.*@ 26 | @Html.RenderEPiServerQuickNavigator() 27 | 28 | 29 | 30 | @if (Model.Layout.IsInReadonlyMode) 31 | { 32 | Html.RenderPartial("Readonly", Model); 33 | } 34 | @Html.FullRefreshPropertiesMetaData() 35 |
36 | @if(!Model.Layout.HideHeader) 37 | { 38 | Html.RenderPartial("Header", Model); 39 | } 40 | @RenderBody() 41 | @if(!Model.Layout.HideFooter) 42 | { 43 | Html.RenderPartial("Footer", Model); 44 | } 45 |
46 | @Html.RequiredClientResources("Footer") 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Layouts/_TwoPlusOne.cshtml: -------------------------------------------------------------------------------- 1 | @using AlloyTemplates 2 | @model IPageViewModel 3 | @{ Layout = "~/Views/Shared/Layouts/_Root.cshtml"; } 4 | 5 | @{Html.RenderPartial("Breadcrumbs");} 6 | 7 |
8 | 9 |
10 | @RenderBody() 11 |
12 | 13 |
14 | @if (IsSectionDefined("RelatedContent")) 15 | { 16 | @RenderSection("RelatedContent") 17 | } 18 | else if (Model.CurrentPage is IHasRelatedContent) 19 | { 20 | @Html.PropertyFor(x => ((IHasRelatedContent)x.CurrentPage).RelatedContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.OneThirdWidth }) 21 | } 22 |
23 |
24 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/PagePartials/ContactPage.cshtml: -------------------------------------------------------------------------------- 1 | @model ContactPage 2 | 3 |
4 | 5 |

@Model.PageName

6 |

@Model.TeaserText

7 |

8 | @Html.Translate("/contact/email"): @Html.DisplayFor(x => x.Email)
9 | @Html.Translate("/contact/phone"): @Model.Phone 10 |

11 |
12 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/PagePartials/ContactPageWide.cshtml: -------------------------------------------------------------------------------- 1 | @model ContactPage 2 |
3 |
4 |
5 | 6 |
7 |

@Model.PageName

8 |

@Model.TeaserText

9 |

10 | @Html.Translate("/contact/email"): @Html.DisplayFor(x => x.Email)
11 | @Html.Translate("/contact/phone"): @Model.Phone 12 |

13 |
14 |
15 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/PagePartials/Page.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Core 2 | @model SitePageData 3 | 4 |
5 | @using(Html.BeginConditionalLink(Model.HasTemplate(), Url.PageLinkUrl(Model), Model.PageName)) 6 | { 7 |

@Model.PageName

8 |

@Model.TeaserText

9 | @Html.DisplayFor(m => m.PageImage) 10 | } 11 |
12 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/PagePartials/PageWide.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Core 2 | @model SitePageData 3 |
4 | @using(Html.BeginConditionalLink(Model.HasTemplate(), Url.PageLinkUrl(Model), Model.PageName)) 5 | { 6 |
7 |
8 | @Html.DisplayFor(m => m.PageImage) 9 |
10 |

@Model.PageName

11 |

@Model.TeaserText

12 |
13 | } 14 |
15 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/Readonly.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 | 3 |
4 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/SubNavigation.cshtml: -------------------------------------------------------------------------------- 1 | @model IPageViewModel 2 | 3 | @helper ItemTemplate(HtmlHelpers.MenuItem firstLevelItem) { 4 | 10 |
11 |
    12 | @Html.MenuList(firstLevelItem.Page.ContentLink, SubLevelItemTemplate) 13 |
14 |
15 | } 16 | 17 | @helper SubLevelItemTemplate(HtmlHelpers.MenuItem subLevelItem) { 18 |
  • 19 | @Html.PageLink(subLevelItem.Page) 20 | @*To show more levels call Html.MenuList recursively here if subLevelItem.Selected == true*@ 21 |
  • 22 | } 23 | 24 |
    25 |
    26 | @if(Model.Section != null) { 27 | @Html.MenuList(Model.Section.ContentLink, ItemTemplate) 28 | } 29 |
    30 |
    31 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/TemplateError.cshtml: -------------------------------------------------------------------------------- 1 | @model ContentRenderingErrorModel 2 |
    3 |

    @string.Format(Html.Translate("/renderingerror/heading"), Model.ContentTypeName, Model.ContentName)

    4 |

    5 | @Model.Exception.Message
    6 | @Model.Exception.StackTrace 7 |

    8 |
    9 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Shared/TemplateHint.cshtml: -------------------------------------------------------------------------------- 1 | @model string 2 |

    @Model

    3 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/StandardPage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using AlloyTemplates 2 | @model PageViewModel 3 | 4 | @{ Layout = "~/Views/Shared/Layouts/_LeftNavigation.cshtml"; } 5 | 6 |

    x.CurrentPage.PageName)>@Model.CurrentPage.PageName

    7 |

    x.CurrentPage.MetaDescription)>@Model.CurrentPage.MetaDescription

    8 |
    9 |
    x.CurrentPage.MainBody)> 10 | @Html.DisplayFor(m => m.CurrentPage.MainBody) 11 |
    12 |
    13 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.TwoThirdsWidth }) 14 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/StartPage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using AlloyTemplates 2 | @model PageViewModel 3 | 4 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row equal-height", tag = Global.ContentAreaTags.FullWidth }) 5 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/VideoFile/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using EPiServer.Framework.Web.Resources 2 | @model VideoViewModel 3 | @{ 4 | ClientResources.RequireScript(Href("~/static/jwplayer/jwplayer.js")); 5 | 6 | //The video element's ID needs to be unique in order for several video blocks and possible the same video block, to work on the same page 7 | var containerId = "video-container-" + Guid.NewGuid().GetHashCode(); 8 | } 9 | @Html.FullRefreshPropertiesMetaData(new []{"Url"}) 10 |
    m.Url)> 11 |
    12 |
    13 |
    14 | 15 | 30 |
    31 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
    7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 36 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/_ReadMe.txt: -------------------------------------------------------------------------------- 1 | View locations in Alloy follows a number of conventions in addition to the default ASP.NET MVC conventions: 2 | * Views for pages and blocks with their own controllers use standard ASP.NET MVC conventions - /.cshtml 3 | * Page types which don't have their own controller are mapped to /Index.cshtml by DefaultPageController 4 | * Views for block types which don't have their own controllers are found in Shared/Blocks 5 | * Partial views for page types which don't have their own controllers for partial requests are found in Shared/PagePartials 6 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Views/_viewstart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/Layouts/_Root.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/episerver.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/favicon.ico: -------------------------------------------------------------------------------- 1 | h( ...>>>Ɋ9777000$$$666!!!### -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Language="C#" Inherits="AlloyTemplates.EPiServerApplication" %> 2 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/module.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/CMS/CMS.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/modules/_protected/CMS/CMS.zip -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/CMS/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/modules/_protected/EPiServer.Cms.TinyMce/EPiServer.Cms.TinyMce.zip -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/EPiServer.Cms.TinyMce/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/EPiServer.Search.Cms/IndexContent.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" AutoEventWireup="false" CodeBehind="IndexContent.aspx.cs" Inherits="EPiServer.UI.Admin.IndexContent" Title="Index Content" %> 2 | 3 | 4 |
    5 |

    <%: Translate("/admin/indexcontent/latestindexing") %> 6 | 7 |

    8 | 9 |
    10 | <%: Translate("/admin/indexcontent/resetinfo") %> 11 |
    12 | 13 |
    14 |
    15 |
    16 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/EPiServer.Search.Cms/module.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/Shell/Shell.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/modules/_protected/Shell/Shell.zip -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modules/_protected/Shell/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modulesbin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/modulesbin/.gitkeep -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/modulesbin/README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/episerver/alloy-mvc-template/58a23bafa64d682adfaf41ceeaf2b13809981bc3/src/Alloy.Mvc.Template/modulesbin/README.txt -------------------------------------------------------------------------------- /src/Alloy.Mvc.Template/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | --------------------------------------------------------------------------------