espresso 0.1.1 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  pkg
2
2
  *.gem
3
+ doc
4
+ .yardoc
data/README.rdoc CHANGED
@@ -10,7 +10,7 @@ Description goes here.
10
10
  future version unintentionally.
11
11
  * Commit, do not mess with rakefile, version, or history.
12
12
  (if you want to have your own version, that is fine but
13
- bump version in a commit by itself I can ignore when I pull)
13
+ bump version in a commit by itself I can ignore when I pull)
14
14
  * Send me a pull request. Bonus points for topic branches.
15
15
 
16
16
  == Copyright
data/Rakefile CHANGED
@@ -4,16 +4,17 @@ require 'rake'
4
4
  begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
- gem.name = "espresso"
7
+ gem.name = 'espresso'
8
8
  gem.summary = %Q{Rails extender to simplify rails development}
9
9
  gem.description = %Q{Useful templates for controller and model functions}
10
- gem.email = "rotuka@tokak.ru"
11
- gem.homepage = "http://github.com/krasivotokak/espresso"
12
- gem.authors = ["Alexander Semyonov"]
13
- gem.add_development_dependency "thoughtbot-shoulda"
10
+ gem.email = 'rotuka@tokak.ru'
11
+ gem.homepage = 'http://github.com/krasivotokak/espresso'
12
+ gem.authors = ['Alexander Semyonov']
14
13
  gem.add_dependency('searchlogic', '>= 2.2.3')
15
- gem.add_dependency('josevalim-inherited_resources', '>= 0.8.5')
16
- gem.add_dependency('mislav-will_paginate', '>= 2.3.11')
14
+ gem.add_dependency('inherited_resources', '>= 0.8.5')
15
+ gem.add_dependency('will_paginate', '>= 2.3.11')
16
+ gem.add_dependency('formtastic', '>= 0.9.7')
17
+ gem.add_development_dependency('shoulda')
17
18
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
19
  end
19
20
  Jeweler::GemcutterTasks.new
@@ -54,5 +55,8 @@ rescue LoadError
54
55
  end
55
56
  end
56
57
 
58
+ desc 'Generate documentation'
59
+ task :doc => :yard
60
+
57
61
  desc "Bump patch version and release to github and gemcutter"
58
62
  task :bump => %w(version:bump:patch release gemcutter:release install)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.12
data/espresso.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{espresso}
8
- s.version = "0.1.1"
8
+ s.version = "0.1.12"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Alexander Semyonov"]
12
- s.date = %q{2009-10-05}
12
+ s.date = %q{2010-03-25}
13
13
  s.description = %q{Useful templates for controller and model functions}
14
14
  s.email = %q{rotuka@tokak.ru}
15
15
  s.extra_rdoc_files = [
@@ -25,18 +25,26 @@ Gem::Specification.new do |s|
25
25
  "espresso.gemspec",
26
26
  "init.rb",
27
27
  "lib/espresso.rb",
28
- "lib/espresso/helpers.rb",
28
+ "lib/espresso/action_controller.rb",
29
+ "lib/espresso/action_view.rb",
30
+ "lib/espresso/action_view/form_builder.rb",
31
+ "lib/espresso/action_view/navigation.rb",
32
+ "lib/espresso/action_view/resources.rb",
33
+ "lib/espresso/action_view/scopes.rb",
34
+ "lib/espresso/action_view/stats.rb",
35
+ "lib/espresso/haml.rb",
29
36
  "lib/espresso/locales/en.yml",
30
37
  "lib/espresso/locales/ru.yml",
31
38
  "lib/espresso/model.rb",
32
- "lib/espresso/objects_controller.rb",
39
+ "lib/espresso/resources.rb",
40
+ "lib/espresso/resources_helpers.rb",
33
41
  "test/espresso_test.rb",
34
42
  "test/test_helper.rb"
35
43
  ]
36
44
  s.homepage = %q{http://github.com/krasivotokak/espresso}
37
45
  s.rdoc_options = ["--charset=UTF-8"]
38
46
  s.require_paths = ["lib"]
39
- s.rubygems_version = %q{1.3.5}
47
+ s.rubygems_version = %q{1.3.6}
40
48
  s.summary = %q{Rails extender to simplify rails development}
41
49
  s.test_files = [
42
50
  "test/espresso_test.rb",
@@ -48,20 +56,24 @@ Gem::Specification.new do |s|
48
56
  s.specification_version = 3
49
57
 
50
58
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
- s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
52
59
  s.add_runtime_dependency(%q<searchlogic>, [">= 2.2.3"])
53
- s.add_runtime_dependency(%q<josevalim-inherited_resources>, [">= 0.8.5"])
54
- s.add_runtime_dependency(%q<mislav-will_paginate>, [">= 2.3.11"])
60
+ s.add_runtime_dependency(%q<inherited_resources>, [">= 0.8.5"])
61
+ s.add_runtime_dependency(%q<will_paginate>, [">= 2.3.11"])
62
+ s.add_runtime_dependency(%q<formtastic>, [">= 0.9.7"])
63
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
55
64
  else
56
- s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
57
65
  s.add_dependency(%q<searchlogic>, [">= 2.2.3"])
58
- s.add_dependency(%q<josevalim-inherited_resources>, [">= 0.8.5"])
59
- s.add_dependency(%q<mislav-will_paginate>, [">= 2.3.11"])
66
+ s.add_dependency(%q<inherited_resources>, [">= 0.8.5"])
67
+ s.add_dependency(%q<will_paginate>, [">= 2.3.11"])
68
+ s.add_dependency(%q<formtastic>, [">= 0.9.7"])
69
+ s.add_dependency(%q<shoulda>, [">= 0"])
60
70
  end
61
71
  else
62
- s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
63
72
  s.add_dependency(%q<searchlogic>, [">= 2.2.3"])
64
- s.add_dependency(%q<josevalim-inherited_resources>, [">= 0.8.5"])
65
- s.add_dependency(%q<mislav-will_paginate>, [">= 2.3.11"])
73
+ s.add_dependency(%q<inherited_resources>, [">= 0.8.5"])
74
+ s.add_dependency(%q<will_paginate>, [">= 2.3.11"])
75
+ s.add_dependency(%q<formtastic>, [">= 0.9.7"])
76
+ s.add_dependency(%q<shoulda>, [">= 0"])
66
77
  end
67
78
  end
79
+
data/init.rb CHANGED
@@ -1,4 +1 @@
1
- require 'activerecord'
2
- require 'espresso/model'
3
-
4
- ActiveRecord::Base.send(:include, Espresso::Model)
1
+ require 'espresso'
@@ -0,0 +1,7 @@
1
+ module Espresso
2
+ module ActionController
3
+ def resources
4
+ Espresso::Resources.resources(self)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,58 @@
1
+ require 'formtastic'
2
+
3
+ module Espresso
4
+ module ActionView
5
+ class FormBuilder < Formtastic::SemanticFormBuilder
6
+ def submit(value=nil, options={})
7
+ value, options = nil, value if value.is_a?(Hash)
8
+ value ||= submit_default_value
9
+ @template.submit_tag(value, options.reverse_merge(:id => "#{object_name}_submit"))
10
+ end
11
+
12
+ def inline_errors_for(method, options = nil) #:nodoc:
13
+ if render_inline_errors?
14
+ errors = Array(@object.errors[method.to_sym]) +
15
+ Array(@object.errors[:"#{method}_id"])
16
+ send(:"error_#{@@inline_errors}", [*errors]) if errors.present?
17
+ else
18
+ nil
19
+ end
20
+ end
21
+
22
+ def submit_default_value
23
+ model = if object.class.respond_to?(:model_name)
24
+ object.class.human_name
25
+ else
26
+ @object_name.to_s.humanize
27
+ end
28
+
29
+ defaults = []
30
+ defaults << :"helpers.submit.#{object_name}.#{form_action}"
31
+ defaults << :"helpers.submit.#{form_action}"
32
+ defaults << "#{form_action.to_s.humanize} #{model}"
33
+
34
+ I18n.t(defaults.shift, :model => model, :default => defaults)
35
+ end
36
+
37
+ def commit_button(*args)
38
+ options = args.extract_options!
39
+
40
+ button_html = options.delete(:button_html) || {}
41
+ button_html.merge!(:class => [button_html[:class], form_action].compact.join(' '))
42
+ element_class = ['commit', options.delete(:class)].compact.join(' ')
43
+ accesskey = (options.delete(:accesskey) || @@default_commit_button_accesskey) unless button_html.has_key?(:accesskey)
44
+ button_html = button_html.merge(:accesskey => accesskey) if accesskey
45
+ template.content_tag(:li, self.submit(options.delete(:label), button_html), :class => element_class)
46
+ end
47
+
48
+ protected
49
+ def model_object
50
+ @object.respond_to?(:to_model) ? @object.to_model : @object
51
+ end
52
+
53
+ def form_action
54
+ model_object ? (model_object.new_record? ? :create : :update) : :submit
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,100 @@
1
+ require 'will_paginate/view_helpers'
2
+
3
+ module Espresso
4
+ module ActionView
5
+ module Navigation
6
+ VIEW_PLACEHOLDERS = {
7
+ 'create' => 'new',
8
+ 'update' => 'edit'
9
+ }
10
+
11
+ # Finds apropriate view name
12
+ def view_name
13
+ unless @view_name
14
+ action_name = controller.action_name
15
+ @view_name = VIEW_PLACEHOLDERS[action_name] || action_name
16
+ end
17
+ @view_name
18
+ end
19
+
20
+ # Make default page title, based on controller and action
21
+ def default_page_title
22
+ text = case view_name
23
+ when 'index'
24
+ controller_name.camelize
25
+ when 'new'
26
+ "#{t('espresso.navigation.new', :default => 'New')} #{controller_name.classify.constantize.human_name}"
27
+ when 'edit'
28
+ "#{t('espresso.navigation.edit', :default => 'Editing')} #{controller_name.classify.constantize.human_name}"
29
+ else
30
+ t("navigation.#{controller_name}.#{view_name}")
31
+ end
32
+ %(<span class="translation_missing">#{text}</span>)
33
+ end
34
+
35
+ def page_title(title = nil, strip = false)
36
+ @page_title = if title
37
+ title
38
+ elsif @page_title
39
+ @page_title
40
+ else
41
+ default = if Rails.env.production?
42
+ default_page_title
43
+ else
44
+ nil
45
+ end
46
+
47
+ rsrc = if resource?
48
+ if resource.new_record?
49
+ resource_class.human_name
50
+ else
51
+ link_to(resource, resource_path)
52
+ end
53
+ else
54
+ nil
55
+ end
56
+
57
+ t("navigation.#{controller_name}.#{view_name}",
58
+ :default => default,
59
+ :resource => rsrc
60
+ )
61
+ end
62
+ if strip
63
+ strip_tags(@page_title)
64
+ else
65
+ @page_title
66
+ end
67
+ end
68
+
69
+ def head_title(default = false, separator = ' | ')
70
+ default ||= t('application.meta.title')
71
+ strip_tags([page_title, default].compact.join(separator))
72
+ end
73
+
74
+ def navigation_list(menu)
75
+ returning '' do |result|
76
+ menu.each do |item|
77
+ path = "/#{item}"
78
+ uri = request.request_uri
79
+ title = t("navigation.#{item}.index", :default => item.to_s.camelize)
80
+ result << content_tag(:li, :class => uri.starts_with?(path) ? 'selected' : nil) do
81
+ link_to_unless_current(title, path) {
82
+ content_tag(:strong, title)
83
+ }
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ include WillPaginate::ViewHelpers
90
+ def will_paginate_with_i18n(collection, options = {})
91
+ will_paginate_without_i18n(collection,
92
+ options.merge({
93
+ :class => 'b-pagination',
94
+ :previous_label => t('espresso.navigation.previous', :default => '← Previous'),
95
+ :next_label => t('espresso.navigation.next', :default => 'Next →')}))
96
+ end
97
+ alias_method_chain :will_paginate, :i18n
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,59 @@
1
+ module Espresso
2
+ module ActionView
3
+ module Resources
4
+ def link_to_new(klass=nil, path=nil)
5
+ klass ||= resource_class
6
+ klass_underscored = klass.name.underscore
7
+ path ||= if klass == resource_class
8
+ new_resource_path
9
+ else
10
+ [:new, klass_underscored]
11
+ end
12
+ link_to(t("helpers.action.#{klass_underscored}.new",
13
+ :default => [:'helpers.action.new', 'Добавить']),
14
+ path,
15
+ :class => 'b-action b-action_new')
16
+ rescue
17
+ end
18
+
19
+ def link_to_show(object=nil)
20
+ object ||= resource
21
+ link_to(t("helpers.action.#{object.class.name.underscore}.show",
22
+ :default => [:'helpers.action.show', object.to_s]),
23
+ object,
24
+ :class => 'b-action b-action_show')
25
+ rescue
26
+ end
27
+
28
+ def link_to_edit(object=nil, path=nil)
29
+ object ||= resource
30
+ path ||= object == resource ? edit_resource_path : [:edit, object]
31
+ link_to(t("helpers.action.#{object.class.name.underscore}.edit",
32
+ :default => [:'helpers.action.edit', 'Редактировать']),
33
+ path,
34
+ :class => 'b-action b-action_edit')
35
+ rescue
36
+ end
37
+
38
+ def link_to_destroy(object=nil, path=nil)
39
+ object ||= resource
40
+ path ||= object == resource ? resource_path : object
41
+ link_to(t("helpers.action.#{object.class.name.underscore}.edit",
42
+ :default => [:'helpers.action.destroy', 'Удалить']),
43
+ path,
44
+ :class => 'b-action b-action_destroy',
45
+ :method => :delete,
46
+ :confirm => 'Вы уверены?')
47
+ end
48
+
49
+ def link_to_index
50
+ link_to(t("helpers.action.#{controller_name.singularize}.index",
51
+ :default => [:'helpers.action.index', '&larr; К списку']),
52
+ collection_path,
53
+ :class => 'b-action b-action_index'
54
+ )
55
+ rescue
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,38 @@
1
+ module Espresso
2
+ module ActionView
3
+ module Scopes
4
+ def simple_search
5
+ returning '' do |form|
6
+ form << form_tag(url_for(:action => :index), :method => :get)
7
+ form << content_tag(:table, :class => 'b-search') do
8
+ content_tag(:tr) do
9
+ returning '' do |result|
10
+ result << content_tag(:td,
11
+ content_tag(:div, text_field_tag(:q, params[:q], :type => 'search'), :class => 'b-input'),
12
+ :class => 'input')
13
+ result << content_tag(:td,
14
+ submit_tag(t('krasivotokak.espresso.find', :default => 'Find!'), :class => 'submit'),
15
+ :class => 'button')
16
+ end
17
+ end
18
+ end
19
+ form << yield if block_given?
20
+ form << '</form>'
21
+ end
22
+ end
23
+
24
+ def scope_filter(scopes)
25
+ items = scopes.inject([]) do |list, scope|
26
+ list << link_to_unless_current(t(".#{scope}"), collection_path(scope => true))
27
+ list
28
+ end
29
+
30
+ content_tag(:div, :class => 'b-scope-filter') do
31
+ content_tag(:ul, :class => 'b-hlist b-hlist_vline') do
32
+ "<li>#{items.join('<li></li>')}</li>"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ module Espresso
2
+ module ActionView
3
+ module Stats
4
+ # Set online statistics trackers
5
+ # @options
6
+ def online_stats(options = {})
7
+ static_includes = []
8
+ dynamic_includes = ''
9
+ noscript_includes = []
10
+ initializers = []
11
+
12
+ if piwik = options.delete(:piwik)
13
+ static_includes << "//#{piwik[:site]}/piwik.js"
14
+ initializers << "var piwikTracker=Piwik.getTracker('//#{piwik[:site]}/piwik.php',#{piwik[:id]});piwikTracker.trackPageView();piwikTracker.enableLinkTracking();"
15
+ noscript_includes << "//#{piwik[:site]}/piwik.php?idsite=#{piwik[:id]}"
16
+ end
17
+
18
+ if metrika = options.delete(:metrika)
19
+ static_includes << '//mc.yandex.ru/resource/watch.js'
20
+ initializers << "var yaCounter#{metrika}=new Ya.Metrika(#{metrika});"
21
+ noscript_includes << "//mc.yandex.ru/watch/#{metrika}"
22
+ end
23
+
24
+ if analytics = options.delete(:analytics)
25
+ dynamic_includes << 'var gaJsHost=("https:"==document.location.protocol)?"https://ssl.":"http://www.";'
26
+ dynamic_includes << 'document.write(unescape("%3Cscript src=\'"+gaJsHost+"google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/script%3Ei"));'
27
+ initializers << "var pageTracker=_gat._getTracker('#{analytics}');pageTracker._trackPageview();"
28
+ end
29
+
30
+ returning('') do |result|
31
+ unless dynamic_includes.empty?
32
+ result << javascript_tag(dynamic_includes)
33
+ end
34
+ result << javascript_include_tag(static_includes) unless static_includes.empty?
35
+ unless initializers.empty?
36
+ initializers = initializers.collect do |initializer|
37
+ "try {#{initializer}} catch(e) {}"
38
+ end.join("\n")
39
+ result << javascript_tag(initializers)
40
+ end
41
+ unless noscript_includes.empty?
42
+ includes = noscript_includes.collect do |noscript|
43
+ %(<img src="#{noscript}" style="border:0" alt="" />)
44
+ end.join("\n")
45
+ result << content_tag(:noscript,
46
+ content_tag(:div,
47
+ includes,
48
+ :style => 'position: absolute'))
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ module Espresso
2
+ module ActionView
3
+ autoload :Resources, 'espresso/action_view/resources'
4
+ autoload :Scopes, 'espresso/action_view/scopes'
5
+ autoload :Navigation, 'espresso/action_view/navigation'
6
+ autoload :FormBuilder, 'espresso/action_view/form_builder'
7
+ autoload :Stats, 'espresso/action_view/stats'
8
+
9
+ include Resources
10
+ include Scopes
11
+ include Navigation
12
+ include Stats
13
+
14
+ # Make body’s modifiers, based on controller_name and action_name
15
+ def body_modifiers
16
+ {:class => "m-#{controller_name} m-#{controller_name}_#{action_name}"}
17
+ end
18
+ end
19
+ end
20
+
21
+ Formtastic::SemanticFormHelper.builder = Espresso::ActionView::FormBuilder
@@ -0,0 +1,26 @@
1
+ require 'haml'
2
+ require 'haml/buffer'
3
+
4
+ class Haml::Buffer
5
+ # Takes an array of objects and uses the class and id of the first
6
+ # one to create an attributes hash.
7
+ # The second object, if present, is used as a prefix,
8
+ # just like you can do with `dom_id()` and `dom_class()` in Rails
9
+ def parse_object_ref(ref)
10
+ prefix = ref[1]
11
+ ref = ref[0]
12
+ # Let's make sure the value isn't nil. If it is, return the default Hash.
13
+ return {} if ref.nil?
14
+ class_name = underscore(ref.class)
15
+ id = "#{class_name}_#{ref.id || 'new'}"
16
+
17
+ if ref.respond_to?(:model_class)
18
+ class_name = ref.model_class
19
+ elsif prefix
20
+ class_name = "#{prefix}_#{class_name}"
21
+ id = "#{prefix}_#{id}"
22
+ end
23
+
24
+ {'id' => id, 'class' => class_name}
25
+ end
26
+ end
@@ -1,6 +1,11 @@
1
1
  ru:
2
2
  krasivotokak:
3
3
  espresso:
4
+
5
+ espresso:
6
+ navigation:
7
+ new: Новый
8
+ edit: Редактирование
4
9
  previous: ← Туда
5
10
  next: Сюда →
6
11
  find: Найти
@@ -1,17 +1,47 @@
1
1
  require 'searchlogic'
2
+ require 'will_paginate'
2
3
 
3
4
  module Espresso
4
5
  # @author Alexander Semyonov
5
6
  module Model
6
- unloadable
7
-
8
7
  def self.included(model)
8
+ super
9
9
  model.class_eval do
10
10
  extend ClassMethods
11
- include InstanceMethods
11
+
12
+ class_inheritable_accessor :model_attrs, :name_field, :per_page
13
+
14
+ self.model_attrs = []
15
+ self.name_field = :name
16
+ self.per_page = 10
17
+
18
+ named_scope :for_index, :conditions => '1 = 1'
19
+ named_scope :for_feed, :order => 'created_at DESC'
20
+ named_scope :for_show, :conditions => '1 = 1'
21
+ named_scope :recent, lambda {
22
+ {:limit => per_page}
23
+ }
12
24
  end
13
25
  end
14
26
 
27
+ # String representation of model, based on Model’s name_field
28
+ def to_s
29
+ send(self.class.name_field).to_s
30
+ end
31
+
32
+ # Model’s classes, based on Model.model_attrs
33
+ def model_class
34
+ main_class = "#{::Espresso::MODEL_PREFIX}-#{self.class.name.underscore}"
35
+ classes = [main_class] +
36
+ self.class.model_attrs.inject([]) do |collection, attribute|
37
+ if send("#{attribute}?")
38
+ collection << " #{main_class}_#{attribute}"
39
+ end
40
+ collection
41
+ end
42
+ classes.join(' ')
43
+ end
44
+
15
45
  module ClassMethods
16
46
  # Paginates search results
17
47
  #
@@ -24,9 +54,9 @@ module Espresso
24
54
  def paginate_found(page = nil, query = {}, simple_query = nil)
25
55
  query ||= {}
26
56
  query.merge!(self.parse_simple_query(simple_query)) if simple_query
27
- @search = search(query)
28
- @results = @search.paginate(:page => page)
29
- [@search, @results]
57
+ searchlogic = search(query)
58
+ results = searchlogic.paginate(:page => page)
59
+ [searchlogic, results]
30
60
  end
31
61
  alias_method :search_results, :paginate_found
32
62
 
@@ -39,13 +69,6 @@ module Espresso
39
69
  {:"#{name_field}_like" => query}
40
70
  end
41
71
 
42
- # «NameField» is a main field, used to represent model in to_s method and in simple queries
43
- # @param [Symbol, String] new_name_field new field name
44
- # @return [Symbol] field name
45
- def name_field
46
- :name
47
- end
48
-
49
72
  # Make a slug from object’s NameField
50
73
  # @param [ActiveRecord::Base] object, which slug is making
51
74
  # @return [String] slug
@@ -53,13 +76,5 @@ module Espresso
53
76
  object.send(name_field).parameterize
54
77
  end
55
78
  end
56
-
57
- module InstanceMethods
58
- def to_s
59
- send(self.class.name_field).to_s
60
- end
61
-
62
- protected
63
- end
64
79
  end
65
80
  end
@@ -0,0 +1,79 @@
1
+ require 'inherited_resources'
2
+ require 'has_scope'
3
+
4
+ module Espresso
5
+ module Resources
6
+ def self.resources(controller = nil)
7
+ controller ||= self
8
+ controller.inherit_resources
9
+ controller.extend ClassMethods
10
+ controller.send(:include, InstanceMethods)
11
+ end
12
+
13
+ def self.included(controller)
14
+ resources(controller)
15
+ end
16
+
17
+ module ClassMethods
18
+ # Adds ability to build feeds for resource’s collections.
19
+ # By default adds Atom feed
20
+ # @example Add Atom feed for #index
21
+ # has_feed :atom
22
+ # @example Add Atom and RSS feed for #index
23
+ # has_feed :atom, :rss
24
+ # @example Add Atom, Rss, and ITunes feed for #index, #list and #archive
25
+ # has_feed :atom, :rss, :itunes_feed, :only => [:index, :list, :archive]
26
+ def has_feed(*args)
27
+ options = args.extract_options!
28
+ if options.empty?
29
+ options[:only] = :index
30
+ end
31
+
32
+ class_inheritable_accessor(:feed_formats) unless respond_to?(:feed_formats)
33
+ self.feed_formats = args.empty? ? [:atom] : args
34
+ self.feed_formats = self.feed_formats.map(&:to_sym)
35
+
36
+ self.feed_formats.each do |format|
37
+ respond_to format, options
38
+ end
39
+
40
+ include FeedScope
41
+ has_scope :for_feed, options.merge(:default => true,
42
+ :type => :boolean,
43
+ :if => :feed_scope_applicable?)
44
+ end
45
+ end
46
+
47
+ module FeedScope
48
+ def feed_scope_applicable?
49
+ params[:format] && self.class.feed_formats.include?(params[:format].to_sym)
50
+ end
51
+ end
52
+
53
+ module InstanceMethods
54
+ protected
55
+
56
+ # Find collection of objects with pagination.
57
+ # Also made Searchlogic object @search
58
+ #
59
+ # @return [WillPaginate::Collection] collection of objects
60
+ def collection
61
+ unless (result = get_collection_ivar).present?
62
+ @search, result = end_of_association_chain.for_index.
63
+ search_results(params[:page],
64
+ params[:query],
65
+ params[:q])
66
+ set_collection_ivar(result)
67
+ end
68
+ result
69
+ end
70
+
71
+ # Build interpolation options for flash messages
72
+ def interpolation_options
73
+ if resource?
74
+ { :resource_title => resource.to_s }
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,24 @@
1
+ module Espresso
2
+ module ResourcesHelpers
3
+ def self.included(base)
4
+ super
5
+ base.send(:helper_method, :resource?, :collection?)
6
+ end
7
+
8
+ # Does the action or view have a resource
9
+ # @return [Boolean] having a resource
10
+ def resource?
11
+ resource
12
+ rescue
13
+ false
14
+ end
15
+
16
+ # Does the action or view have a collection of objects
17
+ # @return [Boolean] having a collection
18
+ def collection?
19
+ collection
20
+ rescue
21
+ false
22
+ end
23
+ end
24
+ end
data/lib/espresso.rb CHANGED
@@ -1,14 +1,32 @@
1
1
  module Espresso
2
+ MODEL_PREFIX = 'b'
3
+
4
+ autoload :Model, 'espresso/model'
5
+ autoload :Resources, 'espresso/resources'
6
+ autoload :ActionView, 'espresso/action_view'
7
+ autoload :ActionController, 'espresso/action_controller'
8
+ autoload :ResourcesHelpers, 'espresso/resources_helpers'
9
+
10
+ # Make a list of locale files, provided by gem
2
11
  def self.locale_files
3
12
  Dir[File.join(File.dirname(__FILE__), 'espresso', 'locales', '*')]
4
13
  end
5
14
  end
6
15
 
7
- require 'espresso/objects_controller'
8
- require 'espresso/model'
16
+ if defined?(ActiveRecord)
17
+ ActiveRecord::Base.send(:include, Espresso::Model)
18
+ end
9
19
 
10
- if defined? Rails
11
- ActiveRecord::Base.send :include, Espresso::Model if defined? ActiveRecord
12
- ActionView::Base.send :include, Espresso::Helpers if defined? ActionView
13
- I18n.load_path.unshift(*Espresso.locale_files)
20
+ if defined?(ActionController)
21
+ ActionController::Base.send(:include, Espresso::ResourcesHelpers)
22
+ ActionController::Base.extend(Espresso::ActionController)
14
23
  end
24
+
25
+ if defined?(ActionView)
26
+ ActionView::Base.send(:include, Espresso::ActionView)
27
+ end
28
+
29
+ require 'i18n'
30
+ I18n.load_path.unshift(*Espresso.locale_files)
31
+
32
+ require 'espresso/haml'
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: espresso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 12
9
+ version: 0.1.12
5
10
  platform: ruby
6
11
  authors:
7
12
  - Alexander Semyonov
@@ -9,49 +14,77 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-10-05 00:00:00 +04:00
17
+ date: 2010-03-25 00:00:00 +03:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
- name: thoughtbot-shoulda
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
21
+ name: searchlogic
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
23
- version: "0"
24
- version:
25
- - !ruby/object:Gem::Dependency
26
- name: searchlogic
27
+ segments:
28
+ - 2
29
+ - 2
30
+ - 3
31
+ version: 2.2.3
27
32
  type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: inherited_resources
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
30
38
  requirements:
31
39
  - - ">="
32
40
  - !ruby/object:Gem::Version
33
- version: 2.2.3
34
- version:
35
- - !ruby/object:Gem::Dependency
36
- name: josevalim-inherited_resources
41
+ segments:
42
+ - 0
43
+ - 8
44
+ - 5
45
+ version: 0.8.5
37
46
  type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: will_paginate
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
40
52
  requirements:
41
53
  - - ">="
42
54
  - !ruby/object:Gem::Version
43
- version: 0.8.5
44
- version:
55
+ segments:
56
+ - 2
57
+ - 3
58
+ - 11
59
+ version: 2.3.11
60
+ type: :runtime
61
+ version_requirements: *id003
45
62
  - !ruby/object:Gem::Dependency
46
- name: mislav-will_paginate
63
+ name: formtastic
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ - 9
72
+ - 7
73
+ version: 0.9.7
47
74
  type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: shoulda
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
50
80
  requirements:
51
81
  - - ">="
52
82
  - !ruby/object:Gem::Version
53
- version: 2.3.11
54
- version:
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ type: :development
87
+ version_requirements: *id005
55
88
  description: Useful templates for controller and model functions
56
89
  email: rotuka@tokak.ru
57
90
  executables: []
@@ -70,11 +103,19 @@ files:
70
103
  - espresso.gemspec
71
104
  - init.rb
72
105
  - lib/espresso.rb
73
- - lib/espresso/helpers.rb
106
+ - lib/espresso/action_controller.rb
107
+ - lib/espresso/action_view.rb
108
+ - lib/espresso/action_view/form_builder.rb
109
+ - lib/espresso/action_view/navigation.rb
110
+ - lib/espresso/action_view/resources.rb
111
+ - lib/espresso/action_view/scopes.rb
112
+ - lib/espresso/action_view/stats.rb
113
+ - lib/espresso/haml.rb
74
114
  - lib/espresso/locales/en.yml
75
115
  - lib/espresso/locales/ru.yml
76
116
  - lib/espresso/model.rb
77
- - lib/espresso/objects_controller.rb
117
+ - lib/espresso/resources.rb
118
+ - lib/espresso/resources_helpers.rb
78
119
  - test/espresso_test.rb
79
120
  - test/test_helper.rb
80
121
  has_rdoc: true
@@ -90,18 +131,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
131
  requirements:
91
132
  - - ">="
92
133
  - !ruby/object:Gem::Version
134
+ segments:
135
+ - 0
93
136
  version: "0"
94
- version:
95
137
  required_rubygems_version: !ruby/object:Gem::Requirement
96
138
  requirements:
97
139
  - - ">="
98
140
  - !ruby/object:Gem::Version
141
+ segments:
142
+ - 0
99
143
  version: "0"
100
- version:
101
144
  requirements: []
102
145
 
103
146
  rubyforge_project:
104
- rubygems_version: 1.3.5
147
+ rubygems_version: 1.3.6
105
148
  signing_key:
106
149
  specification_version: 3
107
150
  summary: Rails extender to simplify rails development
@@ -1,34 +0,0 @@
1
- module Espresso
2
- module Helpers
3
- include WillPaginate::ViewHelpers
4
-
5
- def simple_search
6
- returning '' do |form|
7
- form << form_tag(url_for(:action => :index), :method => :get)
8
- form << content_tag(:table, :class => 'b_search') do
9
- content_tag(:tr) do
10
- returning '' do |result|
11
- result << content_tag(:td,
12
- content_tag(:div, text_field_tag(:q, params[:q], :type => 'search'), :class => 'b_input'),
13
- :class => 'input')
14
- result << content_tag(:td,
15
- submit_tag(t('krasivotokak.espresso.find', :default => 'Find!'), :class => 'submit'),
16
- :class => 'button')
17
- end
18
- end
19
- end
20
- form << yield if block_given?
21
- form << '</form>'
22
- end
23
- end
24
-
25
- def will_paginate_with_i18n(collection, options = {})
26
- will_paginate_without_i18n(collection,
27
- options.merge({
28
- :class => 'b_pagination',
29
- :previous_label => t('krasivotokak.espresso.previous', :default => '← Previous'),
30
- :next_label => t('krasivotokak.espresso.next', :default => 'Next →')}))
31
- end
32
- alias_method_chain :will_paginate, :i18n
33
- end
34
- end
@@ -1,42 +0,0 @@
1
- require 'inherited_resources'
2
-
3
- module Espresso
4
- class ObjectsController < InheritedResources::Base
5
- unloadable
6
-
7
- # Same as default InheritedResources::Base#new, but render 'edit' view,
8
- # other than 'new'
9
- def new
10
- new! do |format|
11
- format.html { render 'edit' }
12
- end
13
- end
14
-
15
- # Same as default InheritedResources::Base#create, but render 'edit' view,
16
- # other than 'new'
17
- def create
18
- create! do |success, failure|
19
- failure.html { render 'edit' }
20
- end
21
- end
22
-
23
- protected
24
-
25
- # Find collection of objects with pagination.
26
- # Also made Searchlogic object @search
27
- #
28
- # @return [WillPaginate::Collection] collection of objects
29
- def collection
30
- unless (result = get_collection_ivar).present?
31
- @search, result = end_of_association_chain.search_results(params[:page], params[:query], params[:q])
32
- set_collection_ivar(result)
33
- end
34
- result
35
- end
36
-
37
- # Build interpolation options for flash messages
38
- def interpolation_options
39
- { :resource_title => resource.to_s }
40
- end
41
- end
42
- end