My Website

By Krystal Ruwoldt

Updated 11/15/2020


See the source code for this project:  

This project is my current portfolio and blog website - this one you are visiting right now!. It is a C# ASP.NET Core 3.1 basic web app with a custom admin user interface so I can edit the website content dynamically. Currently I am already making some major enhancements to the backend, considering dropping Bootstrap altogether for a less verbose CSS/JS framework and redesigning some of the logic in my admin user interface.


Table of Contents


Design & Planning

Purpose

The original purpose of this website was to demonstrate my skills and experience to prospective employers, clients and other developers through a portfolio of past and current projects. It made sense for this website to include a blog so that I could document my development journey. I knew from the outset that this project needed to be a dynamic website for the type of content I wanted to include, so I chose a C# ASP.NET Core web app mainly because I already had experience with the .NET Core framework and C#.

This website could have been constructed faster with Django, but I generally prefer working with strictly-typed languages and like how .NET Core has dependency injection baked right in. This gets a programmer thinking about the dependency inversion principle from the outset and (in my opinion) produces better code.

Initial Design

From the beginning I wanted a dark themed website, as dark screens are generally easier on the eyes. I made a image from a photo of my main PC that I'd been modding and a screen shot of some of the code in my LWJGL (Lightweight Java Game Library) 3D Game Engine Demo. This ended up becoming the Home Page background and the colour palette for the rest of the website. That lead me to creating my logo, which I did in good old Paint.Net. (Sometimes the simplest programs are the best!)

Original desktop/mobile mockup

I decided to use Bootstrap/jQuery for most of the CSS/JS as it's already included in the Visual Studio templates. The content and functionally of the website was more important at this stage then design as I wanted to establish a robust back-end to the website as a priority. So I planned out a visual database schema as a starting point and then got busy implementing this schema using .NET entity framework. Here is the very first database relational diagram I drew using the Db Designer Tool.

First database relational diagram

Posts and portfolio items were separated early on as there was likely to be different data fields required, particularly as I knew I would (at minimum) want a link in the portfolio item for the project's source code. I added a few meta fields in these tables as I was already thinking about SEO (Search Engine Optimization).

Comments were something I wanted to allow (or disallow) so I designed these to be child tables of the Posts and PortfolioItem tables. As I planned to use the built-in Authentication middleware I decided to extend the default database, customising existing tables as required and linking Users with Comments. One logic rule I had for the database early on was that 'user comments would be deleted upon deletion of users but posts/portfolio items should NOT be deleted unless no comments exist'. Basically, if I'd released content that was actually being read, I didn't want to then delete it!

One of the biggest 'bug-bears' I did not pick up at this stage (which in hindsight, I really should have!) was that I set one-to-many relationships between the Categories and Posts and PortfolioItems tables. Although this works somewhat okay, really my projects and posts fall into multiple categories. So changing these relationships to many-to-many is the number one item on the to-do list for the next major update of this site!

After I completed this initial planning, I created a couple of experimental projects to test out my plans and fine-tune some of functionality. These experiments really helped build a foundation that I was to implement in the real project.

Table of Contents


Development

This project was worked on under self imposed time restraints, as I wanted to get the site up and running and then focus on the site content. In the end, what is a website without functionally and great content?

Designing Layout of the Domain

My first experimental project was really just a mock-up to trial a few different design ideas I had for the site. I kind of liked the default layout of the old .NET Framework template - plain and simple! So with this in mind, a dark theme, my background image and logo - I created the Navigation Bar, Footer and Home page layout. This process helped finalise the colour palette I'd end up using across the entire site.

The .NET Framework Default Template

The .NET Framework Default Template

Next I played around with the layout of the Blog, Portfolio, Post and Portfolio Item pages, which indicated early on that I would need some kind of partial view for side bar content (later I would discover View Components... wow!). SASS was then used to come up with an early version of the custom Bootstrap stylesheet for the theme. I also tested out some of the Bootstrap 4 components, such as cards, breadcrumbs and jumbotron. I tried out the carousel but since one of the key rules of UI design is that 'the user should be in control', this 'got the boot' (no pun intended!).

No Carousels or Sliders Please

No carousels or sliders please

Designing Layout of Admin User Interface

Next I had to figure out how I wanted my Admin User Interface to be structured. My main requirement was that I needed the ability to create and edit my content pages in raw HTML. So I found Trumbowyg - a great HTML text editor that was perfect for my needs. I also realised that a partial view or similar component (View Component!) would be needed to make browsing and uploading assets easier.

Repositories and Custom Identity

My second experimental project began as a blank project where I developed the Models and Data Repository. I tested how I would dynamically save images related to posts and portfolio items using PhotoSauce MagicScaler and a separate FileManager repository. The Repository and File Manager classes grew quickly as I implemented CRUD functions for persistant storage of my data. Basic Authentication was added and this gave me an opportunity to test out segregation of the Admin User Interface and Domain.

I only created the basic views and the view models that were necessary to wire up the controllers with the repositories in this project, as it was a test to see if my program logic was sound. I was fairly confident, so I created a new NET Core MVC Web App with Individual User Accounts (which became this version of the actual site!). Dependencies were added as necessary and I quickly copied over all the code I wanted from my two test projects. Identity pages were scaffolded in and customised as needed.

Now that the project looked something more like an actual website, I was able to make a list of features I still wanted to add, or features that needed some improvement. I also had a fair bit of styling to finish, so using Trello together with the Task List in Visual Studio, I worked day by day knocking off these tasks.

Slug Generator and Pagination Helper

While working on a Django project, I got the idea about using a slug field in my post and portfolio URLs. So I created a Slug Generator to get the slug from the post/portfolio item title. I also implemented a Page Helper to enable smart pagination - as at some point I may have many posts and projects and do not want long lines of page numbers displaying all over the screen!

Slug on a newspaper

Slug is newspaper jargon for an 'article', not the garden variety!

View Components

How awesome are View Components?! I've used them for displaying side-bar content (such as links to other posts) or in my admin interface (for viewing related content assets). There will definitely be a blog article on View Components, as I am still amazed at how useful they are!

Add a Dynamic About Page

I decided to make my About page dynamic as I had ideas for different sections that I would want to update as time went on. It was quite easy to do as I had already written some of the content that is on my About Page, so I knew exactly the sort of database table structure I'd need. Then it was just a case of repeating and modifying code I already written for other classes.

Add Static Terms Page & Contact Page

One of the most challenging aspects of creating this website was figuring out terms and conditions, privacy and cookie policies. It was difficult working out which and what parts of law apply for my particular site, but I got a top tip from the ladies at the She Codes organisation, to check out Lawpath.  I was able to get example policies from this Australian online legal group that cover all the standard legalities involved with a website based in Australia. This made it easier to establish my own policies with the help of an online general policy generator.

This site also needed a Contact page so that my email address was not openly displayed. This required the use of an automated email service, which I also needed for various Authentication tasks. Following along with the Microsoft documentation, I set up SendGrid API for this purpose. At this time, the automated email using SendGrid worked well, but during deployment I was to discover a major problem!

Review Website Security & Privacy

Getting close to deployment, I reviewed site security and implemented more privacy measures. As I'd already written my privacy policies, I was able to identity and add additional user consent checkboxes, customisation of the cookie policy and identify additional collected personal data that needed to be included in Downloadable User Data.

Finally I implemented a great number of Security Headers and tested Antiforgery Cookies. Http Strict Transport Security (HSTS) was also reviewed and enabled.

Table of Contents


Testing & Deployment

Testing In Debug

Throughout development I constantly was debugging my code. Generally as I write code, I use breakpoints in the IDE, run the project and step through to check my logic. I could have gone the extra mile and set up unit tests, but for the size of this project and the time restraints I'd set, I left this out. I was (and still am) pretty confident that my code is sound. Yet I will be including unit tests as I upgrade this version of the site.

Publishing Locally

I tested out the website by publishing it locally with SQL Server and IIS. This helped me set up the Production environment and make a few improvements to page loading time. Finally I felt ready to release this website to the www!

Deployment & Automated Email Saga

I spent about a week deploying this website and running speed tests and security tests on the actual site. Since I am using Facebook for an external login provider, I reviewed this and how the website and pages displayed in search results and social media links. But while testing the automated email service, I discovered a major problem!

Unfortunately, some time over August or September, many of SendGrid's IPs had been added to the Spamhas.org blacklist, due to some phishing scandal. So I had to come up with another solution for the email service my site uses. This was a huge setback, but I managed to come up with a solution that I wrote my first epic blog post about.

Real Content Testing

As of the date writing this article, I'm currently in this 'stage'. Whilst I haven't found any major bugs at the moment, I was aware I'd probably need to adjust and add a few style classes to site.css. I've also been testing how the content displays on various devices by using emulators. I also noticed that some monitors render colours somewhat different to what I expected (due to driver settings on monitors/GPUs etc). So I have made a few minor adjustments to make readability a bit better. I also added a nice little JS/CSS Preloader so we don't have to watch pages load chunk by chunk!

A preloader example

SEO Plan, Switching Facebook App to 'Live'

This is the final step I'm taking before I really start promoting this site. Although I've already set up and tested most of the SEO features and tested external logins during deployment, I realized that I'd need to write a little more code to adjust the post or portfolio item title pictures so they display nicely for the og:image tag. I also have a few tweaks lined up to improve first page load times. I am basically now up the last update publish on the site, so then the Facebook app can then be switched to 'live' so that any user can actually sign in using the external login function.

Finally I'll set up a SEO plan for this website. This plan will have ongoing tasks such as chasing back-links, reviewing internal and external links, Google Search Console, social media marketing, reviewing meta-data, content targeting etc.

Table of Contents


Improvements & Future Features

In the next version of this website, these large improvements will be implemented to improve code readability and functionality. More improvements to site speed and better responsiveness for mobile are other areas I want to tinker with.

Refactor 'Portfolio Items' to 'Projects'

Naming my projects as 'portfolio items' became tedious when developing this website. I'll definitely go through and refactor this, which I think will make it bit easier to read! I really don't like naming main tables/classes with more than one descriptive word, because when adding additional tables/classes (like 'PostMainComments') the names become verbose. I guess at the time, the word 'project' did not pop into my head!

Posts and Projects to have Multiple Categories

This is the number one improvement to the functionality and display of the website. As already mentioned in the initial design and planning section of this article, I really should have enabled this from the outset just so my content can be organized better. There will need to be logic established so that:

  • Posts and projects do not have too many categories; and
  • Only one category to be displayed when items are in groups - i.e. a 'primary' category.

After I implement the above, I will also make a few design changes to the home page. I was never really happy with that giant 'click here for categories' button.

Replace Bootstrap and jQuery

Whilst these are great for getting a new website up and running fast, I find Bootstrap and jQuery bloated for what I need. So I'll be switching to Bulma and Vue.js and abstract the entire project out to separate layers in the process. I will be able to do a lot more with the forms I use in the admin area to upload content if I use Vue, and that will make updating this website so much better!

Smaller features to add by the next website release will include the following:

  • Options for users to delete/edit individual comments;
  • Add search fields for website management pages;
  • Improve search options for the portfolio and blog pages;
  • Add other external login providers, perhaps Twitter?

Also to do is a bunch of small code refactors throughout the project and get hold of an iOS device to test the site properly. I've only used emulators, android devices and PCs I've had on hand for testing. If you are reading this on an iOS device, I would really appreciate hearing your opinion! Send me some feedback via my Contact Page.

Table of Contents


Overall it was enjoyable building this website and I learnt quite a lot more than I was expecting. It's a real project that is going to keep on evolving as I and others use it.