common-content 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/MIT-LICENSE +20 -20
  2. data/README.textile +55 -55
  3. data/Rakefile +29 -29
  4. data/app/assets/javascripts/application.js +15 -15
  5. data/app/assets/javascripts/contents.js.coffee +16 -16
  6. data/app/assets/javascripts/jquery-ui-1.8.21.custom.min.js +124 -124
  7. data/app/assets/stylesheets/bootstrap_and_overrides.css.less +29 -29
  8. data/app/assets/stylesheets/contents.css.less +6 -6
  9. data/app/assets/stylesheets/scaffolds.css.less +62 -62
  10. data/app/controllers/contents_controller.rb +99 -99
  11. data/app/helpers/contents_helper.rb +27 -34
  12. data/app/models/content.rb +71 -66
  13. data/app/models/textile.rb +15 -15
  14. data/app/views/contents/_array_form.html.erb +13 -13
  15. data/app/views/contents/_child_content_fields.html.erb +8 -14
  16. data/app/views/contents/_content.xml.builder +3 -3
  17. data/app/views/contents/_fields_edit.html.erb +7 -7
  18. data/app/views/contents/_fields_new.html.erb +12 -14
  19. data/app/views/contents/_navigation.html.erb +13 -0
  20. data/app/views/contents/_resource_fields.html.erb +23 -21
  21. data/app/views/contents/_seo_fields.html.erb +21 -21
  22. data/app/views/contents/_show_children.html.erb +10 -10
  23. data/app/views/contents/edit.html.erb +51 -44
  24. data/app/views/contents/index.html.erb +33 -34
  25. data/app/views/contents/index.xml.builder +4 -4
  26. data/app/views/contents/new.html.erb +13 -13
  27. data/app/views/contents/show.html.erb +25 -25
  28. data/app/views/layouts/contents.html.erb +46 -64
  29. data/config/routes.rb +9 -9
  30. data/lib/common-content.rb +4 -4
  31. data/lib/common-content/engine.rb +7 -7
  32. data/lib/common-content/version.rb +3 -3
  33. data/lib/tasks/common-content_tasks.rake +4 -4
  34. metadata +44 -73
@@ -1,67 +1,72 @@
1
- class Content
2
- include Mongoid::Document
3
- include Mongoid::Timestamps
4
-
5
- field :slug, type: String
6
- validates :slug, presence: true, uniqueness: true
7
- key :slug
8
-
9
- field :title, type: String
10
- validates :title, presence: true
11
-
12
- field :body, type: Textile # optional html block of text for this content
13
-
14
- embeds_one :seo, class_name: 'Content::Seo' # optional SEO fields
15
- accepts_nested_attributes_for :seo # mongoid BUG see http://stackoverflow.com/questions/9392315/mongoid-and-nested-form-for-embeds-one-document
16
-
17
- embeds_many :resources, class_name: 'Content::Resource' # optional 1-n resources like images, videos, REST urls, etc
18
- accepts_nested_attributes_for :resources # mongoid BUG see http://stackoverflow.com/questions/9392315/mongoid-and-nested-form-for-embeds-one-document
19
-
20
- recursively_embeds_many # optionaal 1-n embedded child Content objects, the editable field controls if user can change
21
- accepts_nested_attributes_for :child_contents # mongoid BUG see http://stackoverflow.com/questions/9392315/mongoid-and-nested-form-for-embeds-one-document
22
-
23
- # embeds_one :constraint # the constraints of what fields are required, what child objects can be defined and how many, etc.
24
-
25
- def ancestry
26
- parent_content ? parent_content.ancestry << id : [id]
27
- end
28
-
29
- def self.find_by_ancestry(ancestry = nil, id)
30
- return self.find(id) unless ancestry
31
- parent = Content.find(ancestry.shift)
32
- while(parent_slug = ancestry.shift and parent_slug != id) do
33
- parent = parent.child_contents.find(parent_slug)
34
- end if parent
35
- parent.child_contents.find(id)
36
- end
37
-
38
- def child_order=(order)
39
- return unless order
40
- order = order.split(',')
41
- order.each {|e| e.strip!}
42
- self.child_contents = self.child_contents.sort_by {|kid| order.find_index(kid.id) }
43
- end
44
-
45
- def to_param
46
- parent_content ? parent_content.to_param + '/' + id : id
47
- end
48
-
49
- class Resource
50
- include Mongoid::Document
51
- embedded_in :content
52
-
53
- field :slug, type: String
54
- field :uri, type: String # the URI of the entity we're linking to
55
- field :content_type, type: String # mime type if there is one
56
- end
57
-
58
- class Seo
59
- include Mongoid::Document
60
- embedded_in :content
61
-
62
- field :description, type: String
63
- field :keywords, type: String
64
- field :metatitle, type: String
65
- # validates :description, :keywords, :metatitle, presence: true
66
- end
1
+ class Content
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ field :slug, type: String
6
+ validates :slug, presence: true, uniqueness: true
7
+ key :slug
8
+
9
+ field :title, type: String
10
+ validates :title, presence: true
11
+
12
+ field :body, type: Textile # optional html block of text for this content
13
+
14
+ embeds_one :seo, class_name: 'Content::Seo' # optional SEO fields
15
+ accepts_nested_attributes_for :seo # mongoid BUG see http://stackoverflow.com/questions/9392315/mongoid-and-nested-form-for-embeds-one-document
16
+
17
+ embeds_many :resources, class_name: 'Content::Resource' # optional 1-n resources like images, videos, REST urls, etc
18
+ accepts_nested_attributes_for :resources # mongoid BUG see http://stackoverflow.com/questions/9392315/mongoid-and-nested-form-for-embeds-one-document
19
+
20
+ recursively_embeds_many # optionaal 1-n embedded child Content objects, the editable field controls if user can change
21
+ accepts_nested_attributes_for :child_contents # mongoid BUG see http://stackoverflow.com/questions/9392315/mongoid-and-nested-form-for-embeds-one-document
22
+
23
+ # embeds_one :constraint # the constraints of what fields are required, what child objects can be defined and how many, etc.
24
+ before_save do
25
+ p "calling before_save @child_order = #{@child_order}"
26
+ return unless @child_order
27
+ order = @child_order.split(',')
28
+ order.each {|e| e.strip!}
29
+ self.child_contents = self.child_contents.sort_by {|kid| order.index(kid.id) or -1 }
30
+ end
31
+
32
+ def ancestry
33
+ parent_content ? parent_content.ancestry << id : [id]
34
+ end
35
+
36
+ def self.find_by_ancestry(ancestry = nil, id)
37
+ return self.find(id) unless ancestry
38
+ parent = Content.find(ancestry.shift)
39
+ while(parent_slug = ancestry.shift and parent_slug != id) do
40
+ parent = parent.child_contents.find(parent_slug)
41
+ end if parent
42
+ parent.child_contents.find(id)
43
+ end
44
+
45
+ def child_order=(order)
46
+ @child_order = order
47
+ end
48
+ def child_order; end
49
+
50
+ def to_param
51
+ parent_content ? parent_content.to_param + '/' + id : id
52
+ end
53
+
54
+ class Resource
55
+ include Mongoid::Document
56
+ embedded_in :content
57
+
58
+ field :slug, type: String
59
+ field :uri, type: String # the URI of the entity we're linking to
60
+ field :content_type, type: String # mime type if there is one
61
+ end
62
+
63
+ class Seo
64
+ include Mongoid::Document
65
+ embedded_in :content
66
+
67
+ field :description, type: String
68
+ field :keywords, type: String
69
+ field :metatitle, type: String
70
+ # validates :description, :keywords, :metatitle, presence: true
71
+ end
67
72
  end
@@ -1,16 +1,16 @@
1
- require 'RedCloth'
2
-
3
- class Textile < RedCloth::TextileDoc
4
- include Mongoid::Fields::Serializable
5
-
6
- attr_accessor :max
7
-
8
- def serialize(object)
9
- object.to_s
10
- end
11
- def deserialize(object)
12
- object = '' unless object
13
- RedCloth.new(object)
14
- end
15
-
1
+ require 'RedCloth'
2
+
3
+ class Textile < RedCloth::TextileDoc
4
+ include Mongoid::Fields::Serializable
5
+
6
+ attr_accessor :max
7
+
8
+ def serialize(object)
9
+ object.to_s
10
+ end
11
+ def deserialize(object)
12
+ object = '' unless object
13
+ RedCloth.new(object)
14
+ end
15
+
16
16
  end
@@ -1,14 +1,14 @@
1
- <% f.object.send(fk).each_with_index do |ar, idx| %>
2
- <div class="control-group">
3
- <%= f.fields_for fk do |ar_form| %>
4
- <div class="controls">
5
- <!-- do some stuff to see if this type has a specific view partial -->
6
- <% if File.file?(File.expand_path("_#{ar.type.to_s.downcase}_form.html.erb", File.dirname(__FILE__))) %>
7
- <%= render :partial => "#{ar.type.to_s.downcase}_form", :locals => {f: f, fk: fk} %>
8
- <% else %>
9
- <%= ar_form.text_field "", :class => 'text_field', :value => ar %>
10
- <% end %>
11
- </div>
12
- <% end %>
13
- </div>
1
+ <% f.object.send(fk).each_with_index do |ar, idx| %>
2
+ <div class="control-group">
3
+ <%= f.fields_for fk do |ar_form| %>
4
+ <div class="controls">
5
+ <!-- do some stuff to see if this type has a specific view partial -->
6
+ <% if File.file?(File.expand_path("_#{ar.type.to_s.downcase}_form.html.erb", File.dirname(__FILE__))) %>
7
+ <%= render :partial => "#{ar.type.to_s.downcase}_form", :locals => {f: f, fk: fk} %>
8
+ <% else %>
9
+ <%= ar_form.text_field "", :class => 'text_field', :value => ar %>
10
+ <% end %>
11
+ </div>
12
+ <% end %>
13
+ </div>
14
14
  <% end %>
@@ -1,14 +1,8 @@
1
- <fieldset>
2
- <div class="control-group">
3
- <%= f.label :slug, :class => 'control-label' %>
4
- <div class="controls">
5
- <%= f.text_field :slug, :class => 'text_field' %>
6
- </div>
7
- </div>
8
- <div class="control-group">
9
- <%= f.label :title, :class => 'control-label' %>
10
- <div class="controls">
11
- <%= f.text_field :title, :class => 'text_field' %>
12
- </div>
13
- </div>
14
- </fieldset>
1
+ <% child_index = (child_index or f.object.id) %>
2
+ <div id='<%= child_index %>' class="embedded-child">
3
+ <%= link_to f.object.title, f.object %>
4
+ <fieldset>
5
+ <%= render :partial => 'fields_new', :locals => {f: f} %>
6
+ <%= render :partial => 'fields_edit', :locals => {f: f} %>
7
+ </fieldset>
8
+ </div>
@@ -1,4 +1,4 @@
1
- xml.content do
2
- xml.name(content.slug)
3
- xml.link('rel' => 'self', 'uri' => content_path(content))
1
+ xml.content do
2
+ xml.name(content.slug)
3
+ xml.link('rel' => 'self', 'uri' => content_path(content))
4
4
  end
@@ -1,7 +1,7 @@
1
- <div class="control-group">
2
- <%= f.label :body, :class => 'control-label' %>
3
- <div class="controls">
4
- <%= f.text_area :body, :class => 'text_area' %>
5
- </div>
6
- </div>
7
-
1
+ <div class="control-group">
2
+ <%= f.label :body, :class => 'control-label' %>
3
+ <div class="controls">
4
+ <%= f.text_area :body, :class => 'text_area', rows: '3' %>
5
+ </div>
6
+ </div>
7
+
@@ -1,14 +1,12 @@
1
- <fieldset>
2
- <div class="control-group">
3
- <%= f.label :slug, :class => 'control-label' %>
4
- <div class="controls">
5
- <%= f.text_field :slug, :class => 'text_field', disabled: !@content.new? %>
6
- </div>
7
- </div>
8
- <div class="control-group">
9
- <%= f.label 'title', :class => 'control-label' %>
10
- <div class="controls">
11
- <%= f.text_field :title, :class => 'text_field' %>
12
- </div>
13
- </div>
14
- </fieldset>
1
+ <div class="control-group">
2
+ <%= f.label :slug, :class => 'control-label' %>
3
+ <div class="controls">
4
+ <%= f.text_field :slug, :class => 'text_field', disabled: !f.object.new? %>
5
+ </div>
6
+ </div>
7
+ <div class="control-group">
8
+ <%= f.label 'title', :class => 'control-label' %>
9
+ <div class="controls">
10
+ <%= f.text_field :title, :class => 'text_field' %>
11
+ </div>
12
+ </div>
@@ -0,0 +1,13 @@
1
+
2
+ <div class="navbar navbar-fixed-top">
3
+ <div class="container-fluid">
4
+ <div class="container-fluid nav-collapse">
5
+ <ul class="breadcrumb">
6
+ <li><%= link_to "Contents", "/contents" %></li>
7
+ <% @content.try(:ancestry).try(:each) do |crumb| %>
8
+ <li>/ <%= link_to crumb %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div><!--/.nav-collapse -->
12
+ </div>
13
+ </div>
@@ -1,21 +1,23 @@
1
- <fieldset>
2
- <div class="control-group">
3
- <%= f.label :slug, :class => 'control-label' %>
4
- <div class="controls">
5
- <%= f.text_field :slug, :class => 'text_field' %>
6
- </div>
7
- </div>
8
- <div class="control-group">
9
- <%= f.label :uri, :class => 'control-label' %>
10
- <div class="controls">
11
- <%= f.text_field :uri, :class => 'text_field' %>
12
- </div>
13
- </div>
14
- <div class="control-group">
15
- <%= f.label :type, :class => 'control-label' %>
16
- <div class="controls">
17
- <%= f.text_field :content_type, :class => 'text_field' %>
18
- </div>
19
- </div>
20
- <hr/>
21
- </fieldset>
1
+ <div id='<%= f.object.id %>'>
2
+ <fieldset>
3
+ <div class="control-group">
4
+ <%= f.label :slug, :class => 'control-label' %>
5
+ <div class="controls">
6
+ <%= f.text_field :slug, :class => 'text_field' %>
7
+ </div>
8
+ </div>
9
+ <div class="control-group">
10
+ <%= f.label :uri, :class => 'control-label' %>
11
+ <div class="controls">
12
+ <%= f.text_field :uri, :class => 'text_field' %>
13
+ </div>
14
+ </div>
15
+ <div class="control-group">
16
+ <%= f.label :type, :class => 'control-label' %>
17
+ <div class="controls">
18
+ <%= f.text_field :content_type, :class => 'text_field' %>
19
+ </div>
20
+ </div>
21
+ <hr/>
22
+ </fieldset>
23
+ </div>
@@ -1,22 +1,22 @@
1
- <fieldset>
2
- <h5>SEO</h5>
3
- <div class="control-group">
4
- <%= f.label :title, :class => 'control-label' %>
5
- <div class="controls">
6
- <%= f.text_field :metatitle, :class => 'text_field' %>
7
- </div>
8
- </div>
9
- <div class="control-group">
10
- <%= f.label :description, :class => 'control-label' %>
11
- <div class="controls">
12
- <%= f.text_area :description, :class => 'text_area meta_description', rows: '3' %>
13
- </div>
14
- </div>
15
- <div class="control-group">
16
- <%= f.label :keywords, :class => 'control-label' %>
17
- <div class="controls">
18
- <%= f.text_field :keywords, :class => 'text_field' %>
19
- </div>
20
- </div>
21
- <hr/>
1
+ <fieldset>
2
+ <h5>SEO</h5>
3
+ <div class="control-group">
4
+ <%= f.label :title, :class => 'control-label' %>
5
+ <div class="controls">
6
+ <%= f.text_field :metatitle, :class => 'text_field' %>
7
+ </div>
8
+ </div>
9
+ <div class="control-group">
10
+ <%= f.label :description, :class => 'control-label' %>
11
+ <div class="controls">
12
+ <%= f.text_area :description, :class => 'text_area meta_description', rows: '3' %>
13
+ </div>
14
+ </div>
15
+ <div class="control-group">
16
+ <%= f.label :keywords, :class => 'control-label' %>
17
+ <div class="controls">
18
+ <%= f.text_field :keywords, :class => 'text_field' %>
19
+ </div>
20
+ </div>
21
+ <hr/>
22
22
  </fieldset>
@@ -1,10 +1,10 @@
1
- <% # http://stackoverflow.com/questions/187073/jquery-sortables %>
2
- <div class="">
3
- <!-- <input type='hidden' name='content[child_order]' id='child_order' /> -->
4
- <div id="children">
5
- <% show_children.try :each do |child| %>
6
- <%= content_tag :div, id: child.id do %>
7
- <p><%= link_to child.title, contents_path + '/' + child.ancestry.join('/') + '/edit' %></p>
8
- <% end; end -%>
9
- </div>
10
- </div>
1
+ <% # http://stackoverflow.com/questions/187073/jquery-sortables %>
2
+ <div class="">
3
+ <!-- <input type='hidden' name='content[child_order]' id='child_order' /> -->
4
+ <div id="children">
5
+ <% show_children.try :each do |child| %>
6
+ <%= content_tag :div, id: child.id do %>
7
+ <p><%= link_to child.title, contents_path + '/' + child.ancestry.join('/') + '/edit' %></p>
8
+ <% end; end -%>
9
+ </div>
10
+ </div>
@@ -1,44 +1,51 @@
1
- <%- model_class = @content.class -%>
2
- <div class="page-header">
3
- <h3><%=t '.title', :default => t('helpers.titles.define', :model => model_class.model_name.human,
4
- :default => "Edit #{@content.slug or model_class.model_name.human}") %></h3>
5
- </div>
6
- <%= form_for @content, :html => { :class => 'form-horizontal' } do |f| %>
7
- <% if @content.errors.any? %>
8
- <div class="errors">
9
- <h3>ERROR!</h3>
10
- <ul>
11
- <% @content.errors.full_messages.each do |msg| %>
12
- <%= content_tag :li, msg %>
13
- <% end %>
14
- </ul>
15
- </div>
16
- <% end %>
17
- <%= render :partial => 'fields_new', :locals => {f: f} %>
18
- <%= render :partial => 'fields_edit', :locals => {f: f} %>
19
- <hr/>
20
- <%= link_to_add_fields "+ seo", f, :seo unless @content.seo %>
21
- <%= f.fields_for :seo do |seo| %>
22
- <%= render :partial => 'seo_fields', :locals => {f: seo} %>
23
- <% end %>
24
- <h4>Resources</h4>
25
- <%= link_to_add_fields "Add Resource", f, :resources %>
26
-
27
- <%= f.fields_for :resources do |res| %>
28
- <%= render :partial => 'resource_fields', :locals => {f: res} %>
29
- <% end %>
30
- <h4>Children</h4>
31
- <%= link_to_add_fields "Add Child", f, :child_contents %>
32
- <%= render :partial => 'show_children', object: @content.child_contents %>
33
- <div class="form-actions">
34
- <%= f.submit nil, :class => 'btn btn-primary' %>
35
- <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
36
- contents_path, :class => 'btn' %>
37
- </div>
38
-
39
- <% end %>
40
-
41
- <% content_for :breadcrumb do %>
42
- <%= content_tag :anchor, @content.ancestry %>
43
- <% end %>
44
-
1
+ <%- model_class = @content.class; @ancestry = @content.ancestry -%>
2
+ <div class="page-header">
3
+ <h3><%=t '.title', :default => t('helpers.titles.define', :model => model_class.model_name.human,
4
+ :default => "Edit #{@content.slug or model_class.model_name.human}") %></h3>
5
+ </div>
6
+ <%= form_for @content, :html => { :class => 'form-horizontal' } do |f| %>
7
+ <% if @content.errors.any? %>
8
+ <div class="errors">
9
+ <h3>ERROR!</h3>
10
+ <ul>
11
+ <% @content.errors.full_messages.each do |msg| %>
12
+ <%= content_tag :li, msg %>
13
+ <% end %>
14
+ </ul>
15
+ </div>
16
+ <% end %>
17
+ <%= render :partial => 'fields_new', :locals => {f: f} %>
18
+ <%= render :partial => 'fields_edit', :locals => {f: f} %>
19
+ <hr/>
20
+ <%= link_to_add_fields "+ seo", f, :seo unless @content.seo %>
21
+ <%= f.fields_for :seo do |seo| %>
22
+ <%= render :partial => 'seo_fields', :locals => {f: seo} %>
23
+ <% end %>
24
+ <h4>Resources</h4>
25
+ <%= link_to_add_fields "Add Resource", f, :resources, '#resources' %>
26
+ <div id="resources">
27
+ <%= f.fields_for :resources do |res| %>
28
+ <%= render :partial => 'resource_fields', :locals => {f: res} %>
29
+ <% end %>
30
+ </div>
31
+ <h4>Children</h4>
32
+ <%= f.hidden_field :child_order %>
33
+ <%= link_to_add_fields "Add Child", f, :child_contents, '#children' %>
34
+ <div id="children">
35
+ <%= f.fields_for :child_contents do |child| %>
36
+ <%= render :partial => 'child_content_fields', :locals => {f: child} %>
37
+ <% end %>
38
+ </div>
39
+
40
+ <div class="form-actions">
41
+ <%= f.submit nil, :class => 'btn btn-primary' %>
42
+ <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
43
+ contents_path, :class => 'btn' %>
44
+ </div>
45
+
46
+ <% end %>
47
+
48
+ <% content_for :breadcrumb do %>
49
+ <%= content_tag :anchor, @content.ancestry %>
50
+ <% end %>
51
+