Continuing from last night's post, Part 1 of Migrating WordPress to MVC4 I spent some time today working on the visual display of the migrated posts. Like most programmers using WordPress, I utilize the excellent Syntax Highlighter JavaScript/CSS library for all of my code blocks. The caveat with this, those tags now exist all throughout my posts going back a year or more at this point. Luckily, my Regular Expression skills have gone up considerably with projects like my Windows Phone 8 app, jcCMAP that utilizes XPath and Regular Expressions extensively. So where do you begin? Like many migrations you have a choice, do you migrate the data as is into the new structure or do you manipulate, like in this case with the tags, the actual tags into something that is preprocessed? Being a firm believer in storing data in as bare of a form as possible and then in my business and presentation layers worrying about the UI, I am choosing to leave the tags as they exist. Luckily, the tags follow a very easy to parse syntax with brackets and the name of the language. First steps from last night were to do some refactorization of the Data Layer and split it into a true 3 tier architecture. I first created a PostFactory class to interface with the EntityFramework in my Windows Class Library:
public class PostFactory : IDisposable {
     public List<Objects.Post> GetPosts(DateTime startDate, DateTime endDate) {
     using (var eFactory = new bbxp_jarredcapellmanEntities()) {
     return eFactory.getPostListingSP(startDate, endDate).Select(a => new Objects.Post(a.ID, a.Created, a.Title, a.Body)).ToList(); }
}
.... ]]>
This block grabs all of the posts for a given date range from the getPostListingSP Stored Procedure and then using LINQ does a translation to a Post object that resides in my PCL library. The Post object exists in the Portable Class Library (PCL) to be utilized by the MVC4 app and the eventual Windows Phone 8 app. Planning ahead and doing things right from the get go will save you time - don't rush your initial architecture, you'll pay for it later. Next I create my Post Object that encapsulates the properties I want exposed to the clients (MVC4 App and Windows Phone). Some might find it silly to not simply reuse the EntityFramework Complex Type object that the stored procedure mentioned above returns. I find that approach to be a lack of separation of concerns and crossing tiers between the data and UI layers. For a simple site I might overlook it, but for 99% of the things I do, I always have an object that acts as a middle man between the data and UI layers. Now onto the code:
public class Post {
     // Propertiess public int ID {
     get; set; }
public DateTime PostDate {
     get; set; }
public string Title {
     get; set; }
public string Body {
     get; set; }
public string PostBy {
     get; set; }
public Post(int id, DateTime postDate, string title, string body) {
     ID = id; PostDate = postDate; Title = title; Body = parsePost(body); }
// Parse the SyntaxHighlighter Tags and replace them with the SyntaxHighlighter <pre> tags private static string parsePost(string content) {
     var matches = Regex.Matches(content, @"\[(.*[a-z])\]"); foreach (Match match in matches) {
     var syntaxTag = new SyntaxTag(match.Value); if (!syntaxTag.IsParseable) {
     continue; }
if (syntaxTag.IsClosingTag) {
     content = content.Replace(syntaxTag.FullTagName, "</pre>"); }
else {
     content = content.Replace(syntaxTag.FullTagName, "<pre class=\"brush: " + syntaxTag.NameOnly + ";\">"); }
}
return content; }
}
]]>
Pretty stock code, the only "interesting" code is the regular expression to grab all of the SyntaxHighlighter. For those doing Regular Expressions, I find it incredibly useful to use a tool like Regex Hero to build your Regular Expressions since you can test input on the fly without having to constantly rebuild your code and test. Next on the "to code" list was the SyntaxTag object.
public class SyntaxTag {
     public SyntaxTag(string value) {
     FullTagName = value; }
public string NameOnly {
     get {
     return FullTagName.Replace("[/", "").Replace("[", "").Replace("]", ""); }
}
public bool IsClosingTag {
     get {
     return FullTagName.StartsWith("[/"); }
}
public string FullTagName {
     get; private set; }
// Acceptable syntaxtags (there are more, but this is all I used previously) private enum SYNTAXTAGS {
     csharp, xml, sql, php, c, bash, shell, cpp, js, java, ps, plain }
public bool IsParseable {
     get {
     SYNTAXTAGS tag; return Enum.TryParse(NameOnly, out tag); }
}
}
]]>
Again, a pretty basic class. Based on the full tag, it provides a clean interface to the Post class (or others down the road) without mucking up other areas of code. One thing I did do that many might find strange is to use an enumeration to eliminate false positives. I am a huge fan of strongly typed code (thus why I shy away from languages that aren't) so it made perfect sense to again utilize this approach. As I utilize new tags for whatever reason, the logic is contained only here so I won't be hunting around for where to update it. Another less "clean" approach would be to put these in the web.config or in your SQL Database. Though I find both of those more performance intensive and not necessary in this case. Now that the business and data layers are good to go for the time being, let's go back to our MVC4 App. Inside my controller the code is pretty simple still for my Index:
public ActionResult Index() {
     var model = new Models.HomeModel(); using (var pFactory = new PostFactory()) {
     model.Posts = pFactory.GetPosts(new DateTime(2001, 1, 1), new DateTime(2013, 4, 13)); }
ViewBag.Model = model; return View(model); }
]]>
At the moment I don't have my WCF Service written yet so for the time being I am simply referencing the Windows Class Library mentioned above, thus why I am referencing the PostFactory class directly in the Controller. Then in my View:
@model bbxp.mvc.Models.HomeModel @{
     ViewBag.Title = "Jarred Capellman"; }
@foreach (var post in Model.Posts) {
     @Html.Partial("PartialPost", post) }
<script type="text/javascript"> SyntaxHighlighter.all() </script> ]]>
As I am looping through each post I am calling out to my Partial View, PartialPost. And for my Partial View:
@model bbxp.lib.Objects.Post <div class="post"> <div class="Date"> <h3>@Model.PostDate.ToLongDateString()</h3> </div> <div class="Content"> <div class="Title"> <h2>@Model.Title</h2> </div> <div class="Body">@(new MvcHtmlString(@Model.Body))</div> </div> </div> ]]>
The @(new MvcHtmlString(@Model.Body)) line is very important otherwise your HTML Tags will not be parsed as you would expect. When all is said and done I went from this last night: [caption id="attachment_1982" align="aligncenter" width="300"]End Result of an Initial Conversion End Result of an Initial Conversion[/caption] To this tonight: [caption id="attachment_1992" align="aligncenter" width="300"]After applying regular expressions to the Post Content After applying regular expressions to the Post Content[/caption] Next up is creating the WordPress Sidebar History and extending functionality of the "engine" to support single Post Views.