espresso 0.1.1 → 0.1.12
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.
- data/.gitignore +2 -0
- data/README.rdoc +1 -1
- data/Rakefile +11 -7
- data/VERSION +1 -1
- data/espresso.gemspec +28 -16
- data/init.rb +1 -4
- data/lib/espresso/action_controller.rb +7 -0
- data/lib/espresso/action_view/form_builder.rb +58 -0
- data/lib/espresso/action_view/navigation.rb +100 -0
- data/lib/espresso/action_view/resources.rb +59 -0
- data/lib/espresso/action_view/scopes.rb +38 -0
- data/lib/espresso/action_view/stats.rb +54 -0
- data/lib/espresso/action_view.rb +21 -0
- data/lib/espresso/haml.rb +26 -0
- data/lib/espresso/locales/ru.yml +5 -0
- data/lib/espresso/model.rb +36 -21
- data/lib/espresso/resources.rb +79 -0
- data/lib/espresso/resources_helpers.rb +24 -0
- data/lib/espresso.rb +24 -6
- metadata +73 -30
- data/lib/espresso/helpers.rb +0 -34
- data/lib/espresso/objects_controller.rb +0 -42
data/.gitignore
CHANGED
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
|
-
|
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 =
|
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 =
|
11
|
-
gem.homepage =
|
12
|
-
gem.authors = [
|
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('
|
16
|
-
gem.add_dependency('
|
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
|
+
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
|
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.
|
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{
|
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/
|
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/
|
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.
|
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<
|
54
|
-
s.add_runtime_dependency(%q<
|
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<
|
59
|
-
s.add_dependency(%q<
|
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<
|
65
|
-
s.add_dependency(%q<
|
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
@@ -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', '← К списку']),
|
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
|
data/lib/espresso/locales/ru.yml
CHANGED
data/lib/espresso/model.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
28
|
-
|
29
|
-
[
|
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
|
-
|
8
|
-
|
16
|
+
if defined?(ActiveRecord)
|
17
|
+
ActiveRecord::Base.send(:include, Espresso::Model)
|
18
|
+
end
|
9
19
|
|
10
|
-
if defined?
|
11
|
-
|
12
|
-
|
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
|
-
|
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:
|
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:
|
17
|
-
|
18
|
-
|
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
|
-
|
24
|
-
|
25
|
-
-
|
26
|
-
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 2
|
30
|
+
- 3
|
31
|
+
version: 2.2.3
|
27
32
|
type: :runtime
|
28
|
-
|
29
|
-
|
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
|
-
|
34
|
-
|
35
|
-
-
|
36
|
-
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 8
|
44
|
+
- 5
|
45
|
+
version: 0.8.5
|
37
46
|
type: :runtime
|
38
|
-
|
39
|
-
|
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
|
-
|
44
|
-
|
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:
|
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
|
-
|
49
|
-
|
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
|
-
|
54
|
-
|
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/
|
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/
|
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.
|
147
|
+
rubygems_version: 1.3.6
|
105
148
|
signing_key:
|
106
149
|
specification_version: 3
|
107
150
|
summary: Rails extender to simplify rails development
|
data/lib/espresso/helpers.rb
DELETED
@@ -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
|