module AbstractInterface class << self inject :logger => :logger, :config => :config, :environment => :environment attr_accessor :plugin_name attr_accessor :layout_configurations_dir def generate_helper_methods *args AbstractInterface::ViewBuilder.generate_helper_methods *args end def available_themes; @available_themes ||= [] end def theme_metadata theme logger.warn "Complex calculation (AbstractInterface.theme_metadata) called in production!" if config.production? metadata = {} name = "/#{Crystal::Template::DIRECTORY_NAME}/#{THEMES_DIR}/#{theme}/metadata.rb" if environment.file_exist? name fname = environment.find_file name code = File.read fname metadata = eval code metadata.must_be.a Hash end metadata.to_openobject end def layouts_defined? !!layout_configurations_dir end # Place definitions of your layouts into :layout_configurations_dir folder, you can have multiple such directories def layout_definitions_without_cache theme name = "#{layout_configurations_dir.must_be.present}/#{theme}.yml" raise "File '#{name}' not exist!" unless environment.file_exist? name result = {} environment.find_files(name).each do |fname| lds = YAML.load_file(fname) validate_layout_definition!(lds, theme) result.merge! lds end result end cache_method_with_params_in_production :layout_definitions protected def validate_layout_definition! lds, theme lds.must_be.a Hash unless lds.include?('default') raise "No 'default' layout definition for '#{theme}' Theme (there always should be definition for 'default' layout)!" end lds.each do |theme_name, ld| ld.must_be.a Hash ld.must.include 'layout_template' ld.must.include 'slots' ld['slots'].must_be.a Hash end end end end