scaffold_markup 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.md +41 -0
- data/Rakefile +2 -0
- data/app/helpers/scaffold_markup_helper.rb +15 -0
- data/app/views/application/_form.html.haml +5 -0
- data/app/views/application/_form_actions.html.haml +3 -0
- data/app/views/application/_form_attributes.html.haml +5 -0
- data/app/views/application/_index_actions.html.haml +2 -0
- data/app/views/application/_index_table.html.haml +3 -0
- data/app/views/application/_page_title.html.haml +2 -0
- data/app/views/application/_show_actions.html.haml +3 -0
- data/app/views/application/_show_attributes.html.haml +2 -0
- data/app/views/application/edit.html.haml +3 -0
- data/app/views/application/index.html.haml +4 -0
- data/app/views/application/new.html.haml +3 -0
- data/app/views/application/show.html.haml +7 -0
- data/app/views/kaminari/twitter_bootstrap/_first_page.html.haml +15 -0
- data/app/views/kaminari/twitter_bootstrap/_gap.html.haml +9 -0
- data/app/views/kaminari/twitter_bootstrap/_last_page.html.haml +13 -0
- data/app/views/kaminari/twitter_bootstrap/_next_page.html.haml +13 -0
- data/app/views/kaminari/twitter_bootstrap/_page.html.haml +15 -0
- data/app/views/kaminari/twitter_bootstrap/_paginator.html.haml +20 -0
- data/app/views/kaminari/twitter_bootstrap/_prev_page.html.haml +13 -0
- data/lib/scaffold_markup.rb +21 -0
- data/lib/scaffold_markup/builders/base_builder.rb +22 -0
- data/lib/scaffold_markup/builders/form_builder.rb +77 -0
- data/lib/scaffold_markup/builders/nav_bar_builder.rb +26 -0
- data/lib/scaffold_markup/builders/nav_container_builder.rb +25 -0
- data/lib/scaffold_markup/builders/page_builder.rb +63 -0
- data/lib/scaffold_markup/controllers/base.rb +70 -0
- data/lib/scaffold_markup/engine.rb +4 -0
- data/lib/scaffold_markup/extensions/active_model_extension.rb +6 -0
- data/lib/scaffold_markup/extensions/active_record_extension.rb +14 -0
- data/lib/scaffold_markup/extensions/twitter_bootstrap_markup_extension.rb +5 -0
- data/lib/scaffold_markup/helpers/link_button_helper.rb +32 -0
- data/lib/scaffold_markup/helpers/table_helper.rb +83 -0
- data/lib/scaffold_markup/helpers/url_helper.rb +28 -0
- data/lib/scaffold_markup/version.rb +3 -0
- data/scaffold_markup.gemspec +26 -0
- data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
- data/vendor/assets/images/glyphicons-halflings.png +0 -0
- data/vendor/assets/javascripts/bootstrap.js +1792 -0
- data/vendor/assets/javascripts/jquery.livequery.js +226 -0
- data/vendor/assets/stylesheets/bootstrap.css +5580 -0
- data/vendor/assets/stylesheets/scaffold_markup.css +24 -0
- metadata +146 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# scaffold_markup
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'scaffold_markup'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install scaffold_markup
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Put into aplication.js file
|
22
|
+
|
23
|
+
//= require jquery.livequery
|
24
|
+
//= require bootstrap
|
25
|
+
|
26
|
+
Put into application.css file
|
27
|
+
|
28
|
+
*= require bootstrap
|
29
|
+
*= require scaffold_markup
|
30
|
+
|
31
|
+
All scaffold controller must include
|
32
|
+
|
33
|
+
include ScaffoldMarkup::Controllers::Base
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
1. Fork it
|
38
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
39
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
40
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
41
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module ScaffoldMarkupHelper
|
2
|
+
|
3
|
+
def page_builder(&block)
|
4
|
+
ScaffoldMarkup::Builders::PageBuilder.new(self, &block)
|
5
|
+
end
|
6
|
+
|
7
|
+
def url_helper
|
8
|
+
ScaffoldMarkup::Helpers::UrlHelper.new(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
def resource_class
|
12
|
+
params[:controller].classify.constantize
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
- @model.class.accessible_attribute_names.each do |attribute|
|
2
|
+
- if @model.class.reflected_association(attribute)
|
3
|
+
= form.association @model.class.reflected_association(attribute).name, :required => @model.class.validates_presence?(attribute)
|
4
|
+
- else
|
5
|
+
= form.text attribute, :required => @model.class.validates_presence?(attribute)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
-# Link to the "First" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the first page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-
|
9
|
+
%li{:class => '.first' + (current_page.first? ? ' active' : '')}
|
10
|
+
- if current_page.first?
|
11
|
+
%a= raw(t 'views.pagination.first')
|
12
|
+
- else
|
13
|
+
= link_to raw(t 'views.pagination.first'), url, :remote => remote
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
-# Non-link tag that stands for skipped pages...
|
2
|
+
- available local variables
|
3
|
+
current_page: a page object for the currently displayed page
|
4
|
+
num_pages: total number of pages
|
5
|
+
per_page: number of items to fetch per page
|
6
|
+
remote: data-remote
|
7
|
+
-
|
8
|
+
%li.page.gap
|
9
|
+
%a= raw(t 'views.pagination.truncate')
|
@@ -0,0 +1,13 @@
|
|
1
|
+
-# Link to the "Last" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the last page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-
|
9
|
+
%li{:class => 'last' + (current_page.last? ? ' active' : '')}
|
10
|
+
- if current_page.last?
|
11
|
+
%a= raw(t 'views.pagination.last')
|
12
|
+
- else
|
13
|
+
= link_to raw(t 'views.pagination.last'), url, {:remote => remote}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
-# Link to the "Next" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the next page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-
|
9
|
+
%li{:class => 'next' + (current_page.last? ? ' active' : '')}
|
10
|
+
- if current_page.last?
|
11
|
+
%a= raw(t 'views.pagination.next')
|
12
|
+
- else
|
13
|
+
= link_to raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote
|
@@ -0,0 +1,15 @@
|
|
1
|
+
-# Link showing page number
|
2
|
+
- available local variables
|
3
|
+
page: a page object for "this" page
|
4
|
+
url: url to this page
|
5
|
+
current_page: a page object for the currently displayed page
|
6
|
+
num_pages: total number of pages
|
7
|
+
per_page: number of items to fetch per page
|
8
|
+
remote: data-remote
|
9
|
+
-
|
10
|
+
%li{:class => 'page' + (page.current? ? ' active' : '')}
|
11
|
+
- if page.current?
|
12
|
+
%a= page
|
13
|
+
- else
|
14
|
+
= link_to page, url, opts = {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil}
|
15
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
-# The container tag
|
2
|
+
- available local variables
|
3
|
+
current_page: a page object for the currently displayed page
|
4
|
+
num_pages: total number of pages
|
5
|
+
per_page: number of items to fetch per page
|
6
|
+
remote: data-remote
|
7
|
+
paginator: the paginator that renders the pagination tags inside
|
8
|
+
-
|
9
|
+
= paginator.render do
|
10
|
+
%nav.pagination
|
11
|
+
%ul
|
12
|
+
= first_page_tag
|
13
|
+
= prev_page_tag
|
14
|
+
- each_page do |page|
|
15
|
+
- if page.left_outer? || page.right_outer? || page.inside_window?
|
16
|
+
= page_tag page
|
17
|
+
- elsif !page.was_truncated?
|
18
|
+
= gap_tag
|
19
|
+
= next_page_tag
|
20
|
+
= last_page_tag
|
@@ -0,0 +1,13 @@
|
|
1
|
+
-# Link to the "Previous" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the previous page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-
|
9
|
+
%li{:class => 'prev' + (current_page.first? ? ' active' : '')}
|
10
|
+
- if current_page.first?
|
11
|
+
%a= raw(t 'views.pagination.previous')
|
12
|
+
- else
|
13
|
+
= link_to raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'scaffold_markup/version'
|
2
|
+
require 'scaffold_markup/engine'
|
3
|
+
|
4
|
+
require 'twitter_bootstrap_markup'
|
5
|
+
require 'kaminari'
|
6
|
+
|
7
|
+
require 'scaffold_markup/extensions/active_model_extension'
|
8
|
+
require 'scaffold_markup/extensions/active_record_extension'
|
9
|
+
require 'scaffold_markup/extensions/twitter_bootstrap_markup_extension'
|
10
|
+
|
11
|
+
require 'scaffold_markup/helpers/link_button_helper'
|
12
|
+
require 'scaffold_markup/helpers/table_helper'
|
13
|
+
require 'scaffold_markup/helpers/url_helper'
|
14
|
+
|
15
|
+
require 'scaffold_markup/controllers/base'
|
16
|
+
|
17
|
+
require 'scaffold_markup/builders/base_builder'
|
18
|
+
require 'scaffold_markup/builders/nav_container_builder'
|
19
|
+
require 'scaffold_markup/builders/nav_bar_builder'
|
20
|
+
require 'scaffold_markup/builders/form_builder'
|
21
|
+
require 'scaffold_markup/builders/page_builder'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ScaffoldMarkup
|
2
|
+
module Builders
|
3
|
+
class BaseBuilder
|
4
|
+
include TwitterBootstrapMarkup
|
5
|
+
|
6
|
+
attr_reader :template
|
7
|
+
attr_reader :block
|
8
|
+
attr_reader :url
|
9
|
+
|
10
|
+
def initialize(template, &block)
|
11
|
+
@template = template
|
12
|
+
@block = block
|
13
|
+
@url = Helpers::UrlHelper.new(template)
|
14
|
+
end
|
15
|
+
|
16
|
+
def html_safe
|
17
|
+
to_s.html_safe
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module ScaffoldMarkup
|
2
|
+
module Builders
|
3
|
+
class FormBuilder < BaseBuilder
|
4
|
+
attr_reader :model
|
5
|
+
|
6
|
+
def initialize(template, model, &block)
|
7
|
+
super(template, &block)
|
8
|
+
@model = model
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
_self = self
|
13
|
+
html = Form.horizontal(:method => :post, :action => model.new_record? ? url.list_resource(model.class) : url.resource(model), 'accept-charset' => 'UTF-8') do
|
14
|
+
append Input.hidden :name => 'authenticity_token', :value => _self.template.form_authenticity_token
|
15
|
+
append Input.hidden :name => '_method', :value => :put unless _self.model.new_record?
|
16
|
+
append _self.template.capture(_self, &_self.block)
|
17
|
+
end.to_s
|
18
|
+
flash_errors
|
19
|
+
html
|
20
|
+
end
|
21
|
+
|
22
|
+
def display(attribute)
|
23
|
+
association = model.class.reflected_association(attribute)
|
24
|
+
display_value = association ? model.send(association.name).to_s : model.send(attribute)
|
25
|
+
ControlGroup.new(model.class.human_attribute_name(attribute), :class => 'bold') do
|
26
|
+
append Tag.block(:span, display_value, :class => 'display')
|
27
|
+
end.html_safe
|
28
|
+
end
|
29
|
+
|
30
|
+
def text(attribute, options={})
|
31
|
+
_self = self
|
32
|
+
ControlGroup.new("#{model.class.human_attribute_name(attribute)}#{options[:required] ? ' (*)' : ''}", :class => options[:required] ? 'bold' : '') do
|
33
|
+
text_box = append Input.text(:id => "#{_self.model.class.model_name.underscore}_#{attribute}", :name => "#{_self.model.class.model_name.underscore}[#{attribute}]", :value => _self.model.send(attribute))
|
34
|
+
text_box.attributes[:required] = :required if options[:required]
|
35
|
+
end.html_safe
|
36
|
+
end
|
37
|
+
|
38
|
+
def association(association_name, options={})
|
39
|
+
_self = self
|
40
|
+
attribute = model.class.reflections[association_name].foreign_key
|
41
|
+
ControlGroup.new("#{model.class.human_attribute_name(association_name)}#{options[:required] ? ' (*)' : ''}", :class => options[:required] ? 'bold' : '') do
|
42
|
+
html_attributes = {
|
43
|
+
:prompt => '[Select]',
|
44
|
+
:selected_value => _self.model.send(attribute),
|
45
|
+
:id => "#{_self.model.class.model_name.underscore}_#{attribute}",
|
46
|
+
:name => "#{_self.model.class.model_name.underscore}[#{attribute}]"
|
47
|
+
}
|
48
|
+
select = append Select.new(Hash[_self.model.class.reflections[association_name].klass.all.map { |e| [e.to_s, e.id] }], html_attributes)
|
49
|
+
select.attributes[:required] = :required if options[:required]
|
50
|
+
end.html_safe
|
51
|
+
end
|
52
|
+
|
53
|
+
def actions(&block)
|
54
|
+
#TODO: FormActions tiene que ser una clase de TwitterBootstrapMarkup
|
55
|
+
Tag.block(:div, template.capture(self, &block), :class => 'form-actions').html_safe
|
56
|
+
end
|
57
|
+
|
58
|
+
def flash_errors
|
59
|
+
_self = self
|
60
|
+
if model.errors.any?
|
61
|
+
errors = Alert.danger_closable do
|
62
|
+
append Tag.block(:strong, 'Cant perform requested operation')
|
63
|
+
append do
|
64
|
+
Tag.block(:ul) do
|
65
|
+
_self.model.errors.full_messages.each do |msg|
|
66
|
+
append Tag.new(:li, msg.gsub(/\n/, '<br>'))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
template.content_for(:flash, errors.html_safe)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ScaffoldMarkup
|
2
|
+
module Builders
|
3
|
+
class NavBarBuilder < BaseBuilder
|
4
|
+
|
5
|
+
def to_s
|
6
|
+
_self = self
|
7
|
+
NavBar.top do
|
8
|
+
append _self.template.capture(_self, &_self.block)
|
9
|
+
end.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def brand(text, url)
|
13
|
+
Brand.new(text, url).html_safe
|
14
|
+
end
|
15
|
+
|
16
|
+
def container(&block)
|
17
|
+
NavContainerBuilder.new(template, &block).html_safe
|
18
|
+
end
|
19
|
+
|
20
|
+
def link(text, url)
|
21
|
+
Link.new(text, url).html_safe
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ScaffoldMarkup
|
2
|
+
module Builders
|
3
|
+
class NavContainerBuilder < BaseBuilder
|
4
|
+
|
5
|
+
def initialize(*args, &block)
|
6
|
+
super(*args, &block)
|
7
|
+
@container = NavContainer.new {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
template.capture(self, &block)
|
12
|
+
@container.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def link(text, url)
|
16
|
+
@container.append Link.new(text, url)
|
17
|
+
end
|
18
|
+
|
19
|
+
def pull_right
|
20
|
+
@container.pull_right
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module ScaffoldMarkup
|
2
|
+
module Builders
|
3
|
+
class PageBuilder < BaseBuilder
|
4
|
+
include Helpers::LinkButtonHelper
|
5
|
+
include Helpers::TableHelper
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
html = template.capture(self, &block)
|
9
|
+
flash_messages
|
10
|
+
html
|
11
|
+
end
|
12
|
+
|
13
|
+
def container(&block)
|
14
|
+
#TODO: Container tiene que ser un tag de TwitterBootstrapMarkup
|
15
|
+
Tag.new(:div, template.capture(self, &block), :class => 'container').html_safe
|
16
|
+
end
|
17
|
+
|
18
|
+
def title(text)
|
19
|
+
template.content_for(:page_title, text)
|
20
|
+
end
|
21
|
+
|
22
|
+
def header(title, subtitle=nil)
|
23
|
+
template.content_for(:page_header, PageHeader.new(title, subtitle).html_safe)
|
24
|
+
end
|
25
|
+
|
26
|
+
def well_small(&block)
|
27
|
+
Well.small(template.capture(self, &block)).html_safe
|
28
|
+
end
|
29
|
+
|
30
|
+
def submit_primary(*args)
|
31
|
+
Submit.primary(*args).html_safe
|
32
|
+
end
|
33
|
+
|
34
|
+
def form_for(model, &block)
|
35
|
+
FormBuilder.new(template, model, &block).html_safe
|
36
|
+
end
|
37
|
+
|
38
|
+
def nav_bar(&block)
|
39
|
+
NavBarBuilder.new(template, &block).html_safe
|
40
|
+
end
|
41
|
+
|
42
|
+
def flash_messages
|
43
|
+
unless template.content_for?(:flash)
|
44
|
+
template.flash.keys.each do |key|
|
45
|
+
if template.flash[key].is_a? Array
|
46
|
+
flash_text = template.flash[key].join('<br>')
|
47
|
+
else
|
48
|
+
flash_text = template.flash[key]
|
49
|
+
end
|
50
|
+
template.content_for(:flash, self.send("alert_#{key}", flash_text))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Alert::TYPES.each do |type|
|
56
|
+
define_method "alert_#{type}" do |content=nil, &block|
|
57
|
+
Alert.send("#{type}_closable", content, &block).html_safe
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|