keep it simple-ish - zpqrtbnk · 2014/06/11 core internals for website development keep it...
TRANSCRIPT
![Page 1: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/1.jpg)
2014/06/11
Core internals for Website DevelopmentKeep it simple-ish
Stéphane [email protected]
@zpqrtbnk
![Page 2: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/2.jpg)
Umbraco is great…
And yet Completely Broken ™
Fixing & Refactoring
IAmTheOneToBlameForThoseFancyInterfaceNames
ZpqrtBnk
![Page 3: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/3.jpg)
Simple things should be simpleRefactor for simplicity & predictability
Complex things should be possibleRefactor for extensibility & modularity
Constant work-in-progressNew ways to build websitesCommunity feedback loop
Core Internals for Website Development
![Page 4: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/4.jpg)
Tea Spoon World
Latest News
June 1, 2014
Queen to discussteaspoon etiquettewith parliament
Read more
May 28, 2014
US to defend right to keep and bearteaspoons
Read more
In Depth
Size matters –what makes a teaspoon
Read more
In Depth
Illegal teaspoonusages
Read more
In Depth
If you can readthis you are a
May 12, 2014
![Page 5: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/5.jpg)
Multiple websites, multiple languagesSites demo1.com and demo2.comBoth websites should exist both in English and FrenchBoth will publish news items (title, body, image, map location)
Multiple environmentsTo get things validated by upper management,Customer wants www.demo1.com and staging.demo1.com
Special URLs/news/2014-06-11-helicopters-to-deliver-teaspoons
![Page 6: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/6.jpg)
Setup sites, domains and languages
![Page 7: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/7.jpg)
Demo 1
English
French
Demo 2
English
French
News
Teaspoon something
CONTENT
![Page 8: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/8.jpg)
Demo 1
English
French
Demo 2
English
French
News
Teaspoon something
CONTENT
![Page 9: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/9.jpg)
Demo 1
English
French
Demo 2
English
French
News
Teaspoon something
CONTENT
Culture: en-US
Domains: www.demo1.com, staging.demo1.com
Culture: fr-FR
Culture: en-US
Domains: www.demo2.com, staging.demo2.com
Culture: fr-FR
![Page 10: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/10.jpg)
http://www.demo1.com/ ??
Umbraco wants to render node “Demo1”We want to redirect
to “Demo1 / English”to “Demo1 / French”
PublishedContentRequest.Prepared
![Page 11: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/11.jpg)
PublishedContentRequest.Prepared += (sender, args) =>{
var request = sender as PublishedContentRequest;
if (request == null || !request.HasPublishedContent) return;if (request.PublishedContent.ContentType.Alias != "Site") return;
var roots = request.PublishedContent.Children.OfTypes("HomePage");if (!roots.Any()) return;
var httpRequest = request.RoutingContext.UmbracoContext.HttpContext.Request;
var lang = FigureOutLanguageFromRequest(httpRequest);
var root = PickTheMostAppropriateRoot(roots, lang);
request.SetRedirect(root.Url);}
![Page 12: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/12.jpg)
Urls, Relative vs. Absolute
Navigate demo1, request the url of a Demo1 page relativeNavigate demo1, request the url of a Demo2 page absolute
Also in the backend eg. admin.demos.com !
![Page 13: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/13.jpg)
SiteDomainHelper.AddSite("www", "www.demo1.com", "www.demo2.com");SiteDomainHelper.AddSite("staging", "staging.demo1.com", "staging.demo2.com");
Urls, Picking the right domain
www.demo1 www.demo2staging.demo1 staging.demo2
![Page 14: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/14.jpg)
404 Page Not Found
Just render a page named 404
![Page 15: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/15.jpg)
Demo 1
English
French
Demo 2
English
French
News
404
CONTENT
Articles
![Page 16: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/16.jpg)
RIP NotFoundHandler
IContentFinder.TryFindContent(PublishedContentRequest request)
The “last chance” content finder
![Page 17: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/17.jpg)
public class Find404 : IContentFinder{
public bool TryFindContent(PublishedContentRequest contentRequest){
if (!contentRequest.HasDomain) return false;
var contentCache = contentRequest.RoutingContext.UmbracoContext.ContentCache;var domainRoot = contentCache.GetById(contentRequest.Domain.RootNodeId);
var firstSegment = contentRequest.Uri.AbsolutePath.Split(new [] {'/'}, StringSplitOptions.RemoveEmptyEntries).First();
var root = domainRoot.Children.FirstOrDefault(x => x.UrlName == firstSegment);
root = root ?? domainRoot.Children.First();
var page = root.Descendants().FirstOrDefault(x => x.Name == "404");if (page == null) return false;
contentRequest.PublishedContent = page;var wcd = Domain.GetDomainsById(root.Id, true).SingleOrDefault(x => x.IsWildcard);if (wcd != null)
contentRequest.Culture = new CultureInfo(wcd.Language.CultureAlias);return true;
}}
![Page 18: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/18.jpg)
public class ConfigureMy404Finder : ApplicationEventHandler{
public override void ApplicationStarting(UmbracoApplicationBase umbracoApplication,ApplicationContext applicationContext)
{ContentLastChanceFinderResolver.Current.SetFinder(new Find404());
}}
![Page 19: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/19.jpg)
Nice & clean urls
“Spécial glöbst & cüsmîdt @ Frånzenøx !”
spécial-glöbst-cüsmîdt-@-frånzenøx spécial-glöbst-cüsmîdt-frånzenøx special-globst-cusmidt-franzenox
How many Unicode characters are there?
![Page 20: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/20.jpg)
<settings><requestHandler>
<urlReplacing removeDoubleDashes="true"><char org="!"></char><char org="#"></char>…
</urlReplacing></requestHandler>
</settings>
<settings><requestHandler>
<urlReplacing toAscii="true" /></requestHandler>
</settings>
![Page 21: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/21.jpg)
Simples thingsAre becoming simplerBuilt-in ASCII filterBuilt-in 240 chars limit…
Complex thingsCan be complex: IShortStringHelperProcesses every “short” stringCreates aliases, url segments…
String extension methods: ToUrlSegment(), ToCleanString()…
Replace it, extend it, whatever
![Page 22: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/22.jpg)
Custom news item urlsRequirement: “2014-06-11-helicopters-to-deliver-teaspoons”Content name: “Helicopters to deliver teaspoons”Default url segment: “helicopters-to-deliver-teaspoons”
IUrlSegmentProviderProvides the url segment at publish timeNative support (no need for rewriting, content finder, anything)
![Page 23: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/23.jpg)
public class UrlSegmentProvider : IUrlSegmentProvider{
public string GetUrlSegment(IContentBase content){
var services = ApplicationContext.Current.Services;var contentType = services.GetContentType(content.ContentTypeId);if (contentType.Alias != "NewsItem") return null;
var date = content.GetValue<DateTime>("date").ToString("yyyy-MM-");return date + content.Name.ToUrlSegment();
}}
![Page 24: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/24.jpg)
Beyond the url segmentWhen you want to create a completely different url
IUrlProviderProvides the complete content url when requiredNeeds an inbound strategy (rewriting, content finder, something)
/products/a/aluminum /products/aluminum
![Page 25: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/25.jpg)
Render content
The NewsItems page
![Page 26: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/26.jpg)
UmbracoTemplatePageUmbracoTemplatePage<TContent>UmbracoViewPageUmbracoViewPage<TModel>RenderModel
?!
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage@{
Layout = null;}
Open the template
![Page 27: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/27.jpg)
UmbracoViewPage<TModel>ApplicationContext, UmbracoContext, UmbracoHelperMaps IRenderModel to/from IPublishedContent
UmbracoViewPage: UmbracoViewPage<IPublishedContent>
Model is IPublishedContent
UmbracoTemplatePage: UmbracoViewPage<RenderModel>
Model is RenderModelModel.Content is IPublishedContentdynamic CurrentPage
![Page 28: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/28.jpg)
So?!
[email protected] UmbracoTemplatePage
[email protected]("myProperty")@Model.Content.GetPropertyValue<string>("myProperty") UmbracoViewPage
Strongly [email protected] UmbracoViewPage<MyContentType>MyContentType : IPublishedContent
Complex model UmbracoViewPage<MyModel>MyModel : IPublishedContent or IRenderModel for Umbraco.Field()
![Page 29: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/29.jpg)
So?!
DynamicGives easy access to properties eg CurrentPage.MyPropertyGives easy (?) navigation eg. CurrentPage.ProductsBut…
Not a bad choice todayHope to make it redundant at some point
![Page 30: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/30.jpg)
@inherits Umbraco.Web.Mvc.UmbracoViewPage
<div>@Model.GetPropertyValue("title")</div>
@foreach (var newsItem in Model.Children().Where(x => x.DocumentTypeAlias == "newsItem").OrderByDescending(x => x.GetPropertyValue<DateTime>("date")).Take(8))
{<div class="date">@Model.GetPropertyValue<DateTime>("date").ToString("D")</div><div class="title">@Model.GetPropertyValue<string>("title")</div>
@* HERE I WANT TO SHOW THE IMAGE *@
@* HERE I WANT TO SHOW A MAP LOCATION *@}
News item page template, first try
![Page 31: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/31.jpg)
@inherits Umbraco.Web.Mvc.UmbracoViewPage
@foreach (var newsItem in …Where(x => x.GetPropertyValue<string>("topic") == "food")){
<div class="@(newsItem.IsOdd() ? "news-odd" : "news-even")">
@* DETAILS *@
</div>}
Alternate styling, Index and ToContentSet
![Page 32: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/32.jpg)
@inherits Umbraco.Web.Mvc.UmbracoViewPage
@foreach (var newsItem in …Where(x => x.GetPropertyValue<string>("topic") == "food").ToContentSet())
{<div class="@(newsItem.IsOdd() ? "news-odd" : "news-even")">
@* DETAILS *@
</div>}
Alternate styling, Index and ToContentSet
![Page 33: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/33.jpg)
Quick win
@inherits Umbraco.Web.Mvc.UmbracoViewPage
<div>@Model.GetPropertyValue("title")</div>
@foreach (var newsItem in Model.Children().OfTypes("newsItem").OrderByDescending(x => x.GetPropertyValue<DateTime>("date")).Take(8))
{<div class="date">@Model.GetPropertyValue<DateTime>("date").ToString("D")</div><div class="title">@Model.GetPropertyValue<string>("title")</div>
@* HERE I WANT TO SHOW THE IMAGE *@
@* HERE I WANT TO SHOW A MAP LOCATION *@}
![Page 34: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/34.jpg)
@{var imageId = Model.GetPropertyValue<int>("image");var image = Umbraco.TypedMedia(imageId);if (!image.HasValue("umbracoFile")) image = null;
}@if (image != null){
var alt = image.GetPropertyValue<string>("legend");alt = string.IsNullOrEmpty(alt) ? Image.Name : alt;<div class="image"><img src="@image.Url" src="@alt" /></div>
}
Show the image…
![Page 35: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/35.jpg)
@{var location = Model.GetPropertyValue<string>("location");float latitude = 0, longitude = 0;if (string.IsNullOrEmpty(location) == false){
var parts = location.Split(new[] {','});latitude = float.Parse(parts[0]);longitude = float.Parse(parts[1]);
}}@if (string.IsNullOrEmpty(location) == false){
<div class="location"><img src="http://maps.com/?lat=@latitude&lng=@longitude" />
</div>}
Show the map location…
![Page 36: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/36.jpg)
Happy?
![Page 37: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/37.jpg)
IPropertyValueConverter
Could have been IPublishedContentPropertyFromDbValueConversionProvider
Ensures that GetPropertyValue returns a meaningful value
Some are builtinWrite your own
![Page 38: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/38.jpg)
public class LocationConverter : PropertyValueConverterBase{
public override bool IsConverter(PublishedPropertyType propertyType){
return "Demo.Location".Equals(propertyType.PropertyEditorAlias);}
public override object ConvertDataToSource(PublishedPropertyType propertyType,object source, bool preview)
{var stringSource = source as string;if (string.IsNullOrWhiteSpace(stringSource)) return null;
var coords = stringSource.Split(new[] {','});return new Location(float.Parse(coords[0]), float.Parse(coords[1]));
}}
Convert location properties…
![Page 39: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/39.jpg)
@{var image = Model.GetPropertyValue<IPublishedContent>("image");// umbracoFile test done by the converter
}@if (image != null){
var alt = image.GetPropertyValue<string>("legend");alt = string.IsNullOrEmpty(alt) ? Image.Name : alt;<div class="image">
<img src="@image.Url" src="@alt" /></div>
}
@{var location = Model.GetPropertValue<Location>("location");
}@if (location != null){
<div class="location"><img src="…[email protected]&[email protected]" />
</div>}
Getting better…
![Page 40: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/40.jpg)
Introducing IPublishedContentModelFactoryUmbraco 7.1.4
Every IPublishedContent returned by the cache goes through the factoryIPublishedContent CreateModel(IPublishedContent content)
No factory enabled by defaultShips with builtin PublishedContentModelFactory
![Page 41: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/41.jpg)
public class NewsItem : PublishedContentModel{
public NewsItem(IPublishedContent content): base(content)
{ }
public DateTime Date{
get { return this.GetPropertyValue<DateTime>("date"); }}
}
![Page 42: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/42.jpg)
Introducing Zbu.ModelsBuilder
Independent toolgithub.com/zpqrtbnk
Generates strongly typed models based upon what’s in the databaseAs partial classesThat can be extendedTweak generation via attributes
![Page 43: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/43.jpg)
Server-side componentInstall Umbraco Package or NuGet Package
Visual Studio ExtensionInstall in Visual StudioConfigure to point to website
![Page 44: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/44.jpg)
ZbuModelsBuilder
Demo.Models
Demo
Properties
References
Models
Builder.cs
![Page 45: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/45.jpg)
Demo
Properties
References
Models
Builder.cs
NewsItemsPage.generated.cs
NewsItem.generated.cs
Image.generated.cs
Whatever.generated.cs
![Page 46: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/46.jpg)
Demo
Properties
References
Models
Builder.cs
Image.cs
NewsItem.cs
![Page 47: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/47.jpg)
public partial class Image{
public string Alt{
get{
var alt = this.Legend;return string.IsNullOrWhiteSpace(alt) ? this.Name : alt;
}}
}
Image should have an Alt property
![Page 48: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/48.jpg)
public partial class NewsItem{
[ImplementPropertyType("image")]public Image Image{
get{
var img = this.GetPropertyValue<IPublishedContent>("image") as Image;if (img == null || string.IsNullOrEmpty(img.UmbracoFile)) return null;return img;
}}
}
NewsItem image should return as an image…
![Page 49: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/49.jpg)
@inherits Umbraco.Web.Mvc.UmbracoViewPage<NewsItemsPage>
<div>@Model.Title</div>
@foreach (var newsItem in Model.Children<NewsItem>().OrderByDescending(x => x.Date).Take(8))
{<div class="date">@Model.Date.ToString("D")</div><div class="title">@Model.Title</div>
@if (Model.Image != null){
<div class="image"><img src="@Model.Image.Url" src="@Model.Image.Alt" />
</div>}
@if (Model.Location != null){
<div class="location"><img src="…[email protected]&[email protected]" />
</div>}
}
News item page template
![Page 50: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/50.jpg)
Content models vs. View models
Strongly typed everywhere
![Page 51: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/51.jpg)
Happy?
![Page 52: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/52.jpg)
@foreach (var newsItem in Model.Children<NewsItem>().OrderByDescending(x => x.Date).Take(8))
{…
@foreach (var newsItem in Umbraco.Queries.LatestNews(0, 8)){
…
Simplify content access…
![Page 53: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/53.jpg)
Queries are still work-in-progressExperimented during the retreat
What about XPath?
![Page 54: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/54.jpg)
@inherits Umbraco.Web.Mvc.UmbracoViewPage<NewsItemsPage>
<div>@Model.Title</div>
@foreach (var newsItem in Umbraco.Queries.LatestNews(0, 6)){
<div class="date">@Model.Date.ToString("D")</div><div class="title">@Model.Title</div>
@if (Model.Image != null){
<div class="image"><img src="@Model.Image.Url" src="@Model.Image.Alt" />
</div>}
@if (Model.Location != null){
<div class="location"><img src="…[email protected]&[email protected]" />
</div>}
}
Finally…
![Page 55: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/55.jpg)
<div>@Model.Title</div>
<div>@CurrentPage.Title</div>
Almost happy…
@if (CurrentPage.Image != null){
@if (CurrentPage.HasImage){
![Page 56: Keep it simple-ish - ZpqrtBnk · 2014/06/11 Core internals for Website Development Keep it simple-ish Stéphane Gay stephane@umbraco.dk @zpqrtbnk](https://reader035.vdocuments.us/reader035/viewer/2022081405/5f0a939a7e708231d42c5029/html5/thumbnails/56.jpg)
Happy!