Skip to content

Community project - allowing users to create accounts , submit recipes, vote and comment on recipes. Using Python.

Notifications You must be signed in to change notification settings

RussOakham/wanderlust-recipes

Repository files navigation

Wanderlust Recipes - by Russell Oakham

Project overview

'Wanderlust Recipes' is a community-focused website, where user accounts can create, share and review recipe ideas.

The site is created to engage users of all ages and backgrounds, so is branded in a light, clean and neutral style. Additionally, the term 'Wanderlust' is defined as a 'lust for wandering', so styling elements have been chosen to promote curiosity and exploration.

I have used HTML, CSS, JavaScript and Python to build the site, ensuring it is fully responsive to user interaction on their chosen device.

Deployed site

The live website can be found at the following link; Wanderlust Recipes.

Wanderlust Recipes

Table of Contents

1. UX

Overview of UX design decisions, including examples of websites I have viewed as part of research and inspiration.

User Stories

Browsing
  • (US001) - As a user I want the website to clearly display recipe suggestions to me so I can be introduced to new content.
  • (US002) - As a user I want to see recipe reviews and comments from other users, so I am informed of the best recipes.
Searching
  • (US003) - As a user, I want to be able to view recipes by category, so I can find recipes of specific type I would like to make.
  • (US004) - As a user, I want to be able to search recipes by keyword, so I can find recipes easily, for example by name or by included ingredient.
  • (US005) - As a user, I want to be able to search and filter recipes by rating, so I can find only the highest-rated recipes to choose from.
  • (US006) - As a user, I want to be able to search and filter recipes by serving size, so I can find recipes suited to the number of people I am catering to.
  • (US007) - As a user, I want to be about to save my favourite recipes, so I can quickly find them again in future.
Uploading Recipes
  • (US008) - As a user, I want to be able to upload my own recipes, so other users can benefit from them.
  • (US009) - As a user, I want to gain feedback on the recipes I upload, so I can determine improvements.
  • (US010) - As a user, I want to be able to edit and improve recipes I have already uploaded.
  • (US011) - As a user, I want to be delete recipes I have already uploaded.
Users
  • (US012) - As a user, I want to be able to register with the site, so I can upload and edit recipes, plus save my favourite recipes.
  • (US013) - As a registered user, I want to be able to login to my account, so I can access and edit my recipes, and find my favourite recipes.
  • (US014) - As a registered user, I want to be able to submit ratings and reviews for recipes submitted by other users.
Administration
  • (US015) - As an admin I want to be able to edit and delete content, to ensure it adheres to site rules.
  • (US016) - As an admin I want to be able to add and edit food categories, to continuously improve user experience.
  • (US017) - As an admin I want to be able to delete food categories, to continuously improve user experience.
General
  • (US018) - As a user I want to recieve clear feedback for my actions on the site, so I know they are complete or if further steps are needed.
 

Structure

Overview of site and page structure, explaining functionality and purpose.

Home Page:
  • Header/Footer: For easy navigation across the site and to external resources such as social media pages.
  • Website Logo: To easily identify the 'Wanderlust Recipes' site branding.
  • Recipe Cards: To easily provide users key information on featured recipes, including visual image, short description, user rating, serving size and prep/cook times.
  • Search Bar: Text input bar, allowing users to search recipes by keyword, category, time requirement and minimum rating.
  • Search Results: Once user search input, latest recipes replaced by recipe cards matching the search query.
  • Pagination: Page is paginated after 10 recipes are displayed, to ensure quick page load and easy user navigation.
Recipe Page:
  • Recipe Image: Provides users a visual of the final recipe, to entice users to create it themselves.
  • Recipe Title: Provides users with the name of the dish, indicating the style and main ingredients of the dish.
  • Star Rating: Provides users visual feedback regarding how highly other users have rated the recipe.
  • Preparation & Cooking Time: Provides users information regarding time requirement to prepare the recipe.
  • Serving Size: Provides users information on the serving size the recipe creates, allowing users to adjust ingredient amounts to their own judgement.
  • Ingredient List: Provides users with a list of all ingredients and measures needed to complete the recipe.
  • Method: Provides users step-by-step method for creating the dish.
User Login / Registration Page:
  • Username Input: Text input box, allowing users to enter their username.
  • Password Input: Text input box, allowing users to enter their password.
  • Password Confirmation (Registration) : Text input box, must match password input, to ensure user does not incorrectly type password while registering.
  • Submit / Cancel: Buttons allowing users to submit entered information, or cancel and restart.
User Profile Page:
  • Username Banner: Banner displaying the username of logged in account, allowing users to quickly identify if they are logged into their correct desired account.
  • Recipes Submitted: All historical recipes uploaded by the user displayed in list format, allowing users to easily access their owned recipes for review or edit.
  • Favourite Recipes: All favourited recipes are displayed in list format, allowing users quick access.
New Recipe Page:
  • Input areas for below recipe data points:
    • Recipe Name - Text
    • Recipe Image - File upload and preview
    • Serving Size - As numeric input
    • Preparation Time - As numeric input
    • Cooking Time - As numeric input
    • Recipe Category Selection - Drop down menu
    • Recipe Description: Textbox of 25 to 160 characters
    • Ingredients - List text input
    • Recipe Steps - List text input
Edit Recipe Page:

Inputs are pre-populated with historic recipe information.

  • Input areas for below recipe data points:
    • Recipe Name - Text
    • Recipe Image - File upload and preview
    • Serving Size - As numeric input
    • Preparation Time - As numeric input
    • Cooking Time - As numeric input
    • Recipe Category Selection - Drop down menu
    • Recipe Description: Textbox of 25 to 160 characters
    • Ingredients - List text input
    • Recipe Steps - List text input
  • Delete Recipe - Button with Modal confirmation
Manage Categories Page:

Page visible only to users with role of 'admin'.

  • Add Category - Button, leading to 'Add Category' page.
  • Category Tiles - Visual tiles representing each Recipe Category added to the site.
  • Edit Category - Button, leading to 'Edit Category' page.
Add Category Page:

Page visible only to users with role of 'admin'.

  • Input areas for below category data points:
    • Category Name - Text
    • Category Image - File upload and preview.
    • Add Category - Submit Button
Edit Category Page:

Page visible only to users with role of 'admin', input's pre-populated with historic category information.

  • Input areas for below category data points:
    • Category Name - Text
    • Category Image - File upload and preview.
    • Add Category - Submit Button
  • Delete Category - Button with Modal confirmation
  ### **Skeleton**

At this point I began creating wireframes, using the above structure considerations. I used Balsamiq these below;

Surface

This is the sensory design section of a website, or how it looks, feels and sounds.

Colour & Styling

Upon deciding to brand the website as 'Wanderlust Recipes' I found this logo on Shutterstock. The logo comprises white and blue colours, which give a light and clean aesthetic. With this in mind I consulted this article on how colours evoke emotions, wishing to promote feelings of calm, optimism, energy, nature and creativity, I chose to use a colour palette consisting of whites, blues and greens.

I used the website image color picker, to determine the blue used in the logo is Gunmetal (#1E2B3A). I then used the website Coolers to generate the rest of my colour palette, using Gunmetal (#1E2B3A) as the starting colour and finding additional colours in fitting the style I wished to achieve.

The resulting palette is below;

Wanderlust Color Scheme

Colour Palette
  • Gunmetal - #1E2B3A
  • Indigo Dye - #213F61
  • Metallic Seaweed - #077787
  • Y in Mn Blue - #38506C
  • Light Sea Green - #2BBBAD

I also used a selection of off-white and off-black colours to provide additional accenting to general white/black website elements, such as backgrounds and fonts.

Language/Tone

I wanted the language to reflect a casual and fun atmosphere, reflecting a backpackers lifestyle. Therefore content was written in this style, avoiding technical or formal language where possible.

Similarly, I wanted to use fonts that reinforce the casual identity of the site and also be easy to read. To achieve this I used two Google Fonts;

  • Roboto - A font that promotes natural reading rhythm.
  • Open Sans - A humanist sans serif, designed for excellent legibility with a neutral, yet friendly appearance.
  • Sans-serif - Web safe font, used if primary two fonts fail to load.

Styling Considerations

Before beginning development, I listed some styling ideas that I felt benefit the website. The majority of these can be seen in the wireframes.

  • Favicon: Desktop and Mobile.
  • Navigation
    • Sticky top
    • Mobile: 'Burger' menu icon, expanding on click.
    • Logo: Navigates to the home page on click.
  • Recipe Cards:
    • Visual Image showing final recipe dish, to entice users to select.
  • Recipe Pages:
    • Icons: Icons used to highlight key recipe info, serving size, preparation time, rating.
    • Ingredients & Method - Displayed in tabular format, which user can dynamically choose between via click or swipe.

2. Features

The site allows users to upload new recipes and edit existing ones. Users can search for recipes based on name, description, recipe type, number of servings and minimum rating. Users can favourite recipes, which are displayed on their profile page. Users can also rate others users submitted recipes and comment their feedback.

Existing Features

The Header:
  • Website Logo: Builds brand awareness amongst users.
  • Navigation Bar: Allows users to navigate the site easily and intuitively, as well as login/register their account.
The Footer:
  • Website Developer: Copyright information for website developer brand awareness.
  • Developer Social Links: Links to GitHub and LinkedIn of website developer for brand awareness.
  • Business Social Links: Links to company social media sites, to raise brand awareness.

Both the Header and Footer are present and consistent on all website pages.

Home page:
  • Image Banner: Visually pleasing design, allowing users to immediately identify the site brand.
  • Latest Recipes: List of latest recipes submitted to the site, showing key information; recipe image, type, rating, preparation time and serving size.
  • Search Bar: Allows user to enter keywords to search recipe database
  • Advanced Search: Allows user to enter additional search criteria; recipe type, minimum rating, serving size.
  • Search Results: Replace latest recipes when search is submitted. Recipe cards displayed as search return results.
Login / Registration page:
  • Username Input: Input area for users to enter their profile username.
  • Password: Input area for users to enter their profile password.
  • Confirm Password (Registration page): Input area for users to confirm password, must match password input for successful registration.
  • Cancel: Cancellation button, clearing input text allowing users to refill entries.
  • Login/Registration Button: Button allowing users to login to their account or register for a new account.
User Profile page:
  • Image Banner: Visually pleasing design, allowing users to immediately identify the site brand.
  • Username sub-banner: Text banner showing username of logged in account, allowing users to quickly identify if they are using their correct desired account.
  • Favourite Recipes: Recipes favourited by the user are displayed in list order, allowing quick and easy access.
  • Submitted Recipes: Recipes previously submitted by the user are displayed in list order, allowing users quick and easy access to review or edit.
New Recipe page:
  • Input areas for below recipe data points:
    • Recipe Name - Text
    • Recipe Image - File upload and preview
    • Serving Size - Numeric
    • Preparation Time - hh:mm as drop down menus
    • Cooking Time - hh:mm as drop down menus
    • Recipe Category Selection - drop down menu
    • Recipe Description: Textbox of 25 to 160 characters
    • Ingredients - List text input
    • Recipe Steps - List text input
Edit Recipe page:
  • Input areas for below recipe data points:
    • Recipe Name - Text
    • Recipe Image - File upload and preview
    • Serving Size - Numeric
    • Preparation Time - hh:mm as drop down menus
    • Cooking Time - hh:mm as drop down menus
    • Recipe Category Selection - drop down menu
    • Recipe Description: Textbox of 25 to 160 characters
    • Ingredients - List text input
    • Recipe Steps - List text input
    • Delete Recipe - Button with Modal confirmation
Manage Categories Page:
  • Category Tiles: List of latest recipe categories added to the site, showing category name, image and Edit button.
Add Category page:
  • Input areas for below recipe data points:
    • Category Name - Text
    • Category Image - File upload and preview
Edit Recipe page:
  • Input areas for below recipe data points:
    • Category Name - Text
    • Category Image - File upload and preview
    • Delete Category - Button with Modal confirmation
 

Features to consider implementing in future

As this is a community-focused platform, several future features would be worth considering implementation:

  • Social Media Sharing - Allow users to share recipes directly to their social media accounts.
  • Nutritional Information API Integration - Integrate the platform to a third-party API that automatically calculates the nutritional information of recipes based on their ingredients and serving size. This would be highly beneficial to health-conscious users.
  • Vegetarian/Vegan Alternative Recipes - Allow users to enter Vegetarian or Vegan alternative ingredient lists and methods for existing recipes. Update recipe pages to allow users to choose an alternative option of the recipe and dynamically update the page contents in line with choice.
  • User Comment Section - Allow users to comment on each other's recipes, allowing constructive feedback and additional context to reviews.
  • Optimised Image Delivery - Page load speeds could be sped up via using compression on user-uploaded images, to ensure they are served in a fully optimised state. This could be achieved by further configuring the Cloudinary account to automatically compress images during upload.
  • User Administration - Add user administration page, allowing admins to actions to manage users accounts e.g. suspend accounts, set other users to admin etc.
  • Edit Comments - Add ability for users to edit comments once submitted.
  • Delete Comments - Add modal popup for users to confirm deletion of their comment.

 

3. Database Design

MongoDB was the database solution used for the website development, using the below, structured plan.

Wanderlust Recipes Database Structure

Indexes

Recipes

1. Text index on recipe title, description and ingredients, allowing for text searches.
mongo.db.recipes.create_index([

  ("recipe_title", "text"),
  ("recipe_description", "text"),
  ("ingredients", "text")

  ])

Queries

Browsing

1. Find the latest recipes:
list(
  mongo.db.recipes.find().sort("created_on", -1)
  )

Users

1. Find a specific user account based on username:
mongo.db.users.find_one(
        {"username": username}
    )
2. Insert a new user record into the database, with a defined username, password and user role:
register = {
            "username": request.form.get("username").lower(),
            "password": generate_password_hash(request.form.get("password")),
            "role": "user"
        }
        mongo.db.users.insert_one(register)
3. Find all recipes uploaded by the session user:
recipes = list(mongo.db.recipes.find(
                {"created_by": username}).sort("created_on", -1))
4. Find all recipes favourited by the session user:
favorites = list(mongo.db.rating.aggregate([
                {"$match": {"user_id": user['_id'], 'favorite': True}},
                {
                    "$lookup": {
                        "from": "recipes",
                        "localField": "recipe_id",
                        "foreignField": "_id",
                        "as": "favorites"
                    }
                },
                {"$unwind": "$favorites"},
                {"$replaceRoot": {"newRoot": "$favorites"}}
            ]))

Searching

1. Find a single recipe from its recipe title:
recipe = mongo.db.recipes.find_one({"url": recipe_title})
2. Find recipes conforming to a user inputted search criteria:
def search():
    query = {}
    form_query = []

    if request.method == "POST":
        # Construct the search query with {key: value}
        if "search-text" in request.form and request.form["search-text"]:
            query["$text"] = {
                "$search": request.form["search-text"],
                "$caseSensitive": False,
            }
            form_query.append({
                "key": "search-text",
                "value": request.form["search-text"]
            })

        if "category_name" in request.form and request.form["category_name"]:
            query["category_name"] = request.form["category_name"]
            form_query.append({
                "key": "category_name",
                "value": request.form["category_name"]
            })

        if "servings" in request.form and request.form["servings"]:
            query["servings"] = request.form["servings"]
            form_query.append({
                "key": "servings",
                "value": request.form["servings"]
            })

        if "rating-search" in request.form and int(
                request.form["rating-search"]) > 0:
            minRating = int(request.form["rating-search"])
            query["rating"] = {"$gte": minRating}
            form_query.append({
                "key": "rating[0]",
                "value": request.form["rating-search"]
            })

    recipes = list(mongo.db.recipes.find(query).sort("created_on", -1))

Uploading

1. Add a new recipe:
def add_recipe():
    if request.method == "POST":
        new_recipe = {
            "category_name": request.form.get("category_name"),
            "recipe_title": request.form.get("recipe_title"),
            "image_upload_url": request.form.get("image_upload_url"),
            "servings": request.form.get("servings"),
            "prep_hours": request.form.get("prep_hours"),
            "prep_minutes": request.form.get("prep_minutes"),
            "cook_hours": request.form.get("cook_hours"),
            "cook_minutes": request.form.get("cook_minutes"),
            "recipe_description": request.form.get("recipe_description"),
            "ingredients": request.form.getlist("ingredients"),
            "method_step": request.form.getlist("method_step"),
            "created_by": session["user"],
            "created_on": request.form.get("created_on"),
            "url": request.form.get("recipe_title").replace(' ', '-').lower(),
            "rating": [3, 0, 0, 0, 0, 0]
        }
        mongo.db.recipes.insert_one(new_recipe)
2. Edit an existing recipe:
def edit_recipe(recipe_id):
    if request.method == "POST":
        historic_rating = mongo.db.recipes.find_one(
            {"_id": ObjectId(recipe_id)})["rating"]
        update_recipe = {
            "category_name": request.form.get("category_name"),
            "recipe_title": request.form.get("recipe_title"),
            "image_upload_url": request.form.get("image_upload_url"),
            "servings": request.form.get("servings"),
            "prep_hours": request.form.get("prep_hours"),
            "prep_minutes": request.form.get("prep_minutes"),
            "cook_hours": request.form.get("cook_hours"),
            "cook_minutes": request.form.get("cook_minutes"),
            "recipe_description": request.form.get("recipe_description"),
            "ingredients": request.form.getlist("ingredients"),
            "method_step": request.form.getlist("method_step"),
            "created_by": session["user"],
            "created_on": request.form.get("created_on"),
            "url": request.form.get("recipe_title").replace(' ', '-').lower(),
            "rating": historic_rating
        }
        mongo.db.recipes.update({"_id": ObjectId(recipe_id)}, update_recipe)
3. Favourite a recipe: Form submitted via AJAX request to avoid reload of page, improving user experience
def ajax_recipe_favorite():
    # Ajax request from favorite checkbox toggle to update database
    favorite = ('favorite' in request.json)
    response = {
        "success": True,
        "flash": None,
        "response": favorite
    }

    # Check if user has already favorited recipe
    existing_interaction = mongo.db.rating.find_one({
        "user_id": ObjectId(session['userid']),
        "recipe_id": ObjectId(request.json['recipeId'])
    })

    # Update existing interaction
    if existing_interaction:
        mongo.db.rating.update_one(
            {"_id": existing_interaction['_id']}, {
                '$set': {"favorite": favorite}})

    else:
        # Create new interaction
        interaction = {
            "user_id": ObjectId(session['userid']),
            "recipe_id": ObjectId(request.json['recipeId']),
            "favorite": favorite,
            "rating": 0
        }
        mongo.db.rating.insert_one(interaction)

    return response
4. Submit a rating to a recipe:
if new_interaction is not None:
            result = mongo.db.rating.update_one(
                {"_id": new_interaction},
                {"$set": {"rating": new_rating}}
            )
        # If no record found creates new record with additional info
        else:
            result = mongo.db.rating.insert_one({
                "user_id": ObjectId(session['userid']),
                "recipe_id": ObjectId(request.json['recipeId']),
                "favorite": False,
                "rating": new_rating
            })
5. Update a rating for a recipe:
result = mongo.db.recipes.update_one(
        {"_id": ObjectId(request.json['recipeId'])},
        {
            "$set": {
                "rating.0": rating[0],
                "rating.{i}".format(i=new_rating): int(rating[new_rating]),
                "rating.{i}".format(i=old_rating): int(rating[old_rating])
            }
        })
6. Comment on a recipe:
if "comment" in request.json and len(request.json["comment"]) > 0:
        comment = {
            "author": session["user"].capitalize(),
            "text": request.json['comment']
        }
        mongo.db.recipes.update_one(
            {"_id": ObjectId(request.json['recipeId'])},
            {"$push": {"comments": comment}}
            )

Deletion

1. Delete a Recipe:
mongo.db.recipes.remove({"_id": ObjectId(recipe_id)})
flash("Recipe Successfully Deleted")
2. Delete a Category:
mongo.db.categories.remove({"_id": ObjectId(category_id)})
flash("Category Successfully Deleted")
3. Delete a historic comment on a recipe:
if "comment" in request.json and "recipe" in request.json:
        index = int(request.json["comment"])
        mongo.db.recipes.update(
            {"_id": ObjectId(request.json['recipe'])},
            {"$unset": {"comments.{i}".format(i=index): None}}
        )
        mongo.db.recipes.update(
            {"_id": ObjectId(request.json['recipe'])},
            {"$pull": {"comments": None}}
        )
 

4. Technologies Used

Languages
  • HTML - Programming language providing content and structure of the website.
  • CSS - Programming language providing styling of the website.
  • JavaScript - Programming language used for various interactive elements of the website, including game logic, audio options etc.
  • Python - Programming language used to drive core site functionality including user login and push/retrieving database information.
  • Jinja - Used to generate HTML from site templates
Libraries
  • Materialize CSS Framework - Library of pre-built HTML and CSS components, used for various aspects of the site, such as navigation bar.
  • Font Awesome - Library used for icons, such as social links and other images.
  • Google Fonts - Font style library.
  • jQuery - JavaScript library used for simplification of JS scripts and DOM manipulation.
  • Flask - Micro-framework to simplify Python scripting and web server tasks.
  • Werkzeug - Python library to manage user management integrity.
Editors
  • GitHub - Remote code repository.
  • GitPod - IDE (Integrated Development Environment), for writing, editing and saving code.
  • dbDiagram - Used to plan and visualise database structure
  • Balsamiq - Wireframes for visual design testing.
Tools
Database Management
  • MongoDB - Cloud based database management system, used for storing user profile and recipe information.
Deployment Platform
  • Heroku - Remote hosting platform, for hosting of python driven websites and applications.

 

5. Testing

The testing process can be seen in the TESTING.md document.

 

6. Deployment

Database Deployment

Application Hosting

Heroku

The site is hosted using Heroku, deployed directly from the master branch of GitHub. The deployed site will update automatically as new commits are pushed to the master branch.

Creating a Heroku app

  • From the Heroku dashboard:

    • Select "New"

    • Select "Create new app"

      Create New App

  • Add new app details to form:

    • Add app name (must be unique)

    • Select region

    • Click "Create App"

      Create New App Details

Setting Environmental Variables

  • From the Heroku dashboard:

    • Select your app from the list

      Heroku App

  • Select "Settings" from the top menu:

    • Under 'Config Vars', select "Reveal Config Vars"

    • Add environment variables in key-value pairs, click "Add" to add additional pairings.

      Config-Vars

Deployment

  • Create required deployment files in the repository:

    • requirements.txt

      • Lists the required python modules for Heroku to install.
      • To create:
        • In your IDE terminal, type: pip freeze > requirements.txt
    • Procfile

      • Tells Heroku the command to launch the app.
      • To create:
        • in your IDE terminal, type: python app.py > Procfile
    • .gitignore (optional)

      • Lists files and directories which should be deployed to live app, such as files with environmental passkeys.
      • To create:
        • In your IDE terminal, type: touch .gitignore
        • List the files and directories to be excluded from live deployment, within the .gitignore file.
        • Save in your repository root directory.
  • From the application top menu:

    • Select 'Deploy'
    • Choose your Deployment method:
      • Github:

        • Select the correct Github account.
        • Type in the repository name you wish to deploy.
        • Choose the correct repository from search results.
        • Select "Connect"

        Connect GitHub Repo

      • Manual Deployment:

        • Choose the correct branch you wish to deploy from the drop-down.
        • Select "Deploy Branch"
        • Heroku will return "Your App has successfully deployed". If this shows an error, troubleshooting will be needed.

        Deploy Branch

Automatic Deployment

  • From the application top menu:
    • Select 'Deploy'
    • Ensure app is connected to correct repository
    • Under 'Automatic Deployment' section:
      • Select 'Enable Automatic Deployment"

GitHub and GitPod repository management

How to clone 'Wanderlust Recipes' in GitHub, GitPod and setup on Heroku.

To run a version of the site locally, you can clone this repository using the following steps;

In a code editor of your choice;

  1. Go to GitHub.com
  2. Click on 'Responsitories'
  3. Click on 'Wanderlust Recipes'
  4. Click on the 'Code' button.
  5. Under 'HTTPS' click the clipboard icon to the right of the URL.
  6. In your IDE of choice, open a repository or create a new repository.
  7. Open Terminal ('Terminal' then 'New Terminal' from the top ribbon menu in GitPod.)
  8. Type 'git clone', paste URL link and press enter.

Additional information around these cloning steps can be found on GitHub Pages Help Page.  

Installing Requirements

  • Install all requirements modules to your local IDE with the following CL:
 pip3 install -r requirements.txt

Create Collections in MongoDB

  • Login to your MongoDB account
  • Create a Cluster

Create Cluster

  • Create a database using the following architecture;
MongoDB Database Structure

Base & Recipes

Setup Environmental Variables

  • Create a '.gitignore' file in the root directoy
  • Add 'env.py' and 'pycache/' to the file list within .gitignore
  • Create a 'env.py' file
  • In the 'env.py' file write the following code;
import os

os.environ.setdefault("IP", "0.0.0.0")
os.environ.setdefault("PORT", "5000")
os.environ.setdefault("SECRET_KEY", "[UNIQUE ID]")
os.environ.setdefault("MONGO_URI", "[UNIQUE ID]")
os.environ.setdefault("MONGO_DBNAME", "[UNIQUE ID]")

Note: For each sectionedn noted as [UNIQUE ID], you will need to provide your own unique identifier. These must also be aligned to Heroku environmental variables.

Setup Unique Identifies / Environment Variables

SECRET_KEY

This is required when using flash() and session() functions in flask. The key can be whatever you want, but it's advisable to use a randomly generated secure key from websites such as RandomKeyGen.com.

MONGO_URI

This is used to connect you application to your MongoDB cluster.

  • Click 'Overview' tab from your Cluster, followed by 'Connect'.

Connect Mongo Cluster

  • Select 'Connect your application' from following window.

Connect Application

  • Select your correct version of Python and copy the connection string.

Connection String

  • Replace the 'username' and 'password' text, with the relevant criteria you setup in 'Database Access'.

Database Access

MONGO_DBNAME

This is the name of your database in MongoDB. Which can be foung under the 'Collections' tab, under your cluster.

Running Development Server

To launch a Http server using the development mode code for the application, use the following command in your IDE:


python3 app.py http.server

The IDE will then open a port with http address for you to access.

7. Credits

Design and research

The following are websites and articles that I used for reference and inspiration:

Technical

  • Real Favicon Generator - For the generation of Favicon icons and code.
  • Materialize Docs - For guidance on Materialize use and adaptations.
  • CSS-Tricks - For implementing CSS effects such as box-shadow.
  • w3Schools - For checking proper syntax of HTML and CSS elements.
  • Autoprefixer - For generating CSS browser prefixes.
  • Stackoverflow - For researching and troubleshooting JavaScript and Python code issues.
  • Miguel Grinberg - For researching and troubleshooting Python functionality and code issues.
  • MongoDB Documentation - For researching and troubleshooting database code commands and issues.

Content

All text content on the site was written originally by myself, with the below notes;

The recipe details, images and descriptions were obtained from BBC Good Food and uploaded by Russell Oakham

Media

The photos and images used for this site were obtained.

Recipe Category Images:

404 Error Page

Acknowledgements

  • Thanks to my mentor, Precious Ijege for his suggestions, time and support.
  • Thanks to those on Slack for reviewing my project and making suggestions.
  • Thanks to my housemates, friends and family for reviewing the project and offering constructive feedback.

About

Community project - allowing users to create accounts , submit recipes, vote and comment on recipes. Using Python.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published