James Vidler
VP of Product @ Agility CMS
By - James Vidler
Director, Partner Success
Page
Page Template
Content Zones
Modules
A
B
Page Template
Content Zone A
Content Zone B
Module A
Module B
+
Does a lot of other stuff too:
And more...
HTTP(s) Request
~/about-us
RouteConfig.cs
Matches Agility route constraint
Agility.Web.dll
Renders Page Template and each Module
RenderBody()
Rendered HTML served in Layout file
Now that we understand some basic concepts, we are going to build a blog ...
In the end, we should have a simple blog template, a list of posts, and a module to output the post details.
What we are going to do:
<!-- Normally, you'd but this in a CSS file -->
<style>
.blog-template__wrapper {
max-width: 730px;
margin: 0 auto;
}
</style>
<!-- Page Template Code -->
<div class="blog-template container contentWrap" role="main">
<div class="blog-template__wrapper">
@{Html.RenderContentZone("MainContentZone");}
</div>
</div>
What we are going to do:
using MVC4SampleSite.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVC4SampleSite.Controllers
{
public class BlogController : Controller
{
public ActionResult BlogPostDetails(Module_BlogPostDetails module)
{
return PartialView("~/Views/Blog/BlogPostDetails.cshtml", module);
}
}
}
@model MVC4SampleSite.Models.Module_BlogPostDetails
<div class="blog-post-details">
@if(Model.Image != null)
{
<!-- This img is being thumbnailed to 730px -->
<img class="img-responsive" src="@Model.Image.URL?w=730" alt="@Model.Image.Label" />
}
<h1>@Model.Title</h1>
@Html.Raw(Model.Details)
</div>
Do you think our current Blog Post architecture is scalable? Why not?
How can it be improved?
What we are going to do:
Note: Dynamic Pages CANNOT be created in the page root and must be under a page or folder
Note: This page will be empty for demonstration purposes, but normally this would be your root listing page that lists links to all your dynamic page items
Note: You will notice the module itself no longer has any fields, because the Blog Post will be dynamically resolved at run-time based on the Page Path Formula
using MVC4SampleSite.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Agility.Web.Extensions;
using Agility.Web;
namespace MVC4SampleSite.Controllers
{
public class BlogController : Controller
{
public ActionResult BlogPostDetails(Module_BlogPostDetails module)
{
BlogPost blogPost = AgilityContext.GetDynamicPageItem<BlogPost>();
if(blogPost == null)
{
throw new HttpException(404, "No blog post found matching the Page Path Formula.");
}
return PartialView("~/Views/Blog/BlogPostDetails.cshtml", blogPost);
}
}
}
Note: Agility.Web will automatically convert a standard string like Title to strip out whitespaces and special characters and force a friendly, lowercase URL
What we are going to do:
@using Agility.Web.Objects;
@using MVC4SampleSite.Models
@model MVC4SampleSite.Models.Module_BlogListing
@* // Some Functions *@
@{
//get the entire list of blog posts - the module already knows the type and reference name
var posts = Model.BlogPosts.Items();
//or another, more verbose way...
posts = new AgilityContentRepository<BlogPost>("BlogPosts").Items();
}
@helper GetPostLink(BlogPost p, string dynamicPagePath)
{
//returns a full href tag with the dynamic url slug for the page
DynamicPageItem d = Data.GetDynamicPageItem(dynamicPagePath, p.ReferenceName, p.Row);
Uri url = new Uri(
VirtualPathUtility.ToAbsolute(
String.Format(
"{0}/{1}",
dynamicPagePath.Substring(0, dynamicPagePath.LastIndexOf('/')),
d.Name
).ToLowerInvariant()
), UriKind.Relative
);
<a href="@url" title="@p.Title">@p.Title</a>
}
@* // Out Output *@
<h1>@Model.Title</h1>
@foreach (var p in posts)
{
<div class="post-listing-item">
<h3>@GetPostLink(p, "~/blog/post-dynamic")</h3>
@if (p.Image != null)
{
<img src="@p.Image.URL?w=150" alt="@p.Image.Label" />
}
@Html.Raw(p.Details)
</div>
}
What we are going to do:
<agility.web>
<settings applicationName="Agility Sample MVC4 (Live)"
developmentMode="false" contentCacheFilePath="d:\home\AgilityContent\" xdt:Transform="SetAttributes">
<trace traceLevel="Warning" emailErrors="true" logFilePath="d:\home\AgilityLogs\SampleMVC4.log"
xdt:Transform="SetAttributes" />
</settings>
</agility.web>
By James Vidler
Default slides for intro developer workshop.