From ff7bb96b4ef147dbcaa3afda059016dca53a288f Mon Sep 17 00:00:00 2001 From: Maximiliaan Strother III Date: Wed, 5 Jun 2019 15:08:19 +0200 Subject: [PATCH 1/5] Add support for `per_page` param --- lib/kerosene.ex | 22 ++++++++++++++++++++-- test/kerosene_test.exs | 13 +++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/kerosene.ex b/lib/kerosene.ex index 4692804..4bbbb9f 100644 --- a/lib/kerosene.ex +++ b/lib/kerosene.ex @@ -51,6 +51,8 @@ defmodule Kerosene do |> repo.all end + defp get_offset(_total_pages, _page, nil), do: 0 + defp get_offset(total_pages, page, per_page) do page = case page > total_pages do true -> total_pages @@ -117,11 +119,27 @@ defmodule Kerosene do defp build_options(opts, params) do page = Map.get(params, "page", @page) |> to_integer() - per_page = default_per_page(opts) |> to_integer() + per_page = get_per_page(params, opts) max_page = Keyword.get(opts, :max_page, default_max_page()) - Keyword.merge(opts, [page: page, per_page: per_page, params: params, max_page: max_page]) + Keyword.merge(opts, page: page, per_page: per_page, params: params, max_page: max_page) end + defp get_per_page(%{"per_page" => "all"}, _opts), do: nil + + defp get_per_page(%{"per_page" => per_page}, opts) + when is_integer(per_page) or is_binary(per_page) do + per_page = + if to_integer(per_page) > 0 do + per_page + else + default_per_page(opts) + end + + to_integer(per_page) + end + + defp get_per_page(_params, opts), do: opts |> default_per_page() |> to_integer() + defp default_per_page(opts) do case Keyword.get(opts, :per_page) do nil -> Application.get_env(:kerosene, :per_page, @per_page) diff --git a/test/kerosene_test.exs b/test/kerosene_test.exs index 7eff947..51189e2 100644 --- a/test/kerosene_test.exs +++ b/test/kerosene_test.exs @@ -45,6 +45,19 @@ defmodule KeroseneTest do assert kerosene.per_page == 5 end + test "per_page param" do + create_products() + {_items, kerosene} = Product |> Repo.paginate(%{"per_page" => 5}) + assert kerosene.per_page == 5 + end + + test "all per_page param" do + create_products() + {items, kerosene} = Product |> Repo.paginate(%{"per_page" => "all"}) + assert kerosene.per_page == nil + assert length(items) == 15 + end + test "default per_page option" do create_products() {items, kerosene} = Product |> Repo.paginate(%{}, per_page: nil) From e5624197ca5c1add2779440ca2aa7058b428a57c Mon Sep 17 00:00:00 2001 From: Max Strother Date: Wed, 1 Mar 2023 02:10:29 +0100 Subject: [PATCH 2/5] Bump PhoenixHTML from 2.10.4 to 3.3.1 + bump Plug from 1.4.3 to 1.7.2 since PhoenixHTML requires ~> 1.5 --- mix.exs | 4 ++-- mix.lock | 29 +++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mix.exs b/mix.exs index e99ba0f..31d6841 100644 --- a/mix.exs +++ b/mix.exs @@ -39,8 +39,8 @@ defmodule Kerosene.Mixfile do # # Type "mix help deps" for more examples and options defp deps do - [{:phoenix_html, "~> 2.10"}, - {:plug, "~> 1.4"}, + [{:phoenix_html, "~> 3.3"}, + {:plug, "~> 1.7"}, {:ecto, "~> 3.0"}, {:ecto_sql, "~> 3.0"}, # Test dependencies diff --git a/mix.lock b/mix.lock index 7518900..0211a00 100644 --- a/mix.lock +++ b/mix.lock @@ -1,16 +1,17 @@ %{ - "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []}, - "db_connection": {:hex, :db_connection, "2.0.1", "09454c6c6e8e4295f400b72580b19f0ac68fda2602e209533285206cb99bee6b", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, - "decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"}, - "earmark": {:hex, :earmark, "0.2.1", "ba6d26ceb16106d069b289df66751734802777a3cbb6787026dd800ffeb850f3", [:mix], []}, - "ecto": {:hex, :ecto, "3.0.0", "059250d96f17f9c10f524fcb09d058f566691343e90318a161cf62a48f3912a9", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, - "ecto_sql": {:hex, :ecto_sql, "3.0.0", "8d1883376bee02a0e76b5ef797e39d04333c34b9935d0b4785dbf3cbdb571e2a", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.2.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.12.0", "b774aabfede4af31c0301aece12371cbd25995a21bb3d71d66f5c2fe074c603f", [:mix], [{:earmark, "~> 0.2", [hex: :earmark, optional: false]}]}, - "inch_ex": {:hex, :inch_ex, "0.5.5", "b63f57e281467bd3456461525fdbc9e158c8edbe603da6e3e4671befde796a3d", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]}, - "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []}, - "phoenix_html": {:hex, :phoenix_html, "2.10.4", "d4f99c32d5dc4918b531fdf163e1fd7cf20acdd7703f16f5d02d4db36de803b7", [:mix], [{:plug, "~> 1.0", [hex: :plug, optional: false]}]}, - "plug": {:hex, :plug, "1.4.3", "236d77ce7bf3e3a2668dc0d32a9b6f1f9b1f05361019946aae49874904be4aed", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []}, - "postgrex": {:hex, :postgrex, "0.14.0", "f3d6ffea1ca8a156e0633900a5338a3d17b00435227726baed8982718232b694", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, - "telemetry": {:hex, :telemetry, "0.2.0", "5b40caa3efe4deb30fb12d7cd8ed4f556f6d6bd15c374c2366772161311ce377", [:mix], [], "hexpm"}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"}, + "db_connection": {:hex, :db_connection, "2.0.1", "09454c6c6e8e4295f400b72580b19f0ac68fda2602e209533285206cb99bee6b", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "aad7a9a85a778a798b734a41dcbfb99fbe291e329549a68330e1c5b0865c31f8"}, + "decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm", "130926580655f34d759dd25f5d723fd233c9bbe0399cde57e2a1adea9ed92e08"}, + "earmark": {:hex, :earmark, "0.2.1", "ba6d26ceb16106d069b289df66751734802777a3cbb6787026dd800ffeb850f3", [:mix], [], "hexpm", "c86afb8d22a5aa8315afd4257c7512011c0c9a48b0fea43af7612836b958098b"}, + "ecto": {:hex, :ecto, "3.0.0", "059250d96f17f9c10f524fcb09d058f566691343e90318a161cf62a48f3912a9", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "e425bac0b6a7796655395deaf411f32f9fd8133c65eb2977ec370889e4705a9c"}, + "ecto_sql": {:hex, :ecto_sql, "3.0.0", "8d1883376bee02a0e76b5ef797e39d04333c34b9935d0b4785dbf3cbdb571e2a", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.2.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6fa4c5d69c4fd5be1a1a28fdc0fe98c8d9277eeb505c6da8f316d01330fa56e1"}, + "ex_doc": {:hex, :ex_doc, "0.12.0", "b774aabfede4af31c0301aece12371cbd25995a21bb3d71d66f5c2fe074c603f", [:mix], [{:earmark, "~> 0.2", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm", "76a04c6bb6876df8eae8ff8bf34fb1004bbead5172d31c9dfd71c4e3aed011b7"}, + "inch_ex": {:hex, :inch_ex, "0.5.5", "b63f57e281467bd3456461525fdbc9e158c8edbe603da6e3e4671befde796a3d", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "9c2e35eb4189db5fe3448d1e2b98b0802a3e83a63e39e137c04d09ef1450f636"}, + "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, + "phoenix_html": {:hex, :phoenix_html, "3.3.1", "4788757e804a30baac6b3fc9695bf5562465dd3f1da8eb8460ad5b404d9a2178", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bed1906edd4906a15fd7b412b85b05e521e1f67c9a85418c55999277e553d0d3"}, + "plug": {:hex, :plug, "1.7.2", "d7b7db7fbd755e8283b6c0a50be71ec0a3d67d9213d74422d9372effc8e87fd1", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm", "de9825f21c6fd6adfdeae8f9c80dcd88c1e58301f06bf13d659b7e606b88abe0"}, + "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, + "postgrex": {:hex, :postgrex, "0.14.0", "f3d6ffea1ca8a156e0633900a5338a3d17b00435227726baed8982718232b694", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "ee6d8bc31ec7064f87030b98e431cf7ef0537052339de289b575b0a8872f501e"}, + "telemetry": {:hex, :telemetry, "0.2.0", "5b40caa3efe4deb30fb12d7cd8ed4f556f6d6bd15c374c2366772161311ce377", [:mix], [], "hexpm", "4e9071b8d1795d0f1ae00584594c3faf430c88821b69e4bd09b02e7840231f32"}, } From 6cf52f0d650102e6dbe255c0e5a9e6ecac53446c Mon Sep 17 00:00:00 2001 From: Max Strother Date: Wed, 1 Mar 2023 02:24:58 +0100 Subject: [PATCH 3/5] Add a formatter and format the project --- .formatter.exs | 3 + CHANGELOG.md | 2 +- README.md | 10 +- config/config.exs | 5 +- config/prod.exs | 2 +- config/test.exs | 27 +++-- lib/kerosene.ex | 39 ++++--- lib/kerosene/html.ex | 147 +++++++++++++------------ lib/kerosene/html/bootstrap.ex | 43 ++++---- lib/kerosene/html/bootstrap4.ex | 3 +- lib/kerosene/html/foundation.ex | 39 +++---- lib/kerosene/html/materialize.ex | 7 +- lib/kerosene/html/semantic.ex | 35 +++--- lib/kerosene/html/simple.ex | 3 +- lib/kerosene/json.ex | 4 +- lib/kerosene/paginator.ex | 43 ++++++-- mix.exs | 73 ++++++------ test/json_test.exs | 5 +- test/kerosene/html/bootstrap4_test.exs | 88 +++++++-------- test/kerosene/html/bootstrap_test.exs | 88 +++++++-------- test/kerosene/html/foundation_test.exs | 80 +++++++------- test/kerosene/html/semantic_test.exs | 80 +++++++------- test/kerosene_test.exs | 17 ++- test/paginator_test.exs | 2 +- test/support/product.ex | 20 ++-- test/support/repo.ex | 13 ++- 26 files changed, 466 insertions(+), 412 deletions(-) create mode 100644 .formatter.exs diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..d304ff3 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,3 @@ +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/CHANGELOG.md b/CHANGELOG.md index a9f49f5..2202cb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,4 +21,4 @@ * Update deps * Buxfix minor ## v0.0.1 (2016-03-10) -* Initial Release \ No newline at end of file +* Initial Release diff --git a/README.md b/README.md index 0fdb7be..b4ef5d3 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ end Add Kerosene to your `repo.ex`: ```elixir defmodule MyApp.Repo do - use Ecto.Repo, + use Ecto.Repo, otp_app: :testapp, adapter: Ecto.Adapters.Postgres use Kerosene, per_page: 2 @@ -25,10 +25,10 @@ end ``` ## Usage -Start paginating your queries +Start paginating your queries ```elixir def index(conn, params) do - {products, kerosene} = + {products, kerosene} = Product |> Product.with_lowest_price |> Repo.paginate(params) @@ -37,7 +37,7 @@ def index(conn, params) do end ``` -Add view helpers to your view +Add view helpers to your view ```elixir defmodule MyApp.ProductView do use MyApp.Web, :view @@ -87,7 +87,7 @@ end You can also send in options to paginate helper look at the docs for more details. ## Contributing - + Please do send pull requests and bug reports, positive feedback is always welcome. diff --git a/config/config.exs b/config/config.exs index 2b309c3..b9affac 100644 --- a/config/config.exs +++ b/config/config.exs @@ -27,7 +27,6 @@ use Mix.Config # Configuration from the imported file will override the ones defined # here (which is why it is important to import them last). # -import_config "#{Mix.env}.exs" +import_config "#{Mix.env()}.exs" -config :kerosene, :html, - theme: :bootstrap \ No newline at end of file +config :kerosene, :html, theme: :bootstrap diff --git a/config/prod.exs b/config/prod.exs index a7d258e..d2d855e 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -1 +1 @@ -use Mix.Config \ No newline at end of file +use Mix.Config diff --git a/config/test.exs b/config/test.exs index 428f089..38cefa5 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,14 +1,13 @@ -use Mix.Config - -config :kerosene, ecto_repos: [Kerosene.Repo] - -config :kerosene, Kerosene.Repo, - username: "postgres", - password: "postgres", - database: "kerosene_dev", - hostname: "localhost", - pool: Ecto.Adapters.SQL.Sandbox - -# shut up only log errors -config :logger, :console, - level: :error +use Mix.Config + +config :kerosene, ecto_repos: [Kerosene.Repo] + +config :kerosene, Kerosene.Repo, + username: "postgres", + password: "postgres", + database: "kerosene_dev", + hostname: "localhost", + pool: Ecto.Adapters.SQL.Sandbox + +# shut up only log errors +config :logger, :console, level: :error diff --git a/lib/kerosene.ex b/lib/kerosene.ex index 4bbbb9f..bf4c3ae 100644 --- a/lib/kerosene.ex +++ b/lib/kerosene.ex @@ -1,5 +1,12 @@ defmodule Kerosene do - defstruct items: [], per_page: 0, max_page: 0, page: 0, total_pages: 0, total_count: 0, params: [] + defstruct items: [], + per_page: 0, + max_page: 0, + page: 0, + total_pages: 0, + total_count: 0, + params: [] + import Ecto.Query @per_page 10 @@ -13,8 +20,7 @@ defmodule Kerosene do defmacro __using__(opts \\ []) do quote do def paginate(query, params \\ %{}, options \\ []) do - Kerosene.paginate( __MODULE__, query, params, - Keyword.merge(unquote(opts), options)) + Kerosene.paginate(__MODULE__, query, params, Keyword.merge(unquote(opts), options)) end end end @@ -31,7 +37,7 @@ defmodule Kerosene do page = get_page(opts, total_pages) offset = get_offset(total_count, page, per_page) - kerosene = %Kerosene { + kerosene = %Kerosene{ per_page: per_page, page: page, total_pages: total_pages, @@ -44,6 +50,7 @@ defmodule Kerosene do end defp get_items(repo, query, nil, _), do: repo.all(query) + defp get_items(repo, query, limit, offset) do query |> limit(^limit) @@ -54,10 +61,11 @@ defmodule Kerosene do defp get_offset(_total_pages, _page, nil), do: 0 defp get_offset(total_pages, page, per_page) do - page = case page > total_pages do - true -> total_pages - _ -> page - end + page = + case page > total_pages do + true -> total_pages + _ -> page + end case page > 0 do true -> (page - 1) * per_page @@ -78,11 +86,12 @@ defmodule Kerosene do total_pages || 0 end - defp total_count(query = %{group_bys: [_|_]}), do: total_row_count(query) + defp total_count(query = %{group_bys: [_ | _]}), do: total_row_count(query) defp total_count(query = %{from: %{source: {_, nil}}}), do: total_row_count(query) defp total_count(query) do primary_key = get_primary_key(query) + query |> exclude(:select) |> select([i], count(field(i, ^primary_key), :distinct)) @@ -95,10 +104,11 @@ defmodule Kerosene do end def get_primary_key(query) do - new_query = case is_map(query) do - true -> query.from.source |> elem(1) - _ -> query - end + new_query = + case is_map(query) do + true -> query.from.source |> elem(1) + _ -> query + end new_query |> apply(:__schema__, [:primary_key]) @@ -106,6 +116,7 @@ defmodule Kerosene do end def get_total_pages(_, nil), do: 1 + def get_total_pages(count, per_page) do Float.ceil(count / per_page) |> trunc() end @@ -152,11 +163,13 @@ defmodule Kerosene do end def to_integer(i) when is_integer(i), do: abs(i) + def to_integer(i) when is_binary(i) do case Integer.parse(i) do {n, _} -> n _ -> 0 end end + def to_integer(_), do: @page end diff --git a/lib/kerosene/html.ex b/lib/kerosene/html.ex index 573ec64..203ddce 100644 --- a/lib/kerosene/html.ex +++ b/lib/kerosene/html.ex @@ -1,73 +1,74 @@ -defmodule Kerosene.HTML do - use Phoenix.HTML - alias Kerosene.HTML - import Kerosene.Paginator, only: [build_options: 1] - - @themes [:bootstrap, :bootstrap4, :foundation, :semantic] - - @moduledoc """ - Html helpers to render the pagination links and more, - import the `Kerosene.HTML` in your view module. - - defmodule MyApp.ProductView do - use MyApp.Web, :view - import Kerosene.HTML - end - - now you have these view helpers in your template file. - <%= paginate @conn, @page %> - - Where `@page` is a `%Kerosene{}` struct returned from `Repo.paginate/2`. - - `paginate` helper takes keyword list of `options` and `params`. - <%= paginate @conn, @page, window: 5, next_label: ">>", previous_label: "<<", first: true, last: true, first_label: "First", last_label: "Last" %> - """ - - @doc """ - Generates the HTML pagination links for a given page returned by Kerosene. - - The `theme` indicates which CSS framework you are using. The default is - `:bootstrap`, but you can add your own using the `Kerosene.HTML.do_paginate/3` function - if desired. Kerosene provides few themes out of the box: - - #{inspect @themes} - - Example: - - iex> Kerosene.HTML.paginate(@conn, @kerosene) - - Path can be overriden by adding setting `:path` in the `opts`. - For example: - - Kerosene.HTML.paginate(@conn, @kerosene, path: product_path(@conn, :index, foo: "bar")) - - Additional panigation class can be added by adding setting `:class` in the `opts`. - For example: - - Kerosene.HTML.paginate(@conn, @kerosene, theme: :boostrap4, class: "paginate-sm") - """ - defmacro __using__(_opts \\ []) do - quote do - import Kerosene.HTML - end - end - - def paginate(conn, paginator, opts \\ []) do - opts = build_options(opts) - - conn - |> Kerosene.Paginator.paginate(paginator, opts) - |> render_page_list(opts) - end - - defp render_page_list(page_list, opts) do - case opts[:theme] do - :bootstrap -> HTML.Bootstrap.generate_links(page_list, opts[:class]) - :bootstrap4 -> HTML.Bootstrap4.generate_links(page_list, opts[:class]) - :foundation -> HTML.Foundation.generate_links(page_list, opts[:class]) - :semantic -> HTML.Semantic.generate_links(page_list, opts[:class]) - :materialize -> HTML.Materialize.generate_links(page_list, opts[:class]) - _ -> HTML.Simple.generate_links(page_list, opts[:class]) - end - end -end +defmodule Kerosene.HTML do + @themes [:bootstrap, :bootstrap4, :foundation, :semantic] + + @moduledoc """ + Html helpers to render the pagination links and more, + import the `Kerosene.HTML` in your view module. + + defmodule MyApp.ProductView do + use MyApp.Web, :view + import Kerosene.HTML + end + + now you have these view helpers in your template file. + <%= paginate @conn, @page %> + + Where `@page` is a `%Kerosene{}` struct returned from `Repo.paginate/2`. + + `paginate` helper takes keyword list of `options` and `params`. + <%= paginate @conn, @page, window: 5, next_label: ">>", previous_label: "<<", first: true, last: true, first_label: "First", last_label: "Last" %> + """ + + @doc """ + Generates the HTML pagination links for a given page returned by Kerosene. + + The `theme` indicates which CSS framework you are using. The default is + `:bootstrap`, but you can add your own using the `Kerosene.HTML.do_paginate/3` function + if desired. Kerosene provides few themes out of the box: + + #{inspect(@themes)} + + Example: + + iex> Kerosene.HTML.paginate(@conn, @kerosene) + + Path can be overridden by adding setting `:path` in the `opts`. + For example: + + Kerosene.HTML.paginate(@conn, @kerosene, path: product_path(@conn, :index, foo: "bar")) + + Additional pagination class can be added by adding setting `:class` in the `opts`. + For example: + + Kerosene.HTML.paginate(@conn, @kerosene, theme: :bootstrap4, class: "paginate-sm") + """ + + use Phoenix.HTML + alias Kerosene.HTML + import Kerosene.Paginator, only: [build_options: 1] + + defmacro __using__(_opts \\ []) do + quote do + import Kerosene.HTML + end + end + + def paginate(conn, paginator, opts \\ []) do + opts = build_options(opts) + + conn + |> Kerosene.Paginator.paginate(paginator, opts) + |> render_page_list(opts) + end + + defp render_page_list(page_list, opts) do + case opts[:theme] do + :bootstrap -> HTML.Bootstrap.generate_links(page_list, opts[:class]) + :bootstrap4 -> HTML.Bootstrap4.generate_links(page_list, opts[:class]) + :foundation -> HTML.Foundation.generate_links(page_list, opts[:class]) + :semantic -> HTML.Semantic.generate_links(page_list, opts[:class]) + :materialize -> HTML.Materialize.generate_links(page_list, opts[:class]) + _ -> HTML.Simple.generate_links(page_list, opts[:class]) + end + end +end diff --git a/lib/kerosene/html/bootstrap.ex b/lib/kerosene/html/bootstrap.ex index 32f52df..0bf001a 100644 --- a/lib/kerosene/html/bootstrap.ex +++ b/lib/kerosene/html/bootstrap.ex @@ -1,21 +1,22 @@ -defmodule Kerosene.HTML.Bootstrap do - use Phoenix.HTML - - def generate_links(page_list, additional_class) do - content_tag :nav do - content_tag :ul, class: build_html_class(additional_class) do - for {label, _page, url, current} <- page_list do - content_tag :li, class: build_html_class(current) do - link "#{label}", to: url - end - end - end - end - end - - defp build_html_class(true), do: "active" - defp build_html_class(false), do: nil - defp build_html_class(additional_class) do - String.trim("pagination #{additional_class}") - end -end +defmodule Kerosene.HTML.Bootstrap do + use Phoenix.HTML + + def generate_links(page_list, additional_class) do + content_tag :nav do + content_tag :ul, class: build_html_class(additional_class) do + for {label, _page, url, current} <- page_list do + content_tag :li, class: build_html_class(current) do + link("#{label}", to: url) + end + end + end + end + end + + defp build_html_class(true), do: "active" + defp build_html_class(false), do: nil + + defp build_html_class(additional_class) do + String.trim("pagination #{additional_class}") + end +end diff --git a/lib/kerosene/html/bootstrap4.ex b/lib/kerosene/html/bootstrap4.ex index 34f3a20..e3b5fd3 100644 --- a/lib/kerosene/html/bootstrap4.ex +++ b/lib/kerosene/html/bootstrap4.ex @@ -6,7 +6,7 @@ defmodule Kerosene.HTML.Bootstrap4 do content_tag :ul, class: build_html_class(additional_class) do for {label, _page, url, current} <- page_list do content_tag :li, class: build_html_class(current) do - link "#{label}", to: url, class: "page-link" + link("#{label}", to: url, class: "page-link") end end end @@ -15,6 +15,7 @@ defmodule Kerosene.HTML.Bootstrap4 do defp build_html_class(true), do: "page-item active" defp build_html_class(false), do: "page-item" + defp build_html_class(additional_class) do String.trim("pagination #{additional_class}") end diff --git a/lib/kerosene/html/foundation.ex b/lib/kerosene/html/foundation.ex index 155cb55..08cbcba 100644 --- a/lib/kerosene/html/foundation.ex +++ b/lib/kerosene/html/foundation.ex @@ -1,19 +1,20 @@ -defmodule Kerosene.HTML.Foundation do - use Phoenix.HTML - - def generate_links(page_list, additional_class) do - content_tag :ul, class: build_html_class(additional_class), role: "pagination" do - for {label, _page, url, current} <- page_list do - content_tag :li, class: build_html_class(current) do - link "#{label}", to: url - end - end - end - end - - defp build_html_class(true), do: "active" - defp build_html_class(false), do: nil - defp build_html_class(additional_class) do - String.trim("pagination #{additional_class}") - end -end +defmodule Kerosene.HTML.Foundation do + use Phoenix.HTML + + def generate_links(page_list, additional_class) do + content_tag :ul, class: build_html_class(additional_class), role: "pagination" do + for {label, _page, url, current} <- page_list do + content_tag :li, class: build_html_class(current) do + link("#{label}", to: url) + end + end + end + end + + defp build_html_class(true), do: "active" + defp build_html_class(false), do: nil + + defp build_html_class(additional_class) do + String.trim("pagination #{additional_class}") + end +end diff --git a/lib/kerosene/html/materialize.ex b/lib/kerosene/html/materialize.ex index 716d9fe..3a30ac0 100644 --- a/lib/kerosene/html/materialize.ex +++ b/lib/kerosene/html/materialize.ex @@ -3,16 +3,17 @@ defmodule Kerosene.HTML.Materialize do def generate_links(page_list, additional_class) do content_tag :ul, class: build_html_class(additional_class) do - for {label, _page, url, current} <- page_list do + for {label, _page, url, current} <- page_list do content_tag :li, class: build_html_class(current) do - link "#{label}", to: url + link("#{label}", to: url) end - end + end end end defp build_html_class(true), do: "active" defp build_html_class(false), do: "waves-effect" + defp build_html_class(additional_class) do String.trim("pagination #{additional_class}") end diff --git a/lib/kerosene/html/semantic.ex b/lib/kerosene/html/semantic.ex index b4300eb..aaa701e 100644 --- a/lib/kerosene/html/semantic.ex +++ b/lib/kerosene/html/semantic.ex @@ -1,17 +1,18 @@ -defmodule Kerosene.HTML.Semantic do - use Phoenix.HTML - - def generate_links(page_list, additional_class) do - content_tag :nav, class: build_html_class(additional_class) do - for {label, _page, url, current} <- page_list do - link "#{label}", to: url, class: build_html_class(current) - end - end - end - - defp build_html_class(true), do: "item active" - defp build_html_class(false), do: "item" - defp build_html_class(additional_class) do - String.trim("ui pagination menu #{additional_class}") - end -end +defmodule Kerosene.HTML.Semantic do + use Phoenix.HTML + + def generate_links(page_list, additional_class) do + content_tag :nav, class: build_html_class(additional_class) do + for {label, _page, url, current} <- page_list do + link("#{label}", to: url, class: build_html_class(current)) + end + end + end + + defp build_html_class(true), do: "item active" + defp build_html_class(false), do: "item" + + defp build_html_class(additional_class) do + String.trim("ui pagination menu #{additional_class}") + end +end diff --git a/lib/kerosene/html/simple.ex b/lib/kerosene/html/simple.ex index 4111ab6..69b9bbb 100644 --- a/lib/kerosene/html/simple.ex +++ b/lib/kerosene/html/simple.ex @@ -4,13 +4,14 @@ defmodule Kerosene.HTML.Simple do def generate_links(page_list, additional_class) do content_tag :nav, class: build_html_class(additional_class) do for {label, _page, url, current} <- page_list do - link "#{label}", to: url, class: build_html_class(current) + link("#{label}", to: url, class: build_html_class(current)) end end end defp build_html_class(true), do: "active" defp build_html_class(false), do: nil + defp build_html_class(additional_class) do String.trim("pagination #{additional_class}") end diff --git a/lib/kerosene/json.ex b/lib/kerosene/json.ex index 54b2a0c..dc35539 100644 --- a/lib/kerosene/json.ex +++ b/lib/kerosene/json.ex @@ -37,7 +37,7 @@ defmodule Kerosene.JSON do def render_page_list(page_list) do Enum.map(page_list, fn {link_label, page, url, current} -> - %{label: "#{link_label}", url: url, page: page, current: current} + %{label: "#{link_label}", url: url, page: page, current: current} end) end -end \ No newline at end of file +end diff --git a/lib/kerosene/paginator.ex b/lib/kerosene/paginator.ex index 34130c7..a82eef9 100644 --- a/lib/kerosene/paginator.ex +++ b/lib/kerosene/paginator.ex @@ -1,7 +1,16 @@ defmodule Kerosene.Paginator do use Phoenix.HTML - @default [window: 3, range: true, next_label: "Next", previous_label: "Previous", first: true, first_label: "First", last: true, last_label: "Last"] + @default [ + window: 3, + range: true, + next_label: "Next", + previous_label: "Previous", + first: true, + first_label: "First", + last: true, + last_label: "Last" + ] @moduledoc """ Helpers to render the pagination links and more. @@ -19,18 +28,18 @@ defmodule Kerosene.Paginator do |> page_list(page, total_pages, opts[:window], opts[:range]) |> next_page(page, total_pages) |> last_page(page, total_pages, opts[:window], opts[:last]) - |> Enum.map(fn {l, p} -> - {label_text(l, opts), p, build_url(conn, Map.put(params, "page", p)), page == p} + |> Enum.map(fn {l, p} -> + {label_text(l, opts), p, build_url(conn, Map.put(params, "page", p)), page == p} end) end def label_text(label, opts) do case label do - :first -> opts[:first_label] + :first -> opts[:first_label] :previous -> opts[:previous_label] - :next -> opts[:next_label] - :last -> opts[:last_label] - _ -> label + :next -> opts[:next_label] + :last -> opts[:last_label] + _ -> label end end @@ -38,44 +47,53 @@ defmodule Kerosene.Paginator do Generates a page list based on current window """ def page_list(list, page, total, window, true) when is_integer(window) and window >= 1 do - page_list = left(page, total, window)..right(page, total, window) - |> Enum.map(fn n -> {n, n} end) + page_list = + left(page, total, window)..right(page, total, window) + |> Enum.map(fn n -> {n, n} end) list ++ page_list end + def page_list(list, _page, _total, _window, _range), do: list def left(page, _total, window) when page - window <= 1 do 1 end + def left(page, _total, window), do: page - window def right(page, total, window) when page + window >= total do total end + def right(page, _total, window), do: page + window def previous_page(page) when page > 1 do [{:previous, page - 1}] end + def previous_page(_page), do: [] def next_page(list, page, total) when page < total do list ++ [{:next, page + 1}] end + def next_page(list, _page, _total), do: list def first_page(list, page, window, true) when page - window > 1 do [{:first, 1} | list] end + def first_page(list, _page, _window, _included), do: list def last_page(list, page, total, window, true) when page + window < total do list ++ [{:last, total}] end + def last_page(list, _page, _total, _window, _included), do: list def build_url(conn, nil), do: conn.request_path + def build_url(conn, params) do "#{conn.request_path}?#{build_query(params)}" end @@ -84,7 +102,7 @@ defmodule Kerosene.Paginator do Constructs a query param from a keyword list """ def build_query(params) do - params |> Plug.Conn.Query.encode + params |> Plug.Conn.Query.encode() end def build_params(params, params2) do @@ -94,12 +112,13 @@ defmodule Kerosene.Paginator do def normalize_keys(params) when is_map(params) do for {key, val} <- params, into: %{}, do: {to_string(key), val} end + def normalize_keys(params), do: params def build_options(opts) do params = opts[:params] || %{} - theme = opts[:theme] || Application.get_env(:kerosene, :theme, :bootstrap) - opts = Keyword.merge(opts, [params: params, theme: theme]) + theme = opts[:theme] || Application.get_env(:kerosene, :theme, :bootstrap) + opts = Keyword.merge(opts, params: params, theme: theme) Keyword.merge(@default, opts) end diff --git a/mix.exs b/mix.exs index 31d6841..92b0a4f 100644 --- a/mix.exs +++ b/mix.exs @@ -3,29 +3,32 @@ defmodule Kerosene.Mixfile do @version "0.9.0" def project do - [app: :kerosene, - version: @version, - elixir: "~> 1.2", - elixirc_paths: path(Mix.env), - package: package(), - build_embedded: Mix.env == :prod, - start_permanent: Mix.env == :prod, - deps: deps(), - aliases: aliases(), - name: "Kerosene", - docs: [source_ref: "v#{@version}", main: "Kerosene"], - source_url: "https://github.com/elixirdrops/kerosene", - description: """ - Pagination for Ecto and Phoenix. - """] + [ + app: :kerosene, + version: @version, + elixir: "~> 1.2", + elixirc_paths: path(Mix.env()), + package: package(), + build_embedded: Mix.env() == :prod, + start_permanent: Mix.env() == :prod, + deps: deps(), + aliases: aliases(), + name: "Kerosene", + docs: [source_ref: "v#{@version}", main: "Kerosene"], + source_url: "https://github.com/elixirdrops/kerosene", + description: """ + Pagination for Ecto and Phoenix. + """ + ] end # Configuration for the OTP application # # Type "mix help compile.app" for more information def application do - [applications: application(Mix.env)] + [applications: application(Mix.env())] end + defp application(:test), do: [:postgrex, :ecto, :logger] defp application(_), do: [:logger] @@ -38,30 +41,36 @@ defmodule Kerosene.Mixfile do # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} # # Type "mix help deps" for more examples and options - defp deps do - [{:phoenix_html, "~> 3.3"}, - {:plug, "~> 1.7"}, - {:ecto, "~> 3.0"}, - {:ecto_sql, "~> 3.0"}, - # Test dependencies - {:postgrex, "~> 0.14.0", only: [:test]}, - # Docs dependencies - {:earmark, "~> 0.1", only: :docs}, - {:ex_doc, "~> 0.11", only: :docs}, - {:inch_ex, "~> 0.2", only: :docs}] + def deps do + [ + {:phoenix_html, "~> 3.3"}, + {:plug, "~> 1.7"}, + {:ecto, "~> 3.0"}, + {:ecto_sql, "~> 3.0"}, + # Test dependencies + {:postgrex, "~> 0.14.0", only: [:test]}, + # Docs dependencies + {:earmark, "~> 0.1", only: :docs}, + {:ex_doc, "~> 0.11", only: :docs}, + {:inch_ex, "~> 0.2", only: :docs} + ] end defp path(:test) do ["lib", "test/support", "test/fixtures"] end + defp path(_), do: ["lib"] defp package do - [maintainers: ["Ally Raza"], - licenses: ["MIT"], - links: %{github: "https://github.com/elixirdrops/kerosene"}, - files: ~w(lib test config) ++ - ~w(CHANGELOG.md LICENSE.md mix.exs README.md)] + [ + maintainers: ["Ally Raza"], + licenses: ["MIT"], + links: %{github: "https://github.com/elixirdrops/kerosene"}, + files: + ~w(lib test config) ++ + ~w(CHANGELOG.md LICENSE.md mix.exs README.md) + ] end def aliases do diff --git a/test/json_test.exs b/test/json_test.exs index 32d01e8..97f6520 100644 --- a/test/json_test.exs +++ b/test/json_test.exs @@ -20,10 +20,9 @@ defmodule Kerosene.JSONTest do %{label: "Last", url: "/products?category=25&page=16", page: 16, current: false} ] - data = PaginatorData.page_list + data = PaginatorData.page_list() output = Kerosene.JSON.render_page_list(data) assert expected == output end - -end \ No newline at end of file +end diff --git a/test/kerosene/html/bootstrap4_test.exs b/test/kerosene/html/bootstrap4_test.exs index 6a2f2fb..f0f82ee 100644 --- a/test/kerosene/html/bootstrap4_test.exs +++ b/test/kerosene/html/bootstrap4_test.exs @@ -5,62 +5,62 @@ defmodule Kerosene.HTML.Bootstrap4Test do alias Kerosene.HTML.Bootstrap4 test "renders Bootstrap 4 pagination markup" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Bootstrap4.generate_links(page_list, nil) + safe_html_tree = Bootstrap4.generate_links(page_list, nil) rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup end test "renders Bootstrap 4 pagination markup with additional class" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Bootstrap4.generate_links(page_list, "pagination-sm") + safe_html_tree = Bootstrap4.generate_links(page_list, "pagination-sm") rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup diff --git a/test/kerosene/html/bootstrap_test.exs b/test/kerosene/html/bootstrap_test.exs index 55870dd..7521de1 100644 --- a/test/kerosene/html/bootstrap_test.exs +++ b/test/kerosene/html/bootstrap_test.exs @@ -5,62 +5,62 @@ defmodule Kerosene.HTML.BoostrapTest do alias Kerosene.HTML.Bootstrap test "renders Bootstrap 3 pagination markup" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Bootstrap.generate_links(page_list, nil) + safe_html_tree = Bootstrap.generate_links(page_list, nil) rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup end test "renders Bootstrap pagination markup with additional class" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Bootstrap.generate_links(page_list, "pagination-sm") + safe_html_tree = Bootstrap.generate_links(page_list, "pagination-sm") rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup diff --git a/test/kerosene/html/foundation_test.exs b/test/kerosene/html/foundation_test.exs index b0a87fa..e1d1b64 100644 --- a/test/kerosene/html/foundation_test.exs +++ b/test/kerosene/html/foundation_test.exs @@ -5,58 +5,58 @@ defmodule Kerosene.HTML.FoundationTest do alias Kerosene.HTML.Foundation test "renders Foundation pagination markup" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Foundation.generate_links(page_list, nil) + safe_html_tree = Foundation.generate_links(page_list, nil) rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup end test "renders Foundation pagination markup with additional class" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Foundation.generate_links(page_list, "custom-class") + safe_html_tree = Foundation.generate_links(page_list, "custom-class") rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup diff --git a/test/kerosene/html/semantic_test.exs b/test/kerosene/html/semantic_test.exs index d672593..44f2ca8 100644 --- a/test/kerosene/html/semantic_test.exs +++ b/test/kerosene/html/semantic_test.exs @@ -5,58 +5,58 @@ defmodule Kerosene.HTML.SemanticTest do alias Kerosene.HTML.Semantic test "renders Semantic pagination markup" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Semantic.generate_links(page_list, nil) + safe_html_tree = Semantic.generate_links(page_list, nil) rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup end test "renders Semantic pagination markup with additonal class" do - page_list = PaginatorData.page_list + page_list = PaginatorData.page_list() valid_html_markup = """ - \ - """ + \ + """ - safe_html_tree = Semantic.generate_links(page_list, "custom-class") + safe_html_tree = Semantic.generate_links(page_list, "custom-class") rendered_pagination = Phoenix.HTML.safe_to_string(safe_html_tree) assert rendered_pagination == valid_html_markup diff --git a/test/kerosene_test.exs b/test/kerosene_test.exs index 51189e2..13eeb99 100644 --- a/test/kerosene_test.exs +++ b/test/kerosene_test.exs @@ -10,24 +10,26 @@ defmodule KeroseneTest do defp create_products do for i <- 1..15 do - %Product { name: "Product " <> to_string(i), price: 100.00 } - |> Repo.insert! + %Product{name: "Product " <> to_string(i), price: 100.00} + |> Repo.insert!() end end test "offset works correctly" do create_products() {items, _kerosene} = Product |> Repo.paginate(%{"page" => 2}, per_page: 5) - items = items |> Enum.sort_by(&(&1.id)) |> Enum.map(&(&1.name)) + items = items |> Enum.sort_by(& &1.id) |> Enum.map(& &1.name) assert ["Product 6", "Product 7", "Product 8", "Product 9", "Product 10"] == items end test "non schema based queries" do create_products() + query = - from p in "products", - select: %{id: p.id, name: p.name} + from(p in "products", + select: %{id: p.id, name: p.name} + ) {_items, kerosene} = Repo.paginate(query, %{}) assert kerosene.total_count == 15 @@ -97,7 +99,10 @@ defmodule KeroseneTest do test "max_page constraint" do create_products() - {_items, kerosene} = Product |> Repo.paginate(%{"page" => 100}, total_count: 3, per_page: 5, max_page: 10) + + {_items, kerosene} = + Product |> Repo.paginate(%{"page" => 100}, total_count: 3, per_page: 5, max_page: 10) + assert kerosene.total_count == 3 assert kerosene.total_pages == 1 assert kerosene.page == 1 diff --git a/test/paginator_test.exs b/test/paginator_test.exs index 7f26180..0144844 100644 --- a/test/paginator_test.exs +++ b/test/paginator_test.exs @@ -32,7 +32,7 @@ defmodule Kerosene.PaginatorTest do end test "build full abs url with params" do - params = [query: "foo", page: 2, per_page: 10, foo: [1,2]] + params = [query: "foo", page: 2, per_page: 10, foo: [1, 2]] conn = %{request_path: "http://localhost:4000/products"} expected = "http://localhost:4000/products?query=foo&page=2&per_page=10&foo[]=1&foo[]=2" assert build_url(conn, params) == expected diff --git a/test/support/product.ex b/test/support/product.ex index bc0bc80..2a3d9e2 100644 --- a/test/support/product.ex +++ b/test/support/product.ex @@ -1,10 +1,10 @@ -defmodule Kerosene.Product do - use Ecto.Schema - - schema "products" do - field :name, :string - field :price, :decimal - - timestamps() - end -end \ No newline at end of file +defmodule Kerosene.Product do + use Ecto.Schema + + schema "products" do + field(:name, :string) + field(:price, :decimal) + + timestamps() + end +end diff --git a/test/support/repo.ex b/test/support/repo.ex index 73a79d1..c54605f 100644 --- a/test/support/repo.ex +++ b/test/support/repo.ex @@ -1,6 +1,7 @@ -defmodule Kerosene.Repo do - use Ecto.Repo, - otp_app: :kerosene, - adapter: Ecto.Adapters.Postgres - use Kerosene, otp_app: :kerosene, per_page: 10 -end +defmodule Kerosene.Repo do + use Ecto.Repo, + otp_app: :kerosene, + adapter: Ecto.Adapters.Postgres + + use Kerosene, otp_app: :kerosene, per_page: 10 +end From 8467d87b1b14057eb971d75c7f83ef286573ccbb Mon Sep 17 00:00:00 2001 From: Max Strother Date: Wed, 1 Mar 2023 02:40:16 +0100 Subject: [PATCH 4/5] Bump Elixir requirement from 1.2 to 1.4 The application inference added in that version fixes all the warnings related to dependencies list and applications list :) --- mix.exs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mix.exs b/mix.exs index 92b0a4f..e3bcc4c 100644 --- a/mix.exs +++ b/mix.exs @@ -6,7 +6,7 @@ defmodule Kerosene.Mixfile do [ app: :kerosene, version: @version, - elixir: "~> 1.2", + elixir: "~> 1.4", elixirc_paths: path(Mix.env()), package: package(), build_embedded: Mix.env() == :prod, @@ -26,12 +26,9 @@ defmodule Kerosene.Mixfile do # # Type "mix help compile.app" for more information def application do - [applications: application(Mix.env())] + [extra_applications: [:logger]] end - defp application(:test), do: [:postgrex, :ecto, :logger] - defp application(_), do: [:logger] - # Dependencies can be Hex packages: # # {:mydep, "~> 0.3.0"} From 4eac3f5d842249caed65e2ba8d6c8b864bfb6f44 Mon Sep 17 00:00:00 2001 From: Max Strother Date: Wed, 1 Mar 2023 02:59:34 +0100 Subject: [PATCH 5/5] Release 0.10.0 --- CHANGELOG.md | 6 ++++++ README.md | 9 ++++++--- mix.exs | 8 ++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2202cb1..ac6db50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ## next * Don't require postgrex as a runtime dependency +## v0.10.0 (2023-03-01) +* Add support for `per_page` param +* Add `.formatter.exs` file and format the project +* Bump PhoenixHTML from 2.10.4 to 3.3.1 +* Bump required Elixir version from 1.2 to 1.4 + ## v0.4.0 (2016-10-01) * Bugfix handle list in query params diff --git a/README.md b/README.md index b4ef5d3..5a1ca02 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Pagination for Ecto and Phoenix. +This is a fork of the original [Kerosene](https://github.com/elixirdrops/kerosene), which seems to have been abandoned :( + +Another good fork to consider - [Dissolver](https://github.com/MorphicPro/dissolver)... or any of the other pagination libraries that came up since Kerosene was created! ## Installation @@ -10,7 +13,7 @@ The package is [available in Hex](https://hex.pm/packages/kerosene), the package Add kerosene to your list of dependencies in `mix.exs`: ```elixir def deps do - [{:kerosene, "~> 0.9.0"}] + [{:kerosene, "~> 0.10.0"}] end ``` @@ -18,7 +21,7 @@ Add Kerosene to your `repo.ex`: ```elixir defmodule MyApp.Repo do use Ecto.Repo, - otp_app: :testapp, + otp_app: :my_app, adapter: Ecto.Adapters.Postgres use Kerosene, per_page: 2 end @@ -50,7 +53,7 @@ Generate the links using the view helpers <%= paginate @conn, @kerosene %> ``` -Kerosene provides a [list ](https://hexdocs.pm/kerosene/Kerosene.HTML.html#__using__/1) of themes for pagination. By default it uses bootstrap. To use some other, add to config/config.exs: +Kerosene provides a [list](https://hexdocs.pm/kerosene/Kerosene.HTML.html#__using__/1) of themes for pagination. By default it uses bootstrap. To use some other, add to config/config.exs: ```elixir config :kerosene, theme: :foundation diff --git a/mix.exs b/mix.exs index e3bcc4c..8f18d27 100644 --- a/mix.exs +++ b/mix.exs @@ -1,6 +1,6 @@ defmodule Kerosene.Mixfile do use Mix.Project - @version "0.9.0" + @version "0.10.0" def project do [ @@ -15,7 +15,7 @@ defmodule Kerosene.Mixfile do aliases: aliases(), name: "Kerosene", docs: [source_ref: "v#{@version}", main: "Kerosene"], - source_url: "https://github.com/elixirdrops/kerosene", + source_url: "https://github.com/mdlkxzmcp/kerosene", description: """ Pagination for Ecto and Phoenix. """ @@ -61,9 +61,9 @@ defmodule Kerosene.Mixfile do defp package do [ - maintainers: ["Ally Raza"], + maintainers: ["Ally Raza", "Max Strother"], licenses: ["MIT"], - links: %{github: "https://github.com/elixirdrops/kerosene"}, + links: %{github: "https://github.com/mdlkxzmcp/kerosene"}, files: ~w(lib test config) ++ ~w(CHANGELOG.md LICENSE.md mix.exs README.md)