alecStewart1

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:

  1. 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.

  2. Potentially extending Earmark?

    The two things I’d like to do is:

    1. Have frontmatter in Markdown for posts

    2. 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.

  3. 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

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:

  1. It returns value if the first argument is :body (the second example would return String.trim(value))
  2. 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

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

kokolegorille

Hello and welcome,

This post might give You some idea…

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement