Simple CMS with Linq to SQL part II

Following the same conventions we used to edit and delete our pages, let’s also add the same methods for our content comments.

public ActionResult EditComment(int? id)
{
	// Comment Id
	id = id ?? 0;
	int pageid = 0;

	if (id.Value > 0)
	{
		ContentComment comment;
		ContentPage contentpage;
		using (SimpleCMSDataContext db = new SimpleCMSDataContext())
		{
			comment = (from c in db.ContentComments
					   where c.CommentId == id.Value
					   select c).Single();

			contentpage = (from p in db.ContentPages
						   where p.PageId == comment.PageId
						   select p).Single();

			comment.ContentPage = contentpage;

			pageid = comment.PageId;
			
			ViewData.Model = comment;
			return View();
		}
	}
	return RedirectToAction("Read", new { id = pageid });
}


[HttpPost]
public ActionResult EditComment(int? id, FormCollection collection)
{
	int pageid = 0;
	if (id.HasValue)
	{
		ContentComment comment;
		ContentPage contentpage;
		using (SimpleCMSDataContext db = new SimpleCMSDataContext())
		{
			comment = (from c in db.ContentComments
					   where c.CommentId == id.Value
					   select c).Single();

			contentpage = (from p in db.ContentPages
						   where p.PageId == comment.PageId
						   select p).Single();

			ContentComment edited = GetCommentFromCollection(id.Value, collection, false);

			comment.Approved = edited.Approved;
			comment.Author = edited.Author;
			comment.AuthorEmail = edited.AuthorEmail;

			comment.BodyHtml = edited.BodyHtml;
			comment.BodyText = edited.BodyText;

			// Important to save changes here as the next step alters the model.
			db.SubmitChanges();

			comment.ContentPage = contentpage;

			pageid = comment.PageId;
			ViewData.Model = comment;
			return View();
		}
	}
	return RedirectToAction("Read", new { id = pageid });
}

public ActionResult DeleteComment(int? id)
{
	int pageid = 0;
	if (id.HasValue)
	{
		ContentComment comment;
		using (SimpleCMSDataContext db = new SimpleCMSDataContext())
		{
			comment = (from c in db.ContentComments
					   where c.CommentId == id.Value
					   select c).Single();

			pageid = comment.PageId;
			ViewData.Model = comment;
			return View();
		}
	}
	return RedirectToAction("Read", new { id = pageid });
}


[HttpPost]
public ActionResult DeleteComment(int id, FormCollection collection)
{
	try
	{
		int pageid = 0;
		ContentComment comment;
		using (SimpleCMSDataContext db = new SimpleCMSDataContext())
		{
			comment = (from c in db.ContentComments
					   where c.CommentId == id
					   select c).Single();

			pageid = comment.PageId;
			db.ContentComments.DeleteOnSubmit(comment);
			db.SubmitChanges();
		}
		return RedirectToAction("Read", new { id = pageid });
	}
	catch
	{
	}
	return RedirectToAction("Index");
}

We’re going to use a similar trick to our page editing before to edit our comments. We’ll be reusing the CreateComment control, but introduce code so we can select which mode to show.

Once again, it’s only the top and bottom portions of the control that needs special treatment.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SimpleCMS.Models.ContentComment>" %>
<%
	// If this model has a author IP, then we're editing a comment
	var mode = (string.IsNullOrEmpty(ViewData.Model.AuthorIP)) ? "CreateComment" : "EditComment";
	
	using (Html.BeginForm(mode, "Pages", new { 
		id = (mode == "CreateComment")? ViewData.Model.PageId : ViewData.Model.CommentId
	}, FormMethod.Post))
   {%>
<%: Html.ValidationSummary(true) %>
<div class="postform">
	<fieldset>
		<% if(mode == "CreateComment")  { %>
			<legend>New Comment</legend>
		<% } else { %>
			<legend>Edit Comment</legend>
		<% } %>
		
		<%: Html.HiddenFor(model => model.PageId) %>
		<p>
			<%: Html.LabelFor(model => model.Author) %>
			<%: Html.TextBoxFor(model => model.Author) %>
			<%
				// We don't have anonymous comments enabled, the "Author" field is required
				if (!(bool)Model.ContentPage.AnonComments)
					Html.ValidationMessageFor(model => model.Author); %>
		</p>
		<p>
			<%: Html.LabelFor(model => model.AuthorEmail) %>
			<%: Html.TextBoxFor(model => model.AuthorEmail) %>
			<%if (!(bool)Model.ContentPage.AnonComments)
		 Html.ValidationMessageFor(model => model.AuthorEmail); %>
		</p>
		<p>
			<%: Html.LabelFor(model => model.BodyText) %>
			<%: Html.TextAreaFor(model => model.BodyText, new { rows = 5, cols = 60 })%>
			<%: Html.ValidationMessageFor(model => model.BodyText) %>
		</p>

		<p>
		<% if(mode == "Create")  { %>
			<input type="submit" value="Post new Comment" />
		<% } else { %>
			<input type="submit" value="Save changes" />
		<% } %>
		</p>
	</fieldset>
</div>
<% } %>

And again we’re using the AuthorIP field which was also required in the database. If there is no IP, then this model didn’t come from the database.

All that needs to be done is to add the EditComment and DeleteComment full page views.

First the EditComment view…

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<SimpleCMS.Models.ContentComment>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Editing comment - <%: Model.CommentId %>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Editing comment - <%: Model.CommentId %></h2>

	<% Html.RenderPartial("CreateComment", Model); %>

    <div>
        <%: Html.ActionLink("Back to Page", "Read", new { id = Model.PageId })%>
    </div>
</asp:Content>

And the DeleteComment view…

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<SimpleCMS.Models.ContentComment>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Deleting comment - <%: Model.CommentId %>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Deleting comment - <%: Model.CommentId %></h2>

    <h3>Warning: You're about to delete a comment! This process cannot be undone. 
	Are you sure you wish to continue?</h3>
	<p>This comment was created <%: Html.FriendlyDate(Model.CreatedDate) %> by 
	<%: Model.Author %> and modified <%: Html.FriendlyDate(Model.LastModified) %>.
	</p>
	<%= Model.BodyHtml %>

    <% using (Html.BeginForm()) { %>
        <p>
		    <input type="submit" value="Delete" /> |
		    <%: Html.ActionLink("Back to page", "Read", new { id = Model.PageId })%>
        </p>
    <% } %>
</asp:Content>

Now you have everything needed to create, read, edit and delete pages and comments. In our next installment, we’ll look into refining what we have here and introducing membership and role functionality.

Enjoy!

Advertisement

3 thoughts on “Simple CMS with Linq to SQL part II

  1. Pingback: Simple CMS with Linq to SQL part II-a « This page intentionally left ugly

  2. I don’t know what this is all about, but it could sure use a more tag right near the top of the first page! (you don’t have to publish this)

    • thinsmek, I don’t censor comments that aren’t outright spam or have hate speech ;)

      I used the next best thing to the more tag… the nextpage tag.

      The more tag had caused some issues with my blog in the past, which is why I rarely use it. A lot of my content is raw code, so that may have something to do with it. This is an introduction to writing a content management system from scratch.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s