Mandarin

Generators to help you write an admin interface for your Phoenix application.

Installation

If available in Hex, the package can be installed by adding mandarin to your list of dependencies in mix.exs:

def deps do
  [
    {:mandarin, "~> 0.1.0"}
  ]
end

Documentation and Examples

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/mandarin.

You can find a guide to an example admin interface at Backofice Demo.

File Layout

Instead of splitting the web-related files into different directories (one for controllers, one for views and one for templates), like Phoenix does by default, Mandarin groups your files into feature folders, as discussed here and here.

Essentially, instead of this:

🗀 hello_web
  🗀 controllers
      foo_controller.ex
      bar_controller.ex
      ...
  🗀 templates
    🗀 foo
        index.html.eex
        ...
    🗀 bar
        index.html.eex
        ...
  🗀 views
      foo_view.eex
      bar_view.eex
      ...

You have this:

🗀 hello_web
    🗀 foo
        foo_controller.ex
        foo_view.ex
        🗀 templates
            index.html.eex
            ...
    🗀 bar
        bar_controller.ex
        bar_view.ex
        🗀 templates
            index.html.eex
            ...

The main advantage of the new layout is that it puts everything close together and it makes it easier to customize the controller and the template at the same time. It also makes it easier to delete all files related to a resource if for some reason things are not exactly right. It keeps everything related to your admin interface in one place and draws a cleaner boundary between the admin interface and the rest of your application.

Mandarin Generators

Mandarin is based on generators. The generators work the same as the default phoenix phx.gen.html generator.

First, you must "install" mandarin into your application:

mix mandarin.install NewContext

The mandarin.install generator creates a new context in your application and adds the mandarin.ex file to your application. This file is similar to the YourApp.ex file generated by the phx.new generator. It contains a __using__/1 macro that allows you to use YourApp.Mandarin, :controller and use YourApp.Mandarin, :view.

After creating the new context, you can add new resources to it, using the mandarin.gen.html generator, which takes the same arguments as the Phoenix phx.gen.html generator. This will create an ecto schema inside your context, a database migration and a new controller with CRUD functionality.

Remember that Ecto allows two or more schemas to share the same database table. This means you can (and should!) have a one Ecto schema for the Admin interface

Because the Admin interface is just a context, you can have multiple admin interfaces in your application if you want. For example, you could have an admin interface for "normal" admins, with some limits on what they can do and some safeguards in place, and another interface for "superadmins", which can do literally everything to the database.

To do that, just generate different contexts:

mandarin.install LowLevelAdmin
mandarin.install SuperAdmin

The mandarin.gen.html works just like the normal Phoenix generators:

mix mandarin.gen.html Admin Employee employees \
  full_name:string address:string fiscal_number:string \
  department:references:departments function:references:functions \
  begin_date:date end_date:date --binary-id

For a hands-on guide on how to use the generators, see here.

Forage

The pages generated by Mandarin sit on top of functionality provided by the Forage package. Forage is a helper package containing HTML widgets and functions to dynamically create Ecto queries from query parameters. This allows mandarin to support pagingation and filtering of resources. Forage isn't wey well documented and tested yet, but it works pretty well together with Mandarin.

Contributing

Interested people can contribute to Mandarin through one of the following:

  • Reporting bugs - the GitHub issue tracker is currently the best place for that
  • Fixing new bugs
  • Suggesting improvements - again, by using the GitHub issue tracker

The following should be considered out of scope for Mandarin for the foreseeable future:

  • Replacing the code generators with macros, schema reflection or other kinds of metaprogramming (you already have Kaffy for that)