Giter VIP home page Giter VIP logo

ez-engines / ez-settings Goto Github PK

View Code? Open in Web Editor NEW
9.0 5.0 7.0 133 KB

Ez Settings (read as "easy settings") - one of the ez-engines collection that helps easily add settings interface to your Rails application.

Home Page: https://github.com/ez-engines

License: MIT License

Ruby 88.91% JavaScript 1.99% CSS 1.51% HTML 5.79% Slim 1.80%
rails engines rails-engine component modular easy

ez-settings's Introduction

Ez::Settings

Gem Version Build Status

Ez Settings (read as "easy settings") - one of the ez-engines collection that helps easily add settings interface to your Rails application.

  • Flexible tool with simple DSL
  • Convetion over configuration principles.
  • Depends on ez-core

Installation

Add this line to your application's Gemfile:

gem 'ez-settings', '~> 0.1'

And then execute:

$ bundle

Or install it yourself as:

$ gem install ez-settings

and bundle install

Initialize

rails generate ez:settings:install

Generates initializer config file and I18n yaml file with english keys

config/initializers/ez_settings.rb

# By default engine try to inherit from ApplicationController, but you could change this:
# Ez::Settings.config.base_controller = 'Admin::BaseController'
#
# Then you should define settings interfaces (you can create as much as you need)
# Ierachy is pretty simple: Interface -> Group -> Key
#
# Interface DSL allows you to do this very declaratively
#
app = Ez::Settings::Interface.define :app do         # :app - interface name
  group :general do                                  # :general - name of the group
    key :app_title, default: -> { 'Main app title' } # :app_title - key name for store value in :general group for :app interface
  end

  # And so on...
  group :admin do
    key :app_title, default: -> { 'Admin app title' }
  end

  # If you want to see all power of the engine, add this showcase:
  group :showcase, on_change: ->(changes) { YourHandler.call(changes) } do
    key :string,                        default: -> { 'simple string' }
    key :bool,         type: :boolean,  default: -> { true }
    key :integer,      type: :integer,  default: -> { 777 }, min: 0, suffix: 'USD', wrapper: :custom_wrapper
    key :select,       type: :select,   default: -> { 'foo' }, collection: %w(foo bar baz)
    key :not_validate, required: false, presence: false
    key :not_for_ui,   required: false, ui:       false
  end
  # Group could have:
  # :on_change - closure to call after the group is changed
  # Keys could have:
  # :type (string by default), now ez-settings supports only: string, boolean, integer and select
  # :default value (as callable objects)
  # :required - be or not (all keys are required by default)
  # :ui visible or not (all keys are UI visible by default)
  # :min - the minimum value for the element
  # :suffix - unit of measurement
  # :wrapper - custom wrapper for simple_form
end

# After defining settings interface groups/keys you need to configure it:
app.configure do |config|
  # Backend adapter to store all settings
  config.backend = Ez::Settings::Backend::ActiveRecord.new
  # and DB table name that you can change as well
  # config.active_record_table_name = :ez_settings_store

  # YAML filesystem
  # config.backend = Ez::Settings::Backend::FileSystem.new(Rails.root.join('config', 'settings.yml'))

  # Redis
  # require 'redis'
  # config.backend = Ez::Settings::Backend::Redis.new(Redis.current, namespace: 'myapp')

  # Default path for redirect in the settings controller
  config.default_path = '/admin/settings'

  # Pass your custom css classes through css_map config
  # Defaults would be merged with yours:
  # config.custom_css_map  = {
  #   nav_label:                           'ez-settings-nav-label',
  #   nav_menu:                            'ez-settings-nav-menu',
  #   nav_menu_item:                       'ez-settings-nav-menu-item',
  #   overview_page_wrapper:               'ez-settings-overview',
  #   overview_page_section:               'ez-settings-overview-section',
  #   overview_page_section_header:        'ez-settings-overview-section-header',
  #   overview_page_section_content:       'ez-settings-overview-section-content',
  #   overview_page_section_content_key:   'ez-settings-overview-section-content-key',
  #   overview_page_section_content_value: 'ez-settings-overview-section-content-value',
  #   group_page_wrapper:                  'ez-settings-group-wrapper',
  #   group_page_inner_wrapper:            'ez-settings-group-inner-wrapper',
  #   group_page_header:                   'ez-settings-group-header',
  #   group_page_form_wrapper:             'ez-settings-group-form-wrapper',
  #   group_page_form_inner:               'ez-settings-group-form-inner',
  #   group_page_form_field_row:           'ez-settings-group-form-field-row',
  #   group_page_form_string_wrapper:      'ez-settings-group-form-string-wrapper',
  #   group_page_form_boolean_wrapper:     'ez-settings-group-form-boolean-wrapper',
  #   group_page_form_select_wrapper:      'ez-settings-group-form-select-wrapper',
  #   group_page_actions_wrapper:          'ez-settings-group-actions-wrapper',
  #   group_page_actions_save_button:      'ez-settings-group-actions-save-btn',
  #   group_page_actions_cancel_link:      'ez-settings-group-actions-cancel-link'
  # }
  #
  # Highly recommend inspecting settings page DOM.
  # You can find there a lot of interesting id/class stuff
  #
  # You even can define dynamic map for allows to decide which CSS class could be added
  # `if` must contain callable object that receives controller as a first argument and dynamic element as second one:
  #
  # In this example, you easily could add 'active' CSS class if route end with some fragment:
  # config.dynamic_css_map = {
  #   nav_menu_item: {
  #     css_class: 'active',
  #     if: ->(controller, path_fragment) { controller.request.path.end_with?(path_fragment.to_s) }
  #   }
  # }
end

# Ez::Settings uses Ez::Registry from ez-core lib for storing all knowledges in one place.
# This place is registry records for :settings_interfaces registry
#
# Register `app` variable as settings interface
Ez::Registry.in(:settings_interfaces, by: 'YourAppName') do |registry|
  registry.add app
end

Database storage as backend (ActiveRecord)

You can use migrations generator

rails generate ez:settings:active_record_migrations

Generates migration for ez_settings_store table.

rails db:migrate

Routes

config/routes.rb

Rails.application.routes.draw do
  # your routes code before

  # We recommend to hide settings into admin area
  authenticate :user, ->(u) { u.admin? } do
    namespace :admin do
      # :app just interface name as you registred it in Ez::Registry
      ez_settings_for :app
    end
  end

  # more your routes after
end

This routes setup allows you to have routes like:

rake routes | grep settings

 admin_ez_settings          /admin/settings  Ez::Settings::Engine {:interface=>:app}

  root GET  /                 ez/settings/settings#index
       GET  /:group(.:format) ez/settings/settings#show
       PUT  /:group(.:format) ez/settings/settings#update

In case of example above you could route:

GET      /admin/settings/         - overview page for all :app interface settings
GET/PUT: /admin/settings/general  - general group settings
GET/PUT: /admin/settings/admin    - admin group settings
GET/PUT: /admin/settings/showcase - showcase group settings

Settings accessors

To access your settings use template Ez::Settings['interface', 'group', 'key'].

Access interface:

Ez::Settings[:app]
#=> <Ez::Settings::Interface:0x007ff1ea7d3168 @groups=[...], @keys=[], @name=:app>

Access group:

Ez::Settings[:app, :general]
#=> <Ez::Settings::Interface::Group:0x007ff1ea7d2f88 @interface=:app, @keys=[...], @name=:general, @options={}>

Access setting value:

Ez::Settings[:app, :general, :app_title]
# => 'Main app title'

In the case of missing interface/group/key you will receive one of exceptions:

NotRegistredInterfaceError
NotRegistredGroupError
NotRegistredKeyError

Be careful ;)

I18n

By default, all interfaces/groups/keys name would be humanized, but in fact, it tries to get translations from YAML first.

If you need, create locale file with this structure:

config/locales/ez-settings.en.yml

  en:
    ez_settings:
      label: Ez Settings
      interfaces:
        app:
          label: App Settings
          actions:
            save:
              label: Save Settings
            cancel:
              label: Cancel Settings
          groups:
            general:
              label: General
              description: General settings of your application
            admin:
              label: Admin
              description: Admin area settings
            showcase:
              label: Showcase
              description: Just an example of possible settings UI elements
              keys:
                string:
                  label: String
                bool:
                  label: Bool
                integer:
                  label: Integer
                select:
                  label: Select
                not_validate:
                  label: Not Validate
                not_for_ui:
                  label: Not For UI

TODO

This features will be implemented in upcoming 0.2 and 0.3 releases:

  • [] JSON API endpoints and ez_settings_api_for routes helper
  • [] Scoped settings (:scope_id, :scope_type)
  • [] Controller before actions as configured callbacks (for external usage)
  • [] Interface description (and show at UI)
  • [] Groups description (and show at UI)
  • [] Keys description (and show at UI)
  • [] Database storage as backend (ActiveRecord)
  • [] Backend#read method should receive app, group & key attributes and avoid loading all in case of SQL adapter
  • [] UI frameworks adapters: bootsrap3, bootstrap4, foundation, semantic, etc.
  • Bug: Read only defaul values if ActiveRecord do not ready yet (migrations)

Contributing

Fork => Fix => MR warmly welcomed!

License

The gem is available as open source under the terms of the MIT License.

ez-settings's People

Contributors

ayaremchuk avatar mmelnych avatar nadiyaka avatar sveredyuk avatar vergilet avatar vlasiak avatar vovchynniko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ez-settings's Issues

JSON API endpoints

In case of not using UI add json api endpoints for front-end apps

  • configuration
  • improve routes helpers ez_settings_for :app, only: [:html, json]
  • Add controller for JSON
  • README

Rails generator

rails g ez:settings:install should create config/ez_settings.rb and config/locales/ez-settings.en.yml

Supported ruby versions

Hello,

Thank you for your ez-settings. It's very handy.

Could you add supported ruby versions and implementations in the README?

Thank you :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.