Implement archives and sidebar
This commit is contained in:
parent
ca62b6fe41
commit
f21e459760
20 changed files with 296 additions and 29 deletions
|
@ -1,5 +1,6 @@
|
||||||
defmodule Mebe2.Engine.DB do
|
defmodule Mebe2.Engine.DB do
|
||||||
require Logger
|
require Logger
|
||||||
|
import Ex2ms
|
||||||
alias Mebe2.Engine.{Utils, SlugUtils, Models}
|
alias Mebe2.Engine.{Utils, SlugUtils, Models}
|
||||||
|
|
||||||
alias Calendar.DateTime
|
alias Calendar.DateTime
|
||||||
|
@ -188,6 +189,20 @@ defmodule Mebe2.Engine.DB do
|
||||||
get_post_list(@post_table, [{{{year, month, :_, :_}, :"$1"}, [], [:"$_"]}], first, limit)
|
get_post_list(@post_table, [{{{year, month, :_, :_}, :"$1"}, [], [:"$_"]}], first, limit)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get all months stored in the DB as a list of {year, month} tuples.
|
||||||
|
"""
|
||||||
|
@spec get_all_months() :: [{integer, integer}]
|
||||||
|
def get_all_months() do
|
||||||
|
ms =
|
||||||
|
fun do
|
||||||
|
{{year, month, _, _}, _} -> {year, month}
|
||||||
|
end
|
||||||
|
|
||||||
|
:ets.select_reverse(@post_table, ms)
|
||||||
|
|> Enum.uniq()
|
||||||
|
end
|
||||||
|
|
||||||
@spec get_page(String.t()) :: Models.Page.t() | nil
|
@spec get_page(String.t()) :: Models.Page.t() | nil
|
||||||
def get_page(slug) do
|
def get_page(slug) do
|
||||||
case :ets.match_object(@page_table, {slug, :"$1"}) do
|
case :ets.match_object(@page_table, {slug, :"$1"}) do
|
||||||
|
@ -209,7 +224,7 @@ defmodule Mebe2.Engine.DB do
|
||||||
get_count(:all, :all)
|
get_count(:all, :all)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec get_count(atom, :all | integer | String.t()) :: integer()
|
@spec get_count(atom, :all | integer | String.t() | {integer, integer}) :: integer()
|
||||||
def get_count(type, key) do
|
def get_count(type, key) do
|
||||||
get_meta(type, key, 0)
|
get_meta(type, key, 0)
|
||||||
end
|
end
|
||||||
|
@ -224,7 +239,8 @@ defmodule Mebe2.Engine.DB do
|
||||||
:ets.insert(@meta_table, {{type, key}, value})
|
:ets.insert(@meta_table, {{type, key}, value})
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec get_meta(atom, :all | integer | String.t(), integer | String.t()) :: integer | String.t()
|
@spec get_meta(atom, :all | integer | String.t() | {integer, integer}, integer | String.t()) ::
|
||||||
|
integer | String.t()
|
||||||
defp get_meta(type, key, default) do
|
defp get_meta(type, key, default) do
|
||||||
case :ets.match_object(@meta_table, {{type, key}, :"$1"}) do
|
case :ets.match_object(@meta_table, {{type, key}, :"$1"}) do
|
||||||
[{{_, _}, value}] -> value
|
[{{_, _}, value}] -> value
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmodule Mebe2.Engine.SlugUtils do
|
||||||
|
|
||||||
Nil is returned as is.
|
Nil is returned as is.
|
||||||
"""
|
"""
|
||||||
|
@spec slugify(String.t() | nil) :: String.t() | nil
|
||||||
def slugify(nil), do: nil
|
def slugify(nil), do: nil
|
||||||
|
|
||||||
def slugify(value) do
|
def slugify(value) do
|
||||||
|
@ -19,6 +20,7 @@ defmodule Mebe2.Engine.SlugUtils do
|
||||||
@doc """
|
@doc """
|
||||||
Get the author name related to this slug from the DB.
|
Get the author name related to this slug from the DB.
|
||||||
"""
|
"""
|
||||||
|
@spec unslugify_author(String.t()) :: String.t()
|
||||||
def unslugify_author(slug) do
|
def unslugify_author(slug) do
|
||||||
DB.get_author_name(slug)
|
DB.get_author_name(slug)
|
||||||
end
|
end
|
||||||
|
|
24
lib/web/frontend/src/style/archives.scss
Normal file
24
lib/web/frontend/src/style/archives.scss
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
nav.archives {
|
||||||
|
background-color: $accent-background;
|
||||||
|
color: $accent-text;
|
||||||
|
|
||||||
|
#archives-heading {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $accent-link;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-position: inside;
|
||||||
|
|
||||||
|
&.archives-year-list {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.archives-month-list {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,14 +8,15 @@ html {
|
||||||
|
|
||||||
body {
|
body {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template: 'hd' 'mn' 1fr 'ft' / auto;
|
grid-template: 'hd' 'mn' 1fr 'nav' 'ft' / auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
@media #{$md} {
|
@media #{$md} {
|
||||||
grid-template: 'hd mn'
|
grid-template: 'hd mn' 200px
|
||||||
'hd ft'
|
'nav mn'
|
||||||
|
'nav ft'
|
||||||
/ 1fr 3fr;
|
/ 1fr 3fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +69,12 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Archives in the sidebar
|
||||||
|
>nav.archives {
|
||||||
|
grid-area: nav;
|
||||||
|
padding: $layout-padding;
|
||||||
|
}
|
||||||
|
|
||||||
// Footer after all blog posts
|
// Footer after all blog posts
|
||||||
>footer {
|
>footer {
|
||||||
grid-area: ft;
|
grid-area: ft;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
@import './typography';
|
@import './typography';
|
||||||
@import './media';
|
@import './media';
|
||||||
@import './base-layout';
|
@import './base-layout';
|
||||||
|
@import './archives';
|
||||||
@import './post-list';
|
@import './post-list';
|
||||||
@import './pagination';
|
@import './pagination';
|
||||||
@import './post-layout';
|
@import './post-layout';
|
||||||
|
|
42
lib/web/middleware/archives.ex
Normal file
42
lib/web/middleware/archives.ex
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
defmodule Mebe2.Web.Middleware.Archives do
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
@archives_key :mebe2_archives
|
||||||
|
|
||||||
|
defmacro __using__(_opts) do
|
||||||
|
quote do
|
||||||
|
@before_compile unquote(__MODULE__)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defmacro __before_compile__(_env) do
|
||||||
|
quote do
|
||||||
|
defoverridable Raxx.Server
|
||||||
|
|
||||||
|
@impl Raxx.Server
|
||||||
|
def handle_head(head, config) do
|
||||||
|
unquote(__MODULE__).put_archives()
|
||||||
|
|
||||||
|
super(head, config)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Put yearly and monthly archives into the process storage of the current process.
|
||||||
|
"""
|
||||||
|
@spec put_archives() :: :ok
|
||||||
|
def put_archives() do
|
||||||
|
months = Mebe2.Engine.DB.get_all_months()
|
||||||
|
Process.put(@archives_key, months)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get list of tuples {year, month} that have at least one post.
|
||||||
|
"""
|
||||||
|
@spec get_archives() :: [{integer, integer}]
|
||||||
|
def get_archives() do
|
||||||
|
Process.get(@archives_key, [])
|
||||||
|
end
|
||||||
|
end
|
|
@ -21,30 +21,6 @@ defmodule Mebe2.Web.Middleware.RequestTime do
|
||||||
super(head, config)
|
super(head, config)
|
||||||
|> unquote(__MODULE__).process_response()
|
|> unquote(__MODULE__).process_response()
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl Raxx.Server
|
|
||||||
def handle_data(data, config) do
|
|
||||||
unquote(__MODULE__).put_response_timer()
|
|
||||||
|
|
||||||
super(data, config)
|
|
||||||
|> unquote(__MODULE__).process_response()
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl Raxx.Server
|
|
||||||
def handle_tail(tail, config) do
|
|
||||||
unquote(__MODULE__).put_response_timer()
|
|
||||||
|
|
||||||
super(tail, config)
|
|
||||||
|> unquote(__MODULE__).process_response()
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl Raxx.Server
|
|
||||||
def handle_info(message, config) do
|
|
||||||
unquote(__MODULE__).put_response_timer()
|
|
||||||
|
|
||||||
super(message, config)
|
|
||||||
|> unquote(__MODULE__).process_response()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,15 @@ defmodule Mebe2.Web.Router do
|
||||||
use Ace.HTTP.Service, port: 2142, cleartext: true
|
use Ace.HTTP.Service, port: 2142, cleartext: true
|
||||||
use Raxx.Logger
|
use Raxx.Logger
|
||||||
use Mebe2.Web.Middleware.RequestTime
|
use Mebe2.Web.Middleware.RequestTime
|
||||||
|
use Mebe2.Web.Middleware.Archives
|
||||||
|
|
||||||
use Raxx.Router, [
|
use Raxx.Router, [
|
||||||
{%{method: :GET, path: ["tag", _tag, "p", _page]}, Mebe2.Web.Routes.Tag},
|
{%{method: :GET, path: ["tag", _tag, "p", _page]}, Mebe2.Web.Routes.Tag},
|
||||||
{%{method: :GET, path: ["tag", _tag]}, Mebe2.Web.Routes.Tag},
|
{%{method: :GET, path: ["tag", _tag]}, Mebe2.Web.Routes.Tag},
|
||||||
|
{%{method: :GET, path: ["archive", _year, _month, "p", _page]}, Mebe2.Web.Routes.Month},
|
||||||
|
{%{method: :GET, path: ["archive", _year, _month]}, Mebe2.Web.Routes.Month},
|
||||||
|
{%{method: :GET, path: ["archive", _year, "p", _page]}, Mebe2.Web.Routes.Year},
|
||||||
|
{%{method: :GET, path: ["archive", _year]}, Mebe2.Web.Routes.Year},
|
||||||
{%{method: :GET, path: ["p", _page]}, Mebe2.Web.Routes.Index},
|
{%{method: :GET, path: ["p", _page]}, Mebe2.Web.Routes.Index},
|
||||||
{%{method: :GET, path: [_year, _month, _day, _slug]}, Mebe2.Web.Routes.Post},
|
{%{method: :GET, path: [_year, _month, _day, _slug]}, Mebe2.Web.Routes.Post},
|
||||||
{%{method: :GET, path: [_slug]}, Mebe2.Web.Routes.Page},
|
{%{method: :GET, path: [_slug]}, Mebe2.Web.Routes.Page},
|
||||||
|
|
42
lib/web/routes/month.ex
Normal file
42
lib/web/routes/month.ex
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
defmodule Mebe2.Web.Routes.Month do
|
||||||
|
use Raxx.Server
|
||||||
|
|
||||||
|
@impl Raxx.Server
|
||||||
|
def handle_request(
|
||||||
|
%Raxx.Request{path: ["archive", year_str, month_str, "p", page]} = _req,
|
||||||
|
_state
|
||||||
|
) do
|
||||||
|
with {year, _} <- Integer.parse(year_str),
|
||||||
|
{month, _} <- Integer.parse(month_str) do
|
||||||
|
Mebe2.Web.Routes.Utils.render_posts(
|
||||||
|
page,
|
||||||
|
&post_getter(year, month, &1, &2),
|
||||||
|
&renderer(year, month, &1, &2, &3, &4)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
_ -> Mebe2.Web.Routes.Utils.render_404()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl Raxx.Server
|
||||||
|
def handle_request(%Raxx.Request{path: ["archive", year_str, month_str]} = _req, _state) do
|
||||||
|
with {year, _} <- Integer.parse(year_str),
|
||||||
|
{month, _} <- Integer.parse(month_str) do
|
||||||
|
Mebe2.Web.Routes.Utils.render_posts(
|
||||||
|
&post_getter(year, month, &1, &2),
|
||||||
|
&renderer(year, month, &1, &2, &3, &4)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
_ -> Mebe2.Web.Routes.Utils.render_404()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp post_getter(year, month, first, limit),
|
||||||
|
do: {
|
||||||
|
Mebe2.Engine.DB.get_month_posts(year, month, first, limit),
|
||||||
|
Mebe2.Engine.DB.get_count(:month, {year, month})
|
||||||
|
}
|
||||||
|
|
||||||
|
defp renderer(year, month, response, posts, total, page),
|
||||||
|
do: Mebe2.Web.Views.Month.render(response, year, month, posts, total, page)
|
||||||
|
end
|
37
lib/web/routes/year.ex
Normal file
37
lib/web/routes/year.ex
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
defmodule Mebe2.Web.Routes.Year do
|
||||||
|
use Raxx.Server
|
||||||
|
|
||||||
|
@impl Raxx.Server
|
||||||
|
def handle_request(%Raxx.Request{path: ["archive", year_str, "p", page]} = _req, _state) do
|
||||||
|
with {year, _} <- Integer.parse(year_str) do
|
||||||
|
Mebe2.Web.Routes.Utils.render_posts(
|
||||||
|
page,
|
||||||
|
&post_getter(year, &1, &2),
|
||||||
|
&renderer(year, &1, &2, &3, &4)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
_ -> Mebe2.Web.Routes.Utils.render_404()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl Raxx.Server
|
||||||
|
def handle_request(%Raxx.Request{path: ["archive", year_str]} = _req, _state) do
|
||||||
|
with {year, _} <- Integer.parse(year_str) do
|
||||||
|
Mebe2.Web.Routes.Utils.render_posts(
|
||||||
|
&post_getter(year, &1, &2),
|
||||||
|
&renderer(year, &1, &2, &3, &4)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
_ -> Mebe2.Web.Routes.Utils.render_404()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp post_getter(year, first, limit),
|
||||||
|
do: {
|
||||||
|
Mebe2.Engine.DB.get_year_posts(year, first, limit),
|
||||||
|
Mebe2.Engine.DB.get_count(:year, year)
|
||||||
|
}
|
||||||
|
|
||||||
|
defp renderer(year, response, posts, total, page),
|
||||||
|
do: Mebe2.Web.Views.Year.render(response, year, posts, total, page)
|
||||||
|
end
|
17
lib/web/views/archives.ex
Normal file
17
lib/web/views/archives.ex
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
defmodule Mebe2.Web.Views.Archives do
|
||||||
|
use Raxx.View,
|
||||||
|
template: "archives.html.eex",
|
||||||
|
arguments: []
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get list of tuples {year, month} that have at least one post.
|
||||||
|
"""
|
||||||
|
@spec get_archives() :: [{integer, [{integer, integer}]}]
|
||||||
|
def get_archives() do
|
||||||
|
Mebe2.Web.Middleware.Archives.get_archives()
|
||||||
|
|> Enum.chunk_by(fn {year, _} -> year end)
|
||||||
|
|> Enum.map(fn [{year, _} | _] = list ->
|
||||||
|
{year, Enum.map(list, fn {_, month} -> month end)}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
24
lib/web/views/archives.html.eex
Normal file
24
lib/web/views/archives.html.eex
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<nav class="archives" aria-labelledby="archives-heading">
|
||||||
|
<%= raw(with [_|_] = years <- get_archives() do %>
|
||||||
|
<h2 id="archives-heading">Archives</h2>
|
||||||
|
<ul class="archives-year-list">
|
||||||
|
<%= raw(for {year, months} <- years do %>
|
||||||
|
<li>
|
||||||
|
<a href="<%= Mebe2.Web.Views.Utils.year_path_generator(year).(1) %>">
|
||||||
|
<%= year %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<ul class="archives-month-list">
|
||||||
|
<%= raw(for month <- months do %>
|
||||||
|
<li>
|
||||||
|
<a href="<%= Mebe2.Web.Views.Utils.month_path_generator(year, month).(1) %>">
|
||||||
|
<%= Mebe2.Web.Views.Utils.format_month(year, month) %>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<% end) %>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<% end) %>
|
||||||
|
</ul>
|
||||||
|
<% end) %>
|
||||||
|
</nav>
|
|
@ -24,6 +24,9 @@
|
||||||
<main>
|
<main>
|
||||||
<%= __content__ %>
|
<%= __content__ %>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<%= Mebe2.Web.Views.Archives.html() %>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<p>
|
<p>
|
||||||
© <%= Mebe2.get_conf(:blog_author) %>
|
© <%= Mebe2.get_conf(:blog_author) %>
|
||||||
|
|
5
lib/web/views/month.ex
Normal file
5
lib/web/views/month.ex
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
defmodule Mebe2.Web.Views.Month do
|
||||||
|
use Mebe2.Web.Views.BaseLayout,
|
||||||
|
template: "month.html.eex",
|
||||||
|
arguments: [:year, :month, :posts, :total, :page]
|
||||||
|
end
|
12
lib/web/views/month.html.eex
Normal file
12
lib/web/views/month.html.eex
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="viewing-info">
|
||||||
|
Viewing posts for <em><%= Mebe2.Web.Views.Utils.format_month(year, month) %></em>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%=
|
||||||
|
Mebe2.Web.Views.PostList.html(
|
||||||
|
posts,
|
||||||
|
total,
|
||||||
|
page,
|
||||||
|
Mebe2.Web.Views.Utils.month_path_generator(year, month)
|
||||||
|
)
|
||||||
|
%>
|
|
@ -17,4 +17,39 @@ defmodule Mebe2.Web.Views.Utils do
|
||||||
dstr = Calendar.Strftime.strftime!(post.datetime, "%Y/%m/%d")
|
dstr = Calendar.Strftime.strftime!(post.datetime, "%Y/%m/%d")
|
||||||
"/#{dstr}/#{post.slug}"
|
"/#{dstr}/#{post.slug}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Format the given year and month into a human readable nice string.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Mebe2.Web.Views.Utils.format_month(2014, 12)
|
||||||
|
"December 2014"
|
||||||
|
|
||||||
|
iex> Mebe2.Web.Views.Utils.format_month(2015, 4)
|
||||||
|
"April 2015"
|
||||||
|
"""
|
||||||
|
@spec format_month(integer, integer) :: String.t()
|
||||||
|
def format_month(year, month) do
|
||||||
|
Date.from_erl!({year, month, 1})
|
||||||
|
|> Calendar.Strftime.strftime!("%B %Y")
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Pad the month for path generation.
|
||||||
|
"""
|
||||||
|
@spec pad_month(integer) :: String.t()
|
||||||
|
def pad_month(month), do: Integer.to_string(month) |> String.pad_leading(2, "0")
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get path generator for the given year.
|
||||||
|
"""
|
||||||
|
@spec year_path_generator(integer) :: (integer -> String.t())
|
||||||
|
def year_path_generator(year), do: &"/archive/#{year}/p/#{&1}"
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get path generator for the given year and month combo.
|
||||||
|
"""
|
||||||
|
@spec month_path_generator(integer, integer) :: (integer -> String.t())
|
||||||
|
def month_path_generator(year, month), do: &"/archive/#{year}/#{pad_month(month)}/p/#{&1}"
|
||||||
end
|
end
|
||||||
|
|
5
lib/web/views/year.ex
Normal file
5
lib/web/views/year.ex
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
defmodule Mebe2.Web.Views.Year do
|
||||||
|
use Mebe2.Web.Views.BaseLayout,
|
||||||
|
template: "year.html.eex",
|
||||||
|
arguments: [:year, :posts, :total, :page]
|
||||||
|
end
|
12
lib/web/views/year.html.eex
Normal file
12
lib/web/views/year.html.eex
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="viewing-info">
|
||||||
|
Viewing posts for <em><%= year %></em>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%=
|
||||||
|
Mebe2.Web.Views.PostList.html(
|
||||||
|
posts,
|
||||||
|
total,
|
||||||
|
page,
|
||||||
|
Mebe2.Web.Views.Utils.year_path_generator(year)
|
||||||
|
)
|
||||||
|
%>
|
1
mix.exs
1
mix.exs
|
@ -27,6 +27,7 @@ defmodule Mebe2.MixProject do
|
||||||
{:ace, "~> 0.17.1"},
|
{:ace, "~> 0.17.1"},
|
||||||
{:calendar, "~> 0.17.4"},
|
{:calendar, "~> 0.17.4"},
|
||||||
{:slugger, "~> 0.3.0"},
|
{:slugger, "~> 0.3.0"},
|
||||||
|
{:ex2ms, "~> 1.5.0"},
|
||||||
{:mbu, "~> 3.0.0", runtime: false},
|
{:mbu, "~> 3.0.0", runtime: false},
|
||||||
{:exsync, "~> 0.2.3", only: :dev}
|
{:exsync, "~> 0.2.3", only: :dev}
|
||||||
]
|
]
|
||||||
|
|
1
mix.lock
1
mix.lock
|
@ -7,6 +7,7 @@
|
||||||
"cowlib": {:hex, :cowlib, "2.3.0", "bbd58ef537904e4f7c1dd62e6aa8bc831c8183ce4efa9bd1150164fe15be4caa", [:rebar3], [], "hexpm"},
|
"cowlib": {:hex, :cowlib, "2.3.0", "bbd58ef537904e4f7c1dd62e6aa8bc831c8183ce4efa9bd1150164fe15be4caa", [:rebar3], [], "hexpm"},
|
||||||
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
|
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
|
||||||
"eex_html": {:hex, :eex_html, "0.1.1", "df7ad68245068d5fea0dab2a38e5afdc386ec00a5b6445eac6402ed7aa6a2b12", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
|
"eex_html": {:hex, :eex_html, "0.1.1", "df7ad68245068d5fea0dab2a38e5afdc386ec00a5b6445eac6402ed7aa6a2b12", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"},
|
||||||
"exsync": {:hex, :exsync, "0.2.3", "a1ac11b4bd3808706003dbe587902101fcc1387d9fc55e8b10972f13a563dd15", [:mix], [{:file_system, "~> 0.2", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"},
|
"exsync": {:hex, :exsync, "0.2.3", "a1ac11b4bd3808706003dbe587902101fcc1387d9fc55e8b10972f13a563dd15", [:mix], [{:file_system, "~> 0.2", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
|
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
|
||||||
"hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
"hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
|
Reference in a new issue