neuron 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ = semantic_form_for(resource) do |form|
2
+ = form.inputs
3
+ = form.buttons
@@ -0,0 +1,4 @@
1
+ %article.b-resource
2
+ %header.b-resource__header
3
+ = resource_title
4
+ = render 'form'
@@ -0,0 +1,50 @@
1
+ atom_feed(
2
+ root_url: collection_url(page: params[:page], format: :html),
3
+ language: I18n.locale,
4
+ 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'
5
+ ) do |feed|
6
+ feed.title(head_title)
7
+ feed.updated(collection.first.try(:created_at))
8
+ feed.icon "http://#{request.host}/favicon.ico"
9
+
10
+ if collection.respond_to?(:total_pages) # WillPaginate::Collection
11
+ feed.link(rel: :first, type: 'application/atom+xml', href: collection_url(format: :atom))
12
+ feed.link(rel: :last, type: 'application/atom+xml', href: collection_url(format: :atom, page: collection.total_pages))
13
+ if collection.previous_page
14
+ feed.link(rel: :previous, type: 'application/atom+xml', href: collection_url(format: :atom, page: collection.previous_page))
15
+ end
16
+ if collection.next_page
17
+ feed.link(rel: :next, type: 'application/atom+xml', href: collection_url(format: :atom, page: collection.next_page))
18
+ end
19
+ end
20
+
21
+ if @user
22
+ atom_author(feed, @user)
23
+ end
24
+
25
+ collection.each do |resource|
26
+ feed.entry(resource, url: atom_entry_url(resource)) do |entry|
27
+ entry.title(resource)
28
+
29
+ if resource.respond_to?(:content)
30
+ entry.content simple_format(resource.content), type: :html
31
+ end
32
+
33
+ if resource.respond_to?(:user)
34
+ atom_author(entry, resource.user)
35
+ end
36
+
37
+ if resource.respond_to?(:keywords)
38
+ atom_categories(entry, resource.keywords)
39
+ end
40
+
41
+ if resource.respond_to?(:comments)
42
+ atom_replies(entry, resource)
43
+ end
44
+
45
+ if resource.respond_to?(:commentable) && resource.commentable.respond_to?(:comments)
46
+ atom_in_reply_to(feed, resource.commentable)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,4 @@
1
+ = collection_block
2
+
3
+ = content_for :head do
4
+ = auto_discovery_link_tag(:atom, {auth_token: current_user.try(:authentication_token)}, title: strip_tags(head_title))
@@ -0,0 +1,4 @@
1
+ %article.b-resource
2
+ %header.b-resource__header
3
+ = resource_title
4
+ = render 'form'
@@ -0,0 +1 @@
1
+ console.log(<%= "#<#{resource_class}:#{resource.id}> #{resource.changed? ? 'has not' : 'has'} been updated".to_json %>);
@@ -0,0 +1,6 @@
1
+ %ul.b-flashes
2
+ - flash.each do |kind, message|
3
+ %li{:class => "b-flashes__flash b-flashes__#{kind}"}
4
+ %p
5
+ %span.ui-icon{:class => "ui-icon-#{kind == :alert ? 'alert' : 'info'}"}
6
+ = message
@@ -0,0 +1,4 @@
1
+ ru:
2
+ application:
3
+ meta:
4
+ title: Define me in config/locales/en.yml with key en.application.meta.title
@@ -0,0 +1,4 @@
1
+ ru:
2
+ application:
3
+ meta:
4
+ title: Определите заголовок приложения в файле config/locales/ru.yml с ключом ru.application.meta.title
@@ -0,0 +1,23 @@
1
+ require 'neuron'
2
+ require 'active_support/concern'
3
+
4
+ module Neuron
5
+ module Authorization
6
+ module Controller
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ rescue_from CanCan::AccessDenied do |exception|
11
+ access_denied(exception)
12
+ end
13
+ end
14
+
15
+ def access_denied(exception = nil)
16
+ redirect_to '/422.html'
17
+ end
18
+ end
19
+
20
+ module View
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,83 @@
1
+ require 'inherited_resources'
2
+ require 'cancan'
3
+
4
+ module InheritedResources
5
+ module Actions
6
+ # GET /resources/1/edit
7
+ def edit(options={}, &block)
8
+ authorize! authorization_action, resource
9
+ respond_with(*(with_chain(resource) << options), &block)
10
+ end
11
+ alias :edit! :edit
12
+ end
13
+
14
+ module BaseHelpers
15
+ protected
16
+
17
+ def resource
18
+ get_resource_ivar ||
19
+ set_resource_ivar(end_of_association_chain.accessible_by(current_ability, authorization_action).send(method_for_find, params[:id])).tap do |resource|
20
+ authorize!(authorization_action, resource)
21
+ end
22
+ end
23
+
24
+ def build_resource
25
+ get_resource_ivar || set_resource_ivar(end_of_association_chain.send(method_for_build)).tap do |resource|
26
+ current_ability.attributes_for(authorization_action, resource_class).each do |attribute, value|
27
+ resource.send("#{attribute}=", value) if attribute.is_a?(Symbol)
28
+ end
29
+ resource.attributes = resource_params
30
+ authorize!(action_name, resource)
31
+ end
32
+ end
33
+
34
+ def collection
35
+ get_collection_ivar || begin
36
+ authorize!(authorization_action, resource_class)
37
+ set_collection_ivar(end_of_association_chain.accessible_by(current_ability, authorization_action).paginate(page: params[:page]))
38
+ end
39
+ end
40
+
41
+ def create_resource(object)
42
+ authorize!(authorization_action, object)
43
+ object.save
44
+ end
45
+
46
+ def update_resource(object, attributes)
47
+ authorize!(authorization_action, object)
48
+ object.update_attributes(attributes)
49
+ end
50
+
51
+ def destroy_resource(object)
52
+ authorize!(authorization_action, object)
53
+ object.destroy
54
+ end
55
+
56
+ private
57
+
58
+ def authorization_action
59
+ @authorization_action ||= action_name.to_sym
60
+ end
61
+ end
62
+
63
+ module BelongsToHelpers
64
+ private
65
+
66
+ # Evaluate the parent given. This is used to nest parents in the
67
+ # association chain.
68
+ def evaluate_parent(parent_symbol, parent_config, chain = nil) #:nodoc:
69
+ instantiated_object = instance_variable_get("@#{parent_config[:instance_name]}")
70
+ return instantiated_object if instantiated_object
71
+
72
+ parent = if chain
73
+ chain.send(parent_config[:collection_name])
74
+ else
75
+ parent_config[:parent_class]
76
+ end.accessible_by(current_ability, :read)
77
+
78
+ parent = parent.send(parent_config[:finder], params[parent_config[:param]])
79
+
80
+ instance_variable_set("@#{parent_config[:instance_name]}", parent)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,10 @@
1
+ require 'neuron'
2
+ require 'rails'
3
+
4
+ module Neuron
5
+ class Railtie < Rails::Engine
6
+ config.to_prepare do
7
+ Neuron.setup!
8
+ end
9
+ end
10
+ end
@@ -4,7 +4,7 @@ require 'action_view/template/resolver'
4
4
  module Neuron
5
5
  class Resolver < ::ActionView::FileSystemResolver
6
6
  def initialize
7
- super('app/views/neuron')
7
+ super(File.join(Neuron.path, 'app', 'views'))
8
8
  end
9
9
 
10
10
  def find_templates(name, prefix, partial, details)
@@ -0,0 +1,144 @@
1
+ require 'neuron'
2
+
3
+ module Neuron
4
+ module Resources
5
+ module Controller
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ def resources(options = {})
10
+ inherit_resources
11
+ append_neuron_view_path_resolver
12
+ if options[:orders] == true
13
+ order_scopes
14
+ elsif options[:orders]
15
+ order_scopes(options[:orders])
16
+ end
17
+ end
18
+ # Adds default ordering scopes for #index action
19
+ # @param [Hash] options options hash
20
+ # @option options [Array, Symbol, String] :ascending default ascending scopes
21
+ # @option options [Array, Symbol, String] :descending default descending scopes
22
+ def order_scopes(options = {})
23
+ with_options only: :index, type: :array do |index|
24
+ index.has_scope(:ascending) { |controller, scope, values| values.any? ? scope.asc(*values) : scope }
25
+ index.has_scope(:descending) { |controller, scope, values| values.any? ? scope.desc(*values) : scope }
26
+ end
27
+ prepend_before_filter :set_default_order
28
+ define_method(:set_default_order) do
29
+ unless params[:ascending] || params[:descending]
30
+ params[:ascending] = options[:ascending] if options[:ascending]
31
+ params[:descending] = options[:descending] if options[:descending]
32
+ end
33
+ params[:ascending] = Array(params[:ascending])
34
+ params[:descending] = Array(params[:descending])
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ module View
41
+ # Creates a link that alternates between acending and descending
42
+ # @param [Hash] options options hash
43
+ # @param [Hash] html_options html options hash
44
+ # @option options [Symbol, String] :by the name of the columnt to sort by
45
+ # @option options [String] :as the text used in link, defaults to human_method_name of :by
46
+ # @option options [String] :params hash with additional params which will be added to generated url
47
+ def order(options = {}, html_options = {})
48
+ options[:by] = options[:by].to_sym
49
+ options[:as] ||= human(resource_class, options[:by])
50
+ asc_orders = Array(params[:ascending]).map(&:to_sym)
51
+ desc_orders = Array(params[:descending]).map(&:to_sym)
52
+ ascending = asc_orders.include?(options[:by])
53
+ selected = ascending || desc_orders.include?(options[:by])
54
+ new_scope = ascending ? :descending : :ascending
55
+ url_options = params.dup.merge(ascending: asc_orders, descending: desc_orders)
56
+
57
+ if selected
58
+ css_classes = html_options[:class] ? html_options[:class].split(/\s+/) : []
59
+ if ascending # selected
60
+ options[:as] = "&#9650;&nbsp;#{options[:as]}"
61
+ css_classes << 'ascending'
62
+ url_options[:ascending] = url_options[:ascending] - [options[:by]]
63
+ else # descending selected
64
+ options[:as] = "&#9660;&nbsp;#{options[:as]}"
65
+ css_classes << 'descending'
66
+ url_options[:descending] = url_options[:descending] - [options[:by]]
67
+ end
68
+ html_options[:class] = css_classes.join(' ')
69
+ end
70
+ url_options[new_scope] += [options[:by]]
71
+ url_options[:ascending] = url_options[:ascending].uniq
72
+ url_options[:descending] = url_options[:descending].uniq
73
+ link_to(options[:as].html_safe, collection_path(url_options.deep_merge(options[:params] || {})), html_options)
74
+ end
75
+
76
+ def collection_title(collection = nil, tag = :h1)
77
+ collection ||= self.collection
78
+ options = {count: collection.count}
79
+ ''.html_safe.tap do |result|
80
+ result << title(t("#{controller_i18n_scope}.#{view_name}.title",
81
+ options.merge(default: t("navigation.#{controller_i18n_scope}.#{action_name}", options))),
82
+ tag: tag)
83
+ if can?(:create, resource_class) && controller.respond_to?(:create)
84
+ result << link_to(t("#{controller_i18n_scope}.new", scope: :actions, default: [:new, 'New']), new_resource_path)
85
+ end
86
+ end
87
+ end
88
+
89
+ def collection_list(collection = nil, collection_name = nil)
90
+ collection ||= self.collection
91
+ collection_name ||= self.resource_collection_name
92
+ if collection.respond_to?(:total_pages)
93
+ start = 1 + (collection.current_page - 1) * collection.per_page
94
+ pagination = will_paginate(collection)
95
+ else
96
+ start = 1
97
+ pagination = ''
98
+ end
99
+ content_tag(:ol,
100
+ render(collection),
101
+ class: "b-list b-list_#{collection_name.to_s.gsub(/_/, '-')}",
102
+ start: start) << pagination
103
+ end
104
+
105
+ def collection_block(collection = nil, tag = :h1, &block)
106
+ collection ||= self.collection
107
+ content_tag(:article, class: 'b-collection') do
108
+ ''.html_safe.tap do |result|
109
+ result << content_tag(:header, collection_title(collection, tag), class: 'b-collection__header')
110
+ if block_given?
111
+ result << capture(&block)
112
+ else
113
+ result << if collection.any?
114
+ collection_list(collection)
115
+ else
116
+ content_tag(:p, t(:no_entries, :scope => [:resources, :collection, :no_entries], :default => [controller_i18n_scope.to_sym, :all]))
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ def resource_title(resource = nil)
124
+ resource ||= self.resource
125
+ action = action_name.to_sym
126
+ ''.html_safe.tap do |result|
127
+ result << title(t("navigation.#{controller_i18n_scope}.#{action}",
128
+ resource: link_to(resource, canonical_path(resource)),
129
+ default: resource.to_s).html_safe)
130
+ if (action == :show) && can?(:update, resource)
131
+ result << content_tag(:sup,
132
+ link_to(t(:edit,
133
+ object: resource,
134
+ scope: :actions,
135
+ default: [:"#{controller_i18n_scope}.edit", :edit, 'Edit']), edit_resource_path))
136
+ end
137
+ #if (action == :edit) && can?(:update, resource)
138
+ #result << content_tag(:sup, link_to(t(:edit, :scope => "actions.#{controller_i18n_scope}"), edit_resource_path))
139
+ #end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -1,3 +1,3 @@
1
1
  module Neuron
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
data/lib/neuron.rb CHANGED
@@ -1,13 +1,16 @@
1
1
  require 'neuron/version'
2
2
 
3
3
  module Neuron
4
- autoload :Application, 'neuron/application'
5
- autoload :Controller, 'neuron/controller'
6
- autoload :Navigation, 'neuron/navigation'
7
- autoload :Resolver, 'neuron/resolver'
8
- autoload :View, 'neuron/view'
4
+ autoload :Application, 'neuron/application'
5
+ autoload :Authorization, 'neuron/authorization'
6
+ autoload :Controller, 'neuron/controller'
7
+ autoload :Navigation, 'neuron/navigation'
8
+ autoload :Resolver, 'neuron/resolver'
9
+ autoload :Resources, 'neuron/resources'
10
+ autoload :Railtie, 'neuron/rails'
11
+ autoload :View, 'neuron/view'
9
12
 
10
- def self.enable!
13
+ def self.setup!
11
14
  if defined?(ActionView)
12
15
  ActionView::Base.send :include, Neuron::View
13
16
  ActionView::Base.send :include, Neuron::Navigation::View
@@ -15,7 +18,22 @@ module Neuron
15
18
  if defined?(ActionController)
16
19
  ActionController::Base.send :include, Neuron::Controller
17
20
  end
21
+ if defined?(InheritedResources)
22
+ ActionController::Base.send :include, Neuron::Resources::Controller
23
+ ActionView::Base.send :include, Neuron::Resources::View
24
+ if defined?(CanCan)
25
+ require 'neuron/integrations/cancan_inherited_resources'
26
+ end
27
+ end
28
+ if defined?(CanCan)
29
+ ActionController::Base.send :include, Neuron::Authorization::Controller
30
+ ActionView::Base.send :include, Neuron::Authorization::View
31
+ end
32
+ end
33
+
34
+ def self.path
35
+ File.expand_path('../..', __FILE__)
18
36
  end
19
37
  end
20
38
 
21
- Neuron.enable! if defined?(Rails)
39
+ require 'neuron/rails' if defined?(Rails)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neuron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-05-29 00:00:00.000000000Z
12
+ date: 2011-05-30 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: Code reused in many applications
15
15
  email:
@@ -21,11 +21,24 @@ files:
21
21
  - .gitignore
22
22
  - Gemfile
23
23
  - Rakefile
24
+ - app/views/defaults/_form.html.haml
25
+ - app/views/defaults/edit.html.haml
26
+ - app/views/defaults/index.atom.builder
27
+ - app/views/defaults/index.html.haml
28
+ - app/views/defaults/new.html.haml
29
+ - app/views/defaults/update.js.erb
30
+ - app/views/shared/_flash_messages.html.haml
31
+ - config/locales/neuron.en.yml
32
+ - config/locales/neuron.ru.yml
24
33
  - lib/neuron.rb
25
34
  - lib/neuron/application.rb
35
+ - lib/neuron/authorization.rb
26
36
  - lib/neuron/controller.rb
37
+ - lib/neuron/integrations/cancan_inherited_resources.rb
27
38
  - lib/neuron/navigation.rb
39
+ - lib/neuron/rails.rb
28
40
  - lib/neuron/resolver.rb
41
+ - lib/neuron/resources.rb
29
42
  - lib/neuron/version.rb
30
43
  - lib/neuron/view.rb
31
44
  - neuron.gemspec