Tag Archives: webdevelopment

Filtering and ordering lists with AngularJS

angularJS logo

Recently, I have been spending quite a bit of time playing around with AngularJS. I mostly like it although occasionally “the magic” doesn’t happen and then it is very hard to figure out what went wrong because everything is just so “magical”. By that I mostly mean that bindings between controllers and views are so very automatic that it’s hard to see where they fail, when they fail. Luckily, that doesn’t happen so often and the basic techniques are really easy to pick up.

However, what I especially like about AngularJS is how easy it is to achieve pretty smooth interface interactions. What follows is a small description of  using AngularJS to show a number of records and filter them based on some of their values.

The (much simplified) app I am building here will display a list of books in an imaginary collection, including their title, author, publish year, genre and their rating. The hypothetical visitors to the app will also be able to vote on books to create a top 10 list. They will also be able to order the list by author, title, year, or number of points. And finally, it will be possible to display books from only one genre. You can see a demo of this app here.

Here is what I am using in this project:

  1. AngularJS script and web-server.js that you can find in the seed project (not necessary but it will make your life easier). You can read here how to install node.js and run the server script.
  2. Bootstrap (just for the css)

My apps structure looks like this:

BookCollection file structure

For this tutorial fonts and img folders are irrelevant. The scripts folder holds angular.js and web-server.js file.

In a real application the data for the website would come from a database, but for simplicity’s sake, I will just write an array of objects and get data from there.

Step 1: AngularJS Module

The first thing to do when writing an AngularJS app is to create the module. This is done in the js/app.js file:

var BookCollectionApp = angular.module('BookCollectionApp', []);

All this code does is creating a variable for your angular module. You will use this variable to refer to this module. In a more complex application you might use this file to inject dependencies to your module but in this case this is not necessary.

Step 2: Data

The second piece of code, you want to write is the data factory (js/services/BooksData.js):

BookCollectionApp.factory('BooksData', function(){
	return [
		{title: "To Kill the Mocking Bird", author: "Harper Lee", year: "1960", genre: "Southern Gothic", points: 0},
		{title: "Feet of Clay", author: "Terry Pratchett", year: "1996", genre: "Fantasy", points: 0},
		{title: "Solaris", author: "Stanisław Lem", year: "1961", genre: "SciFi", points: 0},
		{title: "Neverwhere", author: "Neil Gaiman", year: "1996", genre: "Fantasy", points: 0},
		{title: "The Wind-up Bird Chronicle", author: "Haruki Murakami", year: "1997", genre: "Who the hell knows?!", points: 0}
	]
});

In this file I register a factory service called BookData on my app (BookCollectionApp). It will return an array of objects. Each object is a single book bascwith title, author, year, genre and a default point value.

Step 3: AngularJS Controller

Now, it is time to create a controller in the js/controllers/BookCollectionController.js that will be registered on the BookCollectionApp module and that will expose the factory data to potential views:

BookCollectionApp.controller('BookCollectionController', function($scope, BooksData){
	$scope.Books = BooksData;
});

This is a very basic controller file. We will expand it a little bit later but for now this is all that is needed. I register my controller on the BookCollectionApp and I give the controller “BookCollectionController” name. In the controller function I pass scope and BooksData factory and create “Books” variable in my scope giving it the value of what the BooksData factory returns (the array of book objects);

Step 4: View file

With this basic setup, I can move on to building a view that will display books as a list. A View is basically a regular HTML template with data injected through AngularJS. In this case we are talking about index.html file:

<!doctype html>

<meta charset="UTF-8" />
Document
		<link href="css/bootstrap.min.css" rel="stylesheet" />
		<link href="css/style.css" rel="stylesheet" />

On the html tag, I use the ng-app directive to tell my view which module it belongs to.

<body class="container">
	<h1>Book collection</h1>
	<div ng-controller="BookCollectionController" class="row col-md-12">
		<ul class="row col-md-12 books">
			<li ng-repeat="book in Books" class="row col-md-12">
				<div>
					<h3 class="title">{{book.title}}</h3>
					<span class="author">{{book.author}}</span>
					<span class="year">{{book.year}}</span>
					<span class="genre">{{book.genre}}</span>
				</div>
			</li>
		</ul>
	</div>
	<script src="scripts/angular.js"></script>
	<script src="js/app.js"></script>
	<script src="js/services/BooksData.js"></script>
	<script src="js/controllers/BookCollectionController.js"></script>
	<script src="js/bootstrap.min.js"></script>
</body>
</html>

The important bits here are these 3 directives the:

  1. ng-controller – tells the controller on which html elements it should operate.
  2. ng-repeat – repeats the content of the tag for every item in the selection. In this case, it tells the li and everything inside to repeat for every book in the Books variable we created and exposed in the controller
  3. curly braces notation – tells AngularJS to replace the object property with the value of that property. So the book.title will be replaced with the title of each book that the code iterates through

All the necessary scripts are referenced at the end of the file. The result of this code is a simple rendering of the book collection. Now we can move on to more fun properties of AngularJS.

Step 5: Voting functionality

I want to allow visitors to the website to vote on the books, so that I can make a top 10 list. In order to do that, I need to amend 2 files. First, I have to edit the view file so that it has the interface  to display points and vote. I also need to bind it the interface elements to the controller. Then I need to adjust the controller itself so it can handle the voting.

In the index.html, I will adjust the li element like so:

<li ng-repeat="book in Books" class="row col-md-12">
	<div>
		<h3 class="title">{{book.title}}</h3>
		<span class="author">{{book.author}}</span>
		<span class="year">{{book.year}}</span>
		<span class="genre">{{book.genre}}</span>
		<div class="row col-md-12 votes">
			<a class="voteUp" ng-click="voteUp(book)">+</a>
			<span class="points">{{book.points}}</span>
			<a class="voteDown" ng-click="voteDown(book)">-</a>
		</div>
	</div>
</li>

The extra div contains two links and a span. The span simply displays current amount of points. The links have ng-click directive which listens to the click directive on these elements and calls voteUp or voteDown functions. The functions (that we will write in the controller) have the book object passed to them. That means that for every li element, the voteUp function will have access to the correct book object and will be able to change the amount of votes.

And here comes the controller that takes care of the functions.

BookCollectionApp.controller('BookCollectionController', function($scope, BooksData){
	$scope.Books = BooksData;

	$scope.voteUp = function (book) {
		book.points++;
	}

	$scope.voteDown = function (book) {
		book.points--;
	}
});

In this controller, I create voteUp and voteDown functions on the scope (so that the view actually has access to them). The voteUp function adds one to book.points property value and voteDown, surprisingly, detracts one point from the book.points value.

Thanks to two-way binding, every time a user clicks on a plus or minus sign, the object will be edited and the new value will be displayed. Of course this application is not actually using any storage, so the edits will be lost between page reloads.

Step 6: Filtering with AngularJS

And now the moment we’ve all been waiting for. The super easy filtering in AngularJS. So in this app I want to be able to order the list according to some properties on the objects. I also want to display objects of only one type. To do that, I need to start by creating the interface to choose the filter/order by principle:

Order by:
<select ng-model="sortorder">
	<option value="default" selected>None</option>
	<option value="title">Title</option>
	<option value="author">Author</option>
	<option value="-points">Points</option>
</select>
Show:
<select ng-model="showGenre">
	<option value=" " selected>All</option>
	<option ng-repeat="genre in genres" value="{{genre}}">{{genre}}</option>
</select>

This code is added just under the div ng-controller directive. It creates two dropdown lists but I could just as well have lists with links instead or radiobuttons etc. What actually matters is the ng-model directive (you can call it what you like). I’ll use it in the list of books to inform it where it should look for the filter criteria.

Notice that value for points has a “-” sign in front of it. This is to ensure that items are ordered by points from the highest to lowest value and not the opposite (as is the default).

Because, I don’t know in advance what genres I might have in my collection, I create the list dynamically based on the books in the collection. The easiest way would be to simply type:

<option ng-repeat="book in Books" value="{{book.genre}}">{{book.genre}}</option>

This of course would mean that if I had two books of the same genre, the genre will be shown twice in the dropdown. So instead in my controller I will create a new array by pushing none-repeating genres. Here is how the piece of code looks:

$scope.genres = []
	angular.forEach($scope.Books, function(value, genre){
		if($scope.genres.indexOf(value.genre) == -1)
		{
			$scope.genres.push(value.genre);
		}
	});

Now in my view, I can iterate through genres knowing that in the controllers I took care to only store the relevant items.

When the interface is in place, I can take care of actually reacting to the filter parameters that the user has chosen. And here is where the real genius of AngularJS shows. All I need to do is amend this line of code in my view:

<li ng-repeat="book in Books | orderBy:sortorder | filter:showGenre" class="row col-md-12">

Now I told AngularJS to pay attention to sortorder and showGenre models and react to changes on them by applying respective sort orders and filters.

Et voila! Application is ready.

Building News Module with Umbraco v6

This is a small tutorial describing the process of building news module and recycling content in Umbraco v6. I go through the entire process of building a simple Umbraco website that includes a calendar with events, news page with news articles, home page that displays a selection of news and a calendar module that can be rendered on any page within the website.


Update: thanks to a hint from Jeroen Breuer I improved this tutorial a bit. You can do this tutorial as it is or have a look at the end of this post for an update and explanation.

Inaboxdesign.dk: Home screenshot

I am using Umbraco 6.0.3 with Razor and Twitter Bootstrap so that I don’t have to think much about the presentation. I hope you will find it useful and well described but as always with this blog, any and all feedback is very much welcome.

Set up

Start by creating an empty MVC project in Visual Studio. Go to Tools -> library package manager -> Manage NuGet Packages and install Umbraco CMS. You can also use WebMatrix instead. Once Umbraco is installed, go to config folder -> umbracoSettings.config in your solution explorer and find this snippet:

<!-- To switch the default rendering engine to MVC, change this value from WebForms to Mvc -->
<!-- Do not set useAspNetMasterPages to false, it is not relevant to MVC usage -->
WebForms

Replace it “WebForms” with “Mvc”. This will make sure that we are using MVC architecture and Razor engine in our templates and macros.

Run the solution and complete the installation with the database options of your choice. In the next step choose an empty installation

DocTypes

Any good Umbraco website starts with planning – so plan your docTypes carefully.In our case we will have the following docTypes and properties

  • FrontPage (properties: title – textstring)
  • NewsContainer (properties: title – textstring)
  • Article (properties: title – textstring, img – mediaUploader, snippet – RTE, showSnippet – true/false, content -RTE)
  • Calendar (properties: title – textstring)
  • Event (properties: title – textstring, date – Date Picker, img – mediaUploader, snippet – RTE, showSnippet – - true/false, content -RTE)
  • FrontPage doctype will be used to create the Home page at the top of the content tree. The editors will only create the title for this page. The rest of content will be pulled in from the Article and Event docType pages.
  • NewsContainer is not necessary but will make the content tree look much cleaner. It will also help to guide the editors when they create new items on the content tree. Same function is fulfilled by the Calendar.

The properties and docTypes should be fairly self-explanatory so let me just explain that the snippet property will serve to give the user control over what should be displayed on the Home page. If the showSnippet checkbox is checked the snippet will also show as the first paragraph of the Event or Article page.

You might have also noticed that Event and Article are almost identical when it comes to properties. The only difference is that Event docType includes date property. This means that we can have Event docType inherit from Article docType instead of creating all the properties twice.

InaBoxDesign.dk: docType tree

Next step is to actually create the docTypes. Start by creating all the docTypes and their properties. Make sure you create tabs to organize properties into groups. All docTypes should have matching templates.

Once all the docTypes are created and have their properties, you can build the structure of your website. In our small website the structure is fairly simple:

  • FrontPage is allowed at the root and has only two types of allowed children nodes: NewsContainer and Calendar
  • NewsContainer allows Article children
  • Calendar allows Event children

Now you can go ahead and create your basic content. Hint: install FamFamFam Icon package to make it easier for your future editors to discern between docTypes.

Content Tree

Templates

Next step is to present the content. I will use Twitter Bootstrap to make my site shiny but it is up to you if you want to do the same or build your own CSS.

To present the content we need to build templates. I start with Master, to make my life easier. All the other templates will be partials under Master and they will inherit the basic structure of the website. This way I don’t need to repeat the same markup.

Master

All the Master really does is to establish html structure of our website, load scripts and stylesheets and render the content of templates that inherit from it (@RenderBody()). It also renders the navigation macro (@Umbraco.RenderMacro(“Navigation”)) so that navigation will appear on all pages without the need to repeat the code. Isn’t this just neat?

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = null;
}
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>@Umbraco.Field("pageName")</title>
    	<meta name="viewport" content="width=device-width, initial-scale=1.0">
    	<meta name="description" content="">

	<link href="/css/bootstrap.css" rel="stylesheet"/>
    	<link href="/css/bootstrap-responsive.css" rel="stylesheet"/>
	<link href="/css/style.css" rel="stylesheet"/>

	<script src="/scripts/jquery.js"></script>
	<script src="/scripts/bootstrap.js"></script>
</head>
<body>
    @Umbraco.RenderMacro("Navigation")
    <div class="container">
        <div class="hero-unit">
            <h1>Hello, world!</h1>
            <p>This is a community website with news and calendar modules</p>
        </div>
	    @RenderBody()
    	 </div>
    <footer>
        <p>&copy; InaBox 2013</p>
    </footer>
</body>
</html>

Article

This template simply presents the content of any node with docType Article. It renders 3 macros: Image, Snippet and SideCalendar. They will be described further down in this post.

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = "Master.cshtml";
}
    <div class="row">
    <div class="span8">
        <h2>@Umbraco.Field("title")</h2>
        @Umbraco.RenderMacro("Image")
	 @Umbraco.RenderMacro("Snippet")
        @Umbraco.Field("content")
    </div>
    <div class="span4">
        <h2>Upcoming Events</h2>
        @Umbraco.RenderMacro("SideCalendar")
    </div>
    </div>

InaBoxDesign.dk:Article Page

Event

This template presents the content of any node with docType Event. It renders 4 macros: Date, Image, Snippet and SideCalendar. And again, keep reading to find more about them.

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = "Master.cshtml";
}

  <div class="row">
    <div class="span8">
        <h2>@Umbraco.Field("title")</h2>
	 <h4>@Umbraco.RenderMacro("Date")</h4>
        @Umbraco.RenderMacro("Image")
	 @Umbraco.RenderMacro("Snippet")
        @Umbraco.Field("content")
    </div>
	<div class="span4">
		<h2>Upcoming Events</h2>
		@Umbraco.RenderMacro("SideCalendar")
    	</div>
    </div>

InaBoxDesign.dk: Event page, Umbraco News Module

FrontPage

This template presents the content of the FrontPage node, our Home page. It renders only 2 macros: NewsModule and SideCalendar. These two macros provide most of the functionality in our website and they will be explained in detail.

	@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = "Master.cshtml";
}
    <div class="row">
    <div class="span8">
        <h2>@Umbraco.Field("title")</h2>
        @Umbraco.RenderMacro("NewsModule")
    </div>
    <div class="span4">
        <h2>Upcoming Events</h2>
        @Umbraco.RenderMacro("SideCalendar")
    </div>
    </div>

NewsContainer

This template is used by…surprise, surprise…NewsContainer docType. All it does, is to render NewsPage and SideCalendar macros. The first one pulls the content from child nodes of the the node (events under calendar page), the latter displays the next 3 upcoming events.

	@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = "Master.cshtml";
}

   <div class="row">
		<div class="span8">
			<h2>@Umbraco.Field("title")</h2>
			@Umbraco.RenderMacro("NewsPage")
			<p><a class="btn" href="#">View details &raquo;</a></p>
		</div>
		<div class="span4">
        	<h2>Upcoming Events</h2>
        	@Umbraco.RenderMacro("SideCalendar")
    	</div>
    </div>

InaBoxDesign: Umbraco screenshot: NewsContainer

Calendar

And lastly, the very succinct Calendar template renders the tilte of the page and CalendarPage macro. Most of the content on this page will be pulled in from its children – the events.

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = "Master.cshtml";
}
<h2>@Umbraco.Field("title")</h2>
	@Umbraco.RenderMacro("CalendarPage")

InaBoxDesign.dk:Umbraco Screenshot Calendar

Macros

Now comes the lifeblood of the website and the best part: functionality. It will be handled with macro scripts written with Razor.

I’ll start with the three simplest scripts: Date, Image and Snippet. Then I’ll move on to navigation and lastly, I’ll pull the content from Article and Event docTypes to display it wherever I want.

Date

The only reason to have this macro instead of a regular umbraco field is so that we will be able to convert Date property from Event docType into a string and display it in a format that makes us happy campers. In my case the format will be 07/05/2013. If you want to choose another way of displaying your date, have a look at this string format codes.

@inherits umbraco.MacroEngines.DynamicNodeContext

@Model.Date.ToString("dd/MM/yyyy")

Image

Again, this macro is not really necessary but it opens up future possibilities for manipulating the content. I find it most intuitive to only use templates for displaying the most basic umbraco fields and render everything else through macros.

@inherits umbraco.MacroEngines.DynamicNodeContext

<img alt="" src="@Model.Image" />

Snippet

This is another simple macro. You might remember that we gave our editor the option to choose whether they want to display the snippet on the article and event pages or if it should be hidden and only used on the front page as a teaser. In the Snippet macro we simply check if the ShowSnippet checkbox was checked. If yes, then we should display the snippet, if no…well, nothing to see here, move on.

@inherits umbraco.MacroEngines.DynamicNodeContext
@{
	if(@Model.ShowSnippet)
	{
		<div class="snippet">@Model.Snippet</div>
	}
}

Navigation

As the name suggests, this script renders the navigation by iterating through child nodes of the Home page. First we define the root node (var root = Model.AncestorsOrSelf(1)) and then we iterate through its children nodes (@foreach…) and wrap it all up in html markup from Bootstrap – no magic included.

@inherits umbraco.MacroEngines.DynamicNodeContext
@{ 
    var root = Model.AncestorOrSelf(1);
}

<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="brand" href="#">Our Community Website</a>
            <div class="nav-collapse collapse">
                <ul class="nav">
                    <li><a href="@root.Url">@root.Name</a></li>
                    @foreach (var page in root.Children.Where("Visible"))
                        { 
                            <li class="@page.IsAncestorOrSelf(Model, "active", "")">
                                <a href="@page.Url">@page.Name</a>
                            </li>
                        }
                </ul>
            </div>
        </div>
    </div>
</div>

CalendarPage

Similarly to NewsPage, the CalendarPage is a macro that pulls in the content from child pages to display it on Calendar (and Community News). To do this, it starts by checking if the current node has any children and then iterates through them with foreach statement, displaying its properties.

@inherits umbraco.MacroEngines.DynamicNodeContext

@if (Model.Children.Any())
{            
	foreach (var childPage in Model.Children)
	{
		<div class="row">
		    <div class="span12">
				<h4><a href="@childPage.Url">@childPage.Title</a></h4>
					@childPage.Snippet
			</div>	
		</div>
	}
}

NewsPage

This macro does exactly the same as CalendarPage but for NewsContainer docType.

@inherits umbraco.MacroEngines.DynamicNodeContext

@if (Model.Children.Any())
{            
	foreach (var childPage in Model.Children)
	{
		<div class="row">
		    <div class="span8">
				<h4><a href="@childPage.Url">@childPage.Title</a></h4>
				@childPage.Snippet
			</div>	
		</div>
	}
}

NewsModule

News Module is the juicy bit in our website (and the whole reason for this entire article). It is rendered on the front page and it pulls in the content from the 3 topmost Article docType nodes under the Community News node. It simply displays the community news on the Home page.

In the case of this macro we know that our Model (so our current page) refers to Home page. This is because of the structure we’ve established with docTypes. NewsContainer simply cannot be created anywhere else in the node tree.

Therefore we can start by checking if our Model has descendants of type NewsContainer and if NewsContainer has any children. If both of the conditions are satisfied we move on to…yup, you guessed it, iterating through NewsContainer’s children (a.k.a Articles) and display their title and snippet. Notice that we don’t want all the articles so we .Take(3) from the collection.

@inherits umbraco.MacroEngines.DynamicNodeContext
@if (Model.Descendants("NewsContainer").Any())
{   
	if(Model.Descendants("NewsContainer").First().Children.Any())
	{

		foreach (var item in Model.Descendants("NewsContainer").First().Children.Take(3))
		{
			<div class="row">
				<div class="span8">
					<h4>@item.Title</h4>
					@item.Snippet
					<p><a class="btn" href="@item.Url">View details &raquo;</a></p>
				</div>	
			</div>
		}
	}
}	

SideCalendar

This is a bit more complicated version of the previous macro that built news module. It also pulls in the content of 3 nodes of a certain type, events from under the Calendar page. However there are 2 major differences here. The first one is that the 3 nodes are ordered according to the date property.

The second difference stems from the fact that the macro will be rendered on multiple nodes of different types. We want to have the side calendar on the FrontPage, NewsContainer, Article and Event docTypes. This means that we don’t know what will be the exact relation of the node that renders the macro and the nodes that should provide the content (events). To deal with this problem is dealt with by defining the root node and finding Event nodes by crawling down from it.

The first thing we need to do is define the root node as the ultimate ancestor of Model. No matter where in the structure you are, the root is always either your model (if you are on the Home page) or an ancestor of your model (since all pages are created under the Home page).

The second step is to check if root has any children of the type Calendar. If it does, we create a variable that stores the first calendar node (we only have one so this simply means that its not a collection but rather a single node). Then we move on to checking if this calendar has any children (Have we created any events yet?). If it does, we organize them by date (OrderBy(“Date”) ), take the 3 topmost and store them in events variable.

And I think at this point we can all guess what happens next. Yup, it seems like Umbraco is all about iterating.

@inherits umbraco.MacroEngines.DynamicNodeContext

@{
    var root = Model.AncestorOrSelf();
	
	if(root.Descendants("Calendar").Any())
	{
		var calendar = root.Descendants("Calendar").First();
		
		if(calendar.Children.Any())
		{
			var events = calendar.Children.OrderBy("Date").Take(3);
		
			foreach(var item in events)
			{
				 <div class="row">
						<div class="span4">
							<h4>@item.Title</h4>
							<span>@item.Date.ToString("dd/MM/yyyy")</span>
							@item.Snippet
							<p><a class="btn" href="@item.Url">View details &raquo;</a></p>
						</div>	
					</div>
			   
			}
		}
	}
   
}

Update

So as mentioned at the beginning of the post, Jeroen asked the very good question of why using macros for date and image when it can be done in templates instead and he pointed me in the right direction for solutions.

It turns out the the syntax one uses in the macros is not exactly the same as in templates. It seems it has to do with different versions of Razor but let us not get into the topic right now

The point is that you can delete Date and Image macros and enter the following lines of code instead of the respective references to macros in your templates

  • Replace @Umbraco.RenderMacro(“Date”) with
@Umbraco.Field("date", formatAsDate:true)
  • Replace @Umbraco.RenderMacro(“Image”) with
<img src="@Model.Content.GetPropertyValue("Image")" alt=""/>

Summary

This write up should have taken you through all the necessary steps of creating a website that recycles its content with news module and calendar module. Hopefully, the explanations were clear and you will now be able to take this general tool and use it on your various projects.

I am looking forward to hearing about your experiences!

HTML/CSS Frameworks: pro and cons

Recently I’ve been thinking about the way I build websites and I realized that I could get much more effective if I developed some sort of process or method. So, naturally, I turned to css frameworks. But what I found, was a whole lot of discussion and contracting views. It seems that with frameworks, like with…well pretty much everything else on the web, you either love it or hate it.

Proponents of frameworks point out that frameworks organize and speed up your coding. They save time and make you a better web professional. They are also designed to keep the website looking the same in all modern browsers and even deal with the pesky ones (we all know who I’m talking about).

The opposition on the other hand argues that these frameworks are bloated and you will always end up stripping half of the code anyway. Another argument mentions the use of un-semantic and presentational class names.

Being a do-it-yourself kind of girl, I am not super excited about using a ready-made code. After all we all consider Dreamweaver to be the evil incarnated so aren’t frameworks a step in the wrong direction? And can a one-size-framework really fit all? Isn’t it better to spend a little bit more time and treating every website individually?

Dan Cederholm in Handcrafted CSS argues for writing one’s own framework. He gives an example of a very simple, bare-bone code for index.html, master.css and reset.css. He writes that ready-made frameworks are great for learning and quick and dirty prototyping. They can teach you some good code skills and challenge your coding habits. However, for the reasons mentioned above, he does not recommend them for actual development.

It seems that frameworks work for some people and for some types of websites but not for everyone and not always. It all depends on the context and maybe it’s good to have both options to work with. To really have an informed opinion,  I will try (and write about) several of the most popular frameworks. The next post will be about 960 grid system, but I will also look at blueprint and probably one or two others. Unless, during the trial period, any of the frameworks manages to completely change my worldview, I hope to finish this series with a home-made, bare-bone framework. It will be based on Dan Cederholm’s suggestion and what I’ve learned from the other frameworks.

So stay tuned for more on frameworks in the coming weeks.

Building first Umbraco 5 website: Partials

The post you are reading now is the last one in a series of four blog posts describing my experience with creating a relatively simple Umbraco 5-based website for a made-up coffee shop.

  1. Building first Umbraco 5 website: Document Types
  2. Building first Umbraco 5 website: Nodes
  3. Building first Umbraco 5 website: Templates
  4. Building first Umbraco 5 website: Partials

The posts are written in a form of beginners’ tutorial and will take you through all the steps necessary for creating the website. Disclaimer: However, please keep in mind that I am in no way an expert or professional in the field. Therefore I submit to you a description of a learning process rather than an expert tutorial and I ask you to read it as such. More than that, I encourage you to commen,t to point out mistakes or suggest better practices.In the first three posts I:

  1. Explained the concept of document types
  2. Analyzed my website from the perspective of document types
  3. Created document types necessary for the website
  4. Explained the concept of nodes and explained how they are created
  5. Build the document structure for the website we are creating
  6. Showed you how to display content on your website using templates
  7. Explained the way to attach external stylesheets and JavaScript files to your website

In this post I will talk about partials and how to use them in your website. I will also show you the code used to complete the website we were working on. I will explain what the partials do in broad strokes but I will not go into much details. After you go through all the steps in this post, your website will be ready to post online.

Step 1: Partials in Theory

Partials are the life blood of Umbraco. They make sure that your page is dynamic and not everything has to be done manually. They are basically snippets of code written with Razor, which is an ASP.NET programming syntax used to create websites with the C#. For example you might remember that we didn’t want to hard-code the navigation in the header. We didn’t want it because that would mean that with every new page created by the administrator of our page, we would have to go into the code and add a new <li> to our <nav> list.  Partials are exactly the thing that will save us from doing that. We will add a piece of code to our website that will check for all child pages of the root and display them as navigation.

Creating New Partials

  1. In back office go to settings
  2. Right-click on Partials and choose create
  3. Give your partial a recognizable name
  4. Remember to save after editing
Creating New Partials in Umbraco 5

Using Partials in your templates

  1. Go to your template
  2. Place your cursor in the code where the partial should be executed
  3. Choose Insert Partial View from top menu
  4. Choose your partial from the list
  5. Click insert
Inserting Partials in Umbraco 5

Alternatively you can also type: @Html.Partial(“yourPartialsName”)in the templates code.

Step 2: Partials in Practice

To get our website to work we need 4 partials:

  1. For displaying images
  2. For top navigation
  3. For listing events on events page
  4. For displaying content on Menu page

The image partial (called: image) is this:

@inherits RenderViewPage
@using Umbraco.Cms.Web;</pre>
<img src="@Umbraco.GetMediaUrl(@Model.Field(" alt="" />
<pre>

This partial is really just one line of code and you could use it directly in your templates. You can go ahead and replace all @Umbraco.Field(“image”) in your templates with img src=”@Umbraco.GetMediaUrl(@Model.Field(“image”).ToString())”. Placing it in a separate partial introduces more order and organization to your code. Note that if you don’t have an image picked in your content section, this partial will actually cause an error. A more complicated partial that checks if the image hiveId exists is necessary to avoid this error.

This is top navigation (called: navigation):

@inherits RenderViewPage
@using Umbraco.Cms.Web
@using Umbraco.Cms.Web.Macros
@using Umbraco.Framework

@{
    @* Walks up the nodes tree from the current page to the rootNode *@
    var rootNode = DynamicModel.AncestorsOrSelf.Last();
}

@* Checks if the rootNode has children *@
@if (rootNode.Children.Any())
{</pre>
<ul>
	<li>@* Adds the rootNode to the navigation *@ <a href="@rootNode.Url">@rootNode.Name</a></li>
@* For each childPage of the rootNode add the child to the navigation as list item *@ @foreach(var childPage in rootNode.Children) {
	<li><a href="@childPage.Url">@childPage.Name</a></li>
}</ul>
<pre>}
  1. It starts by defining what rootNode is
  2. Then it checks if rootNode has children
  3. If there are children it starts by listing the rootNode (in our case the Home page)
  4. Then it lists the page name and makes it a link

Notice that we add HTML elements that should be created. For example the navigation items are enveloped in an unordered list and list item tags.

Listing events on events page (called: Sub Navigation):

@inherits RenderViewPage
@using Umbraco.Cms.Web
@using Umbraco.Cms.Web.Macros
@using Umbraco.Framework

@* Checks if the rootNode has children*@
@if(DynamicModel.Children.Any())
{</pre>
<div class="lable"><nav id="subnavi">
<ul>@* For each childPage of the rootNode *@ @foreach (var childPage in DynamicModel.Children) {
	<li><a href="@childPage.Url"> @childPage.Name
@childPage.Date
 </a></li>
}</ul>
</nav></div>
<pre>}

This partial basically does the same thing as the previous one, except it only lists the descendants of the page on which the partial is placed. In our case it will list all the particular event pages on the Events page.

Displaying content on Menu page (called: Inherit Content):

@inherits RenderViewPage
@using Umbraco.Cms.Web
@using Umbraco.Cms.Web.Macros
@using Umbraco.Framework

@* Check if rootNode has children*@
@if(DynamicModel.Children.Any())
{
    foreach (var childPage in DynamicModel.Children)
    {
    <ul class="menu">
        <li>
           <h1 class="section">@childPage.heading</h1>
           @if(childPage.Children.Any())
            {
                foreach (var grandchildPage in childPage.Children)
                {
                    <li>
                      <h3 class="item">@grandchildPage.menuItem</h3>
                      <span class="price">@grandchildPage.price</span>
                    </li>
                }
            }
        </li>
     </ul>
    }
}
  1. It checks if there are any children from the page on which this partial is used (these are menu sections)
  2. It lists the heading of the child page
  3. It checks if the childPage has any children (these are menu items)
  4. It lists the childPage child’s menuItem property value and price property value

Linking partials to templates:

  1. In your templates insert image partial everywhere you have @Umbraco.Field(“image”)
  2. Insert Inherit Content at the bottom of Menu template
  3. Insert Navigation into the Layout template between the <nav></nav> tags
  4. Insert the Sub Navigation partial into Events template just before the last </div> tag

The partials used in this website are all variations of the partials that you can find in the Umbraco 5 documentation on GitHub. You can learn much more by browsing this page.

Building first Umbraco 5 website: Templates

The post you are reading now is a third one in a series of four blog posts describing my experience with creating a relatively simple Umbraco 5-based website for a made-up coffee shop.
  1. Building first Umbraco 5 website: Document Types
  2. Building first Umbraco 5 website: Nodes
  3. Building first Umbraco 5 website: Partials

The posts are written in a form of beginners’ tutorial and will take you through all the steps necessary for creating the website.

Disclaimer: However, please keep in mind that I am in no way an expert or professional in the field. Therefore I submit to you a description of a learning process rather than an expert tutorial and I ask you to read it as such. More than that, I encourage you to commen,t to point out mistakes or suggest better practices.

So let’s get on with it. In the first two posts I

  1. Explained the concept of document types
  2. Analyzed my website from the perspective of document types
  3. Created document types necessary for the website
  4. Explained the concept of nodes and explained how they are created
  5. Build the document structure for the website we are creating

In this post I will explain how to make the content display on your website, using templates. I will begin by describing what templates are and how they look like. Then I will show you what to do to make your content display and how to style it.

Then I will move on to practical part of this post and show you how to create templates that will result (almost) in the website I showed you in the first post.

Step 1: Templates in Theory

Templates are files that store your html together with Razor syntax. The latter accounts for the dynamic aspects of your site, such as displaying content or generating navigation that updates automatically depending on what nodes you create. In this post I will only write about displaying content using Razor syntax but in the next one, you will learn about simple partials.

To create or edit templates:

  1. Go to back-office
  2. Choose Settings
  3. Click on Templates to see templates or right click on Templates to create a new one

creating templates with Umbraco 5

Templates folder always contains Layout which is your basic template. If you created any templates when creating document types (see: Document Types) then you will be able to see them here as well.

If you haven’t done anything with your layout template yet, this is how it’s going to look like.

<!DOCTYPE Html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    @RenderSection("head", false)
</head>
<body>
    @RenderBody()
</body>
</html>

This is your very basic Html5 document. It contains very little Html and no content. The reason for it is that you will add more Html and content in different templates that will then be rendered by Layout. If you have little experience with CMSs you might find it a bit confusing at first. But once explained, it will start making perfect sense. The two things you need to notice in the Layout file are:

@RenderSection(“head”, false)
@RenderBody()

These two belong with the Razor syntax and are basically responsible for rendering elements of templates that are child to Layout.

@RendeBody() will render everything that you put in the child template of Layout unless you mark it as a different section

@RenderSection(“head”, false) will render everything in the child template of Layout that you enter into section you define and call “head”. False means that the section is not required so a child template without this section will be rendered without errors (and true would of course mean the opposite).

Creating child templates with Umbraco 5

To create child template right click on layout and choose create. Then enter the name of your template (leave file extension as is) and press next.

Example of Child Template in Umbraco 5

You can now see that “New” my example child template is positioned underneath Layout in the template tree.
The first three line of code in the template editor are of no importance to us at the moment and they should stay as they are.
The next 3 lines of code define which template should be the parent of this one and provide the Html structure for it:

@{
Layout = “_Layout.cshtml”;
}

You can change this by changing the code or by choosing a different file from the dropdown menu in the top navigation of template editor. Once you change the parent template and save it, the template tree in the left window will change as well.
The next piece of code is how you define a section. Everything you enter between the curly brackets will be rendered in this section. Here we have head section that is rendered in the head of your html document but you can also define sidebar or footer section or any other section you see fit.

Everything you enter below the last curly bracket will be considered the body content and will be rendered by @RenderBody() in the Layout.

How to make content display on your website:

You should know by now how to assign templates to document types and nodes but if you can’t remember look back to posts 1 and 2 in this series.

For content to display on your website, you need to tell Umbraco which content should be displayed and where it should be displayed.
In the example Umbraco website above, I also created a node called Home of the document type Text Page, which has 2 properties called Heading (alias: heading, type: textstring) and Body Text (alias: bodyText, type:textarea). This document type is linked to template New.

Once you create the document type and node and fill it with some content you can move on to editing the template itself. (But don’t forget to publish your node).

  1. Go to Settings>Templates>New
  2. In the Template Editor window click on the “Insert an Umbraco Page Field” icon (second from the left)
  3. In the pop-up window open the Field dropdown

Insert Umbraco Property Button

Insert Umbraco Property Pop-up

You can see that you have several options to choose from bodyText and heading are the two properties you added. CurrentTemplateId, Name and UrlName are default fields and allow you to call metadata for the node (such as url or name).

  • Choose heading and click Insert
  • Make sure that the new line of code (@Umbraco.Field(“heading”)) is inserted below the last curly bracket (we want it to be rendered as body)
  • Repeat the process for bodyText

In the dropdown menu you will always be able to see ALL properties, created in ALL document types for your website. That means that you can insert a property that does not appear in the node that is linked to the template you are working on. This will not have any consequences. But that means that to limit the size of the dropdown it makes sense to call main body text in all document types “bodyText” and all headings “heading”( and all sidebar headings “sidebarHeading” etc.). This is also why it is so important to give descriptive names to properties rather than “prop1” “prop2” etc.

The line of code that actually inserts the content is very short and instead of inserting the property you can simply type the code (provided that you remember the alias you want to use).

  • Save template and navigate to your website (if you are not sure how to do that, go to your node, General Properties tab and click on the link)

On your website you should now be able to see the content you inserted in your Home node. Inspect the source code of the website to see where and how the content was inserted.

If you used textstring and textarea you will see that the content has no formatting whatsoever. It is just pure text .To give the text some format, go back to Template Editor and change the last two lines of code to:

<h1>@Umbraco.Field("heading")</h1>
<p>@Umbraco.Field("bodyText")</p>

Save the template and reload your Home page. Now content looks different and if you check the source code you will see that it also has proper markup.
Of course hardly any body text will consist of only one paragraph. This is solved by giving the bodyText property Rich Text Editor type. Every time you hit enter in the editor, new paragraph is created so when you call @Umbraco.Field(“bodyText”) the content will have the proper markup. You can edit the markup from within the RTE by clicking on the HTML button.

Adding Style

To add style to your content you proceed as per usual with your regular HTML/CSS websites. The only difference is that you can do it from within Umbraco.

  1. In back-office go to Stylesheets
  2. Click on the stylesheet you want to edit or right click on Stylesheets to create a new one

Umbraco 5 Stylesheet

RTE stylesheet refers to your Rich Text Editor and we will not be interested in that now. Site stylesheet is a default stylesheet and you can use if it you wish to, but it is not necessary.
For the purpose of this example we will create a new stylesheet called Layout and we will create the following styles:

h1, p
{
color:white;
background-color:black;
width:350px;
padding:10px;
}

Once you save this stylesheet move on to your Layout template and add this line of code:

<link rel="stylesheet" href="/content/styles/layout.css">

This line should go after the title tag. As you can see you link to your css files exactly the same way as you would otherwise. The only difference is the path which is a bit difficult to find the first time you work on your templates.

  • Images are also stored in the content folder: /content/images/yourimage.jpg
  • Jquery scripts are in: /scripts/jquery/yourscript.js

You can now navigate to your website and see the changes.

Step 2: Templates in Practice

Let’s move on to the New Coffee Café page we started building in previous posts.
Begin by creating the following templates:

Templates

Layout

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>

    <link rel="stylesheet" href="/content/styles/reset.css">
    <link rel="stylesheet" href="/content/styles/layout.css">

    @RenderSection("head", false)

</head>
<body>
    <header>
      <span>New Coffee Cafe</span>
      <nav>
      </nav>
    </header>
    <div id="content">
    	@RenderBody()
    </div>
    <footer>
      <div>
      <h3>Address: Green Street 25, NY</h3>
      <h4>Phone: 24 84 12</h4>
      </div>
    </footer>
</body>
</html>

Event

@inherits RenderViewPage
@using System.Web.Mvc.Html;
@using Umbraco.Cms.Web;
@{
	Layout = "_Layout.cshtml";
}

<div id="left">
  <h1>@Umbraco.Field("heading")</h1>
  <h2>@Umbraco.Field("date") @Umbraco.Field("cost")</h2>
      @Umbraco.Field("image")
      @Umbraco.Field("description")
</div>

<div id="right">
  <h1>@Umbraco.Field("headingRight")</h1>
      @Umbraco.Field("addressAndDetails")
</div>

Events

@inherits RenderViewPage
@using System.Web.Mvc.Html;
@using Umbraco.Cms.Web;
@{
	Layout = "_Layout.cshtml";
}

<div id="left">
  <h1>@Umbraco.Field("leftHeading")</h1>
      @Umbraco.Field("image")
      @Umbraco.Field("bodyText")
</div>

<div id="right">
  <h1>@Umbraco.Field("heading")</h1>

</div>

Menu

@inherits PartialViewMacroPage
@using Umbraco.Cms.Web
@using Umbraco.Cms.Web.Macros

@inherits RenderViewPage
@using System.Web.Mvc.Html;
@using Umbraco.Cms.Web;
@{
	Layout = "_Layout.cshtml";
}

@section head
{
	<link rel="stylesheet" href="/content/styles/menu.css">
}

Text Page


@inherits RenderViewPage
@using System.Web.Mvc.Html;
@using Umbraco.Cms.Web;

@{
	Layout = "_Layout.cshtml";
}

<div id="left">
  <h1>@Umbraco.Field("leftHeading")</h1>
      @Umbraco.Field("image")
      @Umbraco.Field("bodyText")
</div>

<div id="right">
  <h1>@Umbraco.Field("heading")</h1>
  <div class="lable">
    <ul>
       <li>@Umbraco.Field("row1Lable")</li>
       <li>@Umbraco.Field("row2Lable")</li>
       <li>@Umbraco.Field("row3Lable")</li>
       <li>@Umbraco.Field("row4Lable")</li>
       <li>@Umbraco.Field("row5Lable")</li>
       <li>@Umbraco.Field("row6Lable")</li>
    </ul>
  </div>
  <div class="value">
    <ul>
       <li>@Umbraco.Field("row1Value")</li>
       <li>@Umbraco.Field("row2Value")</li>
       <li>@Umbraco.Field("row3Value")</li>
       <li>@Umbraco.Field("row4Value")</li>
       <li>@Umbraco.Field("row5Value")</li>
       <li>@Umbraco.Field("row6Value")</li>
     </ul>
  </div>

</div>

Then move on to Stylesheets and create the following stylesheet with the following code.

Layout

body{
  width:1000px;
  background:white;
  margin:auto;
  font-family:"Arial Rounded MT Bold";
}

#content{
  width:1000px;
  background:#D6D3C2;
  float:left;
}

header{
  background:#666666;
  height:200px;
  color:#FFD34F;
  padding-top:30px;

}

header span{
  font-size:50px;
  margin-left:30px;
  margin-top:30px;
}

footer{
  background:#666666;
  clear:both;
}
footer div{
  width:1000px;
  margin:auto;
}

footer h3, h4{
  font-family:"Arial Rounded MT Bold";
  color:#FFD34F;
  text-align:center;
}

nav ul{
  margin-top:104px;
  float:right;
}

nav ul li{
  float:left;
  border: 1px solid #D6D3C2;
  padding:10px;
}

nav ul li a{
   color:#FFD34F;
   text-decoration:none;
   font-size:25px;
}

nav ul li a:hover{
   color:#FFD34F;
   text-decoration:underline;
   font-size:25px;
}

nav#subnavi ul{
   margin-top:-5px;
   width:200px;
   float:none;
}

nav#subnavi ul li{
   padding:0px;
}

nav#subnavi ul li a{
   margin-top:-10px;
   color:black;
   font-size: 15px;
   line-height:20px;

}

nav#subnavi ul li a:hover{
   text-decoration:underline;
}

h1{
  font-size:25px;
  color:#666;
  padding:40px 40px 40px 0;
}

h2{
  margin-top:-37px;
  margin-bottom:20px;
  font-size:15px;
  font-family:"Myriad Pro";
}

div#left {
  width:550px;
  margin-left:40px;
  margin-bottom:40px;
  float:left;
}

div#left img{
   margin-right:15px;
   float:left;
}

div#left p{
   font-size:15px;
   font-family:"Myriad Pro";
   line-height:18px;
}

div#right{
   margin-left:690px;
}

div#right p{
   margin-bottom:10px;
   line-height:18px;
}

.lable{
   float:left;
   margin-right:30px;
   line-height:20px;
}

.lable ul li a p{
  font-size:13px;
  font-family:"Myriad Pro";
}

.value{
   font-family:"Myriad Pro";
   font-size:15px;
   line-height:20px;
}

Menu

ul.menu{
   float:left;
   margin:15px 30px 30px 15px;
}

h1.section{
   padding:2px;
   width:200px;
   background:#FFD34F;
   font-size:18px;
   margin-bottom:9px;
}

h3.item{
  float:left;
  width:190px;
}

Reset

/* http://meyerweb.com/eric/tools/css/reset/
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
  1. If you now navigate to the website you will see that it looks almost as it should. The few things that are missing and/or look wrong are listed below. And I will fix them using partials. You can read about it in the next post.
  2. Instead of images you will see a long string of letters and numbers. This string is the id of the media item. This is the strangest little quirk of Umbraco. In order to display media content you need to use Razor syntax to convert the media id into an actual image. It seems strange and I don’t know why this solution has been implemented.
  3. There is no navigation. We could of course hard code navigation into our templates but that means that when user creates new nodes the navigation will be outdated. Instead we will make Umbraco dynamically generate the navigation.
  4. On the Events page no event list is visible. And again we could hard code the list but the dynamic solution makes so much more sense.
  5. The Menu page is empty. The reason for that is that we never told the Menu template to render the content from Menu Sections and Menu Items.
We will look at all these problems in the next post and solve them with Partials – the life force of Umbraco.

Building first Umbraco 5 website: Nodes

The post you are reading now is a second in a series of four blog posts describing my experience with creating a relatively simple Umbraco 5-based website for a made-up coffee shop.
  1. Building first Umbraco 5 website: Document Types
  2. Building first Umbraco 5 website: Nodes
  3. Building first Umbraco 5 website: Templates
  4. Building first Umbraco 5 website: Partials

The posts are written in a form of beginners’ tutorial and will take you through all the steps necessary for creating the website.

Disclaimer: However, please keep in mind that I am in no way an expert or professional in the field. Therefore I submit to you a description of a learning process rather than an expert tutorial and I ask you to read it as such. More than that, I encourage you to commen,t to point out mistakes or suggest better practices.

So let’s get on with it. In the first post I:

  1. Explained the concept of document types
  2. Analyzed my website from the perspective of document types
  3. Created document types necessary for the website

In this post I will show how one goes about creating pages in Umbraco 5 and filling them in with content.

Step 1: Nodes in Theory

Nodes are elements in your content structure. Most often 1 node equals 1 page but they can also be pieces of content that will be rendered on their parent pages.

To create a node:

  1. Go to back-office
  2. Choose Content from the bottom menu
  3. Right click on the Content in the website structure tree
  4. Click Create
  5. Enter the name and choose document type from the dropdown menu

Creating Nodes in Umbraco 5

When you create the first node, you will have the chance to choose from all previously created document types. But when you create child nodes only document types allowed as children of the parent node will appear in the dropdown.

For example you may recall that Menu document type allowed only child pages of the Menu Section type. Therefore when you try to create a child node you will only be given one choice.

Choosing document type in Umbraco 5

To create child nodes right click on the node you want to be the parent, choose create and the rest of the process is the same.

Once you hit Next you will be taken to the node editing tabs.

The node editing tabs section looks different depending on the document type of the node. For example you might remember that when we created Text Page document type we created two tabs: content and sidebar. We also placed several properties in each of the tabs. Here is how this looks once you create a node with Text Page document type:

Example Node in Umbraco 5

You can see that the tabs you created in document type section become actual tabs in the content section. And properties become input fields (or content/media pickers).

An important tab is the General Properties tab. It is a default tab that contains all meta information about this node. You can always add properties to it, but most of the time it makes more sense to organize your content input fields on separate tabs.

General Properties Tab in Umbraco 5

The particularly interesting field on this tab is the Selected Template dropdown. If your document type allows more than one template you will be able to change it here. Templates are the files containing Html (and possibly some Razor syntax) that govern the display of content and I will write about them in the next post.

The default value here is the template you’ve selected as default for this document type.

Once you change something or fill in some content remember to click on the blue floppy disk on the left side of the top menu to save your changes.

If you have just created a node you will notice that its name in the website content structure window is in gray.

Unpublished Node in Umbraco 5

The reason for this is that the node is not published yet and cannot be accessed through a link. To publish a node, click on the floppy disk and globe icon. Now the name is in black and in the general properties tab you will be able to see the direct link to this node.

Published Node in Umbraco 5

Step 2: Nodes in Practice

Before we will go ahead and create any nodes, we should start with uploading a few images to Umbraco media library so that we can use them as content.

  1. From the bottom menu choose Media
  2. Right click on Media and choose create
  3. Fill in the name and choose image from the dropdown
  4. Upload file
  5. Remember to publish the image by clicking on the floppy disc and globe icon

For the purpose of this tutorial you will need at least one image but the more the merrier.

Now that we know how to create nodes and we have media prepared, we can try this knowledge in practice and create nodes for our website. As you go along with the steps below, enter some content into each of the nodes.

Content Tree in Umbraco 5

You can look back to the previous post to see what document types we created for different pages in our website but I will also repeat it quickly here.

  1. Home node is of type Text Page. It is created as a child of Content and that means that it will be the default page that visitors of the page see when they enter your URL. All other nodes have to be descendants of the Home node.
  2. Events is also Text Page
  3. Baking Workshop, Poetry Reading etc. are of course pages for particular events. They are therefore child nodes for Events node and are of the type Event. You can create as many or as few of these as you wish (but for the purpose of this tutorial it would be best to have at least 3). The names don’t matter either.
  4. Menu is of the type Menu. It does not have any content fields to fill in because it will serve us as a content container. You will learn how to use it in the following posts.
  5. Food, Drink, Desserts etc. are of Menu Section document type and are child nodes of Menu. Feel free to create as many of them as you wish but make sure to have at least 3 (for the purpose of the tutorial)
  6. In each of the Menu Section you can now create child nodes of the type Menu Item. And again it is up to you how many items will there be in every Menu Section.

Menu Sections and Menu Items are separate nodes just like Home or Events. But they will not become separate pages on your website. They will be chunks of content that we will display when user visits the Menu page.

Now that you have created the node structure, remember to fill all the nodes with content and publish them.

At this point you might have tried to navigate to your website in a browser and discovered that the website is completely empty despite the fact that you typed in some content and published the pages. This is because we haven’t actually told the templates to display anything and so they display empty Html documents. In the next post in this series I will discuss how to make templates display your content so stay tuned for that.

Building first Umbraco 5 website: Document Types

  1. Building first Umbraco 5 website: Document Types
  2. Building first Umbraco 5 website: Nodes
  3. Building first Umbraco 5 website: Templates
  4. Building first Umbraco 5 website: Partials

I have been working with the Danish-made CMS, Umbraco 5 for the past few weeks. The experience was both good and bad (read here about my first impressions and here about resources) but definitely interesting enough to share. It resulted in a series of posts, first of which you are reading now.

The series will describe my experience with creating a relatively simple Umbraco 5-based website for a made-up coffee shop. I will try to describe it in a step-by-step tutorial-like way, that is to say that I will spare you the description of every single mistake I made or every single place that got me stuck. I will however point out the pitfalls and sticky points, based on my experience. For the moment I have no possibility to host the website online so no demo is available but I will try to rectify this as soon as possible.

Disclaimer: However, please keep in mind that I am in no way an expert or professional in the field. Therefore I submit to you a description of a learning process rather than an expert tutorial and I ask you to read it as such. More than that, I encourage you to comment to point out mistakes or suggest better practices.

So here it comes.

Step 1: Design

While it is possible to code your website from within Umbraco backoffice it seems to me that this is an ineffective practice. I started by designing and HTML/CSS coding my website before I got anywhere near Umbraco.

The HTML/CSS part will come handy in one of the following posts but we can forget it for the moment. These are the quick designs I made for this test website:

Front Page

Front page design
Events Page

Events page design
Particular Event Page

Event Design Page

Menu Page

Menu Page design

Step 2: Document Types in Theory

To do anything in Umbraco you have to start with document types. These are the “definitions” for your content holders, the nodes. They govern the type of content your user will be allowed to enter in her pages.

To create document types, you need to start by deciding how many different types of pages you have and what content you would like to store in them. The types of pages are not described by the design or layout but rather by the types of content that appears on them. For example a hypothetical gallery and an article will be different document types because one holds images and the other holds mostly text and maybe an illustration. On the other hand a hypothetical article and an about page might well be the same document type even if they have very different d

esign because they both hold mostly text and possibly an image.

It is perfectly possible to create a document type for each and every page you are planning to have in your website but this is a nightmare to maintain and will effectively defeat the purpose of using CMS for quick edit of content. In fact I suggest striving for organization and simplicity when working with Umbraco as this is where its strength lies.

So let’s see how to create document types in Umbraco 5:

  1. Creating document types in Umbraco 5Go to backoffice
  2. Click Settings
  3. Right Click Document Types
  4. Choose Create
  5. Type name of the Document Type and choose if a template with a matching name should be created (it’s not very important because you can always create and delete templates later)

In the Document Type window you will see 4 tabs:

Info

These are general meta properties of your document type. The only one you could consider changing at this stage is the Icon. Different icons help users understand the differences between different types of nodes. This will become clearer as you read on.

Creating Document Types

Composition

This tab allows you to establish the relationship of your document type with other document types and/or templates.

  • Inherit from – this option allows you to choose if some properties of other document types should be inherited by this document type. This is useful for properties such as keywords or meta description. You want to have these type of properties on every page so instead of adding it in every document type you can just set a document type for SEO from which all other document types inherit.
  • Allowed children – this option allows you to establish what pages can be created as children of this document type. In our case that means for example that the Event page document type should allow for Particular Events pages as children.
  • Inheritable only – if chosen will prevent users from creating this node in content section of the backoffice. This again is useful in terms of SEO for example. You don’t want your user to create a page with keywords and description that is published and available as part of the website. Instead you can make the SEO document type inheritable only and make all other document types inherit from it. These means that on each page users will be asked to enter SEO properties.
  • Allowed templates – they are exactly what you think they are. Should your article page have only one layout or should it also have a high-contrast design? This is where you decide if the person creating the page should be guided to the default layout or be allowed to choose from a number of them.
  • Default template – this is also self-explanatory

Properties

This tab is also rather easy to understand. Here is where you create new properties which are basically types of content your users will be allowed to input.

  1. Click on the Click here to add a new property button to add a new property (sic!).
  2. Type the name of your property (ex. Heading, Body Text or Date).
  3. Alias will be filled automatically but you can change it if you need to. It is how Umbraco refers to this property.
  4. Data Type dropdown allows you to choose what kind of content users should be allowed to enter. The most common data types seem to be Rich Text Editor (RTE) which is a typical WYSIWYG kind of editor, Textstring and Textarea which are input fields that do not allow any formatting, and Media Picker which allows you to choose previously uploaded images etc.
  5. Below Data Type you also have Tab dropdown where you choose which tab in content editing section your property should be on. Most commonly it is Content tab (but you can also add Images, SEO or any other tab you can think of).

Document Type Properties Tab in Umbraco 5

Tabs

This tab allows you to create and administrate tabs in the content section. It will start making more sense when we get to the content part in one of the following posts.

Step 3: Document Types in Practice

The pages I designed for the coffee shop can be analyzed from the content perspective in the following way (for the purpose of this website we will ignore the header and footer as they will be for the most part hardcoded, menu will be described in a later post):

1. Front Page

  • Left side heading
  • Image
  • Text block (content text)
  • Right side heading
  • Right side text

2. Events Page

  • Left side heading
  • Image
  • Text block (content text)
  • Right side heading
  • Right side text

3. Particular Event Page

  • Left side heading
  • Date
  • Cost
  • Image
  • Text block (content text)
  • Right side heading
  • Right side text

4. Menu Page

  • Menu section headings
  • Menu items
  • Menu items prices

You will notice that Front Page and Events Page have exactly the same type of content. It will therefore require only one document type, Text Page. The name of the document type depends on you but it is a smart idea to make it descriptive. This document type will contain the following properties (or content fields):

Text Page properties

Notice that I created 2 tabs: content and sidebar. This is the way I choose to organize the content editing section. You can do the same or choose to keep all the properties on one tab.

The solution I used above is not optimal. Row1Lable and Row1Vaule correspond to day of the week and the times the café is open on these days. That of course will prove too few lable/value rows if the owner chooses to have the café open in different times each day of the week. I took a leap here, accounting for the most likely scenario. There are two ways that this can be avoided. One is to use RTE and instruct the user to enter input as a list and add proper styles. But frankly, we all know you can not rely on users to do what you ask them to. I explain the second, most effective solution, below (in Menu document type).

This document type will allow child pages of the type Text Page and Menu (and again this is something that will make more sense when we get to the website structure) and it will not inherit anything (I ignore SEO in this example). The only allowed and also default template for this page will be Text Page.

Particular Event Page has almost the same content as the 2 previous pages and could be dragged under the same document type. That would mean that the user could supply Date and Cost also for Front Page and Events Page and I would have to make sure that in my template I ignore this fields so that they are not rendered on the these pages. But for the sake of cleanliness I will give it a separate document type, Event Page. These also means that I can make the sidebar on this page more flexible and use RTE for Address and Details text section.

Event Page Properties

This document type will not allow any child pages and it will not inherit anything. The only allowed and also default template for this page will be Event.

And lastly, we have Menu Page which is a bit more complicated than the previous pages. The first impulse you might have (as I did) was to create a document type, call it Menu Page and be done with it. However this would mean that we give the user/owner of the café a limited amount of menu sections and menu items. They could have food, drinks and desserts but if they wanted to have alcoholic drinks they would have to come back to us and ask for a new property. So the problem is the same as in the Text Page document type.

This time I wasn’t willing to guess how many food items does the owner of the café plan to have from now to eternity and so instead of 1 document type, I made 3.

Menu

  • Has no properties
  • Allows Menu Section children
  • Has Manu template

Menu Section

  • 1 property: Heading (textstring)
  • Allows Menu Item children
  • Has no template

Menu Item

  • 2 properties: Menu Item (textstring) and Price (integer)
  • Allows no children
  • Has no template

This way the owner of the café is able to create as many Menu type pages as he wishes. For the Menu type page he can create child nodes of Menu Section type (and again, he can create as many child nodes as he wishes) and for each of the Menu Section types he can create as many Menu Item types as he wishes. For example:

Example of content structure in Umbraco 5

In the next blog posts I will explain how to make the Menu page display Menu Section and Menu Item pages’ content but for now don’t worry about how to do that.

This is where I stop this blog post since it grew quite large as it is. The next blog posts in this series will cover:

Post 2: Creating and Publishing pages
Post 3: Templates
Post 4: Adding the magic: Partials

Day 37: Umbraco 5: Resources

Umbraco logoIf you follow this blog a little bit, you might have seen my post from last week about Umbraco 5, where I complained about the lack of documentation for the project. As it turns out, my complaints were heard at “the top”. Niels Hartvig, the founder of Umbraco, was so kind as to not only comment on the post, but also write to me. He let me know that the documentation is being worked on and the team is happy for user input on the matter. I was also invited to take part in the upcoming CodeGarden conference to learn more about the project. Now, that’s what I call a great customer support :) . I am looking forward to the conference and getting to know the community behind Umbraco.

Meanwhile, the Umbraco team has just announced today that the documentation for Umbraco 5 is now available on github. So far it doesn’t have that much content (just an installation guide and a few partials) but it is a good start and a step in the right direction. Certainly an address worth keeping and returning to on regular basis, if you are thinking seriously about Umbraco 5.

While the github site is still a work-in-progress, one has to look for resources all over the net. And here is a list of a few websites, I found useful so far:

  1. A look at the basic parts of building a site with Umbraco 5 RC2 - this post will be especially useful to those who already know Umbraco 4 because it spends a lot of time compering the two versions
  2. Umbraco Video Tutorials - the tutorials refer to Umbraco 4 but some, especially basic, things are the same in both versions
  3. github gist partials by Warren Buckley - razor code snippets to cover some basic functionality (various navigations, RSS etc.)
  4. Introduction to Razor by Scott Guthrie – this isn’t the most “beginner grade” explanation as it assumes some knowledge of programming but it is, nevertheless, well explained.
  5. More Razor posts – Scott Guthrie wrote a series of blog posts about Razor (see the links at the beginning of his post) and I found that each of them was at least partly useful for learning the basics of this syntax.

This list is by no means exhaustive and I am sure you will able to find more valid resources once you start digging.  But I hope you’ll find these links useful.

If you have any more good Umbraco 5 resources do share them with me. 

Day 34: Umbraco 5 for Beginners

Umbraco logo

Quick editors note: as corrected by Niels Hartvig, the course in Denmark for level 1 certificate in Umbraco costs 900,00 € +tax and not over 2.000 as previously stated. Apologies for the mistake.

I spent this entire week working with Umbraco 5 and it’s about time to sum up my experience with this Danish-made CMS system. Let’s start with some background information. Before Monday my only knowledge of Umbraco was that it existed, was free and was based on .NET technology. So you can see that I did actually begin from scratch.

You can learn more about the CMS here but let me just tell you what I’ve  learned this week:

Umbraco is organized into 3 parts (and this is just a simplification to explain things to you):

  1. Nodes (which are either pages or page elements depending on the complexity of the design) – these are the elements that basically constitute your website. Website admin creates or deletes nodes and edits their content.
  2. Document Type – here is where you decide what kind of content is allowed on particular type of pages. For example About Us page could have a document type of Text Page and thus be allowed to have Heading, Body Text and an Image while at the same time Menu page is of type List and is only allowed to have a Heading and a List. It is totally up to the developer of the website what document types to create, how to call them and what to put into them. It is then up to the admin of the website to assign this or that type to the page he is just creating.
  3. Templates – this is where the “magic” happens. A template contains html and Razor code that structures and displays the content. Here, you also reference your JavaScript and stylesheets. Until a page is assigned a template it will not display any content even if admin entered it.

Once you understand the relationship between these three elements you are well on your way to creating your website. Unfortunately, there a few obstacles on your way.

1. Razor Code

Umbraco website claims that the only thing you need to know to start creating your website is HTML and CSS. And this is true but only to a very small extend. After all you do not use CMS to have to hard code your navigation. And if you want to have you navigation update automatically when you create new page, you need to know Razor (or asp syntax if you are using previous versions of Umbraco). And any more complicated juggling with the content/data will definitely require a well-versed developer. This also apply to more complex website layouts.

This of course is a trade of because it means that Umbraco is very flexible and you have total control over the code. Nevertheless some ready-made snippets of code for the most obvious functionality that repeat on nearly every website would definitely be an improvement.

2. Serious Lack of Resources

While there are some materials for Umbraco 4 there is pretty much nothing for Umbraco 5. And the difference between the versions is major and concerns pretty much the most difficult part (Razor code). And even for Umbraco 4 some information is either missing or is buried so deeply that it is nearly impossible to find. And I mean basic information such as where is the root folder and what path to use to reference your .css file. There is one book on Umbraco so maybe some more info is there but it just seems to me that basic information like these should be front and center on Umbraco Wiki.

One explanation to this situation might be that the company behind Umbraco organizes courses that are fairly expensive (900,00 € +tax for level 1 course in Denmark) and so they are not interested in having free resources online. But then what is the point of making Umbraco free and trying to market it to regular users? Umbraco will have hard time becoming a go-to CMS if the learning curve is so steep and there is nothing to help you climb it.

3. Bugs

Umbraco 5 still have a serious amount of bugs and little quirks. This of course will get ironed out in the process but right now it is still slightly annoying.

Conclusion

Umbraco is definitely a powerful tool to have in your toolbox, especially if you work in Denmark where the CMS is gaining more and more recognition. However the investment of time and resources into learning the system is rather substantial so it is probably not a CMS for everyone.

I am pretty excited about getting to know it more, possibly also because it is challenge. 

Day 29: Assorted Tips for Webdevelopers

This post will not be an article as such. It will just be a collection of 3 tips for webdevelopers that I came across in the past week of work.

CSS: Clearfix Solution

No matter if you are just a beginner or a master of CSS, you must have already realized that float is an imperfect tool. The biggest problem with it is that floated content is taken out of the document’s flow and therefore will NOT extend the container it is in. This leads to some broken content and a big headache.

Floated content does not force height change on its container.

Luckily, there is a surprisingly simple solution to this problem called .clearfix. I found it in Dan Cederholm’s Handcrafted CSS book (which I very much recommend) but you can find it all over the web by simply googling for it (hint: you will also find some valuable comments and customization ideas if you google for it.).

1. Add the code below to your css file:

.clearfix:after{
content: ".";
display:block;
height:0;
clear:both;
visibility:hidden;
}

/*for IE6*/

*html .clearfix {
height:1%;
}

/* for IE7*/

*:first-child+html .group{
min-height: 1px;
}

As you can see IE6 and IE7 need additional lines of code but with them they work just fine.

2. Add clearfix class to

containing the floated element and you’re all done.

How does it work?  It creates content, that it places after the floated content in the

and styles it to clear floats. It is pretty much the same as if you were inserting 

. The solution is not ideal. For starters it adds content that has no semantic value and if you read more online you’ll find out it might cause problems in some cases in IE browsers. But so far it is the best solution I found and I’ll stick to it.

Favicon

Favicon is short for favorite icon and it is this small 16×16 pixels image you see next to some websites’ urls in browser url bar (or next to the websites’ name on the browser tab). And for something that small it can give you a really big headache.

For starters, despite how sophisticated it is, Photoshop cannot save as .ico (which is the proper file format for this little fellow). Fireworks and Illustrator won’t help you either. There are a few online tools or Photoshop plugins that you supposedly can use but I managed to get none of them to work properly for me. Interestingly enough, Microsoft Paint can save as .ico and is happy to do that (and yes, I did feel stupid using it).

Also, Opera and Firefox will happily display your favicons no matter what. But if you can’t see your favicon in Chrome and IE don’t despair and don’t spend hours trying to figure out what is wrong. Chrome and IE require the site to be online to display favicons.

Accordion

Accordion is a handy jquery plugin that allows you to display content in chunks at a time. This is very useful for content rich pages, for example FAQs where users are often interested in looking into one specific category of questions. You can download the plugin directly from jquery library but here is a tutorial from tuts+ that allows you to learn more about how accordion works. This gives you greater control over the code and the look and feel of your page. Unfortunately, the links on the page (to for example demo) don’t work.