Skip to content
/ mandarin Public

Admin generators (and utilities) for phoenix + ecto

Notifications You must be signed in to change notification settings

tmbb/mandarin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mandarin

CRUD Generators for Phoenix applications suitable for both admin and user-facing pages with integrated real-time UI updates.

Installation

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 can be found be found at https://hexdocs.pm/mandarin.

Dependencies

Mandarin doesn't have any code that runs at runtime. Instead, it generates code inside your project. However, code generated by Mandarin depends on a number of external packages, which do ship code that runs at runtime:

  • bootstrap5components - a replacement for the default CoreComponents module generated by the Phoenix generators. While bootstrap5components was developped in order to be compatible with Mandarin, it is an independent project and can be used in applications that weren't generated with the Mandarin generators

  • flop and flop_phoenix - utilities to convert query parameters into Ecto queries to simplify filtering and pagination when listing resources

  • all the packages that code generated by the phx.gen.auth generator depends on (those dependencies are added automatically by Mandarin, though)

The code generated by Mandarin depends on a number of other packages, but those are already pulled in by the default Phoenix generators.

The Mandarin.Designer module

Designing a context and schemas with the default command-line phoenix generators is cumbersome and prone to mistakes. It's often better to encapsulate the context design in a script. The functions in this module allow you to carefully design a context and the relationships between schemas and then generate everything all at once (HTML, context, schema, routes, etc.) when you're ready.

If things don't turn out like you expect, you can revert all changes with the mandarin.gen.delete_context MyContext generator, which will remove all files and routes created by the Mandarin generators.

That way, you can prototype a context very quickly, and only commit to it when it's just perfect for your use case.

Quick Start - TODO

To showcase Mandarin, we will re-implement parts of a web app created by Pedro Gaspar to showcase his FlaskAppBuilder framework, which runs on top of the Python web framework Flask.

However, while the FlaskAppBuilder framework generates the web pages based on introspection of Python's classes representing the models in the database, Mandarin will generate actual code, including the Ecto schemas (which are the equivalent to the Python models). This means that Mandarin can't easily make use of already existing ecto schemas, unlike some alternatives like Backpex.

Questions regarding the package design

Why generators?

While I love macros, generators allow for better customization compared to macros. Elixir provides a way of overriding functions, which means one could actually implement the functionality using macros and have the user re-implement it by overriding the functions with custom code. However, it's easier to modify existing code than to write it by scratch, and for the purposes of generating a CRUD interface, where one would expect the need for some customization, having the code already written and only having to modify it is the best option in my opinion.

Why does it use a bootstrap template?

The bootstrap framework is quite extensible with custom themes, such as the Bootswatch themes that are included in the bootstrap5components package by default. It provides sane defaults for those who are not expert designers. And more importantly, I hate tailwind with a passion.

However, it should be easy to use Mandarin with an alternative CSS framework as long as you re-implement the functions in the bootstrap5components package.

I'm planning on creating a MandarinComponents behaviour so that users who want an alternative components module know what to implement.

Do we really need granular real-time UI updates for a CRUD view?

Probably not, but the performance impact will be quite low in small apps and it can help in the case where users are concurrently editing the same resource. It's simple enough that the implemention comes down to few lines of code and it's easy to remove from the generated code if the performance impact turns out to be significant.

Comparison to alternatives

Backpex

Backpex is a very interesting package, which I have been following quite closely. It can generate a CRUD inteface to any number of Ecto schemas without "poluting" the application with lots of code (unlike Mandarin which generates thousands of lines of code). The main problem with projects like Backpex is that one ends up wanting to customize some of the functionality, especially UI-related functionality. And in these cases, adding the appropriate extension points is not very easy: add too few and the project is not extensible enough; add too many and the project becomes really hard to maintain and even the user-code becomes somewhat of a mess. While I think that Backpex is good for a basic admin interface with good CRUD functionality, I don't think it can serve as a good basis for user-facing functionality.

If you're ok with using Phoenix generators, I guess you're probably ok with the idea of generating a CRUD interface which is actually more advanced (and in my opinion better designed) than the default CRUD interface provided by Phoenix.

Torch

Torch does something very similar to what Mandarin does. It uses generators to quickly dump the necessary code to get a CRUD interface up and running and which the user can customize later. I believe that the CRUD interface generated by Mandarin is better and just as easy to extend.

I think that choosing between Torch and Mandarin comes down to user-preference.

Quick Start

Roadmap

Basic functionality

The functionality provided by Mandarin is pretty much complete. Next releases should focus on bug fixing, performance improvements and adding tests to the generated code.

"Compatibility" with the default Phoenix generators

Mandarin will not be updated to keep up with newer versions of the Phoenix generators. This package should be viewed as an alternative to the default generators, not as an improvement. The default generators have made a couple choices I disagree with.

Use of CodeGen

In the future, Mandarin could make use of my code_gen package, which is already used by the bootstrap5components in order to generate less code by default (while allowing the user to pull in that code if needed). I'll keep that option open if anyone really wants it and will accept pull requests that make it possible.

About

Admin generators (and utilities) for phoenix + ecto

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages