Paleo Recipes is a place for visitors to find recipes and delicious meal ideas. Users are able to register a free account, share, manage and dish out (no pun intended!) their own paleo recipes for eating healthy.
Paleo Recipes is a recipe sharing and management Application built using Python, Flask+SQLAlchemy, Flask+PyMongo, Bootstrap 5, Jinja2 and JavaScript. It uses Cloudinary API to manage user-uploaded images. This Application is a hybrid database project using both MongoDB and PostgreSQL.
- User Authentication is handled using relational-backed database (PostgreSQL using Flask+SQLAlchemy).
- Standard CRUD data manipulation is handled using a nonrelational-backed database (MongoDB using Flask+PyMongo).
Paleo Recipes is my third milestone project for Code Institute's Level 5 Diploma in Web Application Development (Full Stack Software Development).
It was an easy choice to decide on building this App as I have tried and enjoyed the paleo-eating lifestyle and know that I have enough background information to make the job of building a hybrid database application a little less daunting! Plus paleo dishes almost always look great in photos, though that may mean a few extra trips to the kitchen to raid the fridge!
But what is the Paleo diet? According to the Mayo Clinic, "a paleo diet is a dietary plan based on foods similar to what might have been eaten during the Paleolithic era, which dates from approximately 2.5 million to 10,000 years ago. A paleo diet typically includes lean meats, fish, fruits, vegetables, nuts and seeds — foods that in the past could be obtained by hunting and gathering. A paleo diet limits foods that became common when farming emerged about 10,000 years ago. These foods include dairy products, legumes and grains."
Table of Contents - Click to Expand
- To develop an App where users can easily find Paleo recipes.
- Guest users will be able to view and find recipes, even without having their own account.
- Registered users will also be able to share and manage their own Paleo recipes.
- Use Mobile First design principle in building a responsive App
- Present the available information in a user friendly way
- Provide users the option to register and create an account.
- Provide registered users (members) access to a full CRUD functionality
- Provide registered users (superadmin) access to a full CRUD functionality
- Provide registered users (members and superadmin) access to a custom user dashboard with read functionality.
- Include defensive programming to enable users to make an informed decision when deleting recipes
- Handle any errors to help the users understand the issue
- Ages 16 and above for viewing, registering and contributing to recipes
- Visitors who are interested in Paleo diet or who already follow the Paleo lifestyle
- Visitors who are looking for healthier dishes (paleo)
- Registered users who want to an easy to way find Paleo recipes and meal plans
- Registered users who want to share their favourite recipes for others to also enjoy
First Time Visitor Goals - As a first time user who has not created an account, I want to be able to:
- Immediately understand the main purpose and use of the application, Paleo Recipes, and how to use it
- Search for specific recipes or view all recipes
- Register/ create a user account
- Learn more about what I can do on the Paleo Recipes App
- Add, edit, retrieve and delete my own paleo recipe(s)
- Add my own Paleo recipe(s), based on Categories
- Upload an image with my recipes
- Be able to add additional information about my recipe
- Have access to tools I may need in order to add, update or delete my recipes
- Search and view specific recipes (if already available on the App)
- Be forewarned of the consequences of what I am about to do on the App, such as deleting my recipes
- Have my own member user dashboard (read functionality)
- Have the ability to maintain the Paleo Recipe App, in particular the categories
- Add, edit and delete my own recipes
- Add, edit, retrieve and delete any recipe by category
- Search and view specific recipes (if already available on the App)
When planning the App features and scope, I drew up an Importance Viability analysis of these features, please see below:
# | Feature | Importance | Viability |
---|---|---|---|
1 | View, Create, Edit and Delete Recipes | 5 | 5 |
2 | View, Create, Edit and Delete Images with Recipes | 5 | 5 |
3 | View, Create, Edit and Delete Recipe Category | 5 | 5 |
4 | Create, Edit and Delete Account | 5 | 3 |
5 | Login and Logout to Account | 5 | 5 |
6 | Moderate Content Submitted by Registered Users | 5 | 1 |
7 | Send message and/ or feedback to Admin | 5 | 2 |
8 | Receive Notifications on users activities | 2 | 2 |
9 | Search for Recipes | 5 | 5 |
10 | Search Recipes by Ingredients | 3 | 1 |
11 | Search Recipes by Category | 5 | 2 |
12 | Share Recipes on Social Media | 3 | 3 |
13 | Display Suggested Recipes | 3 | 2 |
14 | Access to Custom User Dashboard (Read Functionality) | 4 | 5 |
15 | User Action Validation | 5 | 5 |
Based on the results of the Feature Ideas Planning, I have decided to attempt to implement Features numbers 1, 2, 3, 5, 9, 14 and 15 for this production release and park the remaining features due to time limitations.
- Clean and themed presentation of recipe details
- Intuitive App navigation
- Fresh-looking, appetising and themed use of images across the App
- Full CRUD functionality
- Use of Defensive Programming to Safeguard Logged In Users (Members and Superadmin) about any unintended result of their actions
- Robust error handling provide information as well as a much better user experience for any user who may encounter errors when using the Application
The green elements in these diagrams illustrate the pages that are always accessible from the Navbar for all visitors. The grey elements in these diagrams are the pages not accessible to a particular user. The view recipes function is available to all visitors. The search recipes function is available all visitors. The add, edit and delete elements are only available to logged in users. The delete functions will return to:
- A REGISTERED USER DELETING A HIS OR HER OWN RECIPE WILL RETURN TO THE RECIPES PAGE
- A SUPERADMIN DELETING A CATEGORY WILL DELETE ALL RECIPES ASSOCIATE WITH THE DELETED CATEGORY AND WILL RETURN TO THE CATEGORIES PAGE
The Paleo Recipes Application uses a combination of two databases, PostgreSQL and MongoDB.
All User Authentication and the list of Categories are handled using relational-backed database (PostgreSQL using Flask+SQLAlchemy). Except for the deletion of Categories which requires a Superadmin user permission, all the Standard CRUD data manipulation is handled using a nonrelational-backed database (MongoDB using Flask+PyMongo). The diagram below show the structure and schema used in the databases and the relationship between the tables in Postgres with the collection in MongoDB.
During the development of the Application, and prior to project submission, the Entity Relationship Diagram (ERD) below went through several iterations to adapt to the challenges encountered during development, specifically around time constraints. Aside from the recipe management and sharing functionalities, the development plan also included a blog section; and the corresponding topics and blog collections were subsequently created in MongoDB. The blog feature is now tabled for future development. Screenshot of ERD which includes collections that are not used in the current version.
The wireframes created for this project:
- DESKTOP - INDEX PAGE
- DESKTOP - RECIPES PAGE
- DESKTOP - CATEGORIES PAGE
- DESKTOP - ADD RECIPE PAGE
- DESKTOP - EDIT RECIPE PAGE
- DESKTOP - EDIT CATEGORY PAGE
- TABLET - INDEX PAGE
- TABLET - RECIPES PAGE
- TABLET - CATEGORIES PAGE
- MOBILE - INDEX PAGE
- MOBILE - RECIPES PAGE
- MOBILE - CATEGORIES PAGE
Bootstrap5 was used and customised for the front-end development.
I used Google Fonts to import the fonts I used across the application.
The colour scheme and typography used for the Paleo Recipes App was inspired by Rui Sousa's veggie portfolio project found on Behance.
Breakdown of the features and elements implemented for the App.
- Logo
- Recipes
- About
- Register
- Login
- Brief reminder of what's possible do to across the Paleo Recipes application
- Links to different pages
- Link to finding recipes
- Link to creating an account
- Search for recipes
- Manage own recipes
- Choose category
- Input required information about the new recipe
- Upload an image for the recipe using the Public API Key made available to logged in user viewing the add_recipe page
- Add a new category
- Edit/ Update a category
- Delete a category and all associated recipes
- Custom message, depending on if user or if superadmin
- Responsive sidebar for users to access links to search recipes, add recipe and log out
- Username prominently displayed on top left hand side of sidebar (for desktops)
- Sidebar dynamically moves below navbar on small and medium device
- Render all recipes shared by the registered user to be available on his/ her User Dashboard
This shows what CRUD functionality is available from each page
Page | Create | Read | Update | Delete |
---|---|---|---|---|
home | read intro about the app | |||
recipes | search for recipes | edit and update recipe (requires log in & only if owner of the recipe) | delete recipe (requires log in) & only if owner of the recipe | |
add_recipe | choose a category, create a new recipe, upload an image | |||
about | about what is Paleo diet | |||
register | user profile | |||
login | username for password check | |||
edit_recipe | all information incl with recipe and image | all information incl with the recipe & image | ||
categories, requires log in and user is superadmin | categories | all available categories | all available categories | all available categories plus all recipes associated with the deleted category |
profile | user dashboard, custom information for registered users, view all available recipes shared by the logged in user | edit own recipe functionality available to logged in users from their dashboard | delete own recipe functionality available to logged in users from their dashboard |
To keep the application secure and protected against any brute force attack, defensive programming was at the forefront of the development and implementation of every feature included.
- I implemented logged_required functionality across relevant pages
- I also implemented Jinja templating language to ensure that a user without authorization cannot access the protected pages
- The routes functionalities also checks if a user is:
- logged in
- has access to specific pages (based on permissions)
- a superadmin
The following error handlers were added to the Application to handle possible scenarios requiring specific HTTP Response:
- errorhandler(400) for a Bad Request error
- errorhandler(404) for a 404 Not Found error
- errorhandler(408) for a 408 Request Timeout error
- errorhandler(500) for a 500 Internal Server error
-
Languages:
- HTML5 was used for the content and structure of the site.
- CSS3 was used for the styling of the site.
- JavaScript was used for the interactivity of the site.
- Python was used for the back end programming of the site.
-
Cloudinary API was used to enable users to upload images for their recipes whilst keeping the App safe and secure
-
- Flask was used to handle the templating for the site.
-
- Postgres was the relational database used to store user registration, login and authentication. Postgres was also used to store the Categories.
-
- MongoDB was the nonrelational database used to store less structured data such as the recipes. MongoDB is where we host our NoSQL database.
-
- Flask-PyMongo provides MongoDB support for Flask applications.
-
- Pip is the package installer for Python, allowing us to install the packages we need for this site.
-
- Dnspython is a DNS toolkit for python.
-
- Werkzeug is a Web Server Gateway Interface web application library.
-
- Jinja is a templating engine for Python, used to write Flask and other templating services.
-
- Balsamiq was used to create the wireframes for this project.
-
- Git was used for version control and saving work in the repository, using the GitPod extension in Google Chrome to commit to GitHub.
-
- Bootstrap is one of the most popular front-end open source toolkit and was used for ease of styling the Earthlings app.
-
- This project was created in the Google Chrome browser, and as such Chrome was used as the default testing browser.
-
- Heroku is where we deploy this live site. Throughout, we have ensured the version being deployed to Heroku matches the development version by checking features and screen layouts on both versions.
-
- GitHub is where we host our site.
-
- Online-Convert was used to convert the png images to webp.
- Include a Blog Functionality
- Allow registered users to delete their own account
- Add dynamic pagination on user's dashboard for better UX when viewing their own recipes
- Add functionality that will allow the users the choice to upload a new image and not force them to re-upload an existing photo in order to edit recipe
- Dynamically populate the Public API Key to enable image upload without having to display the Public Key to the users
All testing undertaken for this project can be found in the Testing Document
To deploy this project, I used Heroku. The deployed version is the same as in the repository. These are the steps used for deployment to Heroku:
- In GitPod CLI, the the root directoy of the project, run: pip3 free --local > requirements.txt to create a requirements.txt file containing project dependencies.
- In the Gitpod project workspace root directory, create a new file called Procfile, with capital 'P'. Open the Procfile. Inside the file, check that web: python3 app.py has been added when creating the file Save the file.
- Login to Heroku, select Create new app, add the desired name for your app, make sure not to have any spaes, choose your closest region.
- Navigate to the Deploy tab on Heroku dashboard and select Github, search for your repository and click 'connect'.
- Navigate to the settings tab, click reveal config vars and input the the following:
Key | Value |
---|---|
CLOUD_NAME | mycloudinaryname |
API_KEY | myapikey |
API_SECRET | myapisecret |
IP | 0.0.0.0 |
PORT | 5000 |
MONGO_DBNAME | mongodb_name |
MONGO_URI | mongodb+srv://<USERNAME>:<PASSWORD>@<CLUSTER>-4g3i1.mongodb.net/<DATABASE>?retryWrites=true&w=majority |
SECRET_KEY | mysecretkey |
DATABASE_URL | postgresql |
- Go back to the Deploy tab and select enable automatic deploys
- Click deploy branch
- Click Open app once the build is complete
- How to Fork To fork the repository, use the following steps: Login or signup to Github and locate the repository. Click the Fork button in the top right corner
Login or signup to GitHub and locate the GitHub Repository GitHub Repository. Under the repository name, click "clone" or "download". To clone the repository using HTTPS, under "Clone with HTTPS", copy the link. Open the terminal in your preferred code editor and change the current working directory to the location you want to use for the cloned directory. Type git clone, and then paste the URL you copied in Step 3. Press Enter. Your clone will be created.
- The solution to implementing Cloudinary API to allow users to upload images was inspired by the Code Institute Slack Community and in partular, by James Bennison's MS3 Project.
Sample recipes posted on the Paleo Recipes App were sourced from:
Information about Paleo Diet was sourced from the Mayo Clinic
- Images used for the project were licensed from Adobe Stock
README and Testing Inspirations from Nick Lennon's and Naoise Gaffney's individual README documentation for MS3.
A very, very special thanks to James Gregory from Tutor Support at Code Institute. James, you have been a lifesaver! I appreciate your development and tutoring skills!
Special mention and thanks to my mentor, Dario Carrasquel, for his support, invaluable insights and his belief that I can do this well. I am so grateful to have you as my mentor.
A special mention to my MS3 cohorts, glad to have you guys around! Kera, Nazia, Tom and Jack. Thanks! Thanks also to Jo Bowden at SDC.
© 2022 Paleo Recipes App by Joy Zadan (a combined Postgres & MongoDB Full Stack Developer Project)