module Alchemy
Provides authentication accessors.
Alchemy
has some defaults for user model name and login logout path names:
Alchemy.user_class_name
defaults to +‘User’+ Alchemy.user_class_primary_key
defaults to :id
+Alchemy.current_user_method defaults to +‘current_user’+ +Alchemy.signup_path defaults to +‘/signup’+ +Alchemy.login_path defaults to +‘/login’+ +Alchemy.logout_path defaults to +‘/logout’+ +Alchemy.logout_method defaults to +‘delete’+ +Alchemy.unauthorized_path defaults to +‘/’+
Anyway, you can tell Alchemy
about your authentication model configuration:
1. Your user class name - @see: Alchemy.user_class 2. Your users table primary key - @see: Alchemy.user_class_primary_key 3. A method on your ApplicationController to get current user - @see: Alchemy.current_user_method 4. The path to the signup form - @see: Alchemy.signup_path 5. The path to the login form - @see: Alchemy.login_path 6. The path to the logout method - @see: Alchemy.logout_path 7. The http verb for the logout method - @see: Alchemy.logout_method 8. The path to the page showing the user she's unauthorized - @see: Alchemy.unauthorized_path
Example¶ ↑
# config/initializers/alchemy.rb Alchemy.user_class_name = 'Admin' Alchemy.user_class_primary_key = :user_id Alchemy.current_user_method = 'current_admin' Alchemy.signup_path = '/auth/signup' Alchemy.login_path = '/auth/login' Alchemy.logout_path = '/auth/logout' Alchemy.logout_method = 'get' Alchemy.unauthorized_path = '/home'
If you don’t have your own user model or don’t want to provide one, add the ‘alchemy-devise` gem into your App’s Gemfile.
Adding your own CanCan abilities¶ ↑
If your app or your engine has own CanCan abilities you must register them:
Alchemy.register_ability MyCustom::Ability
Custom error classes.
Provides admin interface routing configuration accessors.
Alchemy
has some defaults for admin path and admin constraints:
+Alchemy.admin_path defaults to +‘admin’+ +Alchemy.admin_constraints defaults to +{}+
Anyway, you can tell Alchemy
about your routing configuration:
1. The path to the admin panel - @see: Alchemy.admin_path 2. The constraints for the admin panel (like subdomain) - @see: Alchemy.admin_constraints
A word of caution: you need to know what you are doing if you set admin_path to ”. This can cause routing name clashes, e.g. a page named ‘dashboard’ will clash with the Alchemy
dashboard.
Example¶ ↑
If you do not wish to use the default admin interface routing (‘example.com/admin’) and prefer e.g. ‘hidden.example.com/backend’, those are the settings you need:
# config/initializers/alchemy.rb Alchemy.admin_path = 'backend' Alchemy.admin_constraints = {subdomain: 'hidden'}
Constants
- Deprecation
- LOOKUP_CONTEXT
- VERSION
- YAML_PERMITTED_CLASSES
Attributes
Public Class Methods
Additional importmaps to be included in the Alchemy
admin UI
Be sure to also pin modules with Alchemy.importmap
.
Example¶ ↑
# config/alchemy/importmap.rb Alchemy.importmap.pin "alchemy_solidus", to: "alchemy_solidus.js", preload: true Alchemy.importmap.pin_all_from Alchemy::Solidus::Engine.root.join("app/javascript/alchemy_solidus"), under: "alchemy_solidus", preload: true # lib/alchemy/solidus/engine.rb initializer "alchemy_solidus.assets", before: "alchemy.importmap" do |app| Alchemy.admin_importmaps.add({ importmap_path: root.join("config/importmap.rb"), source_paths: [ root.join("app/javascript") ], name: "alchemy_solidus" }) app.config.assets.precompile << "alchemy_solidus/manifest.js" end
@return [Set<Hash>]
# File lib/alchemy.rb, line 90 def self.admin_importmaps @_admin_importmaps ||= Set.new([{ importmap_path: Engine.root.join("config/importmap.rb"), source_paths: [ Engine.root.join("app/javascript"), Engine.root.join("vendor/javascript") ], name: "alchemy_admin" }]) end
Additional JS modules to be imported in the Alchemy
admin UI
Be sure to also pin the modules with Alchemy.importmap
.
Example¶ ↑
Alchemy.importmap.pin "flatpickr/de", to: "https://ga.jspm.io/npm:flatpickr@4.6.13/dist/l10n/de.js" Alchemy.admin_js_imports << "flatpickr/de"
# File lib/alchemy.rb, line 57 def self.admin_js_imports @_admin_js_imports ||= Set.new end
# File lib/alchemy.rb, line 61 def self.admin_js_imports=(sources) @_admin_js_imports = Set[sources] end
# File lib/alchemy/version.rb, line 10 def self.gem_version Gem::Version.new(VERSION) end
Configure tabs in the link dialog
With this configuration that tabs in the link dialog can be extended without overwriting or defacing the Admin
Interface.
Example¶ ↑
# components/acme/link_tab.rb module Acme class LinkTab < ::Alchemy::Admin::LinkDialog::BaseTab def title "Awesome Tab Title" end def name :unique_name end def fields [ title_input, target_select ] end end end # config/initializers/alchemy.rb Alchemy.link_dialog_tabs << Acme::LinkTab
# File lib/alchemy.rb, line 169 def self.link_dialog_tabs @_link_dialog_tabs ||= Set.new([ Alchemy::Admin::LinkDialog::InternalTab, Alchemy::Admin::LinkDialog::AnchorTab, Alchemy::Admin::LinkDialog::ExternalTab, Alchemy::Admin::LinkDialog::FileTab ]) end
Define page preview sources
A preview source is a Ruby class returning an URL that is used as source for the preview frame in the admin UI.
Example¶ ↑
# lib/acme/preview_source.rb class Acme::PreviewSource < Alchemy::Admin::PreviewUrl def url_for(page) if page.site.name == "Next" "https://user:#{ENV['PREVIEW_HTTP_PASS']}@next.acme.com" else "https://www.acme.com" end end end # config/initializers/alchemy.rb require "acme/preview_source" Alchemy.preview_sources << Acme::PreviewSource # config/locales/de.yml de: activemodel: models: acme/preview_source: Acme Vorschau
# File lib/alchemy.rb, line 38 def self.preview_sources @_preview_sources ||= Set.new << Alchemy::Admin::PreviewUrl end
# File lib/alchemy.rb, line 42 def self.preview_sources=(sources) @_preview_sources = Array(sources) end
Define page publish targets
A publish target is a ActiveJob that gets performed whenever a user clicks the publish page button.
Use this to trigger deployment hooks of external services in an asychronous way.
Example¶ ↑
# app/jobs/publish_job.rb class PublishJob < ApplicationJob def perform(page) RestClient.post(ENV['BUILD_HOOK_URL']) end end # config/initializers/alchemy.rb Alchemy.publish_targets << PublishJob
# File lib/alchemy.rb, line 121 def self.publish_targets @_publish_targets ||= Set.new end
Register a CanCan Ability class
# File lib/alchemy/auth_accessors.rb, line 124 def self.register_ability(klass) @abilities ||= [] @abilities << klass end
All CanCan Ability classes registered to Alchemy
# File lib/alchemy/auth_accessors.rb, line 131 def self.registered_abilities @abilities ||= [] end
Alchemy
shortcut translation method
Instead of having to call:
Alchemy::I18n.translate(:hello)
You can use this shortcut method:
Alchemy.t(:hello)
# File lib/alchemy/i18n.rb, line 15 def t(msg, **kwargs) Alchemy::I18n.translate(msg, **kwargs) end
# File lib/alchemy/auth_accessors.rb, line 94 def self.user_class @@user_class ||= begin @@user_class_name.constantize rescue NameError => e if /#{Regexp.escape(@@user_class_name)}/.match?(e.message) Rails.logger.warn <<~MSG #{e.message} #{e.backtrace.join("\n")} AlchemyCMS cannot find any user class! Please add a user class and tell Alchemy about it: # config/initializers/alchemy.rb Alchemy.user_class_name = 'MyUser' Or add the `alchemy-devise` gem to your Gemfile: bundle add alchemy-devise MSG nil else raise e end end end
- Prefix with
-
when getting to avoid constant name conflicts
# File lib/alchemy/auth_accessors.rb, line 82 def self.user_class_name if !@@user_class_name.is_a?(String) raise TypeError, "Alchemy.user_class_name must be a String, not a Class." end "::#{@@user_class_name}" end
# File lib/alchemy/auth_accessors.rb, line 90 def self.user_class_name=(user_class_name) @@user_class_name = user_class_name end
# File lib/alchemy/version.rb, line 6 def self.version VERSION end