Jbachtiger / ci-pp4-the-unconventional-programmer

Full-Stack Toolkit Project Portfolio

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PP4 - Full Stack Toolkit - The Unconventional Programmer

Introduction

The Unconventional Programmer is a blog/Reddit style website targeted at aspiring and junior developers. This site aims to share useful resources that will help people who have taken unconventional routes into programming and are at the start of their careers. It is a site that allows users to share their personal experiences via either creating a blog post themselves or commenting on existing ones.

The website was built in Django using Python, JavaScript, CSS and HTML. Users are can create, edit, read and delete posts. On login, a profile is automatically created for them which users can click into and edit/update. They can upload images for their blogs as well as a profile picture. Users can also comment on and like/unlike posts.

The site provides role-based permissions for users to interact with the central dataset. Included is user authentication and Full CRUD functionality for blog posts.

Mockup

Live Site

Click here to view live site

Table of Contents

User Experience

Site Goals

  • To provide users who are just starting out their careers in programming to find helpful resources
  • To provide users with a place to share their knowledge and experiences
  • To provide users with a place where they can feel part of a community of like-minded individuals
  • To show users that they are not on their own and there are many people in the same shoes as them and feeling like them
  • To show users that it gets better and that coding is a fantastic career choice

Sites Ideal Users

  • Career changers currently studying at a coding Bootcamp
  • Junior developers who are right at the beginning of their work journey
  • Graduates with programming related degrees
  • People looking to share their experience and knowledge with those less experienced

Epics

6 Epics were created which were further developed into 20 User Stories. The details of each epic along with the associated user stories can be found in the kanban board here.

  1. Initial Django Setup #1
  2. User Profile #5
  3. Sign in/Sign Out #12
  4. Blog Post #17
  5. Site Owner Goals #24
  6. Site Search #15

User Stories

20 User stories were created from the 6 Epics and assigned the classifications of Must-have, Should-have, Could-have and Won't have. Each user story also includes acceptance criteria and tasks that need to be completed for that story to be closed.

Below are links to each of the individual user stories that were completed within the project's initial release.

  1. Initial Django Setup

    • Install Django and supporting libraries #2
    • Keep secret keys secure #3
    • Early deployment of the site to Heroku #4
  2. User Profile

    • Register for an account #6
    • User can view their profile #7
    • User can edit their profile #8
  3. Sign in/Sign Out

    • User account Sign in/Sign out #13
    • Features applicable to signed-in users only #14
  4. Blog Post

    • Create a blog post #18
    • View a blog post #19
    • Update a blog post #20
    • Delete a blog post #21
    • Like/Unlike button #22
    • Comment #23
  5. Site Owner Goals

    • Responsive templates #26

For ease of reading, I have also listed all the completed user stories below:

  • As a developer, I can set up Django and install all the supporting libraries to get started with the project, so that I am ready to start development
  • As a developer, I can set up the Django development environment to secure the secrete keys, so that I do not expose the secret keys to the public or a party that should not see them
  • As a developer, I can deploy the site to Heroku, so that I can confirm that everything is working before the development of the site and enable continuous testing with the production environment
  • As a user, I can create an account by registering my details so that I can comment and like posts
  • As a user, I can see the details of my user profile so that I can see my info and what others can see about me
  • As a user, I can edit my profile so that I can keep my information up to date
  • As a user, I can sign in and sign out of my account so that I can keep my account secure and private
  • As a site owner I will restrict some features of the site to registered users only so that it encourages users to create an account with the site
  • As a user, I can create a blog post so that I can share my ideas and experience
  • As a user,I can read the blogs on the site so that I can benefit from the information shared
  • As a user, I can update a blog I have created so that I can correct mistakes I've made
  • As a user, I can delete a blog post I have written so that I can remove it from the site
  • As a user, I can like or unlike blog posts so that valuable blog posts are recognised as good content
  • As a user, I can comment on blogs so that I can have a community discussion around the topic and gain further insights
  • As a site owner I can create my site to be fully responsive so that it provides a good user experience on all devices

Design

Wireframes

Before coding commenced, a set of wireframes were created to help me visualise roughly what the website would look like on desktop, tablet and mobile. It provided a starting point in terms of design. The finalised project went through many iterations and has changed from the initial wireframes however, inspiration was taken from these wireframes.

  • Homepage Homepage

  • Blog Page Blog Page

  • Profile Profile

  • Sign-in Sign-in

  • Sign-up Sign-up

Color Scheme

  • The colour scheme has been carefully chosen to ensure accessibility for all
  • The colours compliment each other and ensure the text is easily read
  • The colours are consistent throughout the website and are used for specific purposes
  • The main colours used throughout the website are:

Colour Palette

Other colours used also were #8C6D89(light purple), #fff (white) and #ED91B3 (light pink). The colour #ED91B3 replaced #ED5393 as the colour for the CTA buttons. This change was made for accessibility reasons and to ensure the colour contrast was within the correct ratio for readability.

Fonts

The font used in this project was Roboto with a backup of sans-serif. It was chosen for its easy readability for users. Fonts were imported using Google Fonts.

Agile

Throughout this project, an agile approach was taken to developing the website. Each activity was broken down into smaller bite-sized more manageable actions from initially creating 6 Epics, which were then broken down into smaller User stories. Each of the user stories then had an acceptance criterion and a list of tasks to complete. This made the overall project much more manageable to build. GitHub labels were used to categorise the User Stories using the MoSCoW Prioritisation technique. This clearly defined what tasks were most important to complete and where the focus should be.

As mentioned above, a kanban board was created using GitHub Projects here to help keep track of all the tasks including Todo, In Progress, Done and Future Development.

Kanban First Stage

Kanban Second Stage

Kanban Third Stage

Kanban Fourth Stage

Database Schema

Smart Draw was used to create a database schema to visualise the types of custom models this project might require. This schema was used as a guide to what needed to be added to each model. In the end only the Blog Post, Comment and Profile models were used due to time constraint. AllAuth was also used for the authentication system. This uses the built-in Django User Model.

Database Schema

Features

Homepage

A simplistic homepage with minimal distractions ensuring the users main focus is on looking through the blog post lists. The blog posts on the homepage are displayed in a single list view and provide a summary of what the blog contains. This provides the user with some quick information to see if they would like to find out more information about it including who submitted it when it was published, the topic of the post, a summary and how many likes it has received. These fields have all been included to provide the user with a better experience and be able to make an informed decision as to whether they would like to continue into the blog post to read it. Users do not need to be registered to view a post.

Homepage

Navbar

The navigation bar is featured on all pages, is responsive and has active links functionality so the user knows which link they are on by hovering on it in the navbar. It is identical on all pages and is easy to use providing a good user experience. For mobile view, the navbar reduces to a burger menu. The purpose of this feature is to allow users to navigate all pages easily across all devices without having to use a back button to get to the next page. There is also authentication in place which will change what displays on the navbar depending on whether a user is logged in or not.

  • Logged out Navbar

Navbar

  • Logged in Navbar

Navbar

Footer

The footer section includes links to relevant social links which all open up in a new tab to allow easy navigation for the user. They also have a hover effect added to them to make them stand out more and obvious to click. The copyright section is in place for legal reasons and the date is automatically updated using JavaScript. The footer is a good way to encourage users to connect via social media.

Footer

Pagination

The blog posts have had pagination functionality added to them so that 3 posts are displayed on each page. This has been implemented to improve the user experience and not overwhelm the user with information and blog posts.

Pagination

Blog Post

Each post has a title followed by a submitted by field. There are also Edit and Delete buttons for signed in users, which have been put at the top of the page to ensure the user doesn't miss them. The main content is then added using the WYSIWYG editor Summernote which provides basic styling and image uploads. At the bottom of the blog post, there is a section for users to leave comments and talk to each other as well as a like/unlike option. The purpose of the blog layout is to make it as easy as possible for a user to read the content, digest it and then contribute to it in the form of comments and likes.

Read Post

Comments

Each blog post has a comment section where users can post their comments for that specific blog. The user can see the number of comments that have been made on the post, the name of the user who wrote each comment and when that comment was published. Users can only make a comment when signed in and will be prompted to sign-in or sign-up in order to leave comments. This is a great way for users to interact with each other and the publisher, discuss the topic and ask/answer questions.

  • Not signed into an account

Comments

  • Signed into account

Comments

Likes

The user can also like and unlike blog posts. The purpose of this is to provide useful feedback to the community on how popular/good a post is by rewarding that post with likes. If a user changes their mind they can remove their like from a post. Each like is counted on the blog page as well as on the homepage where the blog list sits. If a post is unliked by a user this is reflected in the count.

  • Like

Like

  • Unlike

Unlike

Login / Logout / Sign-up

Django Allauth was installed and used to create the register, sign-in and sign-out functionality meaning the project would have the authentication foundations in place to expand functionality in future. These pages are needed to provide authenication and to allow users access to content that is restricted to those who have created a login.

  • Login

Login

  • Logout

Logout

  • Sign-up

Register

Create a Post

If the user is logged in they can create a post. Current fields being captured include title, title tag, summary (which is used to display on the homepage), body (using the summernote editor) and topic.

Create a Post

Edit a Post

If the user is logged in they can edit a post they have created but not anyone else. Same fields are included as with create a post.

Edit a Post

Delete a Post

Once a user has created a post they can delete their post. They can do this by accessing the blog that they have created and wish to delete and clicking the delete button at the top of the page. They will then be taken to a page asking them if they are sure they wish to delete their blog and to click confirm or go back to their blog page.

Delete a Post

Profile

Once a user registers, they will have a profile page automatically created for them. The link to their profile page will appear in the navigation bar once logged in. If they navigate to this page, they will be able to update their username, email address, add a bio and upload an image. The purpose of this page is to provide users with more control over their account and start to be able to customise their data.

Profile

Messages

To provide users with more feedback after they take certain actions, a messaging system has been added to let users know their desired actions have occurred. For example:

  • Login

Login

  • Logout

Logout

  • Profile Updated

Profile Updated

These messages last for 2 seconds before automatically being timed out. Alternatively, the user can click a little 'X' to remove them.

Admin Page

A superuser was created for this project to manage the backend admin section. Users with admin access have more functionality than normal users such as the ability to create, read, update and delete information like users, posts, profiles and comments.

Access is restricted to approved admins only and can be accessed by adding '/admin' to the URL on the homepage and signing in if not already signed in through the front end of the site.

Admin

Future Development

There is much functionality that can be added to this project in the future including:

  • Blog search - a search box could be included on the homepage to allow users to search the site for posts by topic, author etc

  • Dark Mode Customisation - adding the ability to view the site in dark mode as this is a preferred method for a developer to work with code and would be a nice add on

  • Creating the functionality for users to be able to delete their account through their profile page and not just through the admin

  • Allowing users to reset/change their passwords

  • Report abusive/inappropriate comments flag - this would alert an staff member/admin user to then manually review a comment and be able to remove it if deemed abusive/inappropriate

  • Add comment nesting so that users can see specific responses to their comments

  • The ability for users to login via social networks such as Google or Facebook

Testing

Throughout development, errors and warnings were fixed as I went on such as indentation problems, syntax errors and missing code errors. I also went through all my code files once the main functionality and style of the website was completed by using validators and following best practice to eliminate problems with lines too long, trailing white spaces, stray divs etc.

Google Chrome developer tools were used to inspect pages and look through code to help debug errors caused by HTML, CSS or JavaScript code.

Manual and automated testing has been carried out, as well as proofreading of the ReadMe file using Grammarly.

Manual Testing

I have manually tested all the features of the website making sure to go through them with different browsers and device sizes. I have also checked the features of the site against the original user stories to ensure they have all been actioned.

User Stories

Manual User Stories Testing

Features

Manual Features Testing

Automated Testing

I have performed some basic automated tests on the forms, views and models as shown below.

Models

Views

Forms

Profile - Forms

  • All the above tests passed as shown below

Tests Passed

  • I have also installed Coverage with pip3 install coverage and ran the program in the terminal using the coverage run manage.py test command. A file was generated with coverage html and the results can be found in the htmlcov folder in the index.html file.

Browser and Device Testing

Browsers

  • The website was tested on the following browsers: Google Chrome, Firefox, Microsoft Edge and Safari.
  • For each browser, functionality was tested including links and the responsive design.
  • The website performed as intended and the responsive design was checked using developer tools across multiple devices with structural integrity holding for the various sizes.

Devices Tested

The website was viewed on a variety of devices of all sizes including:

  • Windows 11 Desktop (screen resolutions tested in 2560x1080 and 1920x1080)
  • MacBook Pro (13-inch 2015 version)
  • Moto G4
  • Galaxy S5
  • Pixel 2
  • Pixel 2 XL
  • iPhone 5/SE
  • iPhone 6/7/8
  • iPhone 6/7/8 Plus
  • iPhone X
  • iPad
  • iPad Pro
  • Surface Duo

W3C Validatior

The official W3C Markup Validator was used to validate both the HTML and CSS of the project to ensure there were no syntax errors within the site.

W3C HTML Markup Validator

The below screenshots show the error messages that were found during the HTML page validation process. All errors have been fixed and none remain on any of the HTML pages.

HTML Error 1

Link to commit for fix

HTML Error 2

Link to commit for fix

HTML Error 3

Link to commit for fix

HTML Error 4

All passed pages:

W3C CSS Markup Validatior - https://jigsaw.w3.org/css-validator/validator

CSS Validation

JS Lint

The JavaScript code was checked using jshint.com and returned no errors.

PEP8 Linter Results

All python files that I created were run through the PEP8 linter to validate such as models.py, views.py, forms.py etc and any errors picked up were fixed. There are no errors left in these files.

Models.py File Example

  • Errors in Models.py files

Models.py errors

  • All Models.py file errors fixed

Models.py error free

Colour Contrast Checks

Colour contrast checks have been made on the site using the Colour Contrast Accessibility Validator by a11y. All pages passed the colour contrast analysis except for the CTA button element on each page. The pink button with the white text didn't allow for a great enough contrast. Therefore, I decided to change the button colour to a less bright pink (#ED91B3) and the text colour to black. This increased the contrast and ensured maximum accessibility making the contrast ratio within an acceptable range.

The results are shown below:

Colour Contrast Check

Colour Contrast Check Button Pass

Lighthouse Tool

Lighthouse was used to test the Performance, Best Practices, Accessibility and SEO for desktop and mobile. The results are all within acceptable ranges.

Desktop Results

Lighthouse Desktop

Mobile Results

Lighthouse Mobile

Solved Bugs

  1. Users were able to submit forms with no body content. The validation needed to be added to the post model within the body field to let it know it was required. To do this I changed the fields blank and null to False which solved the problem. Link to commit

  2. Summernote WYSIWYG editor wasn't responsive. To solve this I added additional config vars to change the width to 100%. Link to commit

  3. New users who signed-up weren't having a profile created for them automatically so when clicking on the profile page on the navigation a RelatedObjectDoesNotExist error appeared. This was fixed by moving the code in the signals.py file directly into the model for the profile. Link to commit

  4. Integrity error with duplicated keys. This was solved by making changes to the post model, urls and home.html template so that slugs would be read properly. Link to commit

Known Bugs

There are no known bugs left in this project. If you find any please get in touch with me.

Technologies Used

Languages Used

Frameworks, Libraries and Programs

  • Heroku - this was the platform used to deploy the application
  • Django - Python framework used to create backend logic
  • Bootstrap 5 - CSS framework used to develop responsiveness and mobile-first approach
  • Django-allauth - authentication library used to create user accounts
  • Gitpod - this was my code editor for this project
  • Git - was used for version control using the terminal through Gitpod to commit to Git and push to Github
  • Github - is used to store the code for this project after being pushed from Git
  • Techsini - was used to generate multi-device website mockups
  • Fireshot - this was a Google Chrome extension used to take screenshots
  • PEP8 Online - was used to validate python code to ensure no errors were present
  • Google Fonts - used to import fonts to website
  • Font Awesome - library of icons used for social media and services we offer
  • Balsamiq - was used to create the wireframes during the design process.
  • GoogleDev Tools - was used to help investigate issues with code and visually see what code was related to which area on the page
  • ColorSpace - used to generate colour pallets for use on website
  • a11y - used to check website colour contrast and accessibility
  • smartdraw - used to create the database schema
  • Raw Pixel - used to find royalty-free images
  • Favicon.io - generated the websites favicon

Databases

  • SQLite: local database used to test during development
  • PostgreSQL: database used in Heroku to store data on deployment

Deployment

Deploying to Heroku

This application has been deployed using Heroku by following these steps:

  1. Commit all changes and push them to GitHub
  2. Log in to Heroku or create a new account
  3. From the Heroku dashboard click the "Create New App" button
  4. Enter the name of your app and the region you're located in. Then click "Create App". It is worth noting that your app name must be unique for Heroku to accept it
  5. In your app go to the Resources tab and add a Heroku Postgres database. This can be done by searching for Postgres in the Add-ons search box, select Heroku Postgres and choose the HobbyDev - Free option and submit
  6. Click on the "Settings" tab and scroll down to reveal config vars
  7. This will provide the Postgres Database URL, click on the url box and copy it
  8. Navigate over to your code, create a new file in the same directory as your manage.py file and name it env.py (this will be used to store secret environment variable whilst in development)
  9. Within this file import os library, and set the environment variable for the DATABASE_URL pasting in the address copied from Heroku. The line should appear as os.environ["DATABASE_URL"]= "YOUR Postgres Database URL from Heroku"
  10. Below DATABASE_URL add the secret key using os.environ["SECRET_KEY"] = "your secret key goes here"
  11. Add the secret key just created to the Heroku Config Vars as SECRET_KEY for the KEY value and the secret key value you created as the VALUE
  12. Navigate back to your code and go to your settings.py file and import Path from pathlib, import os and import dj_database_url (near the top of your settings page)
  13. Insert the line - if os.path.isfile("env.py"): import env
  14. Move down to the secret key section in the settings.py file, remove the insecure key and replace it with SECRET_KEY = os.environ.get('SECRET_KEY')
  15. Scroll down further and wire up Postgres database by replacing the databases section with DATABASES = { 'default': dj_database_url.parse(os.environ.get("DATABASE_URL"))} ensure the correct indentation for python is used.
  16. In the terminal migrate the models over to the new database connection
  17. In a browser, search for Cloudinary and either login or create an account and login
  18. Navigate to the Cloudinary dashboard and copy the CLOUDINARY_URL by clicking the copy to clipboard link
  19. Go back to your code and in the env.py file add a line at the bottom - os.environ["CLOUDINARY_URL"] = "paste in the Url copied to the clipboard here"
  20. In Heroku, go to settings and add the CLOUDINARY_URL and value copied to the clipboard to the config vars
  21. Also add in DISABLE_COLLECTSTATIC with the Value - 1 and PORT with the value of 8000 to the config vars
  22. The DISABLE_COLLECTSTATIC key-value pair must be removed prior to final deployment
  23. Back in your settings.py file, add the cloudinary libraries to the list of installed apps, the order they are inserted is important, 'cloudinary_storage' goes above 'django.contrib.staitcfiles' and 'cloudinary' goes below it
  24. Scroll down near the end of the file and below STATIC_URL add the STATIC files settings - the url, storage path, directory path, root path, media url and default file storage path
  25. Link the file to the templates directory in Heroku TEMPLATES_DIR = os.path.join(BASE_DIR, 'templates')
  26. Change the templates directory to TEMPLATES_DIR - 'DIRS': [TEMPLATES_DIR]
  27. Add Heroku hostname into ALLOWED_HOSTS - the format will be the app name given in Heroku when creating the app followed by .herokuapp.com
  28. In your IDE, create three new top-level folders, media, static, templates
  29. Create a new file on the top level directory called 'Procfile' and add the following code to it web: guincorn PROJECT_NAME.wsgi
  30. In the terminal, save files, add the changed files, commit and push to GitHub
  31. In Heroku go to the "Deploy" tab and scroll down to the "Deployment Method" section
  32. Select "GitHub" as the method and click "Connect to GitHub"
  33. Scroll down to the "Connet to GitHub" section and search for the repository name you wish to deploy. Do this by typing in the depository name and click the "Search button
  34. Once the repository has been found, connect it by clicking the "Connect" button next to its name
  35. Choose "Automatic deploys" or "Manual deploys" to deploy your application - watch the build logs for any errors.
  36. Heroku will now build the app for you. Once it has completed the build process you will see a 'Your App Was Successfully Deployed' message and a link to the app to visit the live site.

Forking Repository

You can fork the GitHub repository to make a copy of the original to view and change without affecting the original. This can be done by:

  1. Log into GitHub or create an account
  2. Locate the repository at https://github.com/Jbachtiger/ci-pp4-the-unconventional-programmer
  3. At the top of the repository, on the right-hand side of the page you will see an option to select "Fork" from the available buttons
  4. Click the fork button and a copy of the repository will have been created

Cloning Repository

You can create a clone of your repository by:

  1. Locate the repository you wish to clone https://github.com/Jbachtiger/ci-pp4-the-unconventional-programmer
  2. Click the arrow on the 'Code' button at the top of the list of files
  3. Select the clone by https and copy the URL using the provided clipboard
  4. Navigate to your chosen code editor and within the terminal change the directory to the location your to clone the repository to
  5. Type 'git clone' and paste the https link you copied from GitHub
  6. Press enter and git will clone the repository to your local machine

Credits

Code

  1. Dev - this website was used as a guide to creating a profile page - code was amended to my projects specific needs
  2. I Think Therefore I Blog - code used for likes authentication and amended to suit my project

Content

The content for the blog post was taken purely for illustrative purposes and not written by me. Below are the details of who wrote each post and where it was taken from:

  1. Code Academy - Coding Projects for Beginners
  2. Create Learn - Easy Games to Code
  3. Zero To Mastery - Programmer Success Stories
  4. Harvey Ramer - Stop Coding Under Stress: How to Avoid Bugs and the End of the World
  5. Code Academy - 10 Learner Stories Code
  6. Rescue Time - How to get work done when your not feeling it
  7. The Muse - 5 different types of imposter syndrome and 5 ways to battle each one

Media

All images used in the blog posts were taken directly from the post's sources as detailed above in the content section.

Resources

  1. Stack Overflow - post helped my understanding of how to show active links in the Django navigation bar
  2. PyPi - provided further reading on how to use django active links
  3. Django CKeditor - provided documentation of how the ckeditor works
  4. Kerstin Martin - provided useful information as to how it is possible to automatically update the footer date each year
  5. CSS Tricks - used to read up on various ways to create a sticky footer
  6. Selmi Tech - used to understand how to implement comments functionality in my post-detail page
  7. Learn Django - helped gain a deeper understanding of how Django slugs work
  8. Codemy - provided ideas as to what functionality to add to a blog website and how Django can be utilised
  9. I Think Therefore I Blog Walkthrough - used to understand and reinforce concepts
  10. Django Summernote - the documentation was helpful in figuring out how to use Summernote and make it responsive

Acknowledgements

  • My mentor for their support, advice and patience when reviewing this project with me
  • The Code Institute slack community for always being on hand to ask questions and pointing me in the right direction
  • Tutor support for their gudiance in solving bugs and pointing me in the right way to fix issues
  • My partner, for being so patient with me whilst creating this project and for testing the website

About

Full-Stack Toolkit Project Portfolio


Languages

Language:HTML 47.7%Language:Python 42.6%Language:Dockerfile 6.0%Language:CSS 3.3%Language:JavaScript 0.3%Language:Procfile 0.1%