-
Gather is a recipe website which allows users to submit their own recipes, as well as view those submitted by other members. There is the option to ‘favourite’ recipes so that the user can quickly and easily find their favourite recipes. The website design is responsive so it can be used on any device.
-
This is my Milestone Project 3 submission for Code Institute's Diploma in Web Application Development course. My website uses both relational and non-relational databases, features full CRUD functionality and is built using technologies that I have learnt including HTML, CSS, JavaScript, Python, Flask and PostgreSQL.
Find the project repository here.
- User experience
- Design
- Wireframes
- Features
- All Pages Features
- Index (Landing Page) Features
- Register/ Log In Pages Features
- Find Recipes Page Features
- View Recipe Page Features
- My Recipes (Dashboard) Page Features
- Submit/ Edit Recipe Page Features
- Favourite Recipes Page Features
- Manage Cuisines Page Features
- Add/ Edit Cuisines Pages Features
- Delete Recipe/ Cuisines Pages Features
- Error Handling
- Future Features
- Data Model
- Technologies used
- Testing
- Deployment
- Credits
-
As a first-time user, I want the landing page of the website to explain the purpose of the website and allow me to preview the content.
-
As a first-time user, I want to be able to register for an account.
-
As a first-time user, I want the website to work on any device.
-
As a returning user, I want to be able to log in to my account.
-
As a returning user, I want to be able to create/ view/ edit/ delete my own recipes.
-
As a returning user, I want to be able to view other user’s recipes.
-
As a returning user, I want to be able to favourite recipes and have a view where I can easily see all my favourite recipes in one place. I also want to be able to unfavourite recipes to remove them from this view.
-
As a returning user, I want recipes to include useful information such as a title, ingredient list, instructions broken down into steps, time to make, difficulty level, cuisine, serving size, tags, link to a URL and an image.
-
As a returning user, I want to be able to get a quick overview of a recipe, but also view that recipe on its own page.
-
As a returning user, I want to be able to search for recipes, to make it quicker to find recipes with a certain word in their name, tags or ingredient list.
-
As a returning user, I want to be able to access and use the website on any device.
-
As a business owner, I want users to be able to create, edit and delete their own recipes, but not those of any other user.
-
As a business owner, I want the adding, editing and deleting of cuisines to be limited to admin or those with permission.
-
As a business owner, I want it to be as easy as possible for users to submit recipes, e.g. they can copy and paste an ingredients list in.
-
As a business owner, I want the website to function and look good on any device.
- The website design is playful, colourful and youthful. The name ‘Gather’ refers to the website’s purpose as a way of ‘gathering’ recipes. It also refers to the way that mealtimes are social, and encourage people to gather together. I looked at the design of cookbooks and kitchen interiors for inspiration. Gather’s aesthetic is simple yet full of character, inviting and easy to use.
- Gather uses a simple colour scheme of white, light grey and dark grey with pops of turquoise and red. The background is light grey, with a top and bottom border in turquoise, distinguishing the top nav bar and the bottom footer sections. I have used cards with a white background for areas of dense text for improved legibility. The logo, social icons and anchor links are in the website’s distinctive ‘gather red’ colour. Buttons are either in dark grey or gather-red.
- Headings are in Fredoka One with cursive as a fallback font. As a big, round, bold font, the sparing use of Fredoka One brings a playful touch to the whole website. The body is in Roboto with sans-serif as a fallback font. This means the text will be easy to read on all device sizes.
- I have not used much imagery on the website, as users can upload their own recipe photos. There is a splash image on the landing page to set the tone of the website. The background is a similar colour to the turquoise of the colour scheme.
- I have used icons on buttons on the website to enhance the text that states the button’s action.
- I have used Materialize CSS card componants for displaying recipes and forms. This makes the content stand out from the website background. It also neatly presents the various recipes, brining a sense of harmony and consistency to the website.
-
The nav bar presents different options whether the user is logged in or logged out or an administrator.
-
The links change colour on hover, to signal to the user which link they have the mouse over.
-
The logo links back to the main landing page.
-
The nav bar turns into a slide-out menu on smaller screen sizes
-
The footer includes the website’s name and a brief description.
-
It also features icons with links out to social media. These windows open in a new tab. The icons feature ARIA labels for accessibility best practices.
-
Flash messages appear to confirm when a user has completed an action. E.g. they have logged in or out, they have added, edited or deleted a recipe, or they have added or removed a favourite recipe.
-
Flash messages are also used to inform the user when they do not have access to a page. E.g. a non-admin user is trying to access an admin-only page.
-
The styling of the flash messages is inkeeping with the rest of the site. They alert the user but are not too distracting to ensure a good user experience.
-
The purpose of the Gather website landing page is to explain the purpose of the website. It does this with an eye-catching jumbatron with a tag line and a 'three-across' explainer section with icons.
-
There are big red call-to-action buttons on the page, making the next step clear and easy to the user.
-
Once a users are logged in, the buttons on the landing page change. This means that the page is still useful for a returning user, as it directs them to different pages within the website.
- Another purpose of the landing page is to give the user a feel of the content they can access if they sign up and register. These are displayed as "featured collections" on the homepage. These include "Recently Added Recipes" and "Quick Recipes". Recently Added Recipes will change often, which will help keen the landing page looking fresh.
- The user can quick-view and view these recipes (see these features in more detail below) If the user if logged out, the Favourite button is replaced with a Call to action.
-
The Register and Log in pages both feature forms, a large red submit button, and a link to the other page incase a user is in the wrong place. E.g. on the Register Page, it says "Already Registered? Log in here."
-
The Register form features input fields for Username, First Name, Last Name and Password. All fields are required.
-
The Log in form features input fields for Username and Password. All fields are required.
-
The User's password is hashed for security.
- Each Username must be unique, so when a new user registers, their entered username is checked. If it already exists, a flash message informs the user to try another username.
- If incorrect log in details are provided, then a flash message informs the user that the Username and/or password is incorrect.
-
The purpose of this page is to show the users all recipes. This includes their own recipes and those submitted by other users.
-
From this page, users can search recipes, quick-view recipes, view recipes, and favourite recipes.
-
The user's own recipes appear in the same way as peer submitted recipes. I chose to do this to keep the format neat. User's can manage their own recipes from their 'My Recipe' page.
- The search feature uses a Mongo DB's index. This returns search results based on the recipe name, recipe tags and ingrediant list.
- If no results are found, then a message appears to inform the user.
-
The quick-view expands the information on the card, that the user can scroll through without navigating away from the page.
-
The quick-view is accessed by pressing the red button with a magnifying glass icon. There is a tooltip that appears when the button is hovered over and an Aria Label for screenreaders.
-
I included this feature to help keep the recipe cards neat and consistent. The intital information that the user can see is the recipe image (if provided), a title, the author, tags, and the cuisine.
-
If the user wants to learn something else about a recipe, e.g. how long it takes, or how many servings it makes, then they can use quick view to access this information.
-
Then, if a user wants to open a recipe to follow along or print out, they can use the View Recipe option.
-
The View Recipe page presents the Recipe in a clear and easy to read or follow format.
-
Ingrediants are shown in an unordered list.
-
Steps are shown in an ordered list.
-
There is a back button at the bottom of the page which saves the user neaeing to use their browser back button.
-
The My Recipes page is where the user can submit, view and manage their own recipes.
-
While building the project I was calling it the Dashboard and I have used this term in the code, so this is why I describe it as both My Recipes and Dashboard.
-
As with other pages, I have used icons, tooltips and Aria labels on buttons, so that it's clear to a user what the buttons do.
- This page is only shows recipes submitted by that user. If a user tries to edit or delete recipes that they are not the author of, they will see a flash message informing them and be redirected to the find recipes page.
- If the user has no recipes, then a message appears to inform the user.
-
The submit and edit recipe pages both feature forms and red submit buttons. The edit page also features a cancel button which directs the user back to to their My Recipes page.
-
Input fields include
- Recipe name (required - text - max 50 characters)
- Cuisine (selected from dropdown - required)
- Ingrediant list (required - text - comma seperated)
- Instructions (required - text - new line seperated)
- Difficulty (selected from dropdown - required)
- Duration in minutes (number - required)
- Serves (number - required)
- Image URL (text)
- Tags (required - text - max 50 character - comma seperated)
- URL (text)
-
All inputs are validated and feature labels
-
When a user goes to edit a recipe, the content appears in the relevant input fields.
-
If a recipe image URL is not provided, then a defualt colour swatch is used.
-
It was difficult to get the right balance between making it easy for users to submit recipes, and making sure the recipes were well presented on the website.
-
I decided that I wanted to store the Ingrediants List, Instructions and Tags as arrays in Mongo DB.
-
I decided the best way to do this was to make the user enter the Ingrediants List and Tags as comma seperated lists, and the Instructions and a new line seperated list.
-
This is because, while developing the site, I found it most convieant to copy and paste recipes in from other websites. That's why I decided to create single text-area inputs for the ingrediants list and instructions list, as opposed to making the user enter each item individually.
-
This solution is not ideal, as it leaves a lot of trust in the user to correctly input recipes, so that they are clear and legible to other users. I have increased speed and ease, at the cost of making the system fool-proof.
-
As the ingrediants list input is a text area, I have removed the ability to enter a new line, to encourage the user to use commas.
-
However, the user can still copy and paste text in as seperate lines into the ingrediants field instead of using commas. This feature was useful for development, however I have not made this apparent to the user so to the keep the form clear and simple. So I would consider removing this feature in a real-world application.
-
This feature allows the user to add recipes to their My Favourites page. This would be useful if their is another user's recipe that they like, and would like to "bookmark" it so they can find it easily, and save them having to look through the Find Recipes page.
-
Users can also favourite their own recipe if they choose.
-
User's can favourite recipes simply by clicking the 'Favourite Recipe' button. Once a recipe is favourited, this is replaced by an 'Unfavourite recipe' button. Clicking this will remove the recipe from the User's favourites.
- If the user has no favourite recipes, then a message appears to inform the user.
- This page lists all the available cuisines in alphabetical order. It gives the admin user the option to add, edit or delete cuisines.
- This page is only visible to admin users. If a non-admin is logged in and tries to access this page or tries to access the submit, edit or delete a cuisine pages, they will see a flash message informing them and be redirected to the find recipes page.
- The add and edit cuisine pages feature a form with a single input field for Cuisine Name and a red submit button. The edit button also features a cancel button.
-
Each cuisine name must be unique, and is checked before commiting to the database. If the user enters an exsisting cuisine name, a flash message appears informing them.
-
Like the Manage Cuisines page, a flash message appears if a non-admin user tries to access this page.
-
If a user clicks on a 'Delete Recipe' or 'Delete Cuisine', they will be taken to this page to confirm the deletion. This is extra step to stop users accidentally deleting things.
-
Cuisines are set up with a cascade delete effect. So any recipes with that cuisine will also be deleted. This is made clear on the delete cuisine page.
-
There is a cancel button on each page.
-
In most instances if there is an error, e.g. the recipe id in the page URL is changed, then the user will be redirected back to the Find Recipes page. Logged-out-users will be directed to the log in page, as they cannot access the Find Recipes page.
-
There is an unresolved bug if the page URL is changed on the edit or delete Cuisine page, then the Execption clause will not trigger. See the unresolved bug section.
-
If the user's session cookie deleted, then they will be logged out and unable to access logged-in features.
- The search functionality does not search by cuisine name as these are not stored in Mongo DB. I would also like to add a filter to the Find Recipes page that filters by cuisine name.
- The tags are used within the search function so they are searchable. However they could be used in further ways, such as being clickable and showing other recipes with the same tag.
- I feel the index page would be improved by having more featured collections such as Most Favourited or Fewest Ingrediants.
- I feel a modal would be better here. I made a page for ease.
- As explained in the Features section, I feel there is more I could do to improve the UX of inputting a recipe. For example, there could be a format button which would correctly format the user's input. Or a live preview so that the user can see how their input will look on the site.
- I could add a print recipe button, which would open the page as a printable format in the printer dialog box.
- This would help the user ensure they haven't made a typo in their desired password.
- This would allow the user to edit their username or password, or delete their account.
- I could add a contact admin button, to notify admin if there is an error out of hours.
- Users could add private comments (e.g. their own notes from having tried making the recipe) and/or public comments to let other users know helpful tips or reviews.
- As I have used the same Recipe Card format within multiple templates, I could refactor this code and use a "snippet" to reduce the number of times this code is repeated.
- I would like to add more detailed exception clauses to my Try Except statements. I have used a catch-all clause for simplicty.
- I would like to add more automated tests for my Python and Javascript files. This would mean that developers who work on the website in the future can add new features and be sure they are not breaking the code.
-
- Heroku is the deployment source I used for this project. I'm also using it for the Postgres relational database
-
- I'm using MongoDB for my non-relational database.
-
- Templating language I've used with Python to add logic to my html templates.
-
- Templating language I've used with Python to add logic to my html templates.
-
- Front-end library with HTML, CSS and Javascript based componants. I used features including Nav bar, Cards, Buttons and Forms.
-
- I used jQuery to add functionality to MaterialiseCSS componants.
-
- Two fonts are imported from google fonts.
-
- I used icons from font awesome on buttons.
-
- Git was used as a version control in the terminal.
-
- Github was used to create and store the project repository.
-
- Gitpod was used to create my files and where I wrote the code.
-
- Balsamiq was used to create Wireframes for the project during the initial planning stage.
-
- Techsini was used to help check responsiveness and take screenshots of the page at different screen sizes.
-
- Photoshop was used to resize images for the website.
-
- TinyPNG was used to compress images for a faster loading time.
-
- WebFormatter was used to help beautify the code.
-
- Google Chrome's Dev Tools were used while building the project to test responsiveness and for debugging.
-
- Tool used to mock up database structure diagram.
-
- Unsplash was used to source the jumbatron imager.
- Please refer here for more information on testing of the Gather website
The project was created in Gitpod using the Code Institute Gitpod Full Template using these steps:
- Log in to GitHub and go to the Code Institute student template for Gitpod
- Click 'Use this Template' next to the Green Gitpod button.
- Add a repository name and click 'Create reposiory from template'.
- This will create a copy of the template in your own repository. Now you can click the green 'Gitpod' button to open a workspace in Gitpod.
Forks are used to propose changes to someone else's project or to use someone else's project as a starting point for your own idea. By forking the GitHub Repository you make a copy of the original repository on our GitHub account to view and/or make changes without affecting the original repository.
To Fork a Github Repository:
- Log in to GitHub and go to the GitHub Repository
- Locate the Fork button in the top-right corner of the page, click Fork.
- You should now have a copy of the original repository in your GitHub account.
You will now have a fork of the repository, but you don't have the files in that repository locally on your computer.
To make a local clone:
- Log in to GitHub and go to the GitHub Repository
- Above the list of files, click Code.
- To clone the repository using HTTPS, under "Clone with HTTPS", click the 'Copy' icon. To clone the repository using an SSH key, including a certificate issued by your organization's SSH certificate authority, click Use SSH, then click the 'Copy' icon. To clone a repository using GitHub CLI, click Use GitHub CLI, then click the 'Copy' icon.
- Open Git Bash.
- Change the current working directory to the location where you want the cloned directory.
- Type git clone, and then paste the URL you copied earlier. It will look like this, with your GitHub AE username instead of YOUR-USERNAME:
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
- Press Enter. Your local clone will be created.
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
> Cloning into `gather-recipe-website`...
> remote: Counting objects: 10, done.
> remote: Compressing objects: 100% (8/8), done.
> remove: Total 10 (delta 1), reused 10 (delta 1)
> Unpacking objects: 100% (10/10), done.
Click Here for the GitHub quick start guide with images and more detailed explanations of the above process.
You will need to deploy the application using Heroku.
- Create a requirements.txt file by typing
pip3 freeze --local > requirements.txt
into the Gitpod CLI. Ensure this is added to your .gitignore file. - Create a Procfile by typing
echo web: python app.py > Procfile
. Open it and ensure it doesn't have a new line, as this can create errors. Ensure it starts with a capital P. - Add and commit these files to Github.
- Go to Heroku. Log in or create an account
- Click the 'New' button and click 'Create new app'.
- Enter a unique name for your project with no capital letters or spaces and select your region. Click 'Create App'.
- Inside your project, go to the Resources tab and create a Heroku Postgres Database
- Inside your project, go to the 'Settings' tab. Scroll down and click 'Reveal Config Vars'.
- Add in the following variables
- IP : 0.0.0.0
- PORT : 5000
- MONGO_DBNAME : Your MongoDB database name
- MONGO_URI : This can be found on MongoDB by going to Clusters, Connect, Connect to your application
- SECRET_KEY : Your secret key
- Deploy your project by going to the Deploy tab and choose 'Connect to Github'
- Find your repository name and select Connect.
- To connect your Heroku database, go to 'More' in the top right and select run console. Enter
python3
to access the python intepreter. - Then type
From gather import db
. Then typedb.create_all()
. You can then exit the console.
-
Materalize CSS: I used this library throughout the project. Particularly for the nav bar, cards, forms and buttons.
-
Code Institute: I referred to lessons and source code from Code Institute's Web Application Development course. I sourced the User Authentification and Search bar functionality from the Task Manager Walk Through Project.
-
Stack Overflow: I referred to Stack Overflow articles throughout the project. I used a line of code from this Bug fix to stop testing export showing as error in browser article, creating a UL from a JS array and how to disable the enter key being used in a textarea.
-
W3Schools: I referred to guides on Python MongoDB amongst others.
-
Geekflare: I referred to this walkthrough on Python Unit Testing.
-
Documentation. I referred to this documentation provided by Python, Jest, MongoDB amongst others.
- BBC Good Food: I used this exisiting recipe platform to help me plan the user experience and features of the website. I also sourced many recipes from this website.
- Credit for the Jumbatron image goes to Ella Olsson sourced from Unsplash.
-
Thank you to my Mentor Akshat Garg for helpful feedback, industry insights and recommended tools.
-
Thank you to Christopher Undritz for participating in the peer code review on the Code Institute Slack channel. Thank you to my family for manually testing the website and for feedback.
-
Thank you to the Code Institute London Community for their encouragement and technical support.
-
Thank you to the tutors and staff at Code Institute for their support.
-
Thank you to Ben Smith at City of Bristol College for his support.
Please note this is a personal project. This website is purely for the sake of the developer's portfolio and not for public consumption.
Isabella Mitchell, 2022.