Creating a rotating image gallery in Orchard CMS

by Arra Derderian 2. December 2011 00:33

dreamfar-gallery

A rotating image gallery is something many sites have these days. Most people employ this functionality by adding some jQuery code to rotate through a set list of images or simply by adding a plugin already built. When developing sites in Orchard CMS it is important to make as much content as you can editable by your clients so they can easily manipulate the website when needed. Clients often times want to change out homepage images and will need a way to do this through the dashboard.

There are seven steps to this tutorial:

1. Create your new content type "Banner Image".

2. Creat your new content type "Image Gallery".

3. Create the "Home Page Gallery" content type.

4. Map the "Home Page Gallery" to a container widget that sits on the homepage layer.

5. Add some Banner Images.

6. Create a template to override the rendering.

7. Use some jQuery to animate and rotate the images.

Please follow these steps in this order.

Step 1 : Create new content type of "Banner Image".

First you will need to install the ImageFile module so you can benefit from this new content part. Once you have installed it browse to Content>Content Types. Create a new Content Type called "BannerImage". Add two content fields to this type. The first will be a TextField and call it "ImageText". Next, add an ImageField called "ImageFile". It should also have the following content parts : Common, Containable, Publish Later, Custom Properties, and Title. Click Save.

The ImageText field will hold some descriptive text to show over the image. (Note: You may also add another field called "ImageLink" if you want this text to be clickable and perhaps take you to a specific page on the site.) The second field called ImageLink is responsible for choosing the associated image. Lastly, the Custom Properties field will be used for storing the display order of the images.

Step 2 : Create new content type of "Image Gallery".

Go and create another content type entitled "ImageGallery". This type will require the following content parts : Common, Container, Publish Later, Title, Admin Menu. Click Save.

Step 3 : Create the "Home Page Gallery" content type.

You will notice that now in the dashboard you have an a new type called "Image Gallery" under the New > tab of the dashboard. Select this type and create a new content item entitled "Home Page Gallery". For "Contains" select BannerImage. Set order by to be Custom 1. Lastly, set the menu text to say "Home Page Gallery".

Step 4 : Map the "Image Gallery" to a container widget that sits on the homepage layer.

Browse to Widgets. Depending on the style of your site you will want to put the gallery widget where it belong based on your zones. For this example lets put it in the Content zone and make sure you are on the homepage layer. (Unless you want this to appear somewhere else on the site.) Choose the widget type to be container widget. Title the widget "Image Rotation" and for the "Show Items From This List" property choose Image Gallery : Home Page Gallery. Selec to "Order By" Custom 1 and allow as many images as you think the client will need.

Step 5 : Add some Banner Images.

You now have the structure in place to begin adding content for your gallery. Find your new admin menu item entitled "Home Page Gallery" in the dashboard. Select this option and choose to add a new BannerImage. It will already be set to add the item to your new content type. You will have the option to set a title for the image, upload your image, and set your sort order for the image as well. Go ahead and add a few new content items! Don't forget to publish them!

At this point you may browse to your site's homepage and you should see all of your images and text rendered on top of each other on your homepage. This is the default rendering for a list of items. 

Step 6 :  Create a template to override the rendering.

We obviously don't want this to be how are homepage looks, so we want to add a new template so we can control the rendering to fit our gallery goal. Begin by adding a new template in your themes directory. Under Themes\YourTheme\Views add a new file called "Content-BannerImage.Summary.cshtml". The contents of this file will control the rendering of your gallery.

Here are the contents I used, you may choose to use different markup.

 

@using Orchard.ContentManagement;

@using Orchard.Core.Routable.Models;

@using Orchard.Core.Common.Models;


@{  

    var bannerImage = ((ContentItem)Model.ContentItem).Parts.SelectMany(p => p.Fields).Where(f => f.Name == "ImageFile").First().Storage.Get<string>(null);

    var bannerText = ((ContentItem)Model.ContentItem).Parts.SelectMany(p => p.Fields).Where(f => f.Name == "ImageText").First().Storage.Get<string>(null);

}

@if (HasText(bannerImage))

{   

    <div class="gallery" style="display:none;">

        <img src="@Href(bannerImage)" height="460" width="695" />

        <div class="gallery-overlay">@bannerText</div>

        <div class="gallery-links"></div>

    </div>

}

Save this new file and refresh your site's homepage. You should now see no images being rendered. This is because by default we have set the div(class=gallery) to have a display=none. You can FireBug the page and make sure your images are rendered properly with the new markup around them if you like.

Step 7 : Use some jQuery to animate and rotate the images.

The final step is add some scripting to rotate these images and populate some clickable links for the user to paginate through the gallery. Secondly, these image links will provide the user a status of where they are in the gallery. I am going to attach my script file I used here so you can just pull it down and include it in your Theme. Don't forget to put it in your Themes\YourTheme\Scripts and reference it in your Layout.cshtml file. 

Here is the file:

base.js (1.75 kb)

You will also need some styling help to integrate the correct look and feel on the gallery images and buttons/images to use as well. Here is some links to existing sites we did that utilize this methodology:

Triton Digital

Dover PTO

I hope article helps when trying to create this functionality on your own site's. Any questions or problems, feel free to ask! I think packaging this up into a module will be the next step for me, but it helps to understand how to do it for yourself as well.

Tags: , , ,

Engineering | jquery | orchard cms

Node.js and Web 3.0

by Arra Derderian 14. May 2011 16:54

The other day I read an article on Mashable about a new JS library called Now.js. This article called Will Node Power the Next Twitter? NowJS Is Betting On It discussed how many believe the next phase of the web, Web 3.0, will be powered by servers running on libraries such as Node.js. I watched the video included in the article that depicted a user setting up a node server and then setting up a now.js chat room. It was a cool video that showed a new concept of having server and client both running the same code and managing the users connected to the chat.

NowJS Introduction: Simple Chat Server in 12 Lines of Code from NowJS on Vimeo.

After watching the video I was did some reading around the web at various sites trying to find the pros and cons of a JavaScript based web server. To me it seemed like the argument for node.js was that it is event based where traditional web servers are synchronous in nature. Node.js can handle many requests because they delegate the work and wait for a callback rather than waiting for the request to finish. This sounds like an optimal way to handle requests, but isn't it still only a good way to handle requests? Won't the server eventually be just handling requests so fast and pushing off the work that the system will slow down? Sure the initial request will get through quickly but the time of response will be longer as request amounts increase.

A couple other things I find it hard to believe is that all of the benchmarks done out there are indicating node.js blows away all of the traditional web server technologies. For starters, a compiled program should run quicker than an interpreted language. I know Google's V8 is lightning fast for a JS interpreter but it is just a basic concept I figure has to be brought up. Secondly, while node.js is putting out these great benchmark times it is important to remember it does not contain the modules that a Microsoft IIS has. Security, request filtering, error handling, and much more and not included. Writing out the headers of the document being returned is a manual step as shown here. I am still searching for some of the benchmarks and will post them as I find them.

Anyone who can comment on my questions here would be great. I would like to hear peoples thoughts. In the meantime I am going to try and download some of the pre-compiled libraries of node.js and get it going on Windows. Also I saw another cool walk through of implementing node.js in Windows Azure Cloud. Check them out with me and lets see what Web 3.0 is all about.

Tags: , , , ,

Cloud Computing | Engineering | jquery | Technology

.NET 4.0 thinking about the client side

by Arra Derderian 6. November 2010 23:25

I have always utilized the repeater control when I need a flexible lightweight data binding control. Based on some of the new functionality in .NET 4.0 I may be switching to the ListView control.

In .NET 4.0 the ListView control has a property called ClientIDRowSuffix where you can specify it to automatically generate unique ID's for elements that are dynamically created by the ListView. This is great because using AJAX to update rows or load new rows you need a unique identifier for each element and you would always have to build this logic in on your own. Microsoft also built in the ability to have .NET generate client ID's that are closer to what you actually specify than the automatically generated ID's of previous versions. You should specify ClientIDRowSuffix="ID" and ClientIDMode="Predictable" to get this to work. You will then be given ID's on your elements that are uniquely based on the ID property of your datasource and the ListView ID + Control ID.

These new features are great for client side manipulation and allow you to target elements easily by ID using a library like jQuery. Having to target elements by class is slower and also mixes logic with presentation. 

Also, the ListView control allows a lot more templates to be defined for scenarios such as EmptyItems, SelectedItems, and InsertingItems. Support for grouping, sorting, and pagination is very good as well. I especially like that instead of declaring header, item, and footer templates you declare a layout template that specifies how to render the surrounding markup of the items. This lets you not have broken table or list structures in your code that produce warnings.

I think it might be time to give up the old repeater and move on.

 

 

 

Tags: , ,

ASP.NET | jquery | Technology

jQuery ID Selector for ASP.NET Controls

by Arra Derderian 27. October 2010 00:23

jquery

Having to select .NET controls via jQuery is easy because you can specify a unique class name for whatever control you want to select and use the "." selector to find that element on the client side. The problem is the class selector is slower than the id selector and it also breaks the rules of separating functionality and design. You end up with class names that may get stripped out by a CSSS developer later on. You also have the extra markup required on every element for this class name.

Hoping to find some way to select elements based on .NET id I Googled around and found the following code which adds a custom selector to the jQuery ":" selector called "asp".

Solution 1

jQuery.expr[':'].asp = function (elem, i, match) { return (elem.id && elem.id.match(match[3] + "$")); };

Here we return any elements that have an ID and secondly, end with the id string specified. You would call this code like this:

Calling It

$(":asp(SelectTextBox)")

After looking at this I noticed that because we are using the "EndsWith" regex match that we will get any control with an ID that ends with "SelectTextBox". This is a problem because if we have a control called "NewSelectTextBox" and then another called "SelectTextBox" they both will be selected. So I looked at the .NET markup generated from these two controls existing on the same page and saw that an underscore("_") was preceding the final controls .NET ID on the client. I then came up with solution #2.

Solution 2

jQuery.expr[':'].asp = function (elem, i, match) { return (elem.id && elem.id.match("_" + match[3] + "$")); };

Seems like an easy fix. This would eliminate any similarly named controls. Well there is one last problem that I am still working on getting around. That is that if you nest one of these textboxes in a custom control for example, it will print out the textbox id ending with the same "_ID" and add the parent controls name to the front of it. If there is two of these custom controls on a page you will have to unique controls on the page, but they will both end with "_SameName". I am still wondering how to solve this issue. Perhaps we add more logic to the custom selector to only return the first found element? What do people think? I mean in these situations you would probably want multiple controls returned anyways because you would be modifying all the items or you could combine the selector with a ":first" if you wanted. You probably would end up generating some sort of extra markup for uniqueness as well because the items will most likely represent an ID in your database. Anyways, I thought I would share this and see if anyone had any ideas on it.

Tags: , , , ,

ASP.NET | Engineering | jquery | Technology