{"id":13507986,"url":"https://github.com/smpallen99/ex_admin","last_synced_at":"2025-05-15T00:11:53.375Z","repository":{"id":32876399,"uuid":"36470617","full_name":"smpallen99/ex_admin","owner":"smpallen99","description":"ExAdmin is an auto administration package for Elixir and the Phoenix Framework","archived":false,"fork":false,"pushed_at":"2020-02-03T09:29:34.000Z","size":16831,"stargazers_count":1202,"open_issues_count":132,"forks_count":272,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-04-06T17:08:15.543Z","etag":null,"topics":["admin-dashboard","administration","elixir","hex","mix-tasks","package","phoenix-framework"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smpallen99.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-28T22:55:28.000Z","updated_at":"2025-03-25T01:03:29.000Z","dependencies_parsed_at":"2022-09-01T00:20:37.277Z","dependency_job_id":null,"html_url":"https://github.com/smpallen99/ex_admin","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smpallen99%2Fex_admin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smpallen99%2Fex_admin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smpallen99%2Fex_admin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smpallen99%2Fex_admin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smpallen99","download_url":"https://codeload.github.com/smpallen99/ex_admin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248782275,"owners_count":21160716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin-dashboard","administration","elixir","hex","mix-tasks","package","phoenix-framework"],"created_at":"2024-08-01T02:00:45.014Z","updated_at":"2025-04-13T20:42:40.251Z","avatar_url":"https://github.com/smpallen99.png","language":"Elixir","readme":"# ExAdmin\n\n[![Build Status][travis-img]][travis] [![Hex Version][hex-img]][hex] [![License][license-img]][license]\n\n[travis-img]: https://travis-ci.org/smpallen99/ex_admin.svg?branch=master\n[travis]: https://travis-ci.org/smpallen99/ex_admin\n[hex-img]: https://img.shields.io/hexpm/v/ex_admin.svg\n[hex]: https://hex.pm/packages/ex_admin\n[license-img]: http://img.shields.io/badge/license-MIT-brightgreen.svg\n[license]: http://opensource.org/licenses/MIT\n\nNote: This version has been updated to support both Ecto 1.1 and Ecto 2.0. See [Installation](#installation) for more information.\n\nExAdmin is an auto administration package for [Elixir](http://elixir-lang.org/) and the [Phoenix Framework](http://www.phoenixframework.org/), a port/inspiration of [ActiveAdmin](http://activeadmin.info/) for Ruby on Rails.\n\nCheckout the [Live Demo](http://demo.exadmin.info/admin). The source code can be found at [ExAdmin Demo](https://github.com/smpallen99/ex_admin_demo).\n\nCheckout this [Additional Live Demo](http://demo2.exadmin.info/admin) for examples of many-to-many relationships, nested attributes, and authentication.\n\nSee the [docs](https://hexdocs.pm/ex_admin/) and the [Wiki](https://github.com/smpallen99/ex_admin/wiki) for more information.\n\n## Usage\n\nExAdmin is an add on for an application using the [Phoenix Framework](http://www.phoenixframework.org) to create a CRUD administration tool with little or no code. By running a few mix tasks to define which Ecto Models you want to administer, you will have something that works with no additional code.\n\nBefore using ExAdmin, you will need a Phoenix project and an Ecto model created.\n\n![ExAdmin](http://exadmin.info/doc/ex_admin_blue.png)\n\n### Installation\n\nAdd ex_admin to your deps:\n\n#### Hex\n\nmix.exs\n```elixir\n  defp deps do\n     ...\n     {:ex_admin, \"~\u003e 0.8\"},\n     ...\n  end\n```\n\n#### GitHub with Ecto 2.0\n\nmix.exs\n```elixir\n  defp deps do\n     ...\n     {:ex_admin, github: \"smpallen99/ex_admin\"},\n     ...\n  end\n```\n\nAdd some admin configuration and the admin modules to the config file\n\nconfig/config.exs\n```elixir\nconfig :ex_admin,\n  repo: MyProject.Repo,\n  module: MyProject,    # MyProject.Web for phoenix \u003e= 1.3.0-rc \n  modules: [\n    MyProject.ExAdmin.Dashboard,\n  ]\n\n```\n\nFetch and compile the dependency\n\n```\nmix do deps.get, deps.compile\n```\n\nConfigure ExAdmin:\n\n```\nmix admin.install\n```\n\nAdd the admin routes\n\nweb/router.ex\n```elixir\ndefmodule MyProject.Router do\n  use MyProject.Web, :router\n  use ExAdmin.Router\n  ...\n  scope \"/\", MyProject do\n    ...\n  end\n\n  # setup the ExAdmin routes on /admin\n  scope \"/admin\", ExAdmin do\n    pipe_through :browser\n    admin_routes()\n  end\n```\n\nAdd the paging configuration\n\nlib/my_project/repo.ex\n```elixir\n  defmodule MyProject.Repo do\n    use Ecto.Repo, otp_app: :my_project\n    use Scrivener, page_size: 10\n  end\n\n```\n\nEdit your brunch-config.js file and follow the instructions that the installer appended to this file. This requires you copy 2 blocks and replace the existing blocks.\n\nStart the application with `iex -S mix phoenix.server`\n\nVisit http://localhost:4000/admin\n\nYou should see the default Dashboard page.\n\n## Getting Started\n\n### Adding an Ecto Model to ExAdmin\n\nTo add a model, use `admin.gen.resource` mix task:\n\n```\nmix admin.gen.resource MyModel\n```\n\nAdd the new module to the config file:\n\nconfig/config.exs\n\n```elixir\nconfig :ex_admin,\n  repo: MyProject.Repo,\n  module: MyProject,\n  modules: [\n    MyProject.ExAdmin.Dashboard,\n    MyProject.ExAdmin.MyModel,\n  ]\n```\n\nStart the phoenix server again and browse to `http://localhost:4000/admin/my_model`\n\nYou can now list/add/edit/and delete `MyModel`s.\n\n### Changesets\nExAdmin will use your schema's changesets. By default we call the `changeset` function on your schema, although you\ncan configure the changeset we use for update and create seperately.\n\ncustom changeset:\n```elixir\ndefmodule TestExAdmin.ExAdmin.Simple do\n  use ExAdmin.Register\n\n  register_resource TestExAdmin.Simple do\n    update_changeset :changeset_update\n    create_changeset :changeset_create\n  end\nend\n```\n\n#### Relationships\n\nWe support many-to-many and has many relationships as provided by Ecto. We recommend using cast_assoc for many-to-many relationships\nand put_assoc for has-many. You can see example changesets in our [test schemas](test/support/schema.exs)\n\nWhen passing in results from a form for relationships we do some coercing to make it easier to work with them in your changeset.\nFor collection checkboxes we will pass an array of the selected options ids to your changeset so you can get them and use put_assoc as [seen here](test/support/schema.exs#L26-L35)\n\nIn order to support has many deletions you need you to setup a virtual attribute on your schema's. On the related schema you will\nneed to add an _destroy virtual attribute so we can track the destroy property in the form. You will also need to cast this in your changeset. Here is an example changeset. In this scenario a User has many products and products can be deleted. We also have many roles associated.\n\n```elixir\ndefmodule TestExAdmin.User do\n  import Ecto.Changeset\n  use Ecto.Schema\n  import Ecto.Query\n\n  schema \"users\" do\n    field :name, :string\n    field :email, :string\n    field :active, :boolean, default: true\n    has_many :products, TestExAdmin.Product, on_replace: :delete\n    many_to_many :roles, TestExAdmin.Role, join_through: TestExAdmin.UserRole, on_replace: :delete\n  end\n\n  @fields ~w(name active email)\n\n  def changeset(model, params \\\\ %{}) do\n    model\n    |\u003e cast(params, @fields)\n    |\u003e validate_required([:email, :name])\n    |\u003e cast_assoc(:products, required: false)\n    |\u003e add_roles(params)\n  end\n\n  def add_roles(changeset, params) do\n    if Enum.count(Map.get(params, :roles, [])) \u003e 0 do\n      ids = params[:roles]\n      roles = TestExAdmin.Repo.all(from r in TestExAdmin.Role, where: r.id in ^ids)\n      put_assoc(changeset, :roles, roles)\n    else\n      changeset\n    end\n  end\nend\n\ndefmodule TestExAdmin.Role do\n  use Ecto.Schema\n  import Ecto.Changeset\n  alias TestExAdmin.Repo\n\n  schema \"roles\" do\n    field :name, :string\n    has_many :uses_roles, TestExAdmin.UserRole\n    many_to_many :users, TestExAdmin.User, join_through: TestExAdmin.UserRole\n  end\n\n  @fields ~w(name)\n\n  def changeset(model, params \\\\ %{}) do\n    model\n    |\u003e cast(params, @fields)\n  end\nend\n\n\ndefmodule TestExAdmin.Product do\n  use Ecto.Schema\n  import Ecto.Changeset\n\n  schema \"products\" do\n    field :_destroy, :boolean, virtual: true\n    field :title, :string\n    field :price, :decimal\n    belongs_to :user, TestExAdmin.User\n  end\n\n  def changeset(schema, params \\\\ %{}) do\n    schema\n    |\u003e cast(params, ~w(title price user_id))\n    |\u003e validate_required(~w(title price))\n    |\u003e mark_for_deletion\n  end\n\n  defp mark_for_deletion(changeset) do\n    # If delete was set and it is true, let's change the action\n    if get_change(changeset, :_destroy) do\n      %{changeset | action: :delete}\n    else\n      changeset\n    end\n  end\nend\n```\n\nA good blog post exisits on the Platformatec blog describing how these relationships work: http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/\n\n### Customizing the index page\n\nUse the `index do` command to define the fields to be displayed.\n\nadmin/my_model.ex\n```elixir\ndefmodule MyProject.ExAdmin.MyModel do\n  use ExAdmin.Register\n  register_resource MyProject.MyModel do\n\n    index do\n      selectable_column()\n\n      column :id\n      column :name\n      actions()     # display the default actions column\n    end\n  end\nend\n```\n\n### Customizing the form\n\nThe following example shows how to customize the form with the `form` macro:\n\n```elixir\ndefmodule MyProject.ExAdmin.Contact do\n  use ExAdmin.Register\n\n  register_resource MyProject.Contact do\n    form contact do\n      inputs do\n        input contact, :first_name\n        input contact, :last_name\n        input contact, :email\n        input contact, :register_date, type: Date # if you use Ecto :date type in your schema\n        input contact, :category, collection: MyProject.Category.all\n      end\n\n      inputs \"Groups\" do\n        inputs :groups, as: :check_boxes, collection: MyProject.Group.all\n      end\n    end\n  end\nend\n```\n\n### Customizing the show page\n\nThe following example illustrates how to modify the show page.\n\n```elixir\ndefmodule MyProject.ExAdmin.Question do\n  use ExAdmin.Register\n\n  register_resource MyProject.Question do\n    menu priority: 3\n\n    show question do\n\n      attributes_table   # display the defaults attributes\n\n      # create a panel to list the question's choices\n      panel \"Choices\" do\n        table_for(question.choices) do\n          column :key\n          column :name\n        end\n      end\n    end\n  end\nend\n```\n## Custom Types\n\nSupport for custom field types is done in two areas, rendering fields, and input controls.\n\n### Rendering Custom Types\n\nUse the `ExAdmin.Render.to_string/` protocol for rendering types that are not supported by ExAdmin.\n\nFor example, to support rendering a tuple, add the following file to your project:\n\n```elixir\n# lib/render.ex\ndefimpl ExAdmin.Render, for: Tuple do\n  def to_string(tuple), do: inspect(tuple)\nend\n```\n\n### Input Type\n\nUse the `:field_type_matching` config item to set the input type.\n\nFor example, given the following project:\n\n```elixir\ndefmodule ElixirLangMoscow.SpeakerSlug do\n  use EctoAutoslugField.Slug, from: [:name, :company], to: :slug\nend\n\ndefmodule ElixirLangMoscow.Speaker do\n  use ElixirLangMoscow.Web, :model\n  use Arc.Ecto.Model\n\n  alias ElixirLangMoscow.SpeakerSlug\n  schema \"speakers\" do\n    field :slug, SpeakerSlug.Type\n    field :avatar, ElixirLangMoscow.Avatar.Type\n  end\nend\n```\n\nAdd the following to your project's configuration:\n\n```elixir\nconfig :ex_admin,\n  # ...\n  field_type_matching: %{\n    ElixirLangMoscow.SpeakerSlug.Type =\u003e :string,\n    ElixirLangMoscow.Avatar.Type =\u003e :file\n  }\n```\n\n## Theme Support\n\nExAdmin supports 2 themes. The new AdminLte2 theme is enabled by default. The old ActiveAdmin theme is also supported for those that want backward compatibility.\n\n### Changing the Theme\n\nTo change the theme to ActiveAdmin, at the following to your `config/config.exs` file:\n\nconfig/config.exs\n```elixir\nconfig :ex_admin,\n  theme: ExAdmin.Theme.ActiveAdmin,\n  ...\n```\n\n### Changing the AdminLte2 Skin Color\n\nThe AdminLte2 theme has a number of different skin colors including blue, black, purple, green, red, yellow, blue-light, black-light, purple-light, green-light, red-light, and yellow-light\n\nTo change the skin color to, for example, purple:\n\nconfig/config.exs\n```elixir\nconfig :ex_admin,\n  skin_color: :purple,\n  ...\n```\n\n### Enable Theme Selector\n\nYou can add a theme selector on the top right of the menu bar by adding the following to your `config/config.exs` file:\n\nconfig/config.exs\n```elixir\nconfig :ex_admin,\n  theme_selector: [\n    {\"AdminLte\",  ExAdmin.Theme.AdminLte2},\n    {\"ActiveAdmin\", ExAdmin.Theme.ActiveAdmin}\n  ],\n  ...\n```\n\n### Overriding the model name\n\nYou can override the name of a model by defining a `model_name/0` function on\nthe module. This is useful if you want to use a different module for some of\nyour actions.\n\nadmin/my_model.ex\n```elixir\ndef model_name do\n  \"custom_name\"\nend\n```\n\n## Authentication\n\nExAdmin leaves the job of authentication to 3rd party packages. For an example of using [Coherence](https://github.com/smpallen99/coherence) checkout the [Contact Demo Project](https://github.com/smpallen99/contact_demo).\n\nVisit the [Wiki](https://github.com/smpallen99/ex_admin/wiki/Add-authentication) for more information on adding Authentication.\n\n## Contributing\n\nWe appreciate any contribution to ExAdmin. Check our [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) and [CONTRIBUTING.md](CONTRIBUTING.md) guides for more information. We usually keep a list of features and bugs [in the issue tracker][1].\n\n## References\n\n* Detailed Example [ExAdmin Demo](https://github.com/smpallen99/ex_admin_demo)\n* For a brief tutorial, please visit [Elixir Survey Tutorial](https://github.com/smpallen99/elixir_survey_tutorial)\n* [Live Demo](http://demo.exadmin.info/admin)\n* [Docs](https://hexdocs.pm/ex_admin/)\n\n  [1]: https://github.com/smpallen99/ex_admin/issues\n  [2]: http://groups.google.com/group/exadmin-talk\n\n## License\n\n`ex_admin` is Copyright (c) 2015-2016 E-MetroTel\n\nThe source code is released under the MIT License.\n\nCheck [LICENSE](LICENSE) for more information.\n","funding_links":[],"categories":["Framework Components","Elixir","\u003ca name=\"Elixir\"\u003e\u003c/a\u003eElixir"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmpallen99%2Fex_admin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmpallen99%2Fex_admin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmpallen99%2Fex_admin/lists"}