blahosyl / spicy

Recipes for neurospicy people and those who care for them. Utilitarian, customizable and to the point. | CodeInstitute Portfolio Project 4
https://spicy-recipes-django-5d174ffc7c94.herokuapp.com/
1 stars 0 forks source link
adhd autism customizable neurodiversity recipes

Spicy Recipes

A recipe blog for autistic and other neurospicy folx. Utilitarian, customizable and to the point. No rambling, no unrelated stories, no word count fillers, no distracting design kitsch or vertigo-inducing moving backgrounds. Instead, the focus is on precise and searchable information to easily find recipes for specific needs.

Developer: Dr. Sylvia Blaho

Deployed site starting screen Go to the deployed app

See the development progress and further plans on GitHub Projects.

GitHub last commit GitHub contributors GitHub language count

Table of Contents

Table of contents generated with readme-toc

UX/UI

Strategy

In a world designed for neurotypical people, the needs of neurodivergent people are often disregarded. When it comes to recipe blogs, the 3 main culprits I aim to tackle in this project are

Each issue and its implemented mitigation is described below.

Superfluous information

An oft-parodied trend of many food blogs is their inflated word count by paraphrasing and unrelated personal stories, presumably in an effort to improve their SEO ranking.

While this is a mild annoyance to neurotypical people, it can be a serious accessibility issue for those who are neurodivergent and have executive functioning issues, such as problems focusing or front-end perfectionism.

Lack of specificity

Many autistic people are very particular about food (termed food selectivity in scientific literature; some examples). However, most recipe blogs do not offer easy ways to search for particular textures, tastes or temperatures.

Dopamine design

Analogous to dopamine dressing, being able to surround themselves with colors that match or complement their mood and energy levels is a useful coping strategy for neurodivergent people.

Scope

Clearly separated fields for creating and viewing recipes

To combat the problem of superfluous information, this recipe site is designed to clearly separate the different components of a recipe to provide a better overview for visitors, and a helpful template for recipe writers.

Searching and filtering

To address the problem of lack of specificity, this recipe blog has an emphasis on tagging, searching and filtering recipes, enabling visitors to find recipes matching their specific needs.

Alternative color themes

To facilitate users being able to customize the look of the site, the blog offers a selection of color themes that users can choose from.

Planning and prioritization

Along with usual blog features like access management, post management and collaboration, the following Themes, Epics and User Stories were defined at the beginning of the project (click here for the original Sheet):

Initial scope of project

However, as the development time available for the project was only 1 month, and this was my first Django project, these User Stories were vetted based on whether they were to be part of the Minimum Viable Product (MVP) or not.

Based on the considerations specific to a neurodivergent audience (described above), clarity of presentation and customizability was rated more important than collaboration.

Accordingly, the User Stories in the MVP were determined as follows (click here for the original Sheet):

Initial scope of the MVP

Naturally, this list was modified somewhat during development (see the Prioritization section for details). The final list can be seen in GitHub Issues.

Structure

Data models

The initial design of data models was as follows:

Initial ERD

Notable aspects of the models are described below.

Recipe model

Partially based on the Post model of the I Think Therefore I Blog walkthrough, but changed several aspects:

Ingredient & IngredientQuantity models

Ingredients are available across the project, while IngredientQuantities are specific to individual recipes.

The reasoning behind this setup was threefold:

  1. To allow for more fine-grained access permissions
  2. To lay the foundations for a future implementation of a shopping list making functionality, along the lines of the Dinner Party app I made.
  3. The intermediary IngredientQuantity model also has unit and quantity attributes.
Quantity data type

Decimal instead of float used for quantity.

IngredientQuantity not compulsory

Recipes can be saved without any ingredients (to allow better management of drafts).

Instances of Ingredient cannot be duplicated

Instances of Ingredient where ingr_name & preparation are the same cannot be duplicated.

This is true when adding new ingredients as well as when editing existing ones would result in a duplicated.

IngredientQuantities can be duplicated

Each instance of IngredientQuantity is unique, that is, even if there are 2 recipes that call for 2 apples each, these are treated as separate entities.

Comment model

This model is based entirely on the Comment model of the I Think Therefore I Blog walkthrough project.

RecipeAttribute and Attribute models

These models were added to the initial design in order to enable more filtering and more precise tagging of recipes. Their implementation parallels IngredientQuantity and Ingredient: RecipeAttribute acts as an intermediary between the Recipe and Attribute models.

Using this design as opposed to a ManyToManyField relation between Recipe and Attribute enables setting up a better control of the scope of permissions for staff users.

Profile model

When implementing the community app of the project, this model was added to store public information about the users, with the intention that logged-in users will be able to create and manage profiles for themselves.

Crucially, the Profile model is distinct from the built-in User model, connected by a OnetoOne field.

There are 2 advantages to this setup:

  1. Allow for user information to be accessible in the admin panel but not on the website UI
  2. Avoid accidentally overwriting crucial user information needed for signin and permissions.

Accordingly, the current Entity Relationship Diagram is as follows:

Initial ERD

Access management

The project implemented signup, signin and signout functionalities by using Allauth.

CRUD functionalities are only available to logged-in users.

Visitors who are not logged in can still access the search, filter and color theme functionalities.

CRUD

Logged-in users can Create, Read, Update and Delete their own comments. This functionality is implemented following the walkthrough project.

In addition, Staff users can access the Admin Panel and Create, Read, Update and Delete their own recipes, ingredient quantities, recipe attributes and profiles. Only their own objects are available to Staff users in the Admin Panel, while the Superuser can manage all objects.

UI information design

Navigation bar

This is present on every page, thus it contains elements that are used throughout the site.

The most prominent position has the navigation links letting the user switch between the collection app containing the recipes, and the community app containing the user profiles.

The center position of the nav bar has the blog name, logo and tagline.

On the right, we find the color theme selector toggle and the recipe search bar, but of these being important targeted features of the project.

Collection app

As the primary purpose of the project is to show recipes, the home page of the site displays the list of published recipes.

The recipe filters are prominently placed at the top, since it is anticipated that this feature will be widely used by the target audience.

Clicking on any recipe takes the visitor to the recipe detail page.

Community app

To ease navigation, this app is laid out similarly to the collection app: the main page shows a list of profiles, and clicking on them leads to the profile detail page.

Footer

The footer is also present on every page, but the information contained here is predicted to be used less frequently: the developer name and social media profile links.

Skeleton

Home page wireframes

Since this recipe blog is modeled after the I Think Therefore I Blog walkthrough project, and one of the project's aims is to keep layouts simple and intuitive, the basic layout of the home page and footer was not modified significantly (see the UX improvements section for changes that might not be obvious at first glance).

However, I decided to make several alterations and additions to the navigation bar.

First, I visually separated page navigation from access management functions (signing up/in/out): the page navigation stayed in the top left corner in the navigation, but access management links and information were moved to the so-called "user bar" immediately below.

Within the user bar, (semi-)permanent information was moved to the right side, while the left portion of the user bar was reserved for ephemeral dismissable messages having to do with signing in/out.

Wireframe for recipe list | desktop

I also moved the blog name to the middle of the navigation bar.

The right side of the navigation bar has the color theme toggle and the search field.

The mobile version of the recipe list (with the nav bar open) was mocked up as follows:

Wireframe for recipe list | mobile

Recipe detail wireframes

I have made some more significant changes to the recipe detail page, since the way the data are stored is also more detailed than in the walkthrough project.

I separated the space under the masthead into 2 columns: the smaller one on the left has concrete, bite-sized and easily parsable information like preparation time, cooking time and ingredients. The larger column on the right contained the instructions.

Wireframe for recipe detail page | desktop

Not shown on the wireframes is the Comments section – since this is very much the same as the walkthrough project, I did not make a separate mockup of this. One change I implemented was to show messages to do with comment creation/editing/deletion in the comment section rather than at the top of the page (see the section UX improvements).

A further addition to the masthead on the recipe detail page is the inclusion of attribute tags.

The mockup of the mobile version of the recipe detail page is shown below (with the nav bar closed):

Wireframe for recipe detail page | mobile

I did not make separate wireframes for the profile list and profile detail templates, as these are analogous to their corresponding recipe counterparts.

Surface

Visual design

Logo

The logo I chose for this project is the Rainbow Infinity symbol representing autism. This symbol is most widely used by autistic self-advocacy groups, and is in stark contrasts with the puzzle piece symbol that has been used to spread many harmful stereotypes about autistic people.

logo

The rainbow infinity logo represents the many different facets of autism, the wide potential of autistic people, and the fact that autism is a circular spectrum without a "mild" end and "severe" end – mirroring the recognition that labels such as "low functioning" or "high functioning" are harmful and irrelevant.

The logo is also a not-so-subtle nod to Pride month, when this project was developed, as there is a striking correlation between the neurodivergent and queer communities: autistic people are 8 times more likely to identify as queer as neurodivergent people.

Minimalism

I have consciously stayed away from any unnecessary visual clutter, such as excessive borders and shadows, elements of very different shapes, background images, and auto-moving elements of all kinds.

These elements tend to cause problems for a variety of users (e.g. those with visual impairment, executive functioning impairment, vertigo, etc.). Neurodivergent people are highly likely to experience some of these issues due to their heightened sensory processing, so steering clear of these chimes in perfectly with accessibility goals and particularly suited to the target audience.

Color schemes

As detailed in above, I wanted to offer users to customize the color theme of the site to match their particular needs.

For the MVP I designed 3 monochrome color themes: orange, blue and green. I plan to expand the available themes for future versions of this project.

UX Improvements

Meaningful navigation link names

The names of the navigation links were changed to Collection and Community, to better reflect the names of the apps.

Easier motor coordination

On the recipe list and the profile list, the whole card was made clickable instead of just the title, to accommodate those with below average motor coordination (another frequent occurrence within neurodivergent individuals).

Localized messages

I also separated messages based on their function, and had them display in separate locations:

Project Management | Agile Methodologies

Themes, Epics, Stories & Tasks

The work to be done was divided into the following Themes:

Each theme was then divided into Epics, and Epics into User Stories, as seen here (click here for the original Sheet):

Themes, Epics & User Stories

Each epic was assigned a distinctive color, which was also used for its label in GitHub Issues. Epics belonging to the same Theme were assigned colors of similar hues. This facilitated getting an overview of the work items.

Finally User Stories were broken down into tasks. These can be seen for each User Story individually in GitHub Issues and on the Project Board.

As this was my first project using Django, some User Stories have a very detailed task list, both as learning and as documentation/reference. Issues that have tasks that were already familiar only have high-level bullet points.

Some work items that have initially been classified as Epics have later been reclassified as User Stories – typically these were "meta" items to do with testing and documentation.

Estimation

Estimating the time it would take to complete each User Story is notoriously difficult, doubly so with the first project in a new framework. This is why I did not assign sizes to the individual User Stories, instead, I treated them as one unit.

This proved to be the right strategy in retrospect, as inexperince caused me to take disproportionately long on tasks that would be much faster the second time around. On the other side, some other tasks could be completed much faster than estimated. All in all, the lack of relative sizing of individual User Stories did not have an adverse effect on the project.

Project Board

The Issues were added to the Project Board in GitHub projects. This has a table view and a Kanban board view – this was the one I used most during development.

I have customized the Kanban columns to fit the project needs, and also added swimlanes representing milestones.

Project Board

Labels

I have used several categories of labels during the project:

These have provided an excellent way to both filter Issues and to maintain an easier visual overview of them.

Prioritization: MoSCoW

As the available time for development was only 3 weeks (setting the 4th week aside for testing and documentation), sorting User Stories into must have, should have, could have and won't have was done on the whole group of User Stories rather than on a sprint-by-sprint basis.

I have modified the MoSCoW method slightly in that I split the won't have label into two:

The links below show the User Stories excluding "meta" issues such as testing & documentation.

The statistics on planned vs. implemented User Stories can be seen on the Statistics tab of the User Stories Google Sheet.

Epics that had User Stories of various levels of prioritization received all applicable labels. As the User Stories in the Epic were completed, the labels of completed User Stories were removed from the Epic.

For example, EPIC: View author info has one User Story with priority should have completed, and another User Story with priority could have remaining to be done in version 2. Thus the label p: should have was removed from the Epic, and label the remaining p: could have.

Timeboxing

The available development time for the project was 4 weeks. Accordingly, work items were divided into 4 milestones:

  1. Create & display content
  2. Customization
  3. Interactivity & collaboration
  4. Testing & documentation

The first 3 milestones were assigned the User Stories discussed so far, while the last milestone was planned for "meta" tasks like testing and documentation.

Each milestone was assigned to a week-long sprint.

Initially, roughly the same percentage of must have, should have and could have Stories were assigned to all 3 sprints.

However, as tends to happen in real life, different sprints had different velocities, which is reflected in the uneven number of User Stories completed in each sprint.

Sprint planning

At the beginning of every sprint, I reviewed the Issues assigned to the current milestone and decided the order in which they are to be implemented, in a more fine-grained way than the existing prioritization labels.

I also defined tasks for the highest priority items, with tasks definitions for lower-priority items following as soon as it became plausible that I can finish them that sprint.

Whenever I have received updated information about prioritization or implementation from my mentor or the Code Institute community, I would also make appropriate changes in prioritization during sprints.

Sprint retroactives

At the end of every sprint, I reviewed the items that were not completed, and either reassigned them to the next sprint, or to version 2 of the project.

Features

This section briefly introduces the features implemented in the current version of the project. For videos demonstrating how each feature works, see the Manual feature testing section of TESTING.md.

collection app

Navigation bar

Navigation bar on mobile: closed

The navigation bar is present on all pages, and contains the most frequently used functionalities:

On small viewports parts of the navigation bar are hidden by default and revealed by tapping the hamburger icon.

Navigation bar on mobile: open

On desktop views, all nav bar items are visible by default.

Navigation bar on desktop

Color theme selector

Color theme selector

This dropdown lets users choose between pre-defined color themes. Currently, these are orange, blue and green, but more options are planned for future versions.

The selected color theme is persistent, that is, it remains in effect even if the user navigates to another page within the site, or opens it in another tab.

User bar

User bar

The user bar is situated immediately below the admin bar and is present on all pages. It contains dynamically updated information on the user's login status, and links to the Signup & Signin or the Signout pages, as appropriate.

The left side of the user bar displays ephemeral messages relating to login status (seen dynamically in the videos in Authentication manual testing).

User bar with message

The user bar is also fully responsive.

User bar responsivity

Footer

Footer

The footer shows the site developer information and social media links. These open in a new window. The footer is present on all pages and is fully responsive.

Footer responsivity

Home page | recipe list

Home page

The home page shows published recipes in a responsive grid, with pagination links displaying at the bottom when needed.

Each recipe card is clickable as a whole, to see the details of the selected recipe.

Filtering

The top of the home page has 4 filters:

These show recipes with the selected recipe attributes in the same grid structure as the home page.

Filtering responsivity

In the current version of the app, only one filter can be active at a time. I hope to extend this functionality for future versions.

Searching

The search page displays recipes where the word entered into the Search field (in the navigation bar) is found in any of the following fields:

The results are displayed in a responsive grid used on the home page.

Search page responsivity

Recipe detail page

Recipe detail page

This page shows the different pieces of information relating to the selected recipe in visually distinct, minimally styled blocks.

These include:

Visual separation and simplicity aids processing, which can accommodate users with attention or executive functioning issues.

Commenting

Signed-in users can comment on recipes using the form at the bottom of each recipe detail page. All comments need approval before becoming visible to other users.

Once a superadmin approved a comment, it becomes visible regardless of login status.

Comments can be edited by their author. Edited comments change back to unapproved.

Users can also delete their own comments regardless of approval status.

community app

community page/profile list

This is the starting page of the community app, and shows all user profiles in a responsive grid.

Similarly to the recipe list, the whole surface of a profile card is clickable to view individual profile pages.

Profile list page responsivity

Profile detail page

Each profile page shows the information users chose to share publicly (if any):

The profile detail page is also fully responsive.

Profile detail page responsivity

Access management

Signup detail page responsivity

Access management has been implemented using Allauth. All functionalities work as intended, and the Allauth templates have been adjusted to fit the styling of the site.

See the the writeups and videos in Authentication manual testing for more details.

Admin Panel

Default functionality

The Admin Panel enables the superuser to manage all objects in all models in the app.

Admin Panel: superuser

They can add any objects associated to any user, for example, add a recipe with any user in the database as the author.

recipe author choice: superuser

They can also manage all instances of related models from the Recipe Admin view.

Attributes and comments: superuser

Restricted access for Staff users

The current version of the app does not contain the functionality to manage recipes from the website's UI. Following the suggestion of my mentor, I have deprioritized this and focused my time on creating automated tests instead.

As an interim workaround, I have set up the Admin Panel to provide restricted access to Staff users (Gytha and Tiffany), so that they can manage their own items, but not others'.

Below, we can see the options of the Admin Panel for staff user Tiffany. The available models on the left hand side are considerably restricted, as is the list of recipes, as only those recipes are shown where Tiffany is the author.

Admin Panel: Staff user

Inline foreign keys are also restricted, as shown below: the Staff user can only select themselves as the author of the recipe.

recipe author choice: Staff user

Finally, we see that related models are also limited: the Comment model does not appear in the Recipe view for the Staff user, and Attributes can be added to the recipe, but cannot be modified (as opposed to the superadmin view).

Attributes and ingredients: Staff user

Future features

For future versions of the project, I would like to implement those User Stories that could not be done for this version for lack of time. They are listed under the label v2.

In addition, I would like to extend customization options for the color theme selector, with a wide range of monochromatic palettes, thematic multicolored palettes and dark mode(s).

Similarly, I would like to extend filtering capabilities to combine several filter vectors and also filter for negative attributes (e.g., "not bitter").

Code features

Regular testing

Code was manually tested and validated throughout development. At the end of the development process, a final, comprehensive round of testing and validating was completed. The results are detailed in TESTING.md.

Adequate commenting

Apart from making sure that the app functions as intended, I have also taken special care to make sure the code is well organized and appropriately commented. Since I am just becoming familiar with Django (and dealing with executive functioning issues), I have erred on the side of "more is more" for code comments and docstrings for methods that were new to me.

DRY

I have also done my best to adhere to the principle of Don't Repeat Yourself (DRY).

The Javascript files written for this project have been through several iterations of refactoring.

I have also restructured the templates of the collection app so that the home page, filter results page and search page all use the same code snippets for displaying the recipes and pagination links.

Technologies used

Languages used

Other dependencies used

Tools used

Deployment

The following instructions describe the deployment process with the tools used for this project. Of course, you can choose other tools/providers for the individual functions described below, e. g., a different Postgres database instead of Neon, or a different development environment instead of GitPod. Naturally, detailed instructions are only provided for the tools used in this project.

Prerequisites

Fork the repository

You can fork the repository by following these steps:

  1. Log in to GitHub (if you don't have a GitHub account yet, you can create one for free).
  2. Navigate to the project website https://github.com/blahosyl/spicy.
  3. Click on Fork in the upper right part of the screen.
  4. On the next page you have the possibility to change the repository name. To do this, simply write your desired name in the text field in the center part of the screen. You can also leave the name as it is.
  5. Click Fork in the bottom right part of the screen.

[!TIP] If you do rename the repository, make sure to keep the GitHub naming conventions in mind.

Deploy in the development environment

  1. Open the repository in a new workspace in GitPod. GitPod will automatically run the Python virtual environment for you. If you're using a different development environment, see this documentation.
  2. Install the required dependencies:
    pip3 -r requirements.txt.
  3. To store access credentials and other secrets, create a file called env.py in your top-level project directory. Before adding any content to it, add env.py to .gitignore and commit your changes. This will prevent the contents of env.py from being pushed to the Git repository.
  4. Add the following information to your env.py file:
    • CLOUDINARY_URL -you can find this in your Cloudinary console under API Keys
    • DATABASE_URL
    • DEFAULT_FROM_EMAIL
    • SECRET_KEY
  5. In settings.py, add your GitPod workspace URL to ALLOWED_HOSTS
  6. Run a migration to create your database tables:
    python manage.py migrate
  7. Create a superuser (make sure you save the username and password you use here):
    python manage.py createsuperuser
  8. Run the development server
    python manage.py runserver

Deploy to production

Pre-deployment steps

Make sure to complete the following pre-deployment steps in your development environment, especially if you made changes to the project:

  1. (Re-)create a list of requirements by going to the terminal and typing pip3 freeze > requirements.txt. This popuplates your requirements.txt file with the list of required files.
  2. Collect static files (these are hosted with whitenoise):
    python manage.py collectstatic
  3. In settings.py, make sure DEBUG=False
  4. Commit and push your changes to GitHub.

Steps on Heroku

  1. Log in to your Heroku account (or create a new one if you have not done so yet).
  2. Create a new Heroku app by selecting your region and app name.
  3. Under Settings > Config Vars in Heroku, add the following variables:
    • CLOUDINARY_URL -you can find this in your Cloudinary console under API Keys
    • DATABASE_URL
    • DEFAULT_FROM_EMAIL: this can be the same as EMAIL_APP_USER
    • EMAIL_APP_PASSWORD: instructions for obtaining one
    • EMAIL_APP_USER: the email used with your email server
    • SECRET_KEY
  4. Under Deploy > Deployment method in Heroku, select GitHub and connect Heroku to your GitHub account.
    • Type in your repository name, then click Search.
    • When your repository appears, click Connect next to it.
  5. Under Deploy > Manual deploy in Heroku, select Deploy branch to deploy manually.
    • Once the process is finished, the following message will appear:
      Your app was successfully deployed
    • Click View under the message, and a new tab will appear with your deployed app.
  6. (optional) Under Deploy > Automatic deploy in Heroku, select Enable Automatic Deploys if you want your app to be rebuilt each time you push to the main branch of your GitHub repository (but make sure your settings.py file always has DEBUG=False when you do).

Testing

See the document TESTING.md for details.

Credits

Code credits

Related advice

Study/lookup sources

The following resources were used to learn/double check general, atomic functionalities/syntax/errors:

Text

Profile texts for the mockup users based on Terry Pratchett's Discworld series were taken from Wikipedia. The description of Geoffrey Swivel was adjusted to use the correct pronouns.

All other text was written by me.

Lemon bar recipe based on Chili&Vanilia's post.

Red velvet cake recipe based on Pamela Moxley's post.

Media

Images

Logo/favicon by janeb13 on Pixabay, converted to ico format with Favicon.io.

All other pictures taken by me.

Readmes

Unsolicited pull request by an unknown person

A person unknown to me has forked the project repository and submitted a pull request with some code comments added. I had not communicated with this person before this nor asked for their contribution to the repository. The pull request was closed without merging.

Acknowledgements

I would like to express my deepest gratitude to my mentor, Rory Patrick Sheridan for his incredibly useful and understanding support throughout the project. Issues raised by him or discussed with him can be found here (see the individual ticket descriptions for the details of his contribution).

I am also grateful to the Code Institute tutoring team, in particular, to John and Roo for their help. The details of their contributions can be found here.

I would also like to thank Peter Litauszki for photo and video editing help.