Web Development 101: Part 4, Using Layout

Up until now you've seen how to use WebMatrix to create a very simple web page, and how this page will operate in a number of different browsers as well as how to use CSS styling to make the basic page look a little prettier.

In this Chapter you're going to take all this to the next level and start using server programming. You might be used to client programming, such as building applications that run on a phone, a desktop, or even JavaScript applications that run within the browser. The important difference with server programming is that much of your application code doesn’t run on the client device. Instead, the end user’s actions launch a page request to the server, and if that page is an “active” page, the server runs code and uses that code to generate HTML markup and values that it sends down to the browser. The browser then renders this HTML and users see the result.

As you grow your skills, you’ll find that sometimes it makes sense to mix things up a little, with some code running in your browser (typically using JavaScript, or a Rich Internet Application (RIA) technology such as Silverlight), and the rest running on your server.

WebMatrix introduces the Razor syntax for programming web pages, and one of the features it gives you is a powerful, yet simple, layout engine. In this article we’ll take a look at using the layout features to put all of the common HTML, such as the <head> and the footer content into one location and have it automatically generated for your page, so that when you are building a page such as the movies list, the file for that page will only have the main content for that page, and the rest will be added for you, with you in full control.

Creating a CSHTML page that uses Razor

Up to now you’ve been creating HTML pages that use the .htm or .html extension. These are static pages, so that whenever their address is called by the browser, the server simply sends them and their content to the browser. The server doesn’t process the page in any way.

You may have heard of the term ‘dynamic’ web pages, which are pages that the server builds based on HTML as well as code that runs on the server to determine how it should build the page, with the output being HTML. Dynamic pages give you really powerful scenarios, and for the rest of these series you’ll be using them. Amongst other things, they’ll allow you to store the movies in a database, and have the server generate the content for your page from the data in the database, instead of you writing out the titles of the movies on your HTML page directly, and having to change your page whenever you want to change your list.

In this section you are going to create your first dynamic page.

In WebMatrix, dynamic web pages have the .CSHTML or .VBHTML extension. These are effectively HTML files with inline code written in either C# (CS) or Visual Basic (VB), thus dictating the name. I’ll be using CSHTML files, which allow me to write inline code on the page using the C# language. The methodology for doing this, and the syntax that allows me to do this inline within HTML is nicknamed ‘Razor’.

So let’s create one.

Using WebMatrix, in the Files workspace, create a new CSHTML page called movies.cshtml:

alt

WebMatrix will create a page for you that looks like a basic HTML page. Replace the content of this page with the following:

     <div id="movieslist">
       <ol>
         <li><a href="#">It's a wonderful life</a></li>
         <li><a href="#">Lord of the Rings</a></li>
         <li><a href="#">The Fourth World</a></li>
         <li><a href="#">The Lion King</a></li>
       </ol>
     </div>
      

Doesn’t this look strange? There’s no <HTML> tag, there’s no <HEAD> or <BODY> tag, but guess what, it still works! Or at least it works a little. Run it, and you’ll see this:

alt

The Header and Footer

Now the page above looks very similar to what we did earlier, but let's define the page header as everything in the HTML before the <div> containing the movies list, and the page footer as everything in the HTML after the <div> containing the movies list. Don't confuse this with the <header> and <footer> tags in the default.cshtml page you've been working on thus far.

Create a new page called 'PageHeader.cshtml' and copy everything that is above the moviesList <div> from default.chtml into it. It should look like this:

     <!DOCTYPE html>
     <html lang="en">
     <head>
       <meta charset="utf-8" />
       <title>My Favorite Movies</title>
       <link rel="stylesheet" type="text/css" href="movies.css" />
     </head>
     <body>
       <header>
        <h1>A list of my Favorite Movies</h1>
       </header>

Similarly, create a new page called 'PageFooter.cshtml' and copy everything that is below the moviesList <div> from default.chtml into it. It should look like this:

       <div id=”footer”>
         <footer>
          This site was built using Microsoft WebMatrix. 
          <a href="http://web.ms/webmatrix">Download it now.</a>
         </footer>
       </div>
     </body>
     </html>

Using Razor to dynamically add the header and footer

Now that you have these in place, you're going to write your first piece of server code using 'Razor'. WebMatrix tells the difference between HTML and 'Razor' code by the use of the '@' character. You place this character before any lines of code that are instructions to the server telling it what to do.

So, for example the following command:

@RenderPage("pagename") will cause the server to load the HTML from 'pagename' and put it at this place within the current file. So, for our example, if we change the movies.cshtml to look like this:

     @RenderPage("PageHeader.cshtml")
       <div id="movieslist">
       <ol>
         <li><a href="#">It's a wonderful life</a></li>
         <li><a href="#">Lord of the Rings</a></li>
         <li><a href="#">The Fourth World</a></li>
         <li><a href="#">The Lion King</a></li>
       </ol>
       </div>
     @RenderPage("PageFooter.cshtml")

When we run the page, it will look like this:

alt

It's exactly how the static HTML file appeared. This should be no surprise, because it now has the same header and footer (including the code asking the page to load the CSS), and the same body text. But as you saw, it's a whole lot easier to deal with the page now, as all the code for the header and footer aren't in the way, and any new pages you create will have the same header, footer and style sheet

Creating a Layout page

With this approach, you created the page, and then used Razor code when the page ran to include the header and footer code on the page. It's a bottom-up approach.

Another, and perhaps more efficient approach is to go the other way around -- create a Layout that you use as a template for every page, and then include the specific content you want in that. This is more of a top-down approach.

Let's see how this works: Create a new CSHTML page, and call it _siteLayout.cshtml.

Replace the content of the page that was created for you with the following. If it looks familiar, this is everything that was in the static default.html page that you created earlier

     <!DOCTYPE html>
     <html lang="en">
     <head>
       <meta charset="utf-8" />
       <title>My Favorite Movies</title>
       <link rel="stylesheet" type="text/css" href="movies.css" />
     </head>
     <body>
       <header>
         <h1>A list of my Favorite Movies</h1>
       </header>
       <div id="movieslist">
         <ol>
           <li><a href="#">It's a wonderful life</a></li>
           <li><a href="#">Lord of the Rings</a></li>
           <li><a href="#">The Fourth World</a></li>
           <li><a href="#">The Lion King</a></li>
         </ol>
       </div>
       <div id=”footer”>
         <footer>
          This site was built using Microsoft WebMatrix. 
          <a href="http://web.ms/webmatrix">Download it now.</a>
         </footer>
       </div>
     </body>
     </html>

Now remove the <div> called ‘movieslist’ and replace it with the following code:

@RenderBody()

Remember, earlier we said that the '@' symbol is telling WebMatrix to run code on the server at this point. The RenderBody command simply tells WebMatrix to render the content of the page at this location.

Here’s how your _siteLayout.cshtml page should look now:

     <!DOCTYPE html>
     <html lang="en">
     <head>
       <meta charset="utf-8" />
         <title>My Favorite Movies</title>
         <link rel="stylesheet" type="text/css" href="movies.css" />
       </head>
     <body>
       <header>
         <h1>A list of my Favorite Movies</h1>
       </header>
       @RenderBody()
       <div id=”footer”>
         <footer>
           This site was built using Microsoft WebMatrix. 
           <a href="http://web.ms/webmatrix">Download it now.</a>
         </footer>
       </div>
     </body>
     </html>

So, when it comes to the page called movies.cshtml that you created a moment ago, the content of the page is the <div> and the <ol><li> list. Thus, the idea is, that when you browse to the CSHTML page, WebMatrix will use the layout page to determine how to draw the page, thus it takes the head, the CSS and everything from the layout page.

Before trying this out, don't forget to remove the @RenderPage("PageHeader.cshtml") and @RenderPage("PageFooter.cshtml") commands from movies.cshtml.

Telling WebMatrix how to use the Layout page

Now if you’ve been paying attention, you probably are thinking – how does it know to use _siteLayout.cshtml for my movies.cshtml page? The answer is, it doesn’t. We have to tell WebMatrix to use that.

Fortunately, that’s pretty easy to do.

If you create a page called _PageStart.cshtml, this page will be called whenever WebMatrix runs a CSTHML (or VBHTML) page.

A good use for this is to set up global variables or functions. Here we’ll just tell it that the layout for the entire site will be driven by _siteLayout.cshtml.

So go ahead and create _PageStart.cshtml.

Replace its content with the following:

     @{
       Layout = "~/_siteLayout.cshtml";
     }

Run movies.cshtml and take a look at it in the browser now.

alt

If you try to run your _siteLayout.cshtml or _PageStart.cshtml, you will receive an error. If you are receiving a runtime error, make sure that your movies.cshtml file is selected in your file directory in WebMatrix.

Putting it all together.

So what just happened? Let’s take a look, step by step at what WebMatrix did to run your page:

1. The browser asked the server for movies.cshtml

2. The server saw that _PageStart.cshtml exists, so it ran it. This only had one line of code, setting the Layout variable to say that the layout for the site is in the file called siteLayout.cshtml

3. The server then ran siteLayout.cshtml to lay out the page. This gave it the head, the css, the <body> tags, and everything that you’d expect in a static HTML page

4. The server got to the code that read @RenderBody(), at which point it injected the content of movies.cshtml into the page

5. The server got the rest of the code from siteLayout.cshtml, finishing off the page with the closing </body> and </html> tags as well as the footer.

6. The complete page was returned to the browser, complete with styling information.

Adding another page.

The benefits of this approach are clear, and we can demonstrate this by showing the amount of work that you need to do to create another page.

Using WebMatrix, create another page called about.cshtml.

Replace all of the content of about.cshtml with the following:

<h1>About me</h1>
<h2>I'm the author of this page. I should put something interesting here.</h2>
 

Now browse to about.cshtml – the same process outlined in the previous section will execute, except this time when the _siteLayout.cshtml page reaches @RenderBody(), it will render the content from your about.cshtml page, and the result will look like this:

alt

See how the title and footer of the page remained? Now if I want to edit my ‘about’ page, I don’t have to wade through all the plumbing of the page, but instead just edit the content that goes within the main part of the page. This could save you a lot of time and effort in coding your sites.

It’s just the tip of the iceberg in what you can do with layouts and includes in WebMatrix.

Summary

In this article you saw how using the built-in layout mechanism in WebMatrix can make building sites much easier by taking all the common code for all your pages and putting it into layout files. You built your first dynamic pages (i.e. pages that are built on-the-fly by your server, instead of just files on the server’s file system), using C# and the ‘Razor’ syntax.

In the next section you’ll go deeper into the Razor syntax by replacing the static list of movies with one that is driven off a database. WebMatrix integrates the SQL Server Compact database, which is a free, file-driven database, as well as a set of database tools for creating and managing databases and data. You’ll see how to create the database, add fields, add data, and then write code that takes your data and writes it onto the page whenever a user calls your page!

In the next part you’ll take a look at creating data with your application using WebMatrix built in data management features.

You can discuss this article using the adjacent Facebook talkback.

For technical questions please visit our discussion forums, where we have a vibrant community of developers like you, as well as Microsoft engineers who are ready to answer your questions!