使用Markdown和ASP.NET MVC3创建基于文本的博客
2012-04-26 12:17
288 查看
前言:
步骤1:创建初始的Blog应用
本次示例使用Phil Haack's Really Empty MVC Project Template,添加文件夹:App_Data/BlogPosts,Content/BlogPostImages;添加Controller: HomeController;以及相关联的View Views/Home/Index.cshtml;和其他Shared Views,初始的CSS样式。完整的Solution结构和完成后的应用运行截图如下:
placeholder:截图1
步骤2:安装Markdown
Markdown是一个text-to-HTML转化工具,针对人群为网络写手,博主等。Markdown允许你用容易读/写的纯文本格式写文章,然后转变成结构正确的XHTML(或者HTML)。Markdown格式的文本设计目的是允许内容以as-is发布,像纯文本,不需要用tag标记等。Markdown是免费软件,遵循BSD-style开源协议license。
既然我们使用MVC 3(语言为C#),可以利用MarkdownSharp,也是一个开源的Markdown处理器的C#实现,在Stack Overflow上被featured。使用Nuget Package Manager console安装(添加一个单独文件MarkdownSharp.dll到Bin目录):
PM> Install-Package MarkdownSharp
步骤3:Blog Post和Summary Data命名约定
Blog post是.txt文件,存储在文件夹AppData/BlogPosts。本次示例,我们对文件blog post和文件blog summary使用如下的命名约定,使用字符分割日期和名称信息:
YYYY-MM-DD[blog-post-name-separated-by-hyphens].txt // blog post markdown syntax content
YYYY-MM-DD[blog-post-name-separated-by-hyphens]_summary.txt // JSON formatted blog summary info
使用两个文件的目的是将Markdown的内容和Blog Post summary。Markdown的目标就是内容的as-is,无须任何额外的标记tag或者指令。YYYY-MM-DD用来表示博客发布时间,[]内为博客标题,使用-字符分开单词。Summary文件使用JSON语法现实blog summary。
步骤4:创建File System Data Model
首先,创建model Models/BlogListing.cs,用来表征创建博客需要的数据。
遵循上述命名约定,我们创建两个示例文件。Summary文件使用JSON语法,完整的blog post使用Markdown语法。
在web.config中的appSetting键值中添加BlogPostsDirectory配置,这样可以无需编译修改数据目录。
Models/BlogFileSystemManager.cs用来检查上面配置的数据目录,然后返回博客列表。
最后,是Views/Home/Index.cshtml的代码,注意我们使用的root级的URL,需要在下步定义一些Routes。
现在,运行网站,如下图:
placeholder 截图
步骤7:显示博客内容
在Global.asax.cs定义一些Routes:
当用户点击一个博客链接时,调用Action方法
最终完成,运行截图如下,注意URL已经优化。
placeholder:截图。
步骤1:创建初始的Blog应用
本次示例使用Phil Haack's Really Empty MVC Project Template,添加文件夹:App_Data/BlogPosts,Content/BlogPostImages;添加Controller: HomeController;以及相关联的View Views/Home/Index.cshtml;和其他Shared Views,初始的CSS样式。完整的Solution结构和完成后的应用运行截图如下:
placeholder:截图1
步骤2:安装Markdown
Markdown是一个text-to-HTML转化工具,针对人群为网络写手,博主等。Markdown允许你用容易读/写的纯文本格式写文章,然后转变成结构正确的XHTML(或者HTML)。Markdown格式的文本设计目的是允许内容以as-is发布,像纯文本,不需要用tag标记等。Markdown是免费软件,遵循BSD-style开源协议license。
既然我们使用MVC 3(语言为C#),可以利用MarkdownSharp,也是一个开源的Markdown处理器的C#实现,在Stack Overflow上被featured。使用Nuget Package Manager console安装(添加一个单独文件MarkdownSharp.dll到Bin目录):
PM> Install-Package MarkdownSharp
步骤3:Blog Post和Summary Data命名约定
Blog post是.txt文件,存储在文件夹AppData/BlogPosts。本次示例,我们对文件blog post和文件blog summary使用如下的命名约定,使用字符分割日期和名称信息:
YYYY-MM-DD[blog-post-name-separated-by-hyphens].txt // blog post markdown syntax content
YYYY-MM-DD[blog-post-name-separated-by-hyphens]_summary.txt // JSON formatted blog summary info
使用两个文件的目的是将Markdown的内容和Blog Post summary。Markdown的目标就是内容的as-is,无须任何额外的标记tag或者指令。YYYY-MM-DD用来表示博客发布时间,[]内为博客标题,使用-字符分开单词。Summary文件使用JSON语法现实blog summary。
步骤4:创建File System Data Model
首先,创建model Models/BlogListing.cs,用来表征创建博客需要的数据。
namespace TxtBasedBlog.Sample.Models { public class BlogListing { public string Url { get; set; } public string Title { get; set; } public string ShortDescription { get; set; } public string Content { get; set; } public string Author { get; set; } public DateTime PostDate { get; set; } public string Image { get; set; } } }然后,创建model Models/BlogPost.cs负责加载博客文章内容。
namespace TxtBasedBlog.Sample.Models { public class BlogPost : BlogListing { public string Body { get; set; } } }步骤5:写一个Blog Post示例
遵循上述命名约定,我们创建两个示例文件。Summary文件使用JSON语法,完整的blog post使用Markdown语法。
{ Title: "ASP.NET MVC Overview", Url: "asp_net_mvc_overview", PostDate: "2012-02-09", Author: "Microsoft ASP.NET Team", ShortDescription: "ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and that gives you full control over markup for enjoyable, agile development.", Image: "content/blogpostimages/image001.jpg" }
**ASP.NET MVC** gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and that gives you full control over markup for enjoyable, agile development. MVC includes many features that enable: * fast, TDD-friendly development for creating sophisticated applications * use the latest web standards. [Learn More About MVC](http://www.asp.net/mvc "Learn more about MVC today!")步骤6:显示博客列表
在web.config中的appSetting键值中添加BlogPostsDirectory配置,这样可以无需编译修改数据目录。
<appSettings> ... <add key="BlogPostsDirectory" value="~/App_Data/BlogPosts"/> ... </appSettings>
Models/BlogFileSystemManager.cs用来检查上面配置的数据目录,然后返回博客列表。
namespace TxtBasedBlog.Sample.Models { public class BlogFileSystemManager { private string filePathToBlogPosts; public BlogFileSystemManager(string dirPath) { filePathToBlogPosts = dirPath; } public List<BlogListing> GetBlogListings(int limit) { var allFileNames = getBlogPostsFiles(); var blogListings = new List<BlogListing>(); foreach (var fileName in allFileNames.OrderByDescending(i => i).Take(limit)) { var fileData = File.ReadAllText(fileName); var blogListing = new JavaScriptSerializer().Deserialize<BlogListing>(fileData); blogListings.Add(blogListing); } return blogListings; } private IEnumerable<string> getBlogPostsFiles() { return Directory.GetFiles(filePathToBlogPosts, "*summary.txt").ToList(); } } }
HomeController加载
BlogListing,在View中渲染。
namespace TxtBasedBlog.Sample.Controllers { public class HomeController : Controller { public ActionResult Index() { var manager = new BlogFileSystemManager(Server.MapPath(ConfigurationManager.AppSettings["BlogPostsDirectory"])); var model = manager.GetBlogListings(5); return View(model); } public ActionResult Error() { return View(); } } }
最后,是Views/Home/Index.cshtml的代码,注意我们使用的root级的URL,需要在下步定义一些Routes。
@model IEnumerable<TxtBasedBlog.Sample.Models.BlogListing> <h2>Recent Blog Posts</h2> @{ foreach (var item in Model) { <div class="post"> <div class="img-post"> <a href="/@item.Url" title="@item.Title"><img src="../../@item.Image" alt="" /></a> </div> <div class="inline"> <p><a href="@item.Url">@item.PostDate.ToString("MM/dd/yyyy") - @item.Title</a><br />@Html.Raw(item.ShortDescription)</p> </div> </div> } }
现在,运行网站,如下图:
placeholder 截图
步骤7:显示博客内容
在Global.asax.cs定义一些Routes:
public static void RegisterRoutes(RouteCollection routes) { ... routes.MapRoute( "HomePage", "", new { controller = "Home", action = "Index" } ); routes.MapRoute( "Error", "Oops", new { controller = "Home", action = "Error" } ); routes.MapRoute( "BlogPost", "{postName}", new { controller = "Home", action = "ViewBlogPost", postName = "" } ); ... }
当用户点击一个博客链接时,调用Action方法
ViewBlogPost,在HomeController中添加
ViewBlogPost有关的代码。
namespace TxtBasedBlog.Sample.Controllers { public class HomeController : Controller { ... public ActionResult ViewBlogPost(string postName) { var manager = new BlogFileSystemManager(Server.MapPath(ConfigurationManager.AppSettings["BlogPostsDirectory"])); if (!manager.BlogPostFileExistsByTitleForUrl(postName)) { return RedirectToRoute("Error"); } var model = manager.GetBlogPostByTitleForUrl(postName); return View(model); } ... } }添加
BlogFileSystemManager来确保获得有效的数据文件。
namespace TxtBasedBlog.Sample.Models { public class BlogFileSystemManager { ... public bool BlogPostFileExistsByTitleForUrl(string titleForUrl) { var matchingFiles = getFilesForBlogPostByTitleForUrl(titleForUrl); return (matchingFiles.Count == 2); } public BlogPost GetBlogPostByTitleForUrl(string titleForUrl) { var matchingFiles = getFilesForBlogPostByTitleForUrl(titleForUrl); var summaryFileData = File.ReadAllText(matchingFiles.Where(i => i.Contains("_summary")).FirstOrDefault()); var blogPost = new JavaScriptSerializer().Deserialize(summaryFileData); blogPost.Body = File.ReadAllText(matchingFiles.Where(i => !i.Contains("_summary")).FirstOrDefault()); return blogPost; } private List getFilesForBlogPostByTitleForUrl(string titleForUrl) { // Updated 2012-03-07: // Richard Fawcett's regex suggestion to prevent titleForUrl subset results. Thanks Richard! var files = Directory.GetFiles(filePathToBlogPosts, string.Format("*{0}*.txt", titleForUrl)); var r = new Regex(@"\d{4}-\d{2}-\d{2}_" + titleForUrl + @"(_summary)?\.txt", RegexOptions.IgnoreCase); return files.Where(f => r.IsMatch(f)).ToList(); } ... } }然后,Views/Home/ViewBlogPost.cshtml负责渲染博客文章页面,我们使用一个自定义的Helper方法,
@Html.Markdown()来调用之前安装的Markdown库。
@using TxtBasedBlog.Sample.Models @model TxtBasedBlog.Sample.Models.BlogPost @{ ViewBag.Title = Model.Title; } <h2>@Model.Title</h2> <p>Posted on @Convert.ToDateTime(Model.PostDate).ToString("dd MMM, yyyy") by @Model.Author - @Html.ActionLink("Back to Blog List", "Index")</p> @Html.Markdown(Model.Body)@Html.Markdown()是由 Danny Tuppeny创建,原文见original post。
namespace TxtBasedBlog.Sample.Models { public static class MarkdownHelper { static readonly Markdown MarkdownTransformer = new Markdown(); public static IHtmlString Markdown(this HtmlHelper helper, string text) { var html = MarkdownTransformer.Transform(text); return MvcHtmlString.Create(html); } } }
最终完成,运行截图如下,注意URL已经优化。
placeholder:截图。
相关文章推荐
- 使用LAMP创建基于wordpress的个从博客站点
- 博客(文本)编辑工具Markdown使用初体验
- 使用LAMP创建基于wordpress的个从博客网站 分类: B3_LINUX 2014-07-15 16:45 800人阅读 评论(0) 收藏
- 使用LAMP创建基于wordpress的个从博客网站
- 使用LAMP创建基于wordpress的个从博客网站
- 使用LAMP创建基于wordpress的个从博客网站
- 博客(文本)编辑工具Markdown使用初体验
- 使用LAMP创建基于wordpress的个从博客网站
- 欢迎使用Markdown编辑器写博客右(文本效果页面)
- 使用LAMP创建基于wordpress的个从博客网站
- 使用Apworks开发基于CQRS架构的应用程序(三):创建快照
- 基于CentOS的MySQL学习补充三--使用Shell批量创建数据库表
- 使用curses函数管理基于文本的屏幕
- 欢迎使用Markdown编辑器写博客
- 欢迎使用Markdown编辑器写博客-CSDN
- 欢迎使用Markdown编辑器写博客
- 使用github创建个人博客出错
- 基于内核线程的创建、使用和退出以及延时宏的补充说明介绍
- 使用 Microsoft.NET Frameworks 创建基于 Windows 的应用程序
- 工欲善其事必先利其器(使用Markdown来编写博客)