For many companies, no matter the industry — from financial services and healthcare to software and web development — a common scenario is to have a public website that includes news, press releases, the company about us information as well as internal and external web applications, all hosted on the same website.
When scoping out the platform for a web application versus its public website, a company often has very different platform requirements. For example, a public website would require a Content Management System (“CMS"), along with different content types such as Page, Blog, News, and Events. A web application, whether internal or external, might need a thinner stack like ASP.NET MVC and require fast connectivity to a SQL database for managing data.
Many times when our web development team chooses the platform for our customers, we generally don’t put web applications on a CMS. Mainly because it’s too much overhead for a web application. And vice versa: our website design team would not want to build out a custom CMS on the MVC platform when ones already exist for the websites we’re creating. So how do we get the best of both worlds?
Cloud Construct heavily utilizes Orchard CMS on many of its clients’ web development and design projects. We choose Orchard CMS because of its modularity, extensibility, and ease of development on the MVC platform. Orchard allows for custom modules to be installed on demand via the Gallery, and it also allows you to author your own.
On a recent web application project, a client of ours required an About Us page, a Blog, and a Frequently Asked Questions section on their website. Normally for a web application, you would hard code the About Us page content and FAQ’s, outsource the Blog, and point to the blog from the website. Well, in my opinion, we now have the ability to improve that scenario by exposing all of our Content Management System data via the Orchard OData module. This module allows your website to query your Orchard CMS and return all of your "Creatable" content types for use in your web application. You can even perform CRUD operations on these content types, which is fantastic!
Step 1. I started off on the FAQ's section and created a new Content Type called “FAQ."
Step 2. I created a taxonomy for the FAQ’s, so that they could be categorized.
Step 3. Once I saved this new content type, I created a new FAQ and published it.
Step 4. Now that I have the FAQ published, the next step was to integrate it into the web application project. I first installed the Orchard.ODATA module, then followed the directions to get it running properly on Orchard. Here are some extra instructions on it and some setup gotcha's. Once properly installed, I enabled the module and added the necessary updates to the Orchard web.config as instructed.
Step 5. To test that theODATA module was working, I hit /odata/$metadata and verified it returned a complete list of all content types and their names for querying. Something like this:
<EntityType Name="FAQ">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="CommonPart" Type="Orchard.OData.CommonPart"/>
<Property Name="BodyPart" Type="Orchard.OData.BodyPart"/>
<Property Name="IdentityPart" Type="Orchard.OData.IdentityPart"/>
<Property Name="TitlePart" Type="Orchard.OData.TitlePart"/>
<Property Name="AdminMenuPart" Type="Orchard.OData.AdminMenuPart"/>
<Property Name="Category" Type="Orchard.OData.Category"/>
</EntityType>
Step 6. Now that you I had a service endpoint in place, I tested the FAQ endpoint like this: /odata/faqs?$format=json. It should return the FAQ. Now I have a queryable JSON endpoint for which the web application or anyone else for that matter can consume.
1. Now that the endpoint is exposed, lets integrate it with your web application. I’ll walk you through how: Begin by having your solution open in Visual Studio. Then right click on your solution name in Solution Explorer. Choose "Add A Service Reference.” You'll be presented with a dialog that will let you place your endpoint address in the address bar. Remember to include /odata.
2. As you can see above, Visual Studio discovered my endpoint and found my Pages content type and my FAQ’s. When that happens, name your service reference and click "OK."
NOTE: If you are using the latest Entity Framework 5.6.1 libraries, you will receive an error on adding the reference because Visual Studio tooling is not caught up to that yet in VS 2012. You will need to unhook those references, allow the app to use 5.6.0, and then rewire them after.
3. Now that your service reference is added, you are free to use your new content types as strongly typed objects in code. You can query, sort, filter, etc!
1. For the FAQ's page, I wanted to display my items by taxonomy or category. So, first things first: I made a call to return all FAQ's. This code is in my controller method for my FAQ's page.
public ActionResult FAQ()
{
Uri uri = new Uri(ConfigurationManager.AppSettings["ContentSiteUrl"]);
var container = new OrchardOData(uri);
List<FAQ> faqs = container.FAQs.ToList();
ViewBag.FAQs = faqs;
return View();
}
2. The AppSetting is just the url of your website without the /odata extension, stored in your web.config. The ODATA class OrchardOData will call out to that service and return the list of objects for you. You can then sort and filter them as well.
After that, the objects can be placed in the ViewBag and displayed on the front end. I also get a list of unique taxonomy terms applied to these FAQ's using this call, so I can organize them on the front end:
List<TermPart> uniqueTerms = faqs.Select(x => x.Category.TermPart[0]).GroupBy(x => x.Name).Select(group => group.First()).ToList();
This assumes we only allow 1 category/term per FAQ.
3. I can display all of our items like so:
@foreach (TermPart tp in uniqueTerms)
{
var id = tp.Id;
<div class="faqcategory" id="category-@id">
<h3>@tp.Name</h3>
@foreach (FAQ f in faqs.Where(x => x.Category.TermPart[0].Id == id))
{
<h3 id="faq-@f.Id">@f.TitlePart.Title</h3>
@Html.Raw(f.BodyPart.Text)
}
</div>
}
By following the steps above and referring to the code examples, you can now integrate your Orchard CMS content with your other company web applications. Other website content is now shareable too.
Additionally, you can create stand-alone Orchard websites to manage content for your web applications, but, at this time, you can’t run your web applications under Orchards application domain. You could definitely save on hosting costs that way. What’s more, you can create methods in order to perform CRUD operations on these content types and push changes back and forth.
In short, there are creative and functional ways to utilize Orchard CMS in the future to enhance your web application projects..
Arra Derderian serves as the President and Lead Technical Architect for Cloud Construct, a top Boston web development firm, and founder of the Boston Orchard CMS User Group. He is a member of the Windows Azure Insiders group. Cloud Construct is a digital agency with capabilities that span web development, information architecture, UX, and design.