Select template for a page.

Topics: Administration, Customizing Orchard, Writing modules, Writing themes
Oct 23, 2011 at 11:36 AM
Edited Oct 23, 2011 at 2:25 PM

How to select pagetemplate when creating or edit a page.

In my websites I always want to ease templating when creating pages. How could that be available in Orchard?
By adding a template selector, I now can select any layout file that I created in my theme.

I searched Internet and found this page: http://www.downplay.co.uk/orchard/layout-selector-module , and this is was a good starting point. I installed the module.
The problem here was that this doesn't show more than the Default layout. I changed the DefaultLayoutAlternatesProvider.cs with the code below.
I also added a reference to Orchard.Themes to let it search all templates from the current theme.

It now lets me choose any template file from a dropdown list.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using Orchard.Themes.Services;

namespace Downplay.Orchard.LayoutSelector.Services
{
    public class DefaultLayoutAlternatesProvider : ILayoutAlternatesProvider
    {
        private readonly ISiteThemeService _siteThemeService;
        public DefaultLayoutAlternatesProvider(ISiteThemeService siteThemeService)
        {
            _siteThemeService = siteThemeService;
        }

        public IEnumerable<string> GetLayouts()
        {
            List<string> t = new List<string>();

            foreach (string template in Directory.EnumerateFiles(HttpContext.Current.Server.MapPath(
                        string.Format("~/Themes/{0}/Views/", _siteThemeService.GetCurrentThemeName())),"*.cshtml"))
            {
                var f = new FileInfo(template);

                if (f.Name.StartsWith("Layout"))
                {
                    string fname = f.Name.Replace("Layout", "").Replace("-", "").Replace(".cshtml", "");
                   
                    if (fname.Length > 0)
                        t.Add(fname);
                    else
                        t.Add("Default");
                }
            }

            return t;
        }
    }
}
Oct 29, 2011 at 10:11 PM

rick,

Thanks for this, I was hoping not to have to write my own implementation. I've surely saved myself a good deal of time -- Thanks for the share my friend.

Oct 30, 2011 at 7:36 AM

Yeah.. I found this implementation really useful, and use it all the time. 
Yesterday I also started to build a Css/View editor where I can edit css files and View for a theme. It's almost done, so when it's done I will share this module also.

Oct 30, 2011 at 10:14 AM

Hi Rick, I wrote the Layout Selector module - thanks for your post, that's a really nice modification. I was meaning to improve the module more, but I actually don't use it myself, I've ended up using Bertrand's theme switcher generally when I need multiple layouts, since having a whole replacement theme lets you override more than just the Layout. Still, there are certainly scenarios where the layout selector is a more straightforward option!

Oct 30, 2011 at 1:51 PM

I also added a couple of small enhancements to the module, modifications are in bold:

1) Persist the current selected layout in the drop-down. (LayoutSelector.cshtml)

<fieldset>
<legend>Location</legend>
<div>@Html.LabelFor(o => o.LayoutName, @T("Layout"))</div>
<div>@Html.DropDownListFor(o => o.LayoutName, Model.AvailableLayouts.Select(c => new SelectListItem() { Text = c, Value = (c=="Default")?"":c, Selected = (c == Model.LayoutName) }))</div>
</fieldset>

2) Populate the layout drop-down in alphabetical order. (DefaultLayoutAlternatesProvider.cs)

public IEnumerable<string> GetLayouts()
{
....
return t.OrderBy(x => x);
}
 

Oct 31, 2011 at 5:11 AM
randompete wrote:

Hi Rick, I wrote the Layout Selector module - thanks for your post, that's a really nice modification. I was meaning to improve the module more, but I actually don't use it myself, I've ended up using Bertrand's theme switcher generally when I need multiple layouts, since having a whole replacement theme lets you override more than just the Layout. Still, there are certainly scenarios where the layout selector is a more straightforward option!


This is why I love Codeplex :-)

Nov 3, 2011 at 5:00 AM
Edited Nov 3, 2011 at 8:51 AM

randompete. I was thinking, maybe we can share this feature in an update of your module on Orchard Gallery. I would like to be available from the Gallery in backend. Or I can upload the changes and make a reference to you. I have account M33 within Orchard Gallery.

If you would like to edit your files in your theme like, css, js and razor views, you can check out my new module here: http://www.orchardproject.net/gallery/List/Modules/Orchard.Module.M33.SystemEditor/1.3.6


Nov 3, 2011 at 3:25 PM

Yes, it really should be updated (jhowe11's changes should also go in) - at one point I was thinking of combining it with some other modules, but really it's fine as a standalone feature. Maybe I should set up a Codeplex project...

Nov 3, 2011 at 4:45 PM
randompete wrote:

Yes, it really should be updated (jhowe11's changes should also go in) - at one point I was thinking of combining it with some other modules, but really it's fine as a standalone feature. Maybe I should set up a Codeplex project...


Sounds great! If you setup a codeplex project, I can help out.
Cheers!!

Nov 16, 2011 at 1:44 PM
rickardmagnusson wrote:

Sounds great! If you setup a codeplex project, I can help out.
Cheers!!

Right - sorry for nearly letting this thread fade away!

I've set up the new project: http://layoutselector.codeplex.com

I applied the changes from this thread, and made some additional refactorings. Seeing the quality of my code just from earlier this year it's actually quite amazing how much I've learned :)

Additionally I enhanced rickard's work so it will also check the BaseTheme property and look for additional layouts, recursively.

If anyone who's following this can test the new version that would be great. Rickard, I'll give you project rights on Codeplex and Orchard Gallery, if you have time to update the gallery package (after testing of course!) that would be amazing.

Jan 13, 2012 at 2:51 PM

Love the idea of the Layout Selector.  Did the latest get tested in Orchard 1.3?  I have the module installed.  I have the Layout Selector added to the Pages content type.  When I create or edit a page I get the dropdown list that is populated with my existing Layout files.  When the pages are rendered though they are just using the default layout and not the one I've selected.  I'm sure I just missing one little detail.  Can someone help?

Jan 13, 2012 at 3:03 PM

The Gallery version is very outdated (March) ... I was hoping rickard would update it ;) Have you tried the latest source code from http://layoutselector.codeplex.com?

Jan 13, 2012 at 3:28 PM
randompete wrote:

The Gallery version is very outdated (March) ... I was hoping rickard would update it ;) Have you tried the latest source code from http://layoutselector.codeplex.com?

Yes, I am using version 0.3.

I had a layout file named "Layout-two-column.cshtml" and "two column" was displayed in the dropdown but selecting it did not result in that file being used.

I changed the name of the file to "Layout-twoColumn.cshtml and "twoColumn" now shows in the dropdown.  Selecting it does get the desired results.

I guess I was interfering with the naming convention used for Alternates.

Jan 13, 2012 at 3:35 PM

It looks like a bug in Layout Selector, rickard added a dash-to-space replacement but I guess there's no reverse replacement ... file a workitem :)

Sep 4, 2014 at 5:31 PM
We are using Orchard 1.8 to develop a CMS based website and on a local dev box with a Visual Studio 2013 project file. We are using SQL Server 2012 as the DB .

We have installed DownPlay Design’s Layout Selector - version 0.3. It works fine on the local Dev box with the VS2013 Orchard project.

We published the Orchard.Web project to a production server using a VS file system publish and imported the DB from the dev environment into the production SQL Server DB.

Some of the site seems to run, however it is always using Layout.cshtml rather than specific layout pages (Layout-HomePage.cshtml, Layout-AboutPage.cshtml, etc...) that are supposed to be selected by the Layout Selector.

The Layout Selector DOES NOT show up on the page editor in the Orchard admin panel, even though the module shows as installed in Orchard and as a Feature. Also, the page content definition for pages shows the "Layout Selector" part.

Some of the code seems to be in the Modules folder on the production server (there are some folder file differences between the dev box and the production box), when one edits a page, the DDL to select the layout does not appear in the page editor.

Folder tree for Dev Box: \Modules\Downplay.Orchard.LayoutSelector
|    - Downplay.Orchard.LayoutSelector.csproj
|    - Downplay.Orchard.LayoutSelector.csproj.user
|    - Downplay.Orchard.LayoutSelector.csproj.vspscc
|    - Downplay.Orchard.LayoutSelector_DirList.txt
|    - Migrations.cs
|    - Module.txt
|    - placement.info
|    - Web.config
+_ bin
|  |    - Orchard.Core.dll
|  |    - Orchard.Framework.dll
|  |    - Orchard.Themes.dll
|  |    - System.Web.Mvc.dll
+_ Controllers
+_ Drivers
|  |    - LayoutSelectorPartDriver.cs
+_ Handlers
|  |    - LayoutSelectorPartHandler.cs
+_ Models
|  |    - LayoutSelectorPart.cs
|  |    - LayoutSelectorPartRecord.cs
+_ obj
|  +_ Debug
|       - DesignTimeResolveAssemblyReferencesInput.cache
|       - Downplay.Orchard.LayoutSelector.csproj.FileListAbs
|       - Downplay.Orchard.LayoutSelector.csprojResolveAssem
|     +_ TempPE
+_ Properties
|  |    - AssemblyInfo.cs
+_ Scripts
|  |    - Web.config
+_ Services
|  |    - DefaultLayoutAlternatesProvider.cs
|  |    - ILayoutAlternatesProvider.cs
|  |    - ILayoutSelectorService.cs
|  |    - LayoutSelectorService.cs
|  |    - ThemeLayoutAlternatesProvider.cs
+_ Styles
|  |    - Web.config
+_ Views
     - Web.config
   +_ EditorTemplates
      +_ Parts
         |    - LayoutSelector.cshtml
Folder tree for Production Box: Modules\Downplay.Orchard.LayoutSelector
|    - Module.txt
|    - placement.info
|    - Web.config
+_ Scripts
|  |    - Web.config
+_ Styles
|  |    - Web.config
+_ Views
     - Web.config
   +_ EditorTemplates
      +_ Parts
         |    - LayoutSelector.cshtml

Any one know what we should look for to troubleshoot or how to fix? We need to be able to select a layout for each page and this module did it well; at least it did on the development.

Thanks in advance.
Jan 2, 2015 at 11:31 PM
I was having the same issue as engelhk. I fixed it by changing the target framework of the Layout Selector project to 4.5 in VS and then published again. It started showing up after that.