1
votes

I am using Orchard CMS and the Bootstrap theme. I have been trying to use the carousel built in bootstrap to work as shown in the following blog post: http://www.stevetaylor.me.uk/image-carousel-using-twitter-bootstrap-and-orchard-cms-projections. I have followed the tutorial but i cannot get my new layout file to appear in the query under grid and html list. I believe i have copied the code word for word but still can get it to work. Anybody please help with this as think it would be a great feature to add. if i get it to work i will request it gets added to the bootstrap theme here: http://orchardbootstrap.codeplex.com/

See code below:

CarouselLayoutForm.cs

using System;
using Orchard.DisplayManagement;
using Orchard.Forms.Services;
using Orchard.Localization;

namespace Orchard.Projections.Providers.Layouts {

public class CarouselLayoutForms : IFormProvider {
    protected dynamic Shape { get; set; }
    public Localizer T { get; set; }

    public CarouselLayoutForms(
        IShapeFactory shapeFactory) {
        Shape = shapeFactory;
        T = NullLocalizer.Instance;
    }

    public void Describe(DescribeContext context) {
        Func<IShapeFactory, object> form =
            shape => {

                var f = Shape.Form(
                    Id: "CarouselLayout",                        
                    _HtmlProperties: Shape.Fieldset(
                        Title: T("Html properties"), 
                        _ListId: Shape.TextBox(
                            Id: "outer-grid-id", Name: "OuterDivId",
                            Title: T("Outer div id"),
                            Description: T("The id to provide on the div element."),
                            Classes: new[] { "textMedium", "tokenized" }
                            ),
                        _ListClass: Shape.TextBox(
                            Id: "outer-div-class", Name: "OuterDivClass",
                            Title: T("Outer div class"),
                            Description: T("The class to provide on the div element."),
                            Classes: new[] { "textMedium", "tokenized" }
                            ),
                        _InnerClass: Shape.TextBox(
                            Id: "inner-div-class", Name: "InnerDivClass",
                            Title: T("Inner div class"),
                            Description: T("The class to provide on the inner div element."),
                            Classes: new[] { "textMedium", "tokenized" }
                            ),
                         _FirstItemClass: Shape.TextBox(
                            Id: "first-item-class", Name: "FirstItemClass",
                            Title: T("First item class"),
                            Description: T("The class to provide on the first item element."),
                            Classes: new[] { "textMedium", "tokenized" }
                            ),
                        _ItemClass: Shape.TextBox(
                            Id: "item-class", Name: "ItemClass",
                            Title: T("Item class"),
                            Description: T("The class to provide on the item element."),
                            Classes: new[] { "textMedium", "tokenized" }
                            )
                        )
                    );

                return f;
            };

        context.Form("CarouselLayout", form);

    }
}
   /*
public class CarouselLayoutFormsValitator : FormHandler {
    public Localizer T { get; set; }

    public override void Validating(ValidatingContext context) {
        if (context.FormName == "CarouselLayout") {
            if (context.ValueProvider.GetValue("Alignment") == null) {
                context.ModelState.AddModelError("Alignment", T("The field Alignment is required.").Text);
            }

            if (context.ValueProvider.GetValue("Columns") == null) {
                context.ModelState.AddModelError("Columns", T("The field Columns/Lines is required.").Text);
            }
            else {
                int value;
                if (!Int32.TryParse(context.ValueProvider.GetValue("Columns").AttemptedValue, out value)) {
                    context.ModelState.AddModelError("Columns", T("The field Columns/Lines must be a valid number.").Text);
                }
            }
        }
    }
}
*/

}

CarouselLayout.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Projections.Descriptors.Layout;
using Orchard.Projections.Models;
using Orchard.Projections.Services;

namespace Orchard.Projections.Providers.Layouts {
public class CarouselLayout : ILayoutProvider {
    private readonly IContentManager _contentManager;
    protected dynamic Shape { get; set; }

    public CarouselLayout(IShapeFactory shapeFactory, IContentManager contentManager) {
        _contentManager = contentManager;
        Shape = shapeFactory;
        T = NullLocalizer.Instance;
    }

    public Localizer T { get; set; }

    public void Describe(DescribeLayoutContext describe) {
        describe.For("Html", T("Html"),T("Html Layouts"))
            .Element("Carousel", T("Carousel"), T("Organizes content items in a carousel."),
                DisplayLayout,
                RenderLayout,
                "CarouselLayout"
            );
    }

    public dynamic RenderLayout(LayoutContext context, IEnumerable<LayoutComponentResult> layoutComponentResults) {

        string outerDivClass = context.state.outerDivClass;
        string OuterDivId = context.state.OuterDivID;
        string innerDivClass = context.state.InnerDicClass;
        string firstItemClass = context.state.FirstItemClass;
        string itemClass = context.state.ItemClass;

        IEnumerable<dynamic> shapes =
           context.LayoutRecord.Display == (int)LayoutRecord.Displays.Content
               ? layoutComponentResults.Select(x => _contentManager.BuildDisplay(x.ContentItem, context.LayoutRecord.DisplayType))
               : layoutComponentResults.Select(x => x.Properties);

        return Shape.Carousel(Id: outerDivId, Items: shapes, OuterClasses: new[] { outerDivClass }, 
                InnerClasses: new[] {innerDivClass}, FirstItemClasses: new[] {firstItemClass}, ItemClasses: new[] {itemClass});
    }
}
}

LayoutShapes.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Mvc.Html;
using Orchard.Utility.Extensions;

namespace Orchard.Projections.Providers.Layouts {
public class LayoutShapes : IDependency {
    public LayoutShapes() {
        T = NullLocalizer.Instance;
    }

    public Localizer T { get; set; }

    [Shape]
    public void Carousel(dynamic Display, TextWriter Output, HtmlHelper Html, string Id, IEnumerable<dynamic> Items, 
                        IEnumerable<string> OuterClasses, IDictionary<string, string> OuterAttributes,
                        IEnumerable<string> InnerClasses, IDictionary<string, string> InnerAttributes, 
                        IEnumerable<string> FirstItemClasses, IDictionary<string, string> FirstItemAttributes, IEnumerable<string> ItemClasses,  IDictionary<string, string> ItemAttributes ) 
    {            
        if (Items == null) return;

        var items = Items.ToList();
        var itemsCount = items.Count;

        if (itemsCount < 1) return;

        var outerDivTag = GetTagBuilder("div", Id, OuterClasses, OuterAttributes);
        var innerDivTag = GetTagBuilder("div", string.Empty, InnerClasses, InnerAttributes);
        var firstItemTag = GetTagBuilder("div", string.Empty, FirstItemClasses, FirstItemAttributes);
        var itemTag = GetTagBuilder("div", string.Empty, ItemClasses, ItemAttributes);

        Output.Write(outerDivTag.ToString(TagRenderMode.StartTag));
        Output.Write(innerDivTag.ToString(TagRenderMode.StartTag));

        int i = 0;

        foreach (var item in items)
        {
            if (i== 0)
               Output.Write(firstItemTag.ToString(TagRenderMode.StartTag)); 
            else
               Output.Write(itemTag.ToString(TagRenderMode.StartTag)); 

            Output.Write(Display(item));
            Output.Write(itemTag.ToString(TagRenderMode.EndTag));
            i++;
        }

        Output.Write(innerDivTag.ToString(TagRenderMode.EndTag));

        Output.Write("<a href=\"#{0}\" class=\"carousel-control left\" data-slide=\"prev\">&lsaquo;</a>",id);
        Output.Write("<a href=\"#{0}\" class=\"carousel-control right\" data-slide=\"next\">&lsaquo;</a>",id);

        Output.Write(outerDivTag.ToString(TagRenderMode.EndTag));

        Output.Write("<script>$(function () {$('"+ Id +"').carousel();}); </script>");

    }

    static TagBuilder GetTagBuilder(string tagName, string id, IEnumerable<string> classes, IDictionary<string, string> attributes) {
        var tagBuilder = new TagBuilder(tagName);
        tagBuilder.MergeAttributes(attributes, false);
        foreach (var cssClass in classes ?? Enumerable.Empty<string>())
            tagBuilder.AddCssClass(cssClass);
        if (!string.IsNullOrWhiteSpace(id))
            tagBuilder.GenerateId(id);
        return tagBuilder;
    }

}
}
2
Did you enable the feature? Do you see any exceptions in app_data\logs?Bertrand Le Roy
i am using orchard 1.6 and the projector module is already enabled. The log files are empty in the folder you specified. Thanks for your help.Jonnymaboy
bertrand le roy i have added compile references and module reference to forms and projections in the theme by editing the .csproj file. Now i get errors in the log file: Cannot implicitly convert type 'Orchard.Themes.Models.ThemeEntry' to 'Orchard.ContentManagement.ContentPart'. Please advise if possibleJonnymaboy
I wasn't talking about the projection module, but about your module, the one where you defined this layout.Bertrand Le Roy
For the implicit conversion thing, that's more a C# question. Try to explicitly cast.Bertrand Le Roy

2 Answers

0
votes

Did you add your code to the module Orchard.Projections as explained? You need to add the files in Visual Studio and to save the project for them to be included in the .csproj (unless, the dynamic compilation won't take the files in account), or you can build the module.

0
votes

You are missing the definition for DisplayLayout() in your CarouselLayou.cs file:

    public LocalizedString DisplayLayout(LayoutContext context)
    {
        string columns = context.State.Columns;
        bool horizontal = Convert.ToString(context.State.Alignment) != "vertical";

        return horizontal
                   ? T("{0} columns grid", columns)
                   : T("{0} lines grid", columns);
    }

Also, variable 'id' in LayourShapes.cs should be 'Id', and there are other incorrect casings in the declarations:

string outerDivClass = context.state.outerDivClass;
string OuterDivId = context.state.OuterDivID;
string innerDivClass = context.state.InnerDicClass;
string firstItemClass = context.state.FirstItemClass;
string itemClass = context.state.ItemClass;

should be:

string outerDivClass = context.State.OuterDivClass;
string outerDivId = context.State.OuterDivID;
string innerDivClass = context.State.InnerDicClass;
string firstItemClass = context.State.FirstItemClass;
string itemClass = context.State.ItemClass;