Now that the basic functionality of cleaning and adding new lines is working successfully, it’s time to expand the options a user has to make use of those features. The first way I want to do that is to give the user the ability to add custom recipes. Additionally, I want this ability to function as a fallback, in case the program fails to properly parse the recipe from the urls (which happens a lot right now, although to be fair I haven’t touched that part of the program in a long time). Seeing as this functionality can effectively kill two birds with one stone, I decided that I was going to implement it next.
First, I created a new form in my forms.py
file, consisting of a <textarea>
tag that would enable multi-line entering of a recipe:
Then, I created a new html
template for users who want to enter in a manual recipe. This template will also double as the fallback page if the program fails to successfully parse the recipe.
As you can see, the page is extremely simple right now. But it has all the functionality I need to get a barebones version of this working.
From there, it was time to actually allow the user to access the page. I decided that I would first create the situation where a failed parse defaulted to this page, because that’s a situation I’ve been dealing with a lot, and at present it was a fairly big hole in my workflow.
First, I had to decide how the program would detect a failed parse. I mulled over several different ways to do this, and ultimately decided that the best place to do so would be after the RecipeList
had already been created. This meant that I could still use the “/list/
Note also here that I finally implemented a flash()
feature in the program. Until now I hadn’t needed to, but I knew that it was going to come up eventually. It’s set up in my “layout.html” file like so:
That aside, this enabled me to successfully display the “custom_add_recipe.html” template:
Next, I needed to fill in the code in the form.validate_on_submit()
function (the one that uses a pass
above). This was an excellent opportunity to learn a new bit of Python syntax: the filter()
function. For testing purposes, I was copying a recipe from Allrecipes.com, and the recipe would paste out double-spaced. Then, when I ran a splitlines()
function, the program would parse out the blank lines as recipe lines. To complicate things further, these lines were not just empty strings; they generally had a whitespace character in them as well.
My solution was to write a filter function that returned false if the list was empty or only whitespace, and true otherwise. From there, I repeated a snippet of code from my utils.py
folder to parse the recipe lines through my (still only partially trained) spaCy model:
Thus I was able to go from this…
… to this!
And from there, the rest of my code continues to function as normal. Now, I’ll need to add an option to create a new recipe like this from the beginning, but that’s a topic for my next post.