Creating a simple Content Management System

I have been working on creating a content management system (CMS for short) for troika-game.net. One of my tasks was to implement a way for the admin (who may not be a software engineer himself) to add, edit, and delete news from the home page. It is a very much needed (while still being rather basic) feature of our app. It requires the understanding of several aspects of ASP.NET Core MVC, so it’s a great way to learn the technology and besides – you got to start somewhere!

Entity – defining News

Let’s start by creating a new entity – we want to define what “News” will be for us and what their general structure will be. Of course right now we’re just providing the abstraction, not the actual content. Also, let’s not forget to decorate them with proper attributes like [Required] and datatypes (DateTime for Date, etc.).

    public class News
    {
        public int Id { getset; }
 
        [Required]
        public DateTime Date { getset; }
 
        [Required]
        public string Title { getset; }
 
        [Required]
        public string Summary { getset; }
 
        [Required]
        [DataType(DataType.MultilineText)]
        public string Content { getset; }
 
        [Required]
        public string Author { getset; }
    }

After adding that entity to the application’s database, there’s just one more thing we need to do before we’re ready to write any real logic to our news management system.

Interface – an abstract box of tools

We know what News are “made of”, now we need to think about what we want to “do” with them. We’ll be creating, editing and deleting them; an ability to quickly get all the news into one object will be useful as well – it will come in handy when we want to display all the news on the main page.

public interface INewsManager
{
    void AddNews(News news);
    void EditNews(News editedNews);
    void DeleteNews(int id);
    IEnumerable<News> GetCurrentNews();
    News GetNewsById(int id); 
}

We could create a NewsProvider service that implements the INewsManager now, but since the details of those methods aren’t important for the design of the news management system, I’ll leave it as an exercise to the reader. Instead, let’s go straight to MVC and see how it all connects together.

MVC – Interacting with the application

We need to find a way for the user (probably an administrator in this case) to add real content to our News entity. This is usually done by using html forms, so let’s try it. We’ll create a view file called CreateNews.cshtml and place it in the folder ~/Views/Administrator. A simple way to create a form would be to use Visual Studio’s command Add->View with Template: Create and Model Class: News. Our form could look like that:

@model Data.News
<form asp-action="CreateNews" method="post">
           <div asp-validation-summary="All" class="text-danger"></div>
           <div class="form-group">
               <label asp-for="Date" class="control-label"></label>
               <input asp-for="Date" class="form-control"/>
               <span asp-validation-for="Date" class="text-danger"></span>
           </div>
           <div class="form-group">
               <label asp-for="Title" class="control-label">Title</label>
               <input asp-for="Title" class="form-control" />
               <span asp-validation-for="Title" class="text-danger"></span>
           </div>
... (form shortened for brevity) ...
           <div class="form-group">
               <input type="submit" value="Create" class="btn btn-default" />
           </div>
       </form>

Thanks to the html code above, our user will be able to fill in the contents of the News with whatever he or she wants to. Of course you can choose different class parameters if you wish to customize user experience in your application. Next thing we’ll be doing is writing two CreateNews() methods in AdministratorController. One of them will be a [HttpGet] method for displaying the form, and the second one will be a [HttpPost] method for submitting the model and sending it to the NewsProvider (the implementation of INewsManager interface).

[HttpGet]
public IActionResult CreateNews()
{
    return View();
}
 
[HttpPost]
public IActionResult CreateNews(News newNews)
{
    this.newsManager.AddNews(newNews);
    return this.RedirectToAction("Index""Home");
}

The name of the view (CreateNews.cshtml) is the same as the names of the [HttpGet] and [HttpPost] methods – that is not a coincidence! It’s necessary in order for the controller to be able to find the requested .cshtml file. Our html form is connected to the [HttpPost] method and you’ll also need to place a button connected to the [HttpGet] method somewhere in your application.

One final thing we need to do is finally displaying the News on our home page. To do that, we’ll just create a simple ViewModel that will help us send the News to the View (quite literally):

public class HomeViewModel
{
    [Display(Name = "Enumerable of news")]
    public IEnumerable<News> NewsEnumerable { getset; }
}

We’ll also create an Index() method in HomeController that will use the ViewModel, add News to it and return a View:

public IActionResult Index()
{
    var viewModel = new HomeViewModel();
    viewModel.NewsEnumerable = this.newsManager.GetCurrentNews();
    return View(viewModel);
}

Lastly, our Index.cshtml should be using HomeViewModel and displaying a div container for each News in NewsEnumerable:

@model HomeViewModel;
@foreach (var news in @Model.NewsEnumerable.Reverse())
{
    <div class="itemcontainer">
                <div>@news.Date.ToShortDateString()</div>
                <div class="text-uppercase">@news.Title</div>
                <div>@news.Summary</div>
            </button>
            <div>
                @Html.Raw(news.Content)
                <p>Author - @news.Author</p>
            </div>
            <br />
            <br />
    </div>
}

The Reverse() method called on the NewsEnumerable is important for the news to appear in order from the newest created to the oldest (as news really should ;] ).

In this tutorial we’ve defined a News entity, defined an interface for managing the news in the database, created a html form for the user, and connected it to the controller.  We’ve also displayed the news on the home page. The implementation of the EditNews feature would be nearly identical to CreateNews, and DeleteNews would be even simpler (since we don’t need a form for that).

Leave a Reply

Your email address will not be published. Required fields are marked *