Lighthouse.Net is a powerful, easy-to-use content management system written in ASP.NET. The product’s inline editing approach allows content editors to browse the website and update content using a front-end view of the site.
This document is a guide for implementing Lighthouse.Net. The implementation process consists of converting static HTML pages into a CMS-driven web site. While some experience with Visual Studio and ASP.NET is required to complete this process, implementing your site should be a painless process for a developer with general skills in these technologies.
Lighthouse.Net is a standard ASP.NET MVC 3 application. The following software is required to develop and run a Lighthouse.Net site.
Installing and configuring a Lighthouse.Net site should only take a few minutes. Follow the steps below to set up a new Lighthouse.Net site for initial use.
Lighthouse.Net comes with basic homepage and default templates (based on Twitter Bootstrap). This section will guide you through the process of updating your static site to be powered by Lighthouse.Net.
The following code is the HTML for a very basic web page.
<!DOCTYPE html> <html> <head> <title>Site Title</title> </head> <body> <h1>My Page Title</h1> <div class=”subtitle”>My Page Title</div> <p>My first paragraph.</p> </body> </html>
The following code is the web page listed above converted into a Lighthouse.Net template. With very minimal changes, this page is now fully integrated with Lighthouse.Net.
@{ var Renderer = (Lighthouse.Infastructure.LHPageRenderer)ViewBag.Renderer; } <!DOCTYPE html> <html> <head> @Renderer.Title() @Renderer.LighthouseHeadIncludes() </head> <body> <h1>@Renderer.PagePart(id: "Title")</h1> <div class="subtitle"> @Renderer.PagePart(id: "Subtitle")</div> <p>@Renderer.PagePart(id: "Body")</p> </body> </html>
This section describes the changes needed to convert a static HTML page to a Lighthouse.Net template.
1. To the very top of the file, add the following line of code. This defines the Renderer object, which will be used by other code in your template.
@{
var Renderer = (Lighthouse.Infastructure.LHPageRenderer)ViewBag.Renderer;
}
2. Replace the <title>…</title> line with the following code. The first line allows Lighthouse.Net to dynamically set the title of each page. The second line allows Lighthouse.Net to add some addition code to the page when in SiteEditor mode.
@Renderer.Title() @Renderer.LighthouseHeadIncludes()
3. Replace all static HTML chunks of code which you would like to be controlled via the CMS with a variation of the following line. This enables Lighthouse.Net to control the content for blocks of HTML on your site.
@Renderer.PagePart(id: "Page-Part-Name-Here")
Most websites having a navigation component at the top of each web page. Typically, this is achieved via the use of an unordered list. Here is a sample top navigation (including drop-down sub-navigation):
<ul class="nav"> <li class="active"><a href="/index">Home</a></li> <li><a href="/about ">About</a></li> <li><a href="/contact ">Contact</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu"> <li><a href="/subnav1">Subnav Item 1</a></li> <li><a href="/subnav2"> Subnav Item 2</a></li> </ul> </li> </ul>
Lighthouse.Net’s navigation functionality makes it easy to update a static navigation like this to be managed by the CMS. Replace the entire <ul></ul> block code with a variation of the following:
@Renderer.Navigation(new Lighthouse.Infastructure.LHNavigation{ Id=”main-nav” })
To the top of your HTML document, but after you include a link to the jQuery library), you may need to add a variation of the following code. This block of code enables you to add and remove classes to the navigation area, as appropriate for your specific navigation area’s HTML.
<script type="text/javascript"> $(document).ready(function () { $(".nav-collapse ul li ul").addClass("dropdown-menu"); $(".nav-collapse ul li ul").prev("a").addClass("dropdown-toggle"); //$(".nav-collapse ul li ul").prev("a").attr("data-toggle", "dropdown"); $(".nav-collapse ul li ul").prev("a").append("<b class='caret'></b>"); $(".nav-collapse ul li ul").parent("li").addClass("dropdown"); }); </script>
Note that the Navigation function can be used to display sub-navigation on your site, too. Often, sub-navigation appears as a left or right column of links on your page.
If your HTML contains static links to pages within your site, you will want to update these to use the PageLink function.
For instance, the following link:
<a href="/AboutUs">About Us</a>
should be replaced with the following:
<a href="@Renderer.PageLink("AboutUs")">About Us</a>
This enables Lighthouse.Net to effectively navigate the site when you are in editing mode. The parameter to pass to the function is the name of the page in the CMS.
Lighthouse.Net allows for the creation of as many templates as you need to handle the distinct page layouts on your site. For instance, you may have a default template with a title area and a body area, and a home page template with an image carousel and multiple content areas.
When managing pages in the CMS, you can choose any template registered with Lighthouse.Net to display your content.
To add a new template:
When using the Site Editor, users can style content using the “Styles” button in the top button bar.
To support this integration, please follow these steps.
1. Add the following code to the top of your site’s style sheet.
@import url(/Content/Style_wysiwyg.css);
2. Open /Content/Style_wysiwyg.css. Add any styles that you would like to be accessible in the Styles dropdown to this file. The following is a sample style definition for this file:
p.Important, p.Important *, ul.Important, ul.Important *, a.Important { font-weight:bold; font-style:italic; }
3. Open /Content/style.xml. Add a new style element for each style you would like in the Styles dropdown. Here is an example:
<style> <name>Important Text</name> <class>Important</class> </style>
4. If your site will be using members-only functionality, you will want to add styles for “.validation-summary-errors” and “.field-validation-error”. These styles are standard ASP.NET MVC styles for styling error messages. Here is an example:
.validation-summary-errors { /*font-weight: bold;*/ color: #b94a48; } .field-validation-error { color: #b94a48; display: inline-block; padding-left: 5px; vertical-align: middle; }
There are several web pages that Lighthouse.Net will produce automatically. This list includes:
In order to display these pages correctly, Lighthouse.Net needs to know which ASP.NET MVC layout file to use for these pages. By default, the system will use /Views/Shared/_Layout.cshtml. If you would prefer to use a different layout file, please open /Web.config and update the BasicTemplateLayout parameter. Here is a sample:
<add key="BasicTemplateLayout" value="~/Views/Shared/_BasicTemplateLayout.cshtml" />
This section contains information on additional features of Lighthouse.Net that you can leverage on your site.
Lighthouse.Net includes many security features that ensure your site follows best practices for web applications.
Integrating Google Analytics into your site is a simple two-step process.
1. Open /Web.config. Update the following line of code to contain your Google Analytics account number.
<add key="GoogleAnalyticsAcctNum" value="" />
2. Add the following line of code to the head section of your template:
@Html.Partial("_GoogleAnalytics")
Cookie crumb navigation typically appears near the top of a web page, providing links to all parent pages of the current page. A sample cookie crumb might look like this:
Home > Products > Product 1
To incorporate cookie crumb navigation on your site, use the CookieCrumbs function:
@Renderer.CookieCrumbs(new Lighthouse.Infastructure.LHCookieCrumb{
CSSClass=”crumb-nav” })
In implementing your site, you may come across chunks of HTML that are shared amongst several pages. For example, your site may contain a business address, which is listed on the footer of every page on your site. The standard Renderer.PagePart function is not an ideal solution, since page parts are unique to a single page and this is a piece of content that should stay the same on every page.
The Renderer.MiscContent function addresses this need by allowing you to specify chunks of HTML code that should managed via the Miscellaneous Site Content admin tool.
To add a Miscellaneous Site Content item, follow the following steps:
1. On the admin site, select the “Manage Miscellaneous Site Content” tool. This tool is housed under the “Site” menu by default.
2. Press the "Add" button to add a new entry. Complete the form and press "Submit." Note that the (i) icon on the form provides an explanation for each field on the form.
3. Replace the chunk of HTML code in your template with a call to the Renderer.MiscContent function.
Here is an example:
Initial Static HTML Code:
<p>Here is the left column of text from the site footer.</p>
Code Updated to Use Miscellaneous Content System:
<p>@Renderer.MiscContent("Footer Left Column")</p>
Lighthouse.Net utilizes the Lighthouse.Utilities.Query class for executing database queries. This class allows you to run queries and return results in a single line of code. Additionally, all queries utilizing Lighthouse.Net’s Query class are visible in the Debug Console (described below).
The following code samples may be useful for your project:
// Return a DataTable from a query var myDataTable = new Lighthouse.Utilities.Query("select * from MyTable where sectionID = @sectionID") .AddParameter("@sectionID", sectionID) .ExecuteDataTable();
// Return an object from a query. Useful when returning a single row from the database var myObj = new Query(“select * from Table1 where id = @id”) .AddParameter("@id", id) .ExecuteObject<MyObject>();
During development, it is often helpful to see the database queries that are executed on your site. The Lighthouse.Net Debug Console enables you to see the database queries and other useful information as you navigate the site. Note that you will only see the queries relevant to pages that you request in the same browser session.
To access Debug Console, open your browser to
/Debug.
To enable Debug Console, make sure that
DebugEnabled is set to true in /Web.config.
To disable Debug Console, set this parameter to false. To view the Debug Console, you will also need to confirm that your IP address exists the "Manage Debugging IP Addresses" admin tool.
Note: Make sure to set DebugEnabled to false in a production environment.
Lighthouse.Net comes with several HTML Helpers which you can use on your site.
1. AddStyleSheet – This function can be used to build a list of stylesheets that will be added to a page. The use of this helper ensures that you do not reference the same stylesheet multiple times in your code. Additionally, future versions of Lighthouse.Net may automatically combine and minifiy stylesheets (for smaller, more efficient download), making this functionality more powerful.
Sample code to build to the register stylesheets:
<!--- Add two stylesheets in one call ---> @Html.AddStylesheet( Url.Content("~/Lighthouse/css/MSStandard.css"), Url.Content(dojoLocation + "/dijit/themes/tundra/tundra.css") ) [Other HTML code or business logic here] <!--- Add another stylesheet. Note that this stylesheet has already been added above, so this one will be skipped when the page is rendered ---> @Html.AddStylesheet( Url.Content("~/Lighthouse/css/MSStandard.css") )
Use the following line of code to output all stylesheets registered using AddStyleSheet. This should be placed in the head section of your web page.
@Html.RenderStyles()
2. AddScript – This function can be used to build a list of javascript files that will be added to a page. The use of this helper ensures that you do not reference the same javascript file multiple times in your code. Additionally, future versions of Lighthouse.Net may automatically combine and minifiy javascript files (for smaller, more efficient download), making this functionality more powerful.
Sample code to build to the array of registered scripts:
<!--- Add two javascript files in one call ---> @Html.AddScript( Url.Content("~/Scripts/jquery-1.7.1.min.js"), Url.Content("~/Scripts/bootstrap.min.js"), ) <!--- Add another javascript file. ---> @Html.AddScript( Url.Content("~/Scripts/MySite.js") )
Use the following line of code to output all javascript files registered using AddScript:
@Html.RenderScripts()
Lighthouse.Net provides a very simple interface for caching data to memory. Use the Lighthouse.Utilities.LHCache class to add and remove items from the cache. Items added to the cache are auto-purged after five minutes. Lighthouse.Net uses the LHCache class internally for caching the main page navigation query, data from the Miscellaneous Site Content system, and other content that does not change frequently.
Sample Code:
Add item to cache
Lighthouse.Infastructure.LHCache.AddItem(“MyItem”, myObject);
Get cached Item
Lighthouse.Infastructure.LHCache.GetItem(“MyItem”);
Clear cached Item
Lighthouse.Infastructure.LHCache.ClearItem(“MyItem”);
Clear all cached Items
Lighthouse.Infastructure.LHCache.ClearAllItems();
In ASP.NET sites, it is common to store application settings in the appSettings section of Web.config. Here are a few example settings:
There are a few inefficiencies with this approach:
Lighthouse.NET solves the problem by storing this information in the database. Use "Manage Environments" and "Manage Settings" on your admin site to control the list of settings for your environments.
In your code, use Lighthouse.Utilities.LHSetting.GetItem(itemName) to fetch a setting. For instance, to fetch your mail server username, use:
Lighthouse.Utilities.LHSetting.GetItem("MailServerUserName").
The top-level Web.local.config file is used to identify your environment. This file is not included in the Visual Studio project, as there will be a different version of this file for each environment. Make sure to configure this file correctly for each environment.
In the file, environment names are processed from left to right. If you have a production environment, a development environment, and a local development environment, the Environment variable should consist of Production,Development,{YourName}. All production settings will be loaded first, then overridden with development settings (if they exist), then overridden with your local settings (if they exist).
The currently active Environment Settings for an environment can be seen on the Debug Console at /Debug.
Lighthouse.Net SiteEditor is a great tool for managing the content on your site. For many sites, no additional custom code is required.
If you would like to incorporate more structured database data into your site, Lighthouse.Net offers a robust framework to achieve this. A typical implementation of structured data involves the creation of one or more admin tools to manage the data and custom front-end code to display the data.
Sample Applications:
For the purpose of demonstrating the integration of structured data, we will use the example of a jQuery carousel. Carousels are frequently seen on the home page of web sites, where there are several slides of content in a single content area, with options to navigate amongst the slides. Here is a link to a sample carousel: http://wbpreview.com/previews/WB0C4JJ9R/index.html
The following steps are needed to enable this content to be managed via Lighthouse.Net.
Open MS SQL Server Management Studio and run the following queries. This will create the tables necessary for storing data for the Carousel system.
CREATE TABLE [dbo].[Carousels]( [CarouselID] [int] IDENTITY(1,1) NOT NULL, [Code] [varchar](100) NOT NULL, [DateAdded] [smalldatetime] NOT NULL, [DateUpdated] [smalldatetime] NOT NULL, CONSTRAINT [PK_Carousels] PRIMARY KEY CLUSTERED ( [CarouselID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[CarouselSlides]( [SlideID] [int] IDENTITY(1,1) NOT NULL, [CarouselID] [int] NOT NULL, [Title] [varchar](max) NOT NULL, [Body] [varchar](max) NOT NULL, [ImagePath] [varchar](100) NOT NULL, [OrderNum] [int] NOT NULL, [DateAdded] [smalldatetime] NOT NULL, [DateUpdated] [smalldatetime] NOT NULL, CONSTRAINT [PK_CarouselSlides] PRIMARY KEY CLUSTERED ( [SlideID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[CarouselSlides] ADD CONSTRAINT [DF_CarouselSlides_OrderNum] DEFAULT ((1000)) FOR [OrderNum] GO
Under Areas/Admin/Controllers, create a new file called CarouselController.cs. Copy and paste the following code into the file. This code generates the admin tool to manage carousels.
using Lighthouse.Controllers; using Lighthouse.Data; using Lighthouse.Data.Columns; namespace Lighthouse.Areas.Admin.Controllers { class CarouselTable : Table { public CarouselTable() : base("Carousels") { this.Title = "Carousel"; this.AddColumn( new IntegerColumn() { Name = "CarouselID", DisplayName="Id", IsPrimaryKey = true, IsAutoGenerated = true }, new TextColumn() { Name = "Code", IsRequired = true, AutoCompleteSearch = true }, new TimeStampColumn() { Name = "DateAdded", DisplayName = "Date Added" }, new TimeStampColumn() { Name = "DateUpdated", DisplayName = "Date Updated", StampOnEdit = true } ); } } public class CarouselController : TableController { public override void SetTable() { Table = new CarouselTable(); } } }
You can access the Carousels Admin tool at /Admin/Carousel. To add this new tool to the standard navigation of Lighthouse.Net's admin site, access Administration / Manage Links and add a new record for the tool.
Under Areas/Admin/Controllers, create a new file called CarouselSlideController.cs. Copy and paste the following code into the file. This code generates the admin tool to manage carousel slides.
using Lighthouse.Controllers; using Lighthouse.Data; using Lighthouse.Data.Columns; namespace Lighthouse.Areas.Admin.Controllers { class CarouselSlideTable : Table { public CarouselSlideTable() : base("CarouselSlides") { this.Title = "Carousel Slides"; this.AddColumn( new IntegerColumn() { Name = "SlideID", DisplayName="Id", IsPrimaryKey = true, IsAutoGenerated = true }, new DropdownSingleChoiceColumn() { Name = "CarouselID", DisplayName="Carousel", ForeignTable = new CarouselTable(), IsRequired=true }, new TextColumn() { Name = "Title", IsRequired = true, AutoCompleteSearch = true }, new RichTextColumn() { Name = "Body", IsRequired=true }, new FileColumn() { Name = "ImagePath", DisplayName="Image File", Directory="/Uploads/Carousel", IsRequired=true }, new TimeStampColumn() { Name = "DateAdded", DisplayName = "Date Added" }, new TimeStampColumn() { Name = "DateUpdated", DisplayName = "Date Updated", StampOnEdit = true } ); } } public class CarouselSlideController : TableController { public override void SetTable() { Table = new CarouselSlideTable(); Table.CustomTableActions.Add(new CustomTableAction { ActionName = "Set Order", ActionType = CustomTableActionTypes.ListOrder, OrderColumn = "OrderNum", DescriptionColumn = "Title", SelectQuery = "SELECT s.SlideID AS selectValue, c.Code + ' / ' + s.Title AS selectText FROM dbo.LH_Carousels c JOIN dbo.LH_CarouselSlides s ON c.CarouselID = s.CarouselID ORDER BY c.code, s.OrderNum" }); } } }
You can access the Carousel Slides Admin tool at /Admin/CarouselSlide. To add this new tool to the standard navigation of Lighthouse.Net's admin site, access Administration / Manage Links and add a new record for the tool.
Under /Models, create a new file called CarouselSlide.cs. Here is the code for the model class.
namespace MySite { public class CarouselSlide { public int SlideID { get; set; } public string Title { get; set; } public string Body { get; set; } public string ImagePath { get; set; } public string ClassName { get; set; } } }
Under /Views/Shared, create a new file called _Carousel.cshtml. Copy and paste the following code into the file.
@model string @using MySite; @using System.Data; @{ var code = Model; var dt = new Lighthouse.Utilities.Query("SELECT s.SlideID, s.Title, s.Body, s.ImagePath FROM dbo.LH_Carousels c JOIN dbo.LH_CarouselSlides s ON c.CarouselID = s.CarouselID WHERE c.Code = @code ORDER BY s.OrderNum") .AddParameter("@code", code) .ExecuteDataTable(); var slides = new List<CarouselSlide>(); int i = 1; foreach (DataRow row in dt.Rows) { slides.Add(new CarouselSlide { Title = Convert.ToString(row["title"]), Body= Convert.ToString(row["body"]), ImagePath= Convert.ToString(row["imagePath"]), ClassName = i == 1 ? "active" : "" }); i++; } } <div id="masthead"> <div class="container"> <div id="masthead-carousel" class="carousel slide"> <div class="carousel-inner"> @foreach (var slide in slides) { <div class="@slide.ClassName item"> <img src="@slide.ImagePath" alt="" /> <div class="masthead-details"> <h2>@Html.Raw(slide.Title)</h2> @Html.Raw(slide.Body) </div> <!-- /masthead-details --> </div> <!-- /item --> } </div> <!-- /carousel-inner --> <a class="carousel-control left" href="#masthead-carousel" data-slide="prev">‹</a> <a class="carousel-control right" href="#masthead-carousel" data-slide="next">›</a> </div> <!-- /masthead-carousel --> </div> <!-- /container --> </div> <!-- /masthead -->
In any of your templates, you can now incorporate a carousel using the following line of code:
@Html.Partial("_Carousel", "HomePage")
Lighthouse.Net comes with a standard set of front-end login features. These features include login with username and password, login with Facebook, login with Google, login with LinkedIn, and Forgot Password. This section discusses functionality related to customizing and extending user integration.
When a user is logged into a Lighthouse.Net site, the system runs a single query per page view to fetch information about the user. This information is available to you via the LH.GetLoggedInUser() function. If you need to fetch custom information about the user in this query, you can override the default function by following the steps below.