sitecore mvc (user group conference, may 23rd 2014)

42
#sugcon #sitecore Sitecore MVC Ruud van Falier ParTech IT

Upload: ruud-van-falier

Post on 19-Jun-2015

1.225 views

Category:

Presentations & Public Speaking


0 download

DESCRIPTION

The slides from my presentation about Sitecore MVC during the Dutch Sitecore User Group Conference on the 23rd of May in Utrecht, The Netherlands.

TRANSCRIPT

Page 1: Sitecore MVC (User Group Conference, May 23rd 2014)

#sugcon

#sitecore

Sitecore MVC

Ruud van Falier

ParTech IT

Page 2: Sitecore MVC (User Group Conference, May 23rd 2014)

2

Topics

• The basic concept• Traditional ASP.NET MVC• Sitecore MVC

• Sitecore renderings

• Controllers

• Models• Model binding

• Views• SitecoreHelper

• Inversion of Control• Dependency Injection

• MVC vs. WebForms

Page 3: Sitecore MVC (User Group Conference, May 23rd 2014)

3

How we used to roll…

The basic concept of (Sitecore) MVC

Page 4: Sitecore MVC (User Group Conference, May 23rd 2014)

4

Page 5: Sitecore MVC (User Group Conference, May 23rd 2014)

5

The basic concept of (Sitecore) MVC

View

Model

Controller

UserUses

ManipulatesUpdates

Sees

Page 6: Sitecore MVC (User Group Conference, May 23rd 2014)

6

The basic concept of (Sitecore) MVC

• Views display a certain set of data. They do not know where the data comes from.

• Models are classes that hold data.They may also execute logic for managing this data. They do not know how the data is displayed.

• Controllers are classes that execute logic that controls what data is seen and which view is used to display it.

Page 7: Sitecore MVC (User Group Conference, May 23rd 2014)

7

The basic concept of (Sitecore) MVC

A traditional ASP.NET MVC request

Browser URL Routing Controller Model View

RequestInvoke action

Initialize

Lookup view

Render

HTML

Page 8: Sitecore MVC (User Group Conference, May 23rd 2014)

8

The basic concept of (Sitecore) MVC

A Sitecore MVC request

Request

httpBeginRequest pipeline

MVC route?

Layout specified?

Is it an MVC view

file?

Controller specified?

MVC request

WebFormsrequest

No No No

No

Yes Yes Yes

Yes

Source: Martina Welander

Page 9: Sitecore MVC (User Group Conference, May 23rd 2014)

9

Sitecore Renderings

•View RenderingRenders a View using a built-in controller action. The controller passes a model of type RenderingModel to the View.

•Controller RenderingCalls an action on a controller and lets the controller handle the View rendering.

Page 10: Sitecore MVC (User Group Conference, May 23rd 2014)

10

Controllers

Page 11: Sitecore MVC (User Group Conference, May 23rd 2014)

11

Controllers

PageController

About

Portfolio

News

Request to:/page/news

var model = repository.GetNews();

return View(model);

/Views/News.cshtml

Page 12: Sitecore MVC (User Group Conference, May 23rd 2014)

12

Controllerspublic class MvcDemoController : Controller{ public ViewResult NewsOverview() { // Get news root item from Sitecore. Item newsRoot = Sitecore.Context.Database.GetItem("{NEWS-ROOT-GUID}"); IEnumerable<Item> newsItems = newsRoot.Children;

// Get temperature from weather service. var weatherService = new WeatherService(); int temperature = weatherService.GetTemperature();

// Initialize model for News Overview page. return this.View(new NewsOverviewModel { NewsItems = newsItems, Temperature = temperature }); }}

Page 13: Sitecore MVC (User Group Conference, May 23rd 2014)

13

Controllers

public class MvcDemoController : Controller{ public ViewResult SearchNews(string keyword, int page) { // Perform search and return NewsOverViewModel with results. var model = new NewsOverviewModel(); return this.View(model); }}

/MvcDemo/SearchNews?keyword=my_search_terms&page=1

Page 14: Sitecore MVC (User Group Conference, May 23rd 2014)

14

Controllers

/MvcDemo/SearchNews?keyword=my_search_terms&page=1

public class MvcDemoController : Controller{ public ViewResult SearchNews(SearchRequestModel request) { // Perform search and return NewsOverViewModel with results. var model = new NewsOverviewModel(); return this.View(model); }}

Page 15: Sitecore MVC (User Group Conference, May 23rd 2014)

15

Controllers

Do

• Retrieve data required to initialize models

• Initialize models

• Return appropriate View (or other ActionResult)

Don’t

• Cramp them with logic

• Use them if it’s not necessary

Page 16: Sitecore MVC (User Group Conference, May 23rd 2014)

16

Models

Page 17: Sitecore MVC (User Group Conference, May 23rd 2014)

17

Modelspublic class ContentPageModel{ public string Title { get; set; }

public string Intro { get; set; }

public string Body { get; set; }}

Page 18: Sitecore MVC (User Group Conference, May 23rd 2014)

18

Modelspublic class ContentPageModel{ public string Title { get; set; }

public string Intro { get; set; }

public string Body { get; set; }}

public class ContentPageModel{ public string Title { get; set; }

public string Intro { get; set; }

public string Body { get; set; }

public ContentPageModel Parent { get; set; }

public IEnumerable<ContentPageModel> SubPages { get; set; }}

Page 19: Sitecore MVC (User Group Conference, May 23rd 2014)

19

Modelspublic class ContentPageModel{ public string Title { get; set; }

public string Intro { get; set; }

public string Body { get; set; }}

public class ContentPageModel{ public string Title { get; set; }

public string Intro { get; set; }

public string Body { get; set; }

public ContentPageModel Parent { get; set; }

public IEnumerable<ContentPageModel> SubPages { get; set; }}

public class ContentPageModel{ /* Snipped properties */

public void CreateSubPage(ContentPageModel model) { // Logic for creating a sub page. }

public void DeleteSubPage(ContentPageModel model) { // Logic for deleting a sub page. }}

Page 20: Sitecore MVC (User Group Conference, May 23rd 2014)

20

Model Binding

public class SearchRequestModel{ public string Keyword { get; set; }

public int Page { get; set; }

public bool OrderByRelevance { get; set; }}

public class MvcDemoController : Controller{ public ViewResult SearchNews(SearchRequestModel request) { // Perform search and return NewsOverViewModel with results. var model = new NewsOverviewModel(); return this.View(model); }}

/MvcDemo/SearchNews?keyword=my_search_terms&page=1

Page 21: Sitecore MVC (User Group Conference, May 23rd 2014)

21

Models

In Sitecore MVC:

• View Models usually represent Templates from Sitecore.

• This way, View Models can contain content from Sitecore items.

• There are several Object-Relational Mappers that are created specifically for that task.

Make sure to attend Mike Edwards’ and Robin Hermanussen’s session for more on ORM!

Page 22: Sitecore MVC (User Group Conference, May 23rd 2014)

22

Models

Do

• Hold data

• Provide logic to manipulate data

Don’t

• Add presentation elements to data

• Use for application logic

Page 23: Sitecore MVC (User Group Conference, May 23rd 2014)

23

Views

Page 24: Sitecore MVC (User Group Conference, May 23rd 2014)

24

Razor Syntax

Source: http://haacked.com

Page 25: Sitecore MVC (User Group Conference, May 23rd 2014)

25

Views

@model RenderingModel

<section id="main_content"> <h3> @Model.Item["Title"] </h3> <p> <strong> @Model.Item["Intro"] </strong> </p> @Model.Item["Body"] </section>

Page 26: Sitecore MVC (User Group Conference, May 23rd 2014)

26

Views

@model RenderingModel

<section id="main_content"> <h3> @Model.Item["Title"] </h3> <p> <strong> @Model.Item["Intro"] </strong> </p> @Model.Item["Body"] </section>

@model RenderingModel

<section id="main_content"> <h3> @Model.Item["Title"] </h3> <p> <strong> @Html.Raw(Model.Item["Intro"]) </strong> </p> @Html.Raw(Model.Item["Body"]) </section>

Page 27: Sitecore MVC (User Group Conference, May 23rd 2014)

27

Views

@model RenderingModel

<section id="main_content"> <h3>

@Html.Sitecore().Field("Title") </h3>

<p> <strong> @Html.Sitecore().Field("Intro") </strong> </p>

@Html.Sitecore().Field("Body") </section>

Page 28: Sitecore MVC (User Group Conference, May 23rd 2014)

28

Views

using System.Web;using Sitecore.Mvc.Helpers;

/// <summary>/// Extension methods for the SitecoreHelper class./// </summary>public static class SitecoreHelperExtensions{ public static HtmlString WhoAreYou(this SitecoreHelper helper) { return new HtmlString("I'm your father!"); }}

@Html.Sitecore().WhoAreYou() @* Output: "I'm your father" *@

Page 29: Sitecore MVC (User Group Conference, May 23rd 2014)

29

Views

public class ContentController : Controller{ public ViewResult ContentPage() { var model = new ContentPageModel();

// Populate model properties with data from Sitecore.

return this.View("~/Views/Content page.cshtml", model); }}

public class ContentPageModel{ public string Title { get; set; }

public string Intro { get; set; }

public string Body { get; set; }}

Page 30: Sitecore MVC (User Group Conference, May 23rd 2014)

30

Views

public class ContentController : Controller{ public ViewResult ContentPage() { var model = new ContentPageModel();

// Populate model properties with data from Sitecore.

return this.View("~/Views/Content page.cshtml", model); }}

public class ContentPageModel{ public string Title { get; set; }

public string Intro { get; set; }

public string Body { get; set; }}

@model ContentPageModel

<section id="main_content">

<h3> @Model.Title </h3>

<p> <strong> @Model.Intro </strong> </p>

@Model.Body

</section>

Page 31: Sitecore MVC (User Group Conference, May 23rd 2014)

31

Views

Do

• Display data from a model

• Use simple flow logic that is required to present data (if / foreach / retrieval methods)

Don’t

• Add complex logic

• Go nuts with inline code

Page 32: Sitecore MVC (User Group Conference, May 23rd 2014)

32

Inversion of Control (IoC)

“A software architecture with this design inverts control as compared to traditional procedural programming: in traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the reusable code that calls into the custom, or problem-specific, code.”, Wikipedia

The decoupling of dependencies by isolating code for certain responsibilities into separate libraries and referring to those libraries using their interfaces instead of their concrete implementation.

Page 33: Sitecore MVC (User Group Conference, May 23rd 2014)

33

Inversion of Control (IoC)

IoC serves the following design purposes:

• To decouple the execution of a task from implementation.• To focus a module on the task it is designed

for.• To free modules from assumptions about how

other systems do what they do and instead rely on contracts (interfaces).• To prevent side effects when replacing a

module.

Page 34: Sitecore MVC (User Group Conference, May 23rd 2014)

34

Inversion of Control (IoC)public class MvcDemoController : Controller{ public ViewResult NewsOverview() { // Get news root item from Sitecore. Item newsRoot = Sitecore.Context.Database .GetItem("{NEWS-ROOT-GUID}"); IEnumerable<Item> newsItems = newsRoot.Children;

// Get temperature from weather service. var weatherService = new WeatherService(); int temperature = weatherService.GetTemperature();

// Initialize model for News Overview page. return this.View(new NewsOverviewModel { NewsItems = newsItems, Temperature = temperature }); }}

Page 35: Sitecore MVC (User Group Conference, May 23rd 2014)

35

Inversion of Control (IoC)public class MvcDemoController : Controller{ public ViewResult NewsOverview() { // Get news root item from Sitecore. Item newsRoot = Sitecore.Context.Database .GetItem("{NEWS-ROOT-GUID}"); IEnumerable<Item> newsItems = newsRoot.Children;

// Get temperature from weather service. var weatherService = new WeatherService(); int temperature = weatherService.GetTemperature();

// Initialize model for News Overview page. return this.View(new NewsOverviewModel { NewsItems = newsItems, Temperature = temperature }); }}

TIGHT COUPLING

Page 36: Sitecore MVC (User Group Conference, May 23rd 2014)

36

Inversion of Control (IoC)public class MvcDemoController : Controller{ private readonly ISitecoreContext sitecoreContext; private readonly IWeatherService weatherService;

public MvcDemoController(ISitecoreContext sitecoreContext, IWeatherService weatherService) { this.sitecoreContext = sitecoreContext; this.weatherService = weatherService; }

public ViewResult NewsOverview() { // Get news root item from Sitecore. Item newsRoot = this.sitecoreContext.ItemManager.GetItem("{NEWS-ROOT-GUID}"); IEnumerable<Item> newsItems = newsRoot.Children;

// Get temperature from weather service. int temperature = this.weatherService.GetTemperature();

// Initialize model for News Overview page. return this.View(new NewsOverviewModel { NewsItems = newsItems, Temperature = temperature }); }}

Page 37: Sitecore MVC (User Group Conference, May 23rd 2014)

37

Inversion of Control (IoC)public class MvcDemoController : Controller{ private readonly ISitecoreContext sitecoreContext; private readonly IWeatherService weatherService;

public MvcDemoController(ISitecoreContext sitecoreContext, IWeatherService weatherService) { this.sitecoreContext = sitecoreContext; this.weatherService = weatherService; }

public ViewResult NewsOverview() { // Get news root item from Sitecore. Item newsRoot = this.sitecoreContext.ItemManager.GetItem("{NEWS-ROOT-GUID}"); IEnumerable<Item> newsItems = newsRoot.Children;

// Get temperature from weather service. int temperature = this.weatherService.GetTemperature();

// Initialize model for News Overview page. return this.View(new NewsOverviewModel { NewsItems = newsItems, Temperature = temperature }); }}

LOOSE COUPLING

Page 38: Sitecore MVC (User Group Conference, May 23rd 2014)

38

Dependency Injection (DI)

There are several methods for DI, some examples are:

• Constructor injection (as seen in the example)• Parameter injection• Setter injection

Use a framework that handles DI for you:

• Windsor container (because it ships with Glass)• Ninject• Autofac

Page 39: Sitecore MVC (User Group Conference, May 23rd 2014)

39

MVC vs. WebFormsWhy MVC is better

• Strict separation of responsibilities• Simpler page lifecycle.• Stateless (No more ViewState).• No more server controls.• Very easy to work with AJAX.• Not bound to generated markup.• Multiple forms on a page.

When to stick to WebForms

• Legacy application• Team knowledge• Prototyping

WebForms is just an extremely complex abstraction over HTML/JS, invented before the introduction of jQuery and AJAX;We don’t need this abstraction anymore.

Page 40: Sitecore MVC (User Group Conference, May 23rd 2014)

40

Join us!

Are you an awesome Sitecore Developer?

ParTech is looking for people to expand their team!

We offer you an excellent salary and benefits and the chance to work on enterprise Sitecore projects together with the most skilled developers available.

Join the Sitecore elite,apply at www.partechit.nl !

Page 41: Sitecore MVC (User Group Conference, May 23rd 2014)

41

References

• Follow me on Twitter:@BrruuD

• Contact me by e-mail:[email protected]

• Read our blog:www.partechit.nl/blog

Page 42: Sitecore MVC (User Group Conference, May 23rd 2014)

42

Thank you