Blog: Search
Mix.install([
{:jason, "~> 1.4"},
{:kino, "~> 0.8.0", override: true},
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"}
])
Navigation
Blog: Search
You’re going to add the ability to search for blog posts to your Blog project.
The UI should look similar to the following, but does not have to match exactly as long as it has the required search functionality.
The blog page should have a text input and a search button that directs the user to http://localhost:4000/posts?title=input_string
where search_string is the text inside of the form.
http://localhost:4000/posts?title=input_string should only display blogs whose title includes the search_string (case-insensitive).
Posts Context
The Posts context should be able to search for blog posts by their title. The exact interface depends on how you have implemented posts. You might consider something like the following.
Posts.list_posts(title: "My Title")
Which would return a list of blog structs that include the search string in their title (case insensitive).
[
%Post{id: 1, title: "My Title", content: "My Example Content"},
%Post{id: 3, title: "my title", content: "My Example Content"}
%Post{id: 3, title: "MY TITLE", content: "My Example Content"}
]
Filter out posts that do not include the searched text in their title. posts that include the text should be found.
Consider including the following test cases.
-
Find posts that exactly match search. (
"My Title"matches"My Title") -
Find posts that partially match search. (
"My Title"matches"This Includes My Title In It") -
Find posts that match search lower case insensitive. (
"My Title"matches"my title") -
Find posts that match search capital case insensitive. (
"My Title"matches"MY TITLE") -
Do not find posts that do not match search. (
"My Title"does not match"Non-matching Title")
Posts Controller
The posts controller should already display all posts when the client visits http://localhost:4000/posts.
On the same page that lists all posts, create a form with a text input and a submit button that triggers a GET request to http://localhost:4000/posts?title=search_string where search_string is the value of the text input.
The blog controller should filter the list of blogs by the title query parameter when the client visits http://localhost:4000/posts?title=search_string.
Consider including the following test cases.
- Visit http://localhost:4000/posts and trigger form input with the title “MyTitle”. Assert the client is redirected to http://localhost:4000/posts?title=MyTitle.
- Visit http://localhost:4000/posts?title=MyTitle and find matching blogs.
Further Reading
Consider the following resource(s) to deepen your understanding of the topic.
For a deep-dive into testing, we highly recommend the excellent book Testing Elixir: Effective and Robust Testing for Elixir and its Ecosystem.
Mark As Completed
file_name = Path.basename(Regex.replace(~r/#.+/, __ENV__.file, ""), ".livemd")
save_name =
case Path.basename(__DIR__) do
"reading" -> "blog_search_reading"
"exercises" -> "blog_search_exercise"
end
progress_path = __DIR__ <> "/../progress.json"
existing_progress = File.read!(progress_path) |> Jason.decode!()
default = Map.get(existing_progress, save_name, false)
form =
Kino.Control.form(
[
completed: input = Kino.Input.checkbox("Mark As Completed", default: default)
],
report_changes: true
)
Task.async(fn ->
for %{data: %{completed: completed}} <- Kino.Control.stream(form) do
File.write!(
progress_path,
Jason.encode!(Map.put(existing_progress, save_name, completed), pretty: true)
)
end
end)
form
Commit Your Progress
Run the following in your command line from the curriculum folder to track and save your progress in a Git commit.
Ensure that you do not already have undesired or unrelated changes by running git status or by checking the source control tab in Visual Studio Code.
$ git checkout -b blog-search-exercise
$ git add .
$ git commit -m "finish blog search exercise"
$ git push origin blog-search-exercise
Create a pull request from your blog-search-exercise branch to your solutions branch.
Please do not create a pull request to the DockYard Academy repository as this will spam our PR tracker.
DockYard Academy Students Only:
Notify your teacher by including @BrooklinJazz in your PR description to get feedback.
You (or your teacher) may merge your PR into your solutions branch after review.
If you are interested in joining the next academy cohort, sign up here to receive more news when it is available.
Up Next
| Previous | Next |
|---|---|
| BookSearch: Authors | Schemas and Migrations |