Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

autoforme

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

autoforme

  • 1.13.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

= AutoForme

AutoForme is an administrative web front end to an ORM that uses Forme [1] for building the HTML forms. It is designed to integrate easily into web frameworks, and currently supports Roda, Sinatra, and Rails. The only currently supported ORM is Sequel::Model.

  1. https://github.com/jeremyevans/forme

= Installation

gem install autoforme

= Links

Demo Site :: http://autoforme-demo.jeremyevans.net RDoc :: http://autoforme.jeremyevans.net Source :: https://github.com/jeremyevans/autoforme Discussion Forum :: https://github.com/jeremyevans/autoforme/discussions Bug Tracker :: https://github.com/jeremyevans/autoforme/issues

= Features

  • Create, update, edit, and view model objects
  • Browse and search model objects
  • Edit many-to-many relationships for model objects
  • Easily access associated objects
  • Support autocompletion for all objects
  • Allow customization for all likely configuration points, using any parameters available in the request

= Basic Configuration

AutoForme is configured using a fairly simple DSL. Here is an example for Sinatra:

class App < Sinatra::Base AutoForme.for(:sinatra, self) do order [:name]

  model Artist do
    columns [:name]
  end
  model Album do
    columns [:artist, :name]
  end
end

end

Let's break down how this works. You setup AutoForme using AutoForme.for, which takes 2 arguments, the controller type symbol (currently either :sinatra, :roda, or :rails), and the controller class (either a Sinatra::Base, Roda, or ActionController::Base subclass). You pass AutoForme.for a block, which is instance evaled at the framework level. This level sets the defaults.

The order call in the framework block sets the default order for all models.

The model calls in the framework block take a ORM model class. As only Sequel is currently supported, this should be a Sequel::Model subclass. The block passed to the model method is instance evaled at the model level, and sets the configuration for that model. In this example, the Artist model will only show the name column, and the Album model will only show the artist association and the name column.

In your application, you can then to go '/Artist/browse' or '/Album/browse' to get to the web UI exposed to AutoForme.

= Design

== Principles

  • Use Forme to generate the forms
  • Do not modify/extend model or controller classes
  • Assume that the web framework provides the layout
  • Do not use templates, render form objects to strings
  • Use a block-based DSL in the controller for configuration
  • Allow customization on a per-request basis for everything

== Basic Implementation

The web framework controllers call AutoForme.for to create AutoForme::Framework instances, which contain and set default values for AutoForme::Model instances.

When a request comes in from the web framework, the AutoForme::Framework instance wraps request-level data in a AutoForme::Request. Then it creates an AutoForme::Action to handle this request. The AutoForme::Action either returns a string that the web framework then renders, or it redirects to another page.

= Advanced Configuration

AutoForme doesn't have all that many features compared to other admin frameworks, but the features it does have are extremely flexible.

Most of the configuration you'll do in AutoForme is at the model level (in the context of an AutoForme::Model instance), so we'll start looking at the customization options there. The most common options are probably:

columns :: This is an array of column/association name symbols to use for the model. column_options :: This is a hash of column options for the model, keyed by column symbol, with values that are hashes of column options. order :: This is an expression or an array of expressions by which to order returned rows.

Note that for each of the customization options, you can do per-request customization by using a proc which is called with the type symbol and request (AutoForme::Request instance), which should return an appropriate object.

columns :: Proc called with type symbol and request, should return array of column/association symbols column_options :: Proc called with column/association symbol, type symbol and request, should return hash of column options. order :: Proc called with type symbol and request, should return expression or array of expressions by which to order returned rows.

Below is brief description of other available options. Note that just like the above options you can use Procs with most of these options to do customization on a per-request basis.

association_links :: Array of association symbols for associations to display on the show/edit pages, can also be set to :all for all associations or :all_except_mtm for all associations except many to many associations. autocomplete_options :: Enable autocompletion for this model, with the given options. The following keys are respected: :callback :: Proc called with dataset and options hash containing :type, :request, and :query :display :: A SQL expression to search on and display in the result :limit :: The number of results to return :filter :: Similar to callback, but overriding the default filter (a case insensitive substring search on display) eager :: Array of associations to eagerly load in separate queries eager_graph :: Array of associations to eager load in the same query (necessary if order or filter refers to them) filter :: A Proc called with a dataset, type symbol, and request that can be used to filter the available rows. Can be used to implement access control. redirect :: A Proc called with an object, type symbol, and request that can be used to override the default redirecting after form submittal. inline_mtm_associations :: Array of many to many association symbols to allow editing on the edit page lazy_load_association_links :: Whether to show the association links directly on the show/edit pages, or to load them via ajax on request mtm_associations :: Array of many to many association symbols to support editing on a separate page per_page :: Number of records to show per page on the browse and search pages session_value :: Sets up a filter and before_create hook that makes it so access is limited to objects where the object's column value is the same as the session value with the same name. supported_actions :: Array of action symbols to support for the model, should be a subset of [:browse, :new, :show, :edit, :delete, :search, :mtm_edit]

These options are related to displayed output:

form_attributes :: Hash of attributes to use for any form tags form_options :: Hash of Forme::Form options to pass for any forms created class_display_name :: The string to use on pages when referring to the model class. This defaults to the full class name. display_name :: The string to use when referring to a model instance. Can either be a symbol representing an instance method call, or a Proc called with the model object, the model object and type symbol, or the model object, type symbol, and request, depending on the arity of the Proc. link_name :: The string to use in links for the class. This defaults to +class_display_name+. edit_html :: The html to use for a particular object edit field. Should be a proc that takes the model object, column symbol, type symbol, and request and returns the html to use. page_footer :: Override the default footer used for pages page_header :: Override the default header used for pages show_html :: The html to use for displaying the value for an object field. Should be a proc that takes the model object, column symbol, type symbol, and request and returns the html to use. table_class :: The html class string to use for the browse and search tables view_options :: Hash with options passed when rendering the view (how these options are used varies in each of the supported web frameworks), e.g. view_options: {:layout => :formelayout}

These hook options should be callable objects that are called with the model object and the request.

after_create :: Called after creating the object after_destroy :: Called after destroying the object after_update :: Called after updating the object before_create :: Called before creating the object before_destroy :: Called before destroy the object before_edit :: Called before displaying object on edit page before_new :: Called before displaying object on new page before_update :: Called before updating the object

There's also an addition before_action hook that is called with the type symbol of the request, and the request before every page.

In addition to being specified at the model level, almost all of these options can be specified at the framework level, where they operate as default values for models that don't specify the options. Just like the model level, the framework level also allows customization on a per request basis, though framework-level Procs generally take the model class as an initial argument (in addition to the type symbol and request).

Additionally, AutoForme.for accepts a :prefix option that controls where the forms are mounted:

AutoForme.for(:sinatra, self, :prefix=>'/path/to') do model Artist end

Means you can go to /path/to/Artist/browse to browse the artists.

= Javascript

By default, AutoForme requires no javascript. The only optional part of AutoForme that requires javascript is the autocompleting. AutoForme also has javascript support for the progressive enhancement of the following:

  • Loading association links via ajax if lazy_load_association_links is true.
  • Adding and removing many-to-many associated objects via ajax for inline_mtm_associations

AutoForme's javascript support is contained in the +autoforme.js+ file in the root of the repository. AutoForme's autocompleting support also requires https://github.com/Pixabay/JavaScript-autoComplete

Make sure to load the +autoforme.js+ file after the DOM content has been loaded, such as at the end of the body.

= Reloading Code

By default, AutoForme stores classes by reference. This can cause issues when using code reloading in development environments. You can call +register_by_name+ to set Autoforme to store classes by name, so that if a class is removed and reloaded (giving a new class reference), it will use the new class instead of the reference to the old class. Example:

class App < Sinatra::Base AutoForme.for(:sinatra, self) do register_by_name model Artist end end

= Rails

Because Rails separates routing from request handling, it can be little awkward to use AutoForme in Rails development mode. The best way to handle it is to call +AutoForme.for+ in the related controller file, and have an initializer reference the controller class, causing the controller file to be loaded.

= Roda

Because Roda uses a routing tree, unlike Rails and Sinatra, with Roda you need to dispatch to the autoforme routes at the point in the routing tree where you want to mount them. Additionally, the Roda support offers a Roda plugin for easier configuration.

To mount the autoforme routes in the root of the application, you could do:

class App < Roda plugin :autoforme do model Artist end

route do
  # rest of routing tree
  autoforme
end

end

To mount the routes in a subpath:

class App < Roda plugin :autoforme do model Artist end

route do
  r.on "admin" do
    autoforme
  end

  # rest of routing tree
end

end

To handle multiple autoforme configurations, mounted at different subpaths:

class App < Roda plugin :autoforme

autoforme(name: 'artists') do
  model Artist
end
autoforme(name: 'albums') do
  model Album
end

route do
  r.on "artists" do
    autoforme('artists')
  end
  r.on "albums" do
    autoforme('albums')
  end

  # rest of routing tree
end

end

= TODO

  • capybara-webkit tests for ajax behavior
  • read_only fields for edit page
  • one_to_many/many_to_many associations in columns
  • configurable searching
  • nested form objects

= License

MIT

= Author

Jeremy Evans code@jeremyevans.net

FAQs

Package last updated on 10 Jul 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc