File: lib/radiant/admin_ui.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Radiant#4
  class: AdminUI#5
includes
  Simpleton   
inherits from
  Object ( Builtin-Module )
has properties
attribute: nav [RW] #108
method: nav_tab / 1 #110
method: nav_item / 1 #114
method: tabs #118
method: initialize #128
method: initialize_nav #133
method: load_default_nav #138
method: load_default_regions #156
method: load_default_page_regions #167
method: load_default_user_regions #184
method: load_default_snippet_regions #206
method: load_default_layout_regions #223
method: load_default_configuration_regions #240
method: load_default_extension_regions #254
  class: DuplicateTabNameError#9
inherits from
  StandardError ( Builtin-Module )
  class: NavTab#13
inherits from
  Array ( Builtin-Module )
has properties
attribute: name [R] #14
method: initialize / 1 #16
method: [] / 1 #20
method: << / 1 #28
alias: add << #50
method: add_item / 1 #52
method: visible? / 1 #67
method: deprecated_add / 3 #71
  class: NavSubItem#78
inherits from
  Object ( Builtin-Module )
has properties
attribute: name [R] #79
attribute: url [R] #79
attribute: tab [RW] #80
method: initialize / 2 #82
method: visible? / 1 #86
method: relative_url #90
method: visible_by_controller? / 1 #95

Code

   1  require 'simpleton'
   2  require 'ostruct'
   3 
   4  module Radiant
   5    class AdminUI
   6      # This may be loaded before ActiveSupport, so do an explicit require
   7      require 'radiant/admin_ui/region_set'
   8      
   9      class DuplicateTabNameError < StandardError; end
  10      
  11      # The NavTab Class holds the structure of a navigation tab (including
  12      # its sub-nav items).
  13      class NavTab < Array
  14        attr_reader :name
  15        
  16        def initialize(name)
  17          @name = name
  18        end
  19        
  20        def [](id)
  21          unless id.kind_of? Fixnum
  22            self.find {|subnav_item| subnav_item.name.to_s.titleize == id.to_s.titleize }
  23          else
  24            super
  25          end
  26        end
  27        
  28        def <<(*args)
  29          options = args.extract_options!
  30          item = args.size > 1 ? deprecated_add(*(args << caller)) : args.first
  31          raise DuplicateTabNameError.new("duplicate tab name `#{item.name}'") if self[item.name]
  32          item.tab = self if item.respond_to?(:tab=)
  33          if options.empty?
  34            super(item)
  35          else
  36            options.symbolize_keys!
  37            before = options.delete(:before)
  38            after = options.delete(:after)
  39            tab_name = before || after
  40            if self[tab_name]
  41              _index = index(self[tab_name])
  42              _index += 1 unless before
  43              insert(_index, item)
  44            else
  45              super(item)
  46            end
  47          end
  48        end
  49        
  50        alias :add :<<
  51        
  52        def add_item(*args)
  53          options = args.extract_options!
  54          options.symbolize_keys!
  55          before = options.delete(:before)
  56          after = options.delete(:after)
  57          tab_name = before || after
  58          if self[tab_name]
  59            _index = index(self[tab_name])
  60            _index += 1 unless before
  61            insert(_index, NavSubItem.new(args.first, args.second))
  62          else
  63            add NavSubItem.new(args.first, args.second)
  64          end
  65        end
  66        
  67        def visible?(user)
  68          any? { |sub_item| sub_item.visible?(user) }
  69        end
  70        
  71        def deprecated_add(name, url, caller)
  72          ActiveSupport::Deprecation.warn("admin.tabs.add is no longer supported in Radiant 0.9.x.  Please update your code to use: \ntab \"Content\" do\n\tadd_item(...)\nend", caller)
  73          NavSubItem.new(name, url)
  74        end
  75      end
  76      
  77      # Simple structure for storing the properties of a tab's sub items.
  78      class NavSubItem
  79        attr_reader :name, :url
  80        attr_accessor :tab
  81        
  82        def initialize(name, url = "#")
  83          @name, @url = name, url
  84        end
  85        
  86        def visible?(user)
  87          visible_by_controller?(user)
  88        end
  89        
  90        def relative_url
  91          File.join(ActionController::Base.relative_url_root || '', url)
  92        end
  93        
  94        private
  95        def visible_by_controller?(user)
  96          params = ActionController::Routing::Routes.recognize_path(url, :method => :get)
  97          if params && params[:controller]
  98            klass = "#{params[:controller].camelize}Controller".constantize
  99            klass.user_has_access_to_action?(user, params[:action])
 100          else
 101            false
 102          end
 103        end
 104      end
 105      
 106      include Simpleton
 107      
 108      attr_accessor :nav
 109      
 110      def nav_tab(*args)
 111        NavTab.new(*args)
 112      end
 113      
 114      def nav_item(*args)
 115        NavSubItem.new(*args)
 116      end
 117      
 118      def tabs
 119        nav['Content']
 120      end
 121      
 122      # Region sets
 123      %w{page snippet layout user configuration extension}.each do |controller|
 124        attr_accessor controller
 125        alias_method "#{controller}s", controller
 126      end
 127      
 128      def initialize
 129        initialize_nav
 130        load_default_regions
 131      end
 132      
 133      def initialize_nav
 134        @nav = NavTab.new("Tab Container")
 135        load_default_nav
 136      end
 137      
 138      def load_default_nav
 139        content = nav_tab("Content")
 140        content << nav_item("Pages", "/admin/pages")
 141        nav << content
 142        
 143        design = nav_tab("Design")
 144        design << nav_item("Layouts", "/admin/layouts")
 145        design << nav_item("Snippets", "/admin/snippets")
 146        nav << design
 147        
 148        settings = nav_tab("Settings")
 149        settings << nav_item("General", "/admin/configuration")
 150        settings << nav_item("Personal", "/admin/preferences")
 151        settings << nav_item("Users", "/admin/users")
 152        settings << nav_item("Extensions", "/admin/extensions")
 153        nav << settings
 154      end
 155      
 156      def load_default_regions
 157        @page = load_default_page_regions
 158        @snippet = load_default_snippet_regions
 159        @layout = load_default_layout_regions
 160        @user = load_default_user_regions
 161        @configuration = load_default_configuration_regions
 162        @extension = load_default_extension_regions
 163      end
 164      
 165      private
 166      
 167      def load_default_page_regions
 168        OpenStruct.new.tap do |page|
 169          page.edit = RegionSet.new do |edit|
 170            edit.main.concat %w{edit_header edit_form edit_popups}
 171            edit.form.concat %w{edit_title edit_extended_metadata edit_page_parts}
 172            edit.layout.concat %w{edit_layout edit_type edit_status edit_published_at}
 173            edit.form_bottom.concat %w{edit_buttons edit_timestamp}
 174          end
 175          page.index = RegionSet.new do |index|
 176            index.sitemap_head.concat %w{title_column_header status_column_header actions_column_header}
 177            index.node.concat %w{title_column status_column actions_column}
 178          end
 179          page.remove = page.children = page.index
 180          page.new = page._part = page.edit
 181        end
 182      end
 183      
 184      def load_default_user_regions
 185        OpenStruct.new.tap do |user|
 186          user.preferences = RegionSet.new do |preferences|
 187            preferences.main.concat %w{edit_header edit_form}
 188            preferences.form.concat %w{edit_name edit_email edit_username edit_password edit_locale}
 189            preferences.form_bottom.concat %w{edit_buttons}
 190          end
 191          user.edit = RegionSet.new do |edit|
 192            edit.main.concat %w{edit_header edit_form}
 193            edit.form.concat %w{edit_name edit_email edit_username edit_password
 194                                edit_roles edit_locale edit_notes}
 195            edit.form_bottom.concat %w{edit_buttons edit_timestamp}
 196          end
 197          user.index = RegionSet.new do |index|
 198            index.thead.concat %w{title_header roles_header actions_header}
 199            index.tbody.concat %w{title_cell roles_cell actions_cell}
 200            index.bottom.concat %w{new_button}
 201          end
 202          user.new = user.edit
 203        end
 204      end
 205      
 206      def load_default_snippet_regions
 207        OpenStruct.new.tap do |snippet|
 208          snippet.edit = RegionSet.new do |edit|
 209            edit.main.concat %w{edit_header edit_form}
 210            edit.form.concat %w{edit_title edit_content edit_filter}
 211            edit.form_bottom.concat %w{edit_buttons edit_timestamp}
 212          end
 213          snippet.index = RegionSet.new do |index|
 214            index.top.concat %w{}
 215            index.thead.concat %w{title_header actions_header}
 216            index.tbody.concat %w{title_cell actions_cell}
 217            index.bottom.concat %w{new_button}
 218          end
 219          snippet.new = snippet.edit
 220        end
 221      end
 222      
 223      def load_default_layout_regions
 224        OpenStruct.new.tap do |layout|
 225          layout.edit = RegionSet.new do |edit|
 226            edit.main.concat %w{edit_header edit_form}
 227            edit.form.concat %w{edit_title edit_extended_metadata edit_content}
 228            edit.form_bottom.concat %w{reference_links edit_buttons edit_timestamp}
 229          end
 230          layout.index = RegionSet.new do |index|
 231            index.top.concat %w{}
 232            index.thead.concat %w{title_header actions_header}
 233            index.tbody.concat %w{title_cell actions_cell}
 234            index.bottom.concat %w{new_button}
 235          end
 236          layout.new = layout.edit
 237        end
 238      end
 239      
 240      def load_default_configuration_regions
 241        OpenStruct.new.tap do |configuration|
 242          configuration.show = RegionSet.new do |show|
 243            show.user.concat %w{preferences}
 244            show.config.concat %w{site defaults users}
 245          end
 246          configuration.edit = RegionSet.new do |edit|
 247            edit.main.concat %w{edit_header edit_form}
 248            edit.form.concat %w{edit_site edit_defaults edit_users}
 249            edit.form_bottom.concat %w{edit_buttons}
 250          end
 251        end
 252      end
 253      
 254      def load_default_extension_regions
 255        OpenStruct.new.tap do |extension|
 256          extension.index = RegionSet.new do |index|
 257            index.thead.concat %w{title_header website_header version_header}
 258            index.tbody.concat %w{title_cell website_cell version_cell}
 259          end
 260        end
 261      end
 262    end
 263  end