tandem 0.2.0.rc
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/MIT-LICENSE +20 -0
- data/README.rdoc +205 -0
- data/Rakefile +31 -0
- data/app/assets/images/tandem/blank_image.jpg +0 -0
- data/app/assets/images/tandem/colorbox/border1.png +0 -0
- data/app/assets/images/tandem/colorbox/border2.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderBottomCenter.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderBottomLeft.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderBottomRight.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderMiddleLeft.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderMiddleRight.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderTopCenter.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderTopLeft.png +0 -0
- data/app/assets/images/tandem/colorbox/ie6/borderTopRight.png +0 -0
- data/app/assets/images/tandem/colorbox/loading.gif +0 -0
- data/app/assets/images/tandem/ic-delete_image.png +0 -0
- data/app/assets/images/tandem/ic-star.png +0 -0
- data/app/assets/images/tandem/loader.gif +0 -0
- data/app/assets/images/tandem/loader_stripe.png +0 -0
- data/app/assets/images/tandem/tandem-editImage2.jpg +0 -0
- data/app/assets/images/tandem/tandem_logo.png +0 -0
- data/app/assets/images/tandem/tandem_logo_nav.png +0 -0
- data/app/assets/javascripts/tandem/contents.js +2 -0
- data/app/assets/javascripts/tandem/current_image.jst.eco +19 -0
- data/app/assets/javascripts/tandem/gallery_image.jst.eco +10 -0
- data/app/assets/javascripts/tandem/images.coffee +42 -0
- data/app/assets/javascripts/tandem/pages.js.coffee +32 -0
- data/app/assets/javascripts/tandem/popup.js +23 -0
- data/app/assets/javascripts/tandem.js +16 -0
- data/app/assets/stylesheets/tandem/colorbox.css.erb +83 -0
- data/app/assets/stylesheets/tandem/contents.scss +541 -0
- data/app/assets/stylesheets/tandem/scaffold.scss +61 -0
- data/app/assets/stylesheets/tandem/variables.scss +38 -0
- data/app/assets/stylesheets/tandem.css +7 -0
- data/app/controllers/tandem/application_controller.rb +19 -0
- data/app/controllers/tandem/contents_controller.rb +94 -0
- data/app/controllers/tandem/images_controller.rb +92 -0
- data/app/controllers/tandem/pages_controller.rb +108 -0
- data/app/helpers/tandem/application_helper.rb +29 -0
- data/app/helpers/tandem/contents_helper.rb +19 -0
- data/app/helpers/tandem/images_helper.rb +10 -0
- data/app/helpers/tandem/pages_helper.rb +243 -0
- data/app/models/tandem/ability.rb +6 -0
- data/app/models/tandem/content/image.rb +7 -0
- data/app/models/tandem/content/text.rb +7 -0
- data/app/models/tandem/content.rb +41 -0
- data/app/models/tandem/image.rb +27 -0
- data/app/models/tandem/page.rb +41 -0
- data/app/views/layouts/tandem/image.html.slim +19 -0
- data/app/views/layouts/tandem/popup.html.slim +17 -0
- data/app/views/tandem/contents/_form.html.slim +36 -0
- data/app/views/tandem/contents/edit.html.slim +3 -0
- data/app/views/tandem/contents/index.html.slim +29 -0
- data/app/views/tandem/contents/new.html.slim +3 -0
- data/app/views/tandem/contents/show.html.slim +20 -0
- data/app/views/tandem/images/_form.html.slim +24 -0
- data/app/views/tandem/images/_gallery.html.slim +4 -0
- data/app/views/tandem/images/edit.html.slim +8 -0
- data/app/views/tandem/images/index.html.slim +9 -0
- data/app/views/tandem/images/new.html.slim +4 -0
- data/app/views/tandem/images/show.html.slim +10 -0
- data/app/views/tandem/images/thumb.html.slim +1 -0
- data/app/views/tandem/pages/_form.html.slim +56 -0
- data/app/views/tandem/pages/edit.html.slim +1 -0
- data/app/views/tandem/pages/index.html.slim +35 -0
- data/app/views/tandem/pages/new.html.slim +1 -0
- data/app/views/tandem/pages/show.html.slim +16 -0
- data/config/cucumber.yml +8 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20111122221549_create_tandem_pages.rb +20 -0
- data/db/migrate/20111122222037_create_tandem_contents.rb +21 -0
- data/db/migrate/20111215001943_create_tandem_images.rb +12 -0
- data/db/migrate/30000000000000_create_default_page.rb +10 -0
- data/db/migrate/30000000000001_add_request_key_to_tandem_contents.rb +44 -0
- data/lib/generators/tandem_generator.rb +26 -0
- data/lib/generators/templates/initializer.rb +70 -0
- data/lib/tandem/engine.rb +23 -0
- data/lib/tandem/version.rb +3 -0
- data/lib/tandem.rb +46 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/tasks/tandem_tasks.rake +4 -0
- metadata +354 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Tandem
|
|
2
|
+
class Page < ActiveRecord::Base
|
|
3
|
+
has_many :contents
|
|
4
|
+
belongs_to :parent, :class_name => 'Page'
|
|
5
|
+
has_many :children, :class_name => 'Page', :foreign_key => :parent_id
|
|
6
|
+
|
|
7
|
+
validates :link_label, presence: true, uniqueness: true
|
|
8
|
+
validates :slug, presence: true, uniqueness: true
|
|
9
|
+
validates :is_default, :inclusion => {:in => [true, false]}
|
|
10
|
+
|
|
11
|
+
before_validation :do_before_validation
|
|
12
|
+
after_save :do_after_save
|
|
13
|
+
|
|
14
|
+
scope :top_level, where( parent_id: nil )
|
|
15
|
+
|
|
16
|
+
attr_accessible :parent_id, :title, :page_label, :link_label, :layout, :template, :keywords, :description, :slug, :is_default
|
|
17
|
+
|
|
18
|
+
def to_param
|
|
19
|
+
persisted? ? slug : nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
#auto increment slug until it is unique
|
|
25
|
+
def do_before_validation
|
|
26
|
+
prim_slug, i = slug, 0
|
|
27
|
+
prim_slug, i = $1, $2.to_i if slug =~ /^(.*)_([0-9]+)$/
|
|
28
|
+
|
|
29
|
+
return unless prim_slug.present?
|
|
30
|
+
|
|
31
|
+
attempts = 0
|
|
32
|
+
conditions = new_record? ? ['slug = ?',slug] : ['slug = ? AND id != ?',slug,id]
|
|
33
|
+
conditions[1] = "#{prim_slug}_#{i+=1}" while Page.where(conditions).first && (attempts += 1) < 20
|
|
34
|
+
write_attribute(:slug,conditions[1])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def do_after_save
|
|
38
|
+
self.class.update_all({is_default: false}, ['id != ?',id]) if is_default?
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
doctype 5
|
|
2
|
+
| <!--[if lt IE 7 ]> <html class="ie6 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
3
|
+
| <!--[if IE 7 ]> <html class="ie7 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
4
|
+
| <!--[if IE 8 ]> <html class="ie8 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
5
|
+
| <!--[if IE 9 ]> <html class="ie9 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
6
|
+
| <!--[if !(IE)]><!--> <html class="no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <!--<![endif]-->
|
|
7
|
+
|
|
8
|
+
head
|
|
9
|
+
title Tandem Image Gallery
|
|
10
|
+
|
|
11
|
+
= stylesheet_link_tag "tandem"
|
|
12
|
+
= csrf_meta_tags
|
|
13
|
+
|
|
14
|
+
body
|
|
15
|
+
|
|
16
|
+
= yield
|
|
17
|
+
= javascript_include_tag "tandem"
|
|
18
|
+
|
|
19
|
+
| </html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
doctype 5
|
|
2
|
+
| <!--[if lt IE 7 ]> <html class="ie6 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
3
|
+
| <!--[if IE 7 ]> <html class="ie7 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
4
|
+
| <!--[if IE 8 ]> <html class="ie8 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
5
|
+
| <!--[if IE 9 ]> <html class="ie9 no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]-->
|
|
6
|
+
| <!--[if !(IE)]><!--> <html class="no-js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"> <!--<![endif]-->
|
|
7
|
+
head
|
|
8
|
+
title Tandem Popup
|
|
9
|
+
|
|
10
|
+
= stylesheet_link_tag "tandem"
|
|
11
|
+
= csrf_meta_tags
|
|
12
|
+
|
|
13
|
+
body
|
|
14
|
+
= yield
|
|
15
|
+
= javascript_include_tag "tandem"
|
|
16
|
+
|
|
17
|
+
|</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// This is the form that controls Image upload and Text Editor
|
|
2
|
+
#tandem-editor-wym
|
|
3
|
+
= form_for @content, url: tandem.content_path(@content.id), remote: true, html: {class: "tandem_content_editor tandem_#{@content.class.simple_type}_editor"} do |f|
|
|
4
|
+
-if @content.errors.any?
|
|
5
|
+
#tandem_error_explanation
|
|
6
|
+
h2 = "#{pluralize(@content.errors.count, "error")} prohibited this content from being saved:"
|
|
7
|
+
ul
|
|
8
|
+
- @content.errors.full_messages.each do |msg|
|
|
9
|
+
li= msg
|
|
10
|
+
|
|
11
|
+
-if @content.is_a?(Tandem::Content::Text)
|
|
12
|
+
.field
|
|
13
|
+
= f.text_area :content, text_content_text_area_options(params[:editor])
|
|
14
|
+
|
|
15
|
+
-if @content.is_a?(Tandem::Content::Image)
|
|
16
|
+
= render_eco_template 'current_image', @content.image.as_json
|
|
17
|
+
|
|
18
|
+
#tandem_advanced_settings
|
|
19
|
+
h3.settings-toggle Advanced Settings
|
|
20
|
+
.advanced-settings
|
|
21
|
+
.field
|
|
22
|
+
= f.label :link_url
|
|
23
|
+
= f.text_field :link_url
|
|
24
|
+
.field
|
|
25
|
+
= f.label :link_target
|
|
26
|
+
= f.text_field :link_target
|
|
27
|
+
|
|
28
|
+
.actions
|
|
29
|
+
= f.submit 'Save Your Changes', class: "wymupdate"
|
|
30
|
+
|
|
31
|
+
- if @content.is_a?(Tandem::Content::Image)
|
|
32
|
+
div#tandem-image-editor.clearfix
|
|
33
|
+
= render '/tandem/images/form'
|
|
34
|
+
|
|
35
|
+
#gallery-image.clearfix
|
|
36
|
+
= render '/tandem/images/gallery'
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
h1.tandem-title Listing contents
|
|
2
|
+
|
|
3
|
+
table
|
|
4
|
+
tr
|
|
5
|
+
th Page
|
|
6
|
+
th Type
|
|
7
|
+
th Token
|
|
8
|
+
th Tag
|
|
9
|
+
th Content
|
|
10
|
+
th Bcontent
|
|
11
|
+
th
|
|
12
|
+
th
|
|
13
|
+
th
|
|
14
|
+
|
|
15
|
+
- @contents.each do |content|
|
|
16
|
+
tr
|
|
17
|
+
td= content.page_id
|
|
18
|
+
td= content.type
|
|
19
|
+
td= content.token
|
|
20
|
+
td= content.tag
|
|
21
|
+
td= content.content
|
|
22
|
+
td= content.bcontent
|
|
23
|
+
td= link_to 'Show', content
|
|
24
|
+
td= link_to 'Edit', edit_content_path(content)
|
|
25
|
+
td= link_to 'Delete', content, :confirm => 'Are you sure?', :method => :delete
|
|
26
|
+
|
|
27
|
+
br
|
|
28
|
+
|
|
29
|
+
= link_to 'New Content', new_content_path
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#tandem-upload-image
|
|
2
|
+
= form_for (@image ||= ::Tandem::Image.new), :url => (@image.new_record? ? tandem.images_path : tandem.image_path(@image)), :html => { :multipart => true, :id => 'new_tandem_image' } do |f|
|
|
3
|
+
|
|
4
|
+
-if f.object.errors.any?
|
|
5
|
+
#error_explanation
|
|
6
|
+
h2 = "#{pluralize(f.object.errors.count, "error")} prohibited this image from being saved:"
|
|
7
|
+
ul
|
|
8
|
+
- f.object.errors.full_messages.each do |msg|
|
|
9
|
+
li= msg
|
|
10
|
+
|
|
11
|
+
span#upload-button
|
|
12
|
+
| Upload a New Image
|
|
13
|
+
= f.file_field :resource
|
|
14
|
+
|
|
15
|
+
div.loader
|
|
16
|
+
div.range
|
|
17
|
+
span 0%
|
|
18
|
+
|
|
19
|
+
section#error_explanation
|
|
20
|
+
header
|
|
21
|
+
h1 Oops—there's been a problem
|
|
22
|
+
|
|
23
|
+
ul
|
|
24
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
.tandem-gallery
|
|
2
|
+
ul
|
|
3
|
+
- @images.each do |image|
|
|
4
|
+
li
|
|
5
|
+
= image_tag image.resource.url(:thumb), :onclick => "select_gallery_item(#{image.id})", :class => "thumb"
|
|
6
|
+
ul.actions
|
|
7
|
+
li
|
|
8
|
+
a.use href="/" Use
|
|
9
|
+
= link_to 'Delete', image, :confirm => 'Are you sure?', :method => :delete, :class => "delete"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= image_content_tag @content, {}, :thumb
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// This form controls New Page, Edit Page
|
|
2
|
+
#tandem-editor
|
|
3
|
+
= form_for @page, url: (@page.new_record? ? tandem.pages_path : tandem.page_path(@page)), remote: true, html: { class: 'tandem-page-form' } do |f|
|
|
4
|
+
-if @page.errors.any?
|
|
5
|
+
#error_explanation
|
|
6
|
+
h2 = "#{pluralize(@page.errors.count, "error")} prohibited this page from being saved:"
|
|
7
|
+
ul
|
|
8
|
+
- @page.errors.full_messages.each do |msg|
|
|
9
|
+
li= msg
|
|
10
|
+
#tandem_settings
|
|
11
|
+
h1.tandem-title Page Settings
|
|
12
|
+
.field
|
|
13
|
+
= f.label :parent_id
|
|
14
|
+
= f.radio_button :parent_id, ''
|
|
15
|
+
span Top Level Page
|
|
16
|
+
- if @page.parent.present?
|
|
17
|
+
= f.radio_button :parent_id, @page.parent_id
|
|
18
|
+
span
|
|
19
|
+
| Child Page (
|
|
20
|
+
= page_path(@page.parent)
|
|
21
|
+
| )
|
|
22
|
+
.field
|
|
23
|
+
= f.label :title
|
|
24
|
+
= f.text_field :title
|
|
25
|
+
.field
|
|
26
|
+
= f.label :link_label
|
|
27
|
+
= f.text_field :link_label
|
|
28
|
+
.field
|
|
29
|
+
= f.label :slug
|
|
30
|
+
= f.text_field :slug
|
|
31
|
+
.field
|
|
32
|
+
= f.label :layout
|
|
33
|
+
= f.select :layout, options_for_select(valid_layouts,@page.layout), :include_blank => true
|
|
34
|
+
.field
|
|
35
|
+
= f.label :template
|
|
36
|
+
= f.select :template, options_for_select(valid_templates, @page.template), :include_blank => true
|
|
37
|
+
|
|
38
|
+
#tandem_advanced_settings
|
|
39
|
+
h3.settings-toggle Advanced Settings
|
|
40
|
+
.advanced-settings
|
|
41
|
+
.field
|
|
42
|
+
= f.label :page_label
|
|
43
|
+
= f.text_field :page_label
|
|
44
|
+
.field
|
|
45
|
+
= f.label :keywords
|
|
46
|
+
= f.text_field :keywords
|
|
47
|
+
.field
|
|
48
|
+
= f.label :description
|
|
49
|
+
= f.text_field :description
|
|
50
|
+
.field
|
|
51
|
+
= f.label :is_default, 'Set As Home Page?', :style => "width: auto;margin-right: 8px;"
|
|
52
|
+
= f.check_box :is_default
|
|
53
|
+
.actions
|
|
54
|
+
= f.submit 'Save', :class => "save"
|
|
55
|
+
|
|
56
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
== render 'form'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#tandem-defaults
|
|
2
|
+
h1.tandem-title Pages Listing
|
|
3
|
+
|
|
4
|
+
table
|
|
5
|
+
tr
|
|
6
|
+
th Parent
|
|
7
|
+
th Link Label
|
|
8
|
+
th Page Label
|
|
9
|
+
th Page Title
|
|
10
|
+
th Layout
|
|
11
|
+
th Keywords
|
|
12
|
+
th Description
|
|
13
|
+
th
|
|
14
|
+
th
|
|
15
|
+
th
|
|
16
|
+
|
|
17
|
+
- @pages.each do |page|
|
|
18
|
+
tr
|
|
19
|
+
td= page.parent.try :slug
|
|
20
|
+
td= page.link_label
|
|
21
|
+
td= page.page_label
|
|
22
|
+
td= page.title
|
|
23
|
+
td= page.layout
|
|
24
|
+
td= page.keywords
|
|
25
|
+
td= page.description
|
|
26
|
+
td= link_to 'Show', tandem.page_path(page)
|
|
27
|
+
- if can?(:update, page)
|
|
28
|
+
td= link_to 'Edit', tandem.edit_page_path(page), :class => :page_link
|
|
29
|
+
- if can?(:destroy, page)
|
|
30
|
+
td= link_to 'Delete', tandem.page_path(page), :confirm => 'Are you sure?', :method => :delete
|
|
31
|
+
|
|
32
|
+
br
|
|
33
|
+
|
|
34
|
+
- if can?(:create, ::Tandem::Page)
|
|
35
|
+
= link_to 'New Page', tandem.new_page_path, :class => :page_link, :id => :page_new_link
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
== render 'form'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#tandem-defaults
|
|
2
|
+
= tandem_page_links
|
|
3
|
+
|
|
4
|
+
// Our built-in page uses classes for bootstrap or 960.gs
|
|
5
|
+
|
|
6
|
+
.container_12.row.clearfix
|
|
7
|
+
p#notice = notice
|
|
8
|
+
.grid_12.span12
|
|
9
|
+
= tandem_image_tag(:default_image)
|
|
10
|
+
.grid_7.span7
|
|
11
|
+
= tandem_text_tag(:tandem_text_block, editor: :wysiwyg)
|
|
12
|
+
.grid_5.span5
|
|
13
|
+
= tandem_text_tag(:tandem_sidebar)
|
|
14
|
+
|
|
15
|
+
- unless @page.persisted?
|
|
16
|
+
| This is the default page content and should tell the user to go create a page
|
data/config/cucumber.yml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%
|
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
|
4
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
|
|
5
|
+
%>
|
|
6
|
+
default: --drb <%= std_opts %> features
|
|
7
|
+
wip: --drb --tags @wip:3 --wip features
|
|
8
|
+
rerun: --drb <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Tandem::Engine.routes.draw do
|
|
2
|
+
resources :images do
|
|
3
|
+
member do
|
|
4
|
+
get :thumb
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
resources :pages do
|
|
9
|
+
collection do
|
|
10
|
+
get :home
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
resources :contents, :only => [:edit, :update]
|
|
15
|
+
|
|
16
|
+
root :to => 'pages#home'
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class CreateTandemPages < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :tandem_pages do |t|
|
|
4
|
+
t.integer :parent_id
|
|
5
|
+
t.string :title
|
|
6
|
+
t.string :page_label
|
|
7
|
+
t.string :link_label, :null => false
|
|
8
|
+
t.string :layout
|
|
9
|
+
t.string :template
|
|
10
|
+
t.string :keywords
|
|
11
|
+
t.string :description
|
|
12
|
+
t.string :slug, :null => false
|
|
13
|
+
t.boolean :is_default, :default => false, :null => false
|
|
14
|
+
|
|
15
|
+
t.timestamps
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
add_index :tandem_pages, :parent_id
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class CreateTandemContents < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :tandem_contents do |t|
|
|
4
|
+
t.integer :page_id, :null => false
|
|
5
|
+
t.string :type, :null => false
|
|
6
|
+
t.string :tag, :null => false
|
|
7
|
+
t.text :content
|
|
8
|
+
t.text :details
|
|
9
|
+
t.string :link_url
|
|
10
|
+
t.string :link_target
|
|
11
|
+
t.integer :attachment_id
|
|
12
|
+
t.string :attachment_type, :default => "Tandem::Image"
|
|
13
|
+
t.integer :image_id
|
|
14
|
+
|
|
15
|
+
t.timestamps
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
add_index :tandem_contents, :page_id
|
|
19
|
+
add_index :tandem_contents, [:page_id, :type, :tag], :unique => true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class CreateTandemImages < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :tandem_images do |t|
|
|
4
|
+
t.string :resource_file_name
|
|
5
|
+
t.string :resource_content_type
|
|
6
|
+
t.integer :resource_file_size
|
|
7
|
+
t.datetime :resource_updated_at
|
|
8
|
+
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#NOTE:: The timestamp for the this file is set way into the future so that it is always the last migration run
|
|
2
|
+
class CreateDefaultPage < ActiveRecord::Migration
|
|
3
|
+
def up
|
|
4
|
+
Tandem::Page.new(link_label: 'Sample Page', slug: 'sample').save!
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def down
|
|
8
|
+
Tandem::Page.delete_all
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class AddRequestKeyToTandemContents < ActiveRecord::Migration
|
|
2
|
+
def up
|
|
3
|
+
add_column :tandem_contents, :request_key, :string
|
|
4
|
+
|
|
5
|
+
Tandem::Content.all.each do |content|
|
|
6
|
+
if Tandem::Page.exists?(content.page_id)
|
|
7
|
+
page = Tandem::Page.find(content.page_id)
|
|
8
|
+
content.update_attributes!(:request_key => "tandem-pages-#{page.slug}")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
remove_index :tandem_contents, :page_id
|
|
13
|
+
remove_index :tandem_contents, [:page_id, :type, :tag]
|
|
14
|
+
|
|
15
|
+
remove_column :tandem_contents, :page_id
|
|
16
|
+
|
|
17
|
+
add_index :tandem_contents, :request_key
|
|
18
|
+
add_index :tandem_contents, [:request_key, :type, :tag], :unique => true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def down
|
|
22
|
+
add_column :tandem_contents, :page_id, :integer
|
|
23
|
+
|
|
24
|
+
Tandem::Content.all.each do |content|
|
|
25
|
+
if content.request_key =~ /^tandem-pages-.*$/
|
|
26
|
+
page = Tandem::Page.find_by_slug(content.request_key.gsub(/^tandem-pages-/, ''))
|
|
27
|
+
|
|
28
|
+
if page.present?
|
|
29
|
+
content.update_attributes!(:page_id => page.id)
|
|
30
|
+
else
|
|
31
|
+
raise ActiveRecord::IrreversibleMigration
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
remove_index :tandem_contents, :request_key
|
|
37
|
+
remove_index :tandem_contents, [:request_key, :type, :tag]
|
|
38
|
+
|
|
39
|
+
remove_column :tandem_contents, :request_key
|
|
40
|
+
|
|
41
|
+
add_index :tandem_contents, :page_id
|
|
42
|
+
add_index :tandem_contents, [:page_id, :type, :tag], :unique => true
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
|
|
3
|
+
class TandemGenerator < Rails::Generators::Base
|
|
4
|
+
desc "This generator sets up tandem."
|
|
5
|
+
|
|
6
|
+
def self.source_root
|
|
7
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create_initializer_file
|
|
11
|
+
initializer 'tandem.rb', File.open(File.join(self.class.source_root,'initializer.rb'), 'rb') { |f| f.read }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def add_mounting_route
|
|
15
|
+
route('mount Tandem::Engine => "/"')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def import_migrations
|
|
19
|
+
rake("tandem:install:migrations")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def inject_tandem_assets
|
|
23
|
+
append_to_file 'app/assets/javascripts/application.js', '//= require tandem'
|
|
24
|
+
insert_into_file 'app/assets/stylesheets/application.css', " *= require tandem\n", :before => /^\*\/$/
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Tandem::Configuration.current_user_proc { |request|
|
|
2
|
+
# Uncomment and/or modify the following line once your project has a user model to
|
|
3
|
+
# derive abilities from.
|
|
4
|
+
#
|
|
5
|
+
# The request is passed in so you can access it directly to specify what the current
|
|
6
|
+
# user is, regardless of the context, e.g. main app or Tandem, the proc is called from.
|
|
7
|
+
#
|
|
8
|
+
# User.find(request.session['user_id']) unless request.session['user_id'].blank?
|
|
9
|
+
#
|
|
10
|
+
# Or, for devise:
|
|
11
|
+
#
|
|
12
|
+
# request.env['warden'].authenticate(:scope => :user)
|
|
13
|
+
}
|
|
14
|
+
Tandem::Configuration.user_abilities_proc { |user|
|
|
15
|
+
# Define abilities for the passed in user here. For example:
|
|
16
|
+
#
|
|
17
|
+
# user ||= User.new # guest user (not logged in)
|
|
18
|
+
# if user.admin?
|
|
19
|
+
# can :manage, :all
|
|
20
|
+
# else
|
|
21
|
+
# can :read, :all
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# The first argument to `can` is the action you are giving the user permission to do.
|
|
25
|
+
# If you pass :manage it will apply to every action. Other common actions here are
|
|
26
|
+
# :read, :create, :update and :destroy.
|
|
27
|
+
#
|
|
28
|
+
# The second argument is the resource the user can perform the action on. If you pass
|
|
29
|
+
# :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
|
|
30
|
+
#
|
|
31
|
+
# The third argument is an optional hash of conditions to further filter the objects.
|
|
32
|
+
# For example, here the user can only update published articles.
|
|
33
|
+
#
|
|
34
|
+
# can :update, Article, :published => true
|
|
35
|
+
#
|
|
36
|
+
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
|
|
37
|
+
|
|
38
|
+
can :manage, :all
|
|
39
|
+
#can :manage, Page
|
|
40
|
+
#can :read, Page
|
|
41
|
+
|
|
42
|
+
#can :manage, Content
|
|
43
|
+
#can :update, Content
|
|
44
|
+
#can :read, Content
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# By default, tandem will redirect a user back to the engine mount point "/tandem" on
|
|
48
|
+
# an authentication error. This can cause an infinite loop if for example
|
|
49
|
+
# PageController#index is not readable by all users. Uncomment this to redirect to the
|
|
50
|
+
# app root instead.
|
|
51
|
+
# Tandem::Configuration.unauthorized_path = '/'
|
|
52
|
+
|
|
53
|
+
# Change this to move your layouts directory from /app/views/layouts/tandem
|
|
54
|
+
# Tandem::Configuration.layouts_dir = 'tandem'
|
|
55
|
+
|
|
56
|
+
# Change this to move your uploaded images directory from /public/assets/images/...
|
|
57
|
+
# Tandem::Configuration.uploaded_images_dir = ":rails_root/public"
|
|
58
|
+
|
|
59
|
+
# Change this to modify your uploaded images directory structure & routing from /public/assets/images/1/original/...
|
|
60
|
+
# Tandem::Configuration.uploaded_images_template = "/assets/images/:id/:style/:basename.:extension"
|
|
61
|
+
|
|
62
|
+
# Override Tandem's default paperclip options
|
|
63
|
+
# For example, to use S3, add the aws-sdk gem to your gemfile and uncomment the following
|
|
64
|
+
# Tandem::Configuration.paperclip_options = { :styles => { :thumb => "150x150>" },
|
|
65
|
+
#:storage => :s3,
|
|
66
|
+
#:bucket => Proc.new { Rails.application.engine_name.gsub(/application$/, Rails.env) },
|
|
67
|
+
#:s3_credentials => {
|
|
68
|
+
#:access_key_id => ENV['S3_KEY'],
|
|
69
|
+
#:secret_access_key => ENV['S3_SECRET']
|
|
70
|
+
#} }
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Tandem
|
|
2
|
+
class Engine < Rails::Engine
|
|
3
|
+
isolate_namespace Tandem
|
|
4
|
+
|
|
5
|
+
config.generators do |g|
|
|
6
|
+
g.test_framework :rspec, :fixture => true
|
|
7
|
+
g.fixture_replacement :factory_girl, :dir => "spec/factories"
|
|
8
|
+
g.template_engine :slim
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
config.eager_load_paths << File.expand_path("../../../app/models/tandem/content", __FILE__)
|
|
12
|
+
|
|
13
|
+
initializer "tandem.include_page_helpers" do |app|
|
|
14
|
+
ActiveSupport.on_load(:action_controller) do
|
|
15
|
+
helper ::Tandem::PagesHelper
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
ActiveSupport.on_load(:action_view) do
|
|
19
|
+
include ::Tandem::PagesHelper
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|