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

Orchard Gallery changes URL after Azure move

by Arra Derderian 29. November 2011 00:19

If you are a fan of downloading and installing Modules from the Orchard gallery you will notice the gallery feed recently broke. The new URL is  http://packages.orchardproject.net/FeedService.svc/

Just modify this in Dashboard > Settings > Gallery

Tags:

Azure | orchard cms

Cloud Construct contributes Post File Orchard Module

by Arra Derderian 29. October 2011 22:52

We recently completed a module for uploading a file along with a standard form post. This was code based on the Contact module done by Contrib which we modified to send a file up to the server and drop it in the media folder. Before we accept the file we check for file type and size to make sure nothing malicious is sent up to the server.

Feel free to download the module from Orchard's gallery site : Cloud Construct Post File

The module is themed as a resume submission form so people can submit some information along with their resume. You can add the form as a widget or a complete page on your site. All of the submissions are available through a page in the admin dashboard that lets you view all of the resumes submitted to the site. Secondly, an email is sent out to the email address on file and the resume attached as well.

You can see above that you can easily access the upload file and all the information sent along with the form. There is also some jquery JavaScript code in the module that grabs the code's article header

$("#JobName").val($("article.career h3").html());

This captures the text in the article header and puts it in a hidden field on the page to also be submitted with the request. That way we can associate a job with a submission. I realize this is a little bit of a hack but until I can figure out the Global token piece of Orchard 1.3 or another way to access information about related modules I will need to keep this. Perhaps it was better suited as a Content Part that could be added to Content Type of Career.


Tags: , , ,

orchard cms

Orchard 1.3 is Released!

by Arra Derderian 4. October 2011 17:05

 

 

Orchard 1.3 fixes bugs, improves performance and introduces the following features:

  •  Content item preview
  • Markdown support
  • Delete content types and parts
  • Title part enables non-routable types to have a title
  • Common added by default to content types
  • Rules: trigger custom actions triggered by events
  • Forms API: create forms from code
  • Tokens: system-wide variables
  • New content manager methods: part eager loading, get multiple items by ids in one query
  • Task Lease API: creates server affinities for background tasks on web farms and cloud platforms
  • Localization: data annotations, widgets, alternates
  • Lists have RSS feeds


The full list of fixed bugs for this release can be found here: 


Orchard Items

 

 

Tags: ,

ASP.NET | Azure | Cloud Computing | Engineering | Technology | orchard cms

Application Dynamic Environment Configuration for .NET Apps and Windows Azure Service Roles

by Arra Derderian 30. September 2011 19:57

azure

 

When creating websites and applications it is one thing to make your application work in your development environment but it is another thing to make it work in the many integration environments that it will live in. An example, of this is a website that is developed locally, integration tested on a development box, tested in a QA environment, reviewed by a client in a staging environment, and pushed live to a production environment. 

All of these configurations require different database connection strings, email server addresses, and local file system locations for uploaded files. On top of these dynamic environment settings includes a Version Control system that most all of us use in our everyday life. I am sure everyone has accidentally checked in a web.config file that has a development connection string and it has caused problems in production. Secondly, it is a pain to manage these files in multiple environments by having to edit them on each server. Newer version of .NET have released the concept of the web.config.debug and web.config.release versions to mitigate this problem a bit but it really does not solve the problem for more than two environments.

Lastly, with the ability to write applications for the Windows Azure platform we want our applications to be easily tested locally and deployed to the cloud seamlessly. I want to be able to test my application locally on perhaps a local SQL database, but then when in the Cloud it should be connecting to a SQL Azure datasource and utilizing blob storage instead of file storage.

Cloud Construct has been using the concept of a dynamic configuration file for applications since we started writing web applications and standalone apps as well. The general concept is an XML driven file that contains settings that can be set for multiple environments that use an "endpoint" to resolve at application start the environment the application is running in. For example, in a web application project we will add some code to initialize our static Configuration class. The Configuration class will resolve the environment based on server endpoint and apply its settings to the object's properties. We can then access these properties from any place in our code.

Endpoints are resolved by server name and settings are pulled in the following order: 1. Global Settings 2. Environment Settings 3. Endpoint Settings. This allows global items to be applied to all environments when needed. Then environment specific settings will be applied. Lastly, any machine settings. Here is an example of this file:

config.xml (3.47 kb)

As you can see we have 3 specific environments:

1. Production, a single "Cloud" endpoint which resolves for the wildcard hostnames given in the cloud.

2. Staging, a single server endpoint.

3. Development, my local development machine endpoint and also my machine when it is in the local "Cloud" debugging mode. (It resolves Cloud endpoints over normal endpoints by checking to see if: RoleEnvironment.IsAvailable ? "cloud_endpoint" : "endpoint"

Each of these environments can have multiple endpoints as you can see so that if you have multiple servers in production they can all be resolved to that environment and possibly have their own settings on that machine. This file can be checked in easily to version control without causing problems in other environments accidentally and also limits all settings to a single file. Also I can take my applications and develop them in a way that in the future if clients want to expand to the cloud they can easily do so by just adding a cloud endpoint with its settings. For example, the EmailServer that uses SendGrid in the cloud or a local one when in staging:

if (CloudConstructConfig.Environment.IsInCloud)
{
System.Net.NetworkCredential credentials = 
    new System.Net.NetworkCredential(CloudConstructConfig.EmailUsername, 
   CloudConstructConfig.EmailPassword);

smtpClient.Credentials = credentials;
}

 

Above we are simply adding an extra credential when we are in the cloud to send emails. Otherwise the code is the same!

Sooo I am sure you want to know how do I get this code and integrate it right? Well here is the library: 

CloudConstructWebConfigurator_V1.0.zip (305.98 kb)

In order to integrate it into your application you can do the following:

1. Add a reference to CloudConstructWebConfigurator.dll in your project. (You can also add a reference to log4net dll as well for logging integration if you already are using it.)

2. Add a static class to your project that holds all of the settings configured in your XML file. This is the object you reference in code for your settings. (See the ClassLibrary1 project in the example integration zip below.)

3. Wire up your code in your global.asax.cs file to run on application startup and instantiate your static class.

4. Copy the Config directory into the App_Data directory.

Here is the link to the zip file of the example project utilizing the dynamic configuration library:

WebApplication1.zip (157.22 kb)

Important files to look at are the global.asax.cs, ClassLibrary1.CloudConstructConfig, and config.xml which drives the settings.

NOTE: It may be necessary to also add a reference to Microsoft.WindowsAzure.ServiceRuntime.dll if it does not exist on your system. It is provided with the zip file.

LOGGING INFORMATION:

If you utilize log4net you will get some great startup logging information:

 

2011-10-01 09:55:08,995 INFO  - *********************************

2011-10-01 09:55:09,005 INFO  -  Starting My WebApp

2011-10-01 09:55:09,005 INFO  - *********************************

2011-10-01 09:55:09,163 INFO  - Found host name to be: ARRA-CLOUD-PC.

2011-10-01 09:55:09,164 INFO  - Found 5 required items in the configuration file.

2011-10-01 09:55:09,164 INFO  - Found a global item list in the configuration file.

2011-10-01 09:55:09,167 INFO  - Processed Global file item: ContactEmailTemplate

2011-10-01 09:55:09,167 INFO  - Processed Global configuration item: EmailClientFooter

2011-10-01 09:55:09,168 INFO  - Processed Global flag item: DoCacheProfiles

2011-10-01 09:55:09,349 INFO  - Recognized environment as development, executing in normal context

2011-10-01 09:55:09,349 INFO  - Processed Environment database item: PrimaryDB

2011-10-01 09:55:09,349 INFO  - Processed Environment configuration item: EmailServer

2011-10-01 09:55:09,349 INFO  - Updated to Environment flag item: DoCacheProfiles

2011-10-01 09:55:09,349 INFO  - Matched host as ARRA-CLOUD-PC

2011-10-01 09:55:09,350 INFO  - Loaded 5 out of 5 required items.

2011-10-01 09:55:09,350 INFO  - No errors found when validating all configuration items.

2011-10-01 09:55:09,351 INFO  - Completed loading configuration file.

How to control how your site looks on Facebook

by Arra Derderian 25. September 2011 02:57

Every site out there now ends up being shared on Facebook. If you want your site to look good on a person's wall or in the news feed when it is shared you need to include Open Graph protocol tags. 

The first step to seeing how your site appears is going to Facebook's URL Linter tool. Here you can enter in your site's URL and it will tell you how it will appear on Facebook. You will notice there are tags such as "og:title", "og:image", etc that you can include on your page that will allow you to control how Facebook displays the text and icon associated with your site when someone pastes it into Facebook.

For example:

<meta property="og:title" content="The Cloud Construct Blog" />

<meta property="og:description" content="The Cloud Team's Thoughts, Ideas, and Expressions." />

<meta property="og:type" content="blog" />

<meta property="og:url" content="http://blog.cloudconstruct.com" />

<meta property="og:image" content="http://blog.cloudconstruct.com/images/fb-image.png" />

These would be great properties to include on the homepage of my blog site so when people linked to it on Facebook it appeared correctly and served up a nice image with it. If Facebook decides to display pages of type=blog different than a website it also can do that too. Basically, you are conforming to the Open Graph standards so all sites who choose to dispay your site can do it in the best way possible. The image has specific standards such as being 50x50 and certain file types. After you place the above tags in your page, you will want to read this Facebook Tutorial about adding the appropriate html namespace tags as well:

 

<html xmlns="http://www.w3.org/1999/xhtml"

      xmlns:og="http://ogp.me/ns#"

      xmlns:fb="http://www.facebook.com/2008/fbml">

 

There are tons of tags you can add to make your site even more inline with the OG protocol. See the Social Graph options on the Facebook site.

Lastly, when you run the URL Linter on your site it will update your site in the Facebook cache. So if you are not properly indexed now, run the tool after you update your site and it will update Facebook's cache.

 

NOTE: Although I am writing this article and the Cloud team places these tags in all of our newly developed sites. We still have not had time to put it on our own site. Please don't hold that against us :)

 

Tags: , ,

SEO & Online Marketing | Technology | User Experience

Return valid XML markup in a WCF service based on an XSD.

by Arra Derderian 10. September 2011 18:53

Have you ever had to produce a WCF service or POX webservice that returns valid markup based on a third party schema? Well I have. There is alot of industry standards out there for data transfer and integration. Chances are you may have to support communicating within these means via a webservice. Well as long as you can get your hands on an XSD document for the XML you need to generate Visual Studio makes it easy for you to do this. XSD.exe is a tool that comes with Visual Studio and it allows you to auto generate class files based on your XSD document. 

For example, you have a set of data that stored in your database that you need to communicate with an outside party and you both agree to use a common standard of XML for communication. (Maybe you are in mutual fund trading and there is a standard out there for fund transfer, or the other company has an existing schema they would like you to use.) If there is and XSD document provided by the governing body of that protocol or the company you can simply run "xsd.exe file.xm"l from the command line and you got your application layer for you webservice. Simply drop those class files into your solution and make a database call to populate the objects and return it via your webservice call. 

I like this method over supporting WSDL for services because it is safer from my point of view. No need to publicly expose any internal information and only the parties with the XSD.exe document know how to communicate. The methods and locations of the service are hidden from the end party as well.

Tags: , ,

ASP.NET | Engineering | Technology

Customizing The Orchard Culture Picker Module

by Arra Derderian 27. August 2011 19:01

The Orchard Culture Picker module is a great way to allow users to switch the culture they wish to view your site in. It takes the cultures you enabled in the settings for Orchard and places them in a dropdown for users to select their culture. This is all great but what if you don't want to have a dropdown? Below is an example of a custom implementation by overriding the Culture Picker in my theme:

We allow users to click on the culture they wish to use and have it styled inline with our utility navigation. Lastly, we modify the display text to the user so it is trimmed down from the entire language and culture combination. The code below shows how I modified the original Modules\Orchard.CulturePicker\Views\Parts\CulturePicker.cshtml file. All you need to do is copy that file from the module and put it in your Themes\YOURTHEME\Views\Parts folder. Then you can modify the file as you want. 

The original file uses a dropdown and when you change the value it submits the page to the CulturePicker controller ChangeCulture method. I simply made a link that submits a querystring value to that same method with the same id as the dropdown. (cultureName). The value is sent to the method and it all functions as normal. Here is the code:

@foreach (var item in availableCultureswithNames)
{    
   <text> | </text> 
    if (Model.UserCulture == item.Key)
    {
        @Html.ActionLink(item.Key.Split(new char[]{'-'})[0].ToUpper(), "ChangeCulture", "UserCulture", new { Area = "Orchard.CulturePicker", CultureName = item.Key }, new { @class = "selected" })
    }
    else
    {
        @Html.ActionLink(item.Key.Split(new char[] { '-' })[0].ToUpper(), "ChangeCulture", "UserCulture", new { Area = "Orchard.CulturePicker", CultureName = item.Key }, new { })
    }
}

You can replace this with the code that creates the dropdown and form, starting with the "@using" keyword. It also is splitting the culture key so we only display the language and not the whole culture string to the user. Give it a try!

 

Tags: , , ,

Engineering | Technology

Azure Series Part 3: Migrating Http Modules and Handlers to Windows Azure

by Arra Derderian 10. July 2011 20:17

For some legacy ASP.NET sites you may notice your old HTTP Handlers and Modules being configured in the web.config <system.web> section do not work anymore in the Windows Azure. This is because Windows Azure is configured to run on IIS in "Integrated Pipeline" mode. This means web requests are integrated into IIS as opposed to classic pipeline mode where requests go only through the isapi.dll. In Integrated Pipeline mode your <httModules> and <httpHandlers> nodes will throw an invalid configuration exception.

I struggled to find out why this was happening and then I realized Azure was host in IIS 7 with Integrated Pipeline setup. You now define your modules and handlers in your <system.webserver> section of the web.config. This is helpful because now my "Browser Support Module" can be reused in the cloud. I have a specific module to redirect requests from browsers that are not supported by my website.

 

Tags: , ,

ASP.NET | Azure | Cloud Computing | Engineering

Utilizing the XMLSerializer to add attributes to your XML response.

by Arra Derderian 23. June 2011 17:11

After needing to add a new XML schema response to my existing WCF service, I thought I could just add a new method to my service with a similar name as my existing one and change the return type of that method to be an object with different properties. This would support the separate XML schema I needed to provide. One problem with this solution was that the new object is still using the default DataContract serializer. For some reason the DataContract serializer does not allow serialization of attributes on elements. Why, I don't know. Perhaps to increase speed.

Anyway the only way around this is to utilize the old XMLSerializer provided in the framework. To do this add the [XmlSerializerFormat] attribute to each class definition on your new object. Secondly, don't forget to add it to your service contract as well! I made this mistake and nothing would work until I did this. In the end you just add the [XmlAttribute] attribute to every property you wish to be serialized as a node attribute. If your using the default service factory with the automaticFormatSelectionEnabled="true" flag set in your web.config then you will still get JSON returned if someone requests your method using JSON.

One final note as well. I found that if any of your enumerated types that are part of the Data Contract have the [Flags] attribute then your service help page won't properly render. See this support page here: http://support.microsoft.com/kb/2020406

Tags: , ,

Engineering | Technology