neuron 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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