Component View / Presentation

The presentation logic of our component will consist of a .cshtml view file, and any css or javascript logic that is needed for this component.

For the view, since our data model is created from a document type, it should be structured the same way as an Umbraco template, inheriting from the UmbracoPageTemplate. The only difference is that, this is a partial view, not a regular template view. Since we are going to have a lot of different components, let’s put them all in a component folder at /views/partials/components. We will also name the view file the same name as the component alias, so we know how to find it from our document type object. Here is our componentBodyTile.cshtml view:

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage @using Umbraco.Web.Models; @{ var image = Model.Content.GetPropertyValue<IPublishedContent>("image"); var links = Model.Content.GetPropertyValue<RelatedLinks>("link"); } <div class="c-body-tile"> @if (image != null) { <div> <img src="@image.Url" alt="@image.GetPropertyValue("altText")" class="img-circle"> </div> } <h3 class="c-body-tile__headline bodyTileHeight">@Model.Content.GetPropertyValue("headline")</h3> @Html.Raw(Model.Content.GetPropertyValue("description")) @if (links != null && links.Any()) { foreach (var link in links) { <div class="align-bottom"> <a href="@link.Link" target="@((link.NewWindow) ? "_blank" : "")" class="btn btn-primary">@link.Caption</a> </div> } } </div>

Notice how the entire component is wrapped in div with a class of c-body-tile. This is so the component’s css and js can use this selector to identify this component. Our site will have general base styles and general JavaScript, shared across the site, however now when creating logic for this specific component, we will use this selector to ensure that our component logic, doesn’t impact anything else on the site. Here is the scss style sheet for this component from /scss/partials/components/bodytile.scss

.c-body-tile { text-align:center; margin-bottom:30px; display: flex; flex-direction: column; height: 100%; align-content: start; @media (min-width: $screen-sm) { margin-bottom:0; } img { max-width:100%; } p { width:80%; margin-left:auto; margin-right:auto; max-width:250px; @media (min-width: $screen-md) { } } .align-bottom { margin-top:auto; } }

Layout Helpers

We’ve already said that the website should be built using a responsive grid framework. This means we will need to know how to add our components into the grid. We will also need to be able to make a row the full width of the page, and to remove any gutter padding between columns. Having simple utility classes for all of this will make adding components to pages simpler.

In addition, we will need the ability to alter the spacing between components. Generally, the components should have the minimum amount of space built in so we can control spacing on an implementation level, rather than within the component. To do this we add utility CSS style to have padding/margin on the top/bottom of the div – something like padding-def-smwhere it’s the padding on the {top}-{bottom} of the div. Then when we need spacing we will use these classes to add it.

I won’t get into too much detail on how to implement these things since it will depend on your front-end CSS framework, but make sure you have these capabilities.

Fixed Template Implementation

Ever since the early days of Umbraco, there have been Fixed Pages Templates. These are templates where there is a set layout, which defined by the code, and authors can’t really change it. Maybe there is logic built into the template to alter things based on the content value, but things are pretty much set. If an author wants to swap the order of two blades, that would need to be done by a developer, and takes a bit of work.

Fixed isn’t necessarily a bad thing. Fixed means that the layout must be consistent. It means authors can’t go crazy and make things look bad. This is good when we have a lot of pages that need to be consistent, like a product page.

To develop a fixed template, we will use Nested Content to create a data type from our component document type, and then add this to our page document type for the page. Here is our nested content data type for our component: