alecStewart1
Getting started with Phoenix with Earmark, and ElixirLS
Hello there!
So I’ve been wanting to jump in Phoenix and I thought I’d try making it more difficult for myself with introducing Earmark into the equation.
I would say setting up like a blog, however I would find the CRUD way of doing things to be somewhat silly for me because…well it’s only me creating posts with Markdown.
I do have a few questions:
-
Should I bother with Ecto?
I’m more wondering what the best way to store everything. I think I should store both the Markdown itself and the generated HTML, in separate tables with a shared key like ID or something. Though I’m not the most experience with databases.
-
Potentially extending Earmark?
The two things I’d like to do is:
-
Have frontmatter in Markdown for posts
-
Components of sorts
Mainly just for use with things like code blocks and such.
Though maybe, for now, it would just be worth..somehow using remark? Though that sounds like it be a bit more of a headache.
-
-
ElixirLS to ignore certain folders.
I like that ElixirLS exists, however I wish I could tell it to not look in every directory in my project, slowing itself down and Emacs. Is it possible to have ElixirLS ignore some folders, or is that yet to be added in it’s functionality? Potentially specifying a
.gitignore?
Thank you for any answers you give!
Most Liked
srowley
You could be a little more terse with:
defp parse_attr(:body, value),
do: value
defp parse_attr(:tags, value),
do: value |> String.split(",") |> Enum.map(&String.trim/1) |> Enum.sort()
defp parse_attr(_, value),
do: String.trim(value)
That does the same thing as your first example except that it will not throw an error if something other than :title, :author, :description, :body or :tags is passed as the first argument to that function. In that case it just returns String.trim(value). You could make it throw an error by using a guard (see the example below), and not defining a function clause that matches the first argument on anything.
The code below is what I think you intended to do with your second example, but there are two differences between this and that example:
- It returns
valueif the first argument is:body(the second example would returnString.trim(value)) - It returns “Oops!” if the first argument wasn’t one of the expected ones (the second example returns
String.trim(value)if the first argument is anything other than:tags).
The third clause in that case block will never match because :error would match on the second clause.
defp parse_attr(:body, value),
do: value
defp parse_attr(:tags, value),
do: value |> String.split(",") |> Enum.map(&String.trim/1) |> Enum.sort()
defp parse_attr(trimmed, value) when trimmed in [:title, :author, :description] do
String.trim(value)
end
# If you leave this out, calls to this function will raise an error if the first
# value is not one of the expected ones above.
defp parse_attr(_, value),
do: "Oops!"
As the other poster said, this is pretty idiomatic Elixir code. I felt like it would be confusing when I started learning Elixir, but now I find it much easier to read and reason about than one or more control flow blocks.
John-Goff
Another way to clean up this code without changing any semantics of how it works would be to use guard clauses:
defp parse_attr(attr, value) when attr in [:title, :author, :description],
do: String.trim(value)
defp parse_attr(:body, value),
do: value
defp parse_attr(:tags, value),
do: value |> String.split(",") |> Enum.map(&String.trim/1) |> Enum.sort()
This keeps the functionality intact where this function will reject if not called with one of the specific atoms defined in the function head, but it’s slightly less code to write for each case.
Edit: did not originally see the second part of @srowley’s example, they suggested this approach as well. Anyway, this is how I’d do it.
kokolegorille
Hello and welcome,
This post might give You some idea…
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








